Run post-backup pruning through SQL retention

Stop passing prune options into the legacy scheduled backup engine from the
Django backup command. Record the completed snapshot first, then apply retention
through the SQL-backed retention service so pruning sees the same SnapshotRecord
state as the admin and retention command.

Also record prune failures on BackupRun.result instead of leaving the run in an
ambiguous state.
This commit is contained in:
2026-05-19 11:32:32 +02:00
parent 254f915051
commit 797619acd9
3 changed files with 128 additions and 4 deletions

View File

@@ -11,6 +11,7 @@ from pobsync.commands.run_scheduled import run_scheduled
from pobsync.paths import PobsyncPaths
from pobsync_backend.config_source import DjangoConfigSource
from pobsync_backend.models import BackupRun, HostConfig
from pobsync_backend.retention import run_sql_retention_apply
from pobsync_backend.snapshot_discovery import infer_snapshot_kind, upsert_snapshot_record
@@ -45,9 +46,7 @@ class Command(BaseCommand):
prefix=paths.home,
host=host.host,
dry_run=bool(options["dry_run"]),
prune=bool(options["prune"]),
prune_max_delete=int(options["prune_max_delete"]),
prune_protect_bases=bool(options["prune_protect_bases"]),
prune=False,
config_source=DjangoConfigSource(),
)
except Exception as exc:
@@ -72,7 +71,38 @@ class Command(BaseCommand):
snapshot_record, _created = upsert_snapshot_record(host=host, kind=kind, snapshot_dir=snapshot_path)
except ValueError:
snapshot_record = None
if result.get("ok") and not result.get("dry_run") and options["prune"]:
try:
result["prune"] = run_sql_retention_apply(
prefix=paths.home,
host=host.host,
kind="scheduled",
protect_bases=bool(options["prune_protect_bases"]),
yes=True,
max_delete=int(options["prune_max_delete"]),
acquire_lock=False,
)
except Exception as exc:
result["prune"] = {"ok": False, "error": str(exc), "type": type(exc).__name__}
run.status = BackupRun.Status.FAILED
run.result = result
run.snapshot = snapshot_record
run.save(
update_fields=[
"status",
"ended_at",
"snapshot_path",
"snapshot",
"base_path",
"rsync_exit_code",
"result",
],
)
raise
run.snapshot = snapshot_record
run.result = result
run.save(
update_fields=[
"status",