blob: 5264970f76923deb713d11fd3abb0b981d7d5459 (
plain)
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
|
#!/bin/bash
default_retain_years=7
retain_years= # TODO: read retain_years from .propagation
use_clock_time= # Delete according to clock time (WARNING: eventually deletes all data)
# Never edit this glob.
# Generated via: date -Ins | sed 's/[0-9]/[0-9]/g'
datetime_glob='[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9],[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]-[0-9][0-9]:[0-9][0-9]'
snapshot_prefix='.snapshot~'
main()
{
delete=
if [ "$1" = --delete ]
then
delete=$1
shift
fi
[ $# = 1 ] || exit
case "$1" in
/*) ;;
*) exit 1 ;;
esac
cd "$1" || exit
find . -maxdepth 1 -type d -name "$snapshot_prefix""$datetime_glob" -print0 | sort -zrn | retain
}
is_readonly_subvolume()
{
[ -d "$1" ]
btrfs subvolume show -- "$1" | sed -En -e'/^\tFlags:.*\breadonly\b/{q0}' -e'${q1}'
}
btrfs_subvolume_delete()
{
if [ "$delete" = --delete ]
then
btrfs subvolume delete "$@"
else
>&2 echo btrfs subvolume delete "$@"
fi
}
# Delete all snapshots that we do not retain.
# The retention period is specified in a ".propagation" file.
# If not specified it is 7 years.
# Retain the most recent snapshot within any year of the last 7 years.
# Retain the most recent snapshot within any month of the last 365 days.
# Retain the most recent snapshot within any day of the last 15 days.
# Retain the most recent snapshot within any hour of the last 24 hours.
# Retain the most recent snapshot within any minute of the last hour.
# Retain any snapshot created in the last minute.
retain()
{
2>/dev/null [ "$retain_years" -ge 1 ] || retain_years=$default_retain_years
_year= _month= _day= _hour= _minute= _second= _nanosecond=
now= first=y
if [ "$use_clock_time" ]
then
now=$(date +%s)
fi
while read -d '' line
do
is_readonly_subvolume "$line" || break
dateline=${line#*/"$snapshot_prefix"}
[ "$dateline" != "$line" ]
before=$(date -d "$dateline" +%s)
[ "$now" ] || now=$before
age=$((now - before))
IFS='~-T:,' read year month day hour minute second nanosecond <<< "$dateline"
keep=
if [ "$first" ]
then
keep="latest -> $line"
first=
elif [ "$year" != "$_year" ] && [ "$age" -lt $((retain_years * 366 * 24 * 60 * 60)) ]
then
keep="$year -> $line"
elif [ "$month" != "$_month" ] && [ "$age" -lt $((366 * 24 * 60 * 60)) ]
then
keep="$year-$month -> $line"
elif [ "$day" != "$_day" ] && [ "$age" -lt $((15 * 24 * 60 * 60)) ]
then
keep="$year-$month-$day -> $line"
elif [ "$hour" != "$_hour" ] && [ "$age" -lt $((24 * 60 * 60)) ]
then
keep="$year-$month-${day}T$hour -> $line"
elif [ "$minute" != "$_minute" ] && [ "$age" -lt $((60 * 60)) ]
then
keep="$year-$month-${day}T$hour:$minute -> $line"
elif [ "$age" -lt 60 ]
then
keep="recent -> $line"
fi
if [ "$keep" ]
then
(set -- $keep
printf '%-20s -> %s\n' "$1" "$3" >&2)
else
btrfs_subvolume_delete -- "$line"
fi
_year=$year
_month=$month
_day=$day
_hour=$hour
_minute=$minute
_second=$second
done
}
main "$@"
|