Skip to content

OCPBUGS-62277: Requeue PerformanceStatus update when status write fails#1495

Open
MarSik wants to merge 1 commit into
openshift:mainfrom
MarSik:fix-state-status
Open

OCPBUGS-62277: Requeue PerformanceStatus update when status write fails#1495
MarSik wants to merge 1 commit into
openshift:mainfrom
MarSik:fix-state-status

Conversation

@MarSik
Copy link
Copy Markdown
Contributor

@MarSik MarSik commented Apr 27, 2026

The old code logged an error when not able to save status, but it never retried. This caused stale conditions to be reported until the next reconcile (possibly long time in the future).

Summary by CodeRabbit

  • Bug Fixes
    • Improved error recovery for status update failures: when status synchronization encounters transient errors, the controller now retries after a 30-second delay, reducing missed updates and improving overall system resilience and stability.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 27, 2026

Walkthrough

Adds a package-level statusUpdateRequeueAfter constant (30s) and updates reconcile error handling so failures from StatusWriter.Update and StatusWriter.UpdateOwnedConditions return a reconcile.Result with RequeueAfter: statusUpdateRequeueAfter alongside the error.

Changes

Performance Profile Controller Reconciliation

Layer / File(s) Summary
Constant
pkg/performanceprofile/controller/performanceprofile_controller.go
Adds statusUpdateRequeueAfter = 30 * time.Second.
Component deployment status update
pkg/performanceprofile/controller/performanceprofile_controller.go
On StatusWriter.Update(...) failure during component deployment, reconcile now returns RequeueAfter: statusUpdateRequeueAfter with the error.
Owned conditions update
pkg/performanceprofile/controller/performanceprofile_controller.go
On StatusWriter.UpdateOwnedConditions(...) failure, reconcile now returns RequeueAfter: statusUpdateRequeueAfter with the error.
MCP lookup failure handling
pkg/performanceprofile/controller/performanceprofile_controller.go
When MCP is not found and StatusWriter.Update(...) fails, reconcile now returns RequeueAfter: statusUpdateRequeueAfter with the error.
MCP/profile validation failure handling
pkg/performanceprofile/controller/performanceprofile_controller.go
When profile/MCP validation fails and StatusWriter.Update(...) fails, reconcile now returns RequeueAfter: statusUpdateRequeueAfter with the error.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~5 minutes

🚥 Pre-merge checks | ✅ 11 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Test Structure And Quality ⚠️ Warning PR introduces status update requeue behavior but adds no tests to verify it. The custom check requires test code quality review, but no test coverage exists for the new error handling. Add Ginkgo tests that mock StatusWriter failures and verify reconciliation returns proper requeue results with statusUpdateRequeueAfter delay.
✅ Passed checks (11 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: adding requeue logic when PerformanceStatus updates fail, which matches the core modification in the changeset.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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 All Ginkgo test names in the PR are stable and deterministic. No dynamic content detected: no fmt.Sprintf, string concat, generated pod/node/namespace names, timestamps, or UUIDs.
Microshift Test Compatibility ✅ Passed This PR does not add any new Ginkgo e2e tests. It only modifies the performance profile controller implementation file to add a requeue delay on status update failures. The check is not applicable.
Single Node Openshift (Sno) Test Compatibility ✅ Passed No Ginkgo e2e tests are added in this PR. Changes are limited to modifying controller reconciliation logic for status update error handling. SNO test compatibility check not applicable.
Topology-Aware Scheduling Compatibility ✅ Passed This PR modifies only controller reconciliation error handling logic and introduces no scheduling constraints. The topology-aware scheduling check is not applicable to this change.
Ote Binary Stdout Contract ✅ Passed PR changes do not violate OTE stdout contract. No process-level stdout writes added. Test logging properly redirected via testlog (uses GinkgoWriter) and suite logging configured to stderr.
Ipv6 And Disconnected Network Test Compatibility ✅ Passed No new Ginkgo e2e tests were added in this PR. Only the controller file was modified. The check for IPv6/disconnected network compatibility is not applicable.

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

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

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 golangci-lint (2.12.1)

level=error msg="Running error: context loading failed: failed to load packages: failed to load packages: failed to load with go/packages: err: exit status 1: stderr: go: inconsistent vendoring in :\n\tgithub.com/RHsyseng/operator-utils@v1.4.13: is explicitly required in go.mod, but not marked as explicit in vendor/modules.txt\n\tgithub.com/coreos/go-systemd@v0.0.0-20191104093116-d3cd4ed1dbcf: is explicitly required in go.mod, but not marked as explicit in vendor/modules.txt\n\tgithub.com/coreos/ignition@v0.35.0: is explicitly required in go.mod, but not marked as explicit in vendor/modules.txt\n\tgithub.com/coreos/ignition/v2@v2.26.0: is explicitly required in go.mod, but not marked as explicit in vendor/modules.txt\n\tgithub.com/docker/go-units@v0.5.0: is explicitly required in go.mod, but not marked as explicit in vendor/modules.txt\n\tgithub.com/go-logr/stdr@v1.2.2: is explicitly required in go.mod, but not marked as explicit in vendor/modules.txt\n\tgithub.com/google/go-cmp@v0.7.0

... [truncated 19340 characters] ...

is replaced in go.mod, but not marked as replaced in vendor/modules.txt\n\tk8s.io/legacy-cloud-providers: is replaced in go.mod, but not marked as replaced in vendor/modules.txt\n\tk8s.io/metrics: is replaced in go.mod, but not marked as replaced in vendor/modules.txt\n\tk8s.io/mount-utils: is replaced in go.mod, but not marked as replaced in vendor/modules.txt\n\tk8s.io/pod-security-admission: is replaced in go.mod, but not marked as replaced in vendor/modules.txt\n\tk8s.io/sample-apiserver: is replaced in go.mod, but not marked as replaced in vendor/modules.txt\n\tgithub.com/onsi/ginkgo/v2: is replaced in go.mod, but not marked as replaced in vendor/modules.txt\n\n\tTo ignore the vendor directory, use -mod=readonly or -mod=mod.\n\tTo sync the vendor directory, run:\n\t\tgo mod vendor\n"


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 and usage tips.

@MarSik MarSik changed the title OCPBUGS-62277 Requeue PerformanceStatus update when status write fails OCPBUGS-62277: Requeue PerformanceStatus update when status write fails Apr 27, 2026
@openshift-ci-robot openshift-ci-robot added 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 Apr 27, 2026
@openshift-ci-robot
Copy link
Copy Markdown
Contributor

@MarSik: This pull request references Jira Issue OCPBUGS-62277, 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 old code logged an error when not able to save status, but it never retried. This caused stale conditions to be reported until the next reconcile (possibly long time in the future).

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 review from Tal-or and swatisehgal April 27, 2026 12:02
@openshift-ci
Copy link
Copy Markdown
Contributor

openshift-ci Bot commented Apr 27, 2026

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: MarSik

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

The pull request process is described 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

@openshift-ci openshift-ci Bot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Apr 27, 2026
@MarSik
Copy link
Copy Markdown
Contributor Author

MarSik commented Apr 27, 2026

/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 Apr 27, 2026
@openshift-ci-robot
Copy link
Copy Markdown
Contributor

@MarSik: This pull request references Jira Issue OCPBUGS-62277, 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 @mrniranjan

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 mrniranjan April 27, 2026 12:03
@openshift-ci-robot
Copy link
Copy Markdown
Contributor

@MarSik: This pull request references Jira Issue OCPBUGS-62277, 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 @mrniranjan

Details

In response to this:

The old code logged an error when not able to save status, but it never retried. This caused stale conditions to be reported until the next reconcile (possibly long time in the future).

Summary by CodeRabbit

  • Bug Fixes
  • Improved error recovery for status update failures by implementing a 30-second retry delay, enhancing system resilience when status synchronization encounters transient issues.

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.

The old code logged an error when not able to save status, but it
never retried. This caused stale conditions to be reported until
the next reconcile (possibly long time in the future).
@MarSik MarSik force-pushed the fix-state-status branch from 40bd7af to 06227d4 Compare April 27, 2026 12:05
@MarSik
Copy link
Copy Markdown
Contributor Author

MarSik commented Apr 27, 2026

/cherry-pick release-4.22 release-4.21 release-4.20 release-4.19 release-4.18

@openshift-cherrypick-robot
Copy link
Copy Markdown

@MarSik: once the present PR merges, I will cherry-pick it on top of release-4.22 in a new PR and assign it to you.

Details

In response to this:

/cherry-pick release-4.22 release-4.21 release-4.20 release-4.19 release-4.18

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.

@MarSik
Copy link
Copy Markdown
Contributor Author

MarSik commented Apr 30, 2026

/retest-required

1 similar comment
@MarSik
Copy link
Copy Markdown
Contributor Author

MarSik commented May 4, 2026

/retest-required

@jmencak
Copy link
Copy Markdown
Contributor

jmencak commented May 11, 2026

@coderabbitai full review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 11, 2026

✅ Actions performed

Full review triggered.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 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.

Inline comments:
In `@pkg/performanceprofile/controller/performanceprofile_controller.go`:
- Around line 619-623: The status-update branch currently discards the original
deployment error by returning nil; capture the original deployment error (e.g.,
store the error returned from the deployment step before calling
r.StatusWriter.Update), call r.StatusWriter.Update(ctx, instance, conditions) as
now, and if that update fails return reconcile.Result{RequeueAfter:
statusUpdateRequeueAfter}, <original deployment error> so the reconcile reports
the real failure; specifically, preserve the error produced before the
r.StatusWriter.Update call and return it alongside the RequeueAfter instead of
returning nil.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

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

Review profile: CHILL

Plan: Enterprise

Run ID: 6d598bdd-c6e2-4f50-8268-769b2d7886a9

📥 Commits

Reviewing files that changed from the base of the PR and between 3d98f7e and 06227d4.

📒 Files selected for processing (1)
  • pkg/performanceprofile/controller/performanceprofile_controller.go

Comment on lines 619 to 623
if err := r.StatusWriter.Update(ctx, instance, conditions); err != nil {
klog.Errorf("failed to update performance profile %q status: %v", instance.GetName(), err)
return reconcile.Result{}, err
return reconcile.Result{RequeueAfter: statusUpdateRequeueAfter}, nil
}
return reconcile.Result{}, err
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot May 11, 2026

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Critical: Deployment error is discarded when status update fails.

When the status update fails on line 619, line 621 returns nil error, discarding the original component deployment error from line 607. This causes controller-runtime to treat the reconcile as successful even though deployment failed, masking the real issue.

Controller-runtime supports returning both RequeueAfter and an error. The deployment error must be preserved so the failure is properly recorded.

🔧 Proposed fix to preserve the deployment error
 		conditions := status.GetDegradedConditions(status.ConditionReasonComponentsCreationFailed, err.Error())
 		if err := r.StatusWriter.Update(ctx, instance, conditions); err != nil {
 			klog.Errorf("failed to update performance profile %q status: %v", instance.GetName(), err)
-			return reconcile.Result{RequeueAfter: statusUpdateRequeueAfter}, nil
+			return reconcile.Result{RequeueAfter: statusUpdateRequeueAfter}, err
 		}
 		return reconcile.Result{}, err

This ensures:

  • The deployment error is not lost
  • The reconcile is properly marked as failed
  • Status update will be retried after 30s
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if err := r.StatusWriter.Update(ctx, instance, conditions); err != nil {
klog.Errorf("failed to update performance profile %q status: %v", instance.GetName(), err)
return reconcile.Result{}, err
return reconcile.Result{RequeueAfter: statusUpdateRequeueAfter}, nil
}
return reconcile.Result{}, err
if err := r.StatusWriter.Update(ctx, instance, conditions); err != nil {
klog.Errorf("failed to update performance profile %q status: %v", instance.GetName(), err)
return reconcile.Result{RequeueAfter: statusUpdateRequeueAfter}, err
}
return reconcile.Result{}, err
🤖 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/performanceprofile/controller/performanceprofile_controller.go` around
lines 619 - 623, The status-update branch currently discards the original
deployment error by returning nil; capture the original deployment error (e.g.,
store the error returned from the deployment step before calling
r.StatusWriter.Update), call r.StatusWriter.Update(ctx, instance, conditions) as
now, and if that update fails return reconcile.Result{RequeueAfter:
statusUpdateRequeueAfter}, <original deployment error> so the reconcile reports
the real failure; specifically, preserve the error produced before the
r.StatusWriter.Update call and return it alongside the RequeueAfter instead of
returning nil.

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.

You cannot combine reconcile.Result{RequeueAfter: statusUpdateRequeueAfter} with non-nil error. See controller-runtime code controller-runtime/pkg/internal/controller/controller.go line 467

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Let me look up the controller-runtime source code to verify this behavior.

@jmencak, you are absolutely correct, and I apologize for the incorrect suggestion.

The controller-runtime documentation explicitly states: "If the returned error is non-nil, the Result is ignored and the request will be requeued using exponential backoff. The only exception is if the error is a TerminalError in which case no requeuing happens." And conversely, "If the error is nil and the returned Result has a non-zero result.RequeueAfter, the request will be requeued after the specified duration."

The controller-runtime internal controller code confirms this — when both RequeueAfter/Requeue are set and a non-nil error is returned, it logs: "Warning: Reconciler returned both a result with either RequeueAfter or Requeue set and a non-nil error. RequeueAfter and Requeue will always be ignored if the error is non-nil."

So the PR's current pattern of return reconcile.Result{RequeueAfter: statusUpdateRequeueAfter}, nil is the correct approach — the nil error paired with RequeueAfter achieves the intended fixed-delay retry without triggering exponential backoff. My suggestion to return a non-nil error alongside RequeueAfter would have been silently ignored by the framework. The existing code in the PR is correct.


📝 Learnings were identified and not saved (knowledge base disabled). Enable

@jmencak
Copy link
Copy Markdown
Contributor

jmencak commented May 11, 2026

Should we address this in all 5 places where failed to update performance profile %q status: %v is logged? I can see only 4 are being addressed.

Edit: Ignore, that last one is controller/performanceprofile/status/writer.go and we should leave it as is.

@jmencak
Copy link
Copy Markdown
Contributor

jmencak commented May 11, 2026

/lgtm
/hold
to give other reviewers chance to review.

@openshift-ci openshift-ci Bot added the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label May 11, 2026
@openshift-ci openshift-ci Bot added the lgtm Indicates that a PR is ready to be merged. label May 11, 2026
@ffromani
Copy link
Copy Markdown
Contributor

/lgtm

LGTM to me as well. It seems all correct

@yanirq
Copy link
Copy Markdown
Contributor

yanirq commented May 12, 2026

/retest

@mrniranjan
Copy link
Copy Markdown
Contributor

/verified by @mrniranjan

@openshift-ci-robot openshift-ci-robot added the verified Signifies that the PR passed pre-merge verification criteria label May 12, 2026
@openshift-ci-robot
Copy link
Copy Markdown
Contributor

@mrniranjan: This PR has been marked as verified by @mrniranjan.

Details

In response to this:

/verified by @mrniranjan

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.

@yanirq
Copy link
Copy Markdown
Contributor

yanirq commented May 12, 2026

/lgtm

/hold cancel

@openshift-ci openshift-ci Bot removed the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label May 12, 2026
@jmencak
Copy link
Copy Markdown
Contributor

jmencak commented May 12, 2026

e2e-aws-nto-ext is optional. It will pass after #1512 merges.

@openshift-merge-bot
Copy link
Copy Markdown
Contributor

/retest-required

Remaining retests: 0 against base HEAD 54a9ef7 and 2 for PR HEAD 06227d4 in total

@openshift-ci
Copy link
Copy Markdown
Contributor

openshift-ci Bot commented May 12, 2026

@MarSik: The following tests failed, say /retest to rerun all failed tests or /retest-required to rerun all mandatory failed tests:

Test name Commit Details Required Rerun command
ci/prow/e2e-hypershift-pao 06227d4 link unknown /test e2e-hypershift-pao
ci/prow/e2e-aws-nto-ext 06227d4 link false /test e2e-aws-nto-ext
ci/prow/e2e-hypershift 06227d4 link true /test e2e-hypershift
ci/prow/e2e-gcp-pao-updating-profile 06227d4 link unknown /test e2e-gcp-pao-updating-profile

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

approved Indicates a PR has been approved by an approver from all required OWNERS files. 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. lgtm Indicates that a PR is ready to be merged. verified Signifies that the PR passed pre-merge verification criteria

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants