routerbackup/backup_diff

106 lines
3.1 KiB
Python
Executable File

#!/usr/bin/env python3
import argparse
import os
import re
import glob
import difflib
import datetime
def get_args():
parser = argparse.ArgumentParser(
description='backup_diff - show differences')
parser.add_argument('-H', '--host',
required=True,
action='store',
help='host name, used also as backup filename base ')
parser.add_argument('-o', '--backupdir',
required=True,
action='store',
help='backup directory')
parser.add_argument('nums',
nargs='*',
action='store',
type=int,
help='create diff between versions')
args = parser.parse_args()
return args
def find_backups(backupdir, host):
basepath = f'{backupdir}/{host}'
backups = []
for fn in sorted(glob.glob(f'{basepath}+*/*.lastchange')):
if m := re.search('\+(\d{4}-\d{2}-\d{2})_(\d\d)(\d\d)(\d\d)', fn):
moved = f'{m[1]} {m[2]}:{m[3]}:{m[4]}'
else:
moved = '(undef)'
with open(fn, 'r') as f:
lastchange = f.readlines()[-1].rstrip()
backups.insert(0, {
'since': lastchange,
'until': moved,
'cfn': re.sub('\.lastchange', '.config', fn)
})
try:
with open(f'{basepath}.lastchange', 'r') as f:
lastchange = f.readlines()[-1].rstrip()
except:
pass
try:
info = os.stat(basepath +'.config')
mtime = datetime.datetime.fromtimestamp(info.st_mtime).strftime('%F %H:%M:%S (latest)')
except:
pass
backups.insert(0, {
'since': lastchange or '???',
'until': mtime or '???',
'cfn': f'{basepath}.config'
})
return backups
def diff(backups, host, n1, n2):
contents = []
name = []
for i in (n1, n2):
if i >= len(backups):
i = len(backups) - 1
if i < 0:
i = 0
with open(backups[i]['cfn']) as f:
contents.append(f.readlines())
name.append(f"[{i:3}] {host} | {backups[i]['since']} - {backups[i]['until']}")
differ = False
for line in difflib.unified_diff(
contents[0], contents[1],
fromfile=name[0], tofile=name[1]
):
print(line.rstrip())
differ = True
if not differ:
print(f'--- {name[0]}')
print(f'+++ {name[1]}')
print('no difference')
def main():
args = get_args()
backups = find_backups(args.backupdir, args.host)
if not len(backups):
print(f'No backups found for host: {args.host}')
exit(1)
if len(args.nums) == 1:
diff(backups, args.host, args.nums[0], 0)
elif len(args.nums) > 1:
diff(backups, args.host, args.nums[0], args.nums[1])
else:
for i in range(len(backups)-1, -1, -1):
print(f"{i:3}: {backups[i]['since']} - {backups[i]['until']}")
if __name__ == "__main__":
main()
# vim: set ft=python tabstop=4 shiftwidth=4 expandtab smarttab: