Draft ZFS snapshot utility
[dotfiles.git] / bin / bin / zsnap.zsh
1 #!/bin/zsh -e
2
3 usage() {
4 cat <<EOF
5 Usage: $0 DATASET@SNAPPREFIX snap-initial
6        $0 DATASET@SNAPPREFIX snap
7        $0 DATASET@SNAPPREFIX sync-initial DST
8        $0 DATASET@SNAPPREFIX sync DST
9        $0 DATASET@SNAPPREFIX clean COUNT
10 EOF
11 exit 1
12 }
13
14 enccmd="gpg --compress-level 0 --encrypt --recipient offline --cipher-algo AES-128"
15
16 [ $# -ge 2 ] || usage
17
18 what="$1"
19 action="$2"
20
21 now=$(date "+%Y%m%d%H%M")
22 snaps=$(zfs list -t snap -d 1 -o name -H | grep $what | sort -nr)
23 latest=$(echo $snaps | sed -n 1p)
24
25 case "$action" in
26     snap-initial)
27         zfs snap -r $what-$now
28         echo $what-$now
29         ;;
30     snap)
31         [ -n "$latest" ]
32         [ "$what-$now" != "$latest" ]
33         zfs snap -r $what-$now
34         echo $what-$now
35         ;;
36     sync-initial)
37         dst="$3"
38         [ -d "$dst" ] || usage
39         set PIPE_FAIL
40         zfs send -Rv $latest | zstd | ${=enccmd} > $dst/$latest.zfs.zst.gpg
41         sync
42         touch $dst/$latest.from
43         ;;
44     sync)
45         dst="$3"
46         [ -d "$dst" ] || usage
47         latest_dst=$(find $dst -type f -name "*.from" | sort -rn | sed -n 1p)
48         [ -n "$latest_dst" ]
49         latest_dst=$(basename ${latest_dst%.from})
50         [ "$latest_dst" != "$latest" ]
51         set PIPE_FAIL
52         zfs send -Rv -i $latest_dst $latest | zstd | ${=enccmd} > $dst/$latest.zfs.zst.gpg
53         sync
54         echo "$latest_dst" > $dst/$latest.from
55         ;;
56     clean)
57         count="$3"
58         [ -n "$count" ] || usage
59         count=$(( $count + 1 ))
60         for snap in $(echo $snaps) ; do
61             count=$(( $count - 1 ))
62             [ $count -le 0 ] || continue
63             zfs destroy -Rv $snap
64         done
65         ;;
66     *)
67         usage
68         ;;
69 esac