From deb857bca9ea81dec93e0ba97409d3977d936419 Mon Sep 17 00:00:00 2001 From: Houkime <> Date: Wed, 17 May 2023 17:48:06 +0000 Subject: [PATCH] refactor(backups): use single repo and multiplex by tags --- .../backup/providers/local_file.py | 3 +- selfprivacy_api/backup/restic_backuper.py | 28 +++++++++++-------- 2 files changed, 18 insertions(+), 13 deletions(-) diff --git a/selfprivacy_api/backup/providers/local_file.py b/selfprivacy_api/backup/providers/local_file.py index bdd9213..a20f615 100644 --- a/selfprivacy_api/backup/providers/local_file.py +++ b/selfprivacy_api/backup/providers/local_file.py @@ -8,4 +8,5 @@ class LocalFileBackup(AbstractBackupProvider): # login and key args are for compatibility with generic provider methods. They are ignored. def __init__(self, filename: str, login: str = "", key: str = ""): super().__init__() - self.backuper = ResticBackuper("", "", f":local:{filename}/") + self.backuper = ResticBackuper("", "", ":local:") + self.backuper.set_creds("", "", filename) diff --git a/selfprivacy_api/backup/restic_backuper.py b/selfprivacy_api/backup/restic_backuper.py index 896f68d..07ddb1c 100644 --- a/selfprivacy_api/backup/restic_backuper.py +++ b/selfprivacy_api/backup/restic_backuper.py @@ -18,15 +18,17 @@ class ResticBackuper(AbstractBackuper): self.type = type self.account = "" self.key = "" + self.repo = "" - def set_creds(self, account: str, key: str): + def set_creds(self, account: str, key: str, repo: str): self.account = account self.key = key + self.repo = repo - def restic_repo(self, repository_name: str) -> str: + def restic_repo(self) -> str: # https://restic.readthedocs.io/en/latest/030_preparing_a_new_repo.html#other-services-via-rclone # https://forum.rclone.org/t/can-rclone-be-run-solely-with-command-line-options-no-config-no-env-vars/6314/5 - return f"rclone:{self.type}{repository_name}/sfbackup" + return f"rclone:{self.type}{self.repo}" def rclone_args(self): return "rclone.args=serve restic --stdio" + self.backend_rclone_args() @@ -44,16 +46,23 @@ class ResticBackuper(AbstractBackuper): def _password_command(self): return f"echo {LocalBackupSecret.get()}" - def restic_command(self, repo_name: str, *args): + def restic_command(self, *args, branch_name: str = ""): command = [ "restic", "-o", self.rclone_args(), "-r", - self.restic_repo(repo_name), + self.restic_repo(), "--password-command", self._password_command(), ] + if branch_name != "": + command.extend( + [ + "--tag", + branch_name, + ] + ) if args != []: command.extend(ResticBackuper.__flatten_list(args)) return command @@ -78,10 +87,10 @@ class ResticBackuper(AbstractBackuper): assert not isinstance(folders, str) backup_command = self.restic_command( - repo_name, "backup", "--json", folders, + branch_name=repo_name, ) with subprocess.Popen( backup_command, @@ -115,7 +124,6 @@ class ResticBackuper(AbstractBackuper): def init(self, repo_name): init_command = self.restic_command( - repo_name, "init", ) with subprocess.Popen( @@ -130,7 +138,6 @@ class ResticBackuper(AbstractBackuper): def is_initted(self, repo_name: str) -> bool: command = self.restic_command( - repo_name, "check", "--json", ) @@ -147,7 +154,6 @@ class ResticBackuper(AbstractBackuper): Size of a snapshot """ command = self.restic_command( - repo_name, "stats", snapshot_id, "--json", @@ -169,7 +175,6 @@ class ResticBackuper(AbstractBackuper): # I do not alter the signature yet because maybe this can be # changed with flags restore_command = self.restic_command( - repo_name, "restore", snapshot_id, "--target", @@ -190,7 +195,6 @@ class ResticBackuper(AbstractBackuper): raises Value Error if repo does not exist """ listing_command = self.restic_command( - repo_name, "snapshots", "--json", ) @@ -217,7 +221,7 @@ class ResticBackuper(AbstractBackuper): snapshot = Snapshot( id=restic_snapshot["short_id"], created_at=restic_snapshot["time"], - service_name=repo_name, + service_name=restic_snapshot["tags"][0], ) snapshots.append(snapshot)