Live data from Hacker News

Love systemd timers

blog.tjll.net

121–130 of 309 posts

Re: Love systemd timers

#121
post #116
post #92

Earlier quoted context omitted.

How do you express those things in a systemd timer? E.g. run something 4x per day, */6 in cron.

$ systemctl cat public-inbox-watch@.timer # /etc/systemd/system/public-inbox-watch@.timer [Unit] Description=Periodic fetch of public mailing list [Timer] # twice a day OnCalendar=*-*-* 5,17:35 RandomizedDelaySec=1h Persistent=true [Install] WantedBy=multi-user.target

I, er, what? It's... the same as cron? I'm confused now. It's not exactly the same, I guess?

Re: Love systemd timers

#122

We have used cron perfectly fine for decades and it served us well within its very clear limitations. But now obviously we were so blind and wrong all this time and the only true solution is of course systemd.

Has it actually served you well? Because it hasn't served me well at all.

I am not the biggest fan of systemd, but today I will always reach for a systemd timer over cron simply due to the sheer amount of bad experiences I've had with cron. Hours upon hours wasted trying to troubleshoot crons that weren't working due to some stupid obscure issue, having to use dirty hacks to monitor for success or retry failed jobs.

A few years ago I was trying to run a very simple bash script with cron and the script just died halfway through for no reason. Nothing in logs, worked fine when run directly, but in cron it just stopped halfway through a loop. Never figured out the cause, just gave up and used a timer instead, which worked fine. Never touched cron again after that.

The ease and convenience of monitoring and troubleshooting alone are worth switching over.

Re: Love systemd timers

#123
I will use what I am comfortable with and so should others. CronD, SystemD, atD, multiple conditional checks in a shell script, whatever tickles your fancy. There is no wrong answer, just document what you did and add a comment. Comments are permitted in cron. If someone keeps putting complex obfuscated time structures into cron make them decipher their incantation and keep nagging them until they keep it simple, comment their cron entries or until they and their manager resign.

For what it's worth there are usually web apps popping up that can decipher goofy cron time/date incantations. [1] This one has a git repo in the top right, not my repo. Maybe clone it just in case their site goes away some day.

[1] - https://crontab.cronhub.io/

Re: Love systemd timers

#124

I haven't used systemd timers enough to disagree, but > Ambiguous $PATH settings make cron script execution difficult to predict. What makes you say that? You can set the PATH right in the crontab. Is that harder to "predict" than it being set in /etc/bashrc, ~/.bashrc, ~/.profile, ~/.bash_profile, /etc/systemd/…, or wherever else? > You might feel cool knowing the scheduling grammar by heart I've used Linux since 19…

problem with vars is that they apply to any subsequent entry in the file so you need to take that into consideration; the nice thing about timers is that all settings are self contained and not affected by previous entries. The standard /10 and similar cron expressions also have thundering herd problem when on bunch of servers, tho some variants like in Jenkins use variant H/10 (H standing for hash) where the thing is randomly shifted in time to not hit same minute on same server/job

another benefit is having logs in one place for the job; cron's "send a mail when there is any amount of output text" is just annoying behaviour, but also only place to get the job output unless you redirect it somewhere. Also starting from timer vs just doing systemctl start job.service is the same so easier to debug

other than that the few improvements in how to specify run time have been pretty useful.

For example, setting timer as "persistent" will mean any run "lost" to machine powered off will just be ran next time after boot, so you can have job on your PC that is just "run backup at 2AM" and if you turn it off before that you get the backup done first thing in the morning

There is also both random, and fixed (depending on machine UUID) random delay so avoiding thundering herd problem with backups is also pretty convenient.

There is even option to wake a device for the job if necessary tho the problem of shutdown is left to the user. And picking whether to start counting to next timer from previous one or from the job's end.

What I would like also is to have job summary page ("hey this job was done X times but failed Y times") but that's probably better left to external tooling

> You can set the PATH right in the crontab. Is that harder to "predict" than it being set in /etc/bashrc, ~/.bashrc, ~/.profile, ~/.bash_profile, /etc/systemd/…, or wherever else?

There is* a common trap as the cron PATH is usually just /usr/bin:/bin so anything in /usr/local/bin, or in /sbin won't be there.

Re: Love systemd timers

#125
post #122

We have used cron perfectly fine for decades and it served us well within its very clear limitations. But now obviously we were so blind and wrong all this time and the only true solution is of course systemd.

Has it actually served you well? Because it hasn't served me well at all. I am not the biggest fan of systemd, but today I will always reach for a systemd timer over cron simply due to the sheer amount of bad experiences I've had with cron. Hours upon hours wasted trying to troubleshoot crons that weren't working due to some stupid obscure issue, having to use dirty hacks to monitor for success or retry failed jobs.…

Let me state once again: "within its very clear limitations".

Once you learn that env in cron is not same as in your shell and once you learn to redirect output to loggers - it works just fine.

It would be a lie to say that I never debugged cron and sure it's annoying.

> and the script just died halfway through for no reason

Unrelated to cron. Bad script.

Re: Love systemd timers

#126
After years of using orchestration tools like airflow and dagster so many lightbulbs have just lit up in my head.

I wish documentation for tools would explain their abstractions concepts in terms of its primitives.

Great post, thanks!

Re: Love systemd timers

#127
post #79

I haven't used systemd timers enough to disagree, but > Ambiguous $PATH settings make cron script execution difficult to predict. What makes you say that? You can set the PATH right in the crontab. Is that harder to "predict" than it being set in /etc/bashrc, ~/.bashrc, ~/.profile, ~/.bash_profile, /etc/systemd/…, or wherever else? > You might feel cool knowing the scheduling grammar by heart I've used Linux since 19…

