]> Sergey Matveev's repositories - dotfiles.git/blob - bin/bin/zsnap
90d08f641b3d4dd2d997b189cddc0bd0a51754a5
[dotfiles.git] / bin / bin / zsnap
1 #!/usr/bin/env zsh
2
3 set -e
4 setopt EXTENDED_GLOB
5
6 usage() {
7     cat <<EOF
8 Usage: $0 DATASET@SNAPPREFIX snap-initial
9        $0 DATASET@SNAPPREFIX snap
10        $0 DATASET@SNAPPREFIX sync-initial DST
11        $0 DATASET@SNAPPREFIX sync DST
12        $0 DATASET@SNAPPREFIX clean COUNT
13        FIFO=1
14 EOF
15     exit 1
16 }
17
18 mk_fifo() {
19     [[ -z $FIFO ]] || {
20         mkfifo $dst/$latest_filename.zfs.zst.age
21         echo $dst/$latest_filename.zfs.zst.age
22     }
23 }
24
25 enccmd=(~stargrave/bin/age -R /home/stargrave/.age/general.pub)
26
27 [[ $# -ge 2 ]] || usage
28
29 what=$1
30 action=$2
31
32 zmodload -F zsh/datetime b:strftime
33 now=$(strftime %Y%m%d%H%M)
34 [[ $what =~ / ]] && depth=1 || depth=${#${(s./.)what}}
35 snaps=$(zfs list -t snap -d $depth -o name -H | grep $what | sort -nr)
36 snaps=(${(f)snaps})
37 latest=${snaps[1]}
38 latest_filename=${latest:gs#/#%}
39 dst=$3
40
41 case $action in
42     snap-initial)
43         zfs snap -r $what-$now
44         print $what-$now
45         ;;
46     snap)
47         [[ -n $latest ]]
48         [[ "$what-$now" != $latest ]]
49         zfs snap -r $what-$now
50         print $what-$now
51         ;;
52     sync-initial)
53         [[ -d $dst ]] || usage
54         mk_fifo
55         setopt PIPE_FAIL
56         zfs send -Rwv $latest | zstdmt | $enccmd > $dst/$latest_filename.zfs.zst.age
57         sync
58         touch $dst/$latest_filename.from
59         ;;
60     sync)
61         [[ -d $dst ]] || usage
62         mk_fifo
63         latest_dst=($dst/*.from~$dst/.*(.Onn[1]))
64         [[ $latest_dst ]]
65         latest_dst=${latest_dst[1]}
66         latest_dst=${${latest_dst##*/}%.from}
67         [[ $latest_dst != $latest_filename ]]
68         setopt PIPE_FAIL
69         set -x
70         zfs send -Rwv -i ${latest_dst:gs#%#/} $latest | zstdmt | $enccmd > \
71             $dst/$latest_filename.zfs.zst.age
72         set +x
73         sync
74         print $latest_dst > $dst/$latest_filename.from
75         ;;
76     clean)
77         count=$3
78         [[ -n $count ]] || usage
79         count=$(( $count + 1 ))
80         for snap in $snaps ; do
81             count=$(( $count - 1 ))
82             [[ $count -le 0 ]] || continue
83             zfs destroy -Rv $snap
84         done
85         ;;
86     *)
87         usage
88         ;;
89 esac