Talk:Systemd/Timers

From ArchWiki
Jump to navigation Jump to search

Counterproductive Suggestions

The suggestions on this page are counterproductive. By merging all units under a single target, you're intentionally creating a stampede when the timer goes off. One of the great features of timer units is that a combination of OnCalendar and AccuracySec can trivially mitigate the overlap that's associated with classic cron while still maintaining regularity. This is distinctly better than classic cron which would force a human to schedule the task jitter manually.

In addition, it isn't reasonable to queue these on basic.target as one wants a fully operational system before cron will run. Much like how cron daemons were treated like any other daemon and brought up in runlevel 3 under sysvinit, it makes much more sense to order timers on multi-user.target. Falconindy (talk) 23:38, 4 May 2014 (UTC)

Your remarks seem to make perfect sense and are corroborated by how the old /etc/cron.*/ files provided by packages in [base] group were converted to systemd.timer files (see https://mailman.archlinux.org/pipermail/arch-dev-public/2014-March/026044.html and files present on one's system)).
So to sum it up:
  • A different /usr/lib/systemd/system/*.{timer,service} couple for every unit wanted should be created (or should /etc/systemd/system/ be used instead?);
  • Then a symbolic link to each custom /usr/lib/systemd/system/*.timer file should be made in /usr/lib/systemd/system/multi-user.target.wants/;
I've had a go at it for the reflector service that I was running as a daily (ana)cron job, taking after the new logrotate systemd.timer service converted by Thomas Bächler. Any comments appreciated.
Step one: create timer and service files for every different unit
/usr/lib/systemd/system/reflector.service
[Unit]
Description=Update pacman mirrorlist

[Service]
Type=oneshot
ExecStart=/usr/bin/reflector --protocol http --latest 5 --sort rate --save /etc/pacman.d/mirrorlist
Nice=19
IOSchedulingClass=best-effort
IOSchedulingPriority=7
Note: As for now this service file doesn't work. See my edit below for error log. systemd gurus, your corrections are welcome.
/usr/lib/systemd/system/reflector.timer
[Unit]
Description=Daily update of pacman mirrorlist

[Timer]
OnCalendar=daily
AccuracySec=12h
Persistent=true
Step 2: Order timer on multi-user.target
# ln -s /usr/lib/systemd/system/reflector.timer /usr/lib/systemd/system/multi-user.target.wants/reflector.timer

If the above is correct, this will lead to quite a massive overhaul of the wiki page... Waiting for other comments to proceed.

Edit 2014-05-13: the example service file I wrote for Reflector doesn't work. I get a failed status with systemctl:

# systemctl status -l reflector
● reflector.service - Update pacman mirrorlist
   Loaded: loaded (/usr/lib/systemd/system/reflector.service; static)
   Active: failed (Result: exit-code) since mer. 2014-05-14 00:00:10 CEST; 49min ago
  Process: 6149 ExecStart=/usr/bin/reflector --protocol http --latest 5 --sort rate --save /etc/pacman.d/mirrorlist (code=exited, status=1/FAILURE)
 Main PID: 6149 (code=exited, status=1/FAILURE)

mai 14 00:00:10 arch-clevo reflector[6149]: error: failed to retrieve mirror data: (The read operation timed out)
mai 14 00:00:10 arch-clevo systemd[1]: reflector.service: main process exited, code=exited, status=1/FAILURE
mai 14 00:00:10 arch-clevo systemd[1]: Failed to start Update pacman mirrorlist.
mai 14 00:00:10 arch-clevo systemd[1]: Unit reflector.service entered failed state.

Does anyone know how I should edit this file? I'll be trying different options taken from systemd.service manpage, but if somebody is knowledgeable enough to spare us some time that's all right too... -- Neitsab (talk) 11:44, 8 May 2014 (UTC), edited 23:25, 13 May 2014 (UTC)

Well, I would say that it is a better idea to wait before editing this page. Falconindy, I remember some talk about AccuracySec not working properly on the arch-general ML. Has it been dealt with? - Genghizkhan91 (talk) 05:41, 13 May 2014 (UTC)

Not sure if this is helpful, since it calls a script that does a bunch of things (including reflector) and e-mails me the output, but the following works for me. Except for a couple differences, the systemd service and timer files are largely the same as above. (I had to use "Type=forking", otherwise my MTA would complain about receiving a SIGTERM and would kill the message.) I can post the content of my /usr/local/bin/pacman-sync too if you like, but it's probably not that interesting. After writing these files, I enabled and started pacman-sync.timer.

/etc/systemd/system/pacman-sync.service
[Unit]
Description=Update pacman mirrorlist, sync, and download packages

[Service]
Type=forking
ExecStart=/usr/local/bin/mail-output root "%H: pacman-sync" /usr/local/bin/pacman-sync
Nice=19
IOSchedulingClass=best-effort
IOSchedulingPriority=7
/etc/systemd/system/pacman-sync.timer
[Unit]
Description=Daily update of pacman mirrorlist, sync, and download of packages

[Timer]
OnCalendar=daily
AccuracySec=12h
Persistent=true

[Install]
WantedBy=multi-user.target
/usr/local/bin/mail-output
#!/usr/bin/bash

RECIPIENT="$1" ; shift
SUBJECT="$1" ; shift
CMD="$@"

# Mails the output of the given CMD to the given RECIPIENT with the given SUBJECT.
# No mail is sent if no output is produced.
"$@" 2>&1 | /usr/bin/mail -E -s "${SUBJECT}" "${RECIPIENT}"

-- Liujed (talk) 05:43, 23 May 2014 (UTC)


Finally found how to make sure it works Moviuro (talk) 18:47, 11 June 2014 (UTC)

This unit makes sure that at the time it is fired up the host is available. If it isn't, it will keep trying.

/etc/systemd/system/reachable-retry@.service
[Unit]
Description=Test if %i is reachable
# Customize to your own needs, with network.target or whatever works less worse with you
After=systemd-networkd-wait-online.service
 
[Service]
Type=forking
ExecStart=/usr/bin/ping -c1 %i
Restart=on-failure

[Install]
WantedBy=multi-user.target
/etc/systemd/system/timer-daily.target.wants/reflector.service
[Unit]
Description=Update mirorlist
# Fire up the tester
Requires=reachable-retry@www.archlinux.org.service
# Wait for it to return SUCCESS
After=reachable-retry@www.archlinux.org.service

[Service]
# Copied from wiki
Nice=19
IOSchedulingClass=2
IOSchedulingPriority=7
Type=oneshot
# Customize to your own needs
ExecStart=/usr/bin/reflector -i (fr|nl|be). -f 5 --save /etc/pacman.d/mirrorlist

And voilà Moviuro (talk) 18:47, 11 June 2014 (UTC)

Edited

I think the arguments against unified timers makes sense, so I went ahead and removed that section. I then combined info from other sections to form a more complete example. This left the service examples orphaned (since they all relied on the unified timers) so I moved them (when possible) to their appropriate pages. Silverhammermba (talk) 21:01, 28 July 2014 (UTC)

A bit like unified timer

Solution that solves everything I think (though not perfect as it only works on single services):

/etc/systemd/system/timer-daily@.timer
[Unit]
Description=Daily Timer for the %i service

[Timer]
OnCalendar=daily
Persistent=true
Unit=%i.service

[Install]
WantedBy=multi-user.target

and then

systemctl enable timer-daily@myservice.timer

And Voilà! Moviuro (talk) 21:59, 1 September 2014 (UTC)

That is definitely nicer than the old unified timer example! However it still has the problem of all services using this timer starting simultaneously, which I think was the main complaint originally. Though based on the discussion about AccuracySec being random per-host (and thus useless for timer jitter), we still have no better solution than just per-service timers with manually staggered triggers. Silverhammermba (talk) 22:47, 1 September 2014 (UTC)

Workaround for the particular issue "they all fire up at the same time":

/etc/systemd/system/timer-daily@myservice.timer.d/time.conf
[Timer]
# man 7 systemd.time
# adjust for each service that should not run with all others
OnCalendar=*-*-* 1:30:0
# Disable Persistence if you don't want the timer to "catch up"
#Persistent=false

This way, the last systemctl command still works and we can set a different time in the override configuration. Still a bit of a heavy solution, though Moviuro (talk) 07:38, 2 September 2014 (UTC)

The above discussion shows how the current content of the article was developed, but it might be better to start a fresh item in case related questions arise again. We could close it and, once removed, still refer to it via the history if needed.
Or is there demand for keeping this discussion open? --Indigo (talk) 18:02, 9 January 2015 (UTC)

Mailing output

Are there any built-in facilities for e-mailing the output of timed services? It doesn’t look as if there are. Maybe the wiki could outline a good practice for achieving that effect. A simple workaround would be having the service pipe output into sendmail, but maybe there’s a more elegant way (e.g., maintaining this would be cumbersome for many services). --Eigengrau (talk) 10:37, 14 May 2014 (UTC)

I just noticed that the Gentoo wiki has an example using a failure-email@.service which is started using OnFailure=. This seems like the right way to do it, but I don't fully understand their code. --Silverhammermba (talk) 15:14, 6 October 2014 (UTC)

Hi, I rewrote this for inclusion in systemd-cron mail_on_failure It nows checks for MAILTO=, like vixie-cron. --A-detiste (talk) 08:02, 31 October 2014 (UTC)

mail_on_failure's behaviour doesn't match vixie-cron's. Whereas mail_on_failure only sends mail when a job has failed, vixie-cron will send mail containing the job's output regardless of the job's exit status. (Same probably goes for the OnFailure= approach suggested by the Gentoo wiki, described above.) --Liujed (talk) 20:12, 2 November 2014 (UTC)
Indeed, the taste of users varies on this; OnFailure= was absolutely needed and easy to implement "mail on output" is not so straightforward. I've already discussed this elsewhere DebianBug and here systemd-devel .
Putting in a wrapper script between ExecStart= and the actual script is an added point of failure; using OnFailure is more robust. I even have this mailer run with an underprivilieged user
So to there remains work to get "mail on output", here is some options:
  • use some ExecStartPre= & ExecStartPost= magic that parse journalctl output with '--cursor' and save it somewhere
  • read $MAINPID in ExecStartPost= and do something with it
  • use a wrapper ("ExecStart=/usr/lib/mail_on_output /usr/bin/run-parts /etc/cron.daily/")
--A-detiste (talk) 11:31, 4 November 2014 (UTC)