Page MenuHomePhabricator

D19102.id45769.diff
No OneTemporary

D19102.id45769.diff

diff --git a/resources/sql/autopatches/20180213.hoax.01.hoax.sql b/resources/sql/autopatches/20180213.hoax.01.hoax.sql
new file mode 100644
--- /dev/null
+++ b/resources/sql/autopatches/20180213.hoax.01.hoax.sql
@@ -0,0 +1,8 @@
+CREATE TABLE {$NAMESPACE}_drydock.drydock_hoax (
+ id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
+ phid VARBINARY(64) NOT NULL,
+ name VARCHAR(128) NOT NULL COLLATE {$COLLATE_TEXT},
+ state VARCHAR(32) NOT NULL COLLATE {$COLLATE_TEXT},
+ dateCreated INT UNSIGNED NOT NULL,
+ dateModified INT UNSIGNED NOT NULL
+) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT};
diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -1048,6 +1048,11 @@
'DrydockDefaultEditCapability' => 'applications/drydock/capability/DrydockDefaultEditCapability.php',
'DrydockDefaultViewCapability' => 'applications/drydock/capability/DrydockDefaultViewCapability.php',
'DrydockFilesystemInterface' => 'applications/drydock/interface/filesystem/DrydockFilesystemInterface.php',
+ 'DrydockHoax' => 'applications/drydock/storage/DrydockHoax.php',
+ 'DrydockHoaxBlueprintImplementation' => 'applications/drydock/blueprint/DrydockHoaxBlueprintImplementation.php',
+ 'DrydockHoaxCommandInterface' => 'applications/drydock/interface/command/DrydockHoaxCommandInterface.php',
+ 'DrydockHoaxLog' => 'applications/drydock/storage/DrydockHoaxLog.php',
+ 'DrydockHoaxPHIDType' => 'applications/drydock/phid/DrydockHoaxPHIDType.php',
'DrydockInterface' => 'applications/drydock/interface/DrydockInterface.php',
'DrydockLandRepositoryOperation' => 'applications/drydock/operation/DrydockLandRepositoryOperation.php',
'DrydockLease' => 'applications/drydock/storage/DrydockLease.php',
@@ -1084,6 +1089,7 @@
'DrydockLogSearchEngine' => 'applications/drydock/query/DrydockLogSearchEngine.php',
'DrydockLogType' => 'applications/drydock/logtype/DrydockLogType.php',
'DrydockManagementCommandWorkflow' => 'applications/drydock/management/DrydockManagementCommandWorkflow.php',
+ 'DrydockManagementHoaxWorkflow' => 'applications/drydock/management/DrydockManagementHoaxWorkflow.php',
'DrydockManagementLeaseWorkflow' => 'applications/drydock/management/DrydockManagementLeaseWorkflow.php',
'DrydockManagementReclaimWorkflow' => 'applications/drydock/management/DrydockManagementReclaimWorkflow.php',
'DrydockManagementReleaseLeaseWorkflow' => 'applications/drydock/management/DrydockManagementReleaseLeaseWorkflow.php',
@@ -6269,6 +6275,17 @@
'DrydockDefaultEditCapability' => 'PhabricatorPolicyCapability',
'DrydockDefaultViewCapability' => 'PhabricatorPolicyCapability',
'DrydockFilesystemInterface' => 'DrydockInterface',
+ 'DrydockHoax' => array(
+ 'DrydockDAO',
+ 'PhabricatorPolicyInterface',
+ ),
+ 'DrydockHoaxBlueprintImplementation' => 'DrydockBlueprintImplementation',
+ 'DrydockHoaxCommandInterface' => 'DrydockCommandInterface',
+ 'DrydockHoaxLog' => array(
+ 'DrydockDAO',
+ 'PhabricatorPolicyInterface',
+ ),
+ 'DrydockHoaxPHIDType' => 'PhabricatorPHIDType',
'DrydockInterface' => 'Phobject',
'DrydockLandRepositoryOperation' => 'DrydockRepositoryOperationType',
'DrydockLease' => array(
@@ -6311,6 +6328,7 @@
'DrydockLogSearchEngine' => 'PhabricatorApplicationSearchEngine',
'DrydockLogType' => 'Phobject',
'DrydockManagementCommandWorkflow' => 'DrydockManagementWorkflow',
+ 'DrydockManagementHoaxWorkflow' => 'DrydockManagementWorkflow',
'DrydockManagementLeaseWorkflow' => 'DrydockManagementWorkflow',
'DrydockManagementReclaimWorkflow' => 'DrydockManagementWorkflow',
'DrydockManagementReleaseLeaseWorkflow' => 'DrydockManagementWorkflow',
diff --git a/src/applications/drydock/blueprint/DrydockHoaxBlueprintImplementation.php b/src/applications/drydock/blueprint/DrydockHoaxBlueprintImplementation.php
new file mode 100644
--- /dev/null
+++ b/src/applications/drydock/blueprint/DrydockHoaxBlueprintImplementation.php
@@ -0,0 +1,184 @@
+<?php
+
+final class DrydockHoaxBlueprintImplementation
+ extends DrydockBlueprintImplementation {
+
+ public function isEnabled() {
+ $almanac_app = 'PhabricatorAlmanacApplication';
+ return PhabricatorApplication::isClassInstalled($almanac_app);
+ }
+
+ public function getBlueprintName() {
+ return pht('Hoax (Pretend Host)');
+ }
+
+ public function getBlueprintIcon() {
+ return 'fa-bathtub';
+ }
+
+ public function getDescription() {
+ return pht('Pretend host for developing and testing Drydock blueprints.');
+ }
+
+ protected function shouldUseConcurrentResourceLimit() {
+ return true;
+ }
+
+ public function canAnyBlueprintEverAllocateResourceForLease(
+ DrydockLease $lease) {
+ return true;
+ }
+
+ public function canEverAllocateResourceForLease(
+ DrydockBlueprint $blueprint,
+ DrydockLease $lease) {
+ return true;
+ }
+
+ public function canAllocateResourceForLease(
+ DrydockBlueprint $blueprint,
+ DrydockLease $lease) {
+
+ if ($this->shouldLimitAllocatingPoolSize($blueprint)) {
+ return false;
+ }
+
+ return true;
+ }
+
+ public function allocateResource(
+ DrydockBlueprint $blueprint,
+ DrydockLease $lease) {
+
+ $name = Filesystem::readRandomCharacters(8);
+
+ $hoax = id(new DrydockHoax())
+ ->setName('hoax-'.$name.'.example.horse')
+ ->setState('running')
+ ->save();
+
+ $resource = $this->newResourceTemplate($blueprint)
+ ->setAttribute('hoaxPHID', $hoax->getPHID())
+ ->setAttribute('hoaxName', $hoax->getName());
+
+ $lease_flavor = $lease->getAttribute('flavor');
+ if ($lease_flavor !== null) {
+ $resource->setAttribute('flavor', $lease_flavor);
+ }
+
+ $slot_lock = $this->getConcurrentResourceLimitSlotLock($blueprint);
+ if ($slot_lock !== null) {
+ $resource->needSlotLock($slot_lock);
+ }
+
+ return $resource->allocateResource();
+ }
+
+ public function activateResource(
+ DrydockBlueprint $blueprint,
+ DrydockResource $resource) {
+ return $resource->activateResource($blueprint, $resource);
+ }
+
+ public function activateLease(
+ DrydockBlueprint $blueprint,
+ DrydockResource $resource,
+ DrydockLease $lease) {
+
+ return $lease->activateOnResource($resource);
+ }
+
+ public function destroyResource(
+ DrydockBlueprint $blueprint,
+ DrydockResource $resource) {
+
+ $hoax = id(new DrydockHoax())->loadOneWhere(
+ 'phid = %s',
+ $resource->getAttribute('hoaxPHID'));
+
+ $hoax->setState('destroyed')->save();
+ }
+
+ public function getResourceName(
+ DrydockBlueprint $blueprint,
+ DrydockResource $resource) {
+
+ $hoax_name = $resource->getAttribute('hoaxName', pht('<Unknown>'));
+
+ return pht('Hoax (%s)', $hoax_name);
+ }
+
+ public function canAcquireLeaseOnResource(
+ DrydockBlueprint $blueprint,
+ DrydockResource $resource,
+ DrydockLease $lease) {
+
+ // If the lease has a flavor, the resource needs to have the same flavor.
+ $lease_flavor = $lease->getAttribute('flavor');
+ if ($lease_flavor !== null) {
+ $resource_flavor = $resource->getAttribute('flavor');
+ if ($resource_flavor !== $lease_flavor) {
+ return false;
+ }
+ }
+
+ if (!DrydockSlotLock::isLockFree($this->getLeaseSlotLock($resource))) {
+ return false;
+ }
+
+ return true;
+ }
+
+ public function acquireLease(
+ DrydockBlueprint $blueprint,
+ DrydockResource $resource,
+ DrydockLease $lease) {
+
+ $lease
+ ->needSlotLock($this->getLeaseSlotLock($resource))
+ ->acquireOnResource($resource);
+ }
+
+ public function didReleaseLease(
+ DrydockBlueprint $blueprint,
+ DrydockResource $resource,
+ DrydockLease $lease) {
+ return;
+ }
+
+ public function destroyLease(
+ DrydockBlueprint $blueprint,
+ DrydockResource $resource,
+ DrydockLease $lease) {
+ return;
+ }
+
+ public function getType() {
+ return 'host';
+ }
+
+ public function getInterface(
+ DrydockBlueprint $blueprint,
+ DrydockResource $resource,
+ DrydockLease $lease,
+ $type) {
+
+ $viewer = PhabricatorUser::getOmnipotentUser();
+
+ switch ($type) {
+ case DrydockCommandInterface::INTERFACE_TYPE:
+ return new DrydockHoaxCommandInterface();
+ }
+ }
+
+ protected function getCustomFieldSpecifications() {
+ return array();
+ }
+
+
+ private function getLeaseSlotLock(DrydockResource $resource) {
+ $resource_phid = $resource->getPHID();
+ return "hoax.lease({$resource_phid})";
+ }
+
+}
diff --git a/src/applications/drydock/interface/command/DrydockHoaxCommandInterface.php b/src/applications/drydock/interface/command/DrydockHoaxCommandInterface.php
new file mode 100644
--- /dev/null
+++ b/src/applications/drydock/interface/command/DrydockHoaxCommandInterface.php
@@ -0,0 +1,17 @@
+<?php
+
+final class DrydockHoaxCommandInterface extends DrydockCommandInterface {
+
+ public function getExecFuture($command) {
+ $argv = func_get_args();
+ $full_command = call_user_func_array('csprintf', $argv);
+
+ $bin = dirname(phutil_get_library_root('phabricator')).'/bin';
+
+ return new ExecFuture(
+ '%s/drydock hoax --command %s',
+ $bin,
+ $full_command);
+ }
+
+}
diff --git a/src/applications/drydock/management/DrydockManagementHoaxWorkflow.php b/src/applications/drydock/management/DrydockManagementHoaxWorkflow.php
new file mode 100644
--- /dev/null
+++ b/src/applications/drydock/management/DrydockManagementHoaxWorkflow.php
@@ -0,0 +1,41 @@
+<?php
+
+final class DrydockManagementHoaxWorkflow
+ extends DrydockManagementWorkflow {
+
+ protected function didConstruct() {
+ $this
+ ->setName('hoax')
+ ->setSynopsis(pht('Pretend to run a command.'))
+ ->setArguments(
+ array(
+ array(
+ 'name' => 'command',
+ 'param' => 'commmand',
+ 'help' => pht('Command to run.'),
+ ),
+ ));
+ }
+
+ public function execute(PhutilArgumentParser $args) {
+ $command = $args->getArg('command');
+
+ $argv = id(new PhutilShellLexer())->splitArguments($command);
+
+
+ switch ($argv[0]) {
+ case 'ls':
+ echo "README\n";
+ return 0;
+ default:
+ echo tsprintf(
+ "%s\n",
+ pht(
+ 'Unknown command "%s"! Make sure this binary is properly '.
+ 'installed on your HoaxOS system.',
+ $argv[0]));
+ return 1;
+ }
+ }
+
+}
diff --git a/src/applications/drydock/phid/DrydockHoaxPHIDType.php b/src/applications/drydock/phid/DrydockHoaxPHIDType.php
new file mode 100644
--- /dev/null
+++ b/src/applications/drydock/phid/DrydockHoaxPHIDType.php
@@ -0,0 +1,48 @@
+<?php
+
+final class DrydockHoaxPHIDType extends PhabricatorPHIDType {
+
+ const TYPECONST = 'HOAX';
+
+ public function getTypeName() {
+ return pht('Drydock Hoax');
+ }
+
+ public function getTypeIcon() {
+ return 'fa-bath';
+ }
+
+ public function newObject() {
+ return new DrydockHoax();
+ }
+
+ public function getPHIDTypeApplicationClass() {
+ return 'PhabricatorDrydockApplication';
+ }
+
+ protected function buildQueryForObjects(
+ PhabricatorObjectQuery $query,
+ array $phids) {
+
+ return id(new DrydockHoaxQuery())
+ ->withPHIDs($phids);
+ }
+
+ public function loadHandles(
+ PhabricatorHandleQuery $query,
+ array $handles,
+ array $objects) {
+
+ foreach ($handles as $phid => $handle) {
+ $hoax = $objects[$phid];
+ $id = $hoax->getID();
+
+ $handle->setName(
+ pht(
+ 'Hoax %d: %s',
+ $id,
+ $hoax->getName()));
+ }
+ }
+
+}
diff --git a/src/applications/drydock/storage/DrydockHoax.php b/src/applications/drydock/storage/DrydockHoax.php
new file mode 100644
--- /dev/null
+++ b/src/applications/drydock/storage/DrydockHoax.php
@@ -0,0 +1,47 @@
+<?php
+
+final class DrydockHoax
+ extends DrydockDAO
+ implements PhabricatorPolicyInterface {
+
+ protected $name;
+ protected $state;
+
+ protected function getConfiguration() {
+ return array(
+ self::CONFIG_AUX_PHID => true,
+ self::CONFIG_COLUMN_SCHEMA => array(
+ 'name' => 'text128',
+ 'state' => 'text32',
+ ),
+ self::CONFIG_KEY_SCHEMA => array(
+ ),
+ ) + parent::getConfiguration();
+ }
+
+ public function getPHIDType() {
+ return DrydockHoaxPHIDType::TYPECONST;
+ }
+
+/* -( PhabricatorPolicyInterface )----------------------------------------- */
+
+
+ public function getCapabilities() {
+ return array(
+ PhabricatorPolicyCapability::CAN_VIEW,
+ );
+ }
+
+ public function getPolicy($capability) {
+ return PhabricatorPolicies::getMostOpenPolicy();
+ }
+
+ public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {
+ return false;
+ }
+
+ public function describeAutomaticCapability($capability) {
+ return pht('All users can view hoaxes.');
+ }
+
+}
diff --git a/src/applications/drydock/storage/DrydockHoaxLog.php b/src/applications/drydock/storage/DrydockHoaxLog.php
new file mode 100644
--- /dev/null
+++ b/src/applications/drydock/storage/DrydockHoaxLog.php
@@ -0,0 +1,41 @@
+<?php
+
+final class DrydockHoaxLog
+ extends DrydockDAO
+ implements PhabricatorPolicyInterface {
+
+ protected $hoaxPHID;
+ protected $message;
+
+ protected function getConfiguration() {
+ return array(
+ self::CONFIG_COLUMN_SCHEMA => array(
+ 'message' => 'text',
+ ),
+ self::CONFIG_KEY_SCHEMA => array(
+ ),
+ ) + parent::getConfiguration();
+ }
+
+/* -( PhabricatorPolicyInterface )----------------------------------------- */
+
+
+ public function getCapabilities() {
+ return array(
+ PhabricatorPolicyCapability::CAN_VIEW,
+ );
+ }
+
+ public function getPolicy($capability) {
+ return PhabricatorPolicies::getMostOpenPolicy();
+ }
+
+ public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {
+ return false;
+ }
+
+ public function describeAutomaticCapability($capability) {
+ return pht('All users can view hoax logs.');
+ }
+
+}

File Metadata

Mime Type
text/plain
Expires
Fri, Oct 18, 7:56 AM (4 w, 8 h ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6725721
Default Alt Text
D19102.id45769.diff (13 KB)

Event Timeline