feature(backups): graphql mutation for restore

This commit is contained in:
Houkime 2023-06-01 14:03:26 +00:00
parent f7c0821675
commit 50952d688a
3 changed files with 42 additions and 1 deletions

View file

@ -257,6 +257,25 @@ class Backups:
Backups.sync_service_snapshots(service_id, upstream_snapshots) Backups.sync_service_snapshots(service_id, upstream_snapshots)
return [snap for snap in upstream_snapshots if snap.service_name == service_id] return [snap for snap in upstream_snapshots if snap.service_name == service_id]
@staticmethod
def get_snapshot_by_id(id: str) -> Optional[Snapshot]:
snap = Storage.get_cached_snapshot_by_id(id)
if snap is not None:
return snap
# Possibly our cache entry got invalidated, let's try one more time
Backups.sync_all_snapshots()
snap = Storage.get_cached_snapshot_by_id(id)
return snap
@staticmethod
def sync_all_snapshots():
upstream_snapshots = Backups.provider().backuper.get_snapshots()
Storage.invalidate_snapshot_storage()
for snapshot in upstream_snapshots:
Storage.cache_snapshot(snapshot)
@staticmethod @staticmethod
def restore_service_from_snapshot(service: Service, snapshot_id: str): def restore_service_from_snapshot(service: Service, snapshot_id: str):
repo_name = service.get_id() repo_name = service.get_id()

View file

@ -47,6 +47,11 @@ class Storage:
for key in redis.keys(prefix + "*"): for key in redis.keys(prefix + "*"):
redis.delete(key) redis.delete(key)
@staticmethod
def invalidate_snapshot_storage():
for key in redis.keys(REDIS_SNAPSHOTS_PREFIX + "*"):
redis.delete(key)
@staticmethod @staticmethod
def store_testrepo_path(path: str): def store_testrepo_path(path: str):
redis.set(REDIS_REPO_PATH_KEY, path) redis.set(REDIS_REPO_PATH_KEY, path)
@ -97,6 +102,13 @@ class Storage:
snapshot_key = Storage.__snapshot_key(snapshot) snapshot_key = Storage.__snapshot_key(snapshot)
redis.delete(snapshot_key) redis.delete(snapshot_key)
@staticmethod
def get_cached_snapshot_by_id(snapshot_id: str) -> Optional[Snapshot]:
key = redis.keys(REDIS_SNAPSHOTS_PREFIX + snapshot_id)
if not redis.exists(key):
return None
return hash_as_model(redis, key, Snapshot)
@staticmethod @staticmethod
def get_cached_snapshots() -> List[Snapshot]: def get_cached_snapshots() -> List[Snapshot]:
keys = redis.keys(REDIS_SNAPSHOTS_PREFIX + "*") keys = redis.keys(REDIS_SNAPSHOTS_PREFIX + "*")

View file

@ -14,7 +14,7 @@ from selfprivacy_api.graphql.queries.providers import BackupProvider
from selfprivacy_api.backup import Backups from selfprivacy_api.backup import Backups
from selfprivacy_api.services import get_all_services, get_service_by_id from selfprivacy_api.services import get_all_services, get_service_by_id
from selfprivacy_api.backup.tasks import start_backup from selfprivacy_api.backup.tasks import start_backup, restore_snapshot
@strawberry.input @strawberry.input
@ -80,3 +80,13 @@ class BackupMutations:
start_backup(service) start_backup(service)
return GenericJobMutationReturn() return GenericJobMutationReturn()
@strawberry.mutation(permission_classes=[IsAuthenticated])
def restore_backup(self, snapshot_id: str) -> GenericJobMutationReturn:
"""Restore backup"""
snap = Backups.get_snapshot_by_id(snapshot_id)
if snap in None:
raise ValueError(f"No such snapshot: {snapshot_id}")
restore_snapshot(snap)
return GenericJobMutationReturn()