Path: blob/master/src/applications/harbormaster/step/HarbormasterLeaseWorkingCopyBuildStepImplementation.php
12256 views
<?php12final class HarbormasterLeaseWorkingCopyBuildStepImplementation3extends HarbormasterBuildStepImplementation {45public function getName() {6return pht('Lease Working Copy');7}89public function getGenericDescription() {10return pht('Build a working copy in Drydock.');11}1213public function getBuildStepGroupKey() {14return HarbormasterDrydockBuildStepGroup::GROUPKEY;15}1617public function execute(18HarbormasterBuild $build,19HarbormasterBuildTarget $build_target) {20$viewer = PhabricatorUser::getOmnipotentUser();2122$settings = $this->getSettings();2324// TODO: We should probably have a separate temporary storage area for25// execution stuff that doesn't step on configuration state?26$lease_phid = $build_target->getDetail('exec.leasePHID');2728if ($lease_phid) {29$lease = id(new DrydockLeaseQuery())30->setViewer($viewer)31->withPHIDs(array($lease_phid))32->executeOne();33if (!$lease) {34throw new PhabricatorWorkerPermanentFailureException(35pht(36'Lease "%s" could not be loaded.',37$lease_phid));38}39} else {40$working_copy_type = id(new DrydockWorkingCopyBlueprintImplementation())41->getType();4243$allowed_phids = $build_target->getFieldValue('blueprintPHIDs');44if (!is_array($allowed_phids)) {45$allowed_phids = array();46}47$authorizing_phid = $build_target->getBuildStep()->getPHID();4849$lease = DrydockLease::initializeNewLease()50->setResourceType($working_copy_type)51->setOwnerPHID($build_target->getPHID())52->setAuthorizingPHID($authorizing_phid)53->setAllowedBlueprintPHIDs($allowed_phids);5455$map = $this->buildRepositoryMap($build_target);5657$lease->setAttribute('repositories.map', $map);5859$task_id = $this->getCurrentWorkerTaskID();60if ($task_id) {61$lease->setAwakenTaskIDs(array($task_id));62}6364// TODO: Maybe add a method to mark artifacts like this as pending?6566// Create the artifact now so that the lease is always disposed of, even67// if this target is aborted.68$build_target->createArtifact(69$viewer,70$settings['name'],71HarbormasterWorkingCopyArtifact::ARTIFACTCONST,72array(73'drydockLeasePHID' => $lease->getPHID(),74));7576$lease->queueForActivation();7778$build_target79->setDetail('exec.leasePHID', $lease->getPHID())80->save();81}8283if ($lease->isActivating()) {84// TODO: Smart backoff?85throw new PhabricatorWorkerYieldException(15);86}8788if (!$lease->isActive()) {89// TODO: We could just forget about this lease and retry?90throw new PhabricatorWorkerPermanentFailureException(91pht(92'Lease "%s" never activated.',93$lease->getPHID()));94}95}9697public function getArtifactOutputs() {98return array(99array(100'name' => pht('Working Copy'),101'key' => $this->getSetting('name'),102'type' => HarbormasterWorkingCopyArtifact::ARTIFACTCONST,103),104);105}106107public function getFieldSpecifications() {108return array(109'name' => array(110'name' => pht('Artifact Name'),111'type' => 'text',112'required' => true,113),114'blueprintPHIDs' => array(115'name' => pht('Use Blueprints'),116'type' => 'blueprints',117'required' => true,118),119'repositoryPHIDs' => array(120'name' => pht('Also Clone'),121'type' => 'datasource',122'datasource.class' => 'DiffusionRepositoryDatasource',123),124);125}126127private function buildRepositoryMap(HarbormasterBuildTarget $build_target) {128$viewer = PhabricatorUser::getOmnipotentUser();129$variables = $build_target->getVariables();130131$repository_phid = idx($variables, 'repository.phid');132if (!$repository_phid) {133throw new Exception(134pht(135'Unable to determine how to clone the repository for this '.136'buildable: it is not associated with a tracked repository.'));137}138139$also_phids = $build_target->getFieldValue('repositoryPHIDs');140if (!is_array($also_phids)) {141$also_phids = array();142}143144$all_phids = $also_phids;145$all_phids[] = $repository_phid;146147$repositories = id(new PhabricatorRepositoryQuery())148->setViewer($viewer)149->withPHIDs($all_phids)150->execute();151$repositories = mpull($repositories, null, 'getPHID');152153foreach ($all_phids as $phid) {154if (empty($repositories[$phid])) {155throw new PhabricatorWorkerPermanentFailureException(156pht(157'Unable to load repository with PHID "%s".',158$phid));159}160}161162$map = array();163164foreach ($also_phids as $also_phid) {165$also_repo = $repositories[$also_phid];166$map[$also_repo->getCloneName()] = array(167'phid' => $also_repo->getPHID(),168'branch' => 'master',169);170}171172$repository = $repositories[$repository_phid];173174$commit = idx($variables, 'buildable.commit');175$ref_uri = idx($variables, 'repository.staging.uri');176$ref_ref = idx($variables, 'repository.staging.ref');177if ($commit) {178$spec = array(179'commit' => $commit,180);181} else if ($ref_uri && $ref_ref) {182$spec = array(183'ref' => array(184'uri' => $ref_uri,185'ref' => $ref_ref,186),187);188} else {189throw new Exception(190pht(191'Unable to determine how to fetch changes: this buildable does not '.192'identify a commit or a staging ref. You may need to configure a '.193'repository staging area.'));194}195196$directory = $repository->getCloneName();197$map[$directory] = array(198'phid' => $repository->getPHID(),199'default' => true,200) + $spec;201202return $map;203}204205}206207208