Linux
banshee/linux-collection/linux/ssh/
services
State of the services of a Linux by SSH, under systemd or OpenRC.
by banshee1 installation2 versions
// The state of the services of a Linux, by SSH, under systemd (Debian, Fedora) as under OpenRC (Alpine):
// the collector tries systemd, then OpenRC, and says in "Service manager" which one answered; if neither
// answers, it stops and says so. By default only the SSH server and cron are watched, under their names on
// the three systems; others are chosen on the probe.
// Runs systemctl list-units --type=service --all --no-legend --plain (systemd, on Debian and Fedora),
// otherwise rc-status -a (OpenRC, on Alpine); both only read. OpenRC states are given in systemd's words,
// so that one watch holds on all three: started becomes active, stopped inactive, crashed failed; the
// others stay as written.
need('protocol:ssh');
per('service', 'Services', array('only' => array('ssh', 'sshd', 'cron', 'crond')));
output('manager', 'text', array('label' => 'Service manager'));
output('state', 'text', array('label' => 'State', 'per' => 'service'));
watch.expect('stopped', 'Service stopped', 'state', array('critical' => array('active')));
watch.missing('missing', 'Service missing', 'state');
// The name of a service is the key: a service listed twice is given once.
$states = array();
$manager = 'systemd';
// systemd: one line per service, "nginx.service loaded active running A high performance web server",
// preceded by a "●" when it failed: the name, then the load state, then the active state.
$units = ssh.run('systemctl list-units --type=service --all --no-legend --plain');
if ($units['exit'] == 0) {
foreach (text.lines($units['output']) as $line) {
$m = text.match($line, '([^ ]+)\.service +[^ ]+ +([^ ]+)');
if (list.count($m) > 0) {
$states[$m[1]] = $m[2];
}
}
} else {
// OpenRC: lines "Runlevel: default", then one per service, "sshd [ started ]".
$rc = ssh.run('rc-status -a');
if ($rc['exit'] != 0) {
fail('misconfigured', 'Neither systemd nor OpenRC answers on this machine',
'systemctl: ' . text.trim($units['errors']) . '; rc-status: ' . text.trim($rc['errors']));
}
$manager = 'openrc';
$words = array('started' => 'active', 'stopped' => 'inactive', 'crashed' => 'failed');
foreach (text.lines($rc['output']) as $line) {
$m = text.match($line, '^([^ ]+) +\[ *([a-z]+)');
if (list.count($m) > 0) {
$states[$m[1]] = list.get($words, $m[2], $m[2]);
}
}
}
if (list.count($states) == 0) {
fail('misconfigured', 'No service found in the answer of ' . $manager);
}
value('manager', $manager);
foreach ($states as $name => $state) {
value('state', $state, $name);
}