Search code examples
systemdsystemd-timer

Systemd timer scheduled for first start without manually starting or rebooting the server


Background

I have multiple (30+) custom services/timers which have the same structure (below in Contents section), but different timings. They have to be executed only when they are scheduled and cannot be run manually at random times. The application behind these jobs is often updated and during the update these jobs must be disabled/stopped and re-enabled/started-per-schedule after the update.

Question

I've created new systemd timer/service files and placed them under /etc/systemd/system/. How do I schedule this to start for first time based on OnCalendar without manually starting the timer or rebooting the server?

Contents

I have a service file:

# /etc/systemd/system/dummy.service
[Unit]
Description=dummy Service
Wants=dummy.timer

[Service]
Type=oneshot
User=root
ExecStart=/bin/ping -c 30 8.8.8.8
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=multi-user.target

And a corresponding timer:

# /etc/systemd/system/dummy.timer
[Unit]
Description=dummy Timer
Requires=dummy.service

[Timer]
Unit=dummy.service
OnCalendar=*-*-* *:00:00
AccuracySec=1ms
RandomizedDelaySec=0

[Install]
WantedBy=timers.target

They are placed in /etc/systemd/system/ and then I run the following commands to enable the timer:

systemctl daemon-reload
systemctl enable dummy.timer

And if I run systemctl list-timers --all 'dummy*', the output is as per below, and the timer never executes..

NEXT LEFT LAST PASSED UNIT        ACTIVATES    
n/a  n/a  n/a  n/a    dummy.timer dummy.service

The only way I can make it start running on its schedule is either by rebooting the server (which is not an option) or by manually starting the timer with systemctl start dummy.timer, which is also not what I need.

I've been searching for solution for quite some time now and all I could find was either start manually or reboot. Having found anything SystemD man pages...

The workaround I have in place is using systemd-analyze calendar to read the next run time, date to convert it to %Y%m%d%H%M format and then schedule it with linux at command. This is far from elegant and has issues with jobs that run once a week or once a month, and the server is rebooted after application update and before scheduled run time.

Any ideas?

Thank you!


Solution

  • Ah, found the answer just after commenting.

    The timer is implictly bound to the service of the same name. The Requires= line in the timer definition causes it to run the service. If you remove this line and then enable/start the timer it will only trigger on its schedule. Not at boot, and not when the start is performed, i.e.

    systemctl enable --now dummy.timer