setName('bootstrap') ->setSynopsis(pht('Bootstrap Phacility instances application.')) ->setArguments( array( array( 'name' => 'user', 'param' => 'user', 'help' => pht('User to give cluster management permissions to.'), ), )); } public function execute(PhutilArgumentParser $args) { // Grant user "Can Manage Cluster Devices" $this->updateManageClusterDevicesPolicy($args->getArg('user')); // Create network $network = id(new AlmanacNetworkQuery()) ->setViewer(PhabricatorUser::getOmnipotentUser()) ->withNames(array('Internet')) ->execute(); if (!$network) { $network = id(AlmanacNetwork::initializeNewNetwork()) ->setName('Internet'); $network->save(); } else { $network = head($network); } // Create localhost device with interfaces for ssh and mysql $device = id(new AlmanacDeviceQuery()) ->setViewer(PhabricatorUser::getOmnipotentUser()) ->withNames(array('localhost')) ->execute(); if (!$device) { $device = id(AlmanacDevice::initializeNewDevice()) ->setName('localhost') ->setIsBoundToClusterService(true); $device->save(); $ssh_interface = id(AlmanacInterface::initializeNewInterface()) ->attachNetwork($network) ->setNetworkPHID($network->getPHID()) ->attachDevice($device) ->setDevicePHID($device->getPHID()) ->setAddress('127.0.0.1') ->setPort('22'); $ssh_interface->save(); $sql_interface = id(AlmanacInterface::initializeNewInterface()) ->attachNetwork($network) ->setNetworkPHID($network->getPHID()) ->attachDevice($device) ->setDevicePHID($device->getPHID()) ->setAddress('127.0.0.1') ->setPort('3306'); $sql_interface->save(); } else { $device = head($device); } // create services.phacility.net service // create db.phacility.net service with "instances.open" = true // create repo.phacility.net service with "instances.open" = true // setup bindings // create Phortune merchant account named "Phacility" } private function updateManageClusterDevicesPolicy($user_name) { $user = id(new PhabricatorPeopleQuery()) ->setViewer(PhabricatorUser::getOmnipotentUser()) ->withUsernames(array($user_name)) ->needUserSettings(true) ->executeOne(); if (!$user) { throw new Exception( pht( 'Invalid username ("%s"). There is no user with this username.', $user_name)); } $application = id(new PhabricatorApplicationQuery()) ->setViewer($user) ->withClasses(array('PhabricatorAlmanacApplication')) ->requireCapabilities( array( PhabricatorPolicyCapability::CAN_VIEW, PhabricatorPolicyCapability::CAN_EDIT, )) ->executeOne(); if (!$application) { throw new Exception(pht('Almanac application is not installed.')); } $policies = id(new PhabricatorPolicyQuery()) ->setViewer($user) ->setObject($application) ->execute(); $xactions = array(); $template = $application->getApplicationTransactionTemplate(); foreach ($application->getCapabilities() as $capability) { if ($capability !== 'almanac.cluster') { continue; } $old = $application->getPolicy($capability); $new = $user->getPHID(); if ($old == $new) { // No change to the setting. return; } $xactions[] = id(clone $template) ->setTransactionType( PhabricatorApplicationPolicyChangeTransaction::TRANSACTIONTYPE) ->setMetadataValue( PhabricatorApplicationPolicyChangeTransaction::METADATA_ATTRIBUTE, $capability) ->setNewValue($new); $editor = id(new PhabricatorApplicationEditor()) ->setActor($user) ->setContentSource( PhabricatorContentSource::newForSource( PhabricatorDaemonContentSource::SOURCECONST)) ->setContinueOnNoEffect(true) ->setContinueOnMissingFields(true); $editor->applyTransactions($application, $xactions); return; } } }