v0.53.0: restore guests INTO the felhom pool (pool-scoped-ACL enabler)

RestoreLXCOptions.Pool → pct restore --pool (omit-when-empty). New
reconcile.DefaultPool="felhom"; BringUpSpec.Pool threaded to the bring-up
restore; BOTH restore sites pool the guest (provision/DR via spec.Pool set to
DefaultPool by the CLI; restore-test scratch via DefaultPool = SPIKE residual
#2). No agent ACL change (ships in host-install v1.6.0); the pool param is inert
until the token has Pool.Allocate + the pool exists, so publishing is safe ahead
of the coordinated swap. Tests + red-proofs; go build/vet/test clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-01 12:32:41 +02:00
parent 33e3443545
commit 7639ab5c4b
8 changed files with 129 additions and 3 deletions
+36
View File
@@ -119,6 +119,42 @@ func TestBuildBringUpConfig_ResourceCaps(t *testing.T) {
}
}
// Both restore sites allocate the guest INTO the felhom pool (SPIKE 3b): the provision bring-up
// threads spec.Pool, and the restore-test hardcodes DefaultPool — else a pool-scoped token 403s on
// the created guest's config/start/destroy. Asserts via the fakeAPI's captured RestoreLXCOptions.
func TestRestoreSitesUsePool(t *testing.T) {
// provision bring-up: spec.Pool must flow to the restore
const vmid = 8060
api := &fakeAPI{cfg: map[int]proxmox.GuestConfig{vmid: scratchCfg()}}
e, _, q := newEngine(t, api, EmptyProvider{})
defer q.Close()
res := e.RunBringUp(context.Background(), BringUpSpec{
Mode: ModeProvision, Archive: "local:backup/g.tar.zst", VMID: vmid,
RestoreStorage: "local-lvm", Pool: DefaultPool,
})
if res.Err != nil || !res.Pass {
t.Fatalf("bring-up must pass: %+v", res)
}
if len(api.restores) != 1 || api.restores[0].Pool != DefaultPool {
t.Fatalf("provision restore must set Pool=%q, got %+v", DefaultPool, api.restores)
}
// restore-test: the scratch restore hardcodes DefaultPool
api2 := &fakeAPI{cfg: map[int]proxmox.GuestConfig{990000: scratchCfg()}}
e2, _, q2 := newEngine(t, api2, EmptyProvider{})
defer q2.Close()
rt := e2.RunRestoreTest(context.Background(), RestoreTestSpec{
Archive: "local:backup/x.tar.zst", RestoreStorage: "local-lvm",
ScratchMin: 990000, ScratchMax: 990009, SourceTier: "local",
})
if rt.Err != nil || !rt.Pass {
t.Fatalf("restore-test must pass: %+v", rt)
}
if len(api2.restores) != 1 || api2.restores[0].Pool != DefaultPool {
t.Fatalf("restore-test restore must set Pool=%q, got %+v", DefaultPool, api2.restores)
}
}
// The golden-carried Docker-data volume is grown via a SEPARATE resize on its mpN slot (B4),
// alongside (but distinct from) the rootfs grow.
func TestRunBringUp_StorageSplit_DataVolGrow(t *testing.T) {