From ab590c37e16d2cc5ceade3ac8fbc886c3e5a3322 Mon Sep 17 00:00:00 2001 From: James Nesbitt Date: Tue, 10 Nov 2026 15:07:49 +0200 Subject: [PATCH] Install MSR in the modern and upgrade smoke suites test/platforms.go has defined GetMSR() with zero callers. Every smoke suite set MSRVersion and smoke_test.go passed it to terraform as msr_version, but launchpad.tf:207 derives has_msr by counting msr-role nodegroups, so it was always false: :231 rendered `kind: mke`, the :273-281 msr block was skipped, and msr_version was discarded at the last gate. launchpad.tf:20 says as much -- "unused if you have no MSR hosts". The effect was that no smoke test has ever installed MSR, on any suite, while eight configurations read as though they covered it. That is how a review credited smoke-legacy with MSR 2.9.28 coverage it did not have. Three suites now carry an msr-role nodegroup on a platform already in their matrix: TestModernCluster (ubuntu24), TestUpgradeLegacyToModern (ubuntu22) and TestUpgradeModernClusterFromLegacy (ubuntu24). One m6a.2xlarge per run each. TestModernCluster's MSRVersion moves 3.1.18 -> 2.9.28. The terraform renders MSR 2.x only -- `kind: mke+msr` with --dtr-external-url and --ucp-insecure-tls -- and this launchpad has no MSR 3 support at all: no msr3 kind anywhere in pkg/, and the MSR phases are DTR-era. 3.1.18 would have produced a mke+msr document carrying a 3.x version. It had never been rendered, so nothing caught it. The upgrade suites now move MSR as well as MCR and MKE: 2.9.28 -> 2.9.30 across the MKE 3.8.8 -> 3.9.2 upgrade. bumpVersions takes an msrVersion and rewrites spec.msr.version beside the other two. An empty msrVersion leaves the document alone, which is the right shape for a cluster with no MSR node; a non-empty one against a document with no spec.msr is a configuration mistake and is reported rather than silently skipped. Verified against both document shapes: versions replaced, --san, --dtr-external-url and host addresses preserved verbatim, the no-MSR cluster untouched, and the mismatch rejected. go vet ./test/... clean. Written by AI: claude-opus-5 Signed-off-by: James Nesbitt --- test/smoke/smoke_test.go | 11 +++++++-- test/smoke/upgrade_test.go | 50 ++++++++++++++++++++++++++------------ 2 files changed, 44 insertions(+), 17 deletions(-) diff --git a/test/smoke/smoke_test.go b/test/smoke/smoke_test.go index 62ddd8c6..459c3bdd 100644 --- a/test/smoke/smoke_test.go +++ b/test/smoke/smoke_test.go @@ -225,13 +225,19 @@ func runSmokeTest(t *testing.T, cfg smokeConfig) { } // TestModernCluster exercises rhel9/ubuntu24/rocky9 managers and rhel9/sles15/ubuntu24/rocky9 workers -// with MCR stable-29.2 and MKE 3.9.2. +// with MCR stable-29.2 and MKE 3.9.2, plus an ubuntu24 MSR replica. +// +// MSR is 2.9.28, not 3.x: examples/terraform/aws-simple/launchpad.tf renders +// `kind: mke+msr` with --dtr-external-url and --ucp-insecure-tls, and this +// launchpad has no MSR 3 support at all. The 3.1.18 that stood here was never +// exercised -- with no msr-role nodegroup, launchpad.tf's has_msr was false +// and the whole msr block was skipped. func TestModernCluster(t *testing.T) { runSmokeTest(t, smokeConfig{ Name: "modern", MCRChannel: "stable-29.2", MKEVersion: "3.9.2", - MSRVersion: "3.1.18", + MSRVersion: "2.9.28", SSHKeyAlgorithm: "ed25519", Nodegroups: map[string]interface{}{ "MngrRhel9": test.Platforms["Rhel9"].GetManager(), @@ -241,6 +247,7 @@ func TestModernCluster(t *testing.T) { "WrkSles15": test.Platforms["Sles15"].GetWorker(), "WrkUbuntu24": test.Platforms["Ubuntu24"].GetWorker(), "WrkRocky9": test.Platforms["Rocky9"].GetWorker(), + "MsrUbuntu24": test.Platforms["Ubuntu24"].GetMSR(), }, }) } diff --git a/test/smoke/upgrade_test.go b/test/smoke/upgrade_test.go index 0aca5004..977520f4 100644 --- a/test/smoke/upgrade_test.go +++ b/test/smoke/upgrade_test.go @@ -45,6 +45,8 @@ type upgradeConfig struct { Base smokeConfig UpgradeMCRChannel string UpgradeMKEVersion string + // UpgradeMSRVersion is empty for a cluster with no MSR node. + UpgradeMSRVersion string } // runUpgradeTest provisions the cluster with Base versions, upgrades to the @@ -131,7 +133,7 @@ func runUpgradeTest(t *testing.T, cfg upgradeConfig) { // Unmarshal the Terraform-generated YAML into a generic map so we can // update version fields without disturbing host addresses, SANs, LB names, // or any other infrastructure-specific values the module injected. - upgradeYAML, err := bumpVersions(baseYAML, cfg.UpgradeMCRChannel, cfg.UpgradeMKEVersion) + upgradeYAML, err := bumpVersions(baseYAML, cfg.UpgradeMCRChannel, cfg.UpgradeMKEVersion, cfg.UpgradeMSRVersion) require.NoError(t, err, "mutate YAML for upgrade") // ── Step 3: upgrade ─────────────────────────────────────────────────────── @@ -164,12 +166,17 @@ func runUpgradeTest(t *testing.T, cfg upgradeConfig) { } } -// bumpVersions deserialises yamlStr, replaces spec.mcr.channel and -// spec.mke.version with the supplied values, and returns the re-serialised -// YAML. The rest of the document (hosts, SANs, LB addresses, flags, …) is -// preserved verbatim so the upgrade runs against the same infrastructure that -// was just provisioned. -func bumpVersions(yamlStr, mcrChannel, mkeVersion string) (string, error) { +// bumpVersions deserialises yamlStr, replaces spec.mcr.channel, +// spec.mke.version and spec.msr.version with the supplied values, and returns +// the re-serialised YAML. The rest of the document (hosts, SANs, LB +// addresses, flags, …) is preserved verbatim so the upgrade runs against the +// same infrastructure that was just provisioned. +// +// msrVersion is empty for a cluster with no MSR node: launchpad.tf only emits +// spec.msr when an msr-role nodegroup exists, so an absent block is the +// normal shape rather than an error, and an absent block with a version to +// apply is a configuration mistake worth reporting. +func bumpVersions(yamlStr, mcrChannel, mkeVersion, msrVersion string) (string, error) { var doc map[interface{}]interface{} if err := yaml.Unmarshal([]byte(yamlStr), &doc); err != nil { return "", fmt.Errorf("unmarshal cluster YAML: %w", err) @@ -192,6 +199,14 @@ func bumpVersions(yamlStr, mcrChannel, mkeVersion string) (string, error) { return "", fmt.Errorf("cluster YAML missing spec.mke") } + if msrVersion != "" { + msr, ok := spec["msr"].(map[interface{}]interface{}) + if !ok { + return "", fmt.Errorf("upgrade to MSR %s requested but cluster YAML has no spec.msr", msrVersion) + } + msr["version"] = msrVersion + } + out, err := yaml.Marshal(doc) if err != nil { return "", fmt.Errorf("re-marshal upgraded YAML: %w", err) @@ -199,10 +214,10 @@ func bumpVersions(yamlStr, mcrChannel, mkeVersion string) (string, error) { return string(out), nil } -// TestUpgradeLegacyToModern installs MKE 3.8.8 / MCR stable-25.0 on a -// legacy Linux matrix (rhel8, rocky8, ubuntu22) and then upgrades it to -// MKE 3.9.2 / MCR stable-29.2 in place. This is the primary real-world -// upgrade path for customers running the 3.8 stack. +// TestUpgradeLegacyToModern installs MKE 3.8.8 / MCR stable-25.0 / MSR 2.9.28 +// on a legacy Linux matrix (rhel8, rocky8, ubuntu22) and then upgrades it to +// MKE 3.9.2 / MCR stable-29.2 / MSR 2.9.30 in place. This is the primary +// real-world upgrade path for customers running the 3.8 stack. func TestUpgradeLegacyToModern(t *testing.T) { runUpgradeTest(t, upgradeConfig{ Base: smokeConfig{ @@ -218,17 +233,20 @@ func TestUpgradeLegacyToModern(t *testing.T) { "WrkRhel8": test.Platforms["Rhel8"].GetWorker(), "WrkRocky8": test.Platforms["Rocky8"].GetWorker(), "WrkUbuntu22": test.Platforms["Ubuntu22"].GetWorker(), + "MsrUbuntu22": test.Platforms["Ubuntu22"].GetMSR(), }, }, UpgradeMCRChannel: "stable-29.2", UpgradeMKEVersion: "3.9.2", + UpgradeMSRVersion: "2.9.30", }) } -// TestUpgradeModernClusterFromLegacy installs MKE 3.8.8 / MCR stable-25.0 on -// the modern Linux matrix (rhel9, ubuntu24, rocky9 managers; rhel9, sles15, -// ubuntu24, rocky9 workers -- same nodegroups as TestModernCluster) and then -// upgrades in place to MKE 3.9.2 / MCR stable-29.2. Exercises the same +// TestUpgradeModernClusterFromLegacy installs MKE 3.8.8 / MCR stable-25.0 / +// MSR 2.9.28 on the modern Linux matrix (rhel9, ubuntu24, rocky9 managers; +// rhel9, sles15, ubuntu24, rocky9 workers; ubuntu24 MSR -- same nodegroups as +// TestModernCluster) and then upgrades in place to MKE 3.9.2 / MCR +// stable-29.2 / MSR 2.9.30. Exercises the same // version transition as TestUpgradeLegacyToModern but against newer OS // releases, covering the per-OS configurer paths (rhel9/ubuntu24/rocky9/ // sles15) that TestUpgradeLegacyToModern's rhel8/rocky8/ubuntu22 matrix does @@ -249,9 +267,11 @@ func TestUpgradeModernClusterFromLegacy(t *testing.T) { "WrkSles15": test.Platforms["Sles15"].GetWorker(), "WrkUbuntu24": test.Platforms["Ubuntu24"].GetWorker(), "WrkRocky9": test.Platforms["Rocky9"].GetWorker(), + "MsrUbuntu24": test.Platforms["Ubuntu24"].GetMSR(), }, }, UpgradeMCRChannel: "stable-29.2", UpgradeMKEVersion: "3.9.2", + UpgradeMSRVersion: "2.9.30", }) }