Differential D11288 Diff 27128 src/applications/aphlict/management/PhabricatorAphlictManagementWorkflow.php
Changeset View
Changeset View
Standalone View
Standalone View
src/applications/aphlict/management/PhabricatorAphlictManagementWorkflow.php
<?php | <?php | ||||
abstract class PhabricatorAphlictManagementWorkflow | abstract class PhabricatorAphlictManagementWorkflow | ||||
extends PhabricatorManagementWorkflow { | extends PhabricatorManagementWorkflow { | ||||
private $debug = false; | |||||
private $clientHost; | |||||
public function didConstruct() { | |||||
$this | |||||
->setArguments( | |||||
array( | |||||
array( | |||||
'name' => 'client-host', | |||||
'param' => 'hostname', | |||||
'help' => pht('Hostname to bind to for the client server.'), | |||||
), | |||||
)); | |||||
} | |||||
public function execute(PhutilArgumentParser $args) { | |||||
$this->clientHost = $args->getArg('client-host'); | |||||
return 0; | |||||
} | |||||
final public function getPIDPath() { | final public function getPIDPath() { | ||||
return PhabricatorEnv::getEnvConfig('notification.pidfile'); | return PhabricatorEnv::getEnvConfig('notification.pidfile'); | ||||
} | } | ||||
final public function getPID() { | final public function getPID() { | ||||
$pid = null; | $pid = null; | ||||
if (Filesystem::pathExists($this->getPIDPath())) { | if (Filesystem::pathExists($this->getPIDPath())) { | ||||
$pid = (int)Filesystem::readFile($this->getPIDPath()); | $pid = (int)Filesystem::readFile($this->getPIDPath()); | ||||
} | } | ||||
return $pid; | return $pid; | ||||
} | } | ||||
final public function cleanup($signo = '?') { | final public function cleanup($signo = '?') { | ||||
global $g_future; | global $g_future; | ||||
if ($g_future) { | if ($g_future) { | ||||
$g_future->resolveKill(); | $g_future->resolveKill(); | ||||
$g_future = null; | $g_future = null; | ||||
} | } | ||||
Filesystem::remove($this->getPIDPath()); | Filesystem::remove($this->getPIDPath()); | ||||
exit(1); | exit(1); | ||||
} | } | ||||
protected final function setDebug($debug) { | |||||
$this->debug = $debug; | |||||
} | |||||
public static function requireExtensions() { | public static function requireExtensions() { | ||||
self::mustHaveExtension('pcntl'); | self::mustHaveExtension('pcntl'); | ||||
self::mustHaveExtension('posix'); | self::mustHaveExtension('posix'); | ||||
} | } | ||||
private static function mustHaveExtension($ext) { | private static function mustHaveExtension($ext) { | ||||
if (!extension_loaded($ext)) { | if (!extension_loaded($ext)) { | ||||
echo "ERROR: The PHP extension '{$ext}' is not installed. You must ". | echo "ERROR: The PHP extension '{$ext}' is not installed. You must ". | ||||
"install it to run aphlict on this machine.\n"; | "install it to run aphlict on this machine.\n"; | ||||
exit(1); | exit(1); | ||||
} | } | ||||
$extension = new ReflectionExtension($ext); | $extension = new ReflectionExtension($ext); | ||||
foreach ($extension->getFunctions() as $function) { | foreach ($extension->getFunctions() as $function) { | ||||
$function = $function->name; | $function = $function->name; | ||||
if (!function_exists($function)) { | if (!function_exists($function)) { | ||||
echo "ERROR: The PHP function {$function}() is disabled. You must ". | echo "ERROR: The PHP function {$function}() is disabled. You must ". | ||||
"enable it to run aphlict on this machine.\n"; | "enable it to run aphlict on this machine.\n"; | ||||
exit(1); | exit(1); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
final protected function willLaunch($debug = false) { | final protected function willLaunch() { | ||||
$console = PhutilConsole::getConsole(); | $console = PhutilConsole::getConsole(); | ||||
$pid = $this->getPID(); | $pid = $this->getPID(); | ||||
if ($pid) { | if ($pid) { | ||||
throw new PhutilArgumentUsageException( | throw new PhutilArgumentUsageException( | ||||
pht( | pht( | ||||
'Unable to start notifications server because it is already '. | 'Unable to start notifications server because it is already '. | ||||
'running. Use `aphlict restart` to restart it.')); | 'running. Use `aphlict restart` to restart it.')); | ||||
} | } | ||||
if (posix_getuid() == 0) { | if (posix_getuid() == 0) { | ||||
throw new PhutilArgumentUsageException( | throw new PhutilArgumentUsageException( | ||||
pht( | pht( | ||||
// TODO: Update this message after a while. | // TODO: Update this message after a while. | ||||
'The notification server should not be run as root. It no '. | 'The notification server should not be run as root. It no '. | ||||
'longer requires access to privileged ports.')); | 'longer requires access to privileged ports.')); | ||||
} | } | ||||
// Make sure we can write to the PID file. | // Make sure we can write to the PID file. | ||||
if (!$debug) { | if (!$this->debug) { | ||||
Filesystem::writeFile($this->getPIDPath(), ''); | Filesystem::writeFile($this->getPIDPath(), ''); | ||||
} | } | ||||
// First, start the server in configuration test mode with --test. This | // First, start the server in configuration test mode with --test. This | ||||
// will let us error explicitly if there are missing modules, before we | // will let us error explicitly if there are missing modules, before we | ||||
// fork and lose access to the console. | // fork and lose access to the console. | ||||
$test_argv = $this->getServerArgv($debug); | $test_argv = $this->getServerArgv(); | ||||
$test_argv[] = '--test=true'; | $test_argv[] = '--test=true'; | ||||
execx( | execx( | ||||
'%s %s %Ls', | '%s %s %Ls', | ||||
$this->getNodeBinary(), | $this->getNodeBinary(), | ||||
$this->getAphlictScriptPath(), | $this->getAphlictScriptPath(), | ||||
$test_argv); | $test_argv); | ||||
} | } | ||||
private function getServerArgv($debug) { | private function getServerArgv() { | ||||
$ssl_key = PhabricatorEnv::getEnvConfig('notification.ssl-key'); | $ssl_key = PhabricatorEnv::getEnvConfig('notification.ssl-key'); | ||||
$ssl_cert = PhabricatorEnv::getEnvConfig('notification.ssl-cert'); | $ssl_cert = PhabricatorEnv::getEnvConfig('notification.ssl-cert'); | ||||
$server_uri = PhabricatorEnv::getEnvConfig('notification.server-uri'); | $server_uri = PhabricatorEnv::getEnvConfig('notification.server-uri'); | ||||
$server_uri = new PhutilURI($server_uri); | $server_uri = new PhutilURI($server_uri); | ||||
$client_uri = PhabricatorEnv::getEnvConfig('notification.client-uri'); | $client_uri = PhabricatorEnv::getEnvConfig('notification.client-uri'); | ||||
$client_uri = new PhutilURI($client_uri); | $client_uri = new PhutilURI($client_uri); | ||||
$log = PhabricatorEnv::getEnvConfig('notification.log'); | $log = PhabricatorEnv::getEnvConfig('notification.log'); | ||||
$server_argv = array(); | $server_argv = array(); | ||||
$server_argv[] = '--port='.$client_uri->getPort(); | $server_argv[] = '--client-port='.$client_uri->getPort(); | ||||
$server_argv[] = '--admin='.$server_uri->getPort(); | $server_argv[] = '--admin-port='.$server_uri->getPort(); | ||||
$server_argv[] = '--host='.$server_uri->getDomain(); | $server_argv[] = '--admin-host='.$server_uri->getDomain(); | ||||
if ($ssl_key) { | if ($ssl_key) { | ||||
$server_argv[] = '--ssl-key='.$ssl_key; | $server_argv[] = '--ssl-key='.$ssl_key; | ||||
} | } | ||||
if ($ssl_cert) { | if ($ssl_cert) { | ||||
$server_argv[] = '--ssl-cert='.$ssl_cert; | $server_argv[] = '--ssl-cert='.$ssl_cert; | ||||
} | } | ||||
if (!$debug) { | if (!$this->debug) { | ||||
$server_argv[] = '--log='.$log; | $server_argv[] = '--log='.$log; | ||||
} | } | ||||
if ($this->clientHost) { | |||||
$server_argv[] = '--client-host='.$this->clientHost; | |||||
} | |||||
return $server_argv; | return $server_argv; | ||||
} | } | ||||
private function getAphlictScriptPath() { | private function getAphlictScriptPath() { | ||||
$root = dirname(phutil_get_library_root('phabricator')); | $root = dirname(phutil_get_library_root('phabricator')); | ||||
return $root.'/support/aphlict/server/aphlict_server.js'; | return $root.'/support/aphlict/server/aphlict_server.js'; | ||||
} | } | ||||
final protected function launch($debug = false) { | final protected function launch() { | ||||
$console = PhutilConsole::getConsole(); | $console = PhutilConsole::getConsole(); | ||||
if ($debug) { | if ($this->debug) { | ||||
$console->writeOut(pht("Starting Aphlict server in foreground...\n")); | $console->writeOut(pht("Starting Aphlict server in foreground...\n")); | ||||
} else { | } else { | ||||
Filesystem::writeFile($this->getPIDPath(), getmypid()); | Filesystem::writeFile($this->getPIDPath(), getmypid()); | ||||
} | } | ||||
$command = csprintf( | $command = csprintf( | ||||
'%s %s %Ls', | '%s %s %Ls', | ||||
$this->getNodeBinary(), | $this->getNodeBinary(), | ||||
$this->getAphlictScriptPath(), | $this->getAphlictScriptPath(), | ||||
$this->getServerArgv($debug)); | $this->getServerArgv()); | ||||
if (!$debug) { | if (!$this->debug) { | ||||
declare(ticks = 1); | declare(ticks = 1); | ||||
pcntl_signal(SIGINT, array($this, 'cleanup')); | pcntl_signal(SIGINT, array($this, 'cleanup')); | ||||
pcntl_signal(SIGTERM, array($this, 'cleanup')); | pcntl_signal(SIGTERM, array($this, 'cleanup')); | ||||
} | } | ||||
register_shutdown_function(array($this, 'cleanup')); | register_shutdown_function(array($this, 'cleanup')); | ||||
if ($debug) { | if ($this->debug) { | ||||
$console->writeOut("Launching server:\n\n $ ".$command."\n\n"); | $console->writeOut("Launching server:\n\n $ ".$command."\n\n"); | ||||
$err = phutil_passthru('%C', $command); | $err = phutil_passthru('%C', $command); | ||||
$console->writeOut(">>> Server exited!\n"); | $console->writeOut(">>> Server exited!\n"); | ||||
exit($err); | exit($err); | ||||
} else { | } else { | ||||
while (true) { | while (true) { | ||||
global $g_future; | global $g_future; | ||||
▲ Show 20 Lines • Show All 90 Lines • Show Last 20 Lines |