Systemd: setting dependencies between templated timer units

systemd

I am using some templated timer units to run sets of templated services. There are backup jobs and associated maintenance tasks that require an exclusive lock on the backup repository and cannot run at the same time as the backup jobs. I am trying to figure out how to set up the units so that the jobs are sequenced correctly.

For example, I have the following service templates:

  • backup@.service
  • clean@.service

I have the following timer templates:

  • backup-daily@.timer
  • backup-weekly@.timer
  • clean-daily@.timer
  • clean-weekly@.timer

Where the backup-daily@.timer unit starts the corresponding backup@.service instance and might look something like:

[Unit]
Description=daily backup of %i

[Timer]
OnCalendar=daily
Unit=backup@%i.service

[Install]
WantedBy=timers.target

If I run…

systemctl enable --now backup-daily@foo.timer clean-daily@foo.timer

…I need to ensure that the clean@foo service does not run until after the backup@foo service has completed.

The only solution I've come up with so far is to drop OnCalendar=daily and instead use explicit start times so that I can guarantee the backup jobs start first (e.g., start the backup jobs at 1AM and the maintenance jobs at 2AM), and then utilize some sort of locking (e.g., the flock) command to ensure that the maintenance jobs don't start until after the backup jobs have completed.

That works but it's a little hacky. If there's a bettery way to solve this using systemd I would like to figure that out.

Best Answer

After thinking that question through a bit, there's an obvious answer: In the clean@.service template, add a dependency on the corresponding backup@.service instance, like this:

[Unit]
After=backup@%i.service

This works fine as long as the services are started in parallel. I don't know right now if services with the same OnCalendar setting are started in parallel are not; I'll update this answer once I've figured that one out.