"You just put numbers aligned with the titles." That is not a fair summarization of their point because that is not the grammar. There's commas, slashes, asterisks, combinations, and then if you want randomization you need to put it in the command itself because cron can't do it. (Some crons can, but it's not a general capability of cron.) Writing a non-trivial cron spec is not easy.

I am familiar with the syntax, so I am biased ("*/3" and "12,14,20" makes sense if you are familiar with Unix tools), but it is still more intuitive to me than the systemd unit file syntax and usage. I know that I just have to edit /etc/cron or throw any executable file into /etc/cron.d/monthly and it will work on my system, but I cannot write a systemd timer file from scratch without looking it, and to do that I first have to find the directory where the other examples are located. /etc/systemd doesn't appear to be it.

This is generally my only real complaint about systemd. I don't care if it is too monolitic, written in C or whatever, I just want a straightforward syntax for straightforward operations. I'd like it if systemd could recognize if a .target file is a shell script and just do "the right thing". Perhaps it would make sense for a timer file to recognize cron syntax as well. Or at least allow for a kind of extensibility so that I can have it supported.

If systemd had a little more respect for existing conventions, I am pretty sure it wouldn't be so controversial. After all, system administrators like it because they use it all the time, but a regular, full-timer user like me, who only deals with it when something is broken or have to use it as a means-to-an-end to set something up, then all friction is annoying and bad UX. (And no, using Nix is not the solution)

Re: Love systemd timers

#128
post #74

I haven't used systemd timers enough to disagree, but > Ambiguous $PATH settings make cron script execution difficult to predict. What makes you say that? You can set the PATH right in the crontab. Is that harder to "predict" than it being set in /etc/bashrc, ~/.bashrc, ~/.profile, ~/.bash_profile, /etc/systemd/…, or wherever else? > You might feel cool knowing the scheduling grammar by heart I've used Linux since 19…

The main nice thing about the environment in systemd is that it is standard and mostly a blank slate, whereas at least for me I was always getting bit by the fact that the environment in Crontab was completely different from say, the environment inherited by supervisord or sysvinit scripts. In systemd the actual unit that gets executed is the same regardless of what triggers it, so there is no gap. That does require…

> That does require you to still know what the default environment is, but it is a mostly completely clean environment, without any influence from any shell.

Odd. This script

  #!/bin/bash
  
  set > /tmp/set.txt
when scheduled like so

  * * * * * $HOME/bin/testCronScript.sh
Produces this file in /tmp/set.txt which has had a handful of values (HOME, UID, etc) lightly redacted prior to posting here -to remove PII or for length- but its keys are entirely untouched:

  BASH=/bin/bash
  BASHOPTS=
  BASH_ALIASES=()
  BASH_ARGC=()
  BASH_ARGV=()
  BASH_CMDS=()
  BASH_LINENO=([0]="0")
  BASH_LOADABLES_PATH=/usr/local/lib64/bash:/usr/lib64/bash
  BASH_SOURCE=([0]="/home/user/bin/testCronScript.sh")
  BASH_VERSINFO=
  BASH_VERSION=
  DIRSTACK=()
  EUID=13370
  GROUPS=()
  HOME=/home/user
  HOSTNAME=hostname
  HOSTTYPE=x86_64
  IFS=$' \t\n'
  LANG=en_US.utf8
  LOGNAME=user
  MACHTYPE=x86_64-pc-linux-gnu
  OPTERR=1
  OPTIND=1
  OSTYPE=linux-gnu
  PATH=/usr/bin:/bin:/usr/sbin:/sbin
  PPID=1337
  PS4='+ '
  PWD=/home/user
  SHELL=/bin/sh
  SHELLOPTS=braceexpand:hashall:interactive-comments
  SHLVL=1
  TERM=dumb
  UID=13370
  USER=user
  _=/home/user/bin/testCronScript.sh
Seems pretty clean to me. Even when I run this via /etc/crontab, rather than as a user cron job:

  * * * * * root /home/user/bin/testCronScript.sh
I get effectively the same results.

Maybe your distro's default cron environment was bad, and you never bothered to check and unset the badness? I'd be surprised if they were unable to make the default environment for Timer Units to be bad.

Re: Love systemd timers

#129
post #92
post #79

Earlier quoted context omitted.

"You just put numbers aligned with the titles." That is not a fair summarization of their point because that is not the grammar. There's commas, slashes, asterisks, combinations, and then if you want randomization you need to put it in the command itself because cron can't do it. (Some crons can, but it's not a general capability of cron.) Writing a non-trivial cron spec is not easy.

How do you express those things in a systemd timer? E.g. run something 4x per day, */6 in cron.

That's simple but consider "run something 4x per day but randomize a delay by hour so all of the 200 servers doing that task won't run it all at once"

In cron, you basically have to either use your configuration management to generate those times, or have a random delay script running before the command

In systemd timers, it's just

    OnCalendar=0/6:00:00
    RandomizedOffsetSec=60m
and the offset generated will be stable for the job on a given machine (i.e. always same on this machine but different on others) so you will get nice uniform distribution of load.

If you add

    Persist=true
the job will also be run once if there was one or more scheduled runs when the machine was down

Re: Love systemd timers

#130
post #55
post #32

Earlier quoted context omitted.

Friend, you have changed my life

Is this one of those cases where at one point you had an error in the file and you figured it was down to spaces? You fixed that issue, it still didn't work but from that point you never thought to question the assumption. I find myself doing this sort of thing all the time..

Somewhere in my head I had that spaces caused a syntax error, and the UI for systemd is not obvious when you first start using it ... so if it's working then leave well alone. I'll be making all of my .service files (not so many) human-readable in the near future!
Post reply on HN