1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-30 02:32:42 +01:00
phorge-phorge/scripts/daemon/phabricator_daemon_launcher.php

233 lines
6 KiB
PHP
Raw Normal View History

#!/usr/bin/env php
<?php
/*
* Copyright 2012 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.
*/
$root = dirname(dirname(dirname(__FILE__)));
require_once $root.'/scripts/__init_script__.php';
2011-03-14 23:43:56 +01:00
$control = new PhabricatorDaemonControl();
must_have_extension('pcntl');
must_have_extension('posix');
function must_have_extension($ext) {
if (!extension_loaded($ext)) {
echo "ERROR: The PHP extension '{$ext}' is not installed. You must ".
"install it to run daemons on this machine.\n";
exit(1);
}
}
$command = isset($argv[1]) ? $argv[1] : 'help';
switch ($command) {
2011-03-14 20:33:20 +01:00
case 'list':
2011-03-14 23:43:56 +01:00
$err = $control->executeListCommand();
exit($err);
2011-03-14 20:33:20 +01:00
case 'status':
2011-03-14 23:43:56 +01:00
$err = $control->executeStatusCommand();
exit($err);
2011-03-14 20:33:20 +01:00
2011-03-14 23:43:56 +01:00
case 'stop':
$pass_argv = array_slice($argv, 2);
$err = $control->executeStopCommand($pass_argv);
2011-03-14 23:43:56 +01:00
exit($err);
2011-03-14 20:33:20 +01:00
case 'restart':
$err = $control->executeStopCommand(array());
if ($err) {
exit($err);
}
/* Fall Through */
case 'start':
$running = $control->loadRunningDaemons();
// "running" might not mean actually running so much as was running at
// some point. ergo, do a quick grouping and only barf if daemons are
// *actually* running.
$running_dict = mgroup($running, 'isRunning');
if (!empty($running_dict[true])) {
echo phutil_console_wrap(
"phd start: Unable to start daemons because daemons are already ".
"running.\n".
"You can view running daemons with 'phd status'.\n".
"You can stop running daemons with 'phd stop'.\n".
"You can use 'phd restart' to stop all daemons before starting new ".
"daemons.\n");
exit(1);
}
$daemons = array(
array('PhabricatorRepositoryPullLocalDaemon', array()),
array('PhabricatorGarbageCollectorDaemon', array()),
);
$taskmasters = PhabricatorEnv::getEnvConfig('phd.start-taskmasters');
for ($ii = 0; $ii < $taskmasters; $ii++) {
$daemons[] = array('PhabricatorTaskmasterDaemon', array());
}
will_launch($control);
foreach ($daemons as $spec) {
list($name, $argv) = $spec;
echo "Launching '{$name}'...\n";
$control->launchDaemon($name, $argv);
}
echo "Done.\n";
break;
case 'repository-launch-readonly':
2011-03-15 21:38:14 +01:00
case 'repository-launch-master':
if ($command == 'repository-launch-readonly') {
$daemon_args = array(
'--',
'--no-discovery',
);
} else {
$daemon_args = array();
}
2011-03-15 21:38:14 +01:00
$need_launch = phd_load_tracked_repositories();
if (!$need_launch) {
echo "There are no repositories with tracking enabled.\n";
exit(1);
Use one daemon to discover commits in all repositories, not one per repository Summary: See D2418. This merges the commit discovery daemon into the same single daemon, and applies all the same rules to it. There are relatively few implementation changes, but a few things did change: - I simplified/improved Mercurial importing, by finding full branch tip hashes with "--debug branches" and using "parents --template {node}" so we don't need to do separate "--debug id" calls. - Added a new "--not" flag to exclude repositories, since I switched to real arg parsing anyway. - I removed a web UI notification that you need to restart the daemons, this is no longer true. - I added a web UI notification that no pull daemon is running on the machine. NOTE: @makinde, this doesn't change anything from your perspective, but it something breaks this is the likely cause. This implicitly resolves T792, because discovery no longer runs before pulling. Test Plan: - Swapped databases to a fresh install. - Ran "pulllocal" in debug mode. Verified it correctly does nothing (fixed a minor issue with min() on empty array). - Added an SVN repository. Verified it cloned and discovered correctly. - Added a Mercurial repository. Verified it cloned and discovered correctly. - Added a Git repository. Verified it cloned and discovered correctly. - Ran with arguments to verify behaviors: "--not MTEST --not STEST", "P --no-discovery", "P". Reviewers: btrahan, csilvers, Makinde Reviewed By: btrahan CC: aran Maniphest Tasks: T792 Differential Revision: https://secure.phabricator.com/D2430
2012-05-08 21:53:41 +02:00
}
Add a Mercurial commit discovery daemon Summary: Repository import has three major steps: - Commit discovery (serial) - Message parsing (parallel, mostly VCS independent) - Change parsing (parallel, highly VCS dependent) This implements commit discovery for Mercurial, similar to git's parsing: - List the heads of all the branches. - If we haven't already discovered them, follow them back to their roots (or the first commit we have discovered). - Import all the newly discovered commits, oldest first. This is a little complicated but it ensures we discover commits in depth order, so the discovery process is robust against interruption/failure. If we just inserted commits as we went, we might read the tip, insert it, and then crash. When we ran again, we'd think we had already discovered commits older than HEAD. This also allows later stages to rely on being able to find Phabricator commit IDs which correspond to parent commits. NOTE: This importer is fairly slow because "hg" has a large startup time (compare "hg --version" to "git --version" and "svn --version"; on my machine, hg has 60ms of overhead for any command) and we need to run many commands (see the whole "hg id" mess). You can expect something like 10,000 per hour, which means you may need to run overnight to discover a large repository (IIRC, the svn/git discovery processes are both about an order of magnitude faster). We could improve this with batching, but I want to keep it as simple as possible for now. Test Plan: Discovered all the commits in the main Mercurial repository, http://selenic.com/repo/hg. Reviewers: Makinde, jungejason, nh, tuomaspelkonen, aran Reviewed By: Makinde CC: aran, Makinde Differential Revision: 943
2011-09-16 12:56:23 +02:00
Use one daemon to discover commits in all repositories, not one per repository Summary: See D2418. This merges the commit discovery daemon into the same single daemon, and applies all the same rules to it. There are relatively few implementation changes, but a few things did change: - I simplified/improved Mercurial importing, by finding full branch tip hashes with "--debug branches" and using "parents --template {node}" so we don't need to do separate "--debug id" calls. - Added a new "--not" flag to exclude repositories, since I switched to real arg parsing anyway. - I removed a web UI notification that you need to restart the daemons, this is no longer true. - I added a web UI notification that no pull daemon is running on the machine. NOTE: @makinde, this doesn't change anything from your perspective, but it something breaks this is the likely cause. This implicitly resolves T792, because discovery no longer runs before pulling. Test Plan: - Swapped databases to a fresh install. - Ran "pulllocal" in debug mode. Verified it correctly does nothing (fixed a minor issue with min() on empty array). - Added an SVN repository. Verified it cloned and discovered correctly. - Added a Mercurial repository. Verified it cloned and discovered correctly. - Added a Git repository. Verified it cloned and discovered correctly. - Ran with arguments to verify behaviors: "--not MTEST --not STEST", "P --no-discovery", "P". Reviewers: btrahan, csilvers, Makinde Reviewed By: btrahan CC: aran Maniphest Tasks: T792 Differential Revision: https://secure.phabricator.com/D2430
2012-05-08 21:53:41 +02:00
will_launch($control);
2011-03-15 21:38:14 +01:00
echo "Launching PullLocal daemon...\n";
Use one daemon to discover commits in all repositories, not one per repository Summary: See D2418. This merges the commit discovery daemon into the same single daemon, and applies all the same rules to it. There are relatively few implementation changes, but a few things did change: - I simplified/improved Mercurial importing, by finding full branch tip hashes with "--debug branches" and using "parents --template {node}" so we don't need to do separate "--debug id" calls. - Added a new "--not" flag to exclude repositories, since I switched to real arg parsing anyway. - I removed a web UI notification that you need to restart the daemons, this is no longer true. - I added a web UI notification that no pull daemon is running on the machine. NOTE: @makinde, this doesn't change anything from your perspective, but it something breaks this is the likely cause. This implicitly resolves T792, because discovery no longer runs before pulling. Test Plan: - Swapped databases to a fresh install. - Ran "pulllocal" in debug mode. Verified it correctly does nothing (fixed a minor issue with min() on empty array). - Added an SVN repository. Verified it cloned and discovered correctly. - Added a Mercurial repository. Verified it cloned and discovered correctly. - Added a Git repository. Verified it cloned and discovered correctly. - Ran with arguments to verify behaviors: "--not MTEST --not STEST", "P --no-discovery", "P". Reviewers: btrahan, csilvers, Makinde Reviewed By: btrahan CC: aran Maniphest Tasks: T792 Differential Revision: https://secure.phabricator.com/D2430
2012-05-08 21:53:41 +02:00
$control->launchDaemon(
'PhabricatorRepositoryPullLocalDaemon',
$daemon_args);
Use one daemon to discover commits in all repositories, not one per repository Summary: See D2418. This merges the commit discovery daemon into the same single daemon, and applies all the same rules to it. There are relatively few implementation changes, but a few things did change: - I simplified/improved Mercurial importing, by finding full branch tip hashes with "--debug branches" and using "parents --template {node}" so we don't need to do separate "--debug id" calls. - Added a new "--not" flag to exclude repositories, since I switched to real arg parsing anyway. - I removed a web UI notification that you need to restart the daemons, this is no longer true. - I added a web UI notification that no pull daemon is running on the machine. NOTE: @makinde, this doesn't change anything from your perspective, but it something breaks this is the likely cause. This implicitly resolves T792, because discovery no longer runs before pulling. Test Plan: - Swapped databases to a fresh install. - Ran "pulllocal" in debug mode. Verified it correctly does nothing (fixed a minor issue with min() on empty array). - Added an SVN repository. Verified it cloned and discovered correctly. - Added a Mercurial repository. Verified it cloned and discovered correctly. - Added a Git repository. Verified it cloned and discovered correctly. - Ran with arguments to verify behaviors: "--not MTEST --not STEST", "P --no-discovery", "P". Reviewers: btrahan, csilvers, Makinde Reviewed By: btrahan CC: aran Maniphest Tasks: T792 Differential Revision: https://secure.phabricator.com/D2430
2012-05-08 21:53:41 +02:00
echo "NOTE: '{$command}' is deprecated. Consult the documentation.\n";
Use one daemon to discover commits in all repositories, not one per repository Summary: See D2418. This merges the commit discovery daemon into the same single daemon, and applies all the same rules to it. There are relatively few implementation changes, but a few things did change: - I simplified/improved Mercurial importing, by finding full branch tip hashes with "--debug branches" and using "parents --template {node}" so we don't need to do separate "--debug id" calls. - Added a new "--not" flag to exclude repositories, since I switched to real arg parsing anyway. - I removed a web UI notification that you need to restart the daemons, this is no longer true. - I added a web UI notification that no pull daemon is running on the machine. NOTE: @makinde, this doesn't change anything from your perspective, but it something breaks this is the likely cause. This implicitly resolves T792, because discovery no longer runs before pulling. Test Plan: - Swapped databases to a fresh install. - Ran "pulllocal" in debug mode. Verified it correctly does nothing (fixed a minor issue with min() on empty array). - Added an SVN repository. Verified it cloned and discovered correctly. - Added a Mercurial repository. Verified it cloned and discovered correctly. - Added a Git repository. Verified it cloned and discovered correctly. - Ran with arguments to verify behaviors: "--not MTEST --not STEST", "P --no-discovery", "P". Reviewers: btrahan, csilvers, Makinde Reviewed By: btrahan CC: aran Maniphest Tasks: T792 Differential Revision: https://secure.phabricator.com/D2430
2012-05-08 21:53:41 +02:00
echo "Done.\n";
2011-03-15 21:38:14 +01:00
break;
2011-03-14 20:33:20 +01:00
2011-03-15 21:38:14 +01:00
case 'launch':
case 'debug':
$is_debug = ($argv[1] == 'debug');
2011-03-14 20:33:20 +01:00
$daemon = idx($argv, 2);
if (!$daemon) {
throw new Exception("Daemon name required!");
}
2011-03-15 21:38:14 +01:00
$pass_argv = array_slice($argv, 3);
2011-03-14 23:43:56 +01:00
2011-03-14 20:33:20 +01:00
$n = 1;
if (!$is_debug) {
if (is_numeric($daemon)) {
$n = $daemon;
if ($n < 1) {
throw new Exception("Count must be at least 1!");
}
$daemon = idx($argv, 3);
if (!$daemon) {
throw new Exception("Daemon name required!");
}
$pass_argv = array_slice($argv, 4);
2011-03-14 20:33:20 +01:00
}
}
$loader = new PhutilSymbolLoader();
$symbols = $loader
->setAncestorClass('PhutilDaemon')
->selectSymbolsWithoutLoading();
$symbols = ipull($symbols, 'name');
$match = array();
foreach ($symbols as $symbol) {
if (stripos($symbol, $daemon) !== false) {
if (strtolower($symbol) == strtolower($daemon)) {
$match = array($symbol);
break;
} else {
$match[] = $symbol;
}
}
}
if (count($match) == 0) {
throw new Exception(
"No daemons match! Use 'phd list' for a list of daemons.");
} else if (count($match) > 1) {
throw new Exception(
"Which of these daemons did you mean?\n".
" ".implode("\n ", $match));
} else {
$daemon = reset($match);
}
$with_logs = true;
if ($is_debug) {
// In debug mode, we emit errors straight to stdout, so nothing useful
// will show up in the logs. Don't echo the message about stuff showing
// up in them, since it would be confusing.
$with_logs = false;
}
will_launch($control, $with_logs);
if ($is_debug) {
echo "Launching {$daemon} in debug mode (nondaemonized)...\n";
} else {
echo "Launching {$n} x {$daemon}";
}
2011-03-14 23:43:56 +01:00
2011-03-14 20:33:20 +01:00
for ($ii = 0; $ii < $n; $ii++) {
$control->launchDaemon($daemon, $pass_argv, $is_debug);
if (!$is_debug) {
echo ".";
}
2011-03-14 20:33:20 +01:00
}
2011-03-15 21:38:14 +01:00
2011-03-14 20:33:20 +01:00
echo "\n";
echo "Done.\n";
break;
case '--help':
case 'help':
default:
2011-03-14 23:43:56 +01:00
$err = $control->executeHelpCommand();
exit($err);
}
2011-03-15 21:38:14 +01:00
function phd_load_tracked_repositories() {
$repositories = id(new PhabricatorRepository())->loadAll();
foreach ($repositories as $key => $repository) {
if (!$repository->isTracked()) {
2011-03-15 21:38:14 +01:00
unset($repositories[$key]);
}
}
return $repositories;
}
function will_launch($control, $with_logs = true) {
echo "Staging launch...\n";
$control->pingConduit();
if ($with_logs) {
$log_dir = $control->getControlDirectory('log').'/daemons.log';
echo "NOTE: Logs will appear in '{$log_dir}'.\n\n";
}
}