@@ -15,6 +15,7 @@ import (
1515 "github.com/stretchr/objx"
1616 corev1 "k8s.io/api/core/v1"
1717 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
18+ "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
1819 "k8s.io/apimachinery/pkg/runtime/schema"
1920 "k8s.io/client-go/discovery"
2021 "k8s.io/client-go/dynamic"
@@ -221,12 +222,28 @@ var _ = g.Describe("[sig-cluster-lifecycle][Feature:Machines][Serial] Managed cl
221222 dc , err = dynamic .NewForConfig (cfg )
222223 o .Expect (err ).NotTo (o .HaveOccurred ())
223224
224- // For baremetal platforms, an extra worker must be previously
225- // deployed to allow subsequent scaling operations
225+ // For baremetal platforms, extra workers must be previously
226+ // deployed to allow subsequent scaling operations. We need to
227+ // deploy one extra worker per machineSet since the test scales
228+ // all machineSets simultaneously.
226229 helper = bmhelper .NewBaremetalTestHelper (dc )
227230 if helper .CanDeployExtraWorkers () {
228231 helper .Setup ()
229- helper .DeployExtraWorker (0 )
232+ // Deploy extra workers for each machineSet that will be scaled
233+ machineSets , err := listWorkerMachineSets (dc )
234+ o .Expect (err ).NotTo (o .HaveOccurred ())
235+
236+ // Verify that extraworkers-secret has enough worker data for all machineSets
237+ // before attempting deployment. GetExtraWorkerData will fail if the index
238+ // doesn't exist in the secret.
239+ for i := range machineSets {
240+ _ , _ = helper .GetExtraWorkerData (i )
241+ }
242+
243+ // All extra worker data validated, now deploy them
244+ for i := range machineSets {
245+ helper .DeployExtraWorker (i )
246+ }
230247 }
231248
232249 configClient , err = configclient .NewForConfig (cfg )
@@ -298,6 +315,59 @@ var _ = g.Describe("[sig-cluster-lifecycle][Feature:Machines][Serial] Managed cl
298315 // TODO: skip if platform != aws
299316 skipUnlessMachineAPIOperator (dc , c .CoreV1 ().Namespaces ())
300317
318+ // For baremetal platforms without extraworkers-secret (non-dev-scripts deployments),
319+ // we need to verify sufficient BareMetalHosts are available before attempting to scale.
320+ // If extra workers were not deployed in BeforeEach, check for available hosts and skip if insufficient.
321+ if ! helper .CanDeployExtraWorkers () {
322+ g .By ("checking if baremetal platform has sufficient available hosts for scaling" )
323+
324+ // First check if BareMetalHost resource exists via discovery API
325+ cfg , err := e2e .LoadConfig ()
326+ o .Expect (err ).NotTo (o .HaveOccurred ())
327+ discoveryClient , err := discovery .NewDiscoveryClientForConfig (cfg )
328+ o .Expect (err ).NotTo (o .HaveOccurred ())
329+
330+ resourceList , err := discoveryClient .ServerResourcesForGroupVersion ("metal3.io/v1alpha1" )
331+ bmhResourceExists := false
332+ if err == nil {
333+ for _ , resource := range resourceList .APIResources {
334+ if resource .Name == "baremetalhosts" {
335+ bmhResourceExists = true
336+ break
337+ }
338+ }
339+ }
340+
341+ // If BareMetalHost resource exists, this is a baremetal platform - check for available hosts
342+ if bmhResourceExists {
343+ bmhGVR := schema.GroupVersionResource {Group : "metal3.io" , Resource : "baremetalhosts" , Version : "v1alpha1" }
344+ bmhClient := dc .Resource (bmhGVR ).Namespace (machineAPINamespace )
345+ bmhList , err := bmhClient .List (context .Background (), metav1.ListOptions {})
346+ o .Expect (err ).NotTo (o .HaveOccurred (), "failed to list BareMetalHosts for scaling preflight check" )
347+
348+ if len (bmhList .Items ) > 0 {
349+ availableHosts := 0
350+ for _ , item := range bmhList .Items {
351+ consumerRef , _ , _ := unstructured .NestedMap (item .Object , "spec" , "consumerRef" )
352+ state , _ , _ := unstructured .NestedString (item .Object , "status" , "provisioning" , "state" )
353+ // Count both "available" and "ready" (deprecated alias) states
354+ if consumerRef == nil && (state == "available" || state == "ready" ) {
355+ availableHosts ++
356+ }
357+ }
358+
359+ // Fetch machineSets to determine how many hosts we need
360+ machineSetsTemp , err := listWorkerMachineSets (dc )
361+ o .Expect (err ).NotTo (o .HaveOccurred ())
362+
363+ e2e .Logf ("Baremetal platform detected: %d available BareMetalHosts, %d worker machineSets" , availableHosts , len (machineSetsTemp ))
364+ if availableHosts < len (machineSetsTemp ) {
365+ e2eskipper .Skipf ("Insufficient BareMetalHosts for scaling test: need %d available hosts (one per machineSet), but only %d are available. This test requires extraworkers-secret (dev-scripts) or pre-provisioned available BareMetalHosts." , len (machineSetsTemp ), availableHosts )
366+ }
367+ }
368+ }
369+ }
370+
301371 g .By ("fetching worker machineSets" )
302372 machineSets , err := listWorkerMachineSets (dc )
303373 o .Expect (err ).NotTo (o .HaveOccurred ())
0 commit comments