GL-5: explicit rootfs override for DR restore (live-discovered PVE constraint)

The live validation hit PVE's all-or-nothing restore rule: mpN params
without an explicit rootfs -> HTTP 500 "mount points configured, but
'rootfs' not set" (the same constraint restoretest.go:211 documents for the
live-config path; the spike never ran an override restore). The lost guest
has no live config, so the rootfs SIZE now comes from the archive's own
embedded config via NEW Client.ExtractArchiveConfig (GET vzdump/
extractconfig - verified live: answers 200 under the scoped agent token;
PBS keys stay server-side, the spike's candidate-1 rejection holds; used
for the SIZE ONLY - the bind layout stays the platform constants).
Unparseable/unreadable archive config -> clean refusal before any restore.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PSK5g6qYLknKj8u3QAFEr6
This commit is contained in:
2026-07-08 09:02:36 +02:00
parent c12b512316
commit 3bf0110697
5 changed files with 122 additions and 5 deletions
+12
View File
@@ -63,6 +63,18 @@ func (c *Client) GuestConfig(ctx context.Context, vmid int) (GuestConfig, error)
return cfg, c.get(ctx, path, &cfg)
}
// ExtractArchiveConfig returns GET /nodes/{node}/vzdump/extractconfig — the guest config embedded
// in a backup archive, as raw pct-conf text. Token-covered (verified live under the scoped agent
// token on PVE 9.2.2, GL-5); for a PBS archive the storage-configured encryption key stays
// SERVER-side — the agent never touches key material (the DR spike's candidate-1 rejection holds).
// The DR bring-up reads ONLY the rootfs size from it: PVE refuses a restore that carries mpN
// params without an explicit rootfs, and the lost guest has no live config to size it from.
func (c *Client) ExtractArchiveConfig(ctx context.Context, volume string) (string, error) {
var out string
path := "/nodes/" + c.node + "/vzdump/extractconfig?volume=" + url.QueryEscape(volume)
return out, c.get(ctx, path, &out)
}
// ListSnapshots returns GET /nodes/{node}/lxc/{vmid}/snapshot (the guest's snapshots, including the
// synthetic "current"). The startup stale-lock recovery uses it to find a dangling "vzdump" snapshot
// left by an interrupted snapshot-mode backup.