Changeset View
Standalone View
src/applications/drydock/blueprint/DrydockWorkingCopyBlueprintImplementation.php
| Show First 20 Lines • Show All 167 Lines • ▼ Show 20 Lines | public function activateResource( | ||||
| $interface = $lease->getInterface($command_type); | $interface = $lease->getInterface($command_type); | ||||
| // TODO: Make this configurable. | // TODO: Make this configurable. | ||||
| $resource_id = $resource->getID(); | $resource_id = $resource->getID(); | ||||
| $root = "/var/drydock/workingcopy-{$resource_id}"; | $root = "/var/drydock/workingcopy-{$resource_id}"; | ||||
| $map = $resource->getAttribute('repositories.map'); | $map = $resource->getAttribute('repositories.map'); | ||||
| $futures = array(); | |||||
| $repositories = $this->loadRepositories(ipull($map, 'phid')); | $repositories = $this->loadRepositories(ipull($map, 'phid')); | ||||
| foreach ($map as $directory => $spec) { | foreach ($map as $directory => $spec) { | ||||
| // TODO: Validate directory isn't goofy like "/etc" or "../../lol" | // TODO: Validate directory isn't goofy like "/etc" or "../../lol" | ||||
| // somewhere? | // somewhere? | ||||
| $repository = $repositories[$spec['phid']]; | $repository = $repositories[$spec['phid']]; | ||||
| $path = "{$root}/repo/{$directory}/"; | $path = "{$root}/repo/{$directory}/"; | ||||
| // TODO: Run these in parallel? | $future = $interface->getExecFuture( | ||||
| $interface->execx( | |||||
| 'git clone -- %s %s', | 'git clone -- %s %s', | ||||
| (string)$repository->getCloneURIObject(), | (string)$repository->getCloneURIObject(), | ||||
| $path); | $path); | ||||
| $future->setTimeout($repository->getCopyTimeLimit()); | |||||
| $futures[$directory] = $future; | |||||
amckinley: Could this result in a collision? Or are these directories already guaranteed to be unique? | |||||
Done Inline ActionsThe directories are "sort of guaranteed unique for our purposes" if we get this far since they're already keys in $map. They're originally derived elsewhere from $repository->getCloneName(), which is not always guaranteed to be unique, but I think that's more of an issue for a higher-level layer to care about. We aren't creating any new problems by doing this, at least. epriestley: The directories are "sort of guaranteed unique for our purposes" if we get this far since… | |||||
| } | |||||
| foreach (new FutureIterator($futures) as $key => $future) { | |||||
| $future->resolvex(); | |||||
| } | } | ||||
| $resource | $resource | ||||
| ->setAttribute('workingcopy.root', $root) | ->setAttribute('workingcopy.root', $root) | ||||
| ->activateResource(); | ->activateResource(); | ||||
| } | } | ||||
| public function destroyResource( | public function destroyResource( | ||||
| Show All 38 Lines | public function activateLease( | ||||
| $host_lease = $this->loadHostLease($resource); | $host_lease = $this->loadHostLease($resource); | ||||
| $command_type = DrydockCommandInterface::INTERFACE_TYPE; | $command_type = DrydockCommandInterface::INTERFACE_TYPE; | ||||
| $interface = $host_lease->getInterface($command_type); | $interface = $host_lease->getInterface($command_type); | ||||
| $map = $lease->getAttribute('repositories.map'); | $map = $lease->getAttribute('repositories.map'); | ||||
| $root = $resource->getAttribute('workingcopy.root'); | $root = $resource->getAttribute('workingcopy.root'); | ||||
| $repositories = $this->loadRepositories(ipull($map, 'phid')); | |||||
| $default = null; | $default = null; | ||||
| foreach ($map as $directory => $spec) { | foreach ($map as $directory => $spec) { | ||||
| $repository = $repositories[$spec['phid']]; | |||||
| $interface->pushWorkingDirectory("{$root}/repo/{$directory}/"); | $interface->pushWorkingDirectory("{$root}/repo/{$directory}/"); | ||||
| $cmd = array(); | $cmd = array(); | ||||
| $arg = array(); | $arg = array(); | ||||
| $cmd[] = 'git clean -d --force'; | $cmd[] = 'git clean -d --force'; | ||||
| $cmd[] = 'git fetch'; | $cmd[] = 'git fetch'; | ||||
| Show All 13 Lines | foreach ($map as $directory => $spec) { | ||||
| } else if ($branch !== null) { | } else if ($branch !== null) { | ||||
| $cmd[] = 'git checkout %s --'; | $cmd[] = 'git checkout %s --'; | ||||
| $arg[] = $branch; | $arg[] = $branch; | ||||
| $cmd[] = 'git reset --hard origin/%s'; | $cmd[] = 'git reset --hard origin/%s'; | ||||
| $arg[] = $branch; | $arg[] = $branch; | ||||
| } | } | ||||
| $this->execxv($interface, $cmd, $arg); | $this->newExecvFuture($interface, $cmd, $arg) | ||||
| ->setTimeout($repository->getCopyTimeLimit()) | |||||
| ->resolvex(); | |||||
Not Done Inline ActionsWe don't want to also do these in parallel like activateResource() now does? amckinley: We don't want to also do these in parallel like `activateResource()` now does? | |||||
Done Inline ActionsIt would probably be slightly preferable, but since the two commands have to go in sequence it would be a bigger rework than the clone rework above. In practice, although we use this stuff (multiple working copies: libphutil/ + arcanist/ + phabricator/) other projects normally don't so the benefit is likely minimal. I reworked above but not here just out of guesses about patch size and comfort with how thoroughly I was testing. I think this stuff is likely to get more significant work in some future iteration, e.g. see T9492. epriestley: It would probably be slightly preferable, but since the two commands have to go in sequence it… | |||||
| if (idx($spec, 'default')) { | if (idx($spec, 'default')) { | ||||
| $default = $directory; | $default = $directory; | ||||
| } | } | ||||
| // If we're fetching a ref from a remote, do that separately so we can | // If we're fetching a ref from a remote, do that separately so we can | ||||
| // raise a more tailored error. | // raise a more tailored error. | ||||
| if ($ref) { | if ($ref) { | ||||
| $cmd = array(); | $cmd = array(); | ||||
| $arg = array(); | $arg = array(); | ||||
| $ref_uri = $ref['uri']; | $ref_uri = $ref['uri']; | ||||
| $ref_ref = $ref['ref']; | $ref_ref = $ref['ref']; | ||||
| $cmd[] = 'git fetch --no-tags -- %s +%s:%s'; | $cmd[] = 'git fetch --no-tags -- %s +%s:%s'; | ||||
| $arg[] = $ref_uri; | $arg[] = $ref_uri; | ||||
| $arg[] = $ref_ref; | $arg[] = $ref_ref; | ||||
| $arg[] = $ref_ref; | $arg[] = $ref_ref; | ||||
| $cmd[] = 'git checkout %s --'; | $cmd[] = 'git checkout %s --'; | ||||
| $arg[] = $ref_ref; | $arg[] = $ref_ref; | ||||
| try { | try { | ||||
| $this->execxv($interface, $cmd, $arg); | $this->newExecvFuture($interface, $cmd, $arg) | ||||
| ->setTimeout($repository->getCopyTimeLimit()) | |||||
| ->resolvex(); | |||||
| } catch (CommandException $ex) { | } catch (CommandException $ex) { | ||||
| $display_command = csprintf( | $display_command = csprintf( | ||||
| 'git fetch %R %R', | 'git fetch %R %R', | ||||
| $ref_uri, | $ref_uri, | ||||
| $ref_ref); | $ref_ref); | ||||
| $error = DrydockCommandError::newFromCommandException($ex) | $error = DrydockCommandError::newFromCommandException($ex) | ||||
| ->setPhase(self::PHASE_REMOTEFETCH) | ->setPhase(self::PHASE_REMOTEFETCH) | ||||
| ▲ Show 20 Lines • Show All 197 Lines • ▼ Show 20 Lines | final class DrydockWorkingCopyBlueprintImplementation | ||||
| public function getCommandError(DrydockLease $lease) { | public function getCommandError(DrydockLease $lease) { | ||||
| return $lease->getAttribute('workingcopy.vcs.error'); | return $lease->getAttribute('workingcopy.vcs.error'); | ||||
| } | } | ||||
| private function execxv( | private function execxv( | ||||
| DrydockCommandInterface $interface, | DrydockCommandInterface $interface, | ||||
| array $commands, | array $commands, | ||||
| array $arguments) { | array $arguments) { | ||||
| return $this->newExecvFuture($interface, $commands, $arguments)->resolvex(); | |||||
| } | |||||
| private function newExecvFuture( | |||||
| DrydockCommandInterface $interface, | |||||
| array $commands, | |||||
| array $arguments) { | |||||
| $commands = implode(' && ', $commands); | $commands = implode(' && ', $commands); | ||||
| $argv = array_merge(array($commands), $arguments); | $argv = array_merge(array($commands), $arguments); | ||||
| return call_user_func_array(array($interface, 'execx'), $argv); | return call_user_func_array(array($interface, 'getExecFuture'), $argv); | ||||
| } | } | ||||
| } | } | ||||
Could this result in a collision? Or are these directories already guaranteed to be unique?