Skip to content

🐛 OCPBUGS-76381, OCPBUGS-76383: fix(deploymentConfig): honor empty affinity objects as erasure requests like OLMv0#2591

Merged
openshift-merge-bot[bot] merged 1 commit intooperator-framework:mainfrom
camilamacedo86:fix-empty-affinity
Mar 31, 2026
Merged

🐛 OCPBUGS-76381, OCPBUGS-76383: fix(deploymentConfig): honor empty affinity objects as erasure requests like OLMv0#2591
openshift-merge-bot[bot] merged 1 commit intooperator-framework:mainfrom
camilamacedo86:fix-empty-affinity

Conversation

@camilamacedo86
Copy link
Copy Markdown
Contributor

@camilamacedo86 camilamacedo86 commented Mar 25, 2026

Problem

OLMv1 does not match OLMv0 when users pass empty affinity objects in deploymentConfig.

  1. affinity: {} should erase all affinity from the deployment. OLMv1 keeps the bundle affinity instead.
  2. affinity: {nodeAffinity: {}} should erase only nodeAffinity. OLMv1 leaves an empty nodeAffinity: {} in the manifest.

Why do we need to do it?

Current OLMv1 does not fully erase it, so the bundle’s affinity can remain, or an empty nodeAffinity: {} is left behind.
This ensures affinity: {} removes all affinity and empty subfields such as nodeAffinity: {} remove only that section, instead of preserving bundle affinity or leaving empty objects behind in the rendered manifest.

Solution

Update applyAffinityConfig to follow OLMv0 OverrideDeploymentAffinity behavior:

  • nil → do not touch
  • {} → erase all affinity
  • {nodeAffinity: {}} → erase nodeAffinity, keep others
  • {nodeAffinity: {...}} → replace nodeAffinity, keep others
  • If all sub-fields end up empty, set the whole affinity to nil

Before

# User sets: affinity: {}
# Bundle affinity is kept (wrong)
spec:
  template:
    spec:
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: disktype
                operator: In
                values:
                - ssd
# User sets: affinity: {nodeAffinity: {}}
# Empty object stays in manifest (wrong)
spec:
  template:
    spec:
      affinity:
        nodeAffinity: {}
        podAffinity: ...

After

# User sets: affinity: {}
# All affinity is erased (correct)
spec:
  template:
    spec:
      # no affinity
# User sets: affinity: {nodeAffinity: {}}
# Only nodeAffinity is erased, podAffinity stays (correct)
spec:
  template:
    spec:
      affinity:
        podAffinity: ...

Copilot AI review requested due to automatic review settings March 25, 2026 08:00
@openshift-ci openshift-ci Bot requested review from grokspawn and trgeiger March 25, 2026 08:00
@netlify
Copy link
Copy Markdown

netlify Bot commented Mar 25, 2026

Deploy Preview for olmv1 ready!

Name Link
🔨 Latest commit a942d88
🔍 Latest deploy log https://app.netlify.com/projects/olmv1/deploys/69cad08b7c32ce0008606cd3
😎 Deploy Preview https://deploy-preview-2591--olmv1.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@camilamacedo86 camilamacedo86 changed the title 🐛 fix(deploymentConfig): handle empty affinity objects to match OLMv0 erasure behavior 🐛 OCPBUGS-76381, OCPBUGS-76383: fix(deploymentConfig): handle empty affinity objects to match OLMv0 erasure behavior Mar 25, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR updates the registryv1 bundle deployment rendering logic to match OLMv0’s “erasure” semantics for deploymentConfig.affinity, ensuring that explicitly empty affinity objects clear previously-applied affinity rather than being treated as a no-op.

Changes:

  • Update applyAffinityConfig to treat empty Affinity / empty affinity sub-types (e.g., NodeAffinity: {}) as erase operations.
  • Add/extend unit and e2e coverage for “empty affinity erases” behavior.
  • Add new regression manifest fixtures for empty-affinity rendering cases.

Reviewed changes

Copilot reviewed 26 out of 32 changed files in this pull request and generated no comments.

Show a summary per file
File Description
internal/operator-controller/rukpak/render/registryv1/generators/generators.go Implement OLMv0-like affinity erasure semantics for empty affinity objects/sub-objects.
internal/operator-controller/rukpak/render/registryv1/generators/generators_test.go Add unit tests covering empty affinity and empty sub-type erasure behavior.
test/e2e/features/install.feature Add e2e scenarios validating that empty affinity config erases previously applied affinity (and sub-type-only erasure).
test/regression/convert/generate-manifests.go Add regression generation cases for empty affinity and empty affinity subtype.
test/regression/convert/testdata/expected-manifests/argocd-operator.v0.6.0/with-empty-affinity/00_clusterrole_argocd-operator-metrics-reader.yaml New expected output fixture for empty-affinity rendering case.
test/regression/convert/testdata/expected-manifests/argocd-operator.v0.6.0/with-empty-affinity/01_clusterrole_argocd-operator.v0-1dhiybrldl1gyksid1dk2dqjsc72psdybc7iyvse5gpx.yaml New expected output fixture for empty-affinity rendering case.
test/regression/convert/testdata/expected-manifests/argocd-operator.v0.6.0/with-empty-affinity/02_clusterrole_argocd-operator.v0.-3gkm3u8zfarktdile5wekso69zs9bgzb988mhjm0y6p.yaml New expected output fixture for empty-affinity rendering case.
test/regression/convert/testdata/expected-manifests/argocd-operator.v0.6.0/with-empty-affinity/03_clusterrolebinding_argocd-operator.v0-1dhiybrldl1gyksid1dk2dqjsc72psdybc7iyvse5gpx.yaml New expected output fixture for empty-affinity rendering case.
test/regression/convert/testdata/expected-manifests/argocd-operator.v0.6.0/with-empty-affinity/04_clusterrolebinding_argocd-operator.v0.-3gkm3u8zfarktdile5wekso69zs9bgzb988mhjm0y6p.yaml New expected output fixture for empty-affinity rendering case.
test/regression/convert/testdata/expected-manifests/argocd-operator.v0.6.0/with-empty-affinity/05_configmap_argocd-operator-manager-config.yaml New expected output fixture for empty-affinity rendering case.
test/regression/convert/testdata/expected-manifests/argocd-operator.v0.6.0/with-empty-affinity/06_customresourcedefinition_applications.argoproj.io.yaml New expected output fixture for empty-affinity rendering case.
test/regression/convert/testdata/expected-manifests/argocd-operator.v0.6.0/with-empty-affinity/08_customresourcedefinition_appprojects.argoproj.io.yaml New expected output fixture for empty-affinity rendering case.
test/regression/convert/testdata/expected-manifests/argocd-operator.v0.6.0/with-empty-affinity/09_customresourcedefinition_argocdexports.argoproj.io.yaml New expected output fixture for empty-affinity rendering case.
test/regression/convert/testdata/expected-manifests/argocd-operator.v0.6.0/with-empty-affinity/11_deployment_argocd-operator-controller-manager.yaml New expected output fixture showing affinity erased in rendered Deployment.
test/regression/convert/testdata/expected-manifests/argocd-operator.v0.6.0/with-empty-affinity/12_service_argocd-operator-controller-manager-metrics-service.yaml New expected output fixture for empty-affinity rendering case.
test/regression/convert/testdata/expected-manifests/argocd-operator.v0.6.0/with-empty-affinity/13_serviceaccount_argocd-operator-controller-manager.yaml New expected output fixture for empty-affinity rendering case.
test/regression/convert/testdata/expected-manifests/argocd-operator.v0.6.0/with-empty-affinity-subtype/00_clusterrole_argocd-operator-metrics-reader.yaml New expected output fixture for empty-affinity-subtype rendering case.
test/regression/convert/testdata/expected-manifests/argocd-operator.v0.6.0/with-empty-affinity-subtype/01_clusterrole_argocd-operator.v0-1dhiybrldl1gyksid1dk2dqjsc72psdybc7iyvse5gpx.yaml New expected output fixture for empty-affinity-subtype rendering case.
test/regression/convert/testdata/expected-manifests/argocd-operator.v0.6.0/with-empty-affinity-subtype/02_clusterrole_argocd-operator.v0.-3gkm3u8zfarktdile5wekso69zs9bgzb988mhjm0y6p.yaml New expected output fixture for empty-affinity-subtype rendering case.
test/regression/convert/testdata/expected-manifests/argocd-operator.v0.6.0/with-empty-affinity-subtype/03_clusterrolebinding_argocd-operator.v0-1dhiybrldl1gyksid1dk2dqjsc72psdybc7iyvse5gpx.yaml New expected output fixture for empty-affinity-subtype rendering case.
test/regression/convert/testdata/expected-manifests/argocd-operator.v0.6.0/with-empty-affinity-subtype/04_clusterrolebinding_argocd-operator.v0.-3gkm3u8zfarktdile5wekso69zs9bgzb988mhjm0y6p.yaml New expected output fixture for empty-affinity-subtype rendering case.
test/regression/convert/testdata/expected-manifests/argocd-operator.v0.6.0/with-empty-affinity-subtype/05_configmap_argocd-operator-manager-config.yaml New expected output fixture for empty-affinity-subtype rendering case.
test/regression/convert/testdata/expected-manifests/argocd-operator.v0.6.0/with-empty-affinity-subtype/08_customresourcedefinition_appprojects.argoproj.io.yaml New expected output fixture for empty-affinity-subtype rendering case.
test/regression/convert/testdata/expected-manifests/argocd-operator.v0.6.0/with-empty-affinity-subtype/09_customresourcedefinition_argocdexports.argoproj.io.yaml New expected output fixture for empty-affinity-subtype rendering case.
test/regression/convert/testdata/expected-manifests/argocd-operator.v0.6.0/with-empty-affinity-subtype/11_deployment_argocd-operator-controller-manager.yaml New expected output fixture showing nodeAffinity erased while other affinity parts remain.
test/regression/convert/testdata/expected-manifests/argocd-operator.v0.6.0/with-empty-affinity-subtype/12_service_argocd-operator-controller-manager-metrics-service.yaml New expected output fixture for empty-affinity-subtype rendering case.
test/regression/convert/testdata/expected-manifests/argocd-operator.v0.6.0/with-empty-affinity-subtype/13_serviceaccount_argocd-operator-controller-manager.yaml New expected output fixture for empty-affinity-subtype rendering case.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@camilamacedo86 camilamacedo86 changed the title 🐛 OCPBUGS-76381, OCPBUGS-76383: fix(deploymentConfig): handle empty affinity objects to match OLMv0 erasure behavior WIP 🐛 OCPBUGS-76381, OCPBUGS-76383: fix(deploymentConfig): handle empty affinity objects to match OLMv0 erasure behavior Mar 25, 2026
@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 Mar 25, 2026
@camilamacedo86 camilamacedo86 changed the title WIP 🐛 OCPBUGS-76381, OCPBUGS-76383: fix(deploymentConfig): handle empty affinity objects to match OLMv0 erasure behavior 🐛 OCPBUGS-76381, OCPBUGS-76383: fix(deploymentConfig): handle empty affinity objects to match OLMv0 erasure behavior Mar 30, 2026
@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 Mar 30, 2026
@camilamacedo86 camilamacedo86 changed the title 🐛 OCPBUGS-76381, OCPBUGS-76383: fix(deploymentConfig): handle empty affinity objects to match OLMv0 erasure behavior 🐛 OCPBUGS-76381, OCPBUGS-76383: fix(deploymentConfig): honor empty affinity objects as erasure requests like OLMv0 Mar 30, 2026
@camilamacedo86 camilamacedo86 requested a review from Copilot March 30, 2026 13:42
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 26 out of 32 changed files in this pull request and generated no new comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@tmshort
Copy link
Copy Markdown
Contributor

tmshort commented Mar 30, 2026

/approve
Although I feel that we shouldn't have to duplicate/copy the operators (i.e. argo) into different directories. My gut is telling me that we should have a baseline operator and apply changes to it for the different versions. Just a thought.

@openshift-ci
Copy link
Copy Markdown

openshift-ci Bot commented Mar 30, 2026

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: tmshort

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 Mar 30, 2026
@camilamacedo86
Copy link
Copy Markdown
Contributor Author

Hi @tmshort

Thank you !!

Although I feel that we shouldn't have to duplicate/copy the operators (i.e. argo) into different directories. My gut is telling me that we should have a baseline operator and apply changes to it for the different versions. Just a thought.

That is how it is today, but for sure we can look to see if we can improve that in follow up.

@camilamacedo86 camilamacedo86 force-pushed the fix-empty-affinity branch 2 times, most recently from 66821ae to 0400191 Compare March 30, 2026 18:43
Copilot AI review requested due to automatic review settings March 30, 2026 18:43
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 26 out of 32 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread internal/operator-controller/rukpak/render/registryv1/generators/generators.go Outdated
Copilot AI review requested due to automatic review settings March 30, 2026 19:32
…rasure behavior

- Fixed isNodeAffinityEmpty() to treat non-nil RequiredDuringSchedulingIgnoredDuringExecution
  with empty NodeSelectorTerms as empty (handles YAML unmarshaling edge case)
- Added unit test for empty nodeSelectorTerms scenario

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@codecov
Copy link
Copy Markdown

codecov Bot commented Mar 31, 2026

Codecov Report

❌ Patch coverage is 55.55556% with 28 lines in your changes missing coverage. Please review.
✅ Project coverage is 68.85%. Comparing base (df1b502) to head (a942d88).
⚠️ Report is 6 commits behind head on main.

Files with missing lines Patch % Lines
test/regression/convert/generate-manifests.go 0.00% 18 Missing ⚠️
.../rukpak/render/registryv1/generators/generators.go 77.77% 8 Missing and 2 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2591      +/-   ##
==========================================
- Coverage   68.86%   68.85%   -0.01%     
==========================================
  Files         139      139              
  Lines        9872     9930      +58     
==========================================
+ Hits         6798     6837      +39     
- Misses       2557     2578      +21     
+ Partials      517      515       -2     
Flag Coverage Δ
e2e 37.30% <0.00%> (-0.46%) ⬇️
experimental-e2e 52.40% <0.00%> (-0.20%) ⬇️
unit 53.53% <55.55%> (+0.02%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@perdasilva
Copy link
Copy Markdown
Contributor

/lgtm

@openshift-ci openshift-ci Bot added the lgtm Indicates that a PR is ready to be merged. label Mar 31, 2026
@openshift-merge-bot openshift-merge-bot Bot merged commit 0a6b9de into operator-framework:main Mar 31, 2026
31 of 32 checks passed
@camilamacedo86 camilamacedo86 deleted the fix-empty-affinity branch April 1, 2026 02:01
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. lgtm Indicates that a PR is ready to be merged.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants