-
Notifications
You must be signed in to change notification settings - Fork 0
/
snap_cleaner.py
executable file
·83 lines (62 loc) · 2.56 KB
/
snap_cleaner.py
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
#!/usr/bin/python
import argparse
import datetime
import glob
import sys
from subprocess import call
FIRST_STAGE = 30
SECOND_STAGE = 365
SNAP_PATH = '/home/.snapshots'
SNAP_FORMAT = '%Y-%m-%d-%H-%M'
parser = argparse.ArgumentParser(description='''Removes btrfs subvolumes/snapshots according to the following logic:
1: Keep one snapshot per month for snapshots that are older than %s days
2: Keep one snapshot per week for snapshots that are older than %s days''' % (SECOND_STAGE, FIRST_STAGE))
parser.add_argument('--snapshot-path', dest='snap_path', type=str, default=SNAP_PATH,
help='Path with the btrfs snapshots/subvolumes.')
parser.add_argument('--snapshot-name-format', dest='snap_format', type=str, default=SNAP_FORMAT,
help='Name format of the snapshot/subvolumes.')
parser.add_argument('--dry-run', action='store_true')
args = parser.parse_args()
def put_in_bucket(bucket, snapshot_name, first, second):
if first not in bucket:
bucket[first] = {}
if second not in bucket[first]:
bucket[first][second]=[]
bucket[first][second].append(snapshot_name)
return bucket
def get_to_delete(snapshots):
to_delete = []
for year, bucket in snapshots.items():
for values in bucket.values():
values.sort()
values.pop()
to_delete.extend(values)
return to_delete
def delete_snapshots(snapshots, dry):
for s in snapshots:
print "Deleting snapshot %s" % s
if dry:
print "Noop"
else:
call(['/bin/btrfs', 'subvolume', 'delete', s])
def main(args):
monthly_buckets = {}
weekly_buckets = {}
now = datetime.datetime.now()
filenames = sorted(glob.glob(args.snap_path + '/*'))
for filename in filenames:
snapshot_time = None
try:
snapshot_time = datetime.datetime.strptime(filename.split('/')[-1], args.snap_format)
except:
continue
else:
delta = now - snapshot_time
if delta.days > SECOND_STAGE:
monthly_buckets = put_in_bucket(monthly_buckets, filename, snapshot_time.year, snapshot_time.month)
elif delta.days > FIRST_STAGE:
weekly_buckets = put_in_bucket(weekly_buckets, filename, snapshot_time.year, snapshot_time.isocalendar()[1])
delete_snapshots(get_to_delete(monthly_buckets))
delete_snapshots(get_to_delete(weekly_buckets))
if __name__ == "__main__":
main(args)