Unleash your inner root

Replacing Cron with SystemD.timers

Like most people, Every year I make some new years resolutions. Unlike most people, my resolutions all tend to revolve around IT. Every year I give myself a “It’s , stop doing “. One year I decided to stop using the “ifconfig” command, in favor of finally learning the proper use of the “ip” command (and to a lesser extend nmcli). Last year it was “it’s 2017, stop using python 2, move on to python 3…Even if it’s not widely available and you still have to compile it from source on RHEL/CentOS systems…Like some kind of cave man”. Also on this list was “stop disabling SELinux”

So what was my “one thing” for 2018? Well, near the tail end of 2017 I made a discovery that I was completely unaware of before…SystemD has a built in timer system, that can act as a replacement for cron. Is it easier? No. Far from it. It’s kind of a pain in the ass…is it better? I think so.

You may ask, “Brandon, what IS better about systemd.timers? Why can’t i just keep using cron?” to that I say this:

First cron is dumb. We’ve all had that cron job that is supposed to run every X hours, and every now and again it will take more than X hours to run…and it ruins your life when cron kicks off a second copy of the job. Systemd tracks the PID of the process it starts when the timer is triggered, and it knows that the job is still running when the time rolls around again.

Second your job gets added in as an easily managable systemd journaled service. You can view the logs from the journal. You can enable/disable it with systemctl, and you can force run it with systemctl as well.

Third You can easily get details of all your jobs running on a system with systemctl. Here is an example output of “systemctl list-timers”

NEXT                         LEFT        LAST                         PASSED       UNIT                         ACTIVATES
Wed 2018-02-07 08:28:58 PST  23h left    Tue 2018-02-06 08:28:58 PST  17min ago    systemd-tmpfiles-clean.timer systemd-tmpfiles-clean.service
Mon 2018-02-12 00:00:00 PST  5 days left Mon 2018-02-05 00:00:00 PST  1 day 8h ago weekly-clamav.timer          weekly-clamav.service

As you can see, you can vie wa list of all the timers you have, when they last ran, when they will next run, and what they do.

So…How do you do it? well, as mentioned before…timers are less convenient than a simple cron entry, it requires two files to be created. We’ll use “weekly-clamav” as an example:

/etc/systemd/system/weekly-clamav.timer

[Unit]
Description=Perform ClamAV Scan

[Timer]
OnCalendar=weekly

[Install]
WantedBy=timers.target

the .timer file handles the scheduling. This is going to be the ongoing “service” that manages the job. as such this should be enabled, and started in systemd

systemctl start weekly-clamav.timer
systemctl enable weekly-clamav.timer

Next comes the .service file

/etc/systemd/system/weekly-clamav.service

[Unit]
Description=Perform ClamAV Scan

[Service]
Type=simple
Nice=19
IOSchedulingClass=2
IOSchedulingPriority=7
ExecStart=/etc/system-scripts/clam-scan.sh

this service, when started, will execute /etc/system-scripts/clam-scan.sh. This service should be disabled, and stopped:

systemctl disable weekly-clamav.service
systemctl stop weekly-clamav.service

You can start it manually to force run the job, and systemd will stop it when the job completes, otherwise the weekly-clamav.timer will start the service manually on a weekly basis.

And that is all there is to it.

cronlinuxsystemdsystemd.timerstimers

Brandon.Graves • February 6, 2018


Previous Post

Next Post

Leave a Reply

Your email address will not be published / Required fields are marked *

%d bloggers like this: