Skip to content

Commit 38e7024

Browse files
fix: Allow spec changes after ProgressDeadlineExceeded
Generated-by: Cursor:Claude
1 parent c304741 commit 38e7024

2 files changed

Lines changed: 91 additions & 18 deletions

File tree

internal/operator-controller/controllers/clusterobjectset_controller.go

Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ import (
3131
"sigs.k8s.io/controller-runtime/pkg/builder"
3232
"sigs.k8s.io/controller-runtime/pkg/client"
3333
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
34-
"sigs.k8s.io/controller-runtime/pkg/event"
3534
"sigs.k8s.io/controller-runtime/pkg/handler"
3635
"sigs.k8s.io/controller-runtime/pkg/log"
3736
"sigs.k8s.io/controller-runtime/pkg/predicate"
@@ -344,29 +343,12 @@ type Sourcoser interface {
344343
}
345344

346345
func (c *ClusterObjectSetReconciler) SetupWithManager(mgr ctrl.Manager) error {
347-
skipProgressDeadlineExceededPredicate := predicate.Funcs{
348-
UpdateFunc: func(e event.UpdateEvent) bool {
349-
rev, ok := e.ObjectNew.(*ocv1.ClusterObjectSet)
350-
if !ok {
351-
return true
352-
}
353-
// allow deletions to happen
354-
if !rev.DeletionTimestamp.IsZero() {
355-
return true
356-
}
357-
if cnd := meta.FindStatusCondition(rev.Status.Conditions, ocv1.ClusterObjectSetTypeProgressing); cnd != nil && cnd.Status == metav1.ConditionFalse && cnd.Reason == ocv1.ReasonProgressDeadlineExceeded {
358-
return false
359-
}
360-
return true
361-
},
362-
}
363346
c.Clock = clock.RealClock{}
364347
return ctrl.NewControllerManagedBy(mgr).
365348
For(
366349
&ocv1.ClusterObjectSet{},
367350
builder.WithPredicates(
368351
predicate.ResourceVersionChangedPredicate{},
369-
skipProgressDeadlineExceededPredicate,
370352
),
371353
).
372354
WatchesRawSource(
@@ -685,6 +667,11 @@ func setRetryingConditions(cos *ocv1.ClusterObjectSet, message string) {
685667
}
686668

687669
func markAsProgressing(cos *ocv1.ClusterObjectSet, reason, message string) {
670+
if cnd := meta.FindStatusCondition(cos.Status.Conditions, ocv1.ClusterObjectSetTypeProgressing); cnd != nil &&
671+
cnd.Status == metav1.ConditionFalse && cnd.Reason == ocv1.ReasonProgressDeadlineExceeded &&
672+
reason != ocv1.ReasonSucceeded {
673+
return
674+
}
688675
meta.SetStatusCondition(&cos.Status.Conditions, metav1.Condition{
689676
Type: ocv1.ClusterObjectSetTypeProgressing,
690677
Status: metav1.ConditionTrue,

internal/operator-controller/controllers/clusterobjectset_controller_internal_test.go

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"time"
77

88
"github.com/stretchr/testify/require"
9+
"k8s.io/apimachinery/pkg/api/meta"
910
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1011
"k8s.io/apimachinery/pkg/runtime"
1112
"k8s.io/apimachinery/pkg/runtime/schema"
@@ -235,3 +236,88 @@ func (m *mockTrackingCacheInternal) Watch(ctx context.Context, user client.Objec
235236
func (m *mockTrackingCacheInternal) Source(h handler.EventHandler, predicates ...predicate.Predicate) source.Source {
236237
return nil
237238
}
239+
240+
func Test_markAsProgressing_doesNotOverwriteProgressDeadlineExceeded(t *testing.T) {
241+
for _, tc := range []struct {
242+
name string
243+
existingConditions []metav1.Condition
244+
reason string
245+
expectProgressing metav1.ConditionStatus
246+
expectReason string
247+
}{
248+
{
249+
name: "sets Progressing when no condition exists",
250+
existingConditions: nil,
251+
reason: ocv1.ReasonRollingOut,
252+
expectProgressing: metav1.ConditionTrue,
253+
expectReason: ocv1.ReasonRollingOut,
254+
},
255+
{
256+
name: "sets Progressing when currently RollingOut",
257+
existingConditions: []metav1.Condition{
258+
{
259+
Type: ocv1.ClusterObjectSetTypeProgressing,
260+
Status: metav1.ConditionTrue,
261+
Reason: ocv1.ReasonRollingOut,
262+
},
263+
},
264+
reason: ocv1.ReasonSucceeded,
265+
expectProgressing: metav1.ConditionTrue,
266+
expectReason: ocv1.ReasonSucceeded,
267+
},
268+
{
269+
name: "does not overwrite ProgressDeadlineExceeded with RollingOut",
270+
existingConditions: []metav1.Condition{
271+
{
272+
Type: ocv1.ClusterObjectSetTypeProgressing,
273+
Status: metav1.ConditionFalse,
274+
Reason: ocv1.ReasonProgressDeadlineExceeded,
275+
},
276+
},
277+
reason: ocv1.ReasonRollingOut,
278+
expectProgressing: metav1.ConditionFalse,
279+
expectReason: ocv1.ReasonProgressDeadlineExceeded,
280+
},
281+
{
282+
name: "allows Succeeded to overwrite ProgressDeadlineExceeded",
283+
existingConditions: []metav1.Condition{
284+
{
285+
Type: ocv1.ClusterObjectSetTypeProgressing,
286+
Status: metav1.ConditionFalse,
287+
Reason: ocv1.ReasonProgressDeadlineExceeded,
288+
},
289+
},
290+
reason: ocv1.ReasonSucceeded,
291+
expectProgressing: metav1.ConditionTrue,
292+
expectReason: ocv1.ReasonSucceeded,
293+
},
294+
{
295+
name: "does not overwrite ProgressDeadlineExceeded with Retrying",
296+
existingConditions: []metav1.Condition{
297+
{
298+
Type: ocv1.ClusterObjectSetTypeProgressing,
299+
Status: metav1.ConditionFalse,
300+
Reason: ocv1.ReasonProgressDeadlineExceeded,
301+
},
302+
},
303+
reason: ocv1.ClusterObjectSetReasonRetrying,
304+
expectProgressing: metav1.ConditionFalse,
305+
expectReason: ocv1.ReasonProgressDeadlineExceeded,
306+
},
307+
} {
308+
t.Run(tc.name, func(t *testing.T) {
309+
cos := &ocv1.ClusterObjectSet{
310+
ObjectMeta: metav1.ObjectMeta{Generation: 1},
311+
Status: ocv1.ClusterObjectSetStatus{
312+
Conditions: tc.existingConditions,
313+
},
314+
}
315+
markAsProgressing(cos, tc.reason, "test message")
316+
317+
cnd := meta.FindStatusCondition(cos.Status.Conditions, ocv1.ClusterObjectSetTypeProgressing)
318+
require.NotNil(t, cnd)
319+
require.Equal(t, tc.expectProgressing, cnd.Status)
320+
require.Equal(t, tc.expectReason, cnd.Reason)
321+
})
322+
}
323+
}

0 commit comments

Comments
 (0)