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).
|
|