Skip to content

Commit 40f5d6b

Browse files
committed
trafficrouting: avoid divide-by-zero on PromoteFull with zero-replica rollout
reconcileTrafficRouting computes the PromoteFull desired weight as (maxWeight * canaryAvailable) / *rollout.Spec.Replicas when dynamicStableScale is on. Rollouts that are temporarily scaled to zero still have a spec and are promotable, so PromoteFull can run while *rollout.Spec.Replicas is 0 - the division panics, the recovered error is logged in a hot loop, and the rollout is stuck in a progressing state (#3686). Guard the division: pull spec.Replicas out, treat a nil pointer as zero, and only compute the ratio when we actually have replicas. With zero spec replicas there is nothing to ratio against, so desiredWeight stays at its zero default rather than shifting traffic to a canary that has nowhere to land. Signed-off-by: SAY-5 <SAY-5@users.noreply.github.com> Fixes #3686
1 parent c40cb0d commit 40f5d6b

1 file changed

Lines changed: 11 additions & 1 deletion

File tree

rollout/trafficrouting.go

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,17 @@ func (c *rolloutContext) reconcileTrafficRouting() error {
236236
// But we can only increase canary weight according to available replica counts of the canary.
237237
// we will need to set the desiredWeight to 0 when the newRS is not available.
238238
if c.rollout.Spec.Strategy.Canary.DynamicStableScale {
239-
desiredWeight = (weightutil.MaxTrafficWeight(c.rollout) * c.newRS.Status.AvailableReplicas) / *c.rollout.Spec.Replicas
239+
// A Rollout scaled to zero replicas can still be fully promoted
240+
// (see #3686), so guard the division here. With no spec replicas
241+
// there is nothing to ratio against; leave desiredWeight at 0 so
242+
// we don't shift traffic to a canary that has nowhere to land.
243+
var specReplicas int32
244+
if c.rollout.Spec.Replicas != nil {
245+
specReplicas = *c.rollout.Spec.Replicas
246+
}
247+
if specReplicas > 0 {
248+
desiredWeight = (weightutil.MaxTrafficWeight(c.rollout) * c.newRS.Status.AvailableReplicas) / specReplicas
249+
}
240250
} else if c.rollout.Status.Canary.Weights != nil {
241251
desiredWeight = c.rollout.Status.Canary.Weights.Canary.Weight
242252
}

0 commit comments

Comments
 (0)