From 9ea54ae09053d94cad41724c806633c38cb90ae4 Mon Sep 17 00:00:00 2001 From: Gabriel Scherer Date: Sat, 24 Mar 2018 18:40:46 +0100 Subject: [PATCH] a backup script to send backups over email when changed This is a home-grown backup script that I built for a local HotCRP installation, but I thought that it may be useful to others as well. The backup strategy is as follows: - a backups/ directory at the project root with at most two backups saved, the last one (`new`) and the one before that (`old`) - whenever the script runs, it moves `new` to `old` and creates a new `new` file using the `backupdb.sh` script; then it compares `new` and `old`, and sends the new backup by email if it differs from the old one - if a `passphrase` file exists in the `backups` directory, then it is used as a passphrase for `gpg` to encrypt the backup file Finally, note that we are careful to pass `--skip-dump-date` to `mysqldump`, otherwise the backups would always differ. The script is careful to `cd` to its base directory, so that it can be invoked directly from a crontab. --- lib/mail-backup-if-new.sh | 79 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 lib/mail-backup-if-new.sh diff --git a/lib/mail-backup-if-new.sh b/lib/mail-backup-if-new.sh new file mode 100644 index 0000000000..62b6778364 --- /dev/null +++ b/lib/mail-backup-if-new.sh @@ -0,0 +1,79 @@ +#!/bin/bash + +# backups/ has special 'new' and 'old' symbolic links to the last +# backup and the one-before-last backup. We use them to check whether +# the new backup is identical to the previous backup. If it isn't, we +# send an email with the backup. + +# If a backups/passphrase file exists, its content is used as a +# passphrase to encrypt the backup file before sending it by email. + +# we assume the script is in the 'lib/' directory of a HotCRP install, +# move to the root of the project before running the code +cd "$( dirname "${BASH_SOURCE[0]}" )"/.. + +BACKUP=backup-$(date +%F-%T).txt +PASSPHRASE_FILE=passphrase + +if [ -z "$BACKUP_EMAIL" ] +then + echo "You must define a BACKUP_EMAIL environment variable" + echo "with the email address to send backups to." + exit 2 +fi + +dump () { + # --skip-dump-date is necessary, otherwise a timestamp + # is included in the backup and the files always differ + ./lib/backupdb.sh --skip-dump-date > backups/$BACKUP +} + +# assumes that 'dump ()' ran and that we are in 'backups' +init () { + ln -s old $BACKUP + ln -s new $BACKUP +} + +# assumes that 'dump ()' ran and that we are in 'backups' +age () { + rm $(readlink old) + mv new old + ln -s $BACKUP new +} + +email () { + echo "New backup $(readlink new) differs from $(readlink old), so it is attached" \ + | mailx -s "[hotcrp-mlocaml2017-postproceedings] new backup" -a $BACKUP_FILE $BACKUP_EMAIL +} + +# assumes that 'dump ()' ran and that we are in 'backups' +email_if_changed () { + echo "comparing the new backup $BACKUP and the previous one $(readlink old)" + cmp new old && exit 0 + + if [[ -f $PASSPHRASE_FILE ]] + then + echo "encrypting the backup according to backups/$PASSPHRASE_FILE" + gpg --batch --passphrase-file $PASSPHRASE_FILE --symmetric $BACKUP + BACKUP_FILE=$BACKUP.gpg + email + rm $BACKUP_FILE + else + BACKUP_FILE=$BACKUP + email + fi +} + +mkdir_if_missing () { + if [[ ! -d backups ]] + then + mkdir -p backups + init + fi +} + +dump +cd backups +age +email_if_changed +