snap.push.single (1891B)
1 #!/bin/sh 2 : ${SNAP_SRC:=.} 3 4 usage() { 5 printf >&2 "Usage: %s: [-S SNAP_SRC] [-D SNAP_DST] [-] [RSYNC_ARGS]\n" $(basename "$0") 6 exit 2 7 } 8 9 die() { 10 printf "%s" "$*" 11 exit 1 12 } 13 14 while getopts S:D: opt; do 15 case $opt in 16 (S) SNAP_SRC=$OPTARG;; 17 (D) SNAP_DST=$OPTARG;; 18 (?) usage;; 19 (h) usage;; 20 esac 21 done 22 shift $(($OPTIND - 1)) 23 24 case $1 in 25 (-) shift;; 26 (--) shift;; 27 esac 28 29 if test -z "$SNAP_DST"; then 30 echo >&2 "SNAP_DST is required either as env var or argument" 31 usage 32 fi 33 34 : ${SNAP_WRITESRC:=$SNAP_SRC} 35 36 check_local() { 37 for m in $SNAP_WRITESRC/.snapshot.[0-9]*; do 38 test -f "$m" || continue 39 test -n "$mark" && die "duplicate snapshot mark" 40 mark=$m 41 done 42 43 test -f "$mark" || die "snapshot mark not found" 44 ts=${mark##*.} 45 } 46 47 check_remote() { 48 snap.list "$SNAP_SRC/" | while read m; do 49 test -n "$ts" && die "duplicate snapshot mark" 50 ts=$m 51 done 52 test -n "$ts" || die "snapshot mark not found" 53 } 54 55 rs() { 56 rsync -aA --delete $RSYNC_ARGS "$@" 57 } 58 59 push_remote() { 60 # remote 61 case "$SNAP_DST" in 62 (*.push) ;; 63 (*) SNAP_DST=${SNAP_DST}.push;; 64 esac 65 rs "$@" --exclude=/${mark##*/} "$SNAP_SRC/" "$SNAP_DST/" && \ 66 rs "$@" "$SNAP_WRITESRC/${mark##*/}" "$SNAP_DST/" 67 } 68 69 push_local() { 70 test -d "$SNAP_DST" || die "destination not a directory: ${SNAP_DST}" 71 snapshot=$(snap.list "$SNAP_DST/" | tail -1) 72 if test -n "$snapshot"; then 73 link=${SNAP_DST}/${snapshot} 74 mkdir -p "${SNAP_DST}/batch" || exit $? 75 rs "$@" --write-batch="${SNAP_DST}/batch/${snapshot}-$ts" "--link-dest=$link/" "$SNAP_SRC/" "$SNAP_DST/$ts/" || exit $? 76 else 77 rs "$@" "$SNAP_SRC/" "$SNAP_DST/$ts/" || exit $? 78 fi 79 touch "${SNAP_DST}/${mark##*/}" 80 } 81 82 case "$SNAP_SRC" in 83 (*:*) check_remote;; 84 (*) check_local;; 85 esac 86 87 case "$SNAP_DST" in 88 (rsync:*) push_remote "$@";; 89 (*::*) push_remote "$@";; 90 (*:*) die "pushing via remote shell directly not supported, use -e with rsync:// instead";; 91 (*) push_local "$@";; 92 esac