diff --git a/backup-tar/backup.sh b/backup-tar/backup.sh index ac1bc7918ccb56078e0c215278b546637c9061f1..c36972d73219accb15f6e280f4612b0eb99c78fa 100755 --- a/backup-tar/backup.sh +++ b/backup-tar/backup.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -set -e +set -Eeuo pipefail SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" @@ -13,7 +13,7 @@ fail() { exit 1 } -if [[ $1 ]]; then +if [[ ${1:-} ]]; then . $1 [[ $WORK_DIR ]] && mkdir -p $WORK_DIR && cd $WORK_DIR else @@ -22,12 +22,13 @@ else SOURCES_FILE=$SCRIPT_DIR/sources_$SHORT_HOST . $SOURCES_FILE fi -[[ $TARGET ]] || fail "TARGET expected to be set in config" -[[ $SOURCES ]] || fail "SOURCES expected to be set in $SOURCES_FILE or config" +[[ ${TARGET:-} ]] || fail "TARGET expected to be set in config" +[[ ${SOURCES:-} ]] || fail "SOURCES expected to be set in $SOURCES_FILE or config" TIMESTAMP=$(date +"%Y-%m-%d") mkdir lock || fail "ERROR: backup already in progress (lock dir exists)" -trap "rmdir lock" EXIT +function trap_global { rmdir lock; } +trap trap_global EXIT get_snars() { find $1/ -type f -name '*.snar' -printf '%f\n' | sort; } get_type() { @@ -91,20 +92,28 @@ for SRC in $SOURCES; do fi ssh $TARGET "mkdir -p stamps/${SRC_ID} ${SRC_ID}" - [[ "$TYPE" != "daily" ]] && echo "Backup $SRC ($TYPE)…" + + function trap_local { + ssh $TARGET "rm -f $BACKUP_FILE.tmp $INCFILE.tmp" + rm -f $INCFILE_TMP + trap_global + } + trap trap_local EXIT; + + echo "Backup $SRC ($TYPE)…" { { tar --create --xattrs --acls --listed-incremental=$INCFILE_TMP $SRC | \ xz -T$COMPRESS_THRS -3 | \ - ssh $TARGET "umask 0027; cat > $BACKUP_FILE" + ssh $TARGET "umask 0027; cat > $BACKUP_FILE.tmp" } 3>&1 1>&2 2>&3 | \ { grep -v "Removing leading \`/'" || true; } | \ { grep -v "socket ignored" || true; } } 3>&1 1>&2 2>&3 - xz -T$COMPRESS_THRS --keep --stdout $INCFILE_TMP | ssh $TARGET "umask 0027; cat > $INCFILE_TGT" + xz -T$COMPRESS_THRS --keep --stdout $INCFILE_TMP | ssh $TARGET "umask 0027; cat > $INCFILE_TGT.tmp" if echo $SRC | grep -q '^/home'; then USR=$(echo $SRC | sed 's|^/home/\([^/]*\).*$|\1|') - ssh $TARGET "setfacl -m 'u:$USR:r' $BACKUP_FILE" + ssh $TARGET "setfacl -m 'u:$USR:r' $BACKUP_FILE.tmp" DIR=$(dirname $BACKUP_FILE) while true; do ssh $TARGET "setfacl -m 'u:$USR:rx' $DIR" @@ -112,5 +121,7 @@ for SRC in $SOURCES; do DIR=$(dirname $DIR) done fi + ssh $TARGET "mv $BACKUP_FILE{.tmp,}; mv $INCFILE_TGT{.tmp,}" + trap trap_global EXIT mv $INCFILE_TMP $INCFILE done