feat: record backup snapshots during run completion
Upsert SnapshotRecord rows directly from run_pobsync_backup results so new successful and failed backup runs are reflected in the database without requiring a separate discovery pass. Keep discovery for existing snapshots and repair workflows, and cover success, failure, and dry-run behavior with tests.
This commit is contained in:
@@ -45,19 +45,10 @@ def discover_snapshots(
|
||||
host_root = resolve_host_root(global_config.backup_root, host_config.host)
|
||||
for kind in kinds:
|
||||
for snapshot_dir in iter_snapshot_dirs(host_root, kind):
|
||||
meta = read_snapshot_meta(snapshot_dir)
|
||||
defaults = {
|
||||
"path": str(snapshot_dir),
|
||||
"status": str(meta.get("status") or ""),
|
||||
"started_at": parse_snapshot_datetime(snapshot_dir.name, meta, "started_at"),
|
||||
"ended_at": parse_snapshot_datetime(snapshot_dir.name, meta, "ended_at"),
|
||||
"metadata": meta,
|
||||
}
|
||||
_record, was_created = SnapshotRecord.objects.update_or_create(
|
||||
_record, was_created = upsert_snapshot_record(
|
||||
host=host_config,
|
||||
kind=kind,
|
||||
dirname=snapshot_dir.name,
|
||||
defaults=defaults,
|
||||
snapshot_dir=snapshot_dir,
|
||||
)
|
||||
scanned += 1
|
||||
if was_created:
|
||||
@@ -73,6 +64,34 @@ def discover_snapshots(
|
||||
}
|
||||
|
||||
|
||||
def upsert_snapshot_record(*, host: HostConfig, kind: str, snapshot_dir: Path) -> tuple[SnapshotRecord, bool]:
|
||||
meta = read_snapshot_meta(snapshot_dir)
|
||||
defaults = {
|
||||
"path": str(snapshot_dir),
|
||||
"status": str(meta.get("status") or ""),
|
||||
"started_at": parse_snapshot_datetime(snapshot_dir.name, meta, "started_at"),
|
||||
"ended_at": parse_snapshot_datetime(snapshot_dir.name, meta, "ended_at"),
|
||||
"metadata": meta,
|
||||
}
|
||||
return SnapshotRecord.objects.update_or_create(
|
||||
host=host,
|
||||
kind=kind,
|
||||
dirname=snapshot_dir.name,
|
||||
defaults=defaults,
|
||||
)
|
||||
|
||||
|
||||
def infer_snapshot_kind(snapshot_path: Path) -> str:
|
||||
parent = snapshot_path.parent.name
|
||||
if parent == "scheduled":
|
||||
return "scheduled"
|
||||
if parent == "manual":
|
||||
return "manual"
|
||||
if parent == ".incomplete":
|
||||
return "incomplete"
|
||||
raise ValueError(f"Cannot infer snapshot kind from path: {snapshot_path}")
|
||||
|
||||
|
||||
def _parse_iso_z(value: str) -> datetime | None:
|
||||
try:
|
||||
if value.endswith("Z"):
|
||||
|
||||
Reference in New Issue
Block a user