private function loadWorkingCopyLease(DrydockRepositoryOperation $operation)
 {
     $viewer = $this->getViewer();
     // TODO: This is very similar to leasing in Harbormaster, maybe we can
     // share some of the logic?
     $lease_phid = $operation->getProperty('exec.leasePHID');
     if ($lease_phid) {
         $lease = id(new DrydockLeaseQuery())->setViewer($viewer)->withPHIDs(array($lease_phid))->executeOne();
         if (!$lease) {
             throw new PhabricatorWorkerPermanentFailureException(pht('Lease "%s" could not be loaded.', $lease_phid));
         }
     } else {
         $working_copy_type = id(new DrydockWorkingCopyBlueprintImplementation())->getType();
         $repository = $operation->getRepository();
         $allowed_phids = $repository->getAutomationBlueprintPHIDs();
         $authorizing_phid = $repository->getPHID();
         $lease = DrydockLease::initializeNewLease()->setResourceType($working_copy_type)->setOwnerPHID($operation->getPHID())->setAuthorizingPHID($authorizing_phid)->setAllowedBlueprintPHIDs($allowed_phids);
         $map = $this->buildRepositoryMap($operation);
         $lease->setAttribute('repositories.map', $map);
         $task_id = $this->getCurrentWorkerTaskID();
         if ($task_id) {
             $lease->setAwakenTaskIDs(array($task_id));
         }
         $operation->setProperty('exec.leasePHID', $lease->getPHID())->save();
         $lease->queueForActivation();
     }
     if ($lease->isActivating()) {
         throw new PhabricatorWorkerYieldException(15);
     }
     if (!$lease->isActive()) {
         throw new PhabricatorWorkerPermanentFailureException(pht('Lease "%s" never activated.', $lease->getPHID()));
     }
     return $lease;
 }
 public function execute(HarbormasterBuild $build, HarbormasterBuildTarget $build_target)
 {
     $viewer = PhabricatorUser::getOmnipotentUser();
     $settings = $this->getSettings();
     // TODO: We should probably have a separate temporary storage area for
     // execution stuff that doesn't step on configuration state?
     $lease_phid = $build_target->getDetail('exec.leasePHID');
     if ($lease_phid) {
         $lease = id(new DrydockLeaseQuery())->setViewer($viewer)->withPHIDs(array($lease_phid))->executeOne();
         if (!$lease) {
             throw new PhabricatorWorkerPermanentFailureException(pht('Lease "%s" could not be loaded.', $lease_phid));
         }
     } else {
         $working_copy_type = id(new DrydockWorkingCopyBlueprintImplementation())->getType();
         $allowed_phids = $build_target->getFieldValue('blueprintPHIDs');
         if (!is_array($allowed_phids)) {
             $allowed_phids = array();
         }
         $authorizing_phid = $build_target->getBuildStep()->getPHID();
         $lease = DrydockLease::initializeNewLease()->setResourceType($working_copy_type)->setOwnerPHID($build_target->getPHID())->setAuthorizingPHID($authorizing_phid)->setAllowedBlueprintPHIDs($allowed_phids);
         $map = $this->buildRepositoryMap($build_target);
         $lease->setAttribute('repositories.map', $map);
         $task_id = $this->getCurrentWorkerTaskID();
         if ($task_id) {
             $lease->setAwakenTaskIDs(array($task_id));
         }
         // TODO: Maybe add a method to mark artifacts like this as pending?
         // Create the artifact now so that the lease is always disposed of, even
         // if this target is aborted.
         $build_target->createArtifact($viewer, $settings['name'], HarbormasterWorkingCopyArtifact::ARTIFACTCONST, array('drydockLeasePHID' => $lease->getPHID()));
         $lease->queueForActivation();
         $build_target->setDetail('exec.leasePHID', $lease->getPHID())->save();
     }
     if ($lease->isActivating()) {
         // TODO: Smart backoff?
         throw new PhabricatorWorkerYieldException(15);
     }
     if (!$lease->isActive()) {
         // TODO: We could just forget about this lease and retry?
         throw new PhabricatorWorkerPermanentFailureException(pht('Lease "%s" never activated.', $lease->getPHID()));
     }
 }
 protected function newLease(DrydockBlueprint $blueprint)
 {
     return DrydockLease::initializeNewLease()->setAuthorizingPHID($blueprint->getPHID());
 }
 protected function newLease(DrydockBlueprint $blueprint)
 {
     return DrydockLease::initializeNewLease();
 }