106 lines
3.1 KiB
Python
Executable File
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:
|