fix(gitea): add full backup restore drill receipt path

This commit is contained in:
ogt
2026-07-10 09:45:12 +08:00
parent 97312fa37a
commit 7fd76b3bcf
6 changed files with 387 additions and 8 deletions

View File

@@ -73,9 +73,11 @@ def load_latest_gitea_full_server_backup_dr_receipts(
def build_gitea_full_server_backup_source_contract(repo_root: Path) -> dict[str, Any]:
"""Inspect committed Gitea backup/offsite source without reading secrets."""
backup_script = repo_root / "scripts" / "backup" / "backup-gitea.sh"
restore_drill_script = repo_root / "scripts" / "backup" / "gitea-full-backup-restore-drill.sh"
sync_script = repo_root / "scripts" / "backup" / "sync-offsite-backups.sh"
verify_script = repo_root / "scripts" / "backup" / "verify-offsite-full-sync.sh"
backup_text = _read_text(backup_script)
restore_drill_text = _read_text(restore_drill_script)
sync_text = _read_text(sync_script)
verify_text = _read_text(verify_script)
metric_writer_present = (
@@ -83,6 +85,13 @@ def build_gitea_full_server_backup_source_contract(repo_root: Path) -> dict[str,
and "secret_value_collected" in backup_text
and "production_restore_performed" in backup_text
)
restore_drill_source_ready = (
"awoooi_gitea_full_backup_restore_drill_performed" in restore_drill_text
and "structural_metadata_only" in restore_drill_text
and "never restores to production" in restore_drill_text.lower()
and "SECRET_VALUES_COLLECTED=0" in restore_drill_text
and "PRODUCTION_RESTORE_PERFORMED=0" in restore_drill_text
)
gitea_dump_present = "gitea dump" in backup_text and "/tmp/gitea-dump.zip" in backup_text
restic_target_present = "restic -r" in backup_text and (
"/backup" in backup_text or "BACKUP_BASE" in backup_text
@@ -108,12 +117,16 @@ def build_gitea_full_server_backup_source_contract(repo_root: Path) -> dict[str,
"schema_version": "gitea_full_server_backup_source_contract_v1",
"source_refs": [
"scripts/backup/backup-gitea.sh",
"scripts/backup/gitea-full-backup-restore-drill.sh",
"scripts/backup/sync-offsite-backups.sh",
"scripts/backup/verify-offsite-full-sync.sh",
],
"gitea_dump_source_ready": gitea_dump_present,
"restic_target_source_ready": restic_target_present,
"component_metric_writer_source_ready": metric_writer_present,
"restore_drill_source_ready": restore_drill_source_ready,
"restore_drill_receipt_metric_writer_source_ready": restore_drill_source_ready,
"restore_drill_scope": "structural_metadata_only",
"google_drive_offsite_source_ready": offsite_source_ready,
"component_rows": component_rows,
"source_ready_component_count": sum(
@@ -151,6 +164,7 @@ def build_gitea_full_server_backup_dr_receipts(
"secret_values_collected_by_source_inspection": False,
}
receipt_metrics = _receipt_metric_rollup(metric_samples or [], host)
restore_drill_source_ready = contract.get("restore_drill_source_ready") is True
component_rows = [
{
@@ -192,20 +206,35 @@ def build_gitea_full_server_backup_dr_receipts(
"status": "verified_ready"
if receipt_metrics["restore_drill_performed"]
else "approval_required",
"evidence_refs": ["GET /api/v1/agents/backup-dr-readiness-matrix"],
"evidence_refs": [
"scripts/backup/gitea-full-backup-restore-drill.sh",
"GET /api/v1/agents/backup-dr-readiness-matrix",
"GET /api/v1/agents/backup-restore-drill-approval-package-template",
],
"receipt_state": "restore_drill_receipt_present"
if receipt_metrics["restore_drill_performed"]
else "restore_drill_source_ready_live_receipt_pending"
if restore_drill_source_ready
else "restore_drill_not_executed_by_readback",
"restore_scope": "restore requires controlled drill approval",
"restore_scope": str(
contract.get("restore_drill_scope") or "controlled_restore_drill"
),
"production_restore_performed": False,
"metrics": {
"gitea_restore_drill_status": str(
gitea_readiness.get("restore_drill_status") or ""
),
"restore_execution_allowed": False,
"restore_drill_source_ready": restore_drill_source_ready,
"restore_drill_receipt_metric_writer_source_ready": contract.get(
"restore_drill_receipt_metric_writer_source_ready"
)
is True,
"restore_drill_performed_metric": receipt_metrics[
"restore_drill_performed"
],
"secret_value_collection_allowed": False,
"production_restore_allowed": False,
},
},
*_component_receipt_rows(contract, receipt_metrics),
@@ -277,14 +306,19 @@ def build_gitea_full_server_backup_dr_receipts(
"component_receipt_count"
],
"gitea_full_backup_metric_error": metrics_error,
"restore_drill_source_ready": restore_drill_source_ready,
"restore_drill_receipt_pending": not receipt_metrics[
"restore_drill_performed"
],
"production_restore_performed": False,
},
"source_contract": contract,
"receipt_metric_rollup": receipt_metrics,
"component_rows": component_rows,
"safe_next_actions": [
"deploy backup-gitea.sh receipt metric writer and rerun the normal Gitea backup cadence",
"keep production restore disabled; use controlled restore-drill approval only",
"deploy gitea-full-backup-restore-drill.sh and run it against the latest Gitea dump in an isolated non-production drill",
"write the restore drill textfile receipt only after the structural drill passes",
"keep production restore disabled; production restore metrics must remain zero",
"verify Google Drive/offsite freshness with redacted non-secret receipts",
],
}