Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F13970474
D19102.id45769.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
13 KB
Referenced Files
None
Subscribers
None
D19102.id45769.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D19102: Implement "Hoax" blueprints in Drydock, like "Host" blueprints but imaginary
Attached
Detach File
Event Timeline
Log In to Comment