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:
		
							
								
								
									
										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', | ||||
|     'DiffusionMercurialWireSSHTestCase' => 'applications/diffusion/ssh/__tests__/DiffusionMercurialWireSSHTestCase.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', | ||||
|     'DiffusionPathChangeQuery' => 'applications/diffusion/query/pathchange/DiffusionPathChangeQuery.php', | ||||
|     'DiffusionPathCompleteController' => 'applications/diffusion/controller/DiffusionPathCompleteController.php', | ||||
| @@ -3208,8 +3206,6 @@ phutil_register_library_map(array( | ||||
|     'PhabricatorRepositoryMercurialCommitMessageParserWorker' => 'applications/repository/worker/commitmessageparser/PhabricatorRepositoryMercurialCommitMessageParserWorker.php', | ||||
|     'PhabricatorRepositoryMirror' => 'applications/repository/storage/PhabricatorRepositoryMirror.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', | ||||
|     'PhabricatorRepositoryPullEngine' => 'applications/repository/engine/PhabricatorRepositoryPullEngine.php', | ||||
|     'PhabricatorRepositoryPullEvent' => 'applications/repository/storage/PhabricatorRepositoryPullEvent.php', | ||||
| @@ -4914,8 +4910,6 @@ phutil_register_library_map(array( | ||||
|     'DiffusionMercurialWireProtocolTests' => 'PhabricatorTestCase', | ||||
|     'DiffusionMercurialWireSSHTestCase' => 'PhabricatorTestCase', | ||||
|     'DiffusionMergedCommitsQueryConduitAPIMethod' => 'DiffusionQueryConduitAPIMethod', | ||||
|     'DiffusionMirrorDeleteController' => 'DiffusionController', | ||||
|     'DiffusionMirrorEditController' => 'DiffusionController', | ||||
|     'DiffusionPathChange' => 'Phobject', | ||||
|     'DiffusionPathChangeQuery' => 'Phobject', | ||||
|     'DiffusionPathCompleteController' => 'DiffusionController', | ||||
| @@ -7882,13 +7876,8 @@ phutil_register_library_map(array( | ||||
|     'PhabricatorRepositoryManagementWorkflow' => 'PhabricatorManagementWorkflow', | ||||
|     'PhabricatorRepositoryMercurialCommitChangeParserWorker' => 'PhabricatorRepositoryCommitChangeParserWorker', | ||||
|     'PhabricatorRepositoryMercurialCommitMessageParserWorker' => 'PhabricatorRepositoryCommitMessageParserWorker', | ||||
|     'PhabricatorRepositoryMirror' => array( | ||||
|       'PhabricatorRepositoryDAO', | ||||
|       'PhabricatorPolicyInterface', | ||||
|     ), | ||||
|     'PhabricatorRepositoryMirror' => 'PhabricatorRepositoryDAO', | ||||
|     'PhabricatorRepositoryMirrorEngine' => 'PhabricatorRepositoryEngine', | ||||
|     'PhabricatorRepositoryMirrorPHIDType' => 'PhabricatorPHIDType', | ||||
|     'PhabricatorRepositoryMirrorQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', | ||||
|     'PhabricatorRepositoryParsedChange' => 'Phobject', | ||||
|     'PhabricatorRepositoryPullEngine' => 'PhabricatorRepositoryEngine', | ||||
|     'PhabricatorRepositoryPullEvent' => array( | ||||
|   | ||||
| @@ -122,10 +122,6 @@ final class PhabricatorDiffusionApplication extends PhabricatorApplication { | ||||
|             'testautomation/' => 'DiffusionRepositoryTestAutomationController', | ||||
|           ), | ||||
|           '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 | ||||
|   | ||||
| @@ -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) | ||||
|       ->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) { | ||||
|       $boxes[] = id(new PHUIObjectBoxView()) | ||||
|         ->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) { | ||||
|     $viewer = $this->getViewer(); | ||||
|  | ||||
|   | ||||
| @@ -7,6 +7,7 @@ final class PhabricatorRepositoryMirrorEngine | ||||
|   extends PhabricatorRepositoryEngine { | ||||
|  | ||||
|   public function pushToMirrors() { | ||||
|     $viewer = $this->getViewer(); | ||||
|     $repository = $this->getRepository(); | ||||
|  | ||||
|     if (!$repository->canMirror()) { | ||||
| @@ -19,13 +20,24 @@ final class PhabricatorRepositoryMirrorEngine | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|     $mirrors = id(new PhabricatorRepositoryMirrorQuery()) | ||||
|       ->setViewer($this->getViewer()) | ||||
|       ->withRepositoryPHIDs(array($repository->getPHID())) | ||||
|     $uris = id(new PhabricatorRepositoryURIQuery()) | ||||
|       ->setViewer($viewer) | ||||
|       ->withRepositories(array($repository)) | ||||
|       ->execute(); | ||||
|  | ||||
|     $io_mirror = PhabricatorRepositoryURI::IO_MIRROR; | ||||
|  | ||||
|     $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 { | ||||
|         $this->pushRepositoryToMirror($repository, $mirror); | ||||
|       } catch (Exception $ex) { | ||||
| @@ -44,54 +56,56 @@ final class PhabricatorRepositoryMirrorEngine | ||||
|  | ||||
|   private function pushRepositoryToMirror( | ||||
|     PhabricatorRepository $repository, | ||||
|     PhabricatorRepositoryMirror $mirror) { | ||||
|     PhabricatorRepositoryURI $mirror_uri) { | ||||
|  | ||||
|     // 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 ...". | ||||
|     $this->log( | ||||
|       pht( | ||||
|         'Pushing to remote "%s"...', | ||||
|         $mirror_uri->getEffectiveURI())); | ||||
|  | ||||
|     $proxy = clone $repository; | ||||
|     $proxy->makeEphemeral(); | ||||
|  | ||||
|     $proxy->setDetail('hosting-enabled', false); | ||||
|     $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); | ||||
|     if ($repository->isGit()) { | ||||
|       $this->pushToGitRepository($repository, $mirror_uri); | ||||
|     } else if ($repository->isHg()) { | ||||
|       $this->pushToHgRepository($repository, $mirror_uri); | ||||
|     } else { | ||||
|       throw new Exception(pht('Unsupported VCS!')); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   private function pushToGitRepository( | ||||
|     PhabricatorRepository $proxy) { | ||||
|     PhabricatorRepository $repository, | ||||
|     PhabricatorRepositoryURI $mirror_uri) { | ||||
|  | ||||
|     $future = $proxy->getRemoteCommandFuture( | ||||
|     $argv = array( | ||||
|       'push --verbose --mirror -- %P', | ||||
|       $proxy->getRemoteURIEnvelope()); | ||||
|       $mirror_uri->getURIEnvelope(), | ||||
|     ); | ||||
|  | ||||
|     $future = $mirror_uri->newCommandEngine() | ||||
|       ->setArgv($argv) | ||||
|       ->newFuture(); | ||||
|  | ||||
|     $future | ||||
|       ->setCWD($proxy->getLocalPath()) | ||||
|       ->setCWD($repository->getLocalPath()) | ||||
|       ->resolvex(); | ||||
|   } | ||||
|  | ||||
|   private function pushToHgRepository( | ||||
|     PhabricatorRepository $proxy) { | ||||
|     PhabricatorRepository $repository, | ||||
|     PhabricatorRepositoryURI $mirror_uri) { | ||||
|  | ||||
|     $future = $proxy->getRemoteCommandFuture( | ||||
|     $argv = array( | ||||
|       'push --verbose --rev tip -- %P', | ||||
|       $proxy->getRemoteURIEnvelope()); | ||||
|       $mirror_uri->getURIEnvelope(), | ||||
|     ); | ||||
|  | ||||
|     $future = $mirror_uri->newCommandEngine() | ||||
|       ->setArgv($argv) | ||||
|       ->newFuture(); | ||||
|  | ||||
|     try { | ||||
|       $future | ||||
|         ->setCWD($proxy->getLocalPath()) | ||||
|         ->setCWD($repository->getLocalPath()) | ||||
|         ->resolvex(); | ||||
|     } catch (CommandException $ex) { | ||||
|       if (preg_match('/no changes found/', $ex->getStdOut())) { | ||||
|   | ||||
| @@ -12,12 +12,12 @@ final class PhabricatorRepositoryManagementMirrorWorkflow | ||||
|       ->setArguments( | ||||
|         array( | ||||
|           array( | ||||
|             'name'        => 'verbose', | ||||
|             'help'        => pht('Show additional debugging information.'), | ||||
|             'name' => 'verbose', | ||||
|             'help' => pht('Show additional debugging information.'), | ||||
|           ), | ||||
|           array( | ||||
|             'name'        => 'repos', | ||||
|             'wildcard'    => true, | ||||
|             'name' => 'repos', | ||||
|             'wildcard' => true, | ||||
|           ), | ||||
|         )); | ||||
|   } | ||||
| @@ -31,12 +31,11 @@ final class PhabricatorRepositoryManagementMirrorWorkflow | ||||
|           'Specify one or more repositories to push to mirrors.')); | ||||
|     } | ||||
|  | ||||
|     $console = PhutilConsole::getConsole(); | ||||
|     foreach ($repos as $repo) { | ||||
|       $console->writeOut( | ||||
|       echo tsprintf( | ||||
|         "%s\n", | ||||
|         pht( | ||||
|           "Pushing '%s' to mirrors...", | ||||
|           'Pushing "%s" to mirrors...', | ||||
|           $repo->getDisplayName())); | ||||
|  | ||||
|       $engine = id(new PhabricatorRepositoryMirrorEngine()) | ||||
| @@ -45,7 +44,9 @@ final class PhabricatorRepositoryManagementMirrorWorkflow | ||||
|         ->pushToMirrors(); | ||||
|     } | ||||
|  | ||||
|     $console->writeOut("%s\n", pht('Done.')); | ||||
|     echo tsprintf( | ||||
|       "%s\n", | ||||
|       pht('Done.')); | ||||
|  | ||||
|     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(); | ||||
|       } | ||||
|  | ||||
|       $mirrors = id(new PhabricatorRepositoryMirror()) | ||||
|       $uris = id(new PhabricatorRepositoryURI()) | ||||
|         ->loadAllWhere('repositoryPHID = %s', $this->getPHID()); | ||||
|       foreach ($mirrors as $mirror) { | ||||
|         $mirror->delete(); | ||||
|       foreach ($uris as $uri) { | ||||
|         $uri->delete(); | ||||
|       } | ||||
|  | ||||
|       $ref_cursors = id(new PhabricatorRepositoryRefCursor()) | ||||
|   | ||||
| @@ -1,19 +1,17 @@ | ||||
| <?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 $remoteURI; | ||||
|   protected $credentialPHID; | ||||
|  | ||||
|   private $repository = self::ATTACHABLE; | ||||
|  | ||||
|   public static function initializeNewMirror(PhabricatorUser $actor) { | ||||
|     return id(new PhabricatorRepositoryMirror()) | ||||
|       ->setRemoteURI(''); | ||||
|   } | ||||
|  | ||||
|   protected function getConfiguration() { | ||||
|     return array( | ||||
|       self::CONFIG_AUX_PHID => true, | ||||
| @@ -29,41 +27,4 @@ final class PhabricatorRepositoryMirror extends PhabricatorRepositoryDAO | ||||
|     ) + 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); | ||||
|   } | ||||
|  | ||||
|   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) { | ||||
|     // 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 | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 epriestley
					epriestley