public function execute(HarbormasterBuild $build, HarbormasterBuildTarget $build_target)
 {
     $viewer = PhabricatorUser::getOmnipotentUser();
     $settings = $this->getSettings();
     $variables = $build_target->getVariables();
     $uri = $this->mergeVariables('vurisprintf', $settings['uri'], $variables);
     $method = nonempty(idx($settings, 'method'), 'POST');
     $future = id(new HTTPSFuture($uri))->setMethod($method)->setTimeout(60);
     $credential_phid = $this->getSetting('credential');
     if ($credential_phid) {
         $key = PassphrasePasswordKey::loadFromPHID($credential_phid, $viewer);
         $future->setHTTPBasicAuthCredentials($key->getUsernameEnvelope()->openEnvelope(), $key->getPasswordEnvelope());
     }
     $this->resolveFutures($build, $build_target, array($future));
     list($status, $body, $headers) = $future->resolve();
     $header_lines = array();
     // TODO: We don't currently preserve the entire "HTTP" response header, but
     // should. Once we do, reproduce it here faithfully.
     $status_code = $status->getStatusCode();
     $header_lines[] = "HTTP {$status_code}";
     foreach ($headers as $header) {
         list($head, $tail) = $header;
         $header_lines[] = "{$head}: {$tail}";
     }
     $header_lines = implode("\n", $header_lines);
     $build_target->newLog($uri, 'http.head')->append($header_lines);
     $build_target->newLog($uri, 'http.body')->append($body);
     if ($status->isError()) {
         throw new HarbormasterBuildFailureException();
     }
 }
 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();
         $lease = id(new DrydockLease())->setResourceType($working_copy_type)->setOwnerPHID($build_target->getPHID());
         $variables = $build_target->getVariables();
         $repository_phid = idx($variables, 'repository.phid');
         $commit = idx($variables, 'repository.commit');
         $lease->setAttribute('repositoryPHID', $repository_phid)->setAttribute('commit', $commit);
         $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()));
     }
     $artifact = $build_target->createArtifact($viewer, $settings['name'], HarbormasterWorkingCopyArtifact::ARTIFACTCONST, array('drydockLeasePHID' => $lease->getPHID()));
 }
 public function execute(HarbormasterBuild $build, HarbormasterBuildTarget $build_target)
 {
     $viewer = PhabricatorUser::getOmnipotentUser();
     $settings = $this->getSettings();
     $variables = $build_target->getVariables();
     $uri = $settings['uri'] . '/httpAuth/app/rest/buildQueue';
     $method = 'POST';
     $contentType = 'application/xml';
     $xmlBuilder = new TeamCityXmlBuildBuilder();
     $payload = $xmlBuilder->addBuildId($settings['buildId'])->addBranchName(implode(array("D", $variables['buildable.diff'])))->addDiffId(implode(array("D", $variables['buildable.diff'])))->addHarbormasterPHID($variables['target.phid'])->addRevisionId($variables['buildable.revision'])->build();
     $future = id(new HTTPFuture($uri, $payload))->setMethod($method)->addHeader('Content-Type', $contentType)->setTimeout(60);
     $credential_phid = $this->getSetting('credential');
     if ($credential_phid) {
         $key = PassphrasePasswordKey::loadFromPHID($credential_phid, $viewer);
         $future->setHTTPBasicAuthCredentials($key->getUsernameEnvelope()->openEnvelope(), $key->getPasswordEnvelope());
     }
     $this->resolveFutures($build, $build_target, array($future));
     list($status, $body, $headers) = $future->resolve();
     $header_lines = array();
     // TODO: We don't currently preserve the entire "HTTP" response header, but
     // should. Once we do, reproduce it here faithfully.
     $status_code = $status->getStatusCode();
     $header_lines[] = "HTTP {$status_code}";
     foreach ($headers as $header) {
         list($head, $tail) = $header;
         $header_lines[] = "{$head}: {$tail}";
     }
     $header_lines = implode("\n", $header_lines);
     $build_target->newLog($uri, 'http.head')->append($header_lines);
     $build_target->newLog($uri, 'http.body')->append($body);
     if ($status->isError()) {
         throw new HarbormasterBuildFailureException();
     }
 }
 public function execute(HarbormasterBuild $build, HarbormasterBuildTarget $build_target)
 {
     $viewer = PhabricatorUser::getOmnipotentUser();
     $settings = $this->getSettings();
     $variables = $build_target->getVariables();
     $artifact = $build_target->loadArtifact($settings['hostartifact']);
     $impl = $artifact->getArtifactImplementation();
     $lease = $impl->loadArtifactLease($viewer);
     $this->platform = $lease->getAttribute('platform');
     $command = $this->mergeVariables(array($this, 'escapeCommand'), $settings['command'], $variables);
     $this->platform = null;
     $interface = $lease->getInterface('command');
     $future = $interface->getExecFuture('%C', $command);
     $log_stdout = $build->createLog($build_target, 'remote', 'stdout');
     $log_stderr = $build->createLog($build_target, 'remote', 'stderr');
     $start_stdout = $log_stdout->start();
     $start_stderr = $log_stderr->start();
     $build_update = 5;
     // Read the next amount of available output every second.
     $futures = new FutureIterator(array($future));
     foreach ($futures->setUpdateInterval(1) as $key => $future_iter) {
         if ($future_iter === null) {
             // Check to see if we should abort.
             if ($build_update <= 0) {
                 $build->reload();
                 if ($this->shouldAbort($build, $build_target)) {
                     $future->resolveKill();
                     throw new HarbormasterBuildAbortedException();
                 } else {
                     $build_update = 5;
                 }
             } else {
                 $build_update -= 1;
             }
             // Command is still executing.
             // Read more data as it is available.
             list($stdout, $stderr) = $future->read();
             $log_stdout->append($stdout);
             $log_stderr->append($stderr);
             $future->discardBuffers();
         } else {
             // Command execution is complete.
             // Get the return value so we can log that as well.
             list($err) = $future->resolve();
             // Retrieve the last few bits of information.
             list($stdout, $stderr) = $future->read();
             $log_stdout->append($stdout);
             $log_stderr->append($stderr);
             $future->discardBuffers();
             break;
         }
     }
     $log_stdout->finalize($start_stdout);
     $log_stderr->finalize($start_stderr);
     if ($err) {
         throw new HarbormasterBuildFailureException();
     }
 }
 public function execute(HarbormasterBuild $build, HarbormasterBuildTarget $build_target)
 {
     $settings = $this->getSettings();
     $variables = $build_target->getVariables();
     $path = $this->mergeVariables('vsprintf', $settings['path'], $variables);
     $artifact = $build_target->loadArtifact($settings['hostartifact']);
     $lease = $artifact->loadDrydockLease();
     $interface = $lease->getInterface('filesystem');
     // TODO: Handle exceptions.
     $file = $interface->saveFile($path, $settings['name']);
     // Insert the artifact record.
     $artifact = $build_target->createArtifact(PhabricatorUser::getOmnipotentUser(), $settings['name'], HarbormasterFileArtifact::ARTIFACTCONST, array('filePHID' => $file->getPHID()));
 }
 public function execute(HarbormasterBuild $build, HarbormasterBuildTarget $build_target)
 {
     $settings = $this->getSettings();
     $variables = $build_target->getVariables();
     $path = $this->mergeVariables('vsprintf', $settings['path'], $variables);
     $artifact = $build->loadArtifact($settings['hostartifact']);
     $lease = $artifact->loadDrydockLease();
     $interface = $lease->getInterface('filesystem');
     // TODO: Handle exceptions.
     $file = $interface->saveFile($path, $settings['name']);
     // Insert the artifact record.
     $artifact = $build->createArtifact($build_target, $settings['name'], HarbormasterBuildArtifact::TYPE_FILE);
     $artifact->setArtifactData(array('filePHID' => $file->getPHID()));
     $artifact->save();
 }
 public function execute(HarbormasterBuild $build, HarbormasterBuildTarget $build_target)
 {
     $settings = $this->getSettings();
     $variables = $build_target->getVariables();
     $path = $this->mergeVariables('vsprintf', $settings['path'], $variables);
     $artifact = $build->loadArtifact($settings['artifact']);
     $file = $artifact->loadPhabricatorFile();
     $fragment = id(new PhragmentFragmentQuery())->setViewer(PhabricatorUser::getOmnipotentUser())->withPaths(array($path))->executeOne();
     if ($fragment === null) {
         PhragmentFragment::createFromFile(PhabricatorUser::getOmnipotentUser(), $file, $path, PhabricatorPolicies::getMostOpenPolicy(), PhabricatorPolicies::POLICY_USER);
     } else {
         if ($file->getMimeType() === 'application/zip') {
             $fragment->updateFromZIP(PhabricatorUser::getOmnipotentUser(), $file);
         } else {
             $fragment->updateFromFile(PhabricatorUser::getOmnipotentUser(), $file);
         }
     }
 }
 private function buildRepositoryMap(HarbormasterBuildTarget $build_target)
 {
     $viewer = PhabricatorUser::getOmnipotentUser();
     $variables = $build_target->getVariables();
     $repository_phid = idx($variables, 'repository.phid');
     if (!$repository_phid) {
         throw new Exception(pht('Unable to determine how to clone the repository for this ' . 'buildable: it is not associated with a tracked repository.'));
     }
     $also_phids = $build_target->getFieldValue('repositoryPHIDs');
     if (!is_array($also_phids)) {
         $also_phids = array();
     }
     $all_phids = $also_phids;
     $all_phids[] = $repository_phid;
     $repositories = id(new PhabricatorRepositoryQuery())->setViewer($viewer)->withPHIDs($all_phids)->execute();
     $repositories = mpull($repositories, null, 'getPHID');
     foreach ($all_phids as $phid) {
         if (empty($repositories[$phid])) {
             throw new PhabricatorWorkerPermanentFailureException(pht('Unable to load repository with PHID "%s".', $phid));
         }
     }
     $map = array();
     foreach ($also_phids as $also_phid) {
         $also_repo = $repositories[$also_phid];
         $map[$also_repo->getCloneName()] = array('phid' => $also_repo->getPHID(), 'branch' => 'master');
     }
     $repository = $repositories[$repository_phid];
     $commit = idx($variables, 'buildable.commit');
     $ref_uri = idx($variables, 'repository.staging.uri');
     $ref_ref = idx($variables, 'repository.staging.ref');
     if ($commit) {
         $spec = array('commit' => $commit);
     } else {
         if ($ref_uri && $ref_ref) {
             $spec = array('ref' => array('uri' => $ref_uri, 'ref' => $ref_ref));
         } else {
             throw new Exception(pht('Unable to determine how to fetch changes: this buildable does not ' . 'identify a commit or a staging ref. You may need to configure a ' . 'repository staging area.'));
         }
     }
     $directory = $repository->getCloneName();
     $map[$directory] = array('phid' => $repository->getPHID(), 'default' => true) + $spec;
     return $map;
 }
 public function execute(HarbormasterBuild $build, HarbormasterBuildTarget $build_target)
 {
     $viewer = PhabricatorUser::getOmnipotentUser();
     $settings = $this->getSettings();
     $variables = $build_target->getVariables();
     $artifact = $build_target->loadArtifact($settings['artifact']);
     $impl = $artifact->getArtifactImplementation();
     $lease = $impl->loadArtifactLease($viewer);
     // TODO: Require active lease.
     $command = $this->mergeVariables('vcsprintf', $settings['command'], $variables);
     $interface = $lease->getInterface(DrydockCommandInterface::INTERFACE_TYPE);
     $exec_future = $interface->getExecFuture('%C', $command);
     $harbor_future = id(new HarbormasterExecFuture())->setFuture($exec_future)->setLogs($build_target->newLog('remote', 'stdout'), $build_target->newLog('remote', 'stderr'));
     $this->resolveFutures($build, $build_target, array($harbor_future));
     list($err) = $harbor_future->resolve();
     if ($err) {
         throw new HarbormasterBuildFailureException();
     }
 }
 public function execute(HarbormasterBuild $build, HarbormasterBuildTarget $build_target)
 {
     $viewer = PhabricatorUser::getOmnipotentUser();
     $settings = $this->getSettings();
     $variables = $build_target->getVariables();
     $uri = $this->mergeVariables('vurisprintf', $settings['uri'], $variables);
     $method = nonempty(idx($settings, 'method'), 'POST');
     $future = id(new HTTPSFuture($uri))->setMethod($method)->setTimeout(60);
     $credential_phid = $this->getSetting('credential');
     if ($credential_phid) {
         $key = PassphrasePasswordKey::loadFromPHID($credential_phid, $viewer);
         $future->setHTTPBasicAuthCredentials($key->getUsernameEnvelope()->openEnvelope(), $key->getPasswordEnvelope());
     }
     $this->resolveFutures($build, $build_target, array($future));
     $this->logHTTPResponse($build, $build_target, $future, $uri);
     list($status) = $future->resolve();
     if ($status->isError()) {
         throw new HarbormasterBuildFailureException();
     }
 }
 public function execute(HarbormasterBuild $build, HarbormasterBuildTarget $build_target)
 {
     $viewer = PhabricatorUser::getOmnipotentUser();
     $settings = $this->getSettings();
     $variables = $build_target->getVariables();
     $uri = $this->mergeVariables('vurisprintf', $settings['uri'], $variables);
     $log_body = $build->createLog($build_target, $uri, 'http-body');
     $start = $log_body->start();
     $method = nonempty(idx($settings, 'method'), 'POST');
     $future = id(new HTTPSFuture($uri))->setMethod($method)->setTimeout(60);
     $credential_phid = $this->getSetting('credential');
     if ($credential_phid) {
         $key = PassphrasePasswordKey::loadFromPHID($credential_phid, $viewer);
         $future->setHTTPBasicAuthCredentials($key->getUsernameEnvelope()->openEnvelope(), $key->getPasswordEnvelope());
     }
     list($status, $body, $headers) = $this->resolveFuture($build, $build_target, $future);
     $log_body->append($body);
     $log_body->finalize($start);
     if ($status->getStatusCode() != 200) {
         $build->setBuildStatus(HarbormasterBuild::STATUS_FAILED);
     }
 }