(bugfix) Mark retention failures as backup warnings

Add a warning status for BackupRun records so successful snapshots are not
reported as failed when post-run SQL retention fails.

Keep the prune error in the run result, link the successful snapshot, and
let the management command complete with a warning instead of raising a
backup failure.

Include warning runs in backup trend summaries and add a regression test
for successful backups with failed retention cleanup.
This commit is contained in:
2026-05-19 23:20:52 +02:00
parent 1e04da9de8
commit 8bff241b12
6 changed files with 49 additions and 15 deletions

View File

@@ -102,7 +102,7 @@ class RunBackupRecordsSnapshotTests(TestCase):
self.assertEqual(run.status, BackupRun.Status.SUCCESS)
self.assertEqual(run.result["prune"], {"ok": True, "source": "sql", "deleted": []})
def test_prune_failure_is_recorded_on_backup_run(self) -> None:
def test_prune_failure_marks_backup_run_as_warning(self) -> None:
with TemporaryDirectory() as tmp:
backup_root = Path(tmp) / "backups"
GlobalConfig.objects.create(name="default", backup_root=str(backup_root))
@@ -128,19 +128,20 @@ class RunBackupRecordsSnapshotTests(TestCase):
}
retention_apply.side_effect = ConfigError("Deletion blocked by --max-delete=0")
with self.assertRaises(ConfigError):
call_command(
"run_pobsync_backup",
host.host,
prefix=str(Path(tmp) / "home"),
prune=True,
prune_max_delete=0,
stdout=StringIO(),
)
output = StringIO()
call_command(
"run_pobsync_backup",
host.host,
prefix=str(Path(tmp) / "home"),
prune=True,
prune_max_delete=0,
stdout=output,
)
run = BackupRun.objects.get()
self.assertEqual(run.status, BackupRun.Status.FAILED)
self.assertEqual(run.status, BackupRun.Status.WARNING)
self.assertIsNotNone(run.snapshot)
self.assertIn("completed with warnings", output.getvalue())
self.assertEqual(run.result["prune"]["ok"], False)
self.assertEqual(run.result["prune"]["type"], "ConfigError")
self.assertEqual(run.result["prune"]["error"], "Deletion blocked by --max-delete=0")