Skip to content

Commit afcdf10

Browse files
committed
[BACKPORT] Ensure re-sync is triggered
Backport from 61e76e2 Signed-off-by: David Cassany <[email protected]>
1 parent a810bd3 commit afcdf10

File tree

2 files changed

+74
-9
lines changed

2 files changed

+74
-9
lines changed

controllers/managedosversionchannel_controller.go

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -187,12 +187,12 @@ func (r *ManagedOSVersionChannelReconciler) reconcile(ctx context.Context, manag
187187

188188
if readyCondition.Status == metav1.ConditionTrue {
189189
logger.Info("synchronization already done", "lastSync", lastSync)
190-
return ctrl.Result{}, nil
190+
return ctrl.Result{RequeueAfter: time.Until(lastSync.Add(interval))}, nil
191191
}
192192

193193
if managedOSVersionChannel.Status.FailedSynchronizationAttempts > maxConscutiveFailures {
194194
logger.Error(fmt.Errorf("stop retrying"), "sychronization failed consecutively too many times", "failed attempts", managedOSVersionChannel.Status.FailedSynchronizationAttempts)
195-
return ctrl.Result{}, nil
195+
return ctrl.Result{RequeueAfter: time.Until(lastSync.Add(interval))}, nil
196196
}
197197

198198
pod := &corev1.Pod{}
@@ -453,6 +453,11 @@ func (r *ManagedOSVersionChannelReconciler) createSyncerPod(ctx context.Context,
453453
return nil
454454
}
455455

456+
// filterChannelEvents is a method that filters reconcile requests events for the channels reconciler.
457+
// ManagedOSVersionChannelReconciler watches channels and owned pods. This filter ignores pod
458+
// create/delete/generic events and only reacts on pod phase updates. Channel update events are
459+
// only reconciled if the update includes a new generation of the resource, all other events are not
460+
// filtered.
456461
func filterChannelEvents() predicate.Funcs {
457462
return predicate.Funcs{
458463
// Process only new generation updates for channels and new phase for pods updates
@@ -500,5 +505,16 @@ func filterChannelEvents() predicate.Funcs {
500505
logger.V(log.DebugDepth).Info("Processing generic event", "Obj", e.Object.GetName())
501506
return true
502507
},
508+
// Ignore pods creation
509+
CreateFunc: func(e event.CreateEvent) bool {
510+
logger := ctrl.LoggerFrom(context.Background())
511+
512+
if _, ok := e.Object.(*corev1.Pod); ok {
513+
return false
514+
}
515+
// Return true in case it watches other types
516+
logger.V(log.DebugDepth).Info("Processing create event", "Obj", e.Object.GetName())
517+
return true
518+
},
503519
}
504520
}

controllers/managedosversionchannel_controller_test.go

Lines changed: 56 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -193,10 +193,11 @@ var _ = Describe("reconcile managed os version channel", func() {
193193
Namespace: pod.Namespace,
194194
}, pod)).NotTo(Succeed())
195195

196-
// No re-sync can be triggered before the minium time between syncs
196+
// Re-sync is triggered to interval
197197
res, err = r.Reconcile(ctx, reconcile.Request{NamespacedName: name})
198198
Expect(err).ToNot(HaveOccurred())
199-
Expect(res.RequeueAfter).To(Equal(0 * time.Second))
199+
Expect(res.RequeueAfter).To(BeNumerically("<", 1*time.Minute))
200+
Expect(res.RequeueAfter).To(BeNumerically(">", 59*time.Second))
200201
})
201202

202203
It("should reconcile managed os version channel object without a type", func() {
@@ -533,14 +534,14 @@ var _ = Describe("managed os version channel controller integration tests", func
533534
Namespace: ch.Namespace,
534535
}, pod)
535536
return err != nil && apierrors.IsNotFound(err)
536-
}, 12*time.Second, 2*time.Second).Should(BeTrue())
537+
}, 6*time.Second, 1*time.Second).Should(BeTrue())
537538

538539
// Simulate a channel content change
539540
syncerProvider.SetJSON(updatedJSON)
540541

541-
// Updating the channel after the minimum time between syncs causes an automatic update
542+
// Updating the channel causes an automatic update
542543
patchBase := client.MergeFrom(ch.DeepCopy())
543-
ch.Spec.SyncInterval = "10m"
544+
ch.Spec.SyncInterval = "10s"
544545
Expect(cl.Patch(ctx, ch, patchBase)).To(Succeed())
545546

546547
// Pod is created
@@ -550,7 +551,7 @@ var _ = Describe("managed os version channel controller integration tests", func
550551
Namespace: ch.Namespace,
551552
}, pod)
552553
return err == nil
553-
}, 12*time.Second, 2*time.Second).Should(BeTrue())
554+
}, 6*time.Second, 1*time.Second).Should(BeTrue())
554555
setPodPhase(pod, corev1.PodSucceeded)
555556

556557
// New added versions are synced
@@ -560,14 +561,62 @@ var _ = Describe("managed os version channel controller integration tests", func
560561
Namespace: ch.Namespace,
561562
}, managedOSVersion)
562563
return err == nil
563-
}, 12*time.Second, 2*time.Second).Should(BeTrue())
564+
}, 6*time.Second, 1*time.Second).Should(BeTrue())
564565

565566
// After channel update already existing versions were patched
566567
Expect(cl.Get(ctx, client.ObjectKey{
567568
Name: "v0.1.0",
568569
Namespace: ch.Namespace,
569570
}, managedOSVersion)).To(Succeed())
570571
Expect(managedOSVersion.Spec.Version).To(Equal("v0.1.0-patched"))
572+
573+
// Pod is deleted
574+
Eventually(func() bool {
575+
err := cl.Get(ctx, client.ObjectKey{
576+
Name: ch.Name,
577+
Namespace: ch.Namespace,
578+
}, pod)
579+
return err != nil && apierrors.IsNotFound(err)
580+
}, 2*time.Second, 1*time.Second).Should(BeTrue())
581+
582+
Expect(cl.Get(ctx, client.ObjectKey{
583+
Name: ch.Name,
584+
Namespace: ch.Namespace,
585+
}, ch)).To(Succeed())
586+
587+
// Simulate another channel content change
588+
syncerProvider.SetJSON(syncJSON)
589+
590+
timeout := time.Until(ch.Status.LastSyncedTime.Add(10*time.Second)) - 1*time.Second
591+
592+
// No pod is created during the interval
593+
Consistently(func() bool {
594+
err := cl.Get(ctx, client.ObjectKey{
595+
Name: ch.Name,
596+
Namespace: ch.Namespace,
597+
}, pod)
598+
return apierrors.IsNotFound(err)
599+
}, timeout, 1*time.Second).Should(BeTrue())
600+
601+
// Pod is created once the resync is triggered automatically
602+
Eventually(func() bool {
603+
err := cl.Get(ctx, client.ObjectKey{
604+
Name: ch.Name,
605+
Namespace: ch.Namespace,
606+
}, pod)
607+
return err == nil
608+
}, 4*time.Second, 1*time.Second).Should(BeTrue())
609+
setPodPhase(pod, corev1.PodSucceeded)
610+
611+
// v0.1.0 is updated
612+
Eventually(func() bool {
613+
Expect(cl.Get(ctx, client.ObjectKey{
614+
Name: "v0.1.0",
615+
Namespace: ch.Namespace,
616+
}, managedOSVersion)).To(Succeed())
617+
618+
return managedOSVersion.Spec.Version == "v0.1.0"
619+
}, 6*time.Second, 1*time.Second).Should(BeTrue())
571620
})
572621

573622
It("should not reconcile again if it errors during pod lifecycle", func() {

0 commit comments

Comments
 (0)