From d9dd4d427d0bcc8cdb1cdd040f87151bbe49152e Mon Sep 17 00:00:00 2001 From: epriestley Date: Fri, 15 Apr 2016 12:00:34 -0700 Subject: [PATCH] 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 --- src/__phutil_library_map__.php | 8 +- .../PhabricatorDaemonBulkJobController.php | 25 ++++ ...PhabricatorDaemonBulkJobListController.php | 27 +--- ...bricatorDaemonBulkJobMonitorController.php | 6 +- ...PhabricatorDaemonBulkJobViewController.php | 7 +- .../PhabricatorDaemonConsoleController.php | 13 +- .../PhabricatorDaemonController.php | 7 +- .../PhabricatorDaemonLogListController.php | 10 +- .../PhabricatorDaemonLogViewController.php | 16 +-- .../view/PhabricatorDaemonLogListView.php | 120 ++++++++++++------ 10 files changed, 136 insertions(+), 103 deletions(-) create mode 100644 src/applications/daemon/controller/PhabricatorDaemonBulkJobController.php diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index fffd0424be..e76e768774 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -2160,6 +2160,7 @@ phutil_register_library_map(array( 'PhabricatorCustomFieldStringIndexStorage' => 'infrastructure/customfield/storage/PhabricatorCustomFieldStringIndexStorage.php', 'PhabricatorCustomHeaderConfigType' => 'applications/config/custom/PhabricatorCustomHeaderConfigType.php', 'PhabricatorDaemon' => 'infrastructure/daemon/PhabricatorDaemon.php', + 'PhabricatorDaemonBulkJobController' => 'applications/daemon/controller/PhabricatorDaemonBulkJobController.php', 'PhabricatorDaemonBulkJobListController' => 'applications/daemon/controller/PhabricatorDaemonBulkJobListController.php', 'PhabricatorDaemonBulkJobMonitorController' => 'applications/daemon/controller/PhabricatorDaemonBulkJobMonitorController.php', 'PhabricatorDaemonBulkJobViewController' => 'applications/daemon/controller/PhabricatorDaemonBulkJobViewController.php', @@ -6604,9 +6605,10 @@ phutil_register_library_map(array( 'PhabricatorCustomFieldStringIndexStorage' => 'PhabricatorCustomFieldIndexStorage', 'PhabricatorCustomHeaderConfigType' => 'PhabricatorConfigOptionType', 'PhabricatorDaemon' => 'PhutilDaemon', - 'PhabricatorDaemonBulkJobListController' => 'PhabricatorDaemonController', - 'PhabricatorDaemonBulkJobMonitorController' => 'PhabricatorDaemonController', - 'PhabricatorDaemonBulkJobViewController' => 'PhabricatorDaemonController', + 'PhabricatorDaemonBulkJobController' => 'PhabricatorDaemonController', + 'PhabricatorDaemonBulkJobListController' => 'PhabricatorDaemonBulkJobController', + 'PhabricatorDaemonBulkJobMonitorController' => 'PhabricatorDaemonBulkJobController', + 'PhabricatorDaemonBulkJobViewController' => 'PhabricatorDaemonBulkJobController', 'PhabricatorDaemonConsoleController' => 'PhabricatorDaemonController', 'PhabricatorDaemonContentSource' => 'PhabricatorContentSource', 'PhabricatorDaemonController' => 'PhabricatorController', diff --git a/src/applications/daemon/controller/PhabricatorDaemonBulkJobController.php b/src/applications/daemon/controller/PhabricatorDaemonBulkJobController.php new file mode 100644 index 0000000000..506df1dd1a --- /dev/null +++ b/src/applications/daemon/controller/PhabricatorDaemonBulkJobController.php @@ -0,0 +1,25 @@ +newApplicationMenu() + ->setSearchEngine(new PhabricatorWorkerBulkJobSearchEngine()); + } + + protected function buildApplicationCrumbs() { + $crumbs = parent::buildApplicationCrumbs(); + $crumbs->addTextCrumb(pht('Bulk Jobs'), '/daemon/bulk/'); + return $crumbs; + } + +} diff --git a/src/applications/daemon/controller/PhabricatorDaemonBulkJobListController.php b/src/applications/daemon/controller/PhabricatorDaemonBulkJobListController.php index ee8d4f5bf4..b1754d7291 100644 --- a/src/applications/daemon/controller/PhabricatorDaemonBulkJobListController.php +++ b/src/applications/daemon/controller/PhabricatorDaemonBulkJobListController.php @@ -1,31 +1,12 @@ setQueryKey($request->getURIData('queryKey')) - ->setSearchEngine(new PhabricatorWorkerBulkJobSearchEngine()) - ->setNavigation($this->buildSideNavView()); - return $this->delegateToController($controller); + return id(new PhabricatorWorkerBulkJobSearchEngine()) + ->setController($this) + ->buildResponse(); } - 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; - } } diff --git a/src/applications/daemon/controller/PhabricatorDaemonBulkJobMonitorController.php b/src/applications/daemon/controller/PhabricatorDaemonBulkJobMonitorController.php index 63ba3cacb1..79d509f1ea 100644 --- a/src/applications/daemon/controller/PhabricatorDaemonBulkJobMonitorController.php +++ b/src/applications/daemon/controller/PhabricatorDaemonBulkJobMonitorController.php @@ -1,11 +1,7 @@ getViewer(); diff --git a/src/applications/daemon/controller/PhabricatorDaemonBulkJobViewController.php b/src/applications/daemon/controller/PhabricatorDaemonBulkJobViewController.php index f794024591..f7aa396e94 100644 --- a/src/applications/daemon/controller/PhabricatorDaemonBulkJobViewController.php +++ b/src/applications/daemon/controller/PhabricatorDaemonBulkJobViewController.php @@ -1,11 +1,7 @@ getViewer(); @@ -21,7 +17,6 @@ final class PhabricatorDaemonBulkJobViewController $title = pht('Bulk Job %d', $job->getID()); $crumbs = $this->buildApplicationCrumbs(); - $crumbs->addTextCrumb(pht('Bulk Jobs'), '/daemon/bulk/'); $crumbs->addTextCrumb($title); $crumbs->setBorder(true); diff --git a/src/applications/daemon/controller/PhabricatorDaemonConsoleController.php b/src/applications/daemon/controller/PhabricatorDaemonConsoleController.php index a488ae3a63..7f7b323956 100644 --- a/src/applications/daemon/controller/PhabricatorDaemonConsoleController.php +++ b/src/applications/daemon/controller/PhabricatorDaemonConsoleController.php @@ -121,14 +121,13 @@ final class PhabricatorDaemonConsoleController ->setHeaderText(pht('Recently Completed Tasks (Last 15m)')) ->setTable($completed_table); - $daemon_table = new PhabricatorDaemonLogListView(); - $daemon_table->setUser($viewer); - $daemon_table->setDaemonLogs($logs); - - $daemon_panel = id(new PHUIObjectBoxView()); - $daemon_panel->setHeaderText(pht('Active Daemons')); - $daemon_panel->setObjectList($daemon_table); + $daemon_table = id(new PhabricatorDaemonLogListView()) + ->setUser($viewer) + ->setDaemonLogs($logs); + $daemon_panel = id(new PHUIObjectBoxView()) + ->setHeaderText(pht('Active Daemons')) + ->setTable($daemon_table); $tasks = id(new PhabricatorWorkerLeaseQuery()) ->setSkipLease(true) diff --git a/src/applications/daemon/controller/PhabricatorDaemonController.php b/src/applications/daemon/controller/PhabricatorDaemonController.php index 3b1d17a70b..a2734907fd 100644 --- a/src/applications/daemon/controller/PhabricatorDaemonController.php +++ b/src/applications/daemon/controller/PhabricatorDaemonController.php @@ -1,6 +1,11 @@ getViewer(); + $viewer = $this->getViewer(); $pager = new AphrontCursorPagerView(); $pager->readFromRequest($request); @@ -14,13 +14,13 @@ final class PhabricatorDaemonLogListController ->setAllowStatusWrites(true) ->executeWithCursorPager($pager); - $daemon_table = new PhabricatorDaemonLogListView(); - $daemon_table->setUser($request->getUser()); - $daemon_table->setDaemonLogs($logs); + $daemon_table = id(new PhabricatorDaemonLogListView()) + ->setViewer($viewer) + ->setDaemonLogs($logs); $box = id(new PHUIObjectBoxView()) ->setHeaderText(pht('All Daemons')) - ->appendChild($daemon_table); + ->setTable($daemon_table); $crumbs = $this->buildApplicationCrumbs(); $crumbs->addTextCrumb(pht('All Daemons')); diff --git a/src/applications/daemon/controller/PhabricatorDaemonLogViewController.php b/src/applications/daemon/controller/PhabricatorDaemonLogViewController.php index f2f5121898..004ce3a84e 100644 --- a/src/applications/daemon/controller/PhabricatorDaemonLogViewController.php +++ b/src/applications/daemon/controller/PhabricatorDaemonLogViewController.php @@ -16,10 +16,6 @@ final class PhabricatorDaemonLogViewController return new Aphront404Response(); } - $events = id(new PhabricatorDaemonLogEvent())->loadAllWhere( - 'logID = %d ORDER BY id DESC LIMIT 1000', - $log->getID()); - $crumbs = $this->buildApplicationCrumbs(); $crumbs->addTextCrumb(pht('Daemon %s', $log->getID())); $crumbs->setBorder(true); @@ -69,23 +65,15 @@ final class PhabricatorDaemonLogViewController $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()) + ->setHeaderText(pht('Daemon Details')) + ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) ->addPropertyList($properties); $view = id(new PHUITwoColumnView()) ->setHeader($header) ->setFooter(array( $object_box, - $event_panel, )); return $this->newPage() diff --git a/src/applications/daemon/view/PhabricatorDaemonLogListView.php b/src/applications/daemon/view/PhabricatorDaemonLogListView.php index 046d1a29f5..ba25ac5c5e 100644 --- a/src/applications/daemon/view/PhabricatorDaemonLogListView.php +++ b/src/applications/daemon/view/PhabricatorDaemonLogListView.php @@ -14,65 +14,107 @@ final class PhabricatorDaemonLogListView extends AphrontView { $viewer = $this->getViewer(); $rows = array(); + $daemons = $this->daemonLogs; - $list = new PHUIObjectItemListView(); - $list->setFlush(true); - foreach ($this->daemonLogs as $log) { - $id = $log->getID(); - $epoch = $log->getDateCreated(); + foreach ($daemons as $daemon) { + $id = $daemon->getID(); + $host = $daemon->getHost(); + $pid = $daemon->getPID(); + $name = phutil_tag( + 'a', + array( + 'href' => "/daemon/log/{$id}/", + ), + $daemon->getDaemon()); - $item = id(new PHUIObjectItemView()) - ->setObjectName(pht('Daemon %s', $id)) - ->setHeader($log->getDaemon()) - ->setHref("/daemon/log/{$id}/") - ->addIcon('none', phabricator_datetime($epoch, $viewer)); - - $status = $log->getStatus(); + $status = $daemon->getStatus(); switch ($status) { case PhabricatorDaemonLog::STATUS_RUNNING: - $item->setStatusIcon('fa-rocket green'); - $item->addAttribute(pht('This daemon is running.')); + $status_icon = 'fa-rocket green'; + $status_label = pht('Running'); + $status_tip = pht('This daemon is running.'); break; case PhabricatorDaemonLog::STATUS_DEAD: - $item->setStatusIcon('fa-warning red'); - $item->addAttribute( - pht( - 'This daemon is lost or exited uncleanly, and is presumed '. - 'dead.')); - $item->addIcon('fa-times grey', pht('Dead')); + $status_icon = 'fa-warning red'; + $status_label = pht('Dead'); + $status_tip = pht( + 'This daemon has been lost or exited uncleanly, and is '. + 'presumed dead.'); break; case PhabricatorDaemonLog::STATUS_EXITING: - $item->addAttribute(pht('This daemon is exiting.')); - $item->addIcon('fa-check', pht('Exiting')); + $status_icon = 'fa-check'; + $status_label = pht('Shutting Down'); + $status_tip = pht('This daemon is shutting down.'); break; case PhabricatorDaemonLog::STATUS_EXITED: - $item->setDisabled(true); - $item->addAttribute(pht('This daemon exited cleanly.')); - $item->addIcon('fa-check grey', pht('Exited')); + $status_icon = 'fa-check grey'; + $status_label = pht('Exited'); + $status_tip = pht('This daemon exited cleanly.'); break; case PhabricatorDaemonLog::STATUS_WAIT: - $item->setStatusIcon('fa-clock-o blue'); - $item->addAttribute( - pht( - 'This daemon encountered an error recently and is waiting a '. - 'moment to restart.')); - $item->addIcon('fa-clock-o grey', pht('Waiting')); + $status_icon = 'fa-clock-o blue'; + $status_label = pht('Waiting'); + $status_tip = pht( + 'This daemon encountered an error recently and is waiting a '. + 'moment to restart.'); break; case PhabricatorDaemonLog::STATUS_UNKNOWN: default: - $item->setStatusIcon('fa-warning orange'); - $item->addAttribute( - pht( - 'This daemon has not reported its status recently. It may '. - 'have exited uncleanly.')); - $item->addIcon('fa-warning', pht('Unknown')); + $status_icon = 'fa-warning orange'; + $status_label = pht('Unknown'); + $status_tip = pht( + 'This daemon has not reported its status recently. It may '. + 'have exited uncleanly.'); 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; } }