public function executeAcquireLease(DrydockResource $resource, DrydockLease $lease) { $key = Filesystem::readRandomCharacters(12); $ports = $resource->getAttribute('ports', array()); for ($ii = 2000;; $ii++) { if (empty($ports[$ii])) { $ports[$ii] = $lease->getID(); $port = $ii; break; } } $resource->setAttribute('ports', $ports); $resource->save(); $host = $resource->getAttribute('host'); $lease->setAttribute('port', $port); $lease->setAttribute('key', $key); $lease->save(); $config = <<<EOCONFIG Listen *:{$port} <VirtualHost *:{$port}> DocumentRoot /opt/drydock/webroot/{$key}/ ServerName {$host} </VirtualHost> EOCONFIG; $cmd = $this->getInterface($resource, $lease, 'command'); $cmd->execx(<<<EOSETUP sudo mkdir -p %s && sudo sh -c %s && sudo /etc/init.d/httpd restart EOSETUP , "/opt/drydock/webroot/{$key}/", csprintf('echo %s > %s', $config, "/etc/httpd/conf.d/drydock-{$key}.conf")); $lease->setAttribute('uri', "http://{$host}:{$port}/"); $lease->save(); }
protected function executeAcquireLease(DrydockResource $resource, DrydockLease $lease) { // Because preallocated resources are manually created, we should verify // we have all the information we need. PhutilTypeSpec::checkMap($resource->getAttributesForTypeSpec(array('platform', 'host', 'port', 'credential', 'path')), array('platform' => 'string', 'host' => 'string', 'port' => 'string', 'credential' => 'string', 'path' => 'string')); $v_platform = $resource->getAttribute('platform'); $v_path = $resource->getAttribute('path'); // Similar to DrydockLocalHostBlueprint, we create a folder // on the remote host that the lease can use. $lease_id = $lease->getID(); // Can't use DIRECTORY_SEPERATOR here because that is relevant to // the platform we're currently running on, not the platform we are // remoting to. $separator = '/'; if ($v_platform === 'windows') { $separator = '\\'; } // Clean up the directory path a little. $base_path = rtrim($v_path, '/'); $base_path = rtrim($base_path, '\\'); $full_path = $base_path . $separator . $lease_id; $cmd = $lease->getInterface('command'); $cmd->execx('mkdir %s', $full_path); $lease->setAttribute('path', $full_path); }
public function activateLease(DrydockBlueprint $blueprint, DrydockResource $resource, DrydockLease $lease) { $host_lease = $this->loadHostLease($resource); $command_type = DrydockCommandInterface::INTERFACE_TYPE; $interface = $host_lease->getInterface($command_type); $map = $lease->getAttribute('repositories.map'); $root = $resource->getAttribute('workingcopy.root'); $default = null; foreach ($map as $directory => $spec) { $cmd = array(); $arg = array(); $cmd[] = 'cd %s'; $arg[] = "{$root}/repo/{$directory}/"; $cmd[] = 'git clean -d --force'; $cmd[] = 'git fetch'; $commit = idx($spec, 'commit'); $branch = idx($spec, 'branch'); $ref = idx($spec, 'ref'); if ($commit !== null) { $cmd[] = 'git reset --hard %s'; $arg[] = $commit; } else { if ($branch !== null) { $cmd[] = 'git checkout %s'; $arg[] = $branch; $cmd[] = 'git reset --hard origin/%s'; $arg[] = $branch; } else { if ($ref) { $ref_uri = $ref['uri']; $ref_ref = $ref['ref']; $cmd[] = 'git fetch --no-tags -- %s +%s:%s'; $arg[] = $ref_uri; $arg[] = $ref_ref; $arg[] = $ref_ref; $cmd[] = 'git checkout %s'; $arg[] = $ref_ref; $cmd[] = 'git reset --hard %s'; $arg[] = $ref_ref; } else { $cmd[] = 'git reset --hard HEAD'; } } } $cmd = implode(' && ', $cmd); $argv = array_merge(array($cmd), $arg); $result = call_user_func_array(array($interface, 'execx'), $argv); if (idx($spec, 'default')) { $default = $directory; } } if ($default === null) { $default = head_key($map); } // TODO: Use working storage? $lease->setAttribute('workingcopy.default', "{$root}/repo/{$default}/"); $lease->activateOnResource($resource); }
private function applyMerge(DrydockLease $lease, DrydockCommandInterface $interface, array $merge) { $src_uri = $merge['src.uri']; $src_ref = $merge['src.ref']; $interface->execx('git fetch --no-tags -- %s +%s:%s', $src_uri, $src_ref, $src_ref); // NOTE: This can never actually generate a commit because we pass // "--squash", but git sometimes runs code to check that a username and // email are configured anyway. $real_command = csprintf('git -c user.name=%s -c user.email=%s merge --no-stat --squash -- %R', 'drydock', 'drydock@phabricator', $src_ref); // Show the user a simplified command if the operation fails and we need to // report an error. $show_command = csprintf('git merge --squash -- %R', $src_ref); try { $interface->execx('%C', $real_command); } catch (CommandException $ex) { $error = DrydockCommandError::newFromCommandException(self::PHASE_SQUASHMERGE, $show_command, $ex); $lease->setAttribute('workingcopy.vcs.error', $error); throw $ex; } }
protected function setWorkingCopyVCSErrorFromCommandException(DrydockLease $lease, $phase, $command, CommandException $ex) { $error = array('phase' => $phase, 'command' => (string) $command, 'raw' => (string) $ex->getCommand(), 'err' => $ex->getError(), 'stdout' => $ex->getStdout(), 'stderr' => $ex->getStderr()); $lease->setAttribute('workingcopy.vcs.error', $error); }
private function applyMerge(DrydockLease $lease, DrydockCommandInterface $interface, array $merge) { $src_uri = $merge['src.uri']; $src_ref = $merge['src.ref']; try { $interface->execx('git fetch --no-tags -- %s +%s:%s', $src_uri, $src_ref, $src_ref); } catch (CommandException $ex) { $display_command = csprintf('git fetch %R +%R:%R', $src_uri, $src_ref, $src_ref); $error = DrydockCommandError::newFromCommandException($ex)->setPhase(self::PHASE_MERGEFETCH)->setDisplayCommand($display_command); $lease->setAttribute('workingcopy.vcs.error', $error->toDictionary()); throw $ex; } // NOTE: This can never actually generate a commit because we pass // "--squash", but git sometimes runs code to check that a username and // email are configured anyway. $real_command = csprintf('git -c user.name=%s -c user.email=%s merge --no-stat --squash -- %R', 'drydock', 'drydock@phabricator', $src_ref); try { $interface->execx('%C', $real_command); } catch (CommandException $ex) { $display_command = csprintf('git merge --squash %R', $src_ref); $error = DrydockCommandError::newFromCommandException($ex)->setPhase(self::PHASE_SQUASHMERGE)->setDisplayCommand($display_command); $lease->setAttribute('workingcopy.vcs.error', $error->toDictionary()); throw $ex; } }