diff --git a/src/main.py b/src/main.py index ee50092..23bfb01 100644 --- a/src/main.py +++ b/src/main.py @@ -1,6 +1,7 @@ from datetime import datetime import subprocess import requests +import sys import os import config @@ -9,9 +10,19 @@ def log(*args, **kwargs): date = datetime.now().strftime('%d-%b-%Y %H:%M:%S') print(f"[{date}]", *args, **kwargs) +def log_error(*args, **kwargs): + date = datetime.now().strftime('%d-%b-%Y %H:%M:%S') + print(f"[{date}]", *args, **kwargs, file=sys.stderr) + +def check_return_code(ret, *args, **kwargs): + if ret != 0: + log_error(*args, **kwargs) + exit(1) + if not os.path.exists(config.DISK): log_error(f"Drive {config.DISK} not present on the system") + exit(1) passwd = requests.get(config.PWD_URL).text.strip() log("Got password :", passwd) @@ -20,61 +31,77 @@ ssh_key_passwd = requests.get(config.SSH_KEY_PWD_URL).text.strip() log("Got password :", ssh_key_passwd) -subprocess.run([ - "cryptsetup", "luksOpen", - config.DISK, "backup" -], input=passwd, text=True) +class Drive(): + def __init__(self, disk, passwd, mount_location): + self.disk = disk + self.passwd = passwd + self.mount_location = mount_location -subprocess.call([ - "mount", "/dev/mapper/backup", - config.MNT_LOCATION -]) + def __enter__(self): + subprocess.run([ + "cryptsetup", "luksOpen", + self.disk, "backup" + ], input=self.passwd, text=True) -log("Successfully mounted, doing the backup stuff") + subprocess.call([ + "mount", "/dev/mapper/backup", + self.mount_location + ]) + return self -os.makedirs( - os.path.join(config.MNT_LOCATION, "latest"), - exist_ok=True -) + def __exit__(self, exception_type, exception_value, exception_traceback): + subprocess.call([ + "umount", self.mount_location + ]) -for src, dest in config.BACKUP_MAP: - # We could also use a rsync daemon on the remote machine for pwd(-less) auth - subprocess.call( - [ - "sshpass", "-P", "passphrase", "-e", - "rsync", - "-ahz", - "--partial", - "--delete", - "--stats", - f"{config.REMOTE_USER}@{config.REMOTE_LOCATION}:{src}", - os.path.join(config.MNT_LOCATION, "latest", dest), - ], - env={**os.environ, "SSHPASS":ssh_key_passwd} + subprocess.call([ + "cryptsetup", "luksClose", + "/dev/mapper/backup" + ]) + + +with Drive(config.DISK, passwd, config.MNT_LOCATION) as backup_drive: + log("Successfully mounted, doing the backup stuff") + + os.makedirs( + os.path.join(config.MNT_LOCATION, "latest"), + exist_ok=True ) -log("Rsync ok. Creating snapshot.") + for src, dest in config.BACKUP_MAP: + # We could also use a rsync daemon on the remote machine for pwd(-less) auth + ret = subprocess.call( + [ + "sshpass", "-P", "passphrase", "-e", + "rsync", + "-ahz", + "--partial", + "--delete", + "--stats", + f"{config.REMOTE_USER}@{config.REMOTE_LOCATION}:{src}", + os.path.join(config.MNT_LOCATION, "latest", dest), + ], + env={**os.environ, "SSHPASS":ssh_key_passwd} + ) + check_return_code(ret, f"Error when syncing {config.REMOTE_LOCATION}") -subprocess.call([ - "cp", "-a", - "--reflink=always", #! The partition must be Btrfs or XFS - os.path.join(config.MNT_LOCATION, "latest"), - os.path.join(config.MNT_LOCATION, datetime.today().strftime('%Y-%m-%d')) -]) + log("Rsync ok. Creating snapshot.") -log("Snapshot ok. Deleting unneeded backups.") + ret = subprocess.call([ + "cp", "-a", + "--reflink=always", #! The partition must be Btrfs or XFS + os.path.join(config.MNT_LOCATION, "latest"), + os.path.join(config.MNT_LOCATION, datetime.today().strftime('%Y-%m-%d')) + ]) + check_return_code(ret, f"Error when creating snapshot") -#TODO + log("Snapshot ok. Deleting unneeded backups.") -log("Unmounting.") + #TODO -subprocess.call([ - "umount", config.MNT_LOCATION -]) + log("Unmounting.") -subprocess.call([ - "cryptsetup", "luksClose", - "/dev/mapper/backup" -]) +log("Everything okay, done !") -log("Done !") \ No newline at end of file +with open("latest-success", "w") as f: + f.write(datetime.today().strftime('%Y-%m-%d')) \ No newline at end of file