#!/bin/bash # for duplicity source build PATH="$PATH:/usr/local/bin" # [--retry] interval_name [max_age] # takes 2 arguments specifying the name of the subfolder, # and optionally, the max age of the backup # this script setup by adding a user crontab. see t.org for the script # it's also setup to email me only when it fails, and only for daily or weekly runs # uncomment for debugging, prints all commands to stdout #set -x set -E #trap 'echo trapped error from \"$BASH_COMMAND\" returned $? line $LINENO; accumulated_errors=true' ERR trap 'echo trapped err: $?; accumulated_errors=true' ERR exec 3>&1 4>&2 exec &>> /tmp/small-backup.log echo "BEGIN: $(date): args $*" # only works with a single letter, ie 2D, not 2D12h half-time() { local time_word local letter=${1##*[0-9]} case $letter in s) time_wrod=second ;; m) time_word=minute ;; h) time_word=hour ;; D) time_word=day ;; W) time_word=week ;; M) time_word=month ;; Y) time_word=year ;; esac echo "${1%%$letter} $time_word" local x=$(date +%s -d "${1%%$letter} $time_word") local y=$(date +%s) } if [[ $1 == --retry ]]; then shift x=0 while pid=( $(pidof -o %PPID -x ${0##*/}) ) && (( ${#pid[@]} > 1 )) && (( x < 20 )); do x=$(( x + 1 )) sleep 30 done if [[ $x == 20 ]]; then ps -F ${pid[@]} echo timeout error: existing ${0##*/} running for over 5 minutes >&2 exit 1 fi else if pid=( $(pidof -o %PPID -x ${0##*/}) ) && (( ${#pid[@]} > 1 )); then echo ps -F ${pid[@]} ps -F ${pid[@]} echo error: existing ${0##*/} running >&2 exit 1 fi fi interval=$1 max_age=$2 full_backup_arg="" if [[ $max_age ]]; then full_backup_arg="--full-if-older-than $(half-time $max_age)" fi rbackup () { local d=$1 shift local dest=root@li::/root/rdiff-backups/${d##*/}/${interval} c="rdiff-backup $* --create-full-path $d $dest" echo "$c"; $c if [[ $max_age ]]; then c="rdiff-backup --force --remove-older-than $max_age $dest" echo "$c"; $c fi } rbackup /a/bin --exclude /a/bin/fai-basefiles rbackup /a/c # this is populated after input_setup.sh is run on login ssh root@li mkdir -p /root/duplicity-backups/p/$interval source /p/duplicity/gpg_agent_env duplicity_dest=rsync://root@li//root/duplicity-backups/p/$interval x=(/p/*) if ((${#x[@]} > 1)); then set -x # archive-dir is sort of a persistent cache duplicity --use-agent \ --encrypt-sign-key E969C67B \ --include-globbing-filelist /p/duplicity/filelist \ --archive-dir /p/duplicity/archive \ --tempdir /p/tmp \ $full_backup_arg /p $duplicity_dest if [[ $max_age ]]; then duplicity --use-agent \ remove-all-but-n-full 2 --force $duplicity_dest fi set +x fi # example restore command. We only need to make the first argument be a url for it to know it to do restore # the archive-dir and tempdir args are not needed # duplicity --use-agent --encrypt-sign-key E969C67B --archive-dir /p/duplicity/archive --tempdir /p/tmp ssh://root@li//root/duplicity-backups/p/weekly /p/duptest echo END # to restore duplicity. see man for additional options # duplicity --use-agent restore ... if [[ $accumulated_error ]]; then eccho "tail -n 50 of /tmp/small-backup.log:" tail -n 50 /tmp/small-backup.log exit 1 fi