chiark / gitweb /
rsync-backup.{in,8}: Introduce `hook' concept.
authorMark Wooding <mdw@distorted.org.uk>
Thu, 16 Jan 2014 09:51:56 +0000 (09:51 +0000)
committerMark Wooding <mdw@distorted.org.uk>
Thu, 16 Jan 2014 10:13:50 +0000 (10:13 +0000)
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.

rsync-backup.8
rsync-backup.in

index 0710158e404a67256b2d01cec83459f7458afc2f..04a489a0285f99c5ca72e894b654a6fb64315628 100644 (file)
@@ -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
index 67d0efb34641a16bbcf9e64ad352359a14db2b52..e232bc8d766ed51ef85ad84dee64e44db3731799 100644 (file)
@@ -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" ;;