mirror of
https://we.phorge.it/source/phorge.git
synced 2024-12-18 19:40:55 +01:00
Cut mirroring over to new URIs
Summary: Ref T10748. This migrates and swaps mirroring to `PhabricatorRepositoryURI`, obsoleting `PhabricatorRepositoryMirror`. This prevents you from editing, adding or disabling mirrors unless you know a secret URI (until the UI cuts over fully), but existing mirroring is not affected. Test Plan: - Added a mirroring URI to an old repository. - Verified it worked with `bin/repository mirror`. - Migrated forward. - Verified it still worked with `bin/repository mirror`. - Wow, mirroring: https://github.com/epriestley/locktopia-mirror Reviewers: chad Reviewed By: chad Maniphest Tasks: T10748 Differential Revision: https://secure.phabricator.com/D15841
This commit is contained in:
parent
34e870819c
commit
42eaa88f80
13 changed files with 126 additions and 534 deletions
38
resources/sql/autopatches/20160503.repo.04.mirrormigrate.php
Normal file
38
resources/sql/autopatches/20160503.repo.04.mirrormigrate.php
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
$table = new PhabricatorRepository();
|
||||||
|
$conn_w = $table->establishConnection('w');
|
||||||
|
|
||||||
|
$mirrors = queryfx_all(
|
||||||
|
$conn_w,
|
||||||
|
'SELECT * FROM %T',
|
||||||
|
'repository_mirror');
|
||||||
|
|
||||||
|
foreach ($mirrors as $mirror) {
|
||||||
|
$repository_phid = $mirror['repositoryPHID'];
|
||||||
|
$uri = $mirror['remoteURI'];
|
||||||
|
|
||||||
|
$already_exists = id(new PhabricatorRepositoryURI())->loadOneWhere(
|
||||||
|
'repositoryPHID = %s AND uri = %s',
|
||||||
|
$repository_phid,
|
||||||
|
$uri);
|
||||||
|
if ($already_exists) {
|
||||||
|
// Decline to migrate stuff that looks like it was already migrated.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$new_uri = PhabricatorRepositoryURI::initializeNewURI()
|
||||||
|
->setIOType(PhabricatorRepositoryURI::IO_MIRROR)
|
||||||
|
->setRepositoryPHID($repository_phid)
|
||||||
|
->setURI($uri)
|
||||||
|
->setCredentialPHID($mirror['credentialPHID'])
|
||||||
|
->setDateCreated($mirror['dateCreated'])
|
||||||
|
->setDateModified($mirror['dateModified'])
|
||||||
|
->save();
|
||||||
|
|
||||||
|
echo tsprintf(
|
||||||
|
"%s\n",
|
||||||
|
pht(
|
||||||
|
'Migrated mirror "%s".',
|
||||||
|
$uri));
|
||||||
|
}
|
|
@ -682,8 +682,6 @@ phutil_register_library_map(array(
|
||||||
'DiffusionMercurialWireProtocolTests' => 'applications/diffusion/protocol/__tests__/DiffusionMercurialWireProtocolTests.php',
|
'DiffusionMercurialWireProtocolTests' => 'applications/diffusion/protocol/__tests__/DiffusionMercurialWireProtocolTests.php',
|
||||||
'DiffusionMercurialWireSSHTestCase' => 'applications/diffusion/ssh/__tests__/DiffusionMercurialWireSSHTestCase.php',
|
'DiffusionMercurialWireSSHTestCase' => 'applications/diffusion/ssh/__tests__/DiffusionMercurialWireSSHTestCase.php',
|
||||||
'DiffusionMergedCommitsQueryConduitAPIMethod' => 'applications/diffusion/conduit/DiffusionMergedCommitsQueryConduitAPIMethod.php',
|
'DiffusionMergedCommitsQueryConduitAPIMethod' => 'applications/diffusion/conduit/DiffusionMergedCommitsQueryConduitAPIMethod.php',
|
||||||
'DiffusionMirrorDeleteController' => 'applications/diffusion/controller/DiffusionMirrorDeleteController.php',
|
|
||||||
'DiffusionMirrorEditController' => 'applications/diffusion/controller/DiffusionMirrorEditController.php',
|
|
||||||
'DiffusionPathChange' => 'applications/diffusion/data/DiffusionPathChange.php',
|
'DiffusionPathChange' => 'applications/diffusion/data/DiffusionPathChange.php',
|
||||||
'DiffusionPathChangeQuery' => 'applications/diffusion/query/pathchange/DiffusionPathChangeQuery.php',
|
'DiffusionPathChangeQuery' => 'applications/diffusion/query/pathchange/DiffusionPathChangeQuery.php',
|
||||||
'DiffusionPathCompleteController' => 'applications/diffusion/controller/DiffusionPathCompleteController.php',
|
'DiffusionPathCompleteController' => 'applications/diffusion/controller/DiffusionPathCompleteController.php',
|
||||||
|
@ -3208,8 +3206,6 @@ phutil_register_library_map(array(
|
||||||
'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',
|
'PhabricatorRepositoryMirrorEngine' => 'applications/repository/engine/PhabricatorRepositoryMirrorEngine.php',
|
||||||
'PhabricatorRepositoryMirrorPHIDType' => 'applications/repository/phid/PhabricatorRepositoryMirrorPHIDType.php',
|
|
||||||
'PhabricatorRepositoryMirrorQuery' => 'applications/repository/query/PhabricatorRepositoryMirrorQuery.php',
|
|
||||||
'PhabricatorRepositoryParsedChange' => 'applications/repository/data/PhabricatorRepositoryParsedChange.php',
|
'PhabricatorRepositoryParsedChange' => 'applications/repository/data/PhabricatorRepositoryParsedChange.php',
|
||||||
'PhabricatorRepositoryPullEngine' => 'applications/repository/engine/PhabricatorRepositoryPullEngine.php',
|
'PhabricatorRepositoryPullEngine' => 'applications/repository/engine/PhabricatorRepositoryPullEngine.php',
|
||||||
'PhabricatorRepositoryPullEvent' => 'applications/repository/storage/PhabricatorRepositoryPullEvent.php',
|
'PhabricatorRepositoryPullEvent' => 'applications/repository/storage/PhabricatorRepositoryPullEvent.php',
|
||||||
|
@ -4914,8 +4910,6 @@ phutil_register_library_map(array(
|
||||||
'DiffusionMercurialWireProtocolTests' => 'PhabricatorTestCase',
|
'DiffusionMercurialWireProtocolTests' => 'PhabricatorTestCase',
|
||||||
'DiffusionMercurialWireSSHTestCase' => 'PhabricatorTestCase',
|
'DiffusionMercurialWireSSHTestCase' => 'PhabricatorTestCase',
|
||||||
'DiffusionMergedCommitsQueryConduitAPIMethod' => 'DiffusionQueryConduitAPIMethod',
|
'DiffusionMergedCommitsQueryConduitAPIMethod' => 'DiffusionQueryConduitAPIMethod',
|
||||||
'DiffusionMirrorDeleteController' => 'DiffusionController',
|
|
||||||
'DiffusionMirrorEditController' => 'DiffusionController',
|
|
||||||
'DiffusionPathChange' => 'Phobject',
|
'DiffusionPathChange' => 'Phobject',
|
||||||
'DiffusionPathChangeQuery' => 'Phobject',
|
'DiffusionPathChangeQuery' => 'Phobject',
|
||||||
'DiffusionPathCompleteController' => 'DiffusionController',
|
'DiffusionPathCompleteController' => 'DiffusionController',
|
||||||
|
@ -7882,13 +7876,8 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorRepositoryManagementWorkflow' => 'PhabricatorManagementWorkflow',
|
'PhabricatorRepositoryManagementWorkflow' => 'PhabricatorManagementWorkflow',
|
||||||
'PhabricatorRepositoryMercurialCommitChangeParserWorker' => 'PhabricatorRepositoryCommitChangeParserWorker',
|
'PhabricatorRepositoryMercurialCommitChangeParserWorker' => 'PhabricatorRepositoryCommitChangeParserWorker',
|
||||||
'PhabricatorRepositoryMercurialCommitMessageParserWorker' => 'PhabricatorRepositoryCommitMessageParserWorker',
|
'PhabricatorRepositoryMercurialCommitMessageParserWorker' => 'PhabricatorRepositoryCommitMessageParserWorker',
|
||||||
'PhabricatorRepositoryMirror' => array(
|
'PhabricatorRepositoryMirror' => 'PhabricatorRepositoryDAO',
|
||||||
'PhabricatorRepositoryDAO',
|
|
||||||
'PhabricatorPolicyInterface',
|
|
||||||
),
|
|
||||||
'PhabricatorRepositoryMirrorEngine' => 'PhabricatorRepositoryEngine',
|
'PhabricatorRepositoryMirrorEngine' => 'PhabricatorRepositoryEngine',
|
||||||
'PhabricatorRepositoryMirrorPHIDType' => 'PhabricatorPHIDType',
|
|
||||||
'PhabricatorRepositoryMirrorQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
|
||||||
'PhabricatorRepositoryParsedChange' => 'Phobject',
|
'PhabricatorRepositoryParsedChange' => 'Phobject',
|
||||||
'PhabricatorRepositoryPullEngine' => 'PhabricatorRepositoryEngine',
|
'PhabricatorRepositoryPullEngine' => 'PhabricatorRepositoryEngine',
|
||||||
'PhabricatorRepositoryPullEvent' => array(
|
'PhabricatorRepositoryPullEvent' => array(
|
||||||
|
|
|
@ -122,10 +122,6 @@ final class PhabricatorDiffusionApplication extends PhabricatorApplication {
|
||||||
'testautomation/' => 'DiffusionRepositoryTestAutomationController',
|
'testautomation/' => 'DiffusionRepositoryTestAutomationController',
|
||||||
),
|
),
|
||||||
'pathtree/(?P<dblob>.*)' => 'DiffusionPathTreeController',
|
'pathtree/(?P<dblob>.*)' => 'DiffusionPathTreeController',
|
||||||
'mirror/' => array(
|
|
||||||
'edit/(?:(?P<id>\d+)/)?' => 'DiffusionMirrorEditController',
|
|
||||||
'delete/(?P<id>\d+)/' => 'DiffusionMirrorDeleteController',
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
|
|
||||||
// NOTE: This must come after the rule above; it just gives us a
|
// NOTE: This must come after the rule above; it just gives us a
|
||||||
|
|
|
@ -1,45 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
final class DiffusionMirrorDeleteController
|
|
||||||
extends DiffusionController {
|
|
||||||
|
|
||||||
public function handleRequest(AphrontRequest $request) {
|
|
||||||
$response = $this->loadDiffusionContext();
|
|
||||||
if ($response) {
|
|
||||||
return $response;
|
|
||||||
}
|
|
||||||
|
|
||||||
$viewer = $this->getViewer();
|
|
||||||
$drequest = $this->getDiffusionRequest();
|
|
||||||
$repository = $drequest->getRepository();
|
|
||||||
|
|
||||||
$mirror = id(new PhabricatorRepositoryMirrorQuery())
|
|
||||||
->setViewer($viewer)
|
|
||||||
->withIDs(array($request->getURIData('id')))
|
|
||||||
->requireCapabilities(
|
|
||||||
array(
|
|
||||||
PhabricatorPolicyCapability::CAN_VIEW,
|
|
||||||
PhabricatorPolicyCapability::CAN_EDIT,
|
|
||||||
))
|
|
||||||
->executeOne();
|
|
||||||
if (!$mirror) {
|
|
||||||
return new Aphront404Response();
|
|
||||||
}
|
|
||||||
|
|
||||||
$edit_uri = $this->getRepositoryControllerURI($repository, 'edit/#mirrors');
|
|
||||||
|
|
||||||
if ($request->isFormPost()) {
|
|
||||||
$mirror->delete();
|
|
||||||
return id(new AphrontReloadResponse())->setURI($edit_uri);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->newDialog()
|
|
||||||
->setTitle(pht('Really delete mirror?'))
|
|
||||||
->appendChild(
|
|
||||||
pht('Phabricator will stop pushing updates to this mirror.'))
|
|
||||||
->addSubmitButton(pht('Delete Mirror'))
|
|
||||||
->addCancelButton($edit_uri);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,130 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
final class DiffusionMirrorEditController
|
|
||||||
extends DiffusionController {
|
|
||||||
|
|
||||||
public function handleRequest(AphrontRequest $request) {
|
|
||||||
$response = $this->loadDiffusionContext();
|
|
||||||
if ($response) {
|
|
||||||
return $response;
|
|
||||||
}
|
|
||||||
|
|
||||||
$viewer = $this->getViewer();
|
|
||||||
$drequest = $this->getDiffusionRequest();
|
|
||||||
$repository = $drequest->getRepository();
|
|
||||||
|
|
||||||
PhabricatorPolicyFilter::requireCapability(
|
|
||||||
$viewer,
|
|
||||||
$repository,
|
|
||||||
PhabricatorPolicyCapability::CAN_EDIT);
|
|
||||||
|
|
||||||
if ($request->getURIData('id')) {
|
|
||||||
$mirror = id(new PhabricatorRepositoryMirrorQuery())
|
|
||||||
->setViewer($viewer)
|
|
||||||
->withIDs(array($request->getURIData('id')))
|
|
||||||
->requireCapabilities(
|
|
||||||
array(
|
|
||||||
PhabricatorPolicyCapability::CAN_VIEW,
|
|
||||||
PhabricatorPolicyCapability::CAN_EDIT,
|
|
||||||
))
|
|
||||||
->executeOne();
|
|
||||||
if (!$mirror) {
|
|
||||||
return new Aphront404Response();
|
|
||||||
}
|
|
||||||
$is_new = false;
|
|
||||||
} else {
|
|
||||||
$mirror = PhabricatorRepositoryMirror::initializeNewMirror($viewer)
|
|
||||||
->setRepositoryPHID($repository->getPHID())
|
|
||||||
->attachRepository($repository);
|
|
||||||
$is_new = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
$edit_uri = $this->getRepositoryControllerURI($repository, 'edit/#mirrors');
|
|
||||||
|
|
||||||
$v_remote = $mirror->getRemoteURI();
|
|
||||||
$e_remote = true;
|
|
||||||
|
|
||||||
$v_credentials = $mirror->getCredentialPHID();
|
|
||||||
$e_credentials = null;
|
|
||||||
|
|
||||||
$credentials = id(new PassphraseCredentialQuery())
|
|
||||||
->setViewer($viewer)
|
|
||||||
->withIsDestroyed(false)
|
|
||||||
->execute();
|
|
||||||
|
|
||||||
$errors = array();
|
|
||||||
if ($request->isFormPost()) {
|
|
||||||
$v_remote = $request->getStr('remoteURI');
|
|
||||||
if (strlen($v_remote)) {
|
|
||||||
try {
|
|
||||||
PhabricatorRepository::assertValidRemoteURI($v_remote);
|
|
||||||
$e_remote = null;
|
|
||||||
} catch (Exception $ex) {
|
|
||||||
$e_remote = pht('Invalid');
|
|
||||||
$errors[] = $ex->getMessage();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$e_remote = pht('Required');
|
|
||||||
$errors[] = pht('You must provide a remote URI.');
|
|
||||||
}
|
|
||||||
|
|
||||||
$v_credentials = $request->getStr('credential');
|
|
||||||
if ($v_credentials) {
|
|
||||||
$phids = mpull($credentials, null, 'getPHID');
|
|
||||||
if (empty($phids[$v_credentials])) {
|
|
||||||
$e_credentials = pht('Invalid');
|
|
||||||
$errors[] = pht(
|
|
||||||
'You do not have permission to use those credentials.');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!$errors) {
|
|
||||||
$mirror
|
|
||||||
->setRemoteURI($v_remote)
|
|
||||||
->setCredentialPHID($v_credentials)
|
|
||||||
->save();
|
|
||||||
return id(new AphrontReloadResponse())->setURI($edit_uri);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$form_errors = null;
|
|
||||||
if ($errors) {
|
|
||||||
$form_errors = id(new PHUIInfoView())
|
|
||||||
->setErrors($errors);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($is_new) {
|
|
||||||
$title = pht('Create Mirror');
|
|
||||||
$submit = pht('Create Mirror');
|
|
||||||
} else {
|
|
||||||
$title = pht('Edit Mirror');
|
|
||||||
$submit = pht('Save Changes');
|
|
||||||
}
|
|
||||||
|
|
||||||
$form = id(new PHUIFormLayoutView())
|
|
||||||
->appendChild(
|
|
||||||
id(new AphrontFormTextControl())
|
|
||||||
->setLabel(pht('Remote URI'))
|
|
||||||
->setName('remoteURI')
|
|
||||||
->setValue($v_remote)
|
|
||||||
->setError($e_remote))
|
|
||||||
->appendControl(
|
|
||||||
id(new PassphraseCredentialControl())
|
|
||||||
->setLabel(pht('Credentials'))
|
|
||||||
->setName('credential')
|
|
||||||
->setAllowNull(true)
|
|
||||||
->setValue($v_credentials)
|
|
||||||
->setError($e_credentials)
|
|
||||||
->setOptions($credentials));
|
|
||||||
|
|
||||||
return $this->newDialog()
|
|
||||||
->setTitle($title)
|
|
||||||
->setWidth(AphrontDialogView::WIDTH_FORM)
|
|
||||||
->appendChild($form_errors)
|
|
||||||
->appendChild($form)
|
|
||||||
->addSubmitButton($submit)
|
|
||||||
->addCancelButton($edit_uri);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
|
@ -129,37 +129,6 @@ final class DiffusionRepositoryEditMainController
|
||||||
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||||
->addPropertyList($hosting_properties);
|
->addPropertyList($hosting_properties);
|
||||||
|
|
||||||
if ($repository->canMirror()) {
|
|
||||||
$mirror_actions = $this->buildMirrorActions($repository);
|
|
||||||
$mirror_properties = $this->buildMirrorProperties(
|
|
||||||
$repository,
|
|
||||||
$mirror_actions);
|
|
||||||
|
|
||||||
$mirrors = id(new PhabricatorRepositoryMirrorQuery())
|
|
||||||
->setViewer($viewer)
|
|
||||||
->withRepositoryPHIDs(array($repository->getPHID()))
|
|
||||||
->execute();
|
|
||||||
|
|
||||||
$mirror_list = $this->buildMirrorList($repository, $mirrors);
|
|
||||||
|
|
||||||
$boxes[] = id(new PhabricatorAnchorView())->setAnchorName('mirrors');
|
|
||||||
|
|
||||||
$mirror_info = array();
|
|
||||||
if (PhabricatorEnv::getEnvConfig('phabricator.silent')) {
|
|
||||||
$mirror_info[] = pht(
|
|
||||||
'Phabricator is running in silent mode, so changes will not '.
|
|
||||||
'be pushed to mirrors.');
|
|
||||||
}
|
|
||||||
|
|
||||||
$boxes[] = id(new PHUIObjectBoxView())
|
|
||||||
->setFormErrors($mirror_info)
|
|
||||||
->setHeaderText(pht('Mirrors'))
|
|
||||||
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
|
||||||
->addPropertyList($mirror_properties);
|
|
||||||
|
|
||||||
$boxes[] = $mirror_list;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($remote_properties) {
|
if ($remote_properties) {
|
||||||
$boxes[] = id(new PHUIObjectBoxView())
|
$boxes[] = id(new PHUIObjectBoxView())
|
||||||
->setHeaderText(pht('Remote'))
|
->setHeaderText(pht('Remote'))
|
||||||
|
@ -1193,90 +1162,6 @@ final class DiffusionRepositoryEditMainController
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private function buildMirrorActions(
|
|
||||||
PhabricatorRepository $repository) {
|
|
||||||
|
|
||||||
$viewer = $this->getViewer();
|
|
||||||
|
|
||||||
$mirror_actions = id(new PhabricatorActionListView())
|
|
||||||
->setUser($viewer);
|
|
||||||
|
|
||||||
$new_mirror_uri = $this->getRepositoryControllerURI(
|
|
||||||
$repository,
|
|
||||||
'mirror/edit/');
|
|
||||||
|
|
||||||
$mirror_actions->addAction(
|
|
||||||
id(new PhabricatorActionView())
|
|
||||||
->setName(pht('Add Mirror'))
|
|
||||||
->setIcon('fa-plus')
|
|
||||||
->setHref($new_mirror_uri)
|
|
||||||
->setWorkflow(true));
|
|
||||||
|
|
||||||
return $mirror_actions;
|
|
||||||
}
|
|
||||||
|
|
||||||
private function buildMirrorProperties(
|
|
||||||
PhabricatorRepository $repository,
|
|
||||||
PhabricatorActionListView $actions) {
|
|
||||||
|
|
||||||
$viewer = $this->getViewer();
|
|
||||||
|
|
||||||
$mirror_properties = id(new PHUIPropertyListView())
|
|
||||||
->setUser($viewer)
|
|
||||||
->setActionList($actions);
|
|
||||||
|
|
||||||
$mirror_properties->addProperty(
|
|
||||||
'',
|
|
||||||
phutil_tag(
|
|
||||||
'em',
|
|
||||||
array(),
|
|
||||||
pht('Automatically push changes into other remotes.')));
|
|
||||||
|
|
||||||
return $mirror_properties;
|
|
||||||
}
|
|
||||||
|
|
||||||
private function buildMirrorList(
|
|
||||||
PhabricatorRepository $repository,
|
|
||||||
array $mirrors) {
|
|
||||||
assert_instances_of($mirrors, 'PhabricatorRepositoryMirror');
|
|
||||||
|
|
||||||
$mirror_list = id(new PHUIObjectItemListView())
|
|
||||||
->setNoDataString(pht('This repository has no configured mirrors.'));
|
|
||||||
|
|
||||||
foreach ($mirrors as $mirror) {
|
|
||||||
$item = id(new PHUIObjectItemView())
|
|
||||||
->setHeader($mirror->getRemoteURI());
|
|
||||||
|
|
||||||
$edit_uri = $this->getRepositoryControllerURI(
|
|
||||||
$repository,
|
|
||||||
'mirror/edit/'.$mirror->getID().'/');
|
|
||||||
|
|
||||||
$delete_uri = $this->getRepositoryControllerURI(
|
|
||||||
$repository,
|
|
||||||
'mirror/delete/'.$mirror->getID().'/');
|
|
||||||
|
|
||||||
$item->addAction(
|
|
||||||
id(new PHUIListItemView())
|
|
||||||
->setIcon('fa-pencil')
|
|
||||||
->setHref($edit_uri)
|
|
||||||
->setWorkflow(true));
|
|
||||||
|
|
||||||
$item->addAction(
|
|
||||||
id(new PHUIListItemView())
|
|
||||||
->setIcon('fa-times')
|
|
||||||
->setHref($delete_uri)
|
|
||||||
->setWorkflow(true));
|
|
||||||
|
|
||||||
$mirror_list->addItem($item);
|
|
||||||
}
|
|
||||||
|
|
||||||
return id(new PHUIObjectBoxView())
|
|
||||||
->setHeaderText(pht('Configured Mirrors'))
|
|
||||||
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
|
||||||
->setObjectList($mirror_list);
|
|
||||||
}
|
|
||||||
|
|
||||||
private function buildSymbolsActions(PhabricatorRepository $repository) {
|
private function buildSymbolsActions(PhabricatorRepository $repository) {
|
||||||
$viewer = $this->getViewer();
|
$viewer = $this->getViewer();
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@ final class PhabricatorRepositoryMirrorEngine
|
||||||
extends PhabricatorRepositoryEngine {
|
extends PhabricatorRepositoryEngine {
|
||||||
|
|
||||||
public function pushToMirrors() {
|
public function pushToMirrors() {
|
||||||
|
$viewer = $this->getViewer();
|
||||||
$repository = $this->getRepository();
|
$repository = $this->getRepository();
|
||||||
|
|
||||||
if (!$repository->canMirror()) {
|
if (!$repository->canMirror()) {
|
||||||
|
@ -19,13 +20,24 @@ final class PhabricatorRepositoryMirrorEngine
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$mirrors = id(new PhabricatorRepositoryMirrorQuery())
|
$uris = id(new PhabricatorRepositoryURIQuery())
|
||||||
->setViewer($this->getViewer())
|
->setViewer($viewer)
|
||||||
->withRepositoryPHIDs(array($repository->getPHID()))
|
->withRepositories(array($repository))
|
||||||
->execute();
|
->execute();
|
||||||
|
|
||||||
|
$io_mirror = PhabricatorRepositoryURI::IO_MIRROR;
|
||||||
|
|
||||||
$exceptions = array();
|
$exceptions = array();
|
||||||
foreach ($mirrors as $mirror) {
|
foreach ($uris as $mirror) {
|
||||||
|
if ($mirror->getIsDisabled()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$io_type = $mirror->getEffectiveIOType();
|
||||||
|
if ($io_type != $io_mirror) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$this->pushRepositoryToMirror($repository, $mirror);
|
$this->pushRepositoryToMirror($repository, $mirror);
|
||||||
} catch (Exception $ex) {
|
} catch (Exception $ex) {
|
||||||
|
@ -44,54 +56,56 @@ final class PhabricatorRepositoryMirrorEngine
|
||||||
|
|
||||||
private function pushRepositoryToMirror(
|
private function pushRepositoryToMirror(
|
||||||
PhabricatorRepository $repository,
|
PhabricatorRepository $repository,
|
||||||
PhabricatorRepositoryMirror $mirror) {
|
PhabricatorRepositoryURI $mirror_uri) {
|
||||||
|
|
||||||
// TODO: This is a little bit janky, but we don't have first-class
|
$this->log(
|
||||||
// infrastructure for running remote commands against an arbitrary remote
|
pht(
|
||||||
// right now. Just make an emphemeral copy of the repository and muck with
|
'Pushing to remote "%s"...',
|
||||||
// it a little bit. In the medium term, we should pull this command stuff
|
$mirror_uri->getEffectiveURI()));
|
||||||
// out and use it here and for "Land to ...".
|
|
||||||
|
|
||||||
$proxy = clone $repository;
|
if ($repository->isGit()) {
|
||||||
$proxy->makeEphemeral();
|
$this->pushToGitRepository($repository, $mirror_uri);
|
||||||
|
} else if ($repository->isHg()) {
|
||||||
$proxy->setDetail('hosting-enabled', false);
|
$this->pushToHgRepository($repository, $mirror_uri);
|
||||||
$proxy->setDetail('remote-uri', $mirror->getRemoteURI());
|
|
||||||
$proxy->setCredentialPHID($mirror->getCredentialPHID());
|
|
||||||
|
|
||||||
$this->log(pht('Pushing to remote "%s"...', $mirror->getRemoteURI()));
|
|
||||||
|
|
||||||
if ($proxy->isGit()) {
|
|
||||||
$this->pushToGitRepository($proxy);
|
|
||||||
} else if ($proxy->isHg()) {
|
|
||||||
$this->pushToHgRepository($proxy);
|
|
||||||
} else {
|
} else {
|
||||||
throw new Exception(pht('Unsupported VCS!'));
|
throw new Exception(pht('Unsupported VCS!'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private function pushToGitRepository(
|
private function pushToGitRepository(
|
||||||
PhabricatorRepository $proxy) {
|
PhabricatorRepository $repository,
|
||||||
|
PhabricatorRepositoryURI $mirror_uri) {
|
||||||
|
|
||||||
$future = $proxy->getRemoteCommandFuture(
|
$argv = array(
|
||||||
'push --verbose --mirror -- %P',
|
'push --verbose --mirror -- %P',
|
||||||
$proxy->getRemoteURIEnvelope());
|
$mirror_uri->getURIEnvelope(),
|
||||||
|
);
|
||||||
|
|
||||||
|
$future = $mirror_uri->newCommandEngine()
|
||||||
|
->setArgv($argv)
|
||||||
|
->newFuture();
|
||||||
|
|
||||||
$future
|
$future
|
||||||
->setCWD($proxy->getLocalPath())
|
->setCWD($repository->getLocalPath())
|
||||||
->resolvex();
|
->resolvex();
|
||||||
}
|
}
|
||||||
|
|
||||||
private function pushToHgRepository(
|
private function pushToHgRepository(
|
||||||
PhabricatorRepository $proxy) {
|
PhabricatorRepository $repository,
|
||||||
|
PhabricatorRepositoryURI $mirror_uri) {
|
||||||
|
|
||||||
$future = $proxy->getRemoteCommandFuture(
|
$argv = array(
|
||||||
'push --verbose --rev tip -- %P',
|
'push --verbose --rev tip -- %P',
|
||||||
$proxy->getRemoteURIEnvelope());
|
$mirror_uri->getURIEnvelope(),
|
||||||
|
);
|
||||||
|
|
||||||
|
$future = $mirror_uri->newCommandEngine()
|
||||||
|
->setArgv($argv)
|
||||||
|
->newFuture();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$future
|
$future
|
||||||
->setCWD($proxy->getLocalPath())
|
->setCWD($repository->getLocalPath())
|
||||||
->resolvex();
|
->resolvex();
|
||||||
} catch (CommandException $ex) {
|
} catch (CommandException $ex) {
|
||||||
if (preg_match('/no changes found/', $ex->getStdOut())) {
|
if (preg_match('/no changes found/', $ex->getStdOut())) {
|
||||||
|
|
|
@ -31,12 +31,11 @@ final class PhabricatorRepositoryManagementMirrorWorkflow
|
||||||
'Specify one or more repositories to push to mirrors.'));
|
'Specify one or more repositories to push to mirrors.'));
|
||||||
}
|
}
|
||||||
|
|
||||||
$console = PhutilConsole::getConsole();
|
|
||||||
foreach ($repos as $repo) {
|
foreach ($repos as $repo) {
|
||||||
$console->writeOut(
|
echo tsprintf(
|
||||||
"%s\n",
|
"%s\n",
|
||||||
pht(
|
pht(
|
||||||
"Pushing '%s' to mirrors...",
|
'Pushing "%s" to mirrors...',
|
||||||
$repo->getDisplayName()));
|
$repo->getDisplayName()));
|
||||||
|
|
||||||
$engine = id(new PhabricatorRepositoryMirrorEngine())
|
$engine = id(new PhabricatorRepositoryMirrorEngine())
|
||||||
|
@ -45,7 +44,9 @@ final class PhabricatorRepositoryManagementMirrorWorkflow
|
||||||
->pushToMirrors();
|
->pushToMirrors();
|
||||||
}
|
}
|
||||||
|
|
||||||
$console->writeOut("%s\n", pht('Done.'));
|
echo tsprintf(
|
||||||
|
"%s\n",
|
||||||
|
pht('Done.'));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,41 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
final class PhabricatorRepositoryMirrorPHIDType extends PhabricatorPHIDType {
|
|
||||||
|
|
||||||
const TYPECONST = 'RMIR';
|
|
||||||
|
|
||||||
public function getTypeName() {
|
|
||||||
return pht('Repository Mirror');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function newObject() {
|
|
||||||
return new PhabricatorRepositoryMirror();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getPHIDTypeApplicationClass() {
|
|
||||||
return 'PhabricatorDiffusionApplication';
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function buildQueryForObjects(
|
|
||||||
PhabricatorObjectQuery $query,
|
|
||||||
array $phids) {
|
|
||||||
|
|
||||||
return id(new PhabricatorRepositoryMirrorQuery())
|
|
||||||
->withPHIDs($phids);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function loadHandles(
|
|
||||||
PhabricatorHandleQuery $query,
|
|
||||||
array $handles,
|
|
||||||
array $objects) {
|
|
||||||
|
|
||||||
foreach ($handles as $phid => $handle) {
|
|
||||||
$mirror = $objects[$phid];
|
|
||||||
|
|
||||||
$handle->setName(
|
|
||||||
pht('Mirror %d %s', $mirror->getID(), $mirror->getRemoteURI()));
|
|
||||||
$handle->setURI('/diffusion/mirror/'.$mirror->getID().'/');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,99 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
final class PhabricatorRepositoryMirrorQuery
|
|
||||||
extends PhabricatorCursorPagedPolicyAwareQuery {
|
|
||||||
|
|
||||||
private $ids;
|
|
||||||
private $phids;
|
|
||||||
private $repositoryPHIDs;
|
|
||||||
|
|
||||||
public function withIDs(array $ids) {
|
|
||||||
$this->ids = $ids;
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function withPHIDs(array $phids) {
|
|
||||||
$this->phids = $phids;
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function withRepositoryPHIDs(array $repository_phids) {
|
|
||||||
$this->repositoryPHIDs = $repository_phids;
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function loadPage() {
|
|
||||||
$table = new PhabricatorRepositoryMirror();
|
|
||||||
$conn_r = $table->establishConnection('r');
|
|
||||||
|
|
||||||
$data = queryfx_all(
|
|
||||||
$conn_r,
|
|
||||||
'SELECT * FROM %T %Q %Q %Q',
|
|
||||||
$table->getTableName(),
|
|
||||||
$this->buildWhereClause($conn_r),
|
|
||||||
$this->buildOrderClause($conn_r),
|
|
||||||
$this->buildLimitClause($conn_r));
|
|
||||||
|
|
||||||
return $table->loadAllFromArray($data);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function willFilterPage(array $mirrors) {
|
|
||||||
assert_instances_of($mirrors, 'PhabricatorRepositoryMirror');
|
|
||||||
|
|
||||||
$repository_phids = mpull($mirrors, 'getRepositoryPHID');
|
|
||||||
if ($repository_phids) {
|
|
||||||
$repositories = id(new PhabricatorRepositoryQuery())
|
|
||||||
->setViewer($this->getViewer())
|
|
||||||
->withPHIDs($repository_phids)
|
|
||||||
->execute();
|
|
||||||
$repositories = mpull($repositories, null, 'getPHID');
|
|
||||||
} else {
|
|
||||||
$repositories = array();
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ($mirrors as $key => $mirror) {
|
|
||||||
$phid = $mirror->getRepositoryPHID();
|
|
||||||
if (empty($repositories[$phid])) {
|
|
||||||
unset($mirrors[$key]);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
$mirror->attachRepository($repositories[$phid]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $mirrors;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
|
|
||||||
$where = array();
|
|
||||||
|
|
||||||
if ($this->ids) {
|
|
||||||
$where[] = qsprintf(
|
|
||||||
$conn_r,
|
|
||||||
'id IN (%Ld)',
|
|
||||||
$this->ids);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($this->phids) {
|
|
||||||
$where[] = qsprintf(
|
|
||||||
$conn_r,
|
|
||||||
'phid IN (%Ls)',
|
|
||||||
$this->phids);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($this->repositoryPHIDs) {
|
|
||||||
$where[] = qsprintf(
|
|
||||||
$conn_r,
|
|
||||||
'repositoryPHID IN (%Ls)',
|
|
||||||
$this->repositoryPHIDs);
|
|
||||||
}
|
|
||||||
|
|
||||||
$where[] = $this->buildPagingClause($conn_r);
|
|
||||||
|
|
||||||
return $this->formatWhereClause($where);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getQueryApplicationClass() {
|
|
||||||
return 'PhabricatorDiffusionApplication';
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1493,10 +1493,10 @@ final class PhabricatorRepository extends PhabricatorRepositoryDAO
|
||||||
$commit->delete();
|
$commit->delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
$mirrors = id(new PhabricatorRepositoryMirror())
|
$uris = id(new PhabricatorRepositoryURI())
|
||||||
->loadAllWhere('repositoryPHID = %s', $this->getPHID());
|
->loadAllWhere('repositoryPHID = %s', $this->getPHID());
|
||||||
foreach ($mirrors as $mirror) {
|
foreach ($uris as $uri) {
|
||||||
$mirror->delete();
|
$uri->delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
$ref_cursors = id(new PhabricatorRepositoryRefCursor())
|
$ref_cursors = id(new PhabricatorRepositoryRefCursor())
|
||||||
|
|
|
@ -1,19 +1,17 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
final class PhabricatorRepositoryMirror extends PhabricatorRepositoryDAO
|
/**
|
||||||
implements PhabricatorPolicyInterface {
|
* TODO: Remove this class and drop the underlying table after some time has
|
||||||
|
* passed. It currently exists only so that "bin/storage adjust" does not
|
||||||
|
* complain about the table.
|
||||||
|
*/
|
||||||
|
final class PhabricatorRepositoryMirror
|
||||||
|
extends PhabricatorRepositoryDAO {
|
||||||
|
|
||||||
protected $repositoryPHID;
|
protected $repositoryPHID;
|
||||||
protected $remoteURI;
|
protected $remoteURI;
|
||||||
protected $credentialPHID;
|
protected $credentialPHID;
|
||||||
|
|
||||||
private $repository = self::ATTACHABLE;
|
|
||||||
|
|
||||||
public static function initializeNewMirror(PhabricatorUser $actor) {
|
|
||||||
return id(new PhabricatorRepositoryMirror())
|
|
||||||
->setRemoteURI('');
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function getConfiguration() {
|
protected function getConfiguration() {
|
||||||
return array(
|
return array(
|
||||||
self::CONFIG_AUX_PHID => true,
|
self::CONFIG_AUX_PHID => true,
|
||||||
|
@ -29,41 +27,4 @@ final class PhabricatorRepositoryMirror extends PhabricatorRepositoryDAO
|
||||||
) + parent::getConfiguration();
|
) + parent::getConfiguration();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function generatePHID() {
|
|
||||||
return PhabricatorPHID::generateNewPHID(
|
|
||||||
PhabricatorRepositoryMirrorPHIDType::TYPECONST);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function attachRepository(PhabricatorRepository $repository) {
|
|
||||||
$this->repository = $repository;
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getRepository() {
|
|
||||||
return $this->assertAttached($this->repository);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* -( PhabricatorPolicyInterface )----------------------------------------- */
|
|
||||||
|
|
||||||
|
|
||||||
public function getCapabilities() {
|
|
||||||
return array(
|
|
||||||
PhabricatorPolicyCapability::CAN_VIEW,
|
|
||||||
PhabricatorPolicyCapability::CAN_EDIT,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getPolicy($capability) {
|
|
||||||
return $this->getRepository()->getPolicy($capability);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {
|
|
||||||
return $this->getRepository()->hasAutomaticCapability($capability, $viewer);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function describeAutomaticCapability($capability) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -200,6 +200,29 @@ final class PhabricatorRepositoryURI
|
||||||
return $this->getURIObject(true);
|
return $this->getURIObject(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getURIEnvelope() {
|
||||||
|
$uri = $this->getEffectiveURI();
|
||||||
|
|
||||||
|
$command_engine = $this->newCommandEngine();
|
||||||
|
|
||||||
|
$is_http = $command_engine->isAnyHTTPProtocol();
|
||||||
|
// For SVN, we use `--username` and `--password` flags separately in the
|
||||||
|
// CommandEngine, so we don't need to add any credentials here.
|
||||||
|
$is_svn = $this->getRepository()->isSVN();
|
||||||
|
$credential_phid = $this->getCredentialPHID();
|
||||||
|
|
||||||
|
if ($is_http && !$is_svn && $credential_phid) {
|
||||||
|
$key = PassphrasePasswordKey::loadFromPHID(
|
||||||
|
$credential_phid,
|
||||||
|
PhabricatorUser::getOmnipotentUser());
|
||||||
|
|
||||||
|
$uri->setUser($key->getUsernameEnvelope()->openEnvelope());
|
||||||
|
$uri->setPass($key->getPasswordEnvelope()->openEnvelope());
|
||||||
|
}
|
||||||
|
|
||||||
|
return new PhutilOpaqueEnvelope((string)$uri);
|
||||||
|
}
|
||||||
|
|
||||||
private function getURIObject($normalize) {
|
private function getURIObject($normalize) {
|
||||||
// Users can provide Git/SCP-style URIs in the form "user@host:path".
|
// Users can provide Git/SCP-style URIs in the form "user@host:path".
|
||||||
// These are equivalent to "ssh://user@host/path". We use the more standard
|
// These are equivalent to "ssh://user@host/path". We use the more standard
|
||||||
|
|
Loading…
Reference in a new issue