Page MenuHomePhabricator

D7892.diff
No OneTemporary

D7892.diff

Index: resources/sql/autopatches/20140104.harbormastercmd.sql
===================================================================
--- /dev/null
+++ resources/sql/autopatches/20140104.harbormastercmd.sql
@@ -0,0 +1,18 @@
+CREATE TABLE {$NAMESPACE}_harbormaster.harbormaster_buildcommand (
+ id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
+ authorPHID VARCHAR(64) NOT NULL COLLATE utf8_bin,
+ targetPHID VARCHAR(64) NOT NULL COLLATE utf8_bin,
+ command VARCHAR(128) NOT NULL COLLATE utf8_bin,
+ dateCreated INT UNSIGNED NOT NULL,
+ dateModified INT UNSIGNED NOT NULL,
+ KEY `key_target` (targetPHID)
+) ENGINE=InnoDB, COLLATE utf8_general_ci;
+
+ALTER TABLE {$NAMESPACE}_harbormaster.harbormaster_build
+ DROP cancelRequested;
+
+ALTER TABLE {$NAMESPACE}_harbormaster.harbormaster_buildtarget
+ ADD targetStatus VARCHAR(64) NOT NULL COLLATE utf8_bin;
+
+UPDATE {$NAMESPACE}_harbormaster.harbormaster_buildtarget
+ SET targetStatus = 'target/pending' WHERE targetStatus = '';
Index: src/__phutil_library_map__.php
===================================================================
--- src/__phutil_library_map__.php
+++ src/__phutil_library_map__.php
@@ -704,9 +704,10 @@
'FileMailReceiver' => 'applications/files/mail/FileMailReceiver.php',
'FileReplyHandler' => 'applications/files/mail/FileReplyHandler.php',
'HarbormasterBuild' => 'applications/harbormaster/storage/build/HarbormasterBuild.php',
+ 'HarbormasterBuildActionController' => 'applications/harbormaster/controller/HarbormasterBuildActionController.php',
'HarbormasterBuildArtifact' => 'applications/harbormaster/storage/build/HarbormasterBuildArtifact.php',
'HarbormasterBuildArtifactQuery' => 'applications/harbormaster/query/HarbormasterBuildArtifactQuery.php',
- 'HarbormasterBuildCancelController' => 'applications/harbormaster/controller/HarbormasterBuildCancelController.php',
+ 'HarbormasterBuildCommand' => 'applications/harbormaster/storage/HarbormasterBuildCommand.php',
'HarbormasterBuildEngine' => 'applications/harbormaster/engine/HarbormasterBuildEngine.php',
'HarbormasterBuildItem' => 'applications/harbormaster/storage/build/HarbormasterBuildItem.php',
'HarbormasterBuildItemQuery' => 'applications/harbormaster/query/HarbormasterBuildItemQuery.php',
@@ -3155,13 +3156,14 @@
0 => 'HarbormasterDAO',
1 => 'PhabricatorPolicyInterface',
),
+ 'HarbormasterBuildActionController' => 'HarbormasterController',
'HarbormasterBuildArtifact' =>
array(
0 => 'HarbormasterDAO',
1 => 'PhabricatorPolicyInterface',
),
'HarbormasterBuildArtifactQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
- 'HarbormasterBuildCancelController' => 'HarbormasterController',
+ 'HarbormasterBuildCommand' => 'HarbormasterDAO',
'HarbormasterBuildEngine' => 'Phobject',
'HarbormasterBuildItem' => 'HarbormasterDAO',
'HarbormasterBuildItemQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
@@ -3226,7 +3228,7 @@
'HarbormasterPHIDTypeBuildStep' => 'PhabricatorPHIDType',
'HarbormasterPHIDTypeBuildTarget' => 'PhabricatorPHIDType',
'HarbormasterPHIDTypeBuildable' => 'PhabricatorPHIDType',
- 'HarbormasterPlanController' => 'PhabricatorController',
+ 'HarbormasterPlanController' => 'HarbormasterController',
'HarbormasterPlanDisableController' => 'HarbormasterPlanController',
'HarbormasterPlanEditController' => 'HarbormasterPlanController',
'HarbormasterPlanListController' =>
Index: src/applications/harbormaster/application/PhabricatorApplicationHarbormaster.php
===================================================================
--- src/applications/harbormaster/application/PhabricatorApplicationHarbormaster.php
+++ src/applications/harbormaster/application/PhabricatorApplicationHarbormaster.php
@@ -55,7 +55,8 @@
),
'build/' => array(
'(?:(?P<id>\d+)/)?' => 'HarbormasterBuildViewController',
- 'cancel/(?:(?P<id>\d+)/)?' => 'HarbormasterBuildCancelController',
+ '(?P<action>stop|resume|restart)/(?:(?P<id>\d+)/)?'
+ => 'HarbormasterBuildActionController',
),
'plan/' => array(
'(?:query/(?P<queryKey>[^/]+)/)?'
Index: src/applications/harbormaster/controller/HarbormasterBuildActionController.php
===================================================================
--- /dev/null
+++ src/applications/harbormaster/controller/HarbormasterBuildActionController.php
@@ -0,0 +1,146 @@
+<?php
+
+final class HarbormasterBuildActionController
+ extends HarbormasterController {
+
+ private $id;
+ private $action;
+
+ public function willProcessRequest(array $data) {
+ $this->id = $data['id'];
+ $this->action = $data['action'];
+ }
+
+ public function processRequest() {
+ $request = $this->getRequest();
+ $viewer = $request->getUser();
+ $command = $this->action;
+
+ $build = id(new HarbormasterBuildQuery())
+ ->setViewer($viewer)
+ ->withIDs(array($this->id))
+ ->executeOne();
+ if (!$build) {
+ return new Aphront404Response();
+ }
+
+ switch ($command) {
+ case HarbormasterBuildCommand::COMMAND_RESTART:
+ $can_issue = $build->canRestartBuild();
+ break;
+ case HarbormasterBuildCommand::COMMAND_STOP:
+ $can_issue = $build->canStopBuild();
+ break;
+ case HarbormasterBuildCommand::COMMAND_RESUME:
+ $can_issue = $build->canResumeBuild();
+ break;
+ default:
+ return new Aphront400Response();
+ }
+
+ $build_uri = $this->getApplicationURI('/build/'.$build->getID().'/');
+
+ if ($request->isDialogFormPost() && $can_issue) {
+
+ // Issue the new build command.
+ id(new HarbormasterBuildCommand())
+ ->setAuthorPHID($viewer->getPHID())
+ ->setTargetPHID($build->getPHID())
+ ->setCommand($command)
+ ->save();
+
+ // Schedule a build update. We may already have stuff in queue (in which
+ // case this will just no-op), but we might also be dealing with a
+ // stopped build, which won't restart unless we deal with this.
+ PhabricatorWorker::scheduleTask(
+ 'HarbormasterBuildWorker',
+ array(
+ 'buildID' => $build->getID()
+ ));
+
+ return id(new AphrontRedirectResponse())->setURI($build_uri);
+ }
+
+ switch ($command) {
+ case HarbormasterBuildCommand::COMMAND_RESTART:
+ if ($can_issue) {
+ $title = pht('Really restart build?');
+ $body = pht(
+ 'Progress on this build will be discarded and the build will '.
+ 'restart. Side effects of the build will occur again. Really '.
+ 'restart build?');
+ $submit = pht('Restart Build');
+ } else {
+ $title = pht('Unable to Restart Build');
+ if ($build->isRestarting()) {
+ $body = pht(
+ 'This build is already restarting. You can not reissue a '.
+ 'restart command to a restarting build.');
+ } else {
+ $body = pht(
+ 'You can not restart this build.');
+ }
+ }
+ break;
+ case HarbormasterBuildCommand::COMMAND_STOP:
+ if ($can_issue) {
+ $title = pht('Really stop build?');
+ $body = pht(
+ 'If you stop this build, work will halt once the current steps '.
+ 'complete. You can resume the build later.');
+ $submit = pht('Stop Build');
+ } else {
+ $title = pht('Unable to Stop Build');
+ if ($build->isComplete()) {
+ $body = pht(
+ 'This build is already complete. You can not stop a completed '.
+ 'build.');
+ } else if ($build->isStopped()) {
+ $body = pht(
+ 'This build is already stopped. You can not stop a build which '.
+ 'has already been stopped.');
+ } else if ($build->isStopping()) {
+ $body = pht(
+ 'This build is already stopping. You can not reissue a stop '.
+ 'command to a stopping build.');
+ } else {
+ $body = pht(
+ 'This build can not be stopped.');
+ }
+ }
+ break;
+ case HarbormasterBuildCommand::COMMAND_RESUME:
+ if ($can_issue) {
+ $title = pht('Really resume build?');
+ $body = pht(
+ 'Work will continue on the build. Really resume?');
+ $submit = pht('Resume Build');
+ } else {
+ $title = pht('Unable to Resume Build');
+ if ($build->isResuming()) {
+ $body = pht(
+ 'This build is already resuming. You can not reissue a resume '.
+ 'command to a resuming build.');
+ } else if (!$build->isStopped()) {
+ $body = pht(
+ 'This build is not stopped. You can only resume a stopped '.
+ 'build.');
+ }
+ }
+ break;
+ }
+
+ $dialog = id(new AphrontDialogView())
+ ->setUser($viewer)
+ ->setTitle($title)
+ ->appendChild($body)
+ ->addCancelButton($build_uri);
+
+ if ($can_issue) {
+ $dialog->addSubmitButton($submit);
+ }
+
+ return id(new AphrontDialogResponse())->setDialog($dialog);
+ }
+
+}
Index: src/applications/harbormaster/controller/HarbormasterBuildCancelController.php
===================================================================
--- src/applications/harbormaster/controller/HarbormasterBuildCancelController.php
+++ /dev/null
@@ -1,49 +0,0 @@
-<?php
-
-final class HarbormasterBuildCancelController
- extends HarbormasterController {
-
- private $id;
-
- public function willProcessRequest(array $data) {
- $this->id = $data['id'];
- }
-
- public function processRequest() {
- $request = $this->getRequest();
- $viewer = $request->getUser();
-
- $id = $this->id;
-
- $build = id(new HarbormasterBuildQuery())
- ->setViewer($viewer)
- ->withIDs(array($id))
- ->executeOne();
- if ($build === null) {
- return new Aphront404Response();
- }
-
- $build_uri = $this->getApplicationURI('/build/'.$build->getID());
-
- if ($request->isDialogFormPost()) {
- $build->setCancelRequested(1);
- $build->save();
-
- return id(new AphrontRedirectResponse())->setURI($build_uri);
- }
-
- $dialog = new AphrontDialogView();
- $dialog->setTitle(pht('Really cancel build?'))
- ->setUser($viewer)
- ->addSubmitButton(pht('Cancel'))
- ->addCancelButton($build_uri, pht('Don\'t Cancel'));
- $dialog->appendChild(
- phutil_tag(
- 'p',
- array(),
- pht(
- 'Really cancel this build?')));
- return id(new AphrontDialogResponse())->setDialog($dialog);
- }
-
-}
Index: src/applications/harbormaster/controller/HarbormasterBuildViewController.php
===================================================================
--- src/applications/harbormaster/controller/HarbormasterBuildViewController.php
+++ src/applications/harbormaster/controller/HarbormasterBuildViewController.php
@@ -214,25 +214,33 @@
->setObject($build)
->setObjectURI("/build/{$id}");
- $action =
+ $can_restart = $build->canRestartBuild();
+ $can_stop = $build->canStopBuild();
+ $can_resume = $build->canResumeBuild();
+
+ $list->addAction(
id(new PhabricatorActionView())
- ->setName(pht('Cancel Build'))
- ->setIcon('delete');
- switch ($build->getBuildStatus()) {
- case HarbormasterBuild::STATUS_PENDING:
- case HarbormasterBuild::STATUS_WAITING:
- case HarbormasterBuild::STATUS_BUILDING:
- $cancel_uri = $this->getApplicationURI('/build/cancel/'.$id.'/');
- $action
- ->setHref($cancel_uri)
- ->setWorkflow(true);
- break;
- default:
- $action
- ->setDisabled(true);
- break;
- }
- $list->addAction($action);
+ ->setName(pht('Restart Build'))
+ ->setIcon('backward')
+ ->setHref($this->getApplicationURI('/build/restart/'.$id.'/'))
+ ->setDisabled(!$can_restart)
+ ->setWorkflow(true));
+
+ $list->addAction(
+ id(new PhabricatorActionView())
+ ->setName(pht('Stop Build'))
+ ->setIcon('stop')
+ ->setHref($this->getApplicationURI('/build/stop/'.$id.'/'))
+ ->setDisabled(!$can_stop)
+ ->setWorkflow(true));
+
+ $list->addAction(
+ id(new PhabricatorActionView())
+ ->setName(pht('Resume Build'))
+ ->setIcon('play')
+ ->setHref($this->getApplicationURI('/build/resume/'.$id.'/'))
+ ->setDisabled(!$can_resume)
+ ->setWorkflow(true));
return $list;
}
@@ -272,8 +280,8 @@
}
private function getStatus(HarbormasterBuild $build) {
- if ($build->getCancelRequested()) {
- return pht('Cancelling');
+ if ($build->isStopping()) {
+ return pht('Stopping');
}
switch ($build->getBuildStatus()) {
case HarbormasterBuild::STATUS_INACTIVE:
@@ -290,8 +298,8 @@
return pht('Failed');
case HarbormasterBuild::STATUS_ERROR:
return pht('Unexpected Error');
- case HarbormasterBuild::STATUS_CANCELLED:
- return pht('Cancelled');
+ case HarbormasterBuild::STATUS_STOPPED:
+ return pht('Stopped');
default:
return pht('Unknown');
}
Index: src/applications/harbormaster/controller/HarbormasterBuildableListController.php
===================================================================
--- src/applications/harbormaster/controller/HarbormasterBuildableListController.php
+++ src/applications/harbormaster/controller/HarbormasterBuildableListController.php
@@ -88,10 +88,6 @@
->setViewer($user)
->addNavigationItems($nav->getMenu());
- if ($for_app) {
- $nav->addFilter('new/', pht('New Build Plan'));
- }
-
$nav->addLabel(pht('Build Plans'));
$nav->addFilter('plan/', pht('Manage Build Plans'));
Index: src/applications/harbormaster/controller/HarbormasterBuildableViewController.php
===================================================================
--- src/applications/harbormaster/controller/HarbormasterBuildableViewController.php
+++ src/applications/harbormaster/controller/HarbormasterBuildableViewController.php
@@ -38,9 +38,9 @@
->setObjectName(pht('Build %d', $build->getID()))
->setHeader($build->getName())
->setHref($view_uri);
- if ($build->getCancelRequested()) {
+ if ($build->isStopping()) {
$item->setBarColor('black');
- $item->addAttribute(pht('Cancelling'));
+ $item->addAttribute(pht('Stopping'));
} else {
switch ($build->getBuildStatus()) {
case HarbormasterBuild::STATUS_INACTIVE:
@@ -71,9 +71,9 @@
$item->setBarColor('red');
$item->addAttribute(pht('Unexpected Error'));
break;
- case HarbormasterBuild::STATUS_CANCELLED:
+ case HarbormasterBuild::STATUS_STOPPED:
$item->setBarColor('black');
- $item->addAttribute(pht('Cancelled'));
+ $item->addAttribute(pht('Stopped'));
break;
}
}
Index: src/applications/harbormaster/controller/HarbormasterPlanController.php
===================================================================
--- src/applications/harbormaster/controller/HarbormasterPlanController.php
+++ src/applications/harbormaster/controller/HarbormasterPlanController.php
@@ -1,6 +1,6 @@
<?php
-abstract class HarbormasterPlanController extends PhabricatorController {
+abstract class HarbormasterPlanController extends HarbormasterController {
public function buildApplicationCrumbs() {
$crumbs = parent::buildApplicationCrumbs();
Index: src/applications/harbormaster/controller/HarbormasterPlanListController.php
===================================================================
--- src/applications/harbormaster/controller/HarbormasterPlanListController.php
+++ src/applications/harbormaster/controller/HarbormasterPlanListController.php
@@ -57,6 +57,10 @@
$nav = new AphrontSideNavFilterView();
$nav->setBaseURI(new PhutilURI($this->getApplicationURI()));
+ if ($for_app) {
+ $nav->addFilter('new/', pht('New Build Plan'));
+ }
+
id(new HarbormasterBuildPlanSearchEngine())
->setViewer($user)
->addNavigationItems($nav->getMenu());
Index: src/applications/harbormaster/engine/HarbormasterBuildEngine.php
===================================================================
--- src/applications/harbormaster/engine/HarbormasterBuildEngine.php
+++ src/applications/harbormaster/engine/HarbormasterBuildEngine.php
@@ -72,16 +72,52 @@
}
private function updateBuild(HarbormasterBuild $build) {
- // TODO: Handle cancellation and restarts.
- if ($build->getBuildStatus() == HarbormasterBuild::STATUS_PENDING) {
+ $should_stop = false;
+ $should_resume = false;
+ $should_restart = false;
+ foreach ($build->getUnprocessedCommands() as $command) {
+ switch ($command->getCommand()) {
+ case HarbormasterBuildCommand::COMMAND_STOP:
+ $should_stop = true;
+ $should_resume = false;
+ break;
+ case HarbormasterBuildCommand::COMMAND_RESUME:
+ $should_resume = true;
+ $should_stop = false;
+ break;
+ case HarbormasterBuildCommand::COMMAND_RESTART:
+ $should_restart = true;
+ $should_resume = true;
+ $should_stop = false;
+ break;
+ }
+ }
+
+ if (($build->getBuildStatus() == HarbormasterBuild::STATUS_PENDING) ||
+ ($should_restart)) {
$this->destroyBuildTargets($build);
$build->setBuildStatus(HarbormasterBuild::STATUS_BUILDING);
$build->save();
}
+ if ($should_resume) {
+ $build->setBuildStatus(HarbormasterBuild::STATUS_BUILDING);
+ $build->save();
+ }
+
+ if ($should_stop && !$build->isComplete()) {
+ $build->setBuildStatus(HarbormasterBuild::STATUS_STOPPED);
+ $build->save();
+ }
+
+ foreach ($build->getUnprocessedCommands() as $command) {
+ $command->delete();
+ }
+ $build->attachUnprocessedCommands(array());
+
if ($build->getBuildStatus() == HarbormasterBuild::STATUS_BUILDING) {
- return $this->updateBuildSteps($build);
+ $this->updateBuildSteps($build);
}
}
@@ -118,8 +154,7 @@
if ($step_targets) {
$is_complete = true;
foreach ($step_targets as $target) {
- // TODO: Move this to a top-level "status" field on BuildTarget.
- if (!$target->getDetail('__done__')) {
+ if (!$target->isComplete()) {
$is_complete = false;
break;
}
@@ -127,8 +162,7 @@
$is_failed = false;
foreach ($step_targets as $target) {
- // TODO: Move this to a top-level "status" field on BuildTarget.
- if ($target->getDetail('__failed__')) {
+ if ($target->isFailed()) {
$is_failed = true;
break;
}
@@ -212,7 +246,7 @@
foreach ($runnable as $runnable_step) {
$target = HarbormasterBuildTarget::initializeNewBuildTarget(
$build,
- $step,
+ $runnable_step,
$build->retrieveVariablesFromBuild());
$target->save();
Index: src/applications/harbormaster/event/HarbormasterUIEventListener.php
===================================================================
--- src/applications/harbormaster/event/HarbormasterUIEventListener.php
+++ src/applications/harbormaster/event/HarbormasterUIEventListener.php
@@ -94,8 +94,8 @@
case HarbormasterBuild::STATUS_ERROR:
$item->setIcon('minus-red', pht('Unexpected Error'));
break;
- case HarbormasterBuild::STATUS_CANCELLED:
- $item->setIcon('minus-dark', pht('Cancelled'));
+ case HarbormasterBuild::STATUS_STOPPED:
+ $item->setIcon('minus-dark', pht('Stopped'));
break;
default:
$item->setIcon('question', pht('Unknown'));
Index: src/applications/harbormaster/query/HarbormasterBuildQuery.php
===================================================================
--- src/applications/harbormaster/query/HarbormasterBuildQuery.php
+++ src/applications/harbormaster/query/HarbormasterBuildQuery.php
@@ -92,6 +92,16 @@
$build->attachBuildPlan(idx($plans, $plan_phid));
}
+ $build_phids = mpull($page, 'getPHID');
+ $commands = id(new HarbormasterBuildCommand())->loadAllWhere(
+ 'targetPHID IN (%Ls) ORDER BY id ASC',
+ $build_phids);
+ $commands = mgroup($commands, 'getTargetPHID');
+ foreach ($page as $build) {
+ $unprocessed_commands = idx($commands, $build->getPHID(), array());
+ $build->attachUnprocessedCommands($unprocessed_commands);
+ }
+
return $page;
}
Index: src/applications/harbormaster/step/WaitForPreviousBuildStepImplementation.php
===================================================================
--- src/applications/harbormaster/step/WaitForPreviousBuildStepImplementation.php
+++ src/applications/harbormaster/step/WaitForPreviousBuildStepImplementation.php
@@ -113,7 +113,7 @@
->execute();
foreach ($builds as $build) {
- if ($build->isBuilding()) {
+ if (!$build->isComplete()) {
$blockers[] = pht('Build %d', $build->getID());
}
}
Index: src/applications/harbormaster/storage/HarbormasterBuildCommand.php
===================================================================
--- /dev/null
+++ src/applications/harbormaster/storage/HarbormasterBuildCommand.php
@@ -0,0 +1,13 @@
+<?php
+
+final class HarbormasterBuildCommand extends HarbormasterDAO {
+
+ const COMMAND_STOP = 'stop';
+ const COMMAND_RESUME = 'resume';
+ const COMMAND_RESTART = 'restart';
+
+ protected $authorPHID;
+ protected $targetPHID;
+ protected $command;
+
+}
Index: src/applications/harbormaster/storage/build/HarbormasterBuild.php
===================================================================
--- src/applications/harbormaster/storage/build/HarbormasterBuild.php
+++ src/applications/harbormaster/storage/build/HarbormasterBuild.php
@@ -6,10 +6,10 @@
protected $buildablePHID;
protected $buildPlanPHID;
protected $buildStatus;
- protected $cancelRequested;
private $buildable = self::ATTACHABLE;
private $buildPlan = self::ATTACHABLE;
+ private $unprocessedCommands = self::ATTACHABLE;
/**
* Not currently being built.
@@ -47,14 +47,13 @@
const STATUS_ERROR = 'error';
/**
- * The build has been cancelled.
+ * The build has been stopped.
*/
- const STATUS_CANCELLED = 'cancelled';
+ const STATUS_STOPPED = 'stopped';
public static function initializeNewBuild(PhabricatorUser $actor) {
return id(new HarbormasterBuild())
- ->setBuildStatus(self::STATUS_INACTIVE)
- ->setCancelRequested(0);
+ ->setBuildStatus(self::STATUS_INACTIVE);
}
public function getConfiguration() {
@@ -97,8 +96,7 @@
public function isBuilding() {
return $this->getBuildStatus() === self::STATUS_PENDING ||
$this->getBuildStatus() === self::STATUS_WAITING ||
- $this->getBuildStatus() === self::STATUS_BUILDING ||
- $this->getCancelRequested();
+ $this->getBuildStatus() === self::STATUS_BUILDING;
}
public function createLog(
@@ -106,10 +104,11 @@
$log_source,
$log_type) {
- $log = HarbormasterBuildLog::initializeNewBuildLog($build_target);
- $log->setLogSource($log_source);
- $log->setLogType($log_type);
- $log->save();
+ $log = HarbormasterBuildLog::initializeNewBuildLog($build_target)
+ ->setLogSource($log_source)
+ ->setLogType($log_type)
+ ->save();
+
return $log;
}
@@ -139,25 +138,6 @@
return $artifact;
}
- /**
- * Checks for and handles build cancellation. If this method returns
- * true, the caller should stop any current operations and return control
- * as quickly as possible.
- */
- public function checkForCancellation() {
- // Here we load a copy of the current build and check whether
- // the user requested cancellation. We can't do `reload()` here
- // in case there are changes that have not yet been saved.
- $copy = id(new HarbormasterBuild())->load($this->getID());
- if ($copy->getCancelRequested()) {
- $this->setBuildStatus(HarbormasterBuild::STATUS_CANCELLED);
- $this->setCancelRequested(0);
- $this->save();
- return true;
- }
- return false;
- }
-
public function retrieveVariablesFromBuild() {
$results = array(
'buildable.diff' => null,
@@ -212,6 +192,71 @@
'build.id' => pht('The ID of the current build.'));
}
+ public function isComplete() {
+ switch ($this->getBuildStatus()) {
+ case self::STATUS_PASSED:
+ case self::STATUS_FAILED:
+ case self::STATUS_ERROR:
+ case self::STATUS_STOPPED:
+ return true;
+ }
+
+ return false;
+ }
+
+ public function isStopped() {
+ return ($this->getBuildStatus() == self::STATUS_STOPPED);
+ }
+
+
+/* -( Build Commands )----------------------------------------------------- */
+
+
+ public function getUnprocessedCommands() {
+ return $this->assertAttached($this->unprocessedCommands);
+ }
+
+ public function attachUnprocessedCommands(array $commands) {
+ $this->unprocessedCommands = $commands;
+ return $this;
+ }
+
+ public function hasWaitingCommand($command_name) {
+ foreach ($this->getUnprocessedCommands() as $command_object) {
+ if ($command_object->getCommand() == $command_name) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public function canRestartBuild() {
+ return !$this->isRestarting();
+ }
+
+ public function canStopBuild() {
+ return !$this->isComplete() &&
+ !$this->isStopped() &&
+ !$this->isStopping();
+ }
+
+ public function canResumeBuild() {
+ return $this->isStopped() &&
+ !$this->isResuming();
+ }
+
+ public function isStopping() {
+ return $this->hasWaitingCommand(HarbormasterBuildCommand::COMMAND_STOP);
+ }
+
+ public function isResuming() {
+ return $this->hasWaitingCommand(HarbormasterBuildCommand::COMMAND_RESUME);
+ }
+
+ public function isRestarting() {
+ return $this->hasWaitingCommand(HarbormasterBuildCommand::COMMAND_RESTART);
+ }
+
/* -( PhabricatorPolicyInterface )----------------------------------------- */
Index: src/applications/harbormaster/storage/build/HarbormasterBuildTarget.php
===================================================================
--- src/applications/harbormaster/storage/build/HarbormasterBuildTarget.php
+++ src/applications/harbormaster/storage/build/HarbormasterBuildTarget.php
@@ -8,6 +8,11 @@
protected $className;
protected $details;
protected $variables;
+ protected $targetStatus;
+
+ const STATUS_PENDING = 'target/pending';
+ const STATUS_PASSED = 'target/passed';
+ const STATUS_FAILED = 'target/failed';
private $build = self::ATTACHABLE;
private $buildStep = self::ATTACHABLE;
@@ -21,6 +26,7 @@
->setBuildStepPHID($build_step->getPHID())
->setClassName($build_step->getClassName())
->setDetails($build_step->getDetails())
+ ->setTargetStatus(self::STATUS_PENDING)
->setVariables($variables);
}
@@ -96,6 +102,30 @@
}
+/* -( Status )------------------------------------------------------------- */
+
+
+ public function isComplete() {
+ switch ($this->getTargetStatus()) {
+ case self::STATUS_PASSED:
+ case self::STATUS_FAILED:
+ return true;
+ }
+
+ return false;
+ }
+
+
+ public function isFailed() {
+ switch ($this->getTargetStatus()) {
+ case self::STATUS_FAILED:
+ return true;
+ }
+
+ return false;
+ }
+
+
/* -( PhabricatorPolicyInterface )----------------------------------------- */
Index: src/applications/harbormaster/worker/HarbormasterTargetWorker.php
===================================================================
--- src/applications/harbormaster/worker/HarbormasterTargetWorker.php
+++ src/applications/harbormaster/worker/HarbormasterTargetWorker.php
@@ -38,15 +38,15 @@
try {
$implementation = $target->getImplementation();
if (!$implementation->validateSettings()) {
- $target->setDetail('__failed__', true);
+ $target->setTargetStatus(HarbormasterBuildTarget::STATUS_FAILED);
$target->save();
} else {
$implementation->execute($build, $target);
- $target->setDetail('__done__', true);
+ $target->setTargetStatus(HarbormasterBuildTarget::STATUS_PASSED);
$target->save();
}
} catch (Exception $ex) {
- $target->setDetail('__failed__', true);
+ $target->setTargetStatus(HarbormasterBuildTarget::STATUS_FAILED);
$target->save();
}

File Metadata

Mime Type
text/plain
Expires
Fri, Mar 7, 9:18 AM (20 h, 3 m)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7329239
Default Alt Text
D7892.diff (28 KB)

Event Timeline