This example maintains a mirror of code.dogmap.org.
in the
directory ./mirror
. It runs under Laurent Bercot's
s6
system.
# cd /service/mirror-dogmap # cat run #!/bin/sh exec 2>&1 \ s6-setuidgid mirroruser \ rw-add n d1S now1s \ rw-match \$now1s ,H=2,M=30 wake \ statfile -M finished \ rw-add \$MTAI64N d36H latest \ rw-min \$wake \$latest wake \ statfile -M started \ rw-add \$MTAI64N d1H earliest \ rw-max \$wake \$earliest wake \ sh -c ' echo "@$wake" | s6-tai64nlocal | sed "s/^/next run time: /" exec "$@"' arg0 \ rw-sleep \$wake \ ./doit # cat doit #!/bin/sh touch started && ftpcopy -x '/mirror/*' code.dogmap.org / ./mirror && touch finished
setuidgid
changes to the uid and gid of
mirroruser
, which should be able to write to the
./mirror
directory.
rw-add
adds the current time and 1 second and stores the
result in $now1s
.
rw-match
computes the earliest time at or after
$now1s
that matches 2:30 AM (local time), and stores the
result in $wake
. (Adding 1 second in the previous step
ensures that if ./doit
runs in less than one second,
rw-match
won't schedule it to run again immediately; we'll
schedule it for 2:30 AM the next day.)
statfile
(from the
misc/fdtools package) finds the
last-modified time of the file "finished" and stores it in
$MTAI64N
.
rw-add
adds $MTAI64N
and 36 hours, and stores
the result in $latest
.
rw-min
computes the earlier of $wake
and
$latest
, and stores the result in $wake
. (This
ensures that if the job fails, or was not run for some reason, it will be
scheduled to run at most 36 hours after the last time it completed
successfully, so the mirror will not be too far out of date.)
statfile
finds the last-modified time of the file
"started" and stores it in $MTAI64N
.
rw-add
adds $MTAI64N
and 1 hour, and stores
the result in $earliest
.
rw-max
computes the later of $wake
and
$earliest
, and stores the result in $wake
.
(This ensures that even if the job fails several times, it will not be
attempted more often than once an hour, to avoid swamping a clogged
network link.)
sh
command logs $wake
as the next
scheduled run time.
rw-sleep
sleeps until $wake
. (You can make
it wake up immediately at any time by sending SIGALRM
via
svc -a /service/mirror-dogmap
.)
./doit
touches the file "started
"
to record that the job was attempted.
./doit
updates the mirror with ftpcopy
. If
ftpcopy
exits nonzero, the shell also exits, because of the
-e
option.
./doit
touches the file "finished
" to
record that the job completed successfully.
./doit
(which is running in the same process that was
originally the run
script) exits. supervise
restarts ./run
, and cycle begins again. (If you prefer to
have your services never exit during normal operation, you could have
./doit
end by exec'ing ./run
.)