58 lines
1.8 KiB
Text
58 lines
1.8 KiB
Text
|
#!/usr/bin/env python3
|
||
|
|
||
|
|
||
|
import re
|
||
|
|
||
|
from datetime import datetime
|
||
|
from json import loads
|
||
|
from subprocess import check_call, check_output
|
||
|
from sys import argv
|
||
|
|
||
|
|
||
|
def create_snap_and_rotate(ds, label, retain, now, all_snapshots):
|
||
|
new_snap = '{}@zfs-auto-snap_{}-{}'.format(ds, label, now)
|
||
|
check_call(['zfs', 'snapshot', new_snap])
|
||
|
|
||
|
prefix = '{}@zfs-auto-snap_{}-'.format(ds, label)
|
||
|
my_candidates = []
|
||
|
for i in sorted(all_snapshots):
|
||
|
if i.startswith(prefix):
|
||
|
my_candidates.append(i)
|
||
|
|
||
|
my_candidates.append(new_snap)
|
||
|
|
||
|
for i in my_candidates[:-retain]:
|
||
|
assert '@' in i, 'BUG! Dataset "{}" has no @!'.format(i)
|
||
|
check_call(['zfs', 'destroy', i])
|
||
|
|
||
|
|
||
|
label = argv[1]
|
||
|
|
||
|
with open('/etc/zfs-snapshot-config.json', 'r') as fp:
|
||
|
metadata = loads(fp.read())
|
||
|
|
||
|
if 'snapshot_only' in metadata:
|
||
|
datasets = set(metadata['snapshot_only'])
|
||
|
else:
|
||
|
output = check_output(['zfs', 'list', '-H', '-o', 'name']).decode('UTF-8')
|
||
|
datasets = set(output.splitlines())
|
||
|
|
||
|
for pattern in metadata.get('snapshot_never', set()):
|
||
|
datasets = set(filter(lambda x: not re.search(pattern, x), datasets))
|
||
|
|
||
|
default_retain = metadata['retain_defaults'][label]
|
||
|
now = datetime.now().strftime('%F-%H%M')
|
||
|
snapshots_created = False
|
||
|
|
||
|
if datasets:
|
||
|
all_snapshots = check_output(['zfs', 'list', '-H', '-o', 'name', '-t', 'snap']).decode('UTF-8').splitlines()
|
||
|
|
||
|
for ds in datasets:
|
||
|
retain = int(metadata.get('retain_per_dataset', {}).get(ds, {}).get(label, default_retain))
|
||
|
if retain > 0:
|
||
|
create_snap_and_rotate(ds, label, retain, now, all_snapshots)
|
||
|
snapshots_created = True
|
||
|
|
||
|
with open('/var/tmp/zfs-auto-snapshot.status', 'w') as fp:
|
||
|
fp.write('{}\n'.format(datetime.now().strftime('%s') if snapshots_created else 0))
|