@@ -22,7 +22,6 @@ import (
2222 "time"
2323
2424 corev1 "k8s.io/api/core/v1"
25- apierrors "k8s.io/apimachinery/pkg/api/errors"
2625 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2726 "k8s.io/apimachinery/pkg/runtime"
2827 ctrl "sigs.k8s.io/controller-runtime"
@@ -48,28 +47,6 @@ const (
4847 MaxRebootRetries = 20 // 10 minutes at 30s base intervals
4948)
5049
51- // getNextRequeueDelay calculates per-resource exponential backoff delay based on consecutive failures.
52- // This is used with ctrl.Result{RequeueAfter: delay} rather than the controller's built-in rate limiter
53- // because we need independent backoff per node based on each node's failure history, not global controller
54- // rate limiting. Each RebootNode tracks its own ConsecutiveFailures counter and gets its own backoff schedule.
55- // Returns: 30s, 1m, 2m, 5m (capped at max after 3+ failures)
56- func getNextRequeueDelay (consecutiveFailures int32 ) time.Duration {
57- delays := []time.Duration {
58- 30 * time .Second , // First retry after initial failure
59- 1 * time .Minute , // Second retry
60- 2 * time .Minute , // Third retry
61- 5 * time .Minute , // Fourth+ retry (capped)
62- }
63-
64- // Safely convert int32 to int for array indexing
65- idx := int (consecutiveFailures )
66- if idx >= len (delays ) {
67- return delays [len (delays )- 1 ] // Cap at maximum
68- }
69-
70- return delays [idx ]
71- }
72-
7350// conditionsChanged compares two sets of conditions and returns true if they differ.
7451// It checks the type, status, reason, and message of each condition.
7552func conditionsChanged (original , updated []metav1.Condition ) bool {
@@ -102,47 +79,25 @@ func conditionsChanged(original, updated []metav1.Condition) bool {
10279}
10380
10481// updateRebootNodeStatus is a helper function that handles status updates with proper error handling.
105- // It centralizes the status update logic to avoid code duplication and provides consistent handling
106- // of status updates across different code paths in the reconciliation loop.
107- //
108- //nolint:dupl // Similar to updateTerminateNodeStatus but operates on RebootNode type
82+ // It delegates to the generic updateNodeActionStatus function.
10983func (r * RebootNodeReconciler ) updateRebootNodeStatus (
11084 ctx context.Context ,
11185 req ctrl.Request ,
11286 original * janitordgxcnvidiacomv1alpha1.RebootNode ,
11387 updated * janitordgxcnvidiacomv1alpha1.RebootNode ,
11488 result ctrl.Result ,
11589) (ctrl.Result , error ) {
116- logger := log .FromContext (ctx )
117-
118- // Check if status changed by comparing individual fields.
119- // This status update is safe because controller-runtime uses leader election
120- // to ensure only one controller instance is active at a time, even with multiple replicas.
121- // The active controller has exclusive write access to RebootNode status.
122- statusChanged := original .Status .RetryCount != updated .Status .RetryCount ||
123- original .Status .ConsecutiveFailures != updated .Status .ConsecutiveFailures ||
124- (original .Status .StartTime == nil ) != (updated .Status .StartTime == nil ) ||
125- (original .Status .CompletionTime == nil ) != (updated .Status .CompletionTime == nil ) ||
126- conditionsChanged (original .Status .Conditions , updated .Status .Conditions )
127-
128- if statusChanged {
129- if err := r .Status ().Update (ctx , updated ); err != nil {
130- if apierrors .IsNotFound (err ) {
131- logger .V (0 ).Info ("post-reconciliation status update: object not found, assumed deleted" ,
132- "name" , updated .Name )
133- return ctrl.Result {}, nil
134- }
135- logger .Error (err , "failed to update rebootnode status" ,
136- "node" , updated .Spec .NodeName )
137- return ctrl.Result {}, err
138- }
139- logger .Info ("rebootnode status updated" ,
140- "node" , updated .Spec .NodeName ,
141- "retryCount" , int (updated .Status .RetryCount ),
142- "consecutiveFailures" , int (updated .Status .ConsecutiveFailures ))
143- }
144-
145- return result , nil
90+ return updateNodeActionStatus (
91+ ctx ,
92+ r .Status (),
93+ original ,
94+ updated ,
95+ & original .Status ,
96+ & updated .Status ,
97+ updated .Spec .NodeName ,
98+ "rebootnode" ,
99+ result ,
100+ )
146101}
147102
148103// RebootNodeReconciler reconciles a RebootNode object
0 commit comments