Created
May 20, 2015 01:05
-
-
Save rhysrhaven/e77122b878df4f07c86d to your computer and use it in GitHub Desktop.
wrapper around duplicity in bash
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash -eu | |
## Complicity: A wrapper for Duplicity backup tool | |
## Configure, Load into /etc/cron.daily/, done. | |
## Version 1.4 | |
# Base directory Duplicity backs up | |
base_dir='/' | |
# Excluded directories from the base directory. Like /proc. ** is wildcard | |
exclude_dirs=('**') | |
# Directories that will be included even though you excluded them | |
include_dirs=('') | |
# Remote SFTP directory to store encrypted backup files | |
# ssh://user[:password]@other.host[:port]/some_dir | |
remote_dir="ssh://user:password@host.domain/RELATIVEdir" | |
# URL of GPG Public Key to encrypt files with. wget grabs this URL. Is only downloaded the first time. | |
# By default this should be a pub key only. To enable restoring, load the private key into the keyring. | |
# gpg --homedir=/location_to_archive_dir/gpg --import private.key should work | |
key_url='http://host.domain/key' | |
# You can use the same archive directory with multiple instances of this script if you | |
# use separate names for each script. | |
backup_name='Backup1' | |
# Local storage directory, /tmp/complicity is default | |
archive_dir='/tmp/complicity' | |
# This script always does incremental backups. It will make a full backup if it has | |
# been ${cycle_time} since the last full backup. See Duplicity man page, TIME FORMATS. | |
cycle_time='7D' | |
key_id='' | |
filespec='' | |
err() { | |
echo -n "$1" | |
echo ", Exiting." | |
exit 1 | |
} | |
# Sanity checks to make sure directorys are there | |
if [ ! -w "${archive_dir}" ]; then | |
if [ ! -d "${archive_dir}" ]; then | |
mkdir -p "${archive_dir}" || err "Failed to create archive directory" | |
else | |
err "Archive directory is not writable" | |
fi | |
fi | |
if [ ! -d "${archive_dir}/gpg" ]; then | |
mkdir -p "${archive_dir}/gpg" | |
chmod 700 "${archive_dir}/gpg" | |
fi | |
# Download and import backupkey | |
if [ ! -f "${archive_dir}/gpg/backupkey.gpg" ]; then | |
wget -q ${key_url} -O "${archive_dir}/gpg/backupkey.gpg" || err "Failed to download GPG key" | |
gpg -q --homedir "${archive_dir}/gpg" --import "${archive_dir}/gpg/backupkey.gpg" | |
fi | |
# Have to extract KeyID since duplicity uses the GPG keyring to select keys. | |
key_id="$(gpg --with-colons "${archive_dir}/gpg/backupkey.gpg" | grep -E ^pub | cut -d ":" -f5)" | |
# We use our own keyring, sets all parameters passed to duplicity. | |
gpg_params="--gpg-options \"--homedir=${archive_dir}/gpg --trust-model=always\"" | |
duplicity_params="--archive-dir \"${archive_dir}\" --name \"${backup_name}\" --encrypt-key ${key_id} ${gpg_params} --asynchronous-upload --full-if-older-than ${cycle_time}" | |
# properly escape and generate arguments from the include and exclude arrays | |
if [ -n "${include_dirs}" ]; then | |
for dir in "${include_dirs[@]}"; do | |
filespec+="--include \"${dir}\" " | |
done | |
fi | |
if [ -n "${exclude_dirs}" ]; then | |
for dir in "${exclude_dirs[@]}"; do | |
filespec+="--exclude \"${dir}\" " | |
done | |
fi | |
# Deletes any but the most recent full backup and its associated incrementals. | |
#eval duplicity remove-all-but-n-full ${duplicity_params} ${remote_dir} | |
# If this script is called with no arguments, like from cron, it will initiate backup | |
# If you want to use duplicity to manipulate things, all arguments are passed directly. | |
if [ $# -gt 0 ]; then | |
case $1 in | |
backup) | |
eval duplicity incremental ${duplicity_params} ${filespec} ${base_dir} ${remote_dir} | |
;; | |
status) | |
eval duplicity collection-status ${duplicity_params} ${remote_dir} | |
;; | |
list) | |
eval duplicity list-current-files ${duplicity_params} ${remote_dir} | |
;; | |
remove-count) | |
[ $# -gt 1 ] && delete_count=${2} || delete_count='1' | |
eval duplicity remove-all-but-n-full --force ${delete_count} ${duplicity_params} ${remote_dir} | |
;; | |
remove-time) | |
[ $# -gt 1 ] && delete_time=${2} || delete_time=${cycle_time} | |
eval duplicity remove-older-than --force ${delete_time} ${duplicity_params} ${remote_dir} | |
;; | |
restore) | |
[ $# -gt 1 ] && restore_files="$(basename ${2}) --file-to-restore ${2}" || restore_files="${PWD}/${backup_name}" | |
eval duplicity restore ${duplicity_params} ${remote_dir} ${restore_files} | |
;; | |
esac | |
else | |
${0} backup | |
${0} remove-count | |
fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment