fix(release): make deployment backup and rollback immutable
This commit is contained in:
@@ -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,
|
||||
)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user