GL-5: DR bring-up structural bind overrides + 4d real-bind swap
ModeDRGuestLoss now passes restore-time MountOverrides for the two
platform-constant structural binds (mp8 parent, mp9 bootstrap) via the
shared throwaway-volume format helper - without them a customer-archive
restore under the privsep token fails outright ("restoring 'mp8' to bind
mount is only possible for root"). New post-restore step 4d swaps the real
binds in via the host runner (root pct set, one slot per call), deletes the
displaced unusedN volumes (API config PUT; a scoped-token refusal logs the
residue loudly instead of widening privileges), and respects the
committed/launched rollback envelope. Provision passes nil overrides -
byte-identical behavior (regression contract test).
Engine grows an optional HostRunner + StateDir seam (DR refuses up front
without a runner); selftest bring-up wires the ExecRunner + cleans the
scratch mp9 host dir on teardown; proxmox.GuestConfig.Unused() added.
6 new tests incl. C2 mid-swap rollback + C3 older-archive + 403-warn paths.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PSK5g6qYLknKj8u3QAFEr6
This commit is contained in:
@@ -342,7 +342,7 @@ func bindMountOverrides(mps map[string]string, restoreStorage string) map[string
|
||||
if mp == "" {
|
||||
mp = volPart // fall back to the host path if no explicit in-guest mp=
|
||||
}
|
||||
out[key] = fmt.Sprintf("%s:1,mp=%s,backup=0", restoreStorage, mp)
|
||||
out[key] = throwawayVolumeOverride(restoreStorage, mp)
|
||||
}
|
||||
if len(out) == 0 {
|
||||
return nil
|
||||
@@ -350,6 +350,15 @@ func bindMountOverrides(mps map[string]string, restoreStorage string) map[string
|
||||
return out
|
||||
}
|
||||
|
||||
// throwawayVolumeOverride is the ONE source of the restore-override value format: a throwaway 1G
|
||||
// volume on restoreStorage at the given in-guest path, excluded from backup. Used by the
|
||||
// restore-test's source-config-derived overrides (above) and by the DR bring-up's synthesized
|
||||
// structural-bind overrides (GL-5, bringup.go — its mpN are platform constants, so it skips this
|
||||
// file's is-a-bind filtering and calls the format directly).
|
||||
func throwawayVolumeOverride(restoreStorage, guestPath string) string {
|
||||
return fmt.Sprintf("%s:1,mp=%s,backup=0", restoreStorage, guestPath)
|
||||
}
|
||||
|
||||
// mountPathOf returns the mp= field from an mpN value's trailing options ("" if absent).
|
||||
func mountPathOf(opts string) string {
|
||||
for _, kv := range strings.Split(opts, ",") {
|
||||
|
||||
Reference in New Issue
Block a user