diff --git a/selfprivacy_api/backup/tasks.py b/selfprivacy_api/backup/tasks.py index 4c8c638..8e0f788 100644 --- a/selfprivacy_api/backup/tasks.py +++ b/selfprivacy_api/backup/tasks.py @@ -116,20 +116,8 @@ def eligible_for_full_restoration(snap: Snapshot): return True -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, - ) +def which_snapshots_to_full_restore() -> list[Snapshot]: autoslice = Backups.last_autobackup_slice() - api_snapshot = None for snap in autoslice: if snap.service_name == "api": @@ -143,14 +131,29 @@ def do_full_restore(job: Job) -> None: snapshots_to_restore = [ 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 = 0 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: try: Backups.restore_snapshot(snap) diff --git a/selfprivacy_api/graphql/queries/backup.py b/selfprivacy_api/graphql/queries/backup.py index d9bf14a..7df050f 100644 --- a/selfprivacy_api/graphql/queries/backup.py +++ b/selfprivacy_api/graphql/queries/backup.py @@ -7,6 +7,7 @@ import strawberry from selfprivacy_api.backup import Backups 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.common_types.service import ( 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.services import ServiceManager +from selfprivacy_api.models.backup.snapshot import Snapshot @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 class Backup: @strawberry.field @@ -72,26 +94,12 @@ class Backup: def all_snapshots(self) -> typing.List[SnapshotInfo]: if not Backups.is_initted(): return [] - result = [] snapshots = Backups.get_all_snapshots() - for snap in snapshots: - api_service = None - service = ServiceManager.get_service_by_id(snap.service_name) + return [snapshot_to_api(snap) for snap in snapshots] - 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." - ) - - graphql_snap = SnapshotInfo( - id=snap.id, - service=api_service, - created_at=snap.created_at, - reason=snap.reason, - ) - result.append(graphql_snap) - return result + # A query for seeing which snapshots will be restored when migrating + @strawberry.field + def last_slice(self) -> typing.List[SnapshotInfo]: + if not Backups.is_initted(): + return [] + result = [snapshot_to_api(snap) for snap in which_snapshots_to_full_restore()]