Skip to content

Commit 34cd9a2

Browse files
haoqing0110claude
andauthored
Update rollout logic to use Progressing condition instead of WorkApplied (#1207)
🤖 Generated with [Claude Code](https://claude.com/claude-code) Signed-off-by: Qing Hao <[email protected]> Co-authored-by: Claude <[email protected]>
1 parent 2867c26 commit 34cd9a2

File tree

4 files changed

+414
-35
lines changed

4 files changed

+414
-35
lines changed

pkg/work/hub/controllers/manifestworkreplicasetcontroller/manifestworkreplicaset_deploy_reconcile.go

Lines changed: 40 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -209,41 +209,54 @@ func (d *deployReconciler) reconcile(ctx context.Context, mwrSet *workapiv1alpha
209209
}
210210

211211
func (d *deployReconciler) clusterRolloutStatusFunc(clusterName string, manifestWork workv1.ManifestWork) (clustersdkv1alpha1.ClusterRolloutStatus, error) {
212+
// Initialize default status as ToApply, LastTransitionTime is not needed for ToApply status.
212213
clsRolloutStatus := clustersdkv1alpha1.ClusterRolloutStatus{
213-
ClusterName: clusterName,
214-
LastTransitionTime: &manifestWork.CreationTimestamp,
215-
// Default status is ToApply
216-
Status: clustersdkv1alpha1.ToApply,
214+
ClusterName: clusterName,
215+
Status: clustersdkv1alpha1.ToApply,
217216
}
218217

219-
appliedCondition := apimeta.FindStatusCondition(manifestWork.Status.Conditions, workv1.WorkApplied)
220-
221-
// Applied condition not exist return status as ToApply.
222-
if appliedCondition == nil { //nolint:gocritic
223-
return clsRolloutStatus, nil
224-
} else if appliedCondition.Status == metav1.ConditionTrue ||
225-
apimeta.IsStatusConditionTrue(manifestWork.Status.Conditions, workv1.WorkProgressing) {
226-
// Applied OR Progressing conditions status true return status as Progressing
227-
// ManifestWork Progressing status is not defined however the check is made for future work availability.
228-
clsRolloutStatus.Status = clustersdkv1alpha1.Progressing
229-
} else if appliedCondition.Status == metav1.ConditionFalse {
230-
// Applied Condition status false return status as failed
231-
clsRolloutStatus.Status = clustersdkv1alpha1.Failed
232-
clsRolloutStatus.LastTransitionTime = &appliedCondition.LastTransitionTime
218+
// Get all relevant conditions
219+
progressingCond := apimeta.FindStatusCondition(manifestWork.Status.Conditions, workv1.WorkProgressing)
220+
degradedCond := apimeta.FindStatusCondition(manifestWork.Status.Conditions, workv1.WorkDegraded)
221+
222+
// Return ToApply if:
223+
// - No Progressing condition exists yet (work hasn't been reconciled by agent)
224+
// - Progressing condition hasn't observed the latest spec
225+
// - Degraded condition exists but hasn't observed the latest spec
226+
// (Degraded is optional, but if it exists, we wait for it to catch up)
227+
if progressingCond == nil ||
228+
progressingCond.ObservedGeneration != manifestWork.Generation ||
229+
(degradedCond != nil && degradedCond.ObservedGeneration != manifestWork.Generation) {
233230
return clsRolloutStatus, nil
234231
}
235232

236-
// Available condition return status as Succeeded
237-
if apimeta.IsStatusConditionTrue(manifestWork.Status.Conditions, workv1.WorkAvailable) {
233+
// Agent has observed the latest spec, determine status based on Progressing and Degraded conditions.
234+
// Degraded is an optional condition only used to determine Failed case.
235+
// - Progressing=True + Degraded=True → Failed (work is progressing but degraded)
236+
// - Progressing=True (not degraded) → Progressing
237+
// - Progressing=False → Succeeded
238+
// - Unknown state → Progressing (conservative fallback)
239+
//
240+
// LastTransitionTime is used by rollout strategies to calculate:
241+
// - Timeout for Progressing and Failed statuses
242+
// - Minimum success time (soak time) for Succeeded status
243+
switch {
244+
case progressingCond.Status == metav1.ConditionTrue && degradedCond != nil && degradedCond.Status == metav1.ConditionTrue:
245+
clsRolloutStatus.Status = clustersdkv1alpha1.Failed
246+
clsRolloutStatus.LastTransitionTime = &degradedCond.LastTransitionTime
247+
248+
case progressingCond.Status == metav1.ConditionTrue:
249+
clsRolloutStatus.Status = clustersdkv1alpha1.Progressing
250+
clsRolloutStatus.LastTransitionTime = &progressingCond.LastTransitionTime
251+
252+
case progressingCond.Status == metav1.ConditionFalse:
238253
clsRolloutStatus.Status = clustersdkv1alpha1.Succeeded
239-
return clsRolloutStatus, nil
240-
}
254+
clsRolloutStatus.LastTransitionTime = &progressingCond.LastTransitionTime
241255

242-
// Degraded condition return status as Failed
243-
// ManifestWork Degraded status is not defined however the check is made for future work availability.
244-
if apimeta.IsStatusConditionTrue(manifestWork.Status.Conditions, workv1.WorkDegraded) {
245-
clsRolloutStatus.Status = clustersdkv1alpha1.Failed
246-
clsRolloutStatus.LastTransitionTime = &appliedCondition.LastTransitionTime
256+
default:
257+
// Unknown state, conservatively treat as still progressing
258+
clsRolloutStatus.Status = clustersdkv1alpha1.Progressing
259+
clsRolloutStatus.LastTransitionTime = &progressingCond.LastTransitionTime
247260
}
248261

249262
return clsRolloutStatus, nil

0 commit comments

Comments
 (0)