/** * Runs chef client on the servers that match the query storing command output in the given file. * * @param string $query The chef query to specify what servers to update. * @param string $progressFile The filename to send the knife output to. * @param array $options Additional options for knife ssh. For example: ['-groups' => 'foo'] * @param array $chefOptions Additional options for chef client. For example: ['--override-runlist' => 'role[foo]'] * @return void */ public function updateServers($query, $progressFile = null, array $options = [], array $chefOptions = []) { $instanceIdUrl = 'http://169.254.169.254/latest/meta-data/instance-id'; $chefOptions = array_merge($chefOptions, ['--json-attributes' => '/etc/chef/first-boot.json']); $chefCommand = \Hiatus\addArguments("sudo chef-client -N `curl {$instanceIdUrl}`", $chefOptions); $options = array_merge($options, $this->_chefClientParameters(), $this->_ec2SshParameters(), [$query, $chefCommand]); $command = \Hiatus\addArguments("{$this->_baseKnifeCommand} ssh", $options); if ($progressFile !== null) { \Hiatus\execX("{$command} >" . escapeshellarg($progressFile) . ' 2>&1 &'); } else { passthru($command); } }
/** * Executes the /tmp/userScript on the docker image given. * * @param array $image An image specification. The image must be fully prepared and have an executeCommand to provide what command/interpreter * to use to kick off the user's script. * @return array The result of executing the user's script, including * int exitStatus The exit status of the user's script * string output The stdout of the user's script * string stderr The stderr of the user's script */ function execute(array $image) { $tagName = $image['tagName']; $executeCommand = $image['executeCommand']; file_put_contents('php://stderr', "Executing script on docker image {$tagName}\n"); list($containerId) = \Hiatus\execX('docker -H tcp://localhost:4243 run -d', [$tagName, $executeCommand, '/tmp/userScript']); $containerId = trim($containerId); list($exitStatus) = \Hiatus\execX('docker -H tcp://localhost:4243 wait', [$containerId], 10); $exitStatus = trim($exitStatus); $exitStatus = is_numeric($exitStatus) ? (int) $exitStatus : null; $output = dockerRequest('containers/' . urlencode($containerId) . '/attach?logs=1&stdout=1', 'POST'); $stderr = dockerRequest('containers/' . urlencode($containerId) . '/attach?logs=1&stderr=1', 'POST'); dockerRequest('containers/' . urlencode($containerId), 'DELETE'); return ['exitStatus' => $exitStatus, 'output' => $output, 'stderr' => $stderr]; }