build-golden.sh 2.1.0 -> 3.0.0: a layout change is a major. The golden ships ONE data volume at a NEUTRAL path (/var/lib/felhom); both /var/lib/docker and /mnt/sys_drive are binds of subdirectories of it. mp1 is gone. The variant was chosen on measurement. Three candidates were built and rebooted (SPIKE-r165-phase0-2026-08-03.md); all three boot, reboot 3/3, give ONE df figure and keep a container's statfs(/) on the merged volume — the ordering worry that motivated the probe did not materialise. They differ only in which guarantee they break: volume-at-docker puts customer backups inside Docker's data-root; volume-at-sys_drive puts Docker's ENTIRE data-root under /mnt, which the controller container mounts wholesale (measured: it then sees /mnt/sys_drive/docker). V-c breaks neither. The four assertions were RETARGETED, never deleted, and each was RUN against a deliberately wrong shape — a real split guest and a real archive of it: 8 checks, 8 passed. A new 2b asserts both paths are ONE filesystem, which catches the S2 shape the spike ranked worse than the split. Assertion 5 replaces the old "was mp1 excluded?" guard, whose pattern could no longer match — a guard that cannot match has silently stopped guarding. Provisioning: one volume, one grow. SysDataGrowGB is FOLDED IN rather than dropped, because a census established that felhom-host-install.sh passes -sysdata-grow and the two do not upgrade in the same instant; dropping it would silently shrink every appliance by 42 of 250 GiB. The flags stay accepted for the same reason. The existing test was retargeted to pin the fold, and it caught the change before I did.
This commit is contained in:
@@ -265,10 +265,16 @@ func TestRunBringUp_StorageSplit_DataVolGrow(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// The golden-carried SSD user-data volume (/mnt/sys_drive) is grown via a SEPARATE resize on its
|
||||
// mpN slot (mp1), independent of the rootfs and Docker-data grows. With SysDataGrowGB=0 NO mp1
|
||||
// resize is issued (the volume stays at the golden size, still a separate mount).
|
||||
func TestRunBringUp_StorageSplit_SysDataGrow(t *testing.T) {
|
||||
// R-165 RETARGETED THIS TEST, and the retarget IS the contract change. There is no longer a second
|
||||
// volume, so `SysDataGrowGB` no longer drives its own resize on mp1 — its GiB are FOLDED INTO the
|
||||
// single volume's grow.
|
||||
//
|
||||
// FOLDED, NOT DROPPED, and that is the whole point. `felhom-host-install.sh` computes and passes
|
||||
// `-sysdata-grow` from the thin pool's free space, and an installer and an agent do not upgrade in
|
||||
// the same instant. Dropping the value would silently shrink every appliance built by an older
|
||||
// installer by the user-data share — 42 of 250 GiB on the standard branch — which is precisely the
|
||||
// "a knob that silently does nothing" outcome this work was told to avoid.
|
||||
func TestRunBringUp_StorageSplit_SysDataGrowIsFoldedIn(t *testing.T) {
|
||||
const vmid = 8051
|
||||
api := &fakeAPI{cfg: map[int]proxmox.GuestConfig{vmid: scratchCfg()}}
|
||||
e, _, q := newEngine(t, api, EmptyProvider{})
|
||||
@@ -277,26 +283,29 @@ func TestRunBringUp_StorageSplit_SysDataGrow(t *testing.T) {
|
||||
res := e.RunBringUp(context.Background(), BringUpSpec{
|
||||
Mode: ModeProvision, Archive: "local:backup/golden.tar.zst", VMID: vmid,
|
||||
RestoreStorage: "local-lvm", Hostname: "felhom-prov-8051",
|
||||
DataVolGrowGB: 240, SysDataGrowGB: 42, // grows mp0 AND mp1 (DefaultSysDataMount)
|
||||
DataVolGrowGB: 240, SysDataGrowGB: 42, // ONE volume: 240 + 42 = 282
|
||||
})
|
||||
if res.Err != nil || !res.Pass {
|
||||
t.Fatalf("provision must pass, got %+v", res)
|
||||
}
|
||||
// TWO resizes here: Docker-data mp0 +240G and the user-data volume mp1 +42G (no rootfs grow).
|
||||
if len(api.resizes) != 2 {
|
||||
t.Fatalf("expected data-volume + sys-data resizes, got %+v", api.resizes)
|
||||
// EXACTLY ONE resize. A second one would mean an mp1 the golden no longer ships.
|
||||
if len(api.resizes) != 1 {
|
||||
t.Fatalf("expected exactly ONE data-volume resize (there is no mp1 since R-165), got %+v", api.resizes)
|
||||
}
|
||||
var sawData, sawSys bool
|
||||
for _, r := range api.resizes {
|
||||
if r.disk == "mp0" && r.size == "+240G" {
|
||||
sawData = true
|
||||
}
|
||||
if r.disk == "mp1" && r.size == "+42G" {
|
||||
sawSys = true
|
||||
}
|
||||
r := api.resizes[0]
|
||||
if r.disk != "mp0" {
|
||||
t.Fatalf("resized %q, want mp0 — the single data volume", r.disk)
|
||||
}
|
||||
if !sawData || !sawSys {
|
||||
t.Errorf("want mp0 +240G AND mp1 +42G, got %+v", api.resizes)
|
||||
if r.size != "+282G" {
|
||||
t.Fatalf("resized %s, want +282G (240 data + 42 folded sys-data). Anything less means the "+
|
||||
"retired knob's GiB were DROPPED, silently shrinking every appliance an older "+
|
||||
"felhom-host-install.sh provisions", r.size)
|
||||
}
|
||||
for _, rr := range api.resizes {
|
||||
if rr.disk == "mp1" {
|
||||
t.Fatalf("an mp1 resize was issued (%+v) — the golden ships no second volume, so this "+
|
||||
"would fail on a real box", rr)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user