Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F15464753
D7498.id16904.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
12 KB
Referenced Files
None
Subscribers
None
D7498.id16904.diff
View Options
Index: src/__phutil_library_map__.php
===================================================================
--- src/__phutil_library_map__.php
+++ src/__phutil_library_map__.php
@@ -657,6 +657,7 @@
'HarbormasterBuildTarget' => 'applications/harbormaster/storage/build/HarbormasterBuildTarget.php',
'HarbormasterBuildTargetQuery' => 'applications/harbormaster/query/HarbormasterBuildTargetQuery.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',
@@ -1330,6 +1331,7 @@
'PhabricatorGlobalUploadTargetView' => 'applications/files/view/PhabricatorGlobalUploadTargetView.php',
'PhabricatorHandleObjectSelectorDataView' => 'applications/phid/handle/view/PhabricatorHandleObjectSelectorDataView.php',
'PhabricatorHandleQuery' => 'applications/phid/query/PhabricatorHandleQuery.php',
+ 'PhabricatorHarbormasterBuildDaemon' => 'applications/harbormaster/daemon/PhabricatorHarbormasterBuildDaemon.php',
'PhabricatorHash' => 'infrastructure/util/PhabricatorHash.php',
'PhabricatorHashTestCase' => 'infrastructure/util/__tests__/PhabricatorHashTestCase.php',
'PhabricatorHelpController' => 'applications/help/controller/PhabricatorHelpController.php',
@@ -2873,6 +2875,7 @@
0 => 'HarbormasterDAO',
1 => 'PhabricatorPolicyInterface',
),
+ 'HarbormasterBuildableApplyController' => 'HarbormasterController',
'HarbormasterBuildableArtifactQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'HarbormasterBuildableEditController' => 'HarbormasterController',
'HarbormasterBuildableListController' =>
@@ -3638,6 +3641,7 @@
'PhabricatorGlobalLock' => 'PhutilLock',
'PhabricatorGlobalUploadTargetView' => 'AphrontView',
'PhabricatorHandleQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
+ 'PhabricatorHarbormasterBuildDaemon' => 'PhabricatorDaemon',
'PhabricatorHashTestCase' => 'PhabricatorTestCase',
'PhabricatorHelpController' => 'PhabricatorController',
'PhabricatorHelpKeyboardShortcutController' => 'PhabricatorHelpController',
Index: src/applications/harbormaster/application/PhabricatorApplicationHarbormaster.php
===================================================================
--- src/applications/harbormaster/application/PhabricatorApplicationHarbormaster.php
+++ src/applications/harbormaster/application/PhabricatorApplicationHarbormaster.php
@@ -44,6 +44,7 @@
=> 'HarbormasterBuildableListController',
'buildable/' => array(
'edit/(?:(?P<id>\d+)/)?' => 'HarbormasterBuildableEditController',
+ 'apply/(?:(?P<id>\d+)/)?' => 'HarbormasterBuildableApplyController',
),
'plan/' => array(
'(?:query/(?P<queryKey>[^/]+)/)?'
Index: src/applications/harbormaster/controller/HarbormasterBuildableApplyController.php
===================================================================
--- /dev/null
+++ src/applications/harbormaster/controller/HarbormasterBuildableApplyController.php
@@ -0,0 +1,74 @@
+<?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!");
+ }
+
+ 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();
+
+ return id(new AphrontRedirectResponse());
+ }
+
+ $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('Apply')
+ ->addCancelButton('Cancel');
+ $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));
+ $dialog->addHiddenInput('confirmed', "true");
+ 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/daemon/PhabricatorHarbormasterBuildDaemon.php
===================================================================
--- /dev/null
+++ src/applications/harbormaster/daemon/PhabricatorHarbormasterBuildDaemon.php
@@ -0,0 +1,51 @@
+<?php
+
+/**
+ * Run builds
+ */
+final class PhabricatorHarbormasterBuildDaemon
+ extends PhabricatorDaemon {
+
+ public function run() {
+ while (true) {
+
+ // Take exactly one build off the queue.
+ $build = id(new HarbormasterBuildQuery())
+ ->setViewer(PhabricatorUser::getOmnipotentUser())
+ ->withBuildStatuses(array(HarbormasterBuild::STATUS_PENDING))
+ ->needBuildPlans(true)
+ ->executeOne();
+ if ($build === null) {
+ $this->sleep(15);
+ continue;
+ }
+
+ try {
+ // FIXME: Make this actually atomic in case someone is running two
+ // or more build daemons.
+ $build->setBuildStatus(HarbormasterBuild::STATUS_BUILDING);
+ $build->save();
+
+ $buildable = $build->getBuildable();
+ $plan = $build->getBuildPlan();
+
+ // TODO: Do the actual build here.
+ $this->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;
+ }
+
+ $this->sleep(15);
+ }
+ }
+
+}
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() {
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Apr 3, 12:41 PM (1 w, 3 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7472134
Default Alt Text
D7498.id16904.diff (12 KB)
Attached To
Mode
D7498: Implement basic Harbormaster daemon and start builds.
Attached
Detach File
Event Timeline
Log In to Comment