-
Notifications
You must be signed in to change notification settings - Fork 4
/
cleansnaps.sh
163 lines (141 loc) · 3.81 KB
/
cleansnaps.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
#! /bin/sh
pr_aufruf() {
cat <<ENDE
Aufruf: $(basename $0) [-htf] [-k keep] <Datasetfilter> [Snapshotfilter]
-h Hilfe Anzeigen
-t Testmodus. Simulation von löschen ohne Nachfragen (benötigt -k)
-f Echtmodus. Snapshots löschen ohne Nachfragen (benötigt -k)
-k <Anzahl> Anzahl der letzten Snapshots die behalten werden sollen.
Rest wird gelöscht. Ohne -t oder -f kommt Abfrage ob gelöscht werden soll.
ENDE
}
# Defaults:
# Modi: fragen (default), test (-t) oder echt (-f)
MODUS="fragen"
while getopts ":htfk:" opt
do
case $opt in
h) pr_aufruf
exit 0
;;
t) MODUS="test"
TFLAG="1"
;;
f) MODUS="echt"
FFLAG="1"
;;
k) BEHALTE="$OPTARG"
KFLAG="1"
;;
\?) echo "Unbekannte Option: -$OPTARG" 1>&2;;
:) echo "Fehler Option: -$OPTARG benötigt ein Argument" 1>&2;;
esac
done
shift $((OPTIND -1))
# Mit der Filter Variable kannst du die Liste der datasets beschränken
# Mit der Muster Variable kann man Snapshots nach Muster Filtern
FILTER="$1"
MUSTER="$2"
if [ "$1" = "" -o $# -gt 2 ]
then
pr_aufruf
exit 1
fi
if [ "$FFLAG" = "1" -a "$TFLAG" = "1" ]
then
echo "Option -f oder -t können nicht zusammen verwendet werden."
pr_aufruf
exit 1
elif [ "$FFLAG" -o "$TFLAG" ] && [ "$KFLAG" != "1" ]
then
echo "Option -t oder - f nur zusammen mit -k nutzbar"
pr_aufruf
exit 1
fi
# Prüfen das Behalte eine Zahl >= 0 ist
if [ "$KFLAG" = "1" ]
then
[ $BEHALTE -ge 0 ] 2>/dev/null
if [ "$?" != "0" ]
then
echo "Option -k keine pos. Zahl"
pr_aufruf
exit 1
fi
fi
ZFSSETLIST=$(zfs list | grep "$FILTER" | awk '{print $1}')
echo "# Gefilterte Datasets:"
zfs list | grep -e "$FILTER" -e NAME | sed 's/^/ /'
echo ""
for DATASET in $ZFSSETLIST
do
echo "# Dataset: $DATASET"
echo "# Snapfilter: $MUSTER"
if [ "$MUSTER" = "" ]
then
SNAPS=$(zfs list -r -t snap -H -o name -s creation | grep "${DATASET}@")
else
SNAPS=$(zfs list -r -t snap -H -o name -s creation | grep "${DATASET}@" | grep $MUSTER)
fi
ANZSNAPS=$(echo "$SNAPS"|grep -v "^$"|wc -l|sed 's, ,,g')
echo "# Anzahl Snaps: $ANZSNAPS"
if [ "$KFLAG" = "1" ]
then
DELSNAPS=$((ANZSNAPS - BEHALTE))
echo "# Behalte: $BEHALTE"
echo "# Anzahl Del. Snaps: $(if [ $DELSNAPS -lt 0 ];\
then echo 0;else echo $DELSNAPS;fi)"
else
DELSNAPS="0"
BEHALTE="$ANZSNAPS"
fi
echo "# Liste Snaps:"
echo "$SNAPS" |sed '/^$/d' | awk -v dellines=$DELSNAPS '{
if (NR <= dellines){
printf(" - %s\n",$0)
}
else {
printf(" + %s\n",$0)
}
}'
[ $DELSNAPS -gt 0 -o "$KFLAG" != "1" ] 2>/dev/null
if [ "$?" != "0" ]
then
echo "% Keine Snapshots zum löschen"
echo ""
continue
fi
if [ $DELSNAPS -gt 0 ]
then
if [ "$MODUS" = "fragen" ]
then
printf "> Snapshots (%d von %d) mit J löschen (Return = weiter): " $DELSNAPS $ANZSNAPS
read ZDESTROY
elif [ "$MODUS" = "echt" ]
then
ZDESTROY="J"
else
ZDESTROY="N"
echo "# Testmodus - Für folgende Snapshots würde ein destroy ausgeführt:"
echo "$SNAPS" | head -n $DELSNAPS | xargs -n 1 zfs get -H creation | sed 's/^/ /'
echo ""
continue
fi
if [ "$ZDESTROY" = "J" ]
then
echo "% zfs destroy wird ausgeführt:"
echo "$SNAPS" | head -n $DELSNAPS | xargs -n 1 zfs destroy -v | sed 's/^/ /'
echo "% Liste nach zfs destroy:"
if [ "$MUSTER" = "" ]
then
zfs list -r -t snap -o name -s creation | grep "${DATASET}@" | sed 's/^/ + /'
else
zfs list -r -t snap -o name -s creation | grep "${DATASET}@" | grep $MUSTER | sed 's/^/ + /'
fi
else
echo "% Es wurden keine Snapshots gelöscht"
fi
fi
echo ""
done
exit 0