system: fix service control bugs, dedup and oddities plus new #6376

service_name() and service_message() make this more usable.  Also
add a status command for -s mode that emulates rc system output.
This commit is contained in:
Franco Fichtner 2023-03-15 08:49:04 +01:00
parent 0fc88f2d3d
commit 179c6e4f37
2 changed files with 86 additions and 36 deletions

View File

@ -100,7 +100,7 @@ function is_process_running($process)
return (intval($retval) == 0);
}
function service_by_name($name, $filter = array())
function service_by_name($name, $filter = [])
{
$services = plugins_services();
@ -119,7 +119,7 @@ function service_by_name($name, $filter = array())
}
}
return array();
return [];
}
function service_status($service)
@ -135,17 +135,75 @@ function service_status($service)
return is_process_running($service['name']);
}
function service_control_start($name, $extras)
function service_message($service)
{
$filter = array();
/*
* Emulate the following messages from rc system:
*
* syslog_ng is running as pid 11645.
* syslog_ng is not running.
*/
if (!empty($extras['id'])) {
$pid = '';
$status = false;
if (!empty($service['nocheck'])) {
/* do not expose pid / may not exist */
$status = true;
} elseif (isset($service['pidfile'])) {
$status = isvalidpid($service['pidfile']);
if ($status) {
/* could be wrong pid but best effort only */
$pid = ' as pid ' . trim(@file_get_contents($service['pidfile']) ?? '');
}
} else {
$status = is_process_running($service['name']);
if ($status) {
/* could be wrong pid but best effort only */
$pid = ' as pid ' . shell_safe('/bin/pgrep -anx %s', $service['name']);
}
}
return sprintf('%s is %s.', service_name($service), $status ? 'running' . $pid : 'not running');
}
function service_name($service)
{
return $service['name'] . (array_key_exists('id', $service) ? "[{$service['id']}]" : '');
}
function service_control_get($name, $extras)
{
$filter = [];
if (array_key_exists('id', $extras) && $extras['id'] !== '') {
$filter['id'] = $extras['id'];
}
$service = service_by_name($name, $filter);
if (!isset($service['name'])) {
return sprintf(gettext("Could not start unknown service `%s'"), htmlspecialchars($name));
if (empty($service)) {
$name .= isset($filter['id']) ? "[{$filter['id']}]" : '';
return sprintf(gettext("Could not find unknown service `%s'"), htmlspecialchars($name));
}
return $service;
}
function service_control_status($name, $extras)
{
$service = service_control_get($name, $extras);
if (!is_array($service)) {
return $service;
}
return htmlspecialchars(service_message($service));
}
function service_control_start($name, $extras)
{
$service = service_control_get($name, $extras);
if (!is_array($service)) {
return $service;
}
if (isset($service['configd']['start'])) {
@ -154,7 +212,7 @@ function service_control_start($name, $extras)
}
} elseif (isset($service['php']['start'])) {
foreach ($service['php']['start'] as $cmd) {
$params = array();
$params = [];
if (isset($service['php']['args'])) {
foreach ($service['php']['args'] as $param) {
$params[] = $service[$param];
@ -167,23 +225,17 @@ function service_control_start($name, $extras)
mwexec($cmd);
}
} else {
return sprintf(gettext("Could not start service `%s'"), htmlspecialchars($name));
return sprintf(gettext("Could not start service `%s'"), htmlspecialchars(service_name($service)));
}
return sprintf(gettext("Service `%s' has been started."), htmlspecialchars($name));
return sprintf(gettext("Service `%s' has been started."), htmlspecialchars(service_name($service)));
}
function service_control_stop($name, $extras)
{
$filter = array();
if (!empty($extras['id'])) {
$filter['id'] = $extras['id'];
}
$service = service_by_name($name, $filter);
if (!isset($service['name'])) {
return sprintf(gettext("Could not stop unknown service `%s'"), htmlspecialchars($name));
$service = service_control_get($name, $extras);
if (!is_array($service)) {
return $service;
}
if (isset($service['configd']['stop'])) {
@ -205,20 +257,14 @@ function service_control_stop($name, $extras)
killbyname($service['name']);
}
return sprintf(gettext("Service `%s' has been stopped."), htmlspecialchars($name));
return sprintf(gettext("Service `%s' has been stopped."), htmlspecialchars(service_name($service)));
}
function service_control_restart($name, $extras)
{
$filter = array();
if (!empty($extras['id'])) {
$filter['id'] = $extras['id'];
}
$service = service_by_name($name, $filter);
if (!isset($service['name'])) {
return sprintf(gettext("Could not restart unknown service `%s'"), htmlspecialchars($name));
$service = service_control_get($name, $extras);
if (!is_array($service)) {
return $service;
}
if (isset($service['configd']['restart'])) {
@ -227,7 +273,7 @@ function service_control_restart($name, $extras)
}
} elseif (isset($service['php']['restart'])) {
foreach ($service['php']['restart'] as $cmd) {
$params = array();
$params = [];
if (isset($service['php']['args'])) {
foreach ($service['php']['args'] as $param) {
$params[] = $service[$param];
@ -240,10 +286,10 @@ function service_control_restart($name, $extras)
mwexec($cmd);
}
} else {
return sprintf(gettext("Could not restart service `%s'"), htmlspecialchars($name));
return sprintf(gettext("Could not restart service `%s'"), htmlspecialchars(service_name($service)));
}
return sprintf(gettext("Service `%s' has been restarted."), htmlspecialchars($name));
return sprintf(gettext("Service `%s' has been restarted."), htmlspecialchars(service_name($service)));
}
function is_subsystem_dirty($subsystem = '')

View File

@ -74,7 +74,7 @@ if (isset($opts['h'])) {
echo "\t-h show this help text and exit\n";
echo "\t-i invoke dynamic interface registration\n";
echo "\t-r run mode (e.g. command)\n";
echo "\t-S service dump\n";
echo "\t-S service metadata dump\n";
echo "\t-s service mode (e.g. myservice restart)\n\n";
echo "Without arguments, a list of plugins of the requested type is shown.\n";
} elseif (isset($opts['d'])) {
@ -111,8 +111,9 @@ if (isset($opts['h'])) {
if (isset($args[1]) && $args[1] !== '' && (!array_key_exists('id', $service) || $service['id'] != $args[1])) {
continue;
}
/* fetch status so the caller does not have to */
$service['status'] = service_status($service);
/* fetch status so the caller does not have to (one for legacy, one for mvc) */
$service['status_msg'] = service_message($service);
$service['status'] = strpos($service['status_msg'], 'is running') !== false;
/* collect all matches contrary to what service_by_name() is doing */
$services[] = $service;
}
@ -121,7 +122,7 @@ if (isset($opts['h'])) {
$name = !empty($args[0]) ? $args[0] : '';
$act = !empty($args[1]) ? $args[1] : '';
$filter = [];
if (!empty($args[2])) {
if (isset($args[2]) && $args !== '') {
$filter['id'] = $args[2];
}
switch ($act) {
@ -134,6 +135,9 @@ if (isset($opts['h'])) {
case 'restart':
echo service_control_restart($name, $filter) . PHP_EOL;
break;
case 'status':
echo service_control_status($name, $filter) . PHP_EOL;
break;
default:
echo "Unknown command `$act'\n";
break;