From 2b421c7607175a021e256157fbe829fdf37db8bf Mon Sep 17 00:00:00 2001 From: Codex Date: Wed, 15 Jul 2026 01:15:22 +0200 Subject: [PATCH] Make archive discovery deterministic --- backend/app/commands.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/backend/app/commands.py b/backend/app/commands.py index 91aa44e..58d8405 100644 --- a/backend/app/commands.py +++ b/backend/app/commands.py @@ -139,6 +139,16 @@ def get_task_status(node: str, upid: str) -> dict: return pvesh_json(["get", f"/nodes/{node}/tasks/{upid}/status"]) or {} +def _archive_name_timestamp(path: Path) -> datetime: + match = re.search(r"-(\d{4}_\d{2}_\d{2}-\d{2}_\d{2}_\d{2})", path.name) + if not match: + return datetime.min + try: + return datetime.strptime(match.group(1), "%Y_%m_%d-%H_%M_%S") + except ValueError: + return datetime.min + + def discover_archive(local_backup_dir: str, vmid: int, guest_type: str, started_at: str) -> Path: base = Path(local_backup_dir) prefix = "vzdump-lxc" if guest_type == "lxc" else "vzdump-qemu" @@ -161,7 +171,7 @@ def discover_archive(local_backup_dir: str, vmid: int, guest_type: str, started_ candidates.append(path) if not candidates: raise FileNotFoundError(f"No backup archive found for VMID {vmid} in {base}") - return max(candidates, key=lambda p: p.stat().st_mtime) + return max(candidates, key=lambda p: (p.stat().st_mtime_ns, _archive_name_timestamp(p), p.name)) def rclone_list_remotes(rclone_path: str) -> list[str]: