Skip to content

Conversation

@tchap
Copy link

@tchap tchap commented Feb 5, 2026

Before we start, the idea basically is to extend Sync to return conditions that would overwrite the conditions generated by the library-go machinery. The interface change is not yet implemented in library-go, but it should be OK as this operator is the only operator using the package.


To handle scaling properly, We need to keep some context regarding the state of the Deployment, so I decided to propose a few Deployment annotations. The names are not final, not sure about what the proper prefix is actually. Not sure whether there is a better way to store state, feel free to propose another way.

The main idea is summarized in the doc comment for ProcessDeployment:

// ProcessDeployment ensures the operator does not end up progressing on scaling.
// We define that scaling happens any time .spec.replicas is the only field that changes.
// The idea is then as follows:
//
//  1. When the replicas field is updated, store the change timestamp in a deployment annotation.
//  2. When the deployment eventually starts progressing, add another annotation so that we know it happened.
//  3. When the deployment hasn't progressing for too long, or it has finished progressing, remove all annotations.
//
// When the timestamp annotation is present, we should overwrite Progressing to be false.
//
// So, ProcessDeployment amends the expected deployment in place, also returning any conditions to set on the operator.

The annotation machinery is there to account for eventual consistency between creating/updating the deployment and the deployment controller picking the change up and actually updating the conditions there.

@openshift-ci openshift-ci bot added the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Feb 5, 2026
@openshift-ci
Copy link
Contributor

openshift-ci bot commented Feb 5, 2026

Skipping CI for Draft Pull Request.
If you want CI signal for your change, please convert it to an actual PR.
You can still manually trigger a test run with /test all

@coderabbitai
Copy link

coderabbitai bot commented Feb 5, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Adds scaling guardrail logic that annotates Deployments on replica changes and emits OperatorConditionApplyConfiguration overwrites; wires those overwrites through workload and controller call chains by extending several function signatures; adds a go.mod replace pointing github.com/openshift/library-go to a fork.

Changes

Cohort / File(s) Summary
Module Dependencies
go.mod
Adds // workload-condition-overwrites comment and a replace directing github.com/openshift/library-go to github.com/tchap/library-go v0.0.0-20260205162238-4ebccddf99eb.
Scaling implementation & tests
pkg/controllers/common/scaling/scaling.go, pkg/controllers/common/scaling/scaling_test.go
Adds scaling guardrail functions (ProcessDeployment, specsEqualIgnoringReplicas, isDeploymentProgressing, cancelProgressing) that annotate/track replica changes and return condition-overwrites; adds extensive unit tests covering timing, annotation propagation, parsing errors, and progression logic.
Deployment controller
pkg/controllers/deployment/deployment_controller.go
Extends Sync signature to return []*applyoperatorv1.OperatorConditionApplyConfiguration; fetches existing Deployment and invokes scaling.ProcessDeployment, propagating condition-overwrites through success and error paths.
Workload API & sync logic
pkg/operator/workload/sync_openshift_oauth_apiserver.go
Adds conditionPrefix field to OAuthAPIServerWorkload, updates NewOAuthAPIServerWorkload constructor, and changes Sync/syncDeployment to return condition-overwrites alongside Deployment and errors; prefetches existing Deployment to run scaling logic.
Operator starter
pkg/operator/starter.go
Introduces apiServerConditionsPrefix constant and passes it into NewOAuthAPIServerWorkload during workload construction.
Workload tests updated
pkg/operator/workload/sync_openshift_oauth_apiserver_test.go
Wires a deployments lister via fake informers, adapts test setup to the new three-value return from syncDeployment (captures/ignores the new value), and adjusts comparisons accordingly.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

No actionable comments were generated in the recent review. 🎉


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

@openshift-ci
Copy link
Contributor

openshift-ci bot commented Feb 5, 2026

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: tchap
Once this PR has been reviewed and has the lgtm label, please assign liouk for approval. 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

