@@ -148,20 +148,44 @@ func PatchBMHForProvisioning(ctx context.Context, input PatchBMHForProvisioningI
148148// an annotation and waiting for the status.lastUpdated timestamp to change,
149149// which proves the controller reconciled the BMH.
150150func WaitForBmhReconciled (ctx context.Context , c client.Client , bmh metal3api.BareMetalHost , intervals ... interface {}) {
151- // Get the current BMH state
152151 key := types.NamespacedName {Namespace : bmh .Namespace , Name : bmh .Name }
152+
153+ // Get the initial lastUpdated timestamp before we trigger a reconcile
153154 currentBmh := & metal3api.BareMetalHost {}
154155 Expect (c .Get (ctx , key , currentBmh )).To (Succeed ())
155156 initialLastUpdated := currentBmh .Status .LastUpdated
156157
157- // Touch the BMH with an annotation update to trigger a reconcile
158- helper , err := patch .NewHelper (currentBmh , c )
159- Expect (err ).NotTo (HaveOccurred ())
160- if currentBmh .Annotations == nil {
161- currentBmh .Annotations = make (map [string ]string )
162- }
163- currentBmh .Annotations ["e2e.metal3.io/reconcile-check" ] = metav1 .Now ().Format ("2006-01-02T15:04:05Z" )
164- Expect (helper .Patch (ctx , currentBmh )).To (Succeed ())
158+ // Touch the BMH with an annotation update to trigger a reconcile.
159+ // Use Eventually because the webhook may not be ready immediately after
160+ // BMO deployment upgrade - it can take time for the webhook service
161+ // endpoint to become available.
162+ // We delete the annotation first, then add it, to ensure we always trigger
163+ // a fresh change even if a previous retry partially succeeded.
164+ Eventually (func () error {
165+ currentBmh := & metal3api.BareMetalHost {}
166+ if err := c .Get (ctx , key , currentBmh ); err != nil {
167+ return err
168+ }
169+ helper , err := patch .NewHelper (currentBmh , c )
170+ if err != nil {
171+ return err
172+ }
173+ // Delete annotation first to ensure a fresh change on each retry
174+ delete (currentBmh .Annotations , "e2e.metal3.io/reconcile-check" )
175+ if err = helper .Patch (ctx , currentBmh ); err != nil {
176+ return err
177+ }
178+ // Now add the annotation to trigger reconcile
179+ helper , err = patch .NewHelper (currentBmh , c )
180+ if err != nil {
181+ return err
182+ }
183+ if currentBmh .Annotations == nil {
184+ currentBmh .Annotations = make (map [string ]string )
185+ }
186+ currentBmh .Annotations ["e2e.metal3.io/reconcile-check" ] = metav1 .Now ().Format ("2006-01-02T15:04:05Z" )
187+ return helper .Patch (ctx , currentBmh )
188+ }, intervals ... ).Should (Succeed (), "failed to patch BMH to trigger reconcile (webhook may not be ready)" )
165189
166190 // Wait for lastUpdated to change, proving the controller processed our update
167191 Eventually (func (g Gomega ) {
0 commit comments