feature(backup): endpoint to force autobackup

This commit is contained in:
Houkime 2024-07-29 12:16:33 +00:00
parent bb493e6b74
commit a5b52c8f75
3 changed files with 75 additions and 1 deletions

View file

@ -82,6 +82,12 @@ def do_autobackup() -> None:
inside tests inside tests
""" """
time = datetime.now(timezone.utc) time = datetime.now(timezone.utc)
backups_were_disabled = Backups.autobackup_period_minutes() is None
if backups_were_disabled:
# Temporarily enable autobackup
Backups.set_autobackup_period_minutes(24 * 60) # 1 day
services_to_back_up = Backups.services_to_back_up(time) services_to_back_up = Backups.services_to_back_up(time)
if not services_to_back_up: if not services_to_back_up:
return return
@ -104,7 +110,11 @@ def do_autobackup() -> None:
progress = progress + progress_per_service progress = progress + progress_per_service
Jobs.update(job, JobStatus.RUNNING, progress=progress) Jobs.update(job, JobStatus.RUNNING, progress=progress)
if backups_were_disabled:
Backups.set_autobackup_period_minutes(0)
Jobs.update(job, JobStatus.FINISHED) Jobs.update(job, JobStatus.FINISHED)
# there is no point of returning the job
# this code is called with a delay
def eligible_for_full_restoration(snap: Snapshot): def eligible_for_full_restoration(snap: Snapshot):
@ -194,7 +204,12 @@ def automatic_backup() -> None:
""" """
The worker periodic task that starts the automatic backup process. The worker periodic task that starts the automatic backup process.
""" """
@huey.task()
def trigger_autobackup() -> bool:
do_autobackup() do_autobackup()
return True
@huey.periodic_task(crontab(hour="*/" + str(SNAPSHOT_CACHE_TTL_HOURS))) @huey.periodic_task(crontab(hour="*/" + str(SNAPSHOT_CACHE_TTL_HOURS)))

View file

@ -25,6 +25,7 @@ from selfprivacy_api.backup.tasks import (
restore_snapshot, restore_snapshot,
prune_autobackup_snapshots, prune_autobackup_snapshots,
full_restore, full_restore,
trigger_autobackup,
) )
from selfprivacy_api.backup.jobs import ( from selfprivacy_api.backup.jobs import (
add_backup_job, add_backup_job,
@ -171,6 +172,22 @@ class BackupMutations:
job=job_to_api_job(job), job=job_to_api_job(job),
) )
@strawberry.mutation(permission_classes=[IsAuthenticated])
def manual_autobackup(self) -> GenericMutationReturn:
"""Induce autobackup to back up all the services at once
Useful when migrating but a bit of a hack
"""
# This cannot give us a job, unfortunately
# TODO: We need to pass it
trigger_autobackup()
return GenericMutationReturn(
success=True,
code=200,
message="Backup task queued",
)
@strawberry.mutation(permission_classes=[IsAuthenticated]) @strawberry.mutation(permission_classes=[IsAuthenticated])
def restore_all(self) -> GenericJobMutationReturn: def restore_all(self) -> GenericJobMutationReturn:
""" """

View file

@ -14,6 +14,13 @@ from selfprivacy_api.jobs import Jobs, JobStatus
from selfprivacy_api.backup.storage import Storage from selfprivacy_api.backup.storage import Storage
from selfprivacy_api.backup.local_secret import LocalBackupSecret from selfprivacy_api.backup.local_secret import LocalBackupSecret
from tests.test_graphql.test_services import (
only_dummy_service_and_api,
only_dummy_service,
dkim_file,
)
API_RELOAD_SNAPSHOTS = """ API_RELOAD_SNAPSHOTS = """
mutation TestSnapshotsReload { mutation TestSnapshotsReload {
backup { backup {
@ -26,6 +33,18 @@ mutation TestSnapshotsReload {
} }
""" """
API_MANUAL_AUTOBACKUP = """
mutation TestForcedAutobackup {
backup {
manualAutobackup{
success
message
code
}
}
}
"""
API_SET_AUTOBACKUP_PERIOD_MUTATION = """ API_SET_AUTOBACKUP_PERIOD_MUTATION = """
mutation TestAutobackupPeriod($period: Int) { mutation TestAutobackupPeriod($period: Int) {
backup { backup {
@ -259,6 +278,17 @@ def api_reload_snapshots(authorized_client):
return response return response
def api_manual_autobackup(authorized_client):
response = authorized_client.post(
"/graphql",
json={
"query": API_MANUAL_AUTOBACKUP,
"variables": {},
},
)
return response
def api_init( def api_init(
authorized_client, authorized_client,
kind, kind,
@ -403,7 +433,7 @@ def test_reinit(authorized_client, dummy_service, tmpdir, backups):
assert Jobs.get_job(job["uid"]).status == JobStatus.FINISHED assert Jobs.get_job(job["uid"]).status == JobStatus.FINISHED
def test_migrate(authorized_client, dummy_service, tmpdir, backups): def test_migrate_backup_repo(authorized_client, dummy_service, tmpdir, backups):
""" """
Simulate the workflow of migrating to a new server Simulate the workflow of migrating to a new server
""" """
@ -554,6 +584,18 @@ def test_reload_snapshots_bare_bare_bare(authorized_client, dummy_service, backu
assert snaps == [] assert snaps == []
def test_induce_autobackup(authorized_client, only_dummy_service_and_api, backups):
dummy_service = only_dummy_service_and_api
response = api_manual_autobackup(authorized_client)
# raise ValueError(get_data(response))
data = get_data(response)["backup"]["manualAutobackup"]
assert_ok(data)
snaps = api_snapshots(authorized_client)
assert len(snaps) == 2
def test_reload_snapshots(authorized_client, dummy_service, backups): def test_reload_snapshots(authorized_client, dummy_service, backups):
response = api_backup(authorized_client, dummy_service) response = api_backup(authorized_client, dummy_service)
data = get_data(response)["backup"]["startBackup"] data = get_data(response)["backup"]["startBackup"]