Skip to content

Commit 82bfbbd

Browse files
committed
Fix wait for cache in reconcile_state.go
Signed-off-by: Stefan Büringer [email protected]
1 parent a55f5e6 commit 82bfbbd

File tree

4 files changed

+50
-34
lines changed

4 files changed

+50
-34
lines changed

internal/controllers/topology/cluster/reconcile_state.go

Lines changed: 25 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -464,7 +464,7 @@ func (r *Reconciler) reconcileMachineHealthCheck(ctx context.Context, current, d
464464
if err != nil {
465465
return errors.Wrapf(err, "failed to create patch helper for MachineHealthCheck %s", klog.KObj(desired))
466466
}
467-
if err := helper.Patch(ctx); err != nil {
467+
if _, err := helper.Patch(ctx); err != nil {
468468
return errors.Wrapf(err, "failed to create MachineHealthCheck %s", klog.KObj(desired))
469469
}
470470
r.recorder.Eventf(desired, corev1.EventTypeNormal, createEventReason, "Created MachineHealthCheck %q", klog.KObj(desired))
@@ -500,7 +500,7 @@ func (r *Reconciler) reconcileMachineHealthCheck(ctx context.Context, current, d
500500
}
501501

502502
log.Info("Patching MachineHealthCheck")
503-
if err := patchHelper.Patch(ctx); err != nil {
503+
if _, err := patchHelper.Patch(ctx); err != nil {
504504
return errors.Wrapf(err, "failed to patch MachineHealthCheck %s", klog.KObj(current))
505505
}
506506
r.recorder.Eventf(current, corev1.EventTypeNormal, updateEventReason, "Updated MachineHealthCheck %q", klog.KObj(current))
@@ -530,19 +530,19 @@ func (r *Reconciler) reconcileCluster(ctx context.Context, s *scope.Scope) error
530530
} else {
531531
log.Info("Patching Cluster", "diff", string(changes))
532532
}
533-
if err := patchHelper.Patch(ctx); err != nil {
533+
modifiedResourceVersion, err := patchHelper.Patch(ctx)
534+
if err != nil {
534535
return errors.Wrapf(err, "failed to patch Cluster %s", klog.KObj(s.Current.Cluster))
535536
}
536537
r.recorder.Eventf(s.Current.Cluster, corev1.EventTypeNormal, updateEventReason, "Updated Cluster %q", klog.KObj(s.Current.Cluster))
537538

538539
// Wait until Cluster is updated in the cache.
539540
// Note: We have to do this because otherwise using a cached client in the Reconcile func could
540541
// return a stale state of the Cluster we just patched (because the cache might be stale).
541-
// Note: It is good enough to check that the resource version changed. Other controllers might have updated the
542-
// Cluster as well, but the combination of the patch call above without a conflict and a changed resource
543-
// version here guarantees that we see the changes of our own update.
544542
// Note: Using DeepCopy to not modify s.Current.Cluster as it's not trivial to figure out what impact that would have.
545-
return clientutil.WaitForCacheToBeUpToDate(ctx, r.Client, "Cluster update", s.Current.Cluster.DeepCopy())
543+
cluster := s.Current.Cluster.DeepCopy()
544+
cluster.ResourceVersion = modifiedResourceVersion
545+
return clientutil.WaitForCacheToBeUpToDate(ctx, r.Client, "Cluster update", cluster)
546546
}
547547

548548
// reconcileMachineDeployments reconciles the desired state of the MachineDeployment objects.
@@ -693,7 +693,7 @@ func (r *Reconciler) createMachineDeployment(ctx context.Context, s *scope.Scope
693693
bootstrapCleanupFunc()
694694
return createErrorWithoutObjectName(ctx, err, md.Object)
695695
}
696-
if err := helper.Patch(ctx); err != nil {
696+
if _, err := helper.Patch(ctx); err != nil {
697697
// Best effort cleanup of the InfrastructureMachineTemplate & BootstrapTemplate (only on creation).
698698
infrastructureMachineCleanupFunc()
699699
bootstrapCleanupFunc()
@@ -814,7 +814,8 @@ func (r *Reconciler) updateMachineDeployment(ctx context.Context, s *scope.Scope
814814
} else {
815815
log.Info("Patching MachineDeployment", "diff", string(changes))
816816
}
817-
if err := patchHelper.Patch(ctx); err != nil {
817+
modifiedResourceVersion, err := patchHelper.Patch(ctx)
818+
if err != nil {
818819
// Best effort cleanup of the InfrastructureMachineTemplate & BootstrapTemplate (only on template rotation).
819820
infrastructureMachineCleanupFunc()
820821
bootstrapCleanupFunc()
@@ -825,10 +826,10 @@ func (r *Reconciler) updateMachineDeployment(ctx context.Context, s *scope.Scope
825826
// Wait until MachineDeployment is updated in the cache.
826827
// Note: We have to do this because otherwise using a cached client in current state could
827828
// return a stale state of a MachineDeployment we just patched (because the cache might be stale).
828-
// Note: It is good enough to check that the resource version changed. Other controllers might have updated the
829-
// MachineDeployment as well, but the combination of the patch call above without a conflict and a changed resource
830-
// version here guarantees that we see the changes of our own update.
831-
if err := clientutil.WaitForCacheToBeUpToDate(ctx, r.Client, "MachineDeployment update", currentMD.Object); err != nil {
829+
// Note: Using DeepCopy to not modify currentMD.Object as it's not trivial to figure out what impact that would have.
830+
md := currentMD.Object.DeepCopy()
831+
md.ResourceVersion = modifiedResourceVersion
832+
if err := clientutil.WaitForCacheToBeUpToDate(ctx, r.Client, "MachineDeployment update", md); err != nil {
832833
return err
833834
}
834835

@@ -1016,7 +1017,7 @@ func (r *Reconciler) createMachinePool(ctx context.Context, s *scope.Scope, mp *
10161017
bootstrapCleanupFunc()
10171018
return createErrorWithoutObjectName(ctx, err, mp.Object)
10181019
}
1019-
if err := helper.Patch(ctx); err != nil {
1020+
if _, err := helper.Patch(ctx); err != nil {
10201021
// Best effort cleanup of the InfrastructureMachinePool & BootstrapConfig (only on creation).
10211022
infrastructureMachineMachinePoolCleanupFunc()
10221023
bootstrapCleanupFunc()
@@ -1077,7 +1078,8 @@ func (r *Reconciler) updateMachinePool(ctx context.Context, s *scope.Scope, mpTo
10771078
} else {
10781079
log.Info("Patching MachinePool", "diff", string(changes))
10791080
}
1080-
if err := patchHelper.Patch(ctx); err != nil {
1081+
modifiedResourceVersion, err := patchHelper.Patch(ctx)
1082+
if err != nil {
10811083
return errors.Wrapf(err, "failed to patch MachinePool %s", klog.KObj(currentMP.Object))
10821084
}
10831085
r.recorder.Eventf(cluster, corev1.EventTypeNormal, updateEventReason, "Updated MachinePool %q%s", klog.KObj(currentMP.Object), logMachinePoolVersionChange(currentMP.Object, desiredMP.Object))
@@ -1088,7 +1090,9 @@ func (r *Reconciler) updateMachinePool(ctx context.Context, s *scope.Scope, mpTo
10881090
// Note: It is good enough to check that the resource version changed. Other controllers might have updated the
10891091
// MachinePool as well, but the combination of the patch call above without a conflict and a changed resource
10901092
// version here guarantees that we see the changes of our own update.
1091-
if err := clientutil.WaitForCacheToBeUpToDate(ctx, r.Client, "MachinePool update", currentMP.Object); err != nil {
1093+
mp := currentMP.Object.DeepCopy()
1094+
mp.ResourceVersion = modifiedResourceVersion
1095+
if err := clientutil.WaitForCacheToBeUpToDate(ctx, r.Client, "MachinePool update", mp); err != nil {
10921096
return err
10931097
}
10941098

@@ -1193,7 +1197,7 @@ func (r *Reconciler) reconcileReferencedObject(ctx context.Context, in reconcile
11931197
if err != nil {
11941198
return false, errors.Wrap(createErrorWithoutObjectName(ctx, err, in.desired), "failed to create patch helper")
11951199
}
1196-
if err := helper.Patch(ctx); err != nil {
1200+
if _, err := helper.Patch(ctx); err != nil {
11971201
return false, createErrorWithoutObjectName(ctx, err, in.desired)
11981202
}
11991203
r.recorder.Eventf(in.cluster, corev1.EventTypeNormal, createEventReason, "Created %s %q", in.desired.GetKind(), klog.KObj(in.desired))
@@ -1224,7 +1228,7 @@ func (r *Reconciler) reconcileReferencedObject(ctx context.Context, in reconcile
12241228
} else {
12251229
log.Info(fmt.Sprintf("Patching %s", in.desired.GetKind()), "diff", string(changes))
12261230
}
1227-
if err := patchHelper.Patch(ctx); err != nil {
1231+
if _, err := patchHelper.Patch(ctx); err != nil {
12281232
return false, errors.Wrapf(err, "failed to patch %s %s", in.current.GetKind(), klog.KObj(in.current))
12291233
}
12301234
r.recorder.Eventf(in.cluster, corev1.EventTypeNormal, updateEventReason, "Updated %s %q%s", in.desired.GetKind(), klog.KObj(in.desired), logUnstructuredVersionChange(in.current, in.desired, in.versionGetter))
@@ -1279,7 +1283,7 @@ func (r *Reconciler) reconcileReferencedTemplate(ctx context.Context, in reconci
12791283
if err != nil {
12801284
return false, errors.Wrap(createErrorWithoutObjectName(ctx, err, in.desired), "failed to create patch helper")
12811285
}
1282-
if err := helper.Patch(ctx); err != nil {
1286+
if _, err := helper.Patch(ctx); err != nil {
12831287
return false, createErrorWithoutObjectName(ctx, err, in.desired)
12841288
}
12851289
r.recorder.Eventf(in.cluster, corev1.EventTypeNormal, createEventReason, "Created %s %q", in.desired.GetKind(), klog.KObj(in.desired))
@@ -1319,7 +1323,7 @@ func (r *Reconciler) reconcileReferencedTemplate(ctx context.Context, in reconci
13191323
} else {
13201324
log.Info(fmt.Sprintf("Patching %s", in.desired.GetKind()), "diff", string(changes))
13211325
}
1322-
if err := patchHelper.Patch(ctx); err != nil {
1326+
if _, err := patchHelper.Patch(ctx); err != nil {
13231327
return false, errors.Wrapf(err, "failed to patch %s %s", in.desired.GetKind(), klog.KObj(in.desired))
13241328
}
13251329
r.recorder.Eventf(in.cluster, corev1.EventTypeNormal, updateEventReason, "Updated %s %q (metadata changes)", in.desired.GetKind(), klog.KObj(in.desired))
@@ -1344,7 +1348,7 @@ func (r *Reconciler) reconcileReferencedTemplate(ctx context.Context, in reconci
13441348
if err != nil {
13451349
return false, errors.Wrap(createErrorWithoutObjectName(ctx, err, in.desired), "failed to create patch helper")
13461350
}
1347-
if err := helper.Patch(ctx); err != nil {
1351+
if _, err := helper.Patch(ctx); err != nil {
13481352
return false, createErrorWithoutObjectName(ctx, err, in.desired)
13491353
}
13501354
r.recorder.Eventf(in.cluster, corev1.EventTypeNormal, createEventReason, "Created %s %q as a replacement for %q (template rotation)", in.desired.GetKind(), klog.KObj(in.desired), in.ref.Name)

internal/controllers/topology/cluster/structuredmerge/interfaces.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,5 +41,5 @@ type PatchHelper interface {
4141
Changes() []byte
4242

4343
// Patch patches the given obj in the Kubernetes cluster.
44-
Patch(ctx context.Context) error
44+
Patch(ctx context.Context) (modifiedResourceVersion string, err error)
4545
}

internal/controllers/topology/cluster/structuredmerge/serversidepathhelper.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -133,9 +133,9 @@ func (h *serverSidePatchHelper) HasChanges() bool {
133133
}
134134

135135
// Patch will server side apply the current intent (the modified object.
136-
func (h *serverSidePatchHelper) Patch(ctx context.Context) error {
136+
func (h *serverSidePatchHelper) Patch(ctx context.Context) (string, error) {
137137
if !h.HasChanges() {
138-
return nil
138+
return "", nil
139139
}
140140

141141
log := ctrl.LoggerFrom(ctx)
@@ -147,5 +147,8 @@ func (h *serverSidePatchHelper) Patch(ctx context.Context) error {
147147
// overwrite values and become sole manager.
148148
client.ForceOwnership,
149149
}
150-
return h.client.Apply(ctx, client.ApplyConfigurationFromUnstructured(h.modified), options...)
150+
if err := h.client.Apply(ctx, client.ApplyConfigurationFromUnstructured(h.modified), options...); err != nil {
151+
return "", err
152+
}
153+
return h.modified.GetResourceVersion(), nil
151154
}

internal/controllers/topology/cluster/structuredmerge/serversidepathhelper_test.go

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,8 @@ func TestServerSideApply(t *testing.T) {
104104
g.Expect(p0.Changes()).To(BeNil()) // changes are expected to be nil on create.
105105

106106
// Create the object using server side apply
107-
g.Expect(p0.Patch(ctx)).To(Succeed())
107+
_, err = p0.Patch(ctx)
108+
g.Expect(err).ToNot(HaveOccurred())
108109

109110
// Check the object and verify managed field are properly set.
110111
got := obj.DeepCopy()
@@ -306,7 +307,8 @@ func TestServerSideApply(t *testing.T) {
306307
g.Expect(p0.Changes()).To(BeNil())
307308

308309
// Change the object using server side apply
309-
g.Expect(p0.Patch(ctx)).To(Succeed())
310+
_, err = p0.Patch(ctx)
311+
g.Expect(err).ToNot(HaveOccurred())
310312

311313
// Check the object and verify fields set by the other controller are preserved.
312314
got := obj.DeepCopy()
@@ -354,7 +356,8 @@ func TestServerSideApply(t *testing.T) {
354356
g.Expect(p0.Changes()).To(Equal([]byte(`{"spec":{"controlPlaneEndpoint":{"host":"changed"}}}`)))
355357

356358
// Create the object using server side apply
357-
g.Expect(p0.Patch(ctx)).To(Succeed())
359+
_, err = p0.Patch(ctx)
360+
g.Expect(err).ToNot(HaveOccurred())
358361

359362
// Check the object and verify the change is applied as well as the fields set by the other controller are still preserved.
360363
got := obj.DeepCopy()
@@ -393,7 +396,8 @@ func TestServerSideApply(t *testing.T) {
393396
g.Expect(p0.Changes()).To(BeEmpty()) // Note: metadata.managedFields have been removed from the diff to reduce log verbosity.
394397

395398
// Create the object using server side apply
396-
g.Expect(p0.Patch(ctx)).To(Succeed())
399+
_, err = p0.Patch(ctx)
400+
g.Expect(err).ToNot(HaveOccurred())
397401

398402
// Check the object and verify the change is applied as well as managed field updated accordingly.
399403
got := obj.DeepCopy()
@@ -434,7 +438,8 @@ func TestServerSideApply(t *testing.T) {
434438
g.Expect(p0.Changes()).To(Equal([]byte(`{"spec":{"bar":"changed-by-topology-controller"}}`)))
435439

436440
// Create the object using server side apply
437-
g.Expect(p0.Patch(ctx)).To(Succeed())
441+
_, err = p0.Patch(ctx)
442+
g.Expect(err).ToNot(HaveOccurred())
438443

439444
// Check the object and verify the change is applied as well as managed field updated accordingly.
440445
got := obj.DeepCopy()
@@ -667,7 +672,8 @@ func TestServerSideApplyWithDefaulting(t *testing.T) {
667672
g.Expect(err).ToNot(HaveOccurred())
668673
g.Expect(p0.HasChanges()).To(BeTrue())
669674
g.Expect(p0.HasSpecChanges()).To(BeTrue())
670-
g.Expect(p0.Patch(ctx)).To(Succeed())
675+
_, err = p0.Patch(ctx)
676+
g.Expect(err).ToNot(HaveOccurred())
671677
defer func() {
672678
g.Expect(env.CleanupAndWait(ctx, kct.DeepCopy())).To(Succeed())
673679
}()
@@ -731,7 +737,8 @@ func TestServerSideApplyWithDefaulting(t *testing.T) {
731737
g.Expect(err).ToNot(HaveOccurred())
732738
g.Expect(p0.HasChanges()).To(Equal(tt.expectChanges), fmt.Sprintf("changes: %s", string(p0.Changes())))
733739
g.Expect(p0.HasSpecChanges()).To(Equal(tt.expectSpecChanges))
734-
g.Expect(p0.Patch(ctx)).To(Succeed())
740+
_, err = p0.Patch(ctx)
741+
g.Expect(err).ToNot(HaveOccurred())
735742

736743
// Verify field ownership
737744
// Note: It might take a bit for the cache to be up-to-date.
@@ -779,7 +786,8 @@ func TestServerSideApplyWithDefaulting(t *testing.T) {
779786
// Expect no changes.
780787
g.Expect(p0.HasChanges()).To(BeFalse())
781788
g.Expect(p0.HasSpecChanges()).To(BeFalse())
782-
g.Expect(p0.Patch(ctx)).To(Succeed())
789+
_, err := p0.Patch(ctx)
790+
g.Expect(err).ToNot(HaveOccurred())
783791

784792
// Expect webhook to be called.
785793
g.Expect(defaulter.Counter).To(Equal(countBefore+2),
@@ -806,7 +814,8 @@ func TestServerSideApplyWithDefaulting(t *testing.T) {
806814
// Expect no changes.
807815
g.Expect(p0.HasChanges()).To(BeFalse())
808816
g.Expect(p0.HasSpecChanges()).To(BeFalse())
809-
g.Expect(p0.Patch(ctx)).To(Succeed())
817+
_, err = p0.Patch(ctx)
818+
g.Expect(err).ToNot(HaveOccurred())
810819

811820
// Expect webhook to not be called.
812821
g.Expect(defaulter.Counter).To(Equal(countBefore),

0 commit comments

Comments
 (0)