Skip to content

fix: rollout controller cannot shrink bindings to zero when none are ready#588

Draft
Copilot wants to merge 3 commits into
mainfrom
copilot/fix-rollout-controller-binding-issue
Draft

fix: rollout controller cannot shrink bindings to zero when none are ready#588
Copilot wants to merge 3 commits into
mainfrom
copilot/fix-rollout-controller-binding-issue

Conversation

Copilot AI commented Apr 8, 2026

Copy link
Copy Markdown
Contributor

When a placement's target is scaled to 0, stale bindings are never removed if no bindings have reached a ready state. calculateMaxToRemove computes maxNumberToRemove = len(readyBindings) - len(canBeUnavailableBindings) - minAvailableNumber, which is ≤ 0 when no bindings are ready — blocking all removals unconditionally.

Changes

  • pkg/controllers/rollout/controller.go: Add a scale-to-zero fast path at the top of determineBindingsToUpdate. When targetNumber == 0, all removeCandidates, updateCandidates, and applyFailedUpdateCandidates are returned immediately, bypassing rolling update constraints (there is no minimum availability to preserve when targeting zero).
if targetNumber == 0 {
    toBeUpdatedBindingList := append(removeCandidates, updateCandidates...)
    toBeUpdatedBindingList = append(toBeUpdatedBindingList, applyFailedUpdateCandidates...)
    return toBeUpdatedBindingList, nil
}
  • pkg/controllers/rollout/controller_test.go: Add TestDetermineBindingsToUpdate with three cases:
    • targetNumber=0, no ready bindings → all candidates removed
    • targetNumber=0, some ready bindings + apply-failed candidates → all candidates removed
    • targetNumber>0, no ready bindings → rolling update constraints preserved (existing behavior)

Copilot AI and others added 2 commits April 8, 2026 00:11
When targetNumber is 0, determineBindingsToUpdate now unconditionally
returns all removeCandidates, updateCandidates, and
applyFailedUpdateCandidates for removal, bypassing the rolling update
maxUnavailable constraints. This fixes the bug where stale bindings
were never removed when scaling a placement down to zero clusters and
no bindings were in a ready state.

Also removes the TODO comment that tracked this bug and adds three
table-driven unit tests covering the scale-to-zero cases.

Agent-Logs-Url: https://github.com/kubefleet-dev/kubefleet/sessions/b12fc607-900f-4a0d-a4b8-217bf49c6725

Co-authored-by: ytimocin <5220939+ytimocin@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix rollout controller to shrink to zero when bindings are not ready fix: rollout controller cannot shrink bindings to zero when none are ready Apr 8, 2026
@ytimocin Yetkin Timocin (ytimocin) removed their assignment Apr 8, 2026
@codecov

codecov Bot commented Apr 8, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] Rollout controller does not shrink to zero when bindings are not ready

2 participants