@tchap tchap force-pushed the no-progression-on-cluster-scaleup branch 5 times, most recently from 2c5caf5 to d8b074a Compare February 5, 2026 14:03
@openshift-merge-robot openshift-merge-robot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Feb 5, 2026
@tchap tchap force-pushed the no-progression-on-cluster-scaleup branch 2 times, most recently from 93c17d5 to 40dbc69 Compare February 5, 2026 14:12
@openshift-merge-robot openshift-merge-robot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Feb 5, 2026
@tchap tchap force-pushed the no-progression-on-cluster-scaleup branch 2 times, most recently from 2e340f0 to 5fa520e Compare February 5, 2026 16:26
@tchap
Copy link
Author

tchap commented Feb 5, 2026

/retitle OCPBUGS-65896: controllers: Prevent Progressing=True when scaling only

We can only merge this after the library-go changes are merged.

/hold

@openshift-ci openshift-ci bot changed the title controllers: Prevent Progressing=True when scaling only OCPBUGS-65896: controllers: Prevent Progressing=True when scaling only Feb 5, 2026
@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 Feb 5, 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 Feb 5, 2026
@openshift-ci-robot
Copy link
Contributor

@tchap: This pull request references Jira Issue OCPBUGS-65896, which is invalid:

  • expected the bug to target the "4.22.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:

This is a PoV, it doesn't build currently because of some changes needed in library-go.

Anyway, the idea basically is to extend Sync to return conditions that would overwrite the conditions generated by the library-go machinery.

We need to keep some context regarding the state of the Deployment, so I decided to propose a few annotations. The names are not final, not sure about what the proper prefix is actually. Not sure whether there is a better way to store state, feel free to propose another way.

The main idea is summarized in the doc comment for handleDeploymentScaling:

// handleDeploymentScaling ensures the operator does not end up progressing on scaling.
// We define that scaling happens any time .spec.replicas is the only field that changes.
// The idea is then as follows:
//
//  1. When the replicas field is updated, store the change timestamp in a deployment annotation.
//  2. When the deployment eventually starts progressing, add another annotation so that we know it happened.
//  3. When the deployment hasn't progressing for too long, or it has finished progressing, remove all annotations.
//
// When the timestamp annotation is present, we should overwrite Progressing to be false.

The annotation machinery is there to account for eventual consistency between creating/updating the deployment and the deployment controller picking the change up and actually updating the conditions there.

Also the current change is a PoC for a single controller, there is another controller to change basically in the same way. That refactoring should be pretty trivial.

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.

@tchap
Copy link
Author

tchap commented Feb 5, 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 Feb 5, 2026
@openshift-ci-robot
Copy link
Contributor

@tchap: This pull request references Jira Issue OCPBUGS-65896, 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 (4.22.0) matches configured target version for branch (4.22.0)
  • bug is in the state New, which is one of the valid states (NEW, ASSIGNED, POST)

No GitHub users were found matching the public email listed for the QA contact in Jira (ksiddiqu@redhat.com), skipping review request.

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.

@tchap tchap marked this pull request as ready for review February 5, 2026 16:31
@openshift-ci openshift-ci bot removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Feb 5, 2026
@openshift-ci-robot
Copy link
Contributor

@tchap: This pull request references Jira Issue OCPBUGS-65896, which is valid.

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

No GitHub users were found matching the public email listed for the QA contact in Jira (ksiddiqu@redhat.com), skipping review request.

Details

In response to this:

This is a PoV, it doesn't build currently because of some changes needed in library-go.

Anyway, the idea basically is to extend Sync to return conditions that would overwrite the conditions generated by the library-go machinery.

We need to keep some context regarding the state of the Deployment, so I decided to propose a few annotations. The names are not final, not sure about what the proper prefix is actually. Not sure whether there is a better way to store state, feel free to propose another way.

The main idea is summarized in the doc comment for ProcessDeployment:

// ProcessDeployment ensures the operator does not end up progressing on scaling.
// We define that scaling happens any time .spec.replicas is the only field that changes.
// The idea is then as follows:
//
//  1. When the replicas field is updated, store the change timestamp in a deployment annotation.
//  2. When the deployment eventually starts progressing, add another annotation so that we know it happened.
//  3. When the deployment hasn't progressing for too long, or it has finished progressing, remove all annotations.
//
// When the timestamp annotation is present, we should overwrite Progressing to be false.
//
// So, ProcessDeployment amends the expected deployment in place, also returning any conditions to set on the operator.

