mirror of
https://we.phorge.it/source/phorge.git
synced 2025-01-02 02:40:58 +01:00
Separate repository mirroring into an Engine and provide bin/repository mirror
Summary: Ref T4338. Currently, there's no diagnostic command to execute mirroring (so I can't give users an easy command to run), and it's roughly the last piece of real logic left in the PullLocal daemon. Separate mirroring out, and provide `bin/repository mirror`. Test Plan: - Ran `bin/repository mirror` to mirror a repository. - Ran PullLocalDaemon and verified it also continued mirroring normally. Reviewers: btrahan Reviewed By: btrahan CC: aran Maniphest Tasks: T4338 Differential Revision: https://secure.phabricator.com/D8066
This commit is contained in:
parent
f007ed6263
commit
dd944f7d83
5 changed files with 121 additions and 44 deletions
|
@ -1860,12 +1860,14 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorRepositoryManagementListWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementListWorkflow.php',
|
'PhabricatorRepositoryManagementListWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementListWorkflow.php',
|
||||||
'PhabricatorRepositoryManagementLookupUsersWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementLookupUsersWorkflow.php',
|
'PhabricatorRepositoryManagementLookupUsersWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementLookupUsersWorkflow.php',
|
||||||
'PhabricatorRepositoryManagementMarkImportedWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementMarkImportedWorkflow.php',
|
'PhabricatorRepositoryManagementMarkImportedWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementMarkImportedWorkflow.php',
|
||||||
|
'PhabricatorRepositoryManagementMirrorWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementMirrorWorkflow.php',
|
||||||
'PhabricatorRepositoryManagementPullWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementPullWorkflow.php',
|
'PhabricatorRepositoryManagementPullWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementPullWorkflow.php',
|
||||||
'PhabricatorRepositoryManagementRefsWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementRefsWorkflow.php',
|
'PhabricatorRepositoryManagementRefsWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementRefsWorkflow.php',
|
||||||
'PhabricatorRepositoryManagementWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementWorkflow.php',
|
'PhabricatorRepositoryManagementWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementWorkflow.php',
|
||||||
'PhabricatorRepositoryMercurialCommitChangeParserWorker' => 'applications/repository/worker/commitchangeparser/PhabricatorRepositoryMercurialCommitChangeParserWorker.php',
|
'PhabricatorRepositoryMercurialCommitChangeParserWorker' => 'applications/repository/worker/commitchangeparser/PhabricatorRepositoryMercurialCommitChangeParserWorker.php',
|
||||||
'PhabricatorRepositoryMercurialCommitMessageParserWorker' => 'applications/repository/worker/commitmessageparser/PhabricatorRepositoryMercurialCommitMessageParserWorker.php',
|
'PhabricatorRepositoryMercurialCommitMessageParserWorker' => 'applications/repository/worker/commitmessageparser/PhabricatorRepositoryMercurialCommitMessageParserWorker.php',
|
||||||
'PhabricatorRepositoryMirror' => 'applications/repository/storage/PhabricatorRepositoryMirror.php',
|
'PhabricatorRepositoryMirror' => 'applications/repository/storage/PhabricatorRepositoryMirror.php',
|
||||||
|
'PhabricatorRepositoryMirrorEngine' => 'applications/repository/engine/PhabricatorRepositoryMirrorEngine.php',
|
||||||
'PhabricatorRepositoryMirrorQuery' => 'applications/repository/query/PhabricatorRepositoryMirrorQuery.php',
|
'PhabricatorRepositoryMirrorQuery' => 'applications/repository/query/PhabricatorRepositoryMirrorQuery.php',
|
||||||
'PhabricatorRepositoryPHIDTypeArcanistProject' => 'applications/repository/phid/PhabricatorRepositoryPHIDTypeArcanistProject.php',
|
'PhabricatorRepositoryPHIDTypeArcanistProject' => 'applications/repository/phid/PhabricatorRepositoryPHIDTypeArcanistProject.php',
|
||||||
'PhabricatorRepositoryPHIDTypeCommit' => 'applications/repository/phid/PhabricatorRepositoryPHIDTypeCommit.php',
|
'PhabricatorRepositoryPHIDTypeCommit' => 'applications/repository/phid/PhabricatorRepositoryPHIDTypeCommit.php',
|
||||||
|
@ -4539,6 +4541,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorRepositoryManagementListWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
|
'PhabricatorRepositoryManagementListWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
|
||||||
'PhabricatorRepositoryManagementLookupUsersWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
|
'PhabricatorRepositoryManagementLookupUsersWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
|
||||||
'PhabricatorRepositoryManagementMarkImportedWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
|
'PhabricatorRepositoryManagementMarkImportedWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
|
||||||
|
'PhabricatorRepositoryManagementMirrorWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
|
||||||
'PhabricatorRepositoryManagementPullWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
|
'PhabricatorRepositoryManagementPullWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
|
||||||
'PhabricatorRepositoryManagementRefsWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
|
'PhabricatorRepositoryManagementRefsWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
|
||||||
'PhabricatorRepositoryManagementWorkflow' => 'PhabricatorManagementWorkflow',
|
'PhabricatorRepositoryManagementWorkflow' => 'PhabricatorManagementWorkflow',
|
||||||
|
@ -4549,6 +4552,7 @@ phutil_register_library_map(array(
|
||||||
0 => 'PhabricatorRepositoryDAO',
|
0 => 'PhabricatorRepositoryDAO',
|
||||||
1 => 'PhabricatorPolicyInterface',
|
1 => 'PhabricatorPolicyInterface',
|
||||||
),
|
),
|
||||||
|
'PhabricatorRepositoryMirrorEngine' => 'PhabricatorRepositoryEngine',
|
||||||
'PhabricatorRepositoryMirrorQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
'PhabricatorRepositoryMirrorQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||||
'PhabricatorRepositoryPHIDTypeArcanistProject' => 'PhabricatorPHIDType',
|
'PhabricatorRepositoryPHIDTypeArcanistProject' => 'PhabricatorPHIDType',
|
||||||
'PhabricatorRepositoryPHIDTypeCommit' => 'PhabricatorPHIDType',
|
'PhabricatorRepositoryPHIDTypeCommit' => 'PhabricatorPHIDType',
|
||||||
|
|
|
@ -141,6 +141,7 @@ final class PhabricatorRepositoryPullLocalDaemon
|
||||||
null);
|
null);
|
||||||
$this->discoverRepository($repository);
|
$this->discoverRepository($repository);
|
||||||
$this->updateRepositoryRefs($repository);
|
$this->updateRepositoryRefs($repository);
|
||||||
|
$this->mirrorRepository($repository);
|
||||||
$repository->writeStatusMessage(
|
$repository->writeStatusMessage(
|
||||||
PhabricatorRepositoryStatusMessage::TYPE_FETCH,
|
PhabricatorRepositoryStatusMessage::TYPE_FETCH,
|
||||||
PhabricatorRepositoryStatusMessage::CODE_OKAY);
|
PhabricatorRepositoryStatusMessage::CODE_OKAY);
|
||||||
|
@ -229,21 +230,25 @@ final class PhabricatorRepositoryPullLocalDaemon
|
||||||
|
|
||||||
$this->checkIfRepositoryIsFullyImported($repository);
|
$this->checkIfRepositoryIsFullyImported($repository);
|
||||||
|
|
||||||
|
return (bool)count($refs);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function mirrorRepository(PhabricatorRepository $repository) {
|
||||||
try {
|
try {
|
||||||
$this->pushToMirrors($repository);
|
id(new PhabricatorRepositoryMirrorEngine())
|
||||||
|
->setRepository($repository)
|
||||||
|
->pushToMirrors();
|
||||||
} catch (Exception $ex) {
|
} catch (Exception $ex) {
|
||||||
// TODO: We should report these into the UI properly, but for
|
// TODO: We should report these into the UI properly, but for
|
||||||
// now just complain. These errors are much less severe than
|
// now just complain. These errors are much less severe than
|
||||||
// pull errors.
|
// pull errors.
|
||||||
$proxy = new PhutilProxyException(
|
$proxy = new PhutilProxyException(
|
||||||
pht(
|
pht(
|
||||||
'Error while pushing "%s" repository to a mirror.',
|
'Error while pushing "%s" repository to mirrors.',
|
||||||
$repository->getCallsign()),
|
$repository->getCallsign()),
|
||||||
$ex);
|
$ex);
|
||||||
phlog($proxy);
|
phlog($proxy);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (bool)count($refs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function updateRepositoryRefs(PhabricatorRepository $repository) {
|
private function updateRepositoryRefs(PhabricatorRepository $repository) {
|
||||||
|
@ -299,44 +304,4 @@ final class PhabricatorRepositoryPullLocalDaemon
|
||||||
$repository->saveTransaction();
|
$repository->saveTransaction();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private function pushToMirrors(PhabricatorRepository $repository) {
|
|
||||||
if (!$repository->canMirror()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$mirrors = id(new PhabricatorRepositoryMirrorQuery())
|
|
||||||
->setViewer($this->getViewer())
|
|
||||||
->withRepositoryPHIDs(array($repository->getPHID()))
|
|
||||||
->execute();
|
|
||||||
|
|
||||||
// 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
|
|
||||||
// it a little bit. In the medium term, we should pull this command stuff
|
|
||||||
// out and use it here and for "Land to ...".
|
|
||||||
|
|
||||||
$proxy = clone $repository;
|
|
||||||
$proxy->makeEphemeral();
|
|
||||||
|
|
||||||
$proxy->setDetail('hosting-enabled', false);
|
|
||||||
foreach ($mirrors as $mirror) {
|
|
||||||
$proxy->setDetail('remote-uri', $mirror->getRemoteURI());
|
|
||||||
$proxy->setCredentialPHID($mirror->getCredentialPHID());
|
|
||||||
|
|
||||||
$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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,6 +47,11 @@ abstract class PhabricatorRepositoryEngine {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function getViewer() {
|
||||||
|
return PhabricatorUser::getOmnipotentUser();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @task internal
|
* @task internal
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -0,0 +1,51 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pushes a repository to its mirrors.
|
||||||
|
*/
|
||||||
|
final class PhabricatorRepositoryMirrorEngine
|
||||||
|
extends PhabricatorRepositoryEngine {
|
||||||
|
|
||||||
|
public function pushToMirrors() {
|
||||||
|
$repository = $this->getRepository();
|
||||||
|
|
||||||
|
if (!$repository->canMirror()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$mirrors = id(new PhabricatorRepositoryMirrorQuery())
|
||||||
|
->setViewer($this->getViewer())
|
||||||
|
->withRepositoryPHIDs(array($repository->getPHID()))
|
||||||
|
->execute();
|
||||||
|
|
||||||
|
// 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
|
||||||
|
// it a little bit. In the medium term, we should pull this command stuff
|
||||||
|
// out and use it here and for "Land to ...".
|
||||||
|
|
||||||
|
$proxy = clone $repository;
|
||||||
|
$proxy->makeEphemeral();
|
||||||
|
|
||||||
|
$proxy->setDetail('hosting-enabled', false);
|
||||||
|
foreach ($mirrors as $mirror) {
|
||||||
|
$proxy->setDetail('remote-uri', $mirror->getRemoteURI());
|
||||||
|
$proxy->setCredentialPHID($mirror->getCredentialPHID());
|
||||||
|
|
||||||
|
$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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,52 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorRepositoryManagementMirrorWorkflow
|
||||||
|
extends PhabricatorRepositoryManagementWorkflow {
|
||||||
|
|
||||||
|
public function didConstruct() {
|
||||||
|
$this
|
||||||
|
->setName('mirror')
|
||||||
|
->setExamples('**mirror** [__options__] __repository__ ...')
|
||||||
|
->setSynopsis(
|
||||||
|
pht('Push __repository__, named by callsign, to mirrors.'))
|
||||||
|
->setArguments(
|
||||||
|
array(
|
||||||
|
array(
|
||||||
|
'name' => 'verbose',
|
||||||
|
'help' => pht('Show additional debugging information.'),
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'name' => 'repos',
|
||||||
|
'wildcard' => true,
|
||||||
|
),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function execute(PhutilArgumentParser $args) {
|
||||||
|
$repos = $this->loadRepositories($args, 'repos');
|
||||||
|
|
||||||
|
if (!$repos) {
|
||||||
|
throw new PhutilArgumentUsageException(
|
||||||
|
pht(
|
||||||
|
"Specify one or more repositories to push to mirrors, by ".
|
||||||
|
"callsign."));
|
||||||
|
}
|
||||||
|
|
||||||
|
$console = PhutilConsole::getConsole();
|
||||||
|
foreach ($repos as $repo) {
|
||||||
|
$console->writeOut(
|
||||||
|
"%s\n",
|
||||||
|
pht('Pushing "%s" to mirrors...', $repo->getCallsign()));
|
||||||
|
|
||||||
|
$engine = id(new PhabricatorRepositoryMirrorEngine())
|
||||||
|
->setRepository($repo)
|
||||||
|
->setVerbose($args->getArg('verbose'))
|
||||||
|
->pushToMirrors();
|
||||||
|
}
|
||||||
|
|
||||||
|
$console->writeOut("Done.\n");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in a new issue