Differential D15701 Diff 37844 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 $debug = false; | ||||
private $clientHost; | private $configPath; | ||||
private $clientPort; | |||||
final protected function setDebug($debug) { | final protected function setDebug($debug) { | ||||
$this->debug = $debug; | $this->debug = $debug; | ||||
return $this; | return $this; | ||||
} | } | ||||
protected function getLaunchArguments() { | protected function getLaunchArguments() { | ||||
return array( | return array( | ||||
array( | array( | ||||
'name' => 'client-host', | 'name' => 'config', | ||||
'param' => 'hostname', | 'param' => 'file', | ||||
'help' => pht('Hostname to bind to for the client server.'), | 'help' => pht( | ||||
), | 'Use a specific configuration file instead of the default '. | ||||
array( | 'configuration.'), | ||||
'name' => 'client-port', | |||||
'param' => 'port', | |||||
'help' => pht('Port to bind to for the client server.'), | |||||
), | ), | ||||
); | ); | ||||
} | } | ||||
protected function parseLaunchArguments(PhutilArgumentParser $args) { | protected function parseLaunchArguments(PhutilArgumentParser $args) { | ||||
$this->clientHost = $args->getArg('client-host'); | $config_file = $args->getArg('config'); | ||||
$this->clientPort = $args->getArg('client-port'); | if ($config_file) { | ||||
$full_path = Filesystem::resolvePath($config_file); | |||||
$show_path = $full_path; | |||||
} else { | |||||
$root = dirname(dirname(phutil_get_library_root('phabricator'))); | |||||
$try = array( | |||||
'phabricator/conf/aphlict/aphlict.custom.json', | |||||
'phabricator/conf/aphlict/aphlict.default.json', | |||||
); | |||||
foreach ($try as $config) { | |||||
$full_path = $root.'/'.$config; | |||||
$show_path = $config; | |||||
if (Filesystem::pathExists($full_path)) { | |||||
break; | |||||
} | |||||
} | |||||
} | |||||
echo tsprintf( | |||||
"%s\n", | |||||
pht( | |||||
'Reading configuration from: %s', | |||||
$show_path)); | |||||
try { | |||||
$data = Filesystem::readFile($full_path); | |||||
} catch (Exception $ex) { | |||||
throw new PhutilArgumentUsageException( | |||||
pht( | |||||
'Failed to read configuration file. %s', | |||||
$ex->getMessage())); | |||||
} | |||||
try { | |||||
$data = phutil_json_decode($data); | |||||
} catch (Exception $ex) { | |||||
throw new PhutilArgumentUsageException( | |||||
pht( | |||||
'Configuration file is not properly formatted JSON. %s', | |||||
$ex->getMessage())); | |||||
} | |||||
try { | |||||
PhutilTypeSpec::checkMap( | |||||
$data, | |||||
array( | |||||
'servers' => 'list<wild>', | |||||
)); | |||||
} catch (Exception $ex) { | |||||
throw new PhutilArgumentUsageException( | |||||
pht( | |||||
'Configuration file has improper configuration keys at top '. | |||||
'level. %s', | |||||
$ex->getMessage())); | |||||
} | |||||
$servers = $data['servers']; | |||||
$has_client = false; | |||||
$has_admin = false; | |||||
$port_map = array(); | |||||
foreach ($servers as $index => $server) { | |||||
PhutilTypeSpec::checkMap( | |||||
$server, | |||||
array( | |||||
'type' => 'string', | |||||
'port' => 'int', | |||||
'listen' => 'optional string|null', | |||||
'ssl.key' => 'optional string|null', | |||||
'ssl.cert' => 'optional string|null', | |||||
)); | |||||
$port = $server['port']; | |||||
if (!isset($port_map[$port])) { | |||||
$port_map[$port] = $index; | |||||
} else { | |||||
throw new PhutilArgumentUsageException( | |||||
pht( | |||||
'Two servers (at indexes "%s" and "%s") both bind to the same '. | |||||
'port ("%s"). Each server must bind to a unique port.', | |||||
$port_map[$port], | |||||
$index, | |||||
$port)); | |||||
} | |||||
$type = $server['type']; | |||||
switch ($type) { | |||||
case 'admin': | |||||
$has_admin = true; | |||||
break; | |||||
case 'client': | |||||
$has_client = true; | |||||
break; | |||||
default: | |||||
throw new PhutilArgumentUsageException( | |||||
pht( | |||||
'A specified server (at index "%s", on port "%s") has an '. | |||||
'invalid type ("%s"). Valid types are: admin, client.', | |||||
$index, | |||||
$port, | |||||
$type)); | |||||
} | |||||
$ssl_key = idx($server, 'ssl.key'); | |||||
$ssl_cert = idx($server, 'ssl.cert'); | |||||
if (($ssl_key && !$ssl_cert) || ($ssl_cert && !$ssl_key)) { | |||||
throw new PhutilArgumentUsageException( | |||||
pht( | |||||
'A specified server (at index "%s", on port "%s") specifies '. | |||||
'only one of "%s" and "%s". Each server must specify neither '. | |||||
'(to disable SSL) or specify both (to enable it).', | |||||
$index, | |||||
$port, | |||||
'ssl.key', | |||||
'ssl.cert')); | |||||
} | |||||
} | |||||
if (!$servers) { | |||||
throw new PhutilArgumentUsageException( | |||||
pht( | |||||
'Configuration file does not specify any servers. This service '. | |||||
'will not be able to interact with the outside world if it does '. | |||||
'not listen on any ports. You must specify at least one "%s" '. | |||||
'server and at least one "%s" server.', | |||||
'admin', | |||||
'client')); | |||||
} | |||||
if (!$has_client) { | |||||
throw new PhutilArgumentUsageException( | |||||
pht( | |||||
'Configuration file does not specify any client servers. This '. | |||||
'service will be unable to transmit any notifications without a '. | |||||
'client server. You must specify at least one server with '. | |||||
'type "%s".', | |||||
'client')); | |||||
} | |||||
if (!$has_admin) { | |||||
throw new PhutilArgumentUsageException( | |||||
pht( | |||||
'Configuration file does not specify any administrative '. | |||||
'servers. This service will be unable to receive messages. '. | |||||
'You must specify at least one server with type "%s".', | |||||
'admin')); | |||||
} | |||||
$this->configPath = $full_path; | |||||
} | } | ||||
final public function getPIDPath() { | final public function getPIDPath() { | ||||
$path = PhabricatorEnv::getEnvConfig('notification.pidfile'); | $path = PhabricatorEnv::getEnvConfig('notification.pidfile'); | ||||
try { | try { | ||||
$dir = dirname($path); | $dir = dirname($path); | ||||
if (!Filesystem::pathExists($dir)) { | if (!Filesystem::pathExists($dir)) { | ||||
▲ Show 20 Lines • Show All 102 Lines • ▼ Show 20 Lines | final protected function willLaunch() { | ||||
$test_argv = $this->getServerArgv(); | $test_argv = $this->getServerArgv(); | ||||
$test_argv[] = '--test=true'; | $test_argv[] = '--test=true'; | ||||
execx('%C', $this->getStartCommand($test_argv)); | execx('%C', $this->getStartCommand($test_argv)); | ||||
} | } | ||||
private function getServerArgv() { | private function getServerArgv() { | ||||
$ssl_key = PhabricatorEnv::getEnvConfig('notification.ssl-key'); | |||||
$ssl_cert = PhabricatorEnv::getEnvConfig('notification.ssl-cert'); | |||||
$server_uri = PhabricatorEnv::getEnvConfig('notification.server-uri'); | |||||
$server_uri = new PhutilURI($server_uri); | |||||
$client_uri = PhabricatorEnv::getEnvConfig('notification.client-uri'); | |||||
$client_uri = new PhutilURI($client_uri); | |||||
$log = $this->getLogPath(); | $log = $this->getLogPath(); | ||||
$server_argv = array(); | $server_argv = array(); | ||||
$server_argv[] = '--client-port='.coalesce( | $server_argv[] = '--config='.$this->configPath; | ||||
$this->clientPort, | |||||
$client_uri->getPort()); | |||||
$server_argv[] = '--admin-port='.$server_uri->getPort(); | |||||
$server_argv[] = '--admin-host='.$server_uri->getDomain(); | |||||
if ($ssl_key) { | |||||
$server_argv[] = '--ssl-key='.$ssl_key; | |||||
} | |||||
if ($ssl_cert) { | |||||
$server_argv[] = '--ssl-cert='.$ssl_cert; | |||||
} | |||||
$server_argv[] = '--log='.$log; | $server_argv[] = '--log='.$log; | ||||
if ($this->clientHost) { | |||||
$server_argv[] = '--client-host='.$this->clientHost; | |||||
} | |||||
return $server_argv; | return $server_argv; | ||||
} | } | ||||
final protected function launch() { | final protected function launch() { | ||||
$console = PhutilConsole::getConsole(); | $console = PhutilConsole::getConsole(); | ||||
if ($this->debug) { | if ($this->debug) { | ||||
$console->writeOut( | $console->writeOut( | ||||
▲ Show 20 Lines • Show All 135 Lines • Show Last 20 Lines |