hub v0.13.0: DR recipe — assemble + store + view the secret-free reconstruction recipe

DR recipe slice (hub half), grounded in SPIKE-dr-recipe-2026-06-16. The hub
receives two additive dr_recipe halves on the existing report paths (agent
storage/guest/PBS on host-report; controller customer/apps on the controller
report), stores them PLAINTEXT in a DEDICATED dr_recipe table keyed by customer
(each half preserves the other), and AssembleDRRecipe stitches them into one
operator-readable recipe (ignore-unknown + version-skew tolerant).

View: a DR-recipe panel on the customer page + GET /customers/{id}/dr-recipe.json
download (operator-auth, no secrets to redact). Plaintext-at-rest is correct —
the recipe is the clean inverse of the retired infra-backup.

Tests: store round-trip (each half preserves the other), assemble-matches-golden,
ignore-unknown + version skew, partial halves, no-secrets sweep. Manifest tag
bumped to v0.13.0.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-16 18:49:45 +02:00
parent 228dac4c06
commit 5f5e3c54a1
13 changed files with 597 additions and 69 deletions
+30
View File
@@ -0,0 +1,30 @@
{
"recipe_version": 1,
"customer": { "id": "cust-demo", "display": "Demo Customer", "domain": "demo-felhom.eu" },
"guests": [
{ "vmid": 9201, "cores": 4, "memory_bytes": 12884901888, "disk_bytes": 34359738368 }
],
"pbs": { "repo_id": "felhom-pbs", "namespace": "root", "latest_snapshot_id": "9201" },
"drives": [
{
"durable_id": "uuid:da9e7089-cf8e-4617-adcb-a377743fae00",
"role": "bulk-data",
"mount_path": "/mnt/felhom-usb",
"intent": "enrolled",
"total_bytes": 1000000000000
}
],
"pve_storage": [
{ "name": "local-lvm", "type": "lvmthin", "content": "rootdir,images" },
{ "name": "felhom-usb", "type": "usb", "content": "backup" }
],
"apps": [
{
"catalog_ref": "romm",
"enabled": true,
"storage_bindings": [
{ "container_path": "/roms", "drive": "felhom-flash", "subpath": "userdata/roms" }
]
}
]
}