Bind offline recovery to retained PostgreSQL and application image IDs

Assistant: codex
Assistant-Model: gpt-6.1-sol
Assistant-Session: 01a17f16-d99c-7ea3-95f0-8212897fba6b
This commit is contained in:
tegwick 2026-10-29 22:38:23 +01:00
parent 8700cc307b
commit 80e8550f9b
2 changed files with 16 additions and 1 deletions

View file

@ -81,6 +81,8 @@ def content_fingerprint(archive: Path, destination: Path) -> dict[str, str]:
def main() -> int:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument('snapshot', type=Path)
parser.add_argument('--postgres-image', default='postgres:16',
help='Local PostgreSQL image/digest; use the retained kit image ID offline')
parser.add_argument('--keep-instance', action='store_true',
help='Keep the isolated internal network/database for a content rehearsal')
args = parser.parse_args()
@ -95,7 +97,7 @@ def main() -> int:
name = 'csoc-recovery-' + time.strftime('%Y%m%d%H%M%S', time.gmtime())
network = name + '-net'
work = Path(tempfile.mkdtemp(prefix=name + '-', dir='/tmp'))
image = run(['docker', 'image', 'inspect', 'postgres:16',
image = run(['docker', 'image', 'inspect', args.postgres_image,
'--format', '{{.Id}}']).decode().strip()
if not re.fullmatch(r'sha256:[a-f0-9]{64}', image):
raise Refused('unresolved_postgres_image')

View file

@ -12,6 +12,11 @@ parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--restore-receipt", type=Path, required=True)
parser.add_argument("--snapshot", type=Path, required=True)
parser.add_argument("--output", type=Path, required=True)
parser.add_argument(
"--kit-manifest",
type=Path,
help="Bind offline image IDs to the independently verified kit manifest",
)
args = parser.parse_args()
if args.output.exists() or args.output.is_symlink():
raise SystemExit("fresh output required")
@ -19,6 +24,14 @@ state = json.loads(args.restore_receipt.read_text())
capture = json.loads((args.snapshot / "receipt.json").read_text())
assert capture["status"] == "captured" and capture["app_resumed"] and capture["writers_quiesced"]
image = capture["image"]
if args.kit_manifest:
kit = json.loads(args.kit_manifest.read_text())
assert kit["schema"] == "platform.coulomb-recovery-kit-manifest.v1"
assert kit["application_image"] == capture["image"]
assert kit["captured_at"] == capture["started_at"]
assert kit["postgres_image_id"] == state["postgres_image_id"]
image = kit["application_image_id"]
assert re.fullmatch(r"sha256:[a-f0-9]{64}", image)
if not re.fullmatch(r"csoc-recovery-\d{14}", state["database_container"]):
raise SystemExit("isolated recovery container required")
if state["network"] != state["database_container"] + "-net":