feature(backups): a wrapper for rclone sync

pull/35/head
Houkime 2023-07-03 12:15:36 +00:00 committed by Inex Code
parent 2df930b9ba
commit 1c28984475
2 changed files with 42 additions and 1 deletions

View File

@ -5,6 +5,7 @@ import datetime
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 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
@ -95,6 +96,20 @@ class ResticBackupper(AbstractBackupper):
if "NOTICE:" not in line: if "NOTICE:" not in line:
yield line yield line
@staticmethod
def sync (src_path: str, dest_path:str):
"""a wrapper around rclone sync"""
if not exists(src_path):
raise ValueError("source dir for rclone sync must exist")
rclone_command = ["rclone", "sync", "-P", src_path, dest_path]
for raw_message in ResticBackupper.output_yielder(rclone_command):
if "ERROR" in raw_message:
raise ValueError(raw_message)
def start_backup(self, folders: List[str], tag: str): def start_backup(self, folders: List[str], tag: str):
""" """
Start backup with restic Start backup with restic

View File

@ -7,6 +7,8 @@ from os import urandom
from datetime import datetime, timedelta, timezone from datetime import datetime, timedelta, timezone
import selfprivacy_api.services as services import selfprivacy_api.services as services
from selfprivacy_api.services import Service
from selfprivacy_api.services import get_service_by_id from selfprivacy_api.services import get_service_by_id
from selfprivacy_api.services.test_service import DummyService from selfprivacy_api.services.test_service import DummyService
from selfprivacy_api.graphql.queries.providers import BackupProvider from selfprivacy_api.graphql.queries.providers import BackupProvider
@ -17,6 +19,8 @@ import selfprivacy_api.backup.providers as providers
from selfprivacy_api.backup.providers import AbstractBackupProvider from selfprivacy_api.backup.providers import AbstractBackupProvider
from selfprivacy_api.backup.providers.backblaze import Backblaze from selfprivacy_api.backup.providers.backblaze import Backblaze
from selfprivacy_api.backup.backuppers.restic_backupper import ResticBackupper
from selfprivacy_api.backup.tasks import start_backup, restore_snapshot from selfprivacy_api.backup.tasks import start_backup, restore_snapshot
from selfprivacy_api.backup.storage import Storage from selfprivacy_api.backup.storage import Storage
from selfprivacy_api.backup.jobs import get_backup_job from selfprivacy_api.backup.jobs import get_backup_job
@ -68,7 +72,7 @@ def raw_dummy_service(tmpdir, backups):
@pytest.fixture() @pytest.fixture()
def dummy_service(tmpdir, backups, raw_dummy_service): def dummy_service(tmpdir, backups, raw_dummy_service) -> Service:
service = raw_dummy_service service = raw_dummy_service
repo_path = path.join(tmpdir, "test_repo") repo_path = path.join(tmpdir, "test_repo")
assert not path.exists(repo_path) assert not path.exists(repo_path)
@ -519,3 +523,25 @@ def test_services_to_back_up(backups, dummy_service):
services = Backups.services_to_back_up(now) services = Backups.services_to_back_up(now)
assert len(services) == 1 assert len(services) == 1
assert services[0].get_id() == dummy_service.get_id() assert services[0].get_id() == dummy_service.get_id()
def test_sync(dummy_service):
src = dummy_service.get_folders()[0]
dst = dummy_service.get_folders()[1]
old_files_src = listdir(src)
old_files_dst = listdir(dst)
assert old_files_src != old_files_dst
ResticBackupper.sync(src, dst)
new_files_src = listdir(src)
new_files_dst = listdir(dst)
assert new_files_src == old_files_src
assert new_files_dst == new_files_src
def test_sync_nonexistent_src(dummy_service):
src = "/var/lib/nonexistentFluffyBunniesOfUnix"
dst = dummy_service.get_folders()[1]
with pytest.raises(ValueError):
ResticBackupper.sync(src, dst)