Skip to content

karlicoss/dron

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

188 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

NOTE: this README is a brief overview. Best source of truth is dron --help.

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

What does it do?

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 .service and .timer units
  • on macOS it manages user-level launchd LaunchAgents

Jobs live in a Python module, defaulting to drontab.<hostname>. The module must define a jobs() function that yields dron.api.job(...) objects.

from dron.api import job

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.

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 here. Also:

Setting up

  1. install system dependencies if needed; on Linux, dbus-python may require DBus development libraries
  2. install dron: pip3 install --user git+https://github.com/karlicoss/dron
  3. install sendmail from your package manager if you want local job failure emails

Using

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 apply imports the drontab module, generates backend units, diffs them against managed units, and applies the plan
  • dron lint imports the drontab module and verifies the generated units without applying changes
  • dron print shows parsed jobs, with --pretty for a table
  • dron monitor opens the Textual monitor; dron monitor --once prints a one-shot table
  • dron job past <unit> shows previous runs for one unit
  • dron job run <unit> runs one job immediately, ignoring the timer
  • dron uninstall removes all managed jobs after confirmation

Use --module with apply, lint, and print to point at a different drontab module.

Job syntax

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.

Caveats

  • launchd support intentionally has a smaller schedule surface than systemd
  • older systemd versions only accepted absolute paths for ExecStart; generated units are verified before apply installs them

Potential improvements

  • make applying changes more atomic, for example rolling back all changes until daemon reload succeeds
  • more failure report mechanisms

About

What if cron and systemd had a baby?

Topics

Resources

License

Stars

59 stars

Watchers

1 watching

Forks

Packages

 
 
 

Contributors