2 releases
0.2.1 | Apr 8, 2020 |
---|---|
0.2.0 | Apr 8, 2020 |
#2 in #lxc
49KB
1K
SLoC
lxcrond - cron for lxc containers
Features
-
Single binary, statically compiled with musl for easy lxc deployment.
-
No requirement for a shell.
-
No external deps, neither sendmail nor syslog.
-
Run deamon as root, jobs run as a lower privileged users.
-
No special editor, or reloading of files.
-
Also an entr/inotify replacement or simple ESB to detect and process incoming files.
-
Can be used as a cron library in rust code.
-
Generates a pid file so can be configured in lxinitd with
service /run/lxcrond.pid /sbin/lxcrond
let cron = Cron::new(some_jobs); std:๐งต:spawn(move|| { cron.run(); });
File format
Single file /etc/lxcrontab
is read on start up, unless a different file is specified with -c
.
Normal cron format as per /etc/crontab
except the command is not a bash line.
it is command, plus optionally "
quoted args.
# m h dom mon dow user command
23 1 * * * teknopaul /usr/bin/linci admin "backup"
Supports all *
, & a list of values 5,10,15
Supports standard aliases @daily
etc per busybox, and a few others.
Supports absolute file name, if the file is changed or created run the job.
# path user command
/mnt/cipublish/nginx.conf root /bin/update-nginx
Support absolute directories, if a file arrives the job is run. The job should delete or move the files or it may get re-run every 60 seconds
# path user command
/mnt/uploads clam /bin/scan-uploads
Usage
Usage: lxcrond [options]
Options:
-c, --config [conf_file]
specify config file, default is /etc/lxcrontab
-h, --help print this help menu
-v, --verbose print debug information to stdout
-V, --version print version number and exit
-f, --filesystem-watch
use filesystem polling every 60 seconds to handle file jobs instead of inotify
If there are no jobs to run lxcrond exits.
Software design
Main loop syncs to run once every 60 seconds at :00, then ask is "now" the time to run any job. File operations use the Linux kernels inotify interface, or as a fallback, checks directories every 60 seconds.
Time considerations
There are many caveats to working with time in computers this program takes a simple approach that presumes time jumps are for a reason
that the owner of the machine understands without making presumptions.
If the system time jumps more than one minute its possible that jobs do not fire because that time "did not happen" on this machine.
If time jumps backwards jobs may fire twice because that time "happened twice".
Provided time jumps are significantly less than 60 seconds no funny stuff should happen, ntpd
ensures time is kept in sync without large time jumps.
Thus, if you set a cron to run at 23 12 * * *
every day the job will run at 12:23:00
, provided that time or any time up to 12:23:59
actually happens on this machine when the main loop triggers.
Main loop triggers once every 60 seconds. This duration time is determined by the same clock that can be manipulated as interpreted
by Rust. Rust does a significant amount of interpretation of the system time when considering Duration: specifically it attempts to
ensure that Durations do not occur twice, no matter how skewed the system clock is.
see Struct std::time::Instant
If the system is very heavily loaded or the process is excessively niced it is possible that the time happens but no code runs when the
time happens.
Time now is calculated once per loop, so if any job runs with a given time spec all jobs withe same time spec are guaranteed to run,
even on a very heavily loaded system, so the risk that jobs themselves consume 100% of CPU is mitigated.
TimeZone considerations
N.B. all times are local time. Jobs run in the current timezone so if you travel with a laptop and switch timezones, jobs may not fire or may fire twice.
Daylight Savings considerations
Some times happen twice in the same day if you are unfortunate enough to live in a timezone that does daylight saving. Busybox crond handles
this by not re-firing jobs if the time jumps by one hour, lxcrond
does not do that. This means you can schedule jobs to run every 5 mins
and they will run correctly on daylight savings days.
inotify considerations
If files are polled with inotify there are various caveats, most significantly directories are not polled recursively. There are many other
details to inotify that can cause jobs not to run, see man 7 inotify
.
TODO see .later
Bugs see .later
LXC considerations
If compiled with cargo build --release --target=x86_64-unknown-linux-musl
the only dependencies of this program are the
config file /etc/lxcrontab
and /etc/passwd
.
/etc/passwd
is required to determine the user for executing jobs. lxcrond
will not continue
if /ect/passwd
can not be read to avoid accidentally running scripts with no $HOME
or and unexpected pwd
.
Build
By default make
builds with cargo and the musl
target for to install this target run
rustup target add x86_64-unknown-linux-musl
make
make deb
make install
author
(c) teknopaul 2020
Dependencies
~4โ5.5MB
~85K SLoC