diff --git a/src/applications/drydock/logtype/DrydockLeaseNoAuthorizationsLogType.php b/src/applications/drydock/logtype/DrydockLeaseNoAuthorizationsLogType.php index b5a7ca1b13..cce98956a1 100644 --- a/src/applications/drydock/logtype/DrydockLeaseNoAuthorizationsLogType.php +++ b/src/applications/drydock/logtype/DrydockLeaseNoAuthorizationsLogType.php @@ -1,26 +1,25 @@ getViewer(); $authorizing_phid = idx($data, 'authorizingPHID'); return pht( 'The object which authorized this lease (%s) is not authorized to use '. 'any of the blueprints the lease lists. Approve the authorizations '. 'before using the lease.', - $viewer->renderHandle($authorizing_phid)->render()); + $this->renderHandle($authorizing_phid)); } } diff --git a/src/applications/drydock/logtype/DrydockLeaseReclaimLogType.php b/src/applications/drydock/logtype/DrydockLeaseReclaimLogType.php index 8dbc13d9d4..6e145a24ae 100644 --- a/src/applications/drydock/logtype/DrydockLeaseReclaimLogType.php +++ b/src/applications/drydock/logtype/DrydockLeaseReclaimLogType.php @@ -1,25 +1,23 @@ getViewer(); - $resource_phids = idx($data, 'resourcePHIDs', array()); return pht( 'Reclaimed resource %s.', - $viewer->renderHandleList($resource_phids)->render()); + $this->renderHandleList($resource_phids)); } } diff --git a/src/applications/drydock/logtype/DrydockLeaseWaitingForResourcesLogType.php b/src/applications/drydock/logtype/DrydockLeaseWaitingForResourcesLogType.php index 46ab965b36..bb91acb030 100644 --- a/src/applications/drydock/logtype/DrydockLeaseWaitingForResourcesLogType.php +++ b/src/applications/drydock/logtype/DrydockLeaseWaitingForResourcesLogType.php @@ -1,25 +1,23 @@ getViewer(); - $blueprint_phids = idx($data, 'blueprintPHIDs', array()); return pht( 'Waiting for available resources from: %s.', - $viewer->renderHandleList($blueprint_phids)->render()); + $this->renderHandleList($blueprint_phids)); } } diff --git a/src/applications/drydock/logtype/DrydockLogType.php b/src/applications/drydock/logtype/DrydockLogType.php index 7faab42dfe..690ffc5670 100644 --- a/src/applications/drydock/logtype/DrydockLogType.php +++ b/src/applications/drydock/logtype/DrydockLogType.php @@ -1,41 +1,74 @@ viewer = $viewer; return $this; } - public function getViewer() { + final public function getViewer() { return $this->viewer; } final public function setLog(DrydockLog $log) { $this->log = $log; return $this; } final public function getLog() { return $this->log; } final public function getLogTypeConstant() { return $this->getPhobjectClassConstant('LOGCONST', 64); } final public static function getAllLogTypes() { return id(new PhutilClassMapQuery()) ->setAncestorClass(__CLASS__) ->setUniqueMethod('getLogTypeConstant') ->execute(); } + final public function renderLogForText($data) { + $this->renderingMode = 'text'; + return $this->renderLog($data); + } + + final public function renderLogForHTML($data) { + $this->renderingMode = 'html'; + return $this->renderLog($data); + } + + final protected function renderHandle($phid) { + $viewer = $this->getViewer(); + $handle = $viewer->renderHandle($phid); + + if ($this->renderingMode == 'html') { + return $handle->render(); + } else { + return $handle->setAsText(true)->render(); + } + } + + final protected function renderHandleList(array $phids) { + $viewer = $this->getViewer(); + $handle_list = $viewer->renderHandleList($phids); + + if ($this->renderingMode == 'html') { + return $handle_list->render(); + } else { + return $handle_list->setAsText(true)->render(); + } + } + } diff --git a/src/applications/drydock/logtype/DrydockResourceReclaimLogType.php b/src/applications/drydock/logtype/DrydockResourceReclaimLogType.php index 9e9d5fdef3..aa989e97df 100644 --- a/src/applications/drydock/logtype/DrydockResourceReclaimLogType.php +++ b/src/applications/drydock/logtype/DrydockResourceReclaimLogType.php @@ -1,24 +1,23 @@ getViewer(); $reclaimer_phid = idx($data, 'reclaimerPHID'); return pht( 'Resource reclaimed by %s.', - $viewer->renderHandle($reclaimer_phid)->render()); + $this->renderHandle($reclaimer_phid)); } } diff --git a/src/applications/drydock/management/DrydockManagementLeaseWorkflow.php b/src/applications/drydock/management/DrydockManagementLeaseWorkflow.php index 8c3f682042..75636dab09 100644 --- a/src/applications/drydock/management/DrydockManagementLeaseWorkflow.php +++ b/src/applications/drydock/management/DrydockManagementLeaseWorkflow.php @@ -1,208 +1,208 @@ setName('lease') ->setSynopsis(pht('Lease a resource.')) ->setArguments( array( array( 'name' => 'type', 'param' => 'resource_type', 'help' => pht('Resource type.'), ), array( 'name' => 'until', 'param' => 'time', 'help' => pht('Set lease expiration time.'), ), array( 'name' => 'attributes', 'param' => 'name=value,...', 'help' => pht('Resource specification.'), ), )); } public function execute(PhutilArgumentParser $args) { $viewer = $this->getViewer(); $resource_type = $args->getArg('type'); if (!$resource_type) { throw new PhutilArgumentUsageException( pht( 'Specify a resource type with `%s`.', '--type')); } $until = $args->getArg('until'); if (strlen($until)) { $until = strtotime($until); if ($until <= 0) { throw new PhutilArgumentUsageException( pht( 'Unable to parse argument to "%s".', '--until')); } } $attributes = $args->getArg('attributes'); if ($attributes) { $options = new PhutilSimpleOptions(); $options->setCaseSensitive(true); $attributes = $options->parse($attributes); } $lease = id(new DrydockLease()) ->setResourceType($resource_type); $drydock_phid = id(new PhabricatorDrydockApplication())->getPHID(); $lease->setAuthorizingPHID($drydock_phid); if ($attributes) { $lease->setAttributes($attributes); } // TODO: This is not hugely scalable, although this is a debugging workflow // so maybe it's fine. Do we even need `bin/drydock lease` in the long run? $all_blueprints = id(new DrydockBlueprintQuery()) ->setViewer($viewer) ->execute(); $allowed_phids = mpull($all_blueprints, 'getPHID'); if (!$allowed_phids) { throw new Exception( pht( 'No blueprints exist which can plausibly allocate resources to '. 'satisfy the requested lease.')); } $lease->setAllowedBlueprintPHIDs($allowed_phids); if ($until) { $lease->setUntil($until); } // If something fatals or the user interrupts the process (for example, // with "^C"), release the lease. We'll cancel this below, if the lease // actually activates. $lease->setReleaseOnDestruction(true); // TODO: This would probably be better handled with PhutilSignalRouter, // but it currently doesn't route SIGINT. We're initializing it to setup // SIGTERM handling and make eventual migration easier. $router = PhutilSignalRouter::getRouter(); pcntl_signal(SIGINT, array($this, 'didReceiveInterrupt')); $t_start = microtime(true); $lease->queueForActivation(); echo tsprintf( "%s\n\n __%s__\n\n%s\n", pht('Queued lease for activation:'), PhabricatorEnv::getProductionURI($lease->getURI()), pht('Waiting for daemons to activate lease...')); $this->waitUntilActive($lease); // Now that we've survived activation and the lease is good, make it // durable. $lease->setReleaseOnDestruction(false); $t_end = microtime(true); echo tsprintf( "%s\n\n %s\n\n%s\n", pht( 'Activation complete. This lease is permanent until manually '. 'released with:'), pht('$ ./bin/drydock release-lease --id %d', $lease->getID()), pht( 'Lease activated in %sms.', new PhutilNumber((int)(($t_end - $t_start) * 1000)))); return 0; } public function didReceiveInterrupt($signo) { // Doing this makes us run destructors, particularly the "release on // destruction" trigger on the lease. exit(128 + $signo); } private function waitUntilActive(DrydockLease $lease) { $viewer = $this->getViewer(); $log_cursor = 0; $log_types = DrydockLogType::getAllLogTypes(); $is_active = false; while (!$is_active) { $lease->reload(); // While we're waiting, show the user any logs which the daemons have // generated to give them some clue about what's going on. $logs = id(new DrydockLogQuery()) ->setViewer($viewer) ->withLeasePHIDs(array($lease->getPHID())) ->setBeforeID($log_cursor) ->execute(); if ($logs) { $logs = mpull($logs, null, 'getID'); ksort($logs); $log_cursor = last_key($logs); } foreach ($logs as $log) { $type_key = $log->getType(); if (isset($log_types[$type_key])) { $type_object = id(clone $log_types[$type_key]) ->setLog($log) ->setViewer($viewer); $log_data = $log->getData(); $type = $type_object->getLogTypeName(); - $data = $type_object->renderLog($log_data); + $data = $type_object->renderLogForText($log_data); } else { $type = pht('Unknown ("%s")', $type_key); $data = null; } echo tsprintf( "<%s> %B\n", $type, $data); } $status = $lease->getStatus(); switch ($status) { case DrydockLeaseStatus::STATUS_ACTIVE: $is_active = true; break; case DrydockLeaseStatus::STATUS_RELEASED: throw new Exception(pht('Lease has already been released!')); case DrydockLeaseStatus::STATUS_DESTROYED: throw new Exception(pht('Lease has already been destroyed!')); case DrydockLeaseStatus::STATUS_BROKEN: throw new Exception(pht('Lease has been broken!')); case DrydockLeaseStatus::STATUS_PENDING: case DrydockLeaseStatus::STATUS_ACQUIRED: break; default: throw new Exception( pht( 'Lease has unknown status "%s".', $status)); } if ($is_active) { break; } else { sleep(1); } } } } diff --git a/src/applications/drydock/view/DrydockLogListView.php b/src/applications/drydock/view/DrydockLogListView.php index cb66813507..61fde7cee7 100644 --- a/src/applications/drydock/view/DrydockLogListView.php +++ b/src/applications/drydock/view/DrydockLogListView.php @@ -1,108 +1,108 @@ logs = $logs; return $this; } public function render() { $logs = $this->logs; $viewer = $this->getUser(); $view = new PHUIObjectItemListView(); $types = DrydockLogType::getAllLogTypes(); $rows = array(); foreach ($logs as $log) { $blueprint_phid = $log->getBlueprintPHID(); if ($blueprint_phid) { $blueprint = $viewer->renderHandle($blueprint_phid); } else { $blueprint = null; } $resource_phid = $log->getResourcePHID(); if ($resource_phid) { $resource = $viewer->renderHandle($resource_phid); } else { $resource = null; } $lease_phid = $log->getLeasePHID(); if ($lease_phid) { $lease = $viewer->renderHandle($lease_phid); } else { $lease = null; } if ($log->isComplete()) { $type_key = $log->getType(); if (isset($types[$type_key])) { $type_object = id(clone $types[$type_key]) ->setLog($log) ->setViewer($viewer); $log_data = $log->getData(); $type = $type_object->getLogTypeName(); $icon = $type_object->getLogTypeIcon($log_data); - $data = $type_object->renderLog($log_data); + $data = $type_object->renderLogForHTML($log_data); $data = phutil_escape_html_newlines($data); } else { $type = pht('', $type_key); $data = null; $icon = 'fa-question-circle red'; } } else { $type = phutil_tag('em', array(), pht('Restricted')); $data = phutil_tag( 'em', array(), pht('You do not have permission to view this log event.')); $icon = 'fa-lock grey'; } $rows[] = array( $blueprint, $resource, $lease, id(new PHUIIconView())->setIcon($icon), $type, $data, phabricator_datetime($log->getEpoch(), $viewer), ); } $table = id(new AphrontTableView($rows)) ->setDeviceReadyTable(true) ->setHeaders( array( pht('Blueprint'), pht('Resource'), pht('Lease'), null, pht('Type'), pht('Data'), pht('Date'), )) ->setColumnClasses( array( '', '', '', 'icon', '', 'wide', '', )); return $table; } }