Wandering Thoughts archives

2021-08-23

Notes on deliberately invoking actions controlled by systemd timers

Every so often you want to manually invoke something that is normally automatically run periodically. Back in the days when everything ran through cron entries, you did this by finding the specific cron entry responsible for the action (often searching through /etc/cron.d for likely candidates), getting the specific command line (and sometimes the user involved), and manually running it. These days, an increasing number of things are switching from cron entries to systemd timer units, so you need a somewhat different procedure.

The simple case with a systemd timer unit is very simple, which is that you have a timer unit called 'certbot.timer' and it triggers a systemd service unit called 'certbot.service'. Then you can just do 'systemctl start certbot' to trigger the service unit, and it will be as if it was run because of the timer unit (as far as I know). If you've taken special steps to get mailed any error output, they'll still work and you'll get any errors emailed to you.

(You can find the name of the timer name with 'systemctl list-timers' Different distributions may call some timer and service units by different names; Ubuntu calls it 'certbot.<what>', while Fedora calls it 'certbot-renew.<what>'.)

The complicated case is that the systemd timer unit manually specifies a 'Unit=' setting to run some differently named unit. The systemd timer unit manpage strongly urges you not to do this and I don't think any normal timer unit in Ubuntu or Fedora does this, but people are perverse and somewhere out there I'm sure there's someone using it in their timer units. If you want to be sure of the unit name to start yourself, you need to look it up with 'systemctl show --no-pager --property Unit <whatever>.timer'. If the particular timer unit doesn't specify a 'Unit=', this will give you the default value (eg 'certbot.service'), so you can use it reliably in a script. If you used 'systemctl list-timers' to find the timer name, it will also tell you the service name as well so you can just use that.

(The really complicated case is that some excessively helpful person has set the .service unit so that it refuses to be manually started, with 'RefuseManualStart=yes'. Then you're probably down to reading the .service unit and running the command by hand.)

There are two ways to see the most recent time that a particular timer unit was triggered at. The first is 'systemctl list-timers', which will tell you the last time the unit was triggered among other things. The other way is to look at the timestamp of what is usually /var/lib/systemd/timers/stamp-<whatever>.timer.

(It would be nice if systemd had a way to say 'no, really, act as if this timer had reached its interval right now, I know what I'm doing', but it doesn't seem to. But it doesn't really matter as long as everyone is sensible about service unit naming and not preventing manual starts of timer service units, and I think they are.)

Sidebar: My usage case for this

I have Let's Encrypt certificates for virtual machines that I only start up once in a while, and for reasons beyond the scope of this entry I never want the certificates to expire; I always want to be renewing them instead of requesting their names as new certificates. This can leave me wanting to start up a virtual machine just to get its certificate renewed, and in that case I want to trigger the renewal timer right now (and then shut the VM down again).

linux/SystemdRunningTimers written at 23:00:06; Add Comment


Page tools: See As Normal.
Search:
Login: Password:
Atom Syndication: Recent Pages, Recent Comments.

This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.