1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-12-25 06:50:55 +01:00

Improve daemon console for daemons on multiple hosts

Summary:
Ref T10756. This:

  - Fixes T7307. This UI is now admin-only.
  - Makes the main "running daemons" table more useful for multi-host setups (show where daemons are running).
  - Removes logs from the web UI: these are sometimes vaguely sensitive and shouldn't be visible. The UI tells you how to get them with `bin/phd log`.
  - Minor modernization.

Test Plan:
  - As a non-admin, viewed daemons (access error) and bulk jobs (worked great).
  - Browsed bulk job pages.
  - Ran a bulk job.
  - Viewed daemon console.
  - Viewed task detail / daemon detail / daemon list pages.

{F1220516}

Reviewers: chad

Reviewed By: chad

Maniphest Tasks: T7307, T10756

Differential Revision: https://secure.phabricator.com/D15724
This commit is contained in:
epriestley 2016-04-15 12:00:34 -07:00
parent 42a8776228
commit d9dd4d427d
10 changed files with 136 additions and 103 deletions

View file

@ -2160,6 +2160,7 @@ phutil_register_library_map(array(
'PhabricatorCustomFieldStringIndexStorage' => 'infrastructure/customfield/storage/PhabricatorCustomFieldStringIndexStorage.php', 'PhabricatorCustomFieldStringIndexStorage' => 'infrastructure/customfield/storage/PhabricatorCustomFieldStringIndexStorage.php',
'PhabricatorCustomHeaderConfigType' => 'applications/config/custom/PhabricatorCustomHeaderConfigType.php', 'PhabricatorCustomHeaderConfigType' => 'applications/config/custom/PhabricatorCustomHeaderConfigType.php',
'PhabricatorDaemon' => 'infrastructure/daemon/PhabricatorDaemon.php', 'PhabricatorDaemon' => 'infrastructure/daemon/PhabricatorDaemon.php',
'PhabricatorDaemonBulkJobController' => 'applications/daemon/controller/PhabricatorDaemonBulkJobController.php',
'PhabricatorDaemonBulkJobListController' => 'applications/daemon/controller/PhabricatorDaemonBulkJobListController.php', 'PhabricatorDaemonBulkJobListController' => 'applications/daemon/controller/PhabricatorDaemonBulkJobListController.php',
'PhabricatorDaemonBulkJobMonitorController' => 'applications/daemon/controller/PhabricatorDaemonBulkJobMonitorController.php', 'PhabricatorDaemonBulkJobMonitorController' => 'applications/daemon/controller/PhabricatorDaemonBulkJobMonitorController.php',
'PhabricatorDaemonBulkJobViewController' => 'applications/daemon/controller/PhabricatorDaemonBulkJobViewController.php', 'PhabricatorDaemonBulkJobViewController' => 'applications/daemon/controller/PhabricatorDaemonBulkJobViewController.php',
@ -6604,9 +6605,10 @@ phutil_register_library_map(array(
'PhabricatorCustomFieldStringIndexStorage' => 'PhabricatorCustomFieldIndexStorage', 'PhabricatorCustomFieldStringIndexStorage' => 'PhabricatorCustomFieldIndexStorage',
'PhabricatorCustomHeaderConfigType' => 'PhabricatorConfigOptionType', 'PhabricatorCustomHeaderConfigType' => 'PhabricatorConfigOptionType',
'PhabricatorDaemon' => 'PhutilDaemon', 'PhabricatorDaemon' => 'PhutilDaemon',
'PhabricatorDaemonBulkJobListController' => 'PhabricatorDaemonController', 'PhabricatorDaemonBulkJobController' => 'PhabricatorDaemonController',
'PhabricatorDaemonBulkJobMonitorController' => 'PhabricatorDaemonController', 'PhabricatorDaemonBulkJobListController' => 'PhabricatorDaemonBulkJobController',
'PhabricatorDaemonBulkJobViewController' => 'PhabricatorDaemonController', 'PhabricatorDaemonBulkJobMonitorController' => 'PhabricatorDaemonBulkJobController',
'PhabricatorDaemonBulkJobViewController' => 'PhabricatorDaemonBulkJobController',
'PhabricatorDaemonConsoleController' => 'PhabricatorDaemonController', 'PhabricatorDaemonConsoleController' => 'PhabricatorDaemonController',
'PhabricatorDaemonContentSource' => 'PhabricatorContentSource', 'PhabricatorDaemonContentSource' => 'PhabricatorContentSource',
'PhabricatorDaemonController' => 'PhabricatorController', 'PhabricatorDaemonController' => 'PhabricatorController',

View file

@ -0,0 +1,25 @@
<?php
abstract class PhabricatorDaemonBulkJobController
extends PhabricatorDaemonController {
public function shouldRequireAdmin() {
return false;
}
public function shouldAllowPublic() {
return true;
}
public function buildApplicationMenu() {
return $this->newApplicationMenu()
->setSearchEngine(new PhabricatorWorkerBulkJobSearchEngine());
}
protected function buildApplicationCrumbs() {
$crumbs = parent::buildApplicationCrumbs();
$crumbs->addTextCrumb(pht('Bulk Jobs'), '/daemon/bulk/');
return $crumbs;
}
}

View file

@ -1,31 +1,12 @@
<?php <?php
final class PhabricatorDaemonBulkJobListController final class PhabricatorDaemonBulkJobListController
extends PhabricatorDaemonController { extends PhabricatorDaemonBulkJobController {
public function shouldAllowPublic() {
return true;
}
public function handleRequest(AphrontRequest $request) { public function handleRequest(AphrontRequest $request) {
$controller = id(new PhabricatorApplicationSearchController()) return id(new PhabricatorWorkerBulkJobSearchEngine())
->setQueryKey($request->getURIData('queryKey')) ->setController($this)
->setSearchEngine(new PhabricatorWorkerBulkJobSearchEngine()) ->buildResponse();
->setNavigation($this->buildSideNavView());
return $this->delegateToController($controller);
} }
protected function buildSideNavView($for_app = false) {
$user = $this->getRequest()->getUser();
$nav = new AphrontSideNavFilterView();
$nav->setBaseURI(new PhutilURI($this->getApplicationURI()));
id(new PhabricatorWorkerBulkJobSearchEngine())
->setViewer($user)
->addNavigationItems($nav->getMenu());
$nav->selectFilter(null);
return $nav;
}
} }

View file

@ -1,11 +1,7 @@
<?php <?php
final class PhabricatorDaemonBulkJobMonitorController final class PhabricatorDaemonBulkJobMonitorController
extends PhabricatorDaemonController { extends PhabricatorDaemonBulkJobController {
public function shouldAllowPublic() {
return true;
}
public function handleRequest(AphrontRequest $request) { public function handleRequest(AphrontRequest $request) {
$viewer = $this->getViewer(); $viewer = $this->getViewer();

View file

@ -1,11 +1,7 @@
<?php <?php
final class PhabricatorDaemonBulkJobViewController final class PhabricatorDaemonBulkJobViewController
extends PhabricatorDaemonController { extends PhabricatorDaemonBulkJobController {
public function shouldAllowPublic() {
return true;
}
public function handleRequest(AphrontRequest $request) { public function handleRequest(AphrontRequest $request) {
$viewer = $this->getViewer(); $viewer = $this->getViewer();
@ -21,7 +17,6 @@ final class PhabricatorDaemonBulkJobViewController
$title = pht('Bulk Job %d', $job->getID()); $title = pht('Bulk Job %d', $job->getID());
$crumbs = $this->buildApplicationCrumbs(); $crumbs = $this->buildApplicationCrumbs();
$crumbs->addTextCrumb(pht('Bulk Jobs'), '/daemon/bulk/');
$crumbs->addTextCrumb($title); $crumbs->addTextCrumb($title);
$crumbs->setBorder(true); $crumbs->setBorder(true);

View file

@ -121,14 +121,13 @@ final class PhabricatorDaemonConsoleController
->setHeaderText(pht('Recently Completed Tasks (Last 15m)')) ->setHeaderText(pht('Recently Completed Tasks (Last 15m)'))
->setTable($completed_table); ->setTable($completed_table);
$daemon_table = new PhabricatorDaemonLogListView(); $daemon_table = id(new PhabricatorDaemonLogListView())
$daemon_table->setUser($viewer); ->setUser($viewer)
$daemon_table->setDaemonLogs($logs); ->setDaemonLogs($logs);
$daemon_panel = id(new PHUIObjectBoxView());
$daemon_panel->setHeaderText(pht('Active Daemons'));
$daemon_panel->setObjectList($daemon_table);
$daemon_panel = id(new PHUIObjectBoxView())
->setHeaderText(pht('Active Daemons'))
->setTable($daemon_table);
$tasks = id(new PhabricatorWorkerLeaseQuery()) $tasks = id(new PhabricatorWorkerLeaseQuery())
->setSkipLease(true) ->setSkipLease(true)

View file

@ -1,6 +1,11 @@
<?php <?php
abstract class PhabricatorDaemonController extends PhabricatorController { abstract class PhabricatorDaemonController
extends PhabricatorController {
public function shouldRequireAdmin() {
return true;
}
protected function buildSideNavView() { protected function buildSideNavView() {
$nav = new AphrontSideNavFilterView(); $nav = new AphrontSideNavFilterView();

View file

@ -4,7 +4,7 @@ final class PhabricatorDaemonLogListController
extends PhabricatorDaemonController { extends PhabricatorDaemonController {
public function handleRequest(AphrontRequest $request) { public function handleRequest(AphrontRequest $request) {
$viewer = $request->getViewer(); $viewer = $this->getViewer();
$pager = new AphrontCursorPagerView(); $pager = new AphrontCursorPagerView();
$pager->readFromRequest($request); $pager->readFromRequest($request);
@ -14,13 +14,13 @@ final class PhabricatorDaemonLogListController
->setAllowStatusWrites(true) ->setAllowStatusWrites(true)
->executeWithCursorPager($pager); ->executeWithCursorPager($pager);
$daemon_table = new PhabricatorDaemonLogListView(); $daemon_table = id(new PhabricatorDaemonLogListView())
$daemon_table->setUser($request->getUser()); ->setViewer($viewer)
$daemon_table->setDaemonLogs($logs); ->setDaemonLogs($logs);
$box = id(new PHUIObjectBoxView()) $box = id(new PHUIObjectBoxView())
->setHeaderText(pht('All Daemons')) ->setHeaderText(pht('All Daemons'))
->appendChild($daemon_table); ->setTable($daemon_table);
$crumbs = $this->buildApplicationCrumbs(); $crumbs = $this->buildApplicationCrumbs();
$crumbs->addTextCrumb(pht('All Daemons')); $crumbs->addTextCrumb(pht('All Daemons'));

View file

@ -16,10 +16,6 @@ final class PhabricatorDaemonLogViewController
return new Aphront404Response(); return new Aphront404Response();
} }
$events = id(new PhabricatorDaemonLogEvent())->loadAllWhere(
'logID = %d ORDER BY id DESC LIMIT 1000',
$log->getID());
$crumbs = $this->buildApplicationCrumbs(); $crumbs = $this->buildApplicationCrumbs();
$crumbs->addTextCrumb(pht('Daemon %s', $log->getID())); $crumbs->addTextCrumb(pht('Daemon %s', $log->getID()));
$crumbs->setBorder(true); $crumbs->setBorder(true);
@ -69,23 +65,15 @@ final class PhabricatorDaemonLogViewController
$properties = $this->buildPropertyListView($log); $properties = $this->buildPropertyListView($log);
$event_view = id(new PhabricatorDaemonLogEventsView())
->setUser($viewer)
->setEvents($events);
$event_panel = id(new PHUIObjectBoxView())
->setHeaderText(pht('Events'))
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->appendChild($event_view);
$object_box = id(new PHUIObjectBoxView()) $object_box = id(new PHUIObjectBoxView())
->setHeaderText(pht('Daemon Details'))
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->addPropertyList($properties); ->addPropertyList($properties);
$view = id(new PHUITwoColumnView()) $view = id(new PHUITwoColumnView())
->setHeader($header) ->setHeader($header)
->setFooter(array( ->setFooter(array(
$object_box, $object_box,
$event_panel,
)); ));
return $this->newPage() return $this->newPage()

View file

@ -14,65 +14,107 @@ final class PhabricatorDaemonLogListView extends AphrontView {
$viewer = $this->getViewer(); $viewer = $this->getViewer();
$rows = array(); $rows = array();
$daemons = $this->daemonLogs;
$list = new PHUIObjectItemListView(); foreach ($daemons as $daemon) {
$list->setFlush(true); $id = $daemon->getID();
foreach ($this->daemonLogs as $log) { $host = $daemon->getHost();
$id = $log->getID(); $pid = $daemon->getPID();
$epoch = $log->getDateCreated(); $name = phutil_tag(
'a',
array(
'href' => "/daemon/log/{$id}/",
),
$daemon->getDaemon());
$item = id(new PHUIObjectItemView()) $status = $daemon->getStatus();
->setObjectName(pht('Daemon %s', $id))
->setHeader($log->getDaemon())
->setHref("/daemon/log/{$id}/")
->addIcon('none', phabricator_datetime($epoch, $viewer));
$status = $log->getStatus();
switch ($status) { switch ($status) {
case PhabricatorDaemonLog::STATUS_RUNNING: case PhabricatorDaemonLog::STATUS_RUNNING:
$item->setStatusIcon('fa-rocket green'); $status_icon = 'fa-rocket green';
$item->addAttribute(pht('This daemon is running.')); $status_label = pht('Running');
$status_tip = pht('This daemon is running.');
break; break;
case PhabricatorDaemonLog::STATUS_DEAD: case PhabricatorDaemonLog::STATUS_DEAD:
$item->setStatusIcon('fa-warning red'); $status_icon = 'fa-warning red';
$item->addAttribute( $status_label = pht('Dead');
pht( $status_tip = pht(
'This daemon is lost or exited uncleanly, and is presumed '. 'This daemon has been lost or exited uncleanly, and is '.
'dead.')); 'presumed dead.');
$item->addIcon('fa-times grey', pht('Dead'));
break; break;
case PhabricatorDaemonLog::STATUS_EXITING: case PhabricatorDaemonLog::STATUS_EXITING:
$item->addAttribute(pht('This daemon is exiting.')); $status_icon = 'fa-check';
$item->addIcon('fa-check', pht('Exiting')); $status_label = pht('Shutting Down');
$status_tip = pht('This daemon is shutting down.');
break; break;
case PhabricatorDaemonLog::STATUS_EXITED: case PhabricatorDaemonLog::STATUS_EXITED:
$item->setDisabled(true); $status_icon = 'fa-check grey';
$item->addAttribute(pht('This daemon exited cleanly.')); $status_label = pht('Exited');
$item->addIcon('fa-check grey', pht('Exited')); $status_tip = pht('This daemon exited cleanly.');
break; break;
case PhabricatorDaemonLog::STATUS_WAIT: case PhabricatorDaemonLog::STATUS_WAIT:
$item->setStatusIcon('fa-clock-o blue'); $status_icon = 'fa-clock-o blue';
$item->addAttribute( $status_label = pht('Waiting');
pht( $status_tip = pht(
'This daemon encountered an error recently and is waiting a '. 'This daemon encountered an error recently and is waiting a '.
'moment to restart.')); 'moment to restart.');
$item->addIcon('fa-clock-o grey', pht('Waiting'));
break; break;
case PhabricatorDaemonLog::STATUS_UNKNOWN: case PhabricatorDaemonLog::STATUS_UNKNOWN:
default: default:
$item->setStatusIcon('fa-warning orange'); $status_icon = 'fa-warning orange';
$item->addAttribute( $status_label = pht('Unknown');
pht( $status_tip = pht(
'This daemon has not reported its status recently. It may '. 'This daemon has not reported its status recently. It may '.
'have exited uncleanly.')); 'have exited uncleanly.');
$item->addIcon('fa-warning', pht('Unknown'));
break; break;
} }
$list->addItem($item); $status = phutil_tag(
'span',
array(
'sigil' => 'has-tooltip',
'meta' => array(
'tip' => $status_tip,
),
),
array(
id(new PHUIIconView())->setIcon($status_icon),
' ',
$status_label,
));
$launched = phabricator_datetime($daemon->getDateCreated(), $viewer);
$rows[] = array(
$id,
$host,
$pid,
$name,
$status,
$launched,
);
} }
return $list; $table = id(new AphrontTableView($rows))
->setHeaders(
array(
pht('ID'),
pht('Host'),
pht('PPID'),
pht('Daemon'),
pht('Status'),
pht('Launched'),
))
->setColumnClasses(
array(
null,
null,
null,
'pri',
'wide',
'right date',
));
return $table;
} }
} }