NOTE: this README is a brief overview.
Best source of truth is dron --help.
- d stands for ‘Systemd’
- ron stands for ‘cron’
dron is my attempt to overcome things that make working with Systemd tedious
dron is a small Python CLI for defining scheduled jobs in Python while letting
the operating system do the actual running and scheduling:
- on Linux it manages user-level
systemd.serviceand.timerunits - on macOS it manages user-level
launchdLaunchAgents
Jobs live in a Python module, defaulting to drontab.<hostname>. The module must
define a jobs() function that yields dron.api.job(...) objects.
def jobs():
yield job( ‘daily’, ‘/home/user/scripts/run-borg /home/user’, unit_name=’borg-backup-home’, )
yield job( ‘daily’, ‘linkchecker https://beepb00p.xyz’, unit_name=’linkchecker-beepb00p’, )
def every(, mins: int) -> str: return f’:0/{mins}’
yield job( every(mins=10), ‘ping https://beepb00p.xyz’, unit_name=’ping-beepb00p’, )
Run dron apply after editing the module. dron imports the jobs, builds the
desired backend units, compares them with currently managed units, and applies
the add/update/delete plan.
In short, because I want to benefit from the heavy lifting that Systemd does: timeouts, resource management, restart policies, powerful scheduling specs and logging, while not having to manually manipulate numerous unit files and restart the daemon all over.
I elaborate on what led me to implement it and motivation here. Also:
- install system dependencies if needed; on Linux,
dbus-pythonmay require DBus development libraries - install
dron:pip3 install --user git+https://github.com/karlicoss/dron - install
sendmailfrom your package manager if you want local job failure emails
Usage: dron [OPTIONS] COMMAND [ARGS]...
dron -- simple frontend for Systemd, inspired by cron.
- *d* stands for 'Systemd'
- *ron* stands for 'cron'
dron is my attempt to overcome things that make working with Systemd tedious
Options:
--marker TEXT Use custom marker instead of default `(MANAGED BY DRON)`.
Useful for developing/testing.
--help Show this message and exit.
Commands:
apply Apply drontab (like 'crontab' with no args)
debug Print some debug info
job Actions on individual jobs
lint
monitor Monitor services/timers managed by dron
print Parse and print drontab
uninstall Remove all managed jobs (will ask for confirmation)
* Why?
In short, because I want to benefit from the heavy lifting that Systemd does:
timeouts, resource management, restart policies, powerful scheduling specs and
logging, while not having to manually manipulate numerous unit files and
restart the daemon all over.
I elaborate on what led me to implement it and motivation
[[https://beepb00p.xyz/scheduler.html#what_do_i_want][here]]. Also:
- why not just use [[https://beepb00p.xyz/scheduler.html#cron][cron]]?
- why not just use [[https://beepb00p.xyz/scheduler.html#systemd][systemd]]?
Common commands:
dron applyimports the drontab module, generates backend units, diffs them against managed units, and applies the plandron lintimports the drontab module and verifies the generated units without applying changesdron printshows parsed jobs, with--prettyfor a tabledron monitoropens the Textual monitor;dron monitor --onceprints a one-shot tabledron job past <unit>shows previous runs for one unitdron job run <unit>runs one job immediately, ignoring the timerdron uninstallremoves all managed jobs after confirmation
Use --module with apply, lint, and print to point at a different drontab
module.
The idea is that it’s a simple Python DSL that lets you define jobs with minimal friction.
job(when, command, *, unit_name=None, on_failure=(notify.email_local,), **kwargs)when is a backend schedule string such as daily or *:0/10. Passing None
creates a service without a timer, so it can still be run manually with
dron job run. command can be a shell string or a sequence of command parts.
Any extra keyword arguments are passed to the backend unit generator, which is useful when you need systemd-specific service properties.
launchdsupport intentionally has a smaller schedule surface thansystemd- older
systemdversions only accepted absolute paths forExecStart; generated units are verified beforeapplyinstalls them
- make applying changes more atomic, for example rolling back all changes until daemon reload succeeds
- more failure report mechanisms