--- layout: post title: "Use systemd as a cron replacement" date: 2013-06-09 18:22 comments: true categories: - systemd - timer - linux - cron description: "HOWTO: Replace cron with systemd" --- Since systemd 197 timer units support calendar time events, which makes systemd a full cron replacement. Why one would replace the good old cron? Well, because systemd is good at executing stuff and monitor its state! * with the help of journalctl you get last status and logging output, which is a great thing to debug failing jobs: ``` $ systemctl status reflector-update.service reflector-update.service - "Update pacman's mirrorlist using reflector" Loaded: loaded (/etc/systemd/system/timer-weekly.target.wants/reflector-update.service) Active: inactive (dead) Jun 09 17:58:30 higgsboson reflector[30109]: rating http://www.gtlib.gatech.edu/pub/archlinux/ Jun 09 17:58:30 higgsboson reflector[30109]: rating rsync://rsync.gtlib.gatech.edu/archlinux/ Jun 09 17:58:30 higgsboson reflector[30109]: rating http://lug.mtu.edu/archlinux/ Jun 09 17:58:30 higgsboson reflector[30109]: Server Rate Time ... ``` * there are a lot of useful [systemd unit options](http://www.freedesktop.org/software/systemd/man/systemd.exec.html) like `IOSchedulingPriority`, `Nice` or `JobTimeoutSec` * it is possible to let depend units on other services, like mounting the nfs host before starting the mysql-backup.service or depending on the network.target. So let's get it started. The first thing you might want to do, is to replace the default scripts located in the [runparts](http://superuser.com/questions/402781/what-is-run-parts-in-etc-crontab-and-how-do-i-use-it) directories /etc/cron.{daily,hourly,monthly,weekly}. On my distribution (archlinux) these are logrotate, man-db, shadow and updatedb: For convenience I created a structure like /etc/cron.\*: mkdir /etc/systemd/system/timer-{hourly,daily,weekly}.target.wants and added the following timer. cd /etc/systemd/system wget https://blog.higgsboson.tk/downloads/timers.tar tar -xvf timers.tar && rm timers.tar {% include_code /etc/systemd/system/timer-hourly.timer lang:ini cron-replacement/timer-hourly.timer %} {% include_code /etc/systemd/system/timer-hourly.target lang:ini cron-replacement/timer-hourly.target %} {% include_code /etc/systemd/system/timer-daily.timer lang:ini cron-replacement/timer-daily.timer %} {% include_code /etc/systemd/system/timer-daily.target lang:ini cron-replacement/timer-daily.target %} {% include_code /etc/systemd/system/timer-weekly.timer lang:ini cron-replacement/timer-weekly.timer %} {% include_code /etc/systemd/system/timer-weekly.target lang:ini cron-replacement/timer-weekly.target %} ... and enable them: systemctl enable timer-hourly.timer systemctl enable timer-daily.timer systemctl enable timer-weekly.timer These directories work like their cron equivalents, each service file located in such a directory will be executed at the given time. Now move on to the service files. If you're not running Arch, the paths might be different on your system. cd /etc/systemd/system wget https://blog.higgsboson.tk/downloads/services.tar tar -xvf services.tar && rm services.tar {% include_code /etc/systemd/system/timer-daily.target.wants/logrotate.service lang:ini cron-replacement/logrotate.service %} {% include_code /etc/systemd/system/timer-daily.target.wants/man-db-update.service lang:ini cron-replacement/man-db-update.service %} {% include_code /etc/systemd/system/timer-daily.target.wants/mlocate-update.service lang:ini cron-replacement/mlocate-update.service %} {% include_code /etc/systemd/system/timer-daily.target.wants/verify-shadow.service lang:ini cron-replacement/verify-shadow.service %} At last but not least you can disable cron: systemctl stop cronie && systemctl disable cronie If you want to execute at a special calendar events for example "every first day in a month" use the ["OnCalendar=" option](http://www.freedesktop.org/software/systemd/man/systemd.time.html) in the timer file. example: ``` ini send-bill.timer [Unit] Description=Daily Timer [Timer] OnCalendar=*-*-1 0:0:O Unit=send-bill.target [Install] WantedBy=basic.target ``` That's all for the moment. Have a good time using the power of systemd! Below some service files, I use: {% include_code /etc/systemd/system/timer-weekly.target.wants/reflector-update.service lang:ini cron-replacement/reflector-update.service %} {% include_code /etc/systemd/system/timer-weekly.target.wants/pkgstats.service lang:ini cron-replacement/pkgstats.service %} [See this link](https://bbs.archlinux.org/viewtopic.php?id=162989) for details about my shell-based pacman notifier {% include_code /etc/systemd/system/timer-daily.target.wants/pacman-update.service lang:ini cron-replacement/pacman-update.service %}