The annotation machinery is there to account for eventual consistency between creating/updating the deployment and the deployment controller picking the change up and actually updating the conditions there.

Also the current change is a PoC for a single controller, there is another controller to change basically in the same way. That refactoring should be pretty trivial.

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 ibihim and liouk February 5, 2026 16:33
@tchap tchap force-pushed the no-progression-on-cluster-scaleup branch from 5fa520e to ab1ed0f Compare February 5, 2026 16:54
Copy link

@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

🤖 Fix all issues with AI agents
In `@pkg/controllers/deployment/deployment_controller.go`:
- Around line 269-283: setRollingUpdateParameters mutates RollingUpdate fields
so scaling.ProcessDeployment sees non‑scaling diffs; to fix, normalize
RollingUpdate parameters before the scaling-only comparison by making a copy of
expectedDeployment (or a temp deployment) and setting its
Spec.Strategy.RollingUpdate to match
existingDeployment.Spec.Strategy.RollingUpdate (or nil) so only Replicas differ,
then call scaling.ProcessDeployment(existingDeployment, normalizedExpected,
...). Ensure you still use the original expectedDeployment for applying changes
but use the normalized copy for the conditionOverwrites call involving
setRollingUpdateParameters and scaling.ProcessDeployment.

@tchap tchap force-pushed the no-progression-on-cluster-scaleup branch from ab1ed0f to 966cb2c Compare February 5, 2026 17:08
}

actualDeployment, err := target.syncDeployment(context.TODO(), &scenario.operator.Spec.OperatorSpec, &scenario.operator.Status.OperatorStatus, eventRecorder)
actualDeployment, _, err := target.syncDeployment(context.TODO(), &scenario.operator.Spec.OperatorSpec, &scenario.operator.Status.OperatorStatus, eventRecorder)
Copy link
Author

Choose a reason for hiding this comment

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

I should add some tests here to also check the condition overwrites, I guess?

@tchap tchap force-pushed the no-progression-on-cluster-scaleup branch from 966cb2c to 229cba5 Compare February 5, 2026 17:13
conditionOverwrites, err := scaling.ProcessDeployment(existingDeployment, expectedDeployment, clock.RealClock{}, "OAuthServer")
if err != nil {
return nil, false, nil, append(errs, err)
}
Copy link
Author

Choose a reason for hiding this comment

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

There are no tests for this package really, so I can't extend them really to make sure this works properly. For now only the scaling package is being tested properly.

Copy link

@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

🤖 Fix all issues with AI agents
In `@pkg/operator/workload/sync_openshift_oauth_apiserver.go`:
- Around line 287-297: Add a short comment above the call to
encryptionkms.AddKMSPluginVolumeAndMountToPodSpec explaining why the KMS
volume/mount is applied before calling scaling.ProcessDeployment (e.g., "KMS
volumes must be added before scaling detection so ProcessDeployment sees the
final podSpec and does not misattribute changes" or note that this ordering is
intentional to ensure KMS config is present when comparing specs), mirroring the
explanatory style used in deployment_controller.go; reference the functions
AddKMSPluginVolumeAndMountToPodSpec and scaling.ProcessDeployment in the comment
so future readers understand the rationale.

@tchap tchap force-pushed the no-progression-on-cluster-scaleup branch from 229cba5 to cd9e42a Compare February 5, 2026 17:20
@openshift-merge-robot openshift-merge-robot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Feb 7, 2026
@tchap tchap force-pushed the no-progression-on-cluster-scaleup branch from cd9e42a to 933f489 Compare February 9, 2026 09:22
@openshift-merge-robot openshift-merge-robot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Feb 9, 2026
@openshift-ci
Copy link
Contributor

openshift-ci bot commented Feb 9, 2026

@tchap: 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-aws-operator-serial-ote 933f489 link false /test e2e-aws-operator-serial-ote
ci/prow/e2e-aws-operator-parallel-ote 933f489 link false /test e2e-aws-operator-parallel-ote

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

do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. 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.

3 participants