Skip to content

Commit 0935927

Browse files
committed
Fix CI bootstrap: defer mandatory kubeconfig load until after setup
The earlier safety-ordering commit broke CI: BuildConfigFromFlags was called BEFORE setupMultiTenant, but in CI the kubeconfig file is created BY setupMultiTenant (via kind-cluster-reset). Cold runs hit "stat /tmp/duckgres-kind-kubeconfig: no such file or directory" before the test bodies could run. Split the guard into two phases: Phase 1 (pre-setup, mandatory env-var check + conditional file check): - Always require DUCKGRES_K8S_TEST_KUBECONFIG to be set - If the file already exists (warm local rerun), validate it via requireLocalKindCluster BEFORE setupMultiTenant runs. This is what would have stopped the mw-dev incident in the env-pointed-at-real-cluster variant. - If the file doesn't exist yet (cold CI), skip the file load. setupMultiTenant's opening `kubectl delete namespace` runs against the missing path and fails inert ("no such file") — no damage possible because kubectl can't connect. Phase 2 (post-setup, mandatory): - File MUST exist now; load + requireLocalKindCluster. Final safety net for the cold-bootstrap path. Failure aborts before any test body runs. The env-unset path (the actual mw-dev incident shape) still fail-fasts in <1s with the existing REFUSING message, verified locally.
1 parent 0ed8924 commit 0935927

1 file changed

Lines changed: 38 additions & 6 deletions

File tree

tests/k8s/k8s_test.go

Lines changed: 38 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -89,12 +89,30 @@ kubeconfig was not touched.
8989
========================================================================
9090
`)
9191
}
92-
config, err := clientcmd.BuildConfigFromFlags("", kubeconfig)
93-
if err != nil {
94-
log.Fatalf("Failed to load kubeconfig: %v", err)
95-
}
96-
if err := requireLocalKindCluster(kubeconfig, config); err != nil {
97-
log.Fatalf("REFUSING to run k8s integration tests: %v", err)
92+
93+
// Pre-flight validation: if the kubeconfig FILE already exists at
94+
// this point (warm local run, or rerun after a previous successful
95+
// bootstrap), validate it BEFORE the destructive setupMultiTenant
96+
// call. This is the line that would have stopped the mw-dev incident:
97+
// the user had no DUCKGRES_K8S_TEST_KUBECONFIG set (caught above),
98+
// but if they had pointed it at ~/.kube/config we'd still need to
99+
// reject it before kubectl ran.
100+
//
101+
// On a cold CI bootstrap the file legitimately doesn't exist yet
102+
// (kind-cluster-reset inside setupMultiTenant creates it). In that
103+
// case the destructive `kubectl delete namespace` inside
104+
// setupMultiTenant runs against a missing kubeconfig and fails with
105+
// "stat ...: no such file or directory" — no damage is possible
106+
// because kubectl can't connect. The post-bootstrap validation
107+
// below is the mandatory check for that path.
108+
if _, statErr := os.Stat(kubeconfig); statErr == nil {
109+
preBootstrapCfg, err := clientcmd.BuildConfigFromFlags("", kubeconfig)
110+
if err != nil {
111+
log.Fatalf("Failed to load kubeconfig %q: %v", kubeconfig, err)
112+
}
113+
if err := requireLocalKindCluster(kubeconfig, preBootstrapCfg); err != nil {
114+
log.Fatalf("REFUSING to run k8s integration tests: %v", err)
115+
}
98116
}
99117

100118
skipSetup := envOr("DUCKGRES_K8S_TEST_SKIP_SETUP", "") == "true"
@@ -107,6 +125,20 @@ kubeconfig was not touched.
107125
}
108126
}
109127

128+
// Mandatory post-bootstrap validation. setupMultiTenant has now run
129+
// (or been skipped), so the kubeconfig file MUST exist and MUST
130+
// point at a local kind cluster. This is the last line of defence
131+
// against any cold-bootstrap path that slipped past the pre-flight
132+
// check above (e.g. file didn't exist at startup, setupMultiTenant
133+
// wrote one). Failure here aborts before any test body runs.
134+
config, err := clientcmd.BuildConfigFromFlags("", kubeconfig)
135+
if err != nil {
136+
log.Fatalf("Failed to load kubeconfig %q after setup: %v", kubeconfig, err)
137+
}
138+
if err := requireLocalKindCluster(kubeconfig, config); err != nil {
139+
log.Fatalf("REFUSING to run k8s integration tests: %v", err)
140+
}
141+
110142
clientset, err = kubernetes.NewForConfig(config)
111143
if err != nil {
112144
log.Fatalf("Failed to create k8s client: %v", err)

0 commit comments

Comments
 (0)