refactor(backups): download a copy before replacing original

pull/35/head
Houkime 2023-07-03 20:41:52 +00:00 committed by Inex Code
parent 9137536294
commit 4423db7458
2 changed files with 27 additions and 8 deletions

View File

@ -1,15 +1,16 @@
import subprocess import subprocess
import json import json
import datetime import datetime
import tempfile
from typing import List from typing import List
from collections.abc import Iterable from collections.abc import Iterable
from json.decoder import JSONDecodeError from json.decoder import JSONDecodeError
from os.path import exists from os.path import exists, join
from os import listdir from os import listdir
from time import sleep from time import sleep
from selfprivacy_api.backup.util import output_yielder from selfprivacy_api.backup.util import output_yielder, sync
from selfprivacy_api.backup.backuppers import AbstractBackupper from selfprivacy_api.backup.backuppers import AbstractBackupper
from selfprivacy_api.models.backup.snapshot import Snapshot from selfprivacy_api.models.backup.snapshot import Snapshot
from selfprivacy_api.backup.jobs import get_backup_job from selfprivacy_api.backup.jobs import get_backup_job
@ -210,19 +211,34 @@ class ResticBackupper(AbstractBackupper):
except ValueError as e: except ValueError as e:
raise ValueError("cannot restore a snapshot: " + output) from e raise ValueError("cannot restore a snapshot: " + output) from e
def restore_from_backup(self, snapshot_id, folders): def restore_from_backup(self, snapshot_id, folders: List[str], verify=True):
""" """
Restore from backup with restic Restore from backup with restic
""" """
# snapshots save the path of the folder in the file system if folders is None or folders == []:
# I do not alter the signature yet because maybe this can be raise ValueError("cannot restore without knowing where to!")
# changed with flags
with tempfile.TemporaryDirectory() as dir:
self.do_restore(snapshot_id, target=dir)
for folder in folders:
src = join(dir, folder.strip("/"))
if not exists(src):
raise ValueError(
f"there is no such path: {src}. We tried to find {folder}"
)
dst = folder
sync(src, dst)
def do_restore(self, snapshot_id, target="/", verify=False):
"""barebones restic restore"""
restore_command = self.restic_command( restore_command = self.restic_command(
"restore", "restore",
snapshot_id, snapshot_id,
"--target", "--target",
"/", target,
) )
if verify:
restore_command.append("--verify")
with subprocess.Popen( with subprocess.Popen(
restore_command, stdout=subprocess.PIPE, shell=False restore_command, stdout=subprocess.PIPE, shell=False

View File

@ -86,7 +86,10 @@ def dummy_service(tmpdir, backups, raw_dummy_service) -> Service:
services.services.append(service) services.services.append(service)
assert get_service_by_id(service.get_id()) is not None assert get_service_by_id(service.get_id()) is not None
return service yield service
# cleanup because apparently it matters wrt tasks
services.services.remove(service)
@pytest.fixture() @pytest.fixture()