fix(release): make deployment backup and rollback immutable

This commit is contained in:
Jens
2026-08-30 06:00:43 +02:00
parent a0884d64c9
commit c272220277
47 changed files with 3035 additions and 430 deletions
+12 -5
View File
@@ -9,6 +9,8 @@ from dataclasses import dataclass
from datetime import datetime, timezone
from pathlib import Path
from release_backup_snapshot import verify_backup as verify_byte_snapshots
@dataclass(frozen=True)
class VerifiedBackup:
@@ -16,7 +18,7 @@ class VerifiedBackup:
release_id: str
created_at: datetime
age_hours: float
git_commit: str
backup_tool_revision: str
def _sha256(path: Path) -> str:
@@ -62,6 +64,8 @@ def verify_current_backup(
missing = sorted(name for name in required if not (root / name).is_file())
if missing:
raise RuntimeError(f"Backup is incomplete; missing: {', '.join(missing)}")
if not (root / "storage-snapshot").is_dir():
raise RuntimeError("Backup is incomplete; missing: storage-snapshot")
checksum_lines = (root / "CHECKSUMS.sha256").read_text(encoding="utf-8").splitlines()
checked: set[str] = set()
@@ -93,6 +97,9 @@ def verify_current_backup(
raise RuntimeError("Backup was made from an insecure database configuration")
if manifest.get("inventory_mode") != "sha256" or manifest.get("storage_inventory_requested") is not True:
raise RuntimeError("Destructive maintenance requires a SHA-256 storage inventory backup")
if manifest.get("storage_snapshot_requested") is not True:
raise RuntimeError("Destructive maintenance requires a byte-complete storage snapshot")
verify_byte_snapshots(root)
created = _created_at(manifest.get("created_at"))
current = now or datetime.now(timezone.utc)
@@ -107,17 +114,17 @@ def verify_current_backup(
)
release_id = manifest.get("release_id")
git_commit = manifest.get("git_commit")
backup_tool_revision = manifest.get("backup_tool_revision", manifest.get("git_commit"))
if not isinstance(release_id, str) or not release_id:
raise RuntimeError("Backup release id is missing")
if not isinstance(git_commit, str) or len(git_commit) < 7:
raise RuntimeError("Backup Git commit is missing")
if not isinstance(backup_tool_revision, str) or len(backup_tool_revision) < 7:
raise RuntimeError("Backup tool revision is missing")
return VerifiedBackup(
backup_dir=root,
release_id=release_id,
created_at=created,
age_hours=age_hours,
git_commit=git_commit,
backup_tool_revision=backup_tool_revision,
)