[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: migration from cron.daily to systemd timers



On 1/7/20 3:18 PM, Noah Meyerhans wrote:
> Current the cron.daily script is a no-op by default, and functionality
> is enabled by setting CRON=1 in /etc/default/spamassassin.  For users
> running systemd, I'd expect to ship a timer unit that is disabled by
> default, and have them enable it with:
> 
> $ systemctl enable spamassassin-daily-maintenance.timer

This seems correct. It is the systemd native way to do it.

> For upgrades from versions that did not include the timer, should I
> enable the systemd timer if the user has set CRON=1?  Or should I leave
> the timer disabled and preserve the original behavior via cron.daily?
> Since the cron script is a conffile, and may have local modifications, I
> think it should be left in place, but would take confirmation.  It'd be
> possible to perform the migration while still preserving local
> modifications, e.g. by having the shipped cron script enable the unit
> file, but IMO that would be gross.

Could you check for local modifications and only enable the timer if
there were NOT local modifications?

[ -e /etc/default/spamassassin ] && . /etc/default/spamassassin
if [ -d /run/systemd/system ] && [ "$CRON" = "1" ] &&
   ! some_check_for_local_modifications
then
    systemctl enable spamassassin-daily-maintenance.timer
fi

> If the timer and the cron activity are both enabled, the cron script
> will be a no-op.  This is accomplished with the following in the cron
> script:
> 
> if command -v systemctl > /dev/null 2>&1 &&
>        systemctl is-enabled spamassassin-daily-maintenance.timer; then
>     exit 0
> fi
> 
> Would you do this a different way?
If it was me, I'd just check for whether systemd is running (e.g. [ -d
/run/systemd/system ]), not whether the timer unit is enabled. That way,
at least moving forward, you're only supporting two scenarios (systemd
uses the units, non-systemd uses cron) rather than three (those two plus
the option of systemd systems still using cron).

If you were doing this new, I would suggest that you use cron.d instead
of cron.daily. Then check for systemd by prefixing your command with:
  [ -d /run/systemd/system ] || ...
This way, if the user installs systemd-cron (which replaces crond and
generates systemd service & timer units from cron files), it will not
generate units for the cron job. See:
https://github.com/systemd-cron/systemd-cron/blob/master/src/bin/systemd-crontab-generator.py#L335

Unfortunately, there is currently no equivalent for /etc/cron.daily, as
systemd-cron just runs run-parts. It does not convert each cron.daily
script into a separate service. I filed a feature request for that back
in 2016, and it's gotten another look recently. I may have some time to
work on it again this year and propose a patch if nobody beats me to it:
https://github.com/systemd-cron/systemd-cron/issues/47

If you wanted, you could migrate from /etc/cron.daily to /etc/cron.d and
then apply this approach, but you'd still have the "local modifications"
problem.

If you are willing to drop support for direct local modifications, then
you could use cron.d and disable the script in cron.daily. This would
give you the simplest solution moving forward, but would require
explicit action from anyone who had customized the cron.daily script.

-- 
Richard

Attachment: signature.asc
Description: OpenPGP digital signature


Reply to: