@@ -13,6 +13,7 @@ import (
1313 "time"
1414
1515 "k8s.io/apimachinery/pkg/api/meta"
16+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1617 "k8s.io/apimachinery/pkg/types"
1718 "k8s.io/client-go/tools/record"
1819 "k8s.io/client-go/util/workqueue"
4041 // errInitializedFailed is the error when the ClusterStagedUpdateRun fails to initialize.
4142 // It is a wrapped error of errStagedUpdatedAborted, because some initialization functions are reused in the validation step.
4243 errInitializedFailed = fmt .Errorf ("%w: failed to initialize the clusterStagedUpdateRun" , errStagedUpdatedAborted )
43-
44- // stageUpdatingWaitTime is the time to wait before rechecking the stage update status.
45- // Put it as a variable for convenient testing.
46- stageUpdatingWaitTime = 60 * time .Second
4744)
4845
4946// Reconciler reconciles a ClusterStagedUpdateRun object.
@@ -127,10 +124,35 @@ func (r *Reconciler) Reconcile(ctx context.Context, req runtime.Request) (runtim
127124 klog .V (2 ).InfoS ("The clusterStagedUpdateRun is validated" , "clusterStagedUpdateRun" , runObjRef )
128125 }
129126
130- // TODO(wantjian): execute the clusterStagedUpdateRun and fix the requeue time.
131- klog .V (2 ).InfoS ("Executing the clusterStagedUpdateRun" , "clusterStagedUpdateRun" , runObjRef , "updatingStageIndex" , updatingStageIndex ,
132- "toBeUpdatedBindings count" , len (toBeUpdatedBindings ), "toBeDeletedBindings count" , len (toBeDeletedBindings ))
133- return runtime.Result {RequeueAfter : stageUpdatingWaitTime }, nil
127+ // The previous run is completed but the update to the status failed.
128+ if updatingStageIndex == - 1 {
129+ klog .V (2 ).InfoS ("The clusterStagedUpdateRun is completed" , "clusterStagedUpdateRun" , runObjRef )
130+ return runtime.Result {}, r .recordUpdateRunSucceeded (ctx , & updateRun )
131+ }
132+
133+ // Execute the updateRun.
134+ klog .V (2 ).InfoS ("Continue to execute the clusterStagedUpdateRun" , "updatingStageIndex" , updatingStageIndex , "clusterStagedUpdateRun" , runObjRef )
135+ finished , waitTime , execErr := r .execute (ctx , & updateRun , updatingStageIndex , toBeUpdatedBindings , toBeDeletedBindings )
136+ if execErr != nil && errors .Is (execErr , errStagedUpdatedAborted ) {
137+ // errStagedUpdatedAborted cannot be retried.
138+ return runtime.Result {}, r .recordUpdateRunFailed (ctx , & updateRun , execErr .Error ())
139+ }
140+
141+ if finished {
142+ klog .V (2 ).InfoS ("The clusterStagedUpdateRun is completed" , "clusterStagedUpdateRun" , runObjRef )
143+ return runtime.Result {}, r .recordUpdateRunSucceeded (ctx , & updateRun )
144+ }
145+
146+ // The execution is not finished yet or it encounters a retriable error.
147+ // We need to record the status and requeue.
148+ if updateErr := r .recordUpdateRunStatus (ctx , & updateRun ); updateErr != nil {
149+ return runtime.Result {}, updateErr
150+ }
151+ klog .V (2 ).InfoS ("The clusterStagedUpdateRun is not finished yet" , "requeueWaitTime" , waitTime , "execErr" , execErr , "clusterStagedUpdateRun" , runObjRef )
152+ if execErr != nil {
153+ return runtime.Result {}, execErr
154+ }
155+ return runtime.Result {Requeue : true , RequeueAfter : waitTime }, nil
134156}
135157
136158// handleDelete handles the deletion of the clusterStagedUpdateRun object.
@@ -162,6 +184,48 @@ func (r *Reconciler) ensureFinalizer(ctx context.Context, updateRun *placementv1
162184 return r .Update (ctx , updateRun , client .FieldOwner (utils .UpdateRunControllerFieldManagerName ))
163185}
164186
187+ // recordUpdateRunSucceeded records the succeeded condition in the ClusterStagedUpdateRun status.
188+ func (r * Reconciler ) recordUpdateRunSucceeded (ctx context.Context , updateRun * placementv1alpha1.ClusterStagedUpdateRun ) error {
189+ meta .SetStatusCondition (& updateRun .Status .Conditions , metav1.Condition {
190+ Type : string (placementv1alpha1 .StagedUpdateRunConditionSucceeded ),
191+ Status : metav1 .ConditionTrue ,
192+ ObservedGeneration : updateRun .Generation ,
193+ Reason : condition .UpdateRunSucceededReason ,
194+ })
195+ if updateErr := r .Client .Status ().Update (ctx , updateRun ); updateErr != nil {
196+ klog .ErrorS (updateErr , "Failed to update the ClusterStagedUpdateRun status as succeeded" , "clusterStagedUpdateRun" , klog .KObj (updateRun ))
197+ // updateErr can be retried.
198+ return controller .NewUpdateIgnoreConflictError (updateErr )
199+ }
200+ return nil
201+ }
202+
203+ // recordUpdateRunFailed records the failed condition in the ClusterStagedUpdateRun status.
204+ func (r * Reconciler ) recordUpdateRunFailed (ctx context.Context , updateRun * placementv1alpha1.ClusterStagedUpdateRun , message string ) error {
205+ meta .SetStatusCondition (& updateRun .Status .Conditions , metav1.Condition {
206+ Type : string (placementv1alpha1 .StagedUpdateRunConditionSucceeded ),
207+ Status : metav1 .ConditionFalse ,
208+ ObservedGeneration : updateRun .Generation ,
209+ Reason : condition .UpdateRunFailedReason ,
210+ Message : message ,
211+ })
212+ if updateErr := r .Client .Status ().Update (ctx , updateRun ); updateErr != nil {
213+ klog .ErrorS (updateErr , "Failed to update the ClusterStagedUpdateRun status as failed" , "clusterStagedUpdateRun" , klog .KObj (updateRun ))
214+ // updateErr can be retried.
215+ return controller .NewUpdateIgnoreConflictError (updateErr )
216+ }
217+ return nil
218+ }
219+
220+ // recordUpdateRunStatus records the ClusterStagedUpdateRun status.
221+ func (r * Reconciler ) recordUpdateRunStatus (ctx context.Context , updateRun * placementv1alpha1.ClusterStagedUpdateRun ) error {
222+ if updateErr := r .Client .Status ().Update (ctx , updateRun ); updateErr != nil {
223+ klog .ErrorS (updateErr , "Failed to update the ClusterStagedUpdateRun status" , "clusterStagedUpdateRun" , klog .KObj (updateRun ))
224+ return controller .NewUpdateIgnoreConflictError (updateErr )
225+ }
226+ return nil
227+ }
228+
165229// SetupWithManager sets up the controller with the Manager.
166230func (r * Reconciler ) SetupWithManager (mgr runtime.Manager ) error {
167231 r .recorder = mgr .GetEventRecorderFor ("clusterresource-stagedupdaterun-controller" )
0 commit comments