From: Mark Wooding Date: Thu, 16 Jan 2014 09:51:56 +0000 (+0000) Subject: rsync-backup.{in,8}: Introduce `hook' concept. X-Git-Tag: 1.0.1~3 X-Git-Url: https://git.distorted.org.uk/~mdw/rsync-backup/commitdiff_plain/9b1d71c6944756a0a732b8553d0516c3f0e720e2 rsync-backup.{in,8}: Introduce `hook' concept. I want to make the configuration file so that it can be read by scripts which don't actually want to run a backup. Therefore, code which currently runs unconditionally to (e.g.) copy metadata onto the backup volume must be wrapped up in a function. To make this a bit more disciplined, introduce a general idea of hooks which are run with arguments. The existing `backup_precommit_hook' and `backup_commit_hook' functions are subsumed by this, still provided for compatibility. New hooks are added at the start of the whole backup, at the beginning of each filesystem dump, and at the end of the whole operation. --- diff --git a/rsync-backup.8 b/rsync-backup.8 index 0710158..04a489a 100644 --- a/rsync-backup.8 +++ b/rsync-backup.8 @@ -141,11 +141,29 @@ The backup is now complete. The configuration file is simply a Bash shell fragment: configuration commands are shell functions. .TP +.BI "addhook " hook " " command +Arrange that the named +.I hook +runs the given +.IR command . +See +.B runhook +for more details. +.TP .BI "backup " "fs\fR[:\fIfsarg\fR] ..." Back up the named filesystems. The corresponding .IR fsarg s may be required by the snapshot type. .TP +.BI "defhook " hook +Define a new hook named +.IR hook . +See +.B addhook +and +.B runhook +for more information. +.TP .BI "host " host Future .B backup @@ -246,6 +264,20 @@ mismatch will be retried up to .I count times before being declared a failure. .TP +.BI "runhook " hook " " args\fR... +Invoke the named +.IR hook . +The individual commands on the hook are run, in order, as +.RS +.IP +.I command +.IR args ... +.PP +If any command fails (returns nonzero) then no other hooks are run and +.B runhook +fails with the same exit code. +.RE +.TP .BI "snap " type " " \fR[\fIargs\fR...] Use the snapshot .I type @@ -352,11 +384,28 @@ The name of the current volume. If this is left unset, the volume name is read from the file .IB METADIR /volume once at the start of the backup run. -.SS Hook functions -The configuration file may define shell functions to perform custom -actions at various points in the backup process. +.SS Hooks +The configuration file can modify the behaviour of the backup in two +main ways: by adding commands to hooks (see the +.B addhook +command); and by redefining shell functions. +.PP +The following hooks are defined. .TP -.BI "backup_precommit_hook " host " " fs " " date +.BI "commit " host " " fs " " date +Called during the commit procedure. The backup tree and manifest have +been renamed into their proper places. Typically one would use this +hook to rename files created in a corresponding +.B precommit +command. +.TP +.BI "end " rc +The backup has completed; +.B rsync-backup +will exit with status +.IR rc . +.TP +.BI "precommit " host " " fs " " date Called after a backup has been verified complete and about to be committed. The backup tree is in .B new @@ -367,12 +416,26 @@ manifest is in A typical action would be to create a digital signature on the manifest. .TP +.BI "setup " host " " fs " " date +Called when a backup of a particular filesystem is about to start. It +can return with code 99 to skip the backup. +.TP +.B "start" +Invoked before performing any actual dumps (the first time +.B host +is run). +.PP +The following shell functions can be redefined by users. +.TP .BI "backup_commit_hook " host " " fs " " date -Called during the commit procedure. The backup tree and manifest have -been renamed into their proper places. Typically one would use this -hook to rename files created by the -.B backup_precommit_hook -function. +Called from the +.B commit +hook for compatibility. +.TP +.BI "backup_precommit_hook " host " " fs " " date +Called from the +.B precommit +hook for compatibility. .TP .BR "whine " [ \-n ] " " \fItext\fR... Called to report `interesting' events when the diff --git a/rsync-backup.in b/rsync-backup.in index 67d0efb..e232bc8 100644 --- a/rsync-backup.in +++ b/rsync-backup.in @@ -157,6 +157,31 @@ hostpath () { fi } +defhook () { + hook=$1 + ## Define a hook called HOOK. + + eval hk_$hook= +} + +addhook () { + hook=$1 cmd=$2 + ## Add command CMD to the hook HOOK. + + eval old=\$hk_$hook; new="$old $cmd" + eval hk_$hook=\$new +} + +runhook () { + hook=$1; shift 1 + ## Invoke HOOK, passing it the remaining arguments. + + eval cmds=\$hk_$hook + for cmd in $cmds; do + if ! $cmd "$@"; then return $?; fi + done +} + ###-------------------------------------------------------------------------- ### Database operations. @@ -573,19 +598,28 @@ expire_backups () { done } +## Backup hooks. +defhook setup +defhook precommit +defhook postcommit + backup_precommit_hook () { host=$1 fs=$2 date=$3 - ## Override this hook in the configuration file for special effects. + ## Compatibility: You can override this hook in the configuration file for + ## special effects; but it's better to use `addhook precommit'. : } +addhook precommit backup_precommit_hook backup_commit_hook () { host=$1 fs=$2 date=$3 - ## Override this hook in the configuration file for special effects. + ## Compatibility: You can override this hook in the configuration file for + ## special effects; but it's better to use `addhook commit'. : } +addhook commit backup_commit_hook do_backup () { date=$1 fs=$2 fsarg=$3 @@ -594,6 +628,14 @@ do_backup () { set -e attempt=0 + ## Run a hook beforehand. + set +e; runhook setup $host $fs $date; rc=$?; set -e + case $? in + 0) ;; + 99) log "BACKUP of $host:$fs SKIPPED by hook"; return 0 ;; + *) log "BACKUP of $host:$fs FAILED (hook returns $?)"; return $? ;; + esac + ## Report the start of this attempt. log "START BACKUP of $host:$fs" @@ -693,11 +735,11 @@ do_backup () { ## Commit this backup. case $dryrun in nil) - backup_precommit_hook $host $fs $date + runhook precommit $host $fs $date mv new $date mv new.fshash $date.fshash insert_index $host $fs $date $VOLUME - backup_commit_hook $host $fs $date + runhook commit $host $fs $date mkdir hack ln -s $date hack/last mv hack/last . @@ -839,9 +881,17 @@ backup () { ###-------------------------------------------------------------------------- ### Configuration functions. +defhook start +defhook end + +done_first_host_p=nil + host () { host=$1 like= userat= + case $done_first_host_p in + nil) runhook start; done_first_host_p=t ;; + esac case "${expire_policy+t},${default_policy+t}" in t,) default_policy=$expire_policy ;; esac @@ -899,6 +949,8 @@ case $# in 0) ;; *) usage >&2; exit 1 ;; esac exec 8>&1 . "$conf" + +runhook end $bkprc case "$bkprc" in 0) $verbose "All backups successful" ;; *) $verbose "Backups FAILED" ;;