From f1676439805d8ce088599d55fa6e6a76d0633e7f Mon Sep 17 00:00:00 2001 From: cronekorkn Date: Thu, 2 Mar 2023 18:20:10 +0100 Subject: [PATCH] backup-freshness-check: check local and offsite backup --- .../files/check_backup_freshness | 10 +++--- bundles/backup-freshness-check/items.py | 15 ++++++++ bundles/backup-freshness-check/metadata.py | 36 +++++++++++++++++++ bundles/backup-server/items.py | 12 ------- bundles/backup-server/metadata.py | 32 ----------------- groups/applications/backup-server.py | 1 + nodes/wb.offsite-backups.py | 5 +++ 7 files changed, 63 insertions(+), 48 deletions(-) rename bundles/{backup-server => backup-freshness-check}/files/check_backup_freshness (82%) create mode 100644 bundles/backup-freshness-check/items.py create mode 100644 bundles/backup-freshness-check/metadata.py delete mode 100644 bundles/backup-server/items.py diff --git a/bundles/backup-server/files/check_backup_freshness b/bundles/backup-freshness-check/files/check_backup_freshness similarity index 82% rename from bundles/backup-server/files/check_backup_freshness rename to bundles/backup-freshness-check/files/check_backup_freshness index a8cb859..f683b36 100644 --- a/bundles/backup-server/files/check_backup_freshness +++ b/bundles/backup-freshness-check/files/check_backup_freshness @@ -8,13 +8,13 @@ from datetime import datetime, timedelta now = datetime.now() two_days_ago = now - timedelta(days=2) -with open('/etc/backup-server.json', 'r') as file: - conf = json.load(file) +with open('/etc/backup-freshness-check.json', 'r') as file: + config = json.load(file) local_datasets = check_output(['zfs', 'list', '-H', '-o', 'name']).decode().splitlines() errors = set() -for dataset in conf['datasets']: +for dataset in config['datasets']: if f'tank/{dataset}' not in local_datasets: errors.add(f'dataset "{dataset}" not present at all') continue @@ -22,7 +22,7 @@ for dataset in conf['datasets']: snapshots = [ snapshot for snapshot in check_output(['zfs', 'list', '-H', '-o', 'name', '-t', 'snapshot', f'tank/{dataset}', '-s', 'creation']).decode().splitlines() - if '@auto-backup_' in snapshot + if f"@{config['prefix']}" in snapshot ] if not snapshots: @@ -43,3 +43,5 @@ if errors: for error in errors: print(error) exit(2) +else: + print(f"all {len(config['datasets'])} datasets have fresh backups.") diff --git a/bundles/backup-freshness-check/items.py b/bundles/backup-freshness-check/items.py new file mode 100644 index 0000000..e2ab818 --- /dev/null +++ b/bundles/backup-freshness-check/items.py @@ -0,0 +1,15 @@ +from json import dumps +from bundlewrap.metadata import MetadataJSONEncoder + + +files = { + '/etc/backup-freshness-check.json': { + 'content': dumps({ + 'prefix': node.metadata.get('backup-freshness-check/prefix'), + 'datasets': node.metadata.get('backup-freshness-check/datasets'), + }, indent=4, sort_keys=True, cls=MetadataJSONEncoder), + }, + '/usr/lib/nagios/plugins/check_backup_freshness': { + 'mode': '0755', + }, +} diff --git a/bundles/backup-freshness-check/metadata.py b/bundles/backup-freshness-check/metadata.py new file mode 100644 index 0000000..e55b0d4 --- /dev/null +++ b/bundles/backup-freshness-check/metadata.py @@ -0,0 +1,36 @@ +defaults = { + 'backup-freshness-check': { + 'server': node.name, + 'prefix': 'auto-backup_', + 'datasets': {}, + }, + 'monitoring': { + 'services': { + 'backup freshness': { + 'vars.command': '/usr/lib/nagios/plugins/check_backup_freshness', + 'check_interval': '6h', + 'vars.sudo': True, + }, + }, + }, +} + + +@metadata_reactor.provides( + 'backup-freshness-check/datasets' +) +def backup_freshness_check(metadata): + return { + 'backup-freshness-check': { + 'datasets': { + f"{other_node.metadata.get('id')}/{dataset}" + for other_node in repo.nodes + if other_node.has_bundle('backup') + and other_node.has_bundle('zfs') + and other_node.metadata.get('backup/server') == metadata.get('backup-freshness-check/server') + for dataset, options in other_node.metadata.get('zfs/datasets').items() + if options.get('backup', True) + and not options.get('mountpoint', None) in [None, 'none'] + }, + }, + } diff --git a/bundles/backup-server/items.py b/bundles/backup-server/items.py deleted file mode 100644 index 5f9438b..0000000 --- a/bundles/backup-server/items.py +++ /dev/null @@ -1,12 +0,0 @@ -from json import dumps -from bundlewrap.metadata import MetadataJSONEncoder - - -files = { - '/etc/backup-server.json': { - 'content': dumps(node.metadata.get('backup-receiver'), indent=4, sort_keys=True, cls=MetadataJSONEncoder), - }, - '/usr/lib/nagios/plugins/check_backup_freshness': { - 'mode': '0755', - }, -} diff --git a/bundles/backup-server/metadata.py b/bundles/backup-server/metadata.py index 4173a1e..acef717 100644 --- a/bundles/backup-server/metadata.py +++ b/bundles/backup-server/metadata.py @@ -6,18 +6,6 @@ defaults = { 'rsync': {}, }, }, - 'backup-receiver': { - 'datasets': {}, - }, - 'monitoring': { - 'services': { - 'backup freshness': { - 'vars.command': '/usr/lib/nagios/plugins/check_backup_freshness', - 'check_interval': '6h', - 'vars.sudo': True, - }, - }, - }, 'users': { 'backup-receiver': { 'authorized_keys': set(), @@ -131,23 +119,3 @@ def backup_authorized_keys(metadata): }, }, } - - -@metadata_reactor.provides( - 'backup-receiver/datasets' -) -def check_datasets(metadata): - return { - 'backup-receiver': { - 'datasets': { - f"{other_node.metadata.get('id')}/{dataset}" - for other_node in repo.nodes - if other_node.has_bundle('backup') - and other_node.has_bundle('zfs') - and other_node.metadata.get('backup/server') == node.name - for dataset, options in other_node.metadata.get('zfs/datasets').items() - if options.get('backup', True) - and not options.get('mountpoint', None) in [None, 'none'] - }, - }, - } diff --git a/groups/applications/backup-server.py b/groups/applications/backup-server.py index 1dd9a2f..b15a641 100644 --- a/groups/applications/backup-server.py +++ b/groups/applications/backup-server.py @@ -1,5 +1,6 @@ { 'bundles': [ + 'backup-freshness-check', 'backup-server', 'zfs', ], diff --git a/nodes/wb.offsite-backups.py b/nodes/wb.offsite-backups.py index 15939e1..3948c41 100644 --- a/nodes/wb.offsite-backups.py +++ b/nodes/wb.offsite-backups.py @@ -6,6 +6,7 @@ 'raspberry-pi', ], 'bundles': [ + 'backup-freshness-check', 'dm-crypt', 'smartctl', 'wireguard', @@ -20,6 +21,10 @@ 'gateway4': '192.168.179.1', }, }, + 'backup-freshness-check': { + 'server': 'home.backups', + 'prefix': 'auto-mirror_' + }, 'users': { 'root': { 'authorized_users': {