feature(backup): query to see restored snapshots in advance

This commit is contained in:
Houkime 2024-07-26 11:23:41 +00:00
parent 5e07a9eaeb
commit bfb0442e94
2 changed files with 48 additions and 37 deletions

View file

@ -116,20 +116,8 @@ def eligible_for_full_restoration(snap: Snapshot):
return True return True
def do_full_restore(job: Job) -> None: def which_snapshots_to_full_restore() -> list[Snapshot]:
"""
Body full restore task, a part of server migration.
Broken out to test it independently from task infra
"""
Jobs.update(
job,
JobStatus.RUNNING,
status_text=f"Finding the last autobackup session",
progress=0,
)
autoslice = Backups.last_autobackup_slice() autoslice = Backups.last_autobackup_slice()
api_snapshot = None api_snapshot = None
for snap in autoslice: for snap in autoslice:
if snap.service_name == "api": if snap.service_name == "api":
@ -143,14 +131,29 @@ def do_full_restore(job: Job) -> None:
snapshots_to_restore = [ snapshots_to_restore = [
snap for snap in autoslice if eligible_for_full_restoration(snap) snap for snap in autoslice if eligible_for_full_restoration(snap)
] ]
# API should be restored in the very end of the list because it requires rebuild right afterwards
snapshots_to_restore.append(api_snapshot)
return snapshots_to_restore
def do_full_restore(job: Job) -> None:
"""
Body full restore task, a part of server migration.
Broken out to test it independently from task infra
"""
Jobs.update(
job,
JobStatus.RUNNING,
status_text=f"Finding the last autobackup session",
progress=0,
)
snapshots_to_restore = which_snapshots_to_full_restore()
progress_per_service = 99 // len(snapshots_to_restore) progress_per_service = 99 // len(snapshots_to_restore)
progress = 0 progress = 0
Jobs.update(job, JobStatus.RUNNING, progress=progress) Jobs.update(job, JobStatus.RUNNING, progress=progress)
# API should be restored in the very end of the list because it requires rebuild right afterwards
snapshots_to_restore.append(api_snapshot)
for snap in snapshots_to_restore: for snap in snapshots_to_restore:
try: try:
Backups.restore_snapshot(snap) Backups.restore_snapshot(snap)

View file

@ -7,6 +7,7 @@ import strawberry
from selfprivacy_api.backup import Backups from selfprivacy_api.backup import Backups
from selfprivacy_api.backup.local_secret import LocalBackupSecret from selfprivacy_api.backup.local_secret import LocalBackupSecret
from selfprivacy_api.backup.tasks import which_snapshots_to_full_restore
from selfprivacy_api.graphql.queries.providers import BackupProvider from selfprivacy_api.graphql.queries.providers import BackupProvider
from selfprivacy_api.graphql.common_types.service import ( from selfprivacy_api.graphql.common_types.service import (
Service, Service,
@ -16,6 +17,7 @@ from selfprivacy_api.graphql.common_types.service import (
) )
from selfprivacy_api.graphql.common_types.backup import AutobackupQuotas from selfprivacy_api.graphql.common_types.backup import AutobackupQuotas
from selfprivacy_api.services import ServiceManager from selfprivacy_api.services import ServiceManager
from selfprivacy_api.models.backup.snapshot import Snapshot
@strawberry.type @strawberry.type
@ -54,6 +56,26 @@ def tombstone_service(service_id: str) -> Service:
) )
def snapshot_to_api(snap: Snapshot):
api_service = None
service = ServiceManager.get_service_by_id(snap.service_name)
if service is None:
api_service = tombstone_service(snap.service_name)
else:
api_service = service_to_graphql_service(service)
if api_service is None:
raise NotImplementedError(
f"Could not construct API Service record for:{snap.service_name}. This should be unreachable and is a bug if you see it."
)
return SnapshotInfo(
id=snap.id,
service=api_service,
created_at=snap.created_at,
reason=snap.reason,
)
@strawberry.type @strawberry.type
class Backup: class Backup:
@strawberry.field @strawberry.field
@ -72,26 +94,12 @@ class Backup:
def all_snapshots(self) -> typing.List[SnapshotInfo]: def all_snapshots(self) -> typing.List[SnapshotInfo]:
if not Backups.is_initted(): if not Backups.is_initted():
return [] return []
result = []
snapshots = Backups.get_all_snapshots() snapshots = Backups.get_all_snapshots()
for snap in snapshots: return [snapshot_to_api(snap) for snap in snapshots]
api_service = None
service = ServiceManager.get_service_by_id(snap.service_name)
if service is None: # A query for seeing which snapshots will be restored when migrating
api_service = tombstone_service(snap.service_name) @strawberry.field
else: def last_slice(self) -> typing.List[SnapshotInfo]:
api_service = service_to_graphql_service(service) if not Backups.is_initted():
if api_service is None: return []
raise NotImplementedError( result = [snapshot_to_api(snap) for snap in which_snapshots_to_full_restore()]
f"Could not construct API Service record for:{snap.service_name}. This should be unreachable and is a bug if you see it."
)
graphql_snap = SnapshotInfo(
id=snap.id,
service=api_service,
created_at=snap.created_at,
reason=snap.reason,
)
result.append(graphql_snap)
return result