#!/usr/bin/env python import subprocess import pathlib import os import logging import asyncio async def notify(level, message): # notify = desktop_notify.aio.Notify(level, message) # await notify.show() notify_cmd = ["backup/notify.sh", level, message] notify = subprocess.run(notify_cmd, capture_output=True) def is_mountpoint(path): mountpoint_cmd = ["mountpoint", str(path)] logging.info(' '.join(mountpoint_cmd)) check = subprocess.run(mountpoint_cmd, capture_output=True) if check.returncode != 0: # not a mountpoint logging.error(check.stdout.decode().strip()) return False else: logging.info(check.stdout.decode().strip()) return True async def main(): logging.basicConfig(format='%(asctime)s %(levelname)s: %(message)s', level=logging.DEBUG) subvolumes_to_backup = ["home", "root"] logging.info(f"Backing up {', '.join(subvolumes_to_backup)}") btrfs_subvolume = "/btrfs" snapshot_subvolume = f"{btrfs_subvolume}/snapshots" snapshot_path = pathlib.Path(snapshot_subvolume) old_snapshots = os.listdir(snapshot_path) for snapshot in old_snapshots: delete_cmd = ["btrfs", "sub", "del", f"{snapshot_path}/{snapshot}"] logging.info(' '.join(delete_cmd)) delete = subprocess.run(delete_cmd, capture_output=True) for subvolume in subvolumes_to_backup: snapshot_cmd = [ "btrfs", "sub", "snap", "-r", f"{btrfs_subvolume}/{subvolume}", f"{snapshot_path}"] logging.info(' '.join(snapshot_cmd)) create_new_snap = subprocess.run(snapshot_cmd, capture_output=True) backup_mountpoint = pathlib.Path("/mnt/53de8433-6394-408c-a856-5f3b9908f21f") snapshots = os.listdir(snapshot_path) if is_mountpoint(backup_mountpoint): for new_snapshot in snapshots: backup_cmd = ["rsync", "-av", "--delete", f"{snapshot_path}/{new_snapshot}/", f"{backup_mountpoint}/{new_snapshot}/"] logging.info(' '.join(backup_cmd)) rsync = subprocess.run(backup_cmd, capture_output=True) await notify(f"{new_snapshot} backup successful", ' '.join(backup_cmd)) else: await notify(f"{new_snapshot} backup failed", f"{backup_mountpoint} is not mounted") if __name__ == "__main__": asyncio.run(main())