diff --git a/bundles/systemd-timers/files/check_systemd_timer b/bundles/systemd-timers/files/check_systemd_timer new file mode 100644 index 0000000..7aa53d8 --- /dev/null +++ b/bundles/systemd-timers/files/check_systemd_timer @@ -0,0 +1,24 @@ +#!/bin/sh + +if [[ -z "$1" ]] +then + echo "Usage: $0 " + exit 3 +fi + +if ! [[ -f "/var/lib/systemd-timer-monitored/$1" ]] +then + echo "No status file found" + exit 3 +fi + +exitcode="$(cat "/var/lib/systemd-timer-monitored/$1")" + +echo "Last timer run exited $exitcode" + +if [[ $exitcode -ne 0 ]] +then + exit 2 +else + exit 0 +fi diff --git a/bundles/systemd-timers/files/systemd-timer-monitored b/bundles/systemd-timers/files/systemd-timer-monitored new file mode 100644 index 0000000..8af40f8 --- /dev/null +++ b/bundles/systemd-timers/files/systemd-timer-monitored @@ -0,0 +1,10 @@ +#!/bin/sh + +timer="$1" +shift + +# Simple wrapper script that stores the exit code of a command into a file +"$@" +exitcode=$? + +echo "$exitcode" > "/var/lib/systemd-timer-monitored/$timer" diff --git a/bundles/systemd-timers/files/template.service b/bundles/systemd-timers/files/template.service new file mode 100644 index 0000000..7465f8f --- /dev/null +++ b/bundles/systemd-timers/files/template.service @@ -0,0 +1,15 @@ +[Unit] +Description=Service for Timer ${timer} +After=network.target +% if config.get('requires', ''): +Requires=${config['requires']} +% endif + +[Service] +User=${config.get('user', 'root')} +Group=${config.get('group', config.get('user', 'root'))} +% for k, v in sorted(config.get('environment', {}).items()): +Environment=${k}=${v} +% endfor +WorkingDirectory=${config.get('pwd', '/')} +ExecStart=/usr/local/sbin/systemd-timer-monitored ${timer} ${config['command']} diff --git a/bundles/systemd-timers/files/template.timer b/bundles/systemd-timers/files/template.timer new file mode 100644 index 0000000..e9aed30 --- /dev/null +++ b/bundles/systemd-timers/files/template.timer @@ -0,0 +1,13 @@ +[Unit] +Description=Timer for Service ${timer} + +[Timer] +OnCalendar=${config['when']} +% if config.get('persistent', True): +Persistent=true +% else: +Persistent=false +% endif + +[Install] +WantedBy=timers.target diff --git a/bundles/systemd-timers/items.py b/bundles/systemd-timers/items.py new file mode 100644 index 0000000..cbf4172 --- /dev/null +++ b/bundles/systemd-timers/items.py @@ -0,0 +1,61 @@ +directories = { + '/usr/local/lib/systemd/system': { + 'purge': True, + 'triggers': { + 'action:systemd-reload', + }, + }, + '/var/lib/systemd-timer-monitored': { + 'mode': '0777', + }, +} + +files = { + '/usr/local/sbin/systemd-timer-monitored': { + 'mode': '0755', + }, + '/usr/local/share/icinga/plugins/check_systemd_timer': { + 'mode': '0755', + }, +} + +for timer, config in node.metadata.get('systemd-timers/timers', {}).items(): + if config.get('delete', False): + action[f'systemd-timer_stop_timer_{timer}'] = { + # can't use svc_systemd: here, because that depends on + # action:systemd-reload + 'command': f'systemctl disable --now {timer}.timer', + 'precedes': { + # stop, then delete unit files + 'directory:/usr/local/lib/systemd/system', + }, + } + else: + files[f'/usr/local/lib/systemd/system/{timer}.timer'] = { + 'source': 'template.timer', + 'content_type': 'mako', + 'context': { + 'timer': timer, + 'config': config, + }, + 'triggers': { + 'action:systemd-reload', + }, + } + files[f'/usr/local/lib/systemd/system/{timer}.service'] = { + 'source': 'template.service', + 'content_type': 'mako', + 'context': { + 'timer': timer, + 'config': config, + }, + 'triggers': { + 'action:systemd-reload', + }, + } + svc_systemd[f'{timer}.timer'] = { + 'needs': { + f'file:/usr/local/lib/systemd/system/{timer}.service', + f'file:/usr/local/lib/systemd/system/{timer}.timer', + }, + } diff --git a/bundles/systemd-timers/metadata.py b/bundles/systemd-timers/metadata.py new file mode 100644 index 0000000..23f87ff --- /dev/null +++ b/bundles/systemd-timers/metadata.py @@ -0,0 +1,21 @@ +@metadata_reactor.provides( + 'icinga2_api/systemd-timers/services', +) +def monitoring(metadata): + services = {} + + for timer, config in node.metadata.get('systemd-timers/timers', {}).items(): + if config.get('delete', False): + continue + + services[f'SYSTEMD-TIMER {timer}'] = { + 'command_on_monitored_host': f'/usr/local/share/icinga/plugins/check_systemd_timer {timer}', + } + + return { + 'icinga2_api': { + 'systemd-timers': { + 'services': services, + }, + }, + } diff --git a/groups/os.py b/groups/os.py index f484055..4fa97f7 100644 --- a/groups/os.py +++ b/groups/os.py @@ -28,6 +28,7 @@ groups['linux'] = { 'sysctl', 'systemd', 'systemd-networkd', + 'systemd-timers', 'telegraf', 'users', },