Skip to content

Commit b64d0e2

Browse files
authored
Merge pull request #776 from fluxcd/remove-ready-check
Fix ImagePolicy reconciler spamming `no tags in database` after a restart
2 parents 9e8b90f + 8b4a10e commit b64d0e2

File tree

3 files changed

+21
-26
lines changed

3 files changed

+21
-26
lines changed

internal/controller/imagepolicy_controller.go

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -330,16 +330,6 @@ func (r *ImagePolicyReconciler) reconcile(ctx context.Context, sp *patch.SerialP
330330
return
331331
}
332332

333-
// Proceed only if the ImageRepository has scan result.
334-
if !conditions.IsReady(repo) {
335-
// Mark not ready but don't requeue. When the repository becomes ready,
336-
// it'll trigger a policy reconciliation. No runtime error to prevent
337-
// requeue.
338-
conditions.MarkFalse(obj, meta.ReadyCondition, imagev1.DependencyNotReadyReason, "referenced ImageRepository has not been scanned yet")
339-
result, retErr = ctrl.Result{}, nil
340-
return
341-
}
342-
343333
// Check if the image is valid and mark stalled if not.
344334
if _, err := registry.ParseImageReference(repo.Spec.Image, repo.Spec.Insecure); err != nil {
345335
conditions.MarkStalled(obj, imagev1.ImageURLInvalidReason, "%s", err)
@@ -368,10 +358,10 @@ func (r *ImagePolicyReconciler) reconcile(ctx context.Context, sp *patch.SerialP
368358
return
369359
}
370360

371-
// If there's no tag in the database, mark not ready and retry.
361+
// If there's no tag in the database, mark not ready.
372362
if err == errNoTagsInDatabase {
373363
conditions.MarkFalse(obj, meta.ReadyCondition, imagev1.DependencyNotReadyReason, "%s", err)
374-
result, retErr = ctrl.Result{}, err
364+
result, retErr = ctrl.Result{}, nil
375365
return
376366
}
377367

internal/controller/imagepolicy_controller_test.go

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ import (
4747
"github.com/fluxcd/image-reflector-controller/internal/test"
4848
)
4949

50-
func TestImagePolicyReconciler_imageRepoNotReady(t *testing.T) {
50+
func TestImagePolicyReconciler_imageRepoHasNoTags(t *testing.T) {
5151
g := NewWithT(t)
5252

5353
namespaceName := "imagepolicy-" + randStringRunes(5)
@@ -65,19 +65,14 @@ func TestImagePolicyReconciler_imageRepoNotReady(t *testing.T) {
6565
Name: "repo",
6666
},
6767
Spec: imagev1.ImageRepositorySpec{
68-
Image: "ghcr.io/stefanprodan/podinfo/foo:bar:zzz:qqq/aaa",
68+
Image: "ghcr.io/doesnot/exist",
6969
},
7070
}
7171
g.Expect(k8sClient.Create(ctx, imageRepo)).NotTo(HaveOccurred())
7272
t.Cleanup(func() {
7373
g.Expect(k8sClient.Delete(ctx, imageRepo)).NotTo(HaveOccurred())
7474
})
7575

76-
g.Eventually(func() bool {
77-
err := k8sClient.Get(ctx, client.ObjectKeyFromObject(imageRepo), imageRepo)
78-
return err == nil && conditions.IsStalled(imageRepo)
79-
}).Should(BeTrue())
80-
8176
imagePolicy := &imagev1.ImagePolicy{
8277
ObjectMeta: metav1.ObjectMeta{
8378
Namespace: namespaceName,
@@ -87,6 +82,9 @@ func TestImagePolicyReconciler_imageRepoNotReady(t *testing.T) {
8782
ImageRepositoryRef: meta.NamespacedObjectReference{
8883
Name: imageRepo.Name,
8984
},
85+
Policy: imagev1.ImagePolicyChoice{
86+
Alphabetical: &imagev1.AlphabeticalPolicy{},
87+
},
9088
},
9189
}
9290
g.Expect(k8sClient.Create(ctx, imagePolicy)).NotTo(HaveOccurred())
@@ -174,15 +172,17 @@ func TestImagePolicyReconciler_ignoresImageRepoNotReadyEvent(t *testing.T) {
174172
}).Should(BeTrue())
175173

176174
// Check that the ImagePolicy is still ready and does not get updated.
177-
err := k8sClient.Get(ctx, client.ObjectKeyFromObject(imagePolicy), imagePolicy)
178-
g.Expect(err).NotTo(HaveOccurred())
179-
g.Expect(conditions.IsReady(imagePolicy)).To(BeTrue())
175+
g.Eventually(func() bool {
176+
err := k8sClient.Get(ctx, client.ObjectKeyFromObject(imagePolicy), imagePolicy)
177+
return err == nil && conditions.IsReady(imagePolicy)
178+
}).Should(BeTrue())
180179

181180
// Wait a bit and check that the ImagePolicy remains ready.
182181
time.Sleep(time.Second)
183-
err = k8sClient.Get(ctx, client.ObjectKeyFromObject(imagePolicy), imagePolicy)
184-
g.Expect(err).NotTo(HaveOccurred())
185-
g.Expect(conditions.IsReady(imagePolicy)).To(BeTrue())
182+
g.Eventually(func() bool {
183+
err := k8sClient.Get(ctx, client.ObjectKeyFromObject(imagePolicy), imagePolicy)
184+
return err == nil && conditions.IsReady(imagePolicy)
185+
}).Should(BeTrue())
186186
}
187187

188188
func TestImagePolicyReconciler_invalidImage(t *testing.T) {

internal/controller/imagerepository_controller.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,12 @@ func (r *ImageRepositoryReconciler) reconcile(ctx context.Context, sp *patch.Ser
290290
// Scan the repository if it's scan time. No scan is a no-op reconciliation.
291291
// The next scan time is not reset in case of no-op reconciliation.
292292
if ok {
293-
reconcile.ProgressiveStatus(false, obj, meta.ProgressingReason, "scanning: %s", reasonMsg)
293+
// When the database is empty, we need to set the Ready condition to
294+
// Unknown to force a transition when the controller restarts.
295+
// This transition is required to unblock the ImagePolicy object
296+
// from the Ready condition stuck in False with reason DependencyNotReady.
297+
drift := reasonMsg == scanReasonEmptyDatabase
298+
reconcile.ProgressiveStatus(drift, obj, meta.ProgressingReason, "scanning: %s", reasonMsg)
294299
if err := sp.Patch(ctx, obj, r.patchOptions...); err != nil {
295300
result, retErr = ctrl.Result{}, err
296301
return

0 commit comments

Comments
 (0)