Systemd Cronjob: Der Ersatz von Timer & Services

von | Aug 10, 2016 | IT-Infrastruktur |

Der Systemstart wird bei etlichen Linux-Distributionen mittlerweile von Systemd statt Sysvinit abgewickelt. Das neue Init-System beschleunigt den Bootprozess und erleichtert die Konfiguration des Systems. Systemd übernimmt nun auch das Cron Management. Dabei werden bestehende Cronjobs automatisch entsprechend der bisherigen Cron-Struktur mit einem Wrapper-Script nun mittels Systemd ausgeführt..

Der systemd-crontab-generator wandelt Cronjobs aus /etc/crontab, den /etc/cron.d, /var/spool/cron/crontabs, /etc/anacrontab Verzeichnissen in Systemd Units um. Dabei wird eine Serviceunit, sowie eine entsprechendes Timerunit angelegt. Diese Vorgänge passieren automatisch beim Systemstart sowie bei Änderungen der Dateien.

Systemd Probleme beim Ausführen von Cronjobs

Leider funktioniert das nicht immer, z.B. bei folgendem Cronjob:

*/6 08-17 * * 1-5 root /opt/rt4/iphos/slahours.sh && /opt/rt4/iphos/sla1.sh

Das hat (zumindest derzeit) zwei Gründe:

1. Das Wrapper-Script kann nicht mit Intervallen umgehen (ValueError: invalid literal for int() with base 10: ’08-22′).

root@rt:~# /lib/systemd/system-generators/systemd-crontab-generator --help
Traceback (most recent call last):
  File "/lib/systemd/system-generators/systemd-crontab-generator", line 259, in <module>
    for job in parse_crontab(filename, withuser=True):
  File "/lib/systemd/system-generators/systemd-crontab-generator", line 126, in parse_crontab
    'h': parse_time_unit(hours, HOURS_SET),
  File "/lib/systemd/system-generators/systemd-crontab-generator", line 138, in parse_time_unit
    map(parse_period(mapping), value.split(','))), set())))
  File "/lib/systemd/system-generators/systemd-crontab-generator", line 157, in parser
    value = mapping(value)
ValueError: invalid literal for int() with base 10: '08-22'

2. Systemd kann nicht mit Intervallen bei Uhrzeitangaben umgehen.

Stand:

ii  libpam-systemd:amd64      215-17+deb8u4   amd64   system and service manager - PAM module
rc  libsystemd-login0:amd64   215-17+deb8u4   amd64   systemd login utility library (deprecated)
ii  libsystemd0:amd64         215-17+deb8u4   amd64   systemd utility library
ii  systemd                   215-17+deb8u4   amd64   system and service manager
ii  systemd-cron              1.3.1+ds1-2     all     systemd units to provide minimal cron daemon functionality
ii  systemd-sysv              215-17+deb8u4   amd64   system and service manager - SysV links

Das Anlegen von Timern und Services

Zuerst muss eine Service-Unit anlegt werden, wie z.B.:

root@rt:/etc/systemd/system# cat cron-rt.service
[Unit]
Description=Service for RT
Wants=cron-rt.timer

[Service]
#User=%I
Type=simple
ExecStart=/opt/rt4/iphos/sla.sh

[Install]
WantedBy=basic.target

Anschließend wird eine entsprechende Timer-Unit konfiguriert.

Achtung: Die „OnCalendar“-Syntax unterscheidet sich von bisherigen Crontabs. So ist es z.B. bei Zeitangabe nicht möglich, mit Intervallen zu arbeiten, bei Wochentagen und Datumsangaben hingegen schon

Mon-Fri -*- 8,9,10,11,12,13,14,15,16,17:0/10 => Der Job läuft zw. Montag und Freitag, 8:00 – 17:50 alle 10 Minuten. Wochentage, Montagsangabe yyyy-mm-dd, Zeitangabe hh-mm-ss finden Sie genauer hier beschrieben:
https://www.freedesktop.org/software/systemd/man/systemd.time.html

root@rt:/etc/systemd/system# cat cron-rt.timer
[Unit]
Description=RT Job

[Timer]
OnCalendar=Mon-Fri *-*-* 8,9,10,11,12,13,14,15,16,17:0/10:00
Persistent=true
Unit=cron-rt.service

[Install]
WantedBy=basic.target
Die neuen Units werden nun mit folgendem Befehl geladen:
root@rt:/etc/systemd/system# systemctl daemon-reload

Anschließend wird der Timer aktiviert und gestartet:

root@rt:/etc/systemd/system# systemctl enable cron-rt.timer
root@rt:/etc/systemd/system# systemctl start cron-rt.timer

Anzeigen lassen kann man sich diese dann mit folgenden Befehlen:

root@rt:/etc/systemd/system# systemctl list-timers --all
NEXT                          LEFT             LAST                          PASSED       UNIT                         ACTIVATES
Wed 2016-07-06 12:20:00 CEST  5min left        Wed 2016-07-06 12:10:04 CEST  4min 16s ago cron-rt.timer                cron-rt.service
Wed 2016-07-06 13:00:00 CEST  45min left       n/a                           n/a          cron-hourly.timer            cron-hourly.target
Wed 2016-07-06 13:00:00 CEST  45min left       n/a                           n/a          cron-root-2.timer            cron-root-2.service
Wed 2016-07-06 20:16:14 CEST  8h left          Tue 2016-07-05 20:16:14 CEST  15h ago      systemd-tmpfiles-clean.timer systemd-tmpfiles-clean.service
Thu 2016-07-07 00:00:00 CEST  11h left         Wed 2016-07-06 00:00:14 CEST  12h ago      cron-daily.timer             cron-daily.target
Thu 2016-07-07 00:00:00 CEST  11h left         Wed 2016-07-06 00:00:14 CEST  12h ago      cron-root-0.timer            cron-root-0.service
Thu 2016-07-07 00:00:00 CEST  11h left         Wed 2016-07-06 00:00:14 CEST  12h ago      cron-root-3.timer            cron-root-3.service
Sun 2016-07-10 00:00:00 CEST  3 days left      Tue 2016-07-05 19:40:45 CEST  16h ago      cron-root-1.timer            cron-root-1.service
Mon 2016-07-11 00:00:00 CEST  4 days left      Tue 2016-07-05 19:40:45 CEST  16h ago      cron-weekly.timer            cron-weekly.target
Mon 2016-08-01 00:00:00 CEST  3 weeks 4 days left Tue 2016-07-05 19:40:45 CEST  16h ago   cron-monthly.timer           cron-monthly.target
n/a                           n/a              n/a                           n/a       systemd-readahead-done.timer systemd-readahead-done.service

11 timers listed.
root@rt:/etc/systemd/system# systemctl status cron-rt.timer
&#9679; cron-rt.timer - RT Job
   Loaded: loaded (/etc/systemd/system/cron-rt.timer; enabled)
   Active: active (waiting) since Wed 2016-07-06 12:18:56 CEST; 5s ago