Skip to content

OCPBUGS-86009: Fix dns operator reporting Progressing=True on scale up#477

Open
bentito wants to merge 2 commits into
openshift:masterfrom
bentito:fix-ocpbugs-86009
Open

OCPBUGS-86009: Fix dns operator reporting Progressing=True on scale up#477
bentito wants to merge 2 commits into
openshift:masterfrom
bentito:fix-ocpbugs-86009

Conversation

@bentito

@bentito bentito commented May 28, 2026

Copy link
Copy Markdown
Contributor

The cluster-dns-operator was incorrectly reporting Progressing=True during normal cluster scale-up events. This was caused by computeDNSProgressingCondition checking UpdatedNumberScheduled against DesiredNumberScheduled. When a new node is added, DesiredNumberScheduled increases immediately, but UpdatedNumberScheduled lags until the pod is scheduled/running, causing the operator to appear to be rolling out.

This PR introduces an isDaemonSetRollingOut helper, modeled after similar logic in the cluster-ingress-operator (see PR #1299). It checks if the DaemonSet Generation matches ObservedGeneration, and checks if UpdatedNumberScheduled is less than CurrentNumberScheduled. If not, the operator is simply scaling and should not report Progressing=True.

Tested locally by ensuring the test suite correctly accommodates the new structure and verifies progression states.

Bug: OCPBUGS-86009

Summary by CodeRabbit

  • Bug Fixes
    • Improved DNS component status reporting during DaemonSet updates. “Have…want…” progressing messages are now shown only when the DNS and node-resolver DaemonSets are actively rolling out, and are suppressed when counts don’t match but a rollout isn’t in progress.

@openshift-ci-robot openshift-ci-robot added jira/severity-moderate Referenced Jira bug's severity is moderate for the branch this PR is targeting. jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. jira/invalid-bug Indicates that a referenced Jira bug is invalid for the branch this PR is targeting. labels May 28, 2026
@openshift-ci-robot

Copy link
Copy Markdown
Contributor

@bentito: This pull request references Jira Issue OCPBUGS-86009, which is invalid:

  • expected the bug to target the "5.0.0" version, but no target version was set

Comment /jira refresh to re-evaluate validity if changes to the Jira bug are made, or edit the title of this pull request to link to a different bug.

The bug has been updated to refer to the pull request using the external bug tracker.

Details

In response to this:

The cluster-dns-operator was incorrectly reporting Progressing=True during normal cluster scale-up events. This was caused by computeDNSProgressingCondition checking UpdatedNumberScheduled against DesiredNumberScheduled. When a new node is added, DesiredNumberScheduled increases immediately, but UpdatedNumberScheduled lags until the pod is scheduled/running, causing the operator to appear to be rolling out.

This PR introduces an isDaemonSetRollingOut helper, modeled after similar logic in the cluster-ingress-operator (see PR #1299). It checks if the DaemonSet Generation matches ObservedGeneration, and checks if UpdatedNumberScheduled is less than CurrentNumberScheduled. If not, the operator is simply scaling and should not report Progressing=True.

Tested locally by ensuring the test suite correctly accommodates the new structure and verifies progression states.

Bug: OCPBUGS-86009

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@coderabbitai

coderabbitai Bot commented May 28, 2026

Copy link
Copy Markdown

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository: openshift/coderabbit/.coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 5da1d30c-ac51-4236-b9df-d952081d79a0

📥 Commits

Reviewing files that changed from the base of the PR and between e75b7b4 and b2ee3f5.

📒 Files selected for processing (2)
  • pkg/operator/controller/dns_status.go
  • pkg/operator/controller/dns_status_test.go
🚧 Files skipped from review as they are similar to previous changes (2)
  • pkg/operator/controller/dns_status_test.go
  • pkg/operator/controller/dns_status.go

Walkthrough

A new isDaemonSetRollingOut helper detects when DNS DaemonSets are actively rolling out by comparing Generation vs ObservedGeneration and checking if scheduled pods lag behind updated pods. The progressing condition logic uses this helper to conditionally append "have X, want Y" messages only during active rollouts. Test fixtures are updated to populate CurrentNumberScheduled for proper rollout state validation.

Changes

DNS Rollout Detection and Conditional Progressing Messages

Layer / File(s) Summary
Rollout detection helper
pkg/operator/controller/dns_status.go
New isDaemonSetRollingOut(ds) helper returns true when Generation differs from ObservedGeneration or when UpdatedNumberScheduled is less than CurrentNumberScheduled.
Conditional progressing messages
pkg/operator/controller/dns_status.go
DNS and node-resolver progressing condition messages are appended only when isDaemonSetRollingOut reports an active rollout; otherwise specific "have X, want Y" messages are suppressed.
Test fixture and case updates
pkg/operator/controller/dns_status_test.go
Multiple test helpers and fixtures now populate DaemonSetStatus.CurrentNumberScheduled to support testing rollout-state detection logic, and two new test cases cover scaling up without rolling out.

🎯 2 (Simple) | ⏱️ ~12 minutes

🚥 Pre-merge checks | ✅ 14 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 71.43% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (14 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically describes the main fix: addressing incorrect Progressing=True reporting during cluster scale-up in the DNS operator.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Stable And Deterministic Test Names ✅ Passed No Ginkgo tests found in the codebase; all tests use Go's native testing framework with table-driven tests and t.Run() subtests. The custom check requires Ginkgo test names to be stable/determinist...
Test Structure And Quality ✅ Passed Test code meets all five quality criteria: (1) Single responsibility—each test in the table-driven suite tests one specific behavior, with two new test cases specifically testing DaemonSet scaling-...
Microshift Test Compatibility ✅ Passed PR modifies only standard Go unit tests (dns_status_test.go), not Ginkgo e2e tests. No Ginkgo imports found in repository, so MicroShift API compatibility check not applicable.
Single Node Openshift (Sno) Test Compatibility ✅ Passed No Ginkgo e2e tests added. PR modifies only unit tests using standard Go testing package in pkg/operator/controller/dns_status_test.go; no Ginkgo framework imports detected.
Topology-Aware Scheduling Compatibility ✅ Passed PR introduces only status reporting logic changes; no new scheduling constraints affecting SNO, two-node, arbiter, or HyperShift topologies.
Ote Binary Stdout Contract ✅ Passed No process-level stdout writes detected. All changes are in regular functions, test cases, or pure logic without I/O side effects.
Ipv6 And Disconnected Network Test Compatibility ✅ Passed PR adds no Ginkgo e2e tests; only modifies unit tests in dns_status_test.go using Go's testing.T, which are outside the scope of the IPv6/disconnected network compatibility check.
No-Weak-Crypto ✅ Passed PR contains no weak crypto algorithms (MD5, SHA1, DES, RC4, 3DES, Blowfish, ECB), custom crypto implementations, or non-constant-time secret comparisons. Changes are purely about DaemonSet rollout...
Container-Privileges ✅ Passed PR modifies only Go source files (dns_status.go, dns_status_test.go) for DNS status logic; no container/Kubernetes manifest privilege escalation changes introduced.
No-Sensitive-Data-In-Logs ✅ Passed PR introduces isDaemonSetRollingOut() helper function and modifies status condition logic without adding any logging statements. Existing logging contains only non-sensitive data: resource names, p...

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
pkg/operator/controller/dns_status_test.go (1)

114-115: ⚡ Quick win

Add a dedicated scale-up (non-rollout) regression case.

All updated fixtures pin CurrentNumberScheduled to desired, so the new “scale-up but not rolling out” path is still untested. Please add at least one case with desired > current, updated == current, and matching generation/observed-generation, then assert Progressing=False.

Proposed test-direction diff
- makeDaemonSet := func(desired, available, updated int, nodeSelector map[string]string, tolerations []corev1.Toleration) *appsv1.DaemonSet {
+ makeDaemonSet := func(desired, current, available, updated int, nodeSelector map[string]string, tolerations []corev1.Toleration) *appsv1.DaemonSet {
    return &appsv1.DaemonSet{
      Status: appsv1.DaemonSetStatus{
        DesiredNumberScheduled: int32(desired),
        NumberAvailable:        int32(available),
-       CurrentNumberScheduled: int32(desired),
+       CurrentNumberScheduled: int32(current),
        UpdatedNumberScheduled: int32(updated),
      },
    }
  }

+ {
+   name:         "scale-up only should not be progressing",
+   clusterIP:    "172.30.0.10",
+   dnsDaemonset: makeDaemonSet(6, 5, 5, 5, defaultSelector, defaultTolerations),
+   nrDaemonset:  makeDaemonSet(6, 6, 6, 6, defaultSelector, defaultTolerations),
+   nodeSelector: defaultSelector,
+   tolerations:  defaultTolerations,
+   expected:     operatorv1.ConditionFalse,
+ },

Also applies to: 136-137, 477-478, 645-646

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/operator/controller/dns_status_test.go` around lines 114 - 115, Add a
dedicated regression test case in dns_status_test.go that exercises the
scale-up-but-not-rollout path: create a case where CurrentNumberScheduled <
desired (desired > current), UpdatedNumberScheduled == CurrentNumberScheduled
(no updated replicas), and generation == observedGeneration; place it alongside
the existing table entries that use tc.inputs.desireDNS/CurrentNumberScheduled
so it’s easy to find, and assert that the computed Progressing condition is
False. Ensure the case sets the same generation and observedGeneration values
and uses the same fields (CurrentNumberScheduled, UpdatedNumberScheduled,
DesiredNumberScheduled or tc.inputs.desireDNS) as other fixtures so it mirrors
the other tests but checks Progressing==False.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@pkg/operator/controller/dns_status_test.go`:
- Around line 114-115: Add a dedicated regression test case in
dns_status_test.go that exercises the scale-up-but-not-rollout path: create a
case where CurrentNumberScheduled < desired (desired > current),
UpdatedNumberScheduled == CurrentNumberScheduled (no updated replicas), and
generation == observedGeneration; place it alongside the existing table entries
that use tc.inputs.desireDNS/CurrentNumberScheduled so it’s easy to find, and
assert that the computed Progressing condition is False. Ensure the case sets
the same generation and observedGeneration values and uses the same fields
(CurrentNumberScheduled, UpdatedNumberScheduled, DesiredNumberScheduled or
tc.inputs.desireDNS) as other fixtures so it mirrors the other tests but checks
Progressing==False.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository: openshift/coderabbit/.coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 6ad8a084-6f0d-4209-8763-7ce725c27dbf

📥 Commits

Reviewing files that changed from the base of the PR and between 3d21411 and e75b7b4.

📒 Files selected for processing (2)
  • pkg/operator/controller/dns_status.go
  • pkg/operator/controller/dns_status_test.go

@bentito

bentito commented May 28, 2026

Copy link
Copy Markdown
Contributor Author

This PR is taking a similar approach as openshift/cluster-ingress-operator#1299 did for same problems on CIO

The cluster-dns-operator was incorrectly reporting Progressing=True
during normal cluster scale up events. This was caused by the
computeDNSProgressingCondition checking UpdatedNumberScheduled against
DesiredNumberScheduled. When a new node is added, DesiredNumberScheduled
increases immediately, but UpdatedNumberScheduled lags until the pod is
running, causing the operator to appear to be rolling out.

This commit introduces an isDaemonSetRollingOut helper, modeled after
similar logic in the cluster-ingress-operator. It checks if the
DaemonSet Generation matches ObservedGeneration, and checks if
UpdatedNumberScheduled is less than CurrentNumberScheduled. If not, the
operator is simply scaling and should not report Progressing=True.
@bentito
bentito force-pushed the fix-ocpbugs-86009 branch from e75b7b4 to ee254fc Compare May 28, 2026 18:02
@bentito

bentito commented May 29, 2026

Copy link
Copy Markdown
Contributor Author

/retest

1 similar comment
@bentito

bentito commented May 29, 2026

Copy link
Copy Markdown
Contributor Author

/retest

@bentito

bentito commented Jun 3, 2026

Copy link
Copy Markdown
Contributor Author

/assign @davidesalerno

@davidesalerno davidesalerno left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The changes lgmt evenif I think we still need a dedicated regression test for the exact scenario this PR is fixing: scale-up without rollout.

Right now these fixture updates set CurrentNumberScheduled equal to DesiredNumberScheduled, so the tests don’t exercise the case where:

  • DesiredNumberScheduled > CurrentNumberScheduled
  • UpdatedNumberScheduled == CurrentNumberScheduled
  • Generation == ObservedGeneration

In that state, the DaemonSet is scaling up but not rolling out, and computeDNSProgressingCondition should remain Progressing=False.

Could we add a table-driven case that covers that combination explicitly? That would make the regression protection much stronger for this bug.

Add dedicated regression test cases to TestComputeDNSProgressingCondition to verify that the Progressing condition is False when the DaemonSet is scaling up but not rolling out. This covers the scenario where DesiredNumberScheduled > CurrentNumberScheduled but no active rollout is taking place.
@bentito

bentito commented Jun 23, 2026

Copy link
Copy Markdown
Contributor Author

The changes lgmt evenif I think we still need a dedicated regression test for the exact scenario this PR is fixing: scale-up without rollout.

Right now these fixture updates set CurrentNumberScheduled equal to DesiredNumberScheduled, so the tests don’t exercise the case where:

* `DesiredNumberScheduled > CurrentNumberScheduled`

* `UpdatedNumberScheduled == CurrentNumberScheduled`

* `Generation == ObservedGeneration`

In that state, the DaemonSet is scaling up but not rolling out, and computeDNSProgressingCondition should remain Progressing=False.

Could we add a table-driven case that covers that combination explicitly? That would make the regression protection much stronger for this bug.

Thanks @davidesalerno sorry about delay. I've added unit tests to better lock this in.

@openshift-ci

openshift-ci Bot commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
Once this PR has been reviewed and has the lgtm label, please ask for approval from davidesalerno. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@bentito

bentito commented Jun 23, 2026

Copy link
Copy Markdown
Contributor Author

/jira refresh

@openshift-ci-robot openshift-ci-robot added jira/valid-bug Indicates that a referenced Jira bug is valid for the branch this PR is targeting. and removed jira/invalid-bug Indicates that a referenced Jira bug is invalid for the branch this PR is targeting. labels Jun 23, 2026
@openshift-ci-robot

Copy link
Copy Markdown
Contributor

@bentito: This pull request references Jira Issue OCPBUGS-86009, which is valid. The bug has been moved to the POST state.

3 validation(s) were run on this bug
  • bug is open, matching expected state (open)
  • bug target version (5.0.0) matches configured target version for branch (5.0.0)
  • bug is in the state ASSIGNED, which is one of the valid states (NEW, ASSIGNED, POST)

Requesting review from QA contact:
/cc @melvinjoseph86

Details

In response to this:

/jira refresh

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@openshift-ci
openshift-ci Bot requested a review from melvinjoseph86 June 23, 2026 19:37
@openshift-ci-robot

Copy link
Copy Markdown
Contributor

@bentito: This pull request references Jira Issue OCPBUGS-86009, which is valid.

3 validation(s) were run on this bug
  • bug is open, matching expected state (open)
  • bug target version (5.0.0) matches configured target version for branch (5.0.0)
  • bug is in the state POST, which is one of the valid states (NEW, ASSIGNED, POST)

Requesting review from QA contact:
/cc @melvinjoseph86

Details

In response to this:

The cluster-dns-operator was incorrectly reporting Progressing=True during normal cluster scale-up events. This was caused by computeDNSProgressingCondition checking UpdatedNumberScheduled against DesiredNumberScheduled. When a new node is added, DesiredNumberScheduled increases immediately, but UpdatedNumberScheduled lags until the pod is scheduled/running, causing the operator to appear to be rolling out.

This PR introduces an isDaemonSetRollingOut helper, modeled after similar logic in the cluster-ingress-operator (see PR #1299). It checks if the DaemonSet Generation matches ObservedGeneration, and checks if UpdatedNumberScheduled is less than CurrentNumberScheduled. If not, the operator is simply scaling and should not report Progressing=True.

Tested locally by ensuring the test suite correctly accommodates the new structure and verifies progression states.

Bug: OCPBUGS-86009

Summary by CodeRabbit

  • Bug Fixes
  • Improved DNS component status reporting during DaemonSet updates. “Have…want…” progressing messages are now shown only when the DNS and node-resolver DaemonSets are actively rolling out, and are suppressed when counts don’t match but a rollout isn’t in progress.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@davidesalerno

Copy link
Copy Markdown
Contributor

/payload-aggregate periodic-ci-openshift-release-master-nightly-5.1-e2e-aws-ovn-serial 3

@openshift-ci

openshift-ci Bot commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

@davidesalerno: trigger 0 job(s) for the /payload-(with-prs|job|aggregate|job-with-prs|aggregate-with-prs) command

@davidesalerno

Copy link
Copy Markdown
Contributor

/payload-aggregate periodic-ci-openshift-release-main-nightly-5.0-e2e-aws-ovn-serial 3

@openshift-ci

openshift-ci Bot commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

@davidesalerno: trigger 1 job(s) for the /payload-(with-prs|job|aggregate|job-with-prs|aggregate-with-prs) command

  • periodic-ci-openshift-release-main-nightly-5.0-e2e-aws-ovn-serial

See details on https://pr-payload-tests.ci.openshift.org/runs/ci/b37c2500-6fd9-11f1-9166-b6ab77c06fb2-0

@davidesalerno

Copy link
Copy Markdown
Contributor

/test e2e-aws-ovn-serial-1of2

@openshift-ci

openshift-ci Bot commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

@bentito: all tests passed!

Full PR test history. Your PR dashboard.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here.

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

Labels

jira/severity-moderate Referenced Jira bug's severity is moderate for the branch this PR is targeting. jira/valid-bug Indicates that a referenced Jira bug is valid for the branch this PR is targeting. jira/valid-reference Indicates that this PR references a valid Jira ticket of any type.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants