@@ -441,6 +441,24 @@ func (r *Reconciler) reconcileCluster(ctx context.Context, s *scope.Scope) error
441441 return errors .Wrapf (err , "failed to patch %s" , tlog.KObj {Obj : s .Current .Cluster })
442442 }
443443 r .recorder .Eventf (s .Current .Cluster , corev1 .EventTypeNormal , updateEventReason , "Updated %q" , tlog.KObj {Obj : s .Current .Cluster })
444+
445+ // Wait until Cluster is updated in the cache.
446+ // Note: We have to do this because otherwise using a cached client in the Reconcile func could
447+ // return a stale state of the Cluster we just patched (because the cache might be stale).
448+ // Note: It is good enough to check that the resource version changed. Other controllers might have updated the
449+ // Cluster as well, but the combination of the patch call above without a conflict and a changed resource
450+ // version here guarantees that we see the changes of our own update.
451+ err = wait .PollUntilContextTimeout (ctx , 5 * time .Millisecond , 5 * time .Second , true , func (ctx context.Context ) (bool , error ) {
452+ key := client.ObjectKey {Namespace : s .Current .Cluster .GetNamespace (), Name : s .Current .Cluster .GetName ()}
453+ cachedCluster := & clusterv1.Cluster {}
454+ if err := r .Client .Get (ctx , key , cachedCluster ); err != nil {
455+ return false , err
456+ }
457+ return s .Current .Cluster .GetResourceVersion () != cachedCluster .GetResourceVersion (), nil
458+ })
459+ if err != nil {
460+ return errors .Wrapf (err , "failed waiting for Cluster %s to be updated in the cache after patch" , tlog.KObj {Obj : s .Current .Cluster })
461+ }
444462 return nil
445463}
446464
@@ -578,7 +596,7 @@ func (r *Reconciler) createMachineDeployment(ctx context.Context, s *scope.Scope
578596 return true , nil
579597 })
580598 if err != nil {
581- return errors .Wrapf (err , "failed to create %s: failed waiting for MachineDeployment to be visible in cache" , md .Object .Kind )
599+ return errors .Wrapf (err , "failed waiting for MachineDeployment %s to be visible in the cache after create " , md .Object .Kind )
582600 }
583601
584602 // If the MachineDeployment has defined a MachineHealthCheck reconcile it.
@@ -667,7 +685,7 @@ func (r *Reconciler) updateMachineDeployment(ctx context.Context, s *scope.Scope
667685 return currentMD .Object .GetResourceVersion () != cachedMD .GetResourceVersion (), nil
668686 })
669687 if err != nil {
670- return errors .Wrapf (err , "failed to patch %s: failed waiting for MachineDeployment to be updated in cache" , tlog.KObj {Obj : currentMD .Object })
688+ return errors .Wrapf (err , "failed waiting for MachineDeployment %s to be updated in the cache after patch " , tlog.KObj {Obj : currentMD .Object })
671689 }
672690
673691 // We want to call both cleanup functions even if one of them fails to clean up as much as possible.
0 commit comments