mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-29 02:02:41 +01:00
Diffusion/phd/console improvements.
This commit is contained in:
parent
bf196910b0
commit
bb144542d3
26 changed files with 654 additions and 30 deletions
20
resources/sql/patches/007.daemonlog.sql
Normal file
20
resources/sql/patches/007.daemonlog.sql
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
create database phabricator_daemon;
|
||||||
|
|
||||||
|
create table phabricator_daemon.daemon_log (
|
||||||
|
id int unsigned not null auto_increment primary key,
|
||||||
|
daemon varchar(255) not null,
|
||||||
|
host varchar(255) not null,
|
||||||
|
pid int unsigned not null,
|
||||||
|
argv varchar(512) not null,
|
||||||
|
dateCreated int unsigned not null,
|
||||||
|
dateModified int unsigned not null
|
||||||
|
);
|
||||||
|
|
||||||
|
create table phabricator_daemon.daemon_logevent (
|
||||||
|
id int unsigned not null auto_increment primary key,
|
||||||
|
logID int unsigned not null,
|
||||||
|
logType varchar(4) not null,
|
||||||
|
message longblob not null,
|
||||||
|
epoch int unsigned not null,
|
||||||
|
key (logID, epoch)
|
||||||
|
);
|
|
@ -40,15 +40,80 @@ switch (isset($argv[1]) ? $argv[1] : 'help') {
|
||||||
$err = $control->executeStopCommand();
|
$err = $control->executeStopCommand();
|
||||||
exit($err);
|
exit($err);
|
||||||
|
|
||||||
case 'launch':
|
case 'repository-launch-readonly':
|
||||||
phutil_require_module('phutil', 'moduleutils');
|
$need_launch = phd_load_tracked_repositories_of_type('git');
|
||||||
|
if (!$need_launch) {
|
||||||
|
echo "There are no repositories with tracking enabled.\n";
|
||||||
|
} else {
|
||||||
|
foreach ($need_launch as $repository) {
|
||||||
|
$name = $repository->getName();
|
||||||
|
$callsign = $repository->getCallsign();
|
||||||
|
$desc = "'{$name}' ({$callsign})";
|
||||||
|
$phid = $repository->getPHID();
|
||||||
|
|
||||||
|
echo "Launching 'git pull' daemon on the {$desc} repository...\n";
|
||||||
|
$control->launchDaemon(
|
||||||
|
'PhabricatorRepositoryGitPullDaemon',
|
||||||
|
array(
|
||||||
|
$phid,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'repository-launch-master':
|
||||||
|
$need_launch = phd_load_tracked_repositories();
|
||||||
|
if (!$need_launch) {
|
||||||
|
echo "There are no repositories with tracking enabled.\n";
|
||||||
|
} else {
|
||||||
|
foreach ($need_launch as $repository) {
|
||||||
|
$name = $repository->getName();
|
||||||
|
$callsign = $repository->getCallsign();
|
||||||
|
$desc = "'{$name}' ({$callsign})";
|
||||||
|
$phid = $repository->getPHID();
|
||||||
|
|
||||||
|
switch ($repository->getVersionControlSystem()) {
|
||||||
|
case 'git':
|
||||||
|
echo "Launching 'git pull' daemon on the {$desc} repository...\n";
|
||||||
|
$control->launchDaemon(
|
||||||
|
'PhabricatorRepositoryGitPullDaemon',
|
||||||
|
array(
|
||||||
|
$phid,
|
||||||
|
));
|
||||||
|
echo "Launching discovery daemon on the {$desc} repository...\n";
|
||||||
|
$control->launchDaemon(
|
||||||
|
'PhabricatorRepositoryGitCommitDiscoveryDaemon',
|
||||||
|
array(
|
||||||
|
$phid,
|
||||||
|
));
|
||||||
|
break;
|
||||||
|
case 'svn':
|
||||||
|
echo "Launching discovery daemon on the {$desc} repository...\n";
|
||||||
|
$control->launchDaemon(
|
||||||
|
'PhabricatorRepositorySvnCommitDiscoveryDaemon',
|
||||||
|
array(
|
||||||
|
$phid,
|
||||||
|
));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "Launching CommitTask daemon...\n";
|
||||||
|
$control->launchDaemon(
|
||||||
|
'PhabricatorRepositoryCommitTaskDaemon',
|
||||||
|
array());
|
||||||
|
|
||||||
|
echo "Done.\n";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'launch':
|
||||||
$daemon = idx($argv, 2);
|
$daemon = idx($argv, 2);
|
||||||
if (!$daemon) {
|
if (!$daemon) {
|
||||||
throw new Exception("Daemon name required!");
|
throw new Exception("Daemon name required!");
|
||||||
}
|
}
|
||||||
|
|
||||||
$pass = array_slice($argv, 3);
|
$pass_argv = array_slice($argv, 3);
|
||||||
|
|
||||||
$n = 1;
|
$n = 1;
|
||||||
if (is_numeric($daemon)) {
|
if (is_numeric($daemon)) {
|
||||||
|
@ -60,7 +125,7 @@ switch (isset($argv[1]) ? $argv[1] : 'help') {
|
||||||
if (!$daemon) {
|
if (!$daemon) {
|
||||||
throw new Exception("Daemon name required!");
|
throw new Exception("Daemon name required!");
|
||||||
}
|
}
|
||||||
$pass = array_slice($argv, 4);
|
$pass_argv = array_slice($argv, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
$loader = new PhutilSymbolLoader();
|
$loader = new PhutilSymbolLoader();
|
||||||
|
@ -92,34 +157,13 @@ switch (isset($argv[1]) ? $argv[1] : 'help') {
|
||||||
$daemon = reset($match);
|
$daemon = reset($match);
|
||||||
}
|
}
|
||||||
|
|
||||||
$libphutil_root = dirname(phutil_get_library_root('phutil'));
|
echo "Launching {$n} x {$daemon}";
|
||||||
$launch_daemon = $libphutil_root.'/scripts/daemon/';
|
|
||||||
|
|
||||||
// TODO: This should be a much better user experience.
|
|
||||||
Filesystem::assertExists($pid_dir);
|
|
||||||
Filesystem::assertIsDirectory($pid_dir);
|
|
||||||
Filesystem::assertWritable($pid_dir);
|
|
||||||
|
|
||||||
foreach ($pass as $key => $arg) {
|
|
||||||
$pass[$key] = escapeshellarg($arg);
|
|
||||||
}
|
|
||||||
|
|
||||||
echo "Starting {$n} x {$daemon}";
|
|
||||||
|
|
||||||
chdir($launch_daemon);
|
|
||||||
for ($ii = 0; $ii < $n; $ii++) {
|
for ($ii = 0; $ii < $n; $ii++) {
|
||||||
list($stdout, $stderr) = execx(
|
$control->launchDaemon($daemon, $pass_argv);
|
||||||
"./launch_daemon.php ".
|
|
||||||
"%s ".
|
|
||||||
"--load-phutil-library=%s ".
|
|
||||||
"--daemonize ".
|
|
||||||
"--phd=%s ".
|
|
||||||
implode(' ', $pass),
|
|
||||||
$daemon,
|
|
||||||
phutil_get_library_root('phabricator'),
|
|
||||||
$pid_dir);
|
|
||||||
echo ".";
|
echo ".";
|
||||||
}
|
}
|
||||||
|
|
||||||
echo "\n";
|
echo "\n";
|
||||||
echo "Done.\n";
|
echo "Done.\n";
|
||||||
|
|
||||||
|
@ -174,3 +218,33 @@ switch (isset($argv[1]) ? $argv[1] : 'help') {
|
||||||
$err = $control->executeHelpCommand();
|
$err = $control->executeHelpCommand();
|
||||||
exit($err);
|
exit($err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function phd_load_tracked_repositories_of_type($type) {
|
||||||
|
$repositories = phd_load_tracked_repositories();
|
||||||
|
|
||||||
|
foreach ($repositories as $key => $repository) {
|
||||||
|
if ($repository->getVersionControlSystem() != $type) {
|
||||||
|
unset($repositories[$key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $repositories;
|
||||||
|
}
|
||||||
|
|
||||||
|
function phd_load_tracked_repositories() {
|
||||||
|
phutil_require_module(
|
||||||
|
'phabricator',
|
||||||
|
'applications/repository/storage/repository');
|
||||||
|
|
||||||
|
$repositories = id(new PhabricatorRepository())->loadAll();
|
||||||
|
foreach ($repositories as $key => $repository) {
|
||||||
|
if (!$repository->getDetail('tracking-enabled')) {
|
||||||
|
unset($repositories[$key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $repositories;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -68,6 +68,8 @@ phutil_register_library_map(array(
|
||||||
'ConduitAPIRequest' => 'applications/conduit/protocol/request',
|
'ConduitAPIRequest' => 'applications/conduit/protocol/request',
|
||||||
'ConduitAPI_conduit_connect_Method' => 'applications/conduit/method/conduit/connect',
|
'ConduitAPI_conduit_connect_Method' => 'applications/conduit/method/conduit/connect',
|
||||||
'ConduitAPI_conduit_ping_Method' => 'applications/conduit/method/conduit/ping',
|
'ConduitAPI_conduit_ping_Method' => 'applications/conduit/method/conduit/ping',
|
||||||
|
'ConduitAPI_daemon_launched_Method' => 'applications/conduit/method/daemon/launched',
|
||||||
|
'ConduitAPI_daemon_log_Method' => 'applications/conduit/method/daemon/log',
|
||||||
'ConduitAPI_differential_creatediff_Method' => 'applications/conduit/method/differential/creatediff',
|
'ConduitAPI_differential_creatediff_Method' => 'applications/conduit/method/differential/creatediff',
|
||||||
'ConduitAPI_differential_createrevision_Method' => 'applications/conduit/method/differential/createrevision',
|
'ConduitAPI_differential_createrevision_Method' => 'applications/conduit/method/differential/createrevision',
|
||||||
'ConduitAPI_differential_find_Method' => 'applications/conduit/method/differential/find',
|
'ConduitAPI_differential_find_Method' => 'applications/conduit/method/differential/find',
|
||||||
|
@ -207,6 +209,10 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorDaemonConsoleController' => 'applications/daemon/controller/console',
|
'PhabricatorDaemonConsoleController' => 'applications/daemon/controller/console',
|
||||||
'PhabricatorDaemonControl' => 'infrastructure/daemon/control',
|
'PhabricatorDaemonControl' => 'infrastructure/daemon/control',
|
||||||
'PhabricatorDaemonController' => 'applications/daemon/controller/base',
|
'PhabricatorDaemonController' => 'applications/daemon/controller/base',
|
||||||
|
'PhabricatorDaemonDAO' => 'infrastructure/daemon/storage/base',
|
||||||
|
'PhabricatorDaemonLog' => 'infrastructure/daemon/storage/log',
|
||||||
|
'PhabricatorDaemonLogEvent' => 'infrastructure/daemon/storage/event',
|
||||||
|
'PhabricatorDaemonLogViewController' => 'applications/daemon/controller/logview',
|
||||||
'PhabricatorDaemonReference' => 'infrastructure/daemon/control/reference',
|
'PhabricatorDaemonReference' => 'infrastructure/daemon/control/reference',
|
||||||
'PhabricatorDaemonTimelineConsoleController' => 'applications/daemon/controller/timeline',
|
'PhabricatorDaemonTimelineConsoleController' => 'applications/daemon/controller/timeline',
|
||||||
'PhabricatorDaemonTimelineEventController' => 'applications/daemon/controller/timelineevent',
|
'PhabricatorDaemonTimelineEventController' => 'applications/daemon/controller/timelineevent',
|
||||||
|
@ -421,6 +427,8 @@ phutil_register_library_map(array(
|
||||||
'CelerityResourceController' => 'AphrontController',
|
'CelerityResourceController' => 'AphrontController',
|
||||||
'ConduitAPI_conduit_connect_Method' => 'ConduitAPIMethod',
|
'ConduitAPI_conduit_connect_Method' => 'ConduitAPIMethod',
|
||||||
'ConduitAPI_conduit_ping_Method' => 'ConduitAPIMethod',
|
'ConduitAPI_conduit_ping_Method' => 'ConduitAPIMethod',
|
||||||
|
'ConduitAPI_daemon_launched_Method' => 'ConduitAPIMethod',
|
||||||
|
'ConduitAPI_daemon_log_Method' => 'ConduitAPIMethod',
|
||||||
'ConduitAPI_differential_creatediff_Method' => 'ConduitAPIMethod',
|
'ConduitAPI_differential_creatediff_Method' => 'ConduitAPIMethod',
|
||||||
'ConduitAPI_differential_createrevision_Method' => 'ConduitAPIMethod',
|
'ConduitAPI_differential_createrevision_Method' => 'ConduitAPIMethod',
|
||||||
'ConduitAPI_differential_find_Method' => 'ConduitAPIMethod',
|
'ConduitAPI_differential_find_Method' => 'ConduitAPIMethod',
|
||||||
|
@ -521,6 +529,10 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorDaemon' => 'PhutilDaemon',
|
'PhabricatorDaemon' => 'PhutilDaemon',
|
||||||
'PhabricatorDaemonConsoleController' => 'PhabricatorDaemonController',
|
'PhabricatorDaemonConsoleController' => 'PhabricatorDaemonController',
|
||||||
'PhabricatorDaemonController' => 'PhabricatorController',
|
'PhabricatorDaemonController' => 'PhabricatorController',
|
||||||
|
'PhabricatorDaemonDAO' => 'PhabricatorLiskDAO',
|
||||||
|
'PhabricatorDaemonLog' => 'PhabricatorDaemonDAO',
|
||||||
|
'PhabricatorDaemonLogEvent' => 'PhabricatorDaemonDAO',
|
||||||
|
'PhabricatorDaemonLogViewController' => 'PhabricatorDaemonController',
|
||||||
'PhabricatorDaemonTimelineConsoleController' => 'PhabricatorDaemonController',
|
'PhabricatorDaemonTimelineConsoleController' => 'PhabricatorDaemonController',
|
||||||
'PhabricatorDaemonTimelineEventController' => 'PhabricatorDaemonController',
|
'PhabricatorDaemonTimelineEventController' => 'PhabricatorDaemonController',
|
||||||
'PhabricatorDirectoryCategory' => 'PhabricatorDirectoryDAO',
|
'PhabricatorDirectoryCategory' => 'PhabricatorDirectoryDAO',
|
||||||
|
|
|
@ -209,6 +209,9 @@ class AphrontDefaultApplicationConfiguration
|
||||||
),
|
),
|
||||||
|
|
||||||
'/daemon/' => array(
|
'/daemon/' => array(
|
||||||
|
'log/' => array(
|
||||||
|
'(?P<id>\d+)/$' => 'PhabricatorDaemonLogViewController',
|
||||||
|
),
|
||||||
'timeline/$' => 'PhabricatorDaemonTimelineConsoleController',
|
'timeline/$' => 'PhabricatorDaemonTimelineConsoleController',
|
||||||
'timeline/(?P<id>\d+)/$' => 'PhabricatorDaemonTimelineEventController',
|
'timeline/(?P<id>\d+)/$' => 'PhabricatorDaemonTimelineEventController',
|
||||||
'$' => 'PhabricatorDaemonConsoleController',
|
'$' => 'PhabricatorDaemonConsoleController',
|
||||||
|
|
|
@ -0,0 +1,61 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright 2011 Facebook, Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class ConduitAPI_daemon_launched_Method extends ConduitAPIMethod {
|
||||||
|
|
||||||
|
public function shouldRequireAuthentication() {
|
||||||
|
// TODO: Lock this down once we build phantoms.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getMethodDescription() {
|
||||||
|
return "Used by daemons to log run status.";
|
||||||
|
}
|
||||||
|
|
||||||
|
public function defineParamTypes() {
|
||||||
|
return array(
|
||||||
|
'daemon' => 'required string',
|
||||||
|
'host' => 'required string',
|
||||||
|
'pid' => 'required int',
|
||||||
|
'argv' => 'required string',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function defineReturnType() {
|
||||||
|
return 'string';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function defineErrorTypes() {
|
||||||
|
return array(
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function execute(ConduitAPIRequest $request) {
|
||||||
|
|
||||||
|
$daemon_log = new PhabricatorDaemonLog();
|
||||||
|
$daemon_log->setDaemon($request->getValue('daemon'));
|
||||||
|
$daemon_log->setHost($request->getValue('host'));
|
||||||
|
$daemon_log->setPID($request->getValue('pid'));
|
||||||
|
$daemon_log->setArgv(json_decode($request->getValue('argv')));
|
||||||
|
|
||||||
|
$daemon_log->save();
|
||||||
|
|
||||||
|
return $daemon_log->getID();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
13
src/applications/conduit/method/daemon/launched/__init__.php
Normal file
13
src/applications/conduit/method/daemon/launched/__init__.php
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is automatically generated. Lint this module to rebuild it.
|
||||||
|
* @generated
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_module('phabricator', 'applications/conduit/method/base');
|
||||||
|
phutil_require_module('phabricator', 'infrastructure/daemon/storage/log');
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_source('ConduitAPI_daemon_launched_Method.php');
|
|
@ -0,0 +1,60 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright 2011 Facebook, Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class ConduitAPI_daemon_log_Method extends ConduitAPIMethod {
|
||||||
|
|
||||||
|
public function shouldRequireAuthentication() {
|
||||||
|
// TODO: Lock this down once we build phantoms.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getMethodDescription() {
|
||||||
|
return "Used by daemons to log events.";
|
||||||
|
}
|
||||||
|
|
||||||
|
public function defineParamTypes() {
|
||||||
|
return array(
|
||||||
|
'daemonLogID' => 'required int',
|
||||||
|
'type' => 'required string',
|
||||||
|
'message' => 'optional string',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function defineReturnType() {
|
||||||
|
return 'void';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function defineErrorTypes() {
|
||||||
|
return array(
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function execute(ConduitAPIRequest $request) {
|
||||||
|
|
||||||
|
$daemon_event = new PhabricatorDaemonLogEvent();
|
||||||
|
$daemon_event->setLogID($request->getValue('daemonLogID'));
|
||||||
|
$daemon_event->setLogType($request->getValue('type'));
|
||||||
|
$daemon_event->setMessage((string)$request->getValue('message'));
|
||||||
|
$daemon_event->setEpoch(time());
|
||||||
|
|
||||||
|
$daemon_event->save();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
13
src/applications/conduit/method/daemon/log/__init__.php
Normal file
13
src/applications/conduit/method/daemon/log/__init__.php
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is automatically generated. Lint this module to rebuild it.
|
||||||
|
* @generated
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_module('phabricator', 'applications/conduit/method/base');
|
||||||
|
phutil_require_module('phabricator', 'infrastructure/daemon/storage/event');
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_source('ConduitAPI_daemon_log_Method.php');
|
|
@ -19,6 +19,60 @@
|
||||||
class PhabricatorDaemonConsoleController extends PhabricatorDaemonController {
|
class PhabricatorDaemonConsoleController extends PhabricatorDaemonController {
|
||||||
|
|
||||||
public function processRequest() {
|
public function processRequest() {
|
||||||
|
$logs = id(new PhabricatorDaemonLog())->loadAllWhere(
|
||||||
|
'1 = 1 ORDER BY id DESC LIMIT 15');
|
||||||
|
|
||||||
|
$rows = array();
|
||||||
|
foreach ($logs as $log) {
|
||||||
|
$epoch = $log->getDateCreated();
|
||||||
|
|
||||||
|
$argv = $log->getArgv();
|
||||||
|
$argv = array_map('phutil_escape_html', $argv);
|
||||||
|
$argv = implode('<br />', $argv);
|
||||||
|
|
||||||
|
$rows[] = array(
|
||||||
|
phutil_escape_html($log->getDaemon()),
|
||||||
|
phutil_escape_html($log->getHost()),
|
||||||
|
$log->getPID(),
|
||||||
|
$argv,
|
||||||
|
date('M j, Y', $epoch),
|
||||||
|
date('g:i A', $epoch),
|
||||||
|
phutil_render_tag(
|
||||||
|
'a',
|
||||||
|
array(
|
||||||
|
'href' => '/daemon/log/'.$log->getID().'/',
|
||||||
|
'class' => 'button small grey',
|
||||||
|
),
|
||||||
|
'View Log'),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$daemon_table = new AphrontTableView($rows);
|
||||||
|
$daemon_table->setHeaders(
|
||||||
|
array(
|
||||||
|
'Daemon',
|
||||||
|
'Host',
|
||||||
|
'PID',
|
||||||
|
'Argv',
|
||||||
|
'Date',
|
||||||
|
'Time',
|
||||||
|
'View',
|
||||||
|
));
|
||||||
|
$daemon_table->setColumnClasses(
|
||||||
|
array(
|
||||||
|
'',
|
||||||
|
'',
|
||||||
|
'',
|
||||||
|
'wide wrap',
|
||||||
|
'',
|
||||||
|
'right',
|
||||||
|
'action',
|
||||||
|
));
|
||||||
|
|
||||||
|
$daemon_panel = new AphrontPanelView();
|
||||||
|
$daemon_panel->setHeader('Recently Launched Daemons');
|
||||||
|
$daemon_panel->appendChild($daemon_table);
|
||||||
|
|
||||||
$tasks = id(new PhabricatorWorkerTask())->loadAllWhere(
|
$tasks = id(new PhabricatorWorkerTask())->loadAllWhere(
|
||||||
'leaseOwner IS NOT NULL');
|
'leaseOwner IS NOT NULL');
|
||||||
|
|
||||||
|
@ -118,6 +172,7 @@ class PhabricatorDaemonConsoleController extends PhabricatorDaemonController {
|
||||||
|
|
||||||
return $this->buildStandardPageResponse(
|
return $this->buildStandardPageResponse(
|
||||||
array(
|
array(
|
||||||
|
$daemon_panel,
|
||||||
$leased_panel,
|
$leased_panel,
|
||||||
$queued_panel,
|
$queued_panel,
|
||||||
$cursor_panel,
|
$cursor_panel,
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
|
|
||||||
|
|
||||||
phutil_require_module('phabricator', 'applications/daemon/controller/base');
|
phutil_require_module('phabricator', 'applications/daemon/controller/base');
|
||||||
|
phutil_require_module('phabricator', 'infrastructure/daemon/storage/log');
|
||||||
phutil_require_module('phabricator', 'infrastructure/daemon/timeline/storage/cursor');
|
phutil_require_module('phabricator', 'infrastructure/daemon/timeline/storage/cursor');
|
||||||
phutil_require_module('phabricator', 'infrastructure/daemon/workers/storage/task');
|
phutil_require_module('phabricator', 'infrastructure/daemon/workers/storage/task');
|
||||||
phutil_require_module('phabricator', 'storage/queryfx');
|
phutil_require_module('phabricator', 'storage/queryfx');
|
||||||
|
|
|
@ -0,0 +1,82 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright 2011 Facebook, Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class PhabricatorDaemonLogViewController extends PhabricatorDaemonController {
|
||||||
|
|
||||||
|
private $id;
|
||||||
|
|
||||||
|
public function willProcessRequest(array $data) {
|
||||||
|
$this->id = $data['id'];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function processRequest() {
|
||||||
|
|
||||||
|
$log = id(new PhabricatorDaemonLog())->load($this->id);
|
||||||
|
if (!$log) {
|
||||||
|
return new Aphront404Response();
|
||||||
|
}
|
||||||
|
|
||||||
|
$events = id(new PhabricatorDaemonLogEvent())->loadAllWhere(
|
||||||
|
'logID = %d ORDER BY id DESC LIMIT 200',
|
||||||
|
$log->getID());
|
||||||
|
|
||||||
|
$content = array();
|
||||||
|
|
||||||
|
|
||||||
|
$rows = array();
|
||||||
|
foreach ($events as $event) {
|
||||||
|
$rows[] = array(
|
||||||
|
phutil_escape_html($event->getLogType()),
|
||||||
|
date('M j, Y', $event->getEpoch()),
|
||||||
|
date('g:i:s A', $event->getEpoch()),
|
||||||
|
str_replace("\n", '<br />', phutil_escape_html($event->getMessage())),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$log_table = new AphrontTableView($rows);
|
||||||
|
$log_table->setHeaders(
|
||||||
|
array(
|
||||||
|
'Type',
|
||||||
|
'Date',
|
||||||
|
'Time',
|
||||||
|
'Message',
|
||||||
|
));
|
||||||
|
$log_table->setColumnClasses(
|
||||||
|
array(
|
||||||
|
'',
|
||||||
|
'',
|
||||||
|
'right',
|
||||||
|
'wide wrap',
|
||||||
|
));
|
||||||
|
|
||||||
|
$log_panel = new AphrontPanelView();
|
||||||
|
$log_panel->setHeader('Daemon Logs');
|
||||||
|
$log_panel->appendChild($log_table);
|
||||||
|
|
||||||
|
$content[] = $log_panel;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return $this->buildStandardPageResponse(
|
||||||
|
$content,
|
||||||
|
array(
|
||||||
|
'title' => 'Log',
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
20
src/applications/daemon/controller/logview/__init__.php
Normal file
20
src/applications/daemon/controller/logview/__init__.php
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is automatically generated. Lint this module to rebuild it.
|
||||||
|
* @generated
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_module('phabricator', 'aphront/response/404');
|
||||||
|
phutil_require_module('phabricator', 'applications/daemon/controller/base');
|
||||||
|
phutil_require_module('phabricator', 'infrastructure/daemon/storage/event');
|
||||||
|
phutil_require_module('phabricator', 'infrastructure/daemon/storage/log');
|
||||||
|
phutil_require_module('phabricator', 'view/control/table');
|
||||||
|
phutil_require_module('phabricator', 'view/layout/panel');
|
||||||
|
|
||||||
|
phutil_require_module('phutil', 'markup');
|
||||||
|
phutil_require_module('phutil', 'utils');
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_source('PhabricatorDaemonLogViewController.php');
|
|
@ -23,6 +23,11 @@ class DiffusionHomeController extends DiffusionController {
|
||||||
// TODO: Restore "shortcuts" feature.
|
// TODO: Restore "shortcuts" feature.
|
||||||
|
|
||||||
$repositories = id(new PhabricatorRepository())->loadAll();
|
$repositories = id(new PhabricatorRepository())->loadAll();
|
||||||
|
foreach ($repositories as $key => $repository) {
|
||||||
|
if (!$repository->getDetail('tracking-enabled')) {
|
||||||
|
unset($repositories[$key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$commit = new PhabricatorRepositoryCommit();
|
$commit = new PhabricatorRepositoryCommit();
|
||||||
$conn_r = $commit->establishConnection('r');
|
$conn_r = $commit->establishConnection('r');
|
||||||
|
@ -77,7 +82,8 @@ class DiffusionHomeController extends DiffusionController {
|
||||||
'href' => '/diffusion/'.$repository->getCallsign().'/',
|
'href' => '/diffusion/'.$repository->getCallsign().'/',
|
||||||
),
|
),
|
||||||
phutil_escape_html($repository->getName())),
|
phutil_escape_html($repository->getName())),
|
||||||
$repository->getVersionControlSystem(),
|
PhabricatorRepositoryType::getNameForRepositoryType(
|
||||||
|
$repository->getVersionControlSystem()),
|
||||||
idx($commit_counts, $id, 0),
|
idx($commit_counts, $id, 0),
|
||||||
$commit
|
$commit
|
||||||
? DiffusionView::linkCommit(
|
? DiffusionView::linkCommit(
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
phutil_require_module('phabricator', 'applications/diffusion/controller/base');
|
phutil_require_module('phabricator', 'applications/diffusion/controller/base');
|
||||||
phutil_require_module('phabricator', 'applications/diffusion/view/base');
|
phutil_require_module('phabricator', 'applications/diffusion/view/base');
|
||||||
|
phutil_require_module('phabricator', 'applications/repository/constants/repositorytype');
|
||||||
phutil_require_module('phabricator', 'applications/repository/storage/commit');
|
phutil_require_module('phabricator', 'applications/repository/storage/commit');
|
||||||
phutil_require_module('phabricator', 'applications/repository/storage/repository');
|
phutil_require_module('phabricator', 'applications/repository/storage/repository');
|
||||||
phutil_require_module('phabricator', 'storage/queryfx');
|
phutil_require_module('phabricator', 'storage/queryfx');
|
||||||
|
|
|
@ -21,4 +21,13 @@ final class PhabricatorRepositoryType {
|
||||||
const REPOSITORY_TYPE_GIT = 'git';
|
const REPOSITORY_TYPE_GIT = 'git';
|
||||||
const REPOSITORY_TYPE_SVN = 'svn';
|
const REPOSITORY_TYPE_SVN = 'svn';
|
||||||
|
|
||||||
|
public static function getNameForRepositoryType($type) {
|
||||||
|
static $map = array(
|
||||||
|
self::REPOSITORY_TYPE_GIT => 'Git',
|
||||||
|
self::REPOSITORY_TYPE_SVN => 'Subversion',
|
||||||
|
);
|
||||||
|
|
||||||
|
return idx($map, $type, 'Unknown');
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,5 +6,7 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_module('phutil', 'utils');
|
||||||
|
|
||||||
|
|
||||||
phutil_require_source('PhabricatorRepositoryType.php');
|
phutil_require_source('PhabricatorRepositoryType.php');
|
||||||
|
|
|
@ -26,10 +26,24 @@ class PhabricatorRepositoryListController
|
||||||
|
|
||||||
$rows = array();
|
$rows = array();
|
||||||
foreach ($repos as $repo) {
|
foreach ($repos as $repo) {
|
||||||
|
|
||||||
|
if ($repo->getDetail('tracking-enabled')) {
|
||||||
|
$diffusion_link = phutil_render_tag(
|
||||||
|
'a',
|
||||||
|
array(
|
||||||
|
'href' => '/diffusion/'.$repo->getCallsign().'/',
|
||||||
|
),
|
||||||
|
'View in Diffusion');
|
||||||
|
} else {
|
||||||
|
$diffusion_link = '<em>Not Tracked</em>';
|
||||||
|
}
|
||||||
|
|
||||||
$rows[] = array(
|
$rows[] = array(
|
||||||
phutil_escape_html($repo->getCallsign()),
|
phutil_escape_html($repo->getCallsign()),
|
||||||
phutil_escape_html($repo->getName()),
|
phutil_escape_html($repo->getName()),
|
||||||
$repo->getVersionControlSystem(),
|
PhabricatorRepositoryType::getNameForRepositoryType(
|
||||||
|
$repo->getVersionControlSystem()),
|
||||||
|
$diffusion_link,
|
||||||
phutil_render_tag(
|
phutil_render_tag(
|
||||||
'a',
|
'a',
|
||||||
array(
|
array(
|
||||||
|
@ -53,6 +67,7 @@ class PhabricatorRepositoryListController
|
||||||
'Callsign',
|
'Callsign',
|
||||||
'Repository',
|
'Repository',
|
||||||
'Type',
|
'Type',
|
||||||
|
'Diffusion',
|
||||||
'',
|
'',
|
||||||
''
|
''
|
||||||
));
|
));
|
||||||
|
@ -61,6 +76,7 @@ class PhabricatorRepositoryListController
|
||||||
null,
|
null,
|
||||||
'wide',
|
'wide',
|
||||||
null,
|
null,
|
||||||
|
null,
|
||||||
'action',
|
'action',
|
||||||
'action',
|
'action',
|
||||||
));
|
));
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_module('phabricator', 'applications/repository/constants/repositorytype');
|
||||||
phutil_require_module('phabricator', 'applications/repository/controller/base');
|
phutil_require_module('phabricator', 'applications/repository/controller/base');
|
||||||
phutil_require_module('phabricator', 'applications/repository/storage/repository');
|
phutil_require_module('phabricator', 'applications/repository/storage/repository');
|
||||||
phutil_require_module('phabricator', 'view/control/table');
|
phutil_require_module('phabricator', 'view/control/table');
|
||||||
|
|
|
@ -141,12 +141,58 @@ final class PhabricatorDaemonControl {
|
||||||
**parse-commit** __rXnnnn__
|
**parse-commit** __rXnnnn__
|
||||||
Parse a single commit.
|
Parse a single commit.
|
||||||
|
|
||||||
|
**repository-launch-master**
|
||||||
|
Launches daemons to update and parse all tracked repositories. You
|
||||||
|
must also launch Taskmaster daemons, either on the same machine or
|
||||||
|
elsewhere. You should launch a master only one machine. For other
|
||||||
|
machines, launch a 'readonly'.
|
||||||
|
|
||||||
|
**repository-launch-readonly**
|
||||||
|
Launches daemons to 'git pull' tracked git repositories so they
|
||||||
|
stay up to date.
|
||||||
|
|
||||||
EOHELP
|
EOHELP
|
||||||
);
|
);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function launchDaemon($daemon, array $argv) {
|
||||||
|
$symbols = $this->loadAvailableDaemonClasses();
|
||||||
|
$symbols = ipull($symbols, 'name', 'name');
|
||||||
|
if (empty($symbols[$daemon])) {
|
||||||
|
throw new Exception("Daemon '{$daemon}' is not known.");
|
||||||
|
}
|
||||||
|
|
||||||
|
$pid_dir = $this->getControlDirectory('pid');
|
||||||
|
|
||||||
|
$libphutil_root = dirname(phutil_get_library_root('phutil'));
|
||||||
|
$launch_daemon = $libphutil_root.'/scripts/daemon/';
|
||||||
|
|
||||||
|
// TODO: This should be a much better user experience.
|
||||||
|
Filesystem::assertExists($pid_dir);
|
||||||
|
Filesystem::assertIsDirectory($pid_dir);
|
||||||
|
Filesystem::assertWritable($pid_dir);
|
||||||
|
|
||||||
|
foreach ($argv as $key => $arg) {
|
||||||
|
$argv[$key] = escapeshellarg($arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Side effect. :/ We're playing games here to keep 'ps' looking reasonable.
|
||||||
|
chdir($launch_daemon);
|
||||||
|
|
||||||
|
execx(
|
||||||
|
"./launch_daemon.php ".
|
||||||
|
"%s ".
|
||||||
|
"--load-phutil-library=%s ".
|
||||||
|
"--conduit-uri=%s ".
|
||||||
|
"--daemonize ".
|
||||||
|
"--phd=%s ".
|
||||||
|
implode(' ', $argv),
|
||||||
|
$daemon,
|
||||||
|
phutil_get_library_root('phabricator'),
|
||||||
|
PhabricatorEnv::getURI('/api/'),
|
||||||
|
$pid_dir);
|
||||||
|
}
|
||||||
|
|
||||||
protected function getControlDirectory($dir) {
|
protected function getControlDirectory($dir) {
|
||||||
return PhabricatorEnv::getEnvConfig('phd.pid-directory').'/'.$dir;
|
return PhabricatorEnv::getEnvConfig('phd.pid-directory').'/'.$dir;
|
||||||
|
|
|
@ -11,6 +11,8 @@ phutil_require_module('phabricator', 'infrastructure/env');
|
||||||
|
|
||||||
phutil_require_module('phutil', 'console');
|
phutil_require_module('phutil', 'console');
|
||||||
phutil_require_module('phutil', 'filesystem');
|
phutil_require_module('phutil', 'filesystem');
|
||||||
|
phutil_require_module('phutil', 'future/exec');
|
||||||
|
phutil_require_module('phutil', 'moduleutils');
|
||||||
phutil_require_module('phutil', 'symbols');
|
phutil_require_module('phutil', 'symbols');
|
||||||
phutil_require_module('phutil', 'utils');
|
phutil_require_module('phutil', 'utils');
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright 2011 Facebook, Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
abstract class PhabricatorDaemonDAO extends PhabricatorLiskDAO {
|
||||||
|
|
||||||
|
public function getApplicationName() {
|
||||||
|
return 'daemon';
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
12
src/infrastructure/daemon/storage/base/__init__.php
Normal file
12
src/infrastructure/daemon/storage/base/__init__.php
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is automatically generated. Lint this module to rebuild it.
|
||||||
|
* @generated
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_module('phabricator', 'applications/base/storage/lisk');
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_source('PhabricatorDaemonDAO.php');
|
|
@ -0,0 +1,32 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright 2011 Facebook, Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class PhabricatorDaemonLogEvent extends PhabricatorDaemonDAO {
|
||||||
|
|
||||||
|
protected $logID;
|
||||||
|
protected $logType;
|
||||||
|
protected $message;
|
||||||
|
protected $epoch;
|
||||||
|
|
||||||
|
public function getConfiguration() {
|
||||||
|
return array(
|
||||||
|
self::CONFIG_TIMESTAMPS => false,
|
||||||
|
) + parent::getConfiguration();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
12
src/infrastructure/daemon/storage/event/__init__.php
Normal file
12
src/infrastructure/daemon/storage/event/__init__.php
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is automatically generated. Lint this module to rebuild it.
|
||||||
|
* @generated
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_module('phabricator', 'infrastructure/daemon/storage/base');
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_source('PhabricatorDaemonLogEvent.php');
|
|
@ -0,0 +1,34 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright 2011 Facebook, Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class PhabricatorDaemonLog extends PhabricatorDaemonDAO {
|
||||||
|
|
||||||
|
protected $daemon;
|
||||||
|
protected $host;
|
||||||
|
protected $pid;
|
||||||
|
protected $argv;
|
||||||
|
|
||||||
|
public function getConfiguration() {
|
||||||
|
return array(
|
||||||
|
self::CONFIG_SERIALIZATION => array(
|
||||||
|
'argv' => self::SERIALIZATION_JSON,
|
||||||
|
),
|
||||||
|
) + parent::getConfiguration();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
12
src/infrastructure/daemon/storage/log/__init__.php
Normal file
12
src/infrastructure/daemon/storage/log/__init__.php
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is automatically generated. Lint this module to rebuild it.
|
||||||
|
* @generated
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_module('phabricator', 'infrastructure/daemon/storage/base');
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_source('PhabricatorDaemonLog.php');
|
Loading…
Reference in a new issue