Paketbau/SUSE-Paketkonventionen/Cron Jobs
aus openSUSE, der freien Wissensdatenbank
8. Cron Jobs
Der gewöhnliche Weg, Cron Jobs in /etc/crontab zu definieren, unterliegt einigen Beschränkungen:
- Jobs werden zu exakten Zeiten gestartet. Jobs die also beispielsweise um Mitternacht ausgeführt werden sollen, werden nie angegangen, wenn der Nutzer seinen Rechner jede Nacht ausschaltet.
- Pakete können ihre Jobs nicht einfach hinzufügen oder ihre Einstellungen nach einer Aktualisierung anpassen, da sich die Informationen in einer einzelnen Datei befinden.
Aus diesem Grund hat SUSE dem cron-Paket zwei Erweiterungen hinzugefügt:
- Es erlaubt, Cron Jobs auf regulären Grundlagen auszuführen (stündlich, täglich, wöchentlich und monatlich), auch dann, wenn der Computer für einige Zeit ausgeschaltet ist. Jedes Paket kann solche Jobs in einer separaten Datei definieren.
- Es erlaubt, genaue Ausführungszeiten für Jobs in separaten Dateien zu definieren.
Die folgenden zwei Abschnitte beschreiben diese Erweiterungen und erklären, wie man sie in einem Paket benutzt.
8.1. Regulär gestartete Jobs
Einige Pakete müssen regelmäßig Wartungsarbeiten durchführen, bspw. das Bereinigen alter Zwischenspeicherdateien oder Neubauten von Suchdatenbanken. Für diesen Zweck stellt openSUSE/SUSE Linux die folgenden Verzeichnisse bereit:
-
/etc/cron.hourly -
/etc/cron.daily -
/etc/cron.weekly -
/etc/cron.monthly
Wie in /etc/crontab angegeben, führt cron alle 15 Minuten das Skript /usr/lib/cron/run-crons aus. Es sucht in den Unterverzeichnissen /etc/cron.{hourly,daily,weekly,monthly} nach Skripten und prüft, welche davon ausgeführt werden sollen. Die Informationen über die letzten Ausführungen werden in Dateien unter /var/spool/cron/lastrun gespeichert. Dieser Aufbau sorgt dafür, dass Skripte auf einer regulären Grundlage ausgeführt werden, im Gegensatz zu einem statischen cron-Eintrag, der zu einer bestimmten Zeit ausgeführt werden muss. Feste Zeiten sind weiterhin möglich und werden weiter unten beschrieben.
Jedes Paket kann ein Skript in einem dieser Verzeichnisse ablegen. Das Skript ist im Paket in der Regel als Extraquelle enthalten. Es wird im %install-Abschnitt installiert und in der %files-Sektion aufgelistet.
Dieses Beispiel entstammt dem Paket man. Es werden dabei zwei cron-Skripte installiert, um diese einfach und übersichtlich zu halten:
Source2: cron.daily.do_mandb
Source3: cron.daily.clean_catman
[...]
%install
mkdir -p ${RPM_BUILD_ROOT}/etc/cron.daily
install -m 700 %{SOURCE2} ${RPM_BUILD_ROOT}\
/etc/cron.daily/do_mandb
install -m 700 %{SOURCE3} ${RPM_BUILD_ROOT}\
/etc/cron.daily/clean_catman
[...]
%files
[...]
/etc/cron.daily/clean_catman
/etc/cron.daily/do_mandb
In den cron-Skripten gibt es keine Begrenzungen. Sie sollten dennoch angemessene Prüfungen durchführen, bevor sie eine Aktion ausführen, da andernfalls das Mail-Konto des Administrators mit Fehlerbenachrichtigungen überflutet wird. Das Skript sollte beispielsweise prüfen, ob eine Binärdatei überhaupt existiert, bevor es diese ausführen will. Es sollte “0” auch dann als Rückgabewert liefern, wenn die Aktion fehlgeschlagen ist, es sei denn, es ist wirklich wichtig, Probleme zu melden.
Dieses Beispiel entstammt dem Paket wwwoffle:
#!/bin/sh
#
# purge the wwwoffle cache directory according to
# the parameters defined in /etc/wwwoffle/wwwoffle.conf
#
if [ -x /usr/bin/wwwoffle ] ; then
/sbin/checkproc /usr/sbin/wwwoffled && \
/usr/bin/wwwoffle -purge -c /etc/wwwoffle/wwwoffle.conf
exit 0
else
exit 0
fi
Beachten Sie das Beispiel für die Überprüfung. Die Aktion kann nur ausgeführt werden, wenn die Binärdatei existiert und der Dienst läuft.
Das folgende, komplexere Beispiel entstammt dem Paket man:
#!/bin/sh
#
# clean_catman. This script was split off cron.daily
# Please add your local changes to cron.daily.local
# since this file will be overwritten, when updating your system.
#
# Copyright (c) 1996-2002 SuSE GmbH Nuernberg, Germany.
#
# please send bugfixes or comments to feedback@suse.de.
#
# Authors:
# Burchard Steinbuild, feedback to http://www.suse.de/feedback
# Florian La Roche, feedback to http://www.suse.de/feedback
#
# paranoia settings
#
umask 022
PATH=/sbin:/bin:/usr/sbin:/usr/bin
export PATH
if [ -f /etc/sysconfig/cron ] ; then
. /etc/sysconfig/cron
fi
# Delete too old preformatted man-pages.
if test "$DELETE_OLD_CATMAN" = yes ; then
if test -z "$CATMAN_ATIME" ; then
# Default is 7 days
CATMAN_ATIME=7
fi
test -e /var/cache/man -a -x /usr/bin/safe-rm && \
find /var/cache/man -name '*.gz' -type f \
-atime +$CATMAN_ATIME -print0 | \
xargs --no-run-if-empty --max-lines=200 --null -- \
/usr/bin/safe-rm
fi
exit 0
Beachten Sie das Beispiel für die paranoia-Einstellung am Anfang. Dies ist sinnvoll, um die Verletzbarkeit des Skripts aus Sicherheitsgesichtspunkten zu verringern. Beachten Sie auch die richtige Nutzung von /etc/sysconfig. Der Nutzer muss das Skript nicht selber bearbeiten, sondern kann die Systemeinstellungen an einer zentralen Stelle einrichten.
8.2. Zu exakter Zeit gestartete Jobs
Einige Pakete benötigen eine feinere Kontrolle über ihren Ablauf als stündlich, täglich, wöchentlich und monatlich. Für diesen Zweck bringt openSUSE/SUSE Linux das Verzeichnis /etc/cron.d mit.
Dieses Verzeichnis ist nicht für Skripte gedacht, sondern für Konfigurationsdateien, die das gleiche Format wie /etc/crontab haben. Lesen Sie die Handbuchseite (man page) crontab(5) für weitere Informationen. Cron behandelt Dateien Dateien in diesem Verzeichnis genauso wie /etc/crontab. Das Verzeichnis wird auf Veränderungen überwacht und Jobs werden so ausgeführt, wie sie konfiguriert sind. Der Vorteil ist, dass jedes Paket seine Konfiguration in einer eigenen Datei ablegen kann.
Jedes Paket kann in diesem Verzeichnis eine Konfigurationsdatei ablegen. Der Name der Konfigurationsdatei sollte den gleichen Namen wie das Paket tragen und darf nur aus Klein- und Großbuchstaben, Ziffern, Unterstrichen und Bindestrichen bestehen.
Die Konfigurationsdatei kann im Paket als Extraquelle enthalten sein. Dann wird es im %install-Abschnitt installiert und in der %files-Sektion aufgeführt. Es ist sinnvoll, die Datei als %config zu markieren, da der Nutzer eventuell die Zeitsteuerung ändern möchte. Dieses Beispiel entstammt dem Paket awstats:
Source4: cron.d.awstats
[...]
%install
[...]
install -d -m 755 $RPM_BUILD_ROOT/etc/cron.d
install -m 700 %{SOURCE4} $RPM_BUILD_ROOT/etc/cron.d/awstats
[...]
%files
[...]
%config /etc/cron.d/awstats
Die Konfigurationsdatei /etc/cron.d/awstats sieht wie folgt aus:
#update reports every 6 hour 0 */6 * * * root /usr/sbin/awstats-update
Eine sehr interessante Lösung wird im Paket mailman genutzt. Dort ist die cron-Konfigurationsdatei bereits in den Originalquellen enthalten und wird durch make install installiert. Der Unterschied besteht darin, dass die Konfiguration nicht standardmäßig genutzt wird. Sie wird als /usr/lib/mailman/cron/crontab installiert und nach /etc/init.d kopiert, sobald der Dienst gestartet wird, und von dort wieder entfernt, wenn er gestoppt wird. Dieser Ansatz wurde gewählt, weil die Cron Jobs hier Teil der vom Dienst bereitgestellten Funktionen sind und nicht benötigt werden, wenn der Dienst gestoppt ist.
Dies ist der zugehörige Teil des Init-Skripts /etc/init.d/mailman:
ETC_CT=/etc/cron.d/mailman
MM_CT=/usr/lib/mailman/cron/crontab
MM_CTRL=/usr/lib/mailman/bin/mailmanctl
MM_PID=/var/lib/mailman/data/master-qrunner.pid
[...]
case "$1" in
start)
echo -n "Starting mailman"
if ! /sbin/checkproc -k -p $MM_PID /usr/bin/python; then
install -m 0644 $MM_CT $ETC_CT
$MM_CTRL --quiet --stale-lock-cleanup start
else
rc_reset
fi
rc_status -v
;;
stop)
echo -n "Shutting down mailman"
rm -f $ETC_CT
/sbin/killproc -p $MM_PID -TERM /usr/bin/python
rc_status -v
;;
Dies sind einige Teile der Konfigurationsdatei, die nach /etc/cron.d kopiert wird:
# # if you want to make changes to this file, please modify # /usr/lib/mailman/cron/crontab and restart mailman # # At 8AM every day, mail reminders to admins as to pending # requests. They are less likely to ignore these reminders if # they're mailed early in the morning, but of course, this is # local time... ;) 0 8 * * * mailman /usr/bin/python -S /usr/lib/mailman/cron/checkdbs # # At 9AM, send notifications to disabled members that are due # to be reminded to re-enable their accounts. 0 9 * * * mailman /usr/bin/python -S /usr/lib/mailman/cron/disabled [...] # At 3:27am every night, regenerate the gzip'd archive file. Only # turn this on if the internal archiver is used and # GZIP_ARCHIVE_TXT_FILES is false in mm_cfg.py 27 3 * * * mailman /usr/bin/python -S /usr/lib/mailman/cron/nightly_gzip [...]

