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