Intro
I thought I'd share some useful scripts for systemd that replace a cron daemon, and that I use on many of my Gentoo machines. Since moving away from openrc, I had to relearn a bit, especially the daily cron jobs that I was so used to. But I will trade crontab -e for journalctl functionality any day-- so useful. Anyways, I no longer have any crons installed. What to do? I have 1 Gentoo headless file server that needs to run all of these services, 1 desktop (the "bulldozer") and a couple laptops that need to run a subset of these services.
1. Eix-sync Service and Timer
I have the excellent eix program installed, and use the wrapper eix-sync for portage and overlay syncing and eix database updating in one shot. Naturally, I want to run this daily for all my machines, and I have my server as a local portage mirror (just a matter of changing the make.conf SYNC setting on the clients: SYNC="rsync://jwilly/gentoo-portage"). Thus, the service need for systemd. Putting this is crontab was super easy. Here's how to do it for systemd. Soon you'll see it's almost as easy, just a few things to understand and watch out for.
I give credit to solpeth for the idea and simple howto. It's basically a copy of his/hers.
The idea is that a timer file is running (started and enabled by user), which will trigger a service file (not enabled by user) to run at a specific time of day, or week, or whatever, and repeat. Hence why it's called a timer. The service file that's triggered will run whatever script or program you want once, repeating as dictated by the timer file. I have my timer setup to trigger once a day, everyday.
The idea is that a timer file is running (started and enabled by user), which will trigger a service file (not enabled by user) to run at a specific time of day, or week, or whatever, and repeat. Hence why it's called a timer. The service file that's triggered will run whatever script or program you want once, repeating as dictated by the timer file. I have my timer setup to trigger once a day, everyday.
My /etc/systemd/system/eix-sync-daily.service, which is not enabled nor started, but is triggered by the timer file:
[Unit] Description=eix-sync [Service] Nice=19 IOSchedulingClass=2 IOSchedulingPriority=7 ExecStart=/usr/bin/eix-sync |
The timer file, /etc/systemd/system/eix-sync-daily.timer, is what triggers the service. The timer is enabled and started, and you can see that it is setup to run daily:
OnCalendar=daily will run at about midnight every night. It isn't exact timing, but it's usually within a minute or two. More timing info can be found on freedesktop.org's man pages: systemd.timer and systemd.time.
I think you can see how to modify these two simple files to run almost any program, script you want. In fact, that's exactly what I've done in the next section.
[Unit] Description=Run eix-sync daily [Timer] OnCalendar=daily Persistent=true Unit=eix-sync-daily.service [Install] WantedBy=timers.target |
OnCalendar=daily will run at about midnight every night. It isn't exact timing, but it's usually within a minute or two. More timing info can be found on freedesktop.org's man pages: systemd.timer and systemd.time.
I think you can see how to modify these two simple files to run almost any program, script you want. In fact, that's exactly what I've done in the next section.
2. Blogger Post Daily Service and Timer
I help manage a blog which needs to post everyday. I also didn't want to do this everyday, manually, so of course I figured out a way to let a script do this! The script was written in python, of which I am no expert. I expanded the systemd service+timer duo to make the script run everyday at midnight. Actually, I post at 11pm so I can verify it before I sleep. It's very similar to the eix-sync service+timer.
Here's the service file, /etc/systemd/system/post-tomorrows-daily-bible.service: (Again, this is neither enabled nor started).
Here's the service file, /etc/systemd/system/post-tomorrows-daily-bible.service: (Again, this is neither enabled nor started).
[Unit] Description=post-tomorrows-daily-bible.service [Service] Type=simple ExecStart=/usr/local/bin/post-tomorrows-daily-bible.sh WorkingDirectory=/mnt/huge/share/Podcasts/RochDailyBible |
I actually have a bash script that then runs the python script (I couldn't get the python script to run from the service file, not sure why).
The bash script is simple:
#!/bin/bash # Run Python script (cd /mnt/huge/share/Podcasts/RochDailyBible && python blogger_setup_daily2.py) |
The timer file, /etc/systemd/system/post-tomorrows-daily-bible.timer: (This one is enabled and started, of course)
[Unit] Description=post-tomorrows-daily-bible.timer [Timer] OnCalendar=23:00 Unit=post-tomorrows-daily-bible.service [Install] WantedBy=timers.target |
Notice the OnCalendar is literal, at 11pm. It can take much more complicated, powerful timing parameters, but this works for what I need.
The scripts in order, in summary: timer triggers at 11pm calls the service, which then calls the bash.sh, which then calls the python.py.
3. Delete Old Distfiles Daily Service and Timer
I was starting to fill up my harddrive with old distribution source files, and with Gentoo they reside in /usr/portage/distfiles. There's only so much room for old libreoffice, ibm-jdk, and kernel sources! Those are yesterday's duckies. Ha, I think I had at one time 8 or 9 gigs and I needed storage for a few audiobooks. Weeding those out looks like deleting anything that hasn't been accessed in 180 days. I figure that's plenty of time to keep things around. Herein lies my service+timer and the cleaning script I run.
The service file, /etc/systemd/system/delete-old-distfiles.service:
[Unit] Description=delete-old-distfiles-180 [Service] #Type=simple Nice=19 IOSchedulingClass=2 IOSchedulingPriority=7 ExecStart=/usr/local/bin/delete-old-distfiles.sh WorkingDirectory=/usr/portage/distfiles |
The bash script, /usr/local/bin/delete-old-distfiles.sh, to clean my distfiles not accessed in 180 days:
#!/bin/bash echo "" echo "Current Root filesystem usage:" df -h | grep Filesystem df -h | grep /dev/sda3 echo "" echo "" echo "Deleting distfiles older than 180 days..." find /usr/portage/distfiles -maxdepth 1 -type f -atime +180 -delete echo "" echo "New Root filesystem usage:" df -h | grep Filesystem df -h | grep /dev/sda3 echo "" |
The interesting part of the clean script is the "find" line, where I only go 1 level deep in the directory, look for only files that have an access time older than 180 days and delete them.
[Unit] Description=Run delete-old-distfiles daily [Timer] OnCalendar=daily Persistent=true Unit=delete-old-distfiles.service [Install] WantedBy=timers.target |
Again, this one runs at midnight, like my first one.
That's it for now. Hope these examples help anyone who's trying to schedule tasks in systemd!
~JWilly
Comments
Post a Comment