For many years I relied upon rdiff-backup to securely backup all my servers and desktop machines, including routers, laptops, etc. Sadly, the rdiff-backup project was abandoned, and the search for a replacement began in earnest. Luckily, a similar (and better) replacement exists: Duplicity!
Like rdiff-backup, duplicity is best operated by a wrapper script from a cron job, to keep everything running in a smooth and automatic fashion. To this end, I’ve updated my rdiff-backup Bash wrapper script to use duplicity instead. The script takes care of process locking and excluding files which shouldn’t go into the archive. In hopes it’ll be useful to someone, you can download it, or view it:
#!/bin/bash # VERSION=1.1.0 # 2015/01/05 # # Please do not put spaces in the name of this script, # the lock file is based on $0 and spaces break things. # # You will want something like this in ~/.ssh/config, where the virtual host # name corresponds to the NAME variable below: # # Host my-backup # Hostname backupserver.my.lan # User backup # Identityfile /root/.ssh/id_rsa_my-backup # Compression yes # Protocol 2 # # # # Changelog: # # 2015/01/05 - Aaron Ten Clay # Add '/root/.cache/duplicity' as the explicit cache path # Add '/root/.cache/duplicity' to default exclusionlist # Used 'NAME' variable in backup path # Added default 'full if older than 4 months' argument # # 2014/05/13 - Aaron Ten Clay # Add '/mnt' to default exclusionlist, again. Should not have been removed. # # 2014/03/27 - Aaron Ten Clay # Changed to duplicity since rdiff-backup is now unmaintained # # 2011/09/05 - Aaron Ten Clay # Corrected output redirection and added filtering for harmless error messages # # 2011/04/10 - Aaron Ten Clay # Updated order of include/exclude arguments to capture kernel config # Added output filtering via Grep to ignore SpecialFileError messages # # 2009/07/20 - Aaron Ten Clay # Added rudimentary version checking # # 2009/02/21 - Aaron Ten Clay # Fixed spelling error # # 2009/01/20 - Aaron Ten Clay # Repaired grammar in error messages # # 2009/01/17 - Aaron Ten Clay # Repaired remote version error message # # Quick customization parameters NAME="my-backup" TARGET="rsync://${NAME}/root" PASSPHRASE="super-secret-passphrase-here" # Main script function check_script_version { latest=$(wget --no-check-certificate -qO- "http://10.43.101.63:24469/projects/duplicity-wrapper-script/version-check?version=${VERSION}") if [[ "x${latest}" == "x" ]]; then echo "Notice: Version check failed" else if [[ "${latest}" != "latest" ]]; then echo "Notice: Version check returned: ${latest}" fi fi } function sigcaught () { rm -f "$lockfile" echo "Error: caught interrupt" >&2 exit 2 } # Here begins the actual work # Exit if using uninitialized variable set -o nounset check_script_version lockfile="/tmp/$(basename $0).pid" if ( set -o noclobber; echo "$" > "$lockfile") 2> /dev/null; then trap sigcaught INT TERM EXIT export PASSPHRASE duplicity \ --full-if-older-than 4M \ --archive-dir /root/.cache/duplicity \ --exclude /root/.cache/duplicity \ --exclude /dev \ --exclude /media \ --exclude /mnt \ --exclude /opt \ --exclude /proc \ --exclude /sys \ --exclude /tmp \ --exclude /usr/portage \ --exclude /usr/tmp \ --include /usr/src/linux/.config \ --exclude /usr/src \ --exclude /var/cache \ --exclude /var/log \ --exclude /var/tmp \ --asynchronous-upload \ --name "${NAME}" \ --no-print-statistics \ --volsize 100 \ $* \ "/" \ "${TARGET}" \ 2>&1 rm -f "$lockfile" trap - INT TERM EXIT else echo "Error: Failed to acquire lockfile: $lockfile, held by PID $(cat $lockfile)" >&2 fi