Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F15454413
D7498.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
19 KB
Referenced Files
None
Subscribers
None
D7498.diff
View Options
Index: src/__phutil_library_map__.php
===================================================================
--- src/__phutil_library_map__.php
+++ src/__phutil_library_map__.php
@@ -656,7 +656,9 @@
'HarbormasterBuildStepQuery' => 'applications/harbormaster/query/HarbormasterBuildStepQuery.php',
'HarbormasterBuildTarget' => 'applications/harbormaster/storage/build/HarbormasterBuildTarget.php',
'HarbormasterBuildTargetQuery' => 'applications/harbormaster/query/HarbormasterBuildTargetQuery.php',
+ 'HarbormasterBuildWorker' => 'applications/harbormaster/worker/HarbormasterBuildWorker.php',
'HarbormasterBuildable' => 'applications/harbormaster/storage/HarbormasterBuildable.php',
+ 'HarbormasterBuildableApplyController' => 'applications/harbormaster/controller/HarbormasterBuildableApplyController.php',
'HarbormasterBuildableArtifactQuery' => 'applications/harbormaster/query/HarbormasterBuildableArtifactQuery.php',
'HarbormasterBuildableEditController' => 'applications/harbormaster/controller/HarbormasterBuildableEditController.php',
'HarbormasterBuildableListController' => 'applications/harbormaster/controller/HarbormasterBuildableListController.php',
@@ -675,11 +677,9 @@
'HarbormasterPHIDTypeBuildable' => 'applications/harbormaster/phid/HarbormasterPHIDTypeBuildable.php',
'HarbormasterPlanController' => 'applications/harbormaster/controller/HarbormasterPlanController.php',
'HarbormasterPlanEditController' => 'applications/harbormaster/controller/HarbormasterPlanEditController.php',
- 'HarbormasterPlanExecuteController' => 'applications/harbormaster/controller/HarbormasterPlanExecuteController.php',
'HarbormasterPlanListController' => 'applications/harbormaster/controller/HarbormasterPlanListController.php',
'HarbormasterPlanViewController' => 'applications/harbormaster/controller/HarbormasterPlanViewController.php',
'HarbormasterRemarkupRule' => 'applications/harbormaster/remarkup/HarbormasterRemarkupRule.php',
- 'HarbormasterRunnerWorker' => 'applications/harbormaster/worker/HarbormasterRunnerWorker.php',
'HarbormasterScratchTable' => 'applications/harbormaster/storage/HarbormasterScratchTable.php',
'HeraldAction' => 'applications/herald/storage/HeraldAction.php',
'HeraldAdapter' => 'applications/herald/adapter/HeraldAdapter.php',
@@ -2868,11 +2868,13 @@
'HarbormasterBuildStepQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'HarbormasterBuildTarget' => 'HarbormasterDAO',
'HarbormasterBuildTargetQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
+ 'HarbormasterBuildWorker' => 'PhabricatorWorker',
'HarbormasterBuildable' =>
array(
0 => 'HarbormasterDAO',
1 => 'PhabricatorPolicyInterface',
),
+ 'HarbormasterBuildableApplyController' => 'HarbormasterController',
'HarbormasterBuildableArtifactQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'HarbormasterBuildableEditController' => 'HarbormasterController',
'HarbormasterBuildableListController' =>
@@ -2895,7 +2897,6 @@
'HarbormasterPHIDTypeBuildable' => 'PhabricatorPHIDType',
'HarbormasterPlanController' => 'PhabricatorController',
'HarbormasterPlanEditController' => 'HarbormasterPlanController',
- 'HarbormasterPlanExecuteController' => 'HarbormasterPlanController',
'HarbormasterPlanListController' =>
array(
0 => 'HarbormasterPlanController',
@@ -2903,7 +2904,6 @@
),
'HarbormasterPlanViewController' => 'HarbormasterPlanController',
'HarbormasterRemarkupRule' => 'PhabricatorRemarkupRuleObject',
- 'HarbormasterRunnerWorker' => 'PhabricatorWorker',
'HarbormasterScratchTable' => 'HarbormasterDAO',
'HeraldAction' => 'HeraldDAO',
'HeraldApplyTranscript' => 'HeraldDAO',
Index: src/applications/harbormaster/application/PhabricatorApplicationHarbormaster.php
===================================================================
--- src/applications/harbormaster/application/PhabricatorApplicationHarbormaster.php
+++ src/applications/harbormaster/application/PhabricatorApplicationHarbormaster.php
@@ -44,13 +44,13 @@
=> 'HarbormasterBuildableListController',
'buildable/' => array(
'edit/(?:(?P<id>\d+)/)?' => 'HarbormasterBuildableEditController',
+ 'apply/(?:(?P<id>\d+)/)?' => 'HarbormasterBuildableApplyController',
),
'plan/' => array(
'(?:query/(?P<queryKey>[^/]+)/)?'
=> 'HarbormasterPlanListController',
'edit/(?:(?P<id>\d+)/)?' => 'HarbormasterPlanEditController',
'(?P<id>\d+)/' => 'HarbormasterPlanViewController',
- 'execute/(?P<id>\d+)/' => 'HarbormasterPlanExecuteController',
),
),
);
Index: src/applications/harbormaster/controller/HarbormasterBuildableApplyController.php
===================================================================
--- /dev/null
+++ src/applications/harbormaster/controller/HarbormasterBuildableApplyController.php
@@ -0,0 +1,81 @@
+<?php
+
+final class HarbormasterBuildableApplyController
+ 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;
+
+ $buildable = id(new HarbormasterBuildableQuery())
+ ->setViewer($viewer)
+ ->withIDs(array($id))
+ ->executeOne();
+ if ($buildable === null) {
+ throw new Exception("Buildable not found!");
+ }
+
+ $buildable_uri = '/B'.$buildable->getID();
+
+ if ($request->isDialogFormPost()) {
+ $plan = id(new HarbormasterBuildPlanQuery())
+ ->setViewer($viewer)
+ ->withIDs(array($request->getInt('build-plan')))
+ ->executeOne();
+
+ $build = HarbormasterBuild::initializeNewBuild($viewer);
+ $build->setBuildablePHID($buildable->getPHID());
+ $build->setBuildPlanPHID($plan->getPHID());
+ $build->setBuildStatus(HarbormasterBuild::STATUS_PENDING);
+ $build->save();
+
+ PhabricatorWorker::scheduleTask(
+ 'HarbormasterBuildWorker',
+ array(
+ 'buildID' => $build->getID()
+ ));
+
+ return id(new AphrontRedirectResponse())->setURI($buildable_uri);
+ }
+
+ $plans = id(new HarbormasterBuildPlanQuery())
+ ->setViewer($viewer)
+ ->execute();
+
+ $options = array();
+ foreach ($plans as $plan) {
+ $options[$plan->getID()] = $plan->getName();
+ }
+
+ // FIXME: I'd really like to use the dialog that "Edit Differential
+ // Revisions" uses, but that code is quite hard-coded for the particular
+ // uses, so for now we just give a single dropdown.
+
+ $dialog = new AphrontDialogView();
+ $dialog->setTitle(pht('Apply which plan?'))
+ ->setUser($viewer)
+ ->addSubmitButton(pht('Apply'))
+ ->addCancelButton($buildable_uri);
+ $dialog->appendChild(
+ phutil_tag(
+ 'p',
+ array(),
+ pht(
+ 'Select what build plan you want to apply to this buildable:')));
+ $dialog->appendChild(
+ id(new AphrontFormSelectControl())
+ ->setUser($viewer)
+ ->setName('build-plan')
+ ->setOptions($options));
+ return id(new AphrontDialogResponse())->setDialog($dialog);
+ }
+
+}
Index: src/applications/harbormaster/controller/HarbormasterBuildableListController.php
===================================================================
--- src/applications/harbormaster/controller/HarbormasterBuildableListController.php
+++ src/applications/harbormaster/controller/HarbormasterBuildableListController.php
@@ -36,7 +36,7 @@
$id = $buildable->getID();
$item = id(new PHUIObjectItemView())
- ->setHeader(pht('Build %d', $buildable->getID()));
+ ->setHeader(pht('Buildable %d', $buildable->getID()));
if ($id) {
$item->setHref("/B{$id}");
Index: src/applications/harbormaster/controller/HarbormasterBuildableViewController.php
===================================================================
--- src/applications/harbormaster/controller/HarbormasterBuildableViewController.php
+++ src/applications/harbormaster/controller/HarbormasterBuildableViewController.php
@@ -37,6 +37,32 @@
$item = id(new PHUIObjectItemView())
->setObjectName(pht('Build %d', $build->getID()))
->setHeader($build->getName());
+ switch ($build->getBuildStatus()) {
+ case HarbormasterBuild::STATUS_INACTIVE:
+ $item->setBarColor('grey');
+ $item->addAttribute(pht('Inactive'));
+ break;
+ case HarbormasterBuild::STATUS_PENDING:
+ $item->setBarColor('blue');
+ $item->addAttribute(pht('Pending'));
+ break;
+ case HarbormasterBuild::STATUS_WAITING:
+ $item->setBarColor('blue');
+ $item->addAttribute(pht('Waiting on Resource'));
+ break;
+ case HarbormasterBuild::STATUS_BUILDING:
+ $item->setBarColor('yellow');
+ $item->addAttribute(pht('Building'));
+ break;
+ case HarbormasterBuild::STATUS_PASSED:
+ $item->setBarColor('green');
+ $item->addAttribute(pht('Passed'));
+ break;
+ case HarbormasterBuild::STATUS_FAILED:
+ $item->setBarColor('red');
+ $item->addAttribute(pht('Failed'));
+ break;
+ }
$build_list->addItem($item);
}
@@ -80,6 +106,15 @@
->setObject($buildable)
->setObjectURI("/B{$id}");
+ $apply_uri = $this->getApplicationURI('/buildable/apply/'.$id.'/');
+
+ $list->addAction(
+ id(new PhabricatorActionView())
+ ->setName(pht('Apply Build Plan'))
+ ->setIcon('edit')
+ ->setHref($apply_uri)
+ ->setWorkflow(true));
+
return $list;
}
Index: src/applications/harbormaster/controller/HarbormasterPlanExecuteController.php
===================================================================
--- src/applications/harbormaster/controller/HarbormasterPlanExecuteController.php
+++ /dev/null
@@ -1,88 +0,0 @@
-<?php
-
-final class HarbormasterPlanExecuteController
- extends HarbormasterPlanController {
-
- private $id;
-
- public function willProcessRequest(array $data) {
- $this->id = $data['id'];
- }
-
- public function processRequest() {
- $request = $this->getRequest();
- $viewer = $request->getUser();
-
- $this->requireApplicationCapability(
- HarbormasterCapabilityManagePlans::CAPABILITY);
-
- $id = $this->id;
-
- $plan = id(new HarbormasterBuildPlanQuery())
- ->setViewer($viewer)
- ->withIDs(array($id))
- ->executeOne();
- if (!$plan) {
- return new Aphront404Response();
- }
-
- $cancel_uri = $this->getApplicationURI("plan/{$id}/");
-
- $v_buildable = null;
- $e_buildable = null;
-
- $errors = array();
- if ($request->isFormPost()) {
- $v_buildable = $request->getStr('buildable');
-
- if ($v_buildable) {
- $buildable = id(new HarbormasterBuildableQuery())
- ->setViewer($viewer)
- ->withIDs(array(trim($v_buildable, 'B')))
- ->executeOne();
- if (!$buildable) {
- $e_buildable = pht('Invalid');
- }
- } else {
- $e_buildable = pht('Required');
- $errors[] = pht('You must provide a buildable.');
- }
-
- if (!$errors) {
- $build_plan = HarbormasterBuild::initializeNewBuild($viewer)
- ->setBuildablePHID($buildable->getPHID())
- ->setBuildPlanPHID($plan->getPHID())
- ->save();
-
- $buildable_id = $buildable->getID();
-
- return id(new AphrontRedirectResponse())
- ->setURI("/B{$buildable_id}");
- }
- }
-
- if ($errors) {
- $errors = id(new AphrontErrorView())->setErrors($errors);
- }
-
- $form = id(new PHUIFormLayoutView())
- ->appendChild(
- id(new AphrontFormTextControl())
- ->setLabel(pht('Buildable'))
- ->setName('buildable')
- ->setValue($v_buildable)
- ->setError($e_buildable));
-
- $dialog = id(new AphrontDialogView())
- ->setUser($viewer)
- ->setTitle(pht('Execute Build Plan'))
- ->setWidth(AphrontDialogView::WIDTH_FORM)
- ->appendChild($errors)
- ->appendChild($form)
- ->addSubmitButton(pht('Execute Build Plan'))
- ->addCancelButton($cancel_uri);
-
- return id(new AphrontDialogResponse())->setDialog($dialog);
- }
-
-}
Index: src/applications/harbormaster/controller/HarbormasterPlanViewController.php
===================================================================
--- src/applications/harbormaster/controller/HarbormasterPlanViewController.php
+++ src/applications/harbormaster/controller/HarbormasterPlanViewController.php
@@ -88,14 +88,6 @@
->setDisabled(!$can_edit)
->setIcon('edit'));
- $list->addAction(
- id(new PhabricatorActionView())
- ->setName(pht('Manually Execute Plan'))
- ->setHref($this->getApplicationURI("plan/execute/{$id}/"))
- ->setWorkflow(true)
- ->setDisabled(!$can_edit)
- ->setIcon('arrow_right'));
-
return $list;
}
Index: src/applications/harbormaster/query/HarbormasterBuildQuery.php
===================================================================
--- src/applications/harbormaster/query/HarbormasterBuildQuery.php
+++ src/applications/harbormaster/query/HarbormasterBuildQuery.php
@@ -5,6 +5,7 @@
private $ids;
private $phids;
+ private $buildStatuses;
private $buildablePHIDs;
private $buildPlanPHIDs;
@@ -20,6 +21,11 @@
return $this;
}
+ public function withBuildStatuses(array $build_statuses) {
+ $this->buildStatuses = $build_statuses;
+ return $this;
+ }
+
public function withBuildablePHIDs(array $buildable_phids) {
$this->buildablePHIDs = $buildable_phids;
return $this;
@@ -115,6 +121,13 @@
$this->phids);
}
+ if ($this->buildStatuses) {
+ $where[] = qsprintf(
+ $conn_r,
+ 'buildStatus in (%Ls)',
+ $this->buildStatuses);
+ }
+
if ($this->buildablePHIDs) {
$where[] = qsprintf(
$conn_r,
Index: src/applications/harbormaster/storage/HarbormasterBuildable.php
===================================================================
--- src/applications/harbormaster/storage/HarbormasterBuildable.php
+++ src/applications/harbormaster/storage/HarbormasterBuildable.php
@@ -12,10 +12,12 @@
private $containerObject = self::ATTACHABLE;
private $buildableHandle = self::ATTACHABLE;
+ const STATUS_WHATEVER = 'whatever';
+
public static function initializeNewBuildable(PhabricatorUser $actor) {
return id(new HarbormasterBuildable())
- ->setBuildStatus('new') // TODO: Define these.
- ->setBuildableStatus('active'); // TODO: Define these, too.
+ ->setBuildStatus(self::STATUS_WHATEVER)
+ ->setBuildableStatus(self::STATUS_WHATEVER);
}
public function getConfiguration() {
Index: src/applications/harbormaster/storage/build/HarbormasterBuild.php
===================================================================
--- src/applications/harbormaster/storage/build/HarbormasterBuild.php
+++ src/applications/harbormaster/storage/build/HarbormasterBuild.php
@@ -10,9 +10,39 @@
private $buildable = self::ATTACHABLE;
private $buildPlan = self::ATTACHABLE;
+ /**
+ * Not currently being built.
+ */
+ const STATUS_INACTIVE = 'inactive';
+
+ /**
+ * Pending pick up by the Harbormaster daemon.
+ */
+ const STATUS_PENDING = 'pending';
+
+ /**
+ * Waiting for a resource to be allocated (not yet relevant).
+ */
+ const STATUS_WAITING = 'waiting';
+
+ /**
+ * Current building the buildable.
+ */
+ const STATUS_BUILDING = 'building';
+
+ /**
+ * The build has passed.
+ */
+ const STATUS_PASSED = 'passed';
+
+ /**
+ * The build has failed.
+ */
+ const STATUS_FAILED = 'failed';
+
public static function initializeNewBuild(PhabricatorUser $actor) {
return id(new HarbormasterBuild())
- ->setBuildStatus('building'); // TODO: Sort this.
+ ->setBuildStatus(self::STATUS_INACTIVE);
}
public function getConfiguration() {
Index: src/applications/harbormaster/worker/HarbormasterBuildWorker.php
===================================================================
--- /dev/null
+++ src/applications/harbormaster/worker/HarbormasterBuildWorker.php
@@ -0,0 +1,51 @@
+<?php
+
+/**
+ * Run builds
+ */
+final class HarbormasterBuildWorker extends PhabricatorWorker {
+
+ public function getRequiredLeaseTime() {
+ return 60 * 60 * 24;
+ }
+
+ public function doWork() {
+ $data = $this->getTaskData();
+ $id = idx($data, 'buildID');
+
+ // Get a reference to the build.
+ $build = id(new HarbormasterBuildQuery())
+ ->setViewer(PhabricatorUser::getOmnipotentUser())
+ ->withBuildStatuses(array(HarbormasterBuild::STATUS_PENDING))
+ ->withIDs(array($id))
+ ->needBuildPlans(true)
+ ->executeOne();
+ if (!$build) {
+ throw new PhabricatorWorkerPermanentFailureException(
+ pht('Invalid build ID "%s".', $id));
+ }
+
+ try {
+ $build->setBuildStatus(HarbormasterBuild::STATUS_BUILDING);
+ $build->save();
+
+ $buildable = $build->getBuildable();
+ $plan = $build->getBuildPlan();
+
+ // TODO: Do the actual build here.
+ sleep(15);
+
+ // If we get to here, then the build has passed.
+ $build->setBuildStatus(HarbormasterBuild::STATUS_PASSED);
+ $build->save();
+ } catch (Exception $e) {
+ // If any exception is raised, the build is marked as a failure and
+ // the exception is re-thrown (this ensures we don't leave builds
+ // in an inconsistent state).
+ $build->setBuildStatus(HarbormasterBuild::STATUS_FAILED);
+ $build->save();
+ throw $e;
+ }
+ }
+
+}
Index: src/applications/harbormaster/worker/HarbormasterRunnerWorker.php
===================================================================
--- src/applications/harbormaster/worker/HarbormasterRunnerWorker.php
+++ /dev/null
@@ -1,53 +0,0 @@
-<?php
-
-final class HarbormasterRunnerWorker extends PhabricatorWorker {
-
- public function getRequiredLeaseTime() {
- return 60 * 60 * 24;
- }
-
- protected function doWork() {
- $data = $this->getTaskData();
- $id = idx($data, 'commitID');
-
- $commit = id(new PhabricatorRepositoryCommit())->loadOneWhere(
- 'id = %d',
- $id);
-
- if (!$commit) {
- throw new PhabricatorWorkerPermanentFailureException(
- "Commit '{$id}' does not exist!");
- }
-
- // TODO: (T603) Policy interaction?
- $repository = id(new PhabricatorRepository())->loadOneWhere(
- 'id = %d',
- $commit->getRepositoryID());
-
- if (!$repository) {
- throw new PhabricatorWorkerPermanentFailureException(
- "Unable to load repository for commit '{$id}'!");
- }
-
- $lease = id(new DrydockLease())
- ->setResourceType('working-copy')
- ->setAttributes(
- array(
- 'repositoryID' => $repository->getID(),
- 'commit' => $commit->getCommitIdentifier(),
- ))
- ->releaseOnDestruction()
- ->waitUntilActive();
-
- $cmd = $lease->getInterface('command');
- list($json) = $cmd
- ->setWorkingDirectory($lease->getResource()->getAttribute('path'))
- ->execx('arc unit --everything --json');
- $lease->release();
-
- // TODO: Do something actually useful with this. Requires Harbormaster
- // buildout.
- echo $json;
- }
-
-}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Mar 30, 6:25 PM (2 w, 3 h ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7523497
Default Alt Text
D7498.diff (19 KB)
Attached To
Mode
D7498: Implement basic Harbormaster daemon and start builds.
Attached
Detach File
Event Timeline
Log In to Comment