From 31e11a97d2c59b0f00478d1e6257dc848e97f34e Mon Sep 17 00:00:00 2001 From: epriestley Date: Sat, 25 Jan 2014 14:02:09 -0800 Subject: [PATCH] If repository mirroring fails, keep trying the other mirrors Summary: Ref T4338. Currently, if you have several mirrors and the first one fails, we won't try the other mirrors (since we'll throw and that will take us out of the mirroring process). Instead, try each mirror even if one fails, and then throw an AggregateException with all the failures. Test Plan: - Ran `bin/repository mirror` normally. - Faked an exception, ran again, got the AggregateException I expected. Reviewers: btrahan Reviewed By: btrahan CC: aran Maniphest Tasks: T4338 Differential Revision: https://secure.phabricator.com/D8067 --- .../PhabricatorRepositoryMirrorEngine.php | 50 +++++++++++++------ 1 file changed, 35 insertions(+), 15 deletions(-) diff --git a/src/applications/repository/engine/PhabricatorRepositoryMirrorEngine.php b/src/applications/repository/engine/PhabricatorRepositoryMirrorEngine.php index 058ef3f1f8..5d69644e7b 100644 --- a/src/applications/repository/engine/PhabricatorRepositoryMirrorEngine.php +++ b/src/applications/repository/engine/PhabricatorRepositoryMirrorEngine.php @@ -18,6 +18,28 @@ final class PhabricatorRepositoryMirrorEngine ->withRepositoryPHIDs(array($repository->getPHID())) ->execute(); + $exceptions = array(); + foreach ($mirrors as $mirror) { + try { + $this->pushRepositoryToMirror($repository, $mirror); + } catch (Exception $ex) { + $exceptions[] = $ex; + } + } + + if ($exceptions) { + throw new PhutilAggregateException( + pht( + 'Exceptions occurred while mirroring the "%s" repository.', + $repository->getCallsign()), + $exceptions); + } + } + + private function pushRepositoryToMirror( + PhabricatorRepository $repository, + PhabricatorRepositoryMirror $mirror) { + // TODO: This is a little bit janky, but we don't have first-class // infrastructure for running remote commands against an arbitrary remote // right now. Just make an emphemeral copy of the repository and muck with @@ -28,24 +50,22 @@ final class PhabricatorRepositoryMirrorEngine $proxy->makeEphemeral(); $proxy->setDetail('hosting-enabled', false); - foreach ($mirrors as $mirror) { - $proxy->setDetail('remote-uri', $mirror->getRemoteURI()); - $proxy->setCredentialPHID($mirror->getCredentialPHID()); + $proxy->setDetail('remote-uri', $mirror->getRemoteURI()); + $proxy->setCredentialPHID($mirror->getCredentialPHID()); - $this->log(pht('Pushing to remote "%s"...', $mirror->getRemoteURI())); + $this->log(pht('Pushing to remote "%s"...', $mirror->getRemoteURI())); - if (!$proxy->isGit()) { - throw new Exception('Unsupported VCS!'); - } - - $future = $proxy->getRemoteCommandFuture( - 'push --verbose --mirror -- %P', - $proxy->getRemoteURIEnvelope()); - - $future - ->setCWD($proxy->getLocalPath()) - ->resolvex(); + if (!$proxy->isGit()) { + throw new Exception(pht('Unsupported VCS!')); } + + $future = $proxy->getRemoteCommandFuture( + 'push --verbose --mirror -- %P', + $proxy->getRemoteURIEnvelope()); + + $future + ->setCWD($proxy->getLocalPath()) + ->resolvex(); } }