Skip to content

MCO-2136: Implement osImageStream inheritance for custom MCPs#5697

Open
umohnani8 wants to merge 1 commit intoopenshift:mainfrom
umohnani8:osimgstream-spec
Open

MCO-2136: Implement osImageStream inheritance for custom MCPs#5697
umohnani8 wants to merge 1 commit intoopenshift:mainfrom
umohnani8:osimgstream-spec

Conversation

@umohnani8
Copy link
Contributor

@umohnani8 umohnani8 commented Feb 25, 2026

- What I did
Custom MachineConfigPools now inherit the osImageStream setting from the worker pool when they don't explicitly define one. This aligns with the existing inheritance model where custom MCPs inherit all other settings from the worker pool.

Inheritance priority:

  1. Custom MCP's explicit spec.osImageStream.name (if set)
  2. Worker pool's spec.osImageStream.name (if custom MCP has none)
  3. OSImageStream.status.defaultStream (if neither specify one)

Changes:

  • Add isCustomPool() helper to identify custom pools (not master/worker/arbiter)
  • Add getOSImageStreamNameForPool() to implement inheritance logic at runtime
  • Add getOSImageStreamNameForPoolBootstrap() for bootstrap scenarios
  • Modify getOSImageStreamForPool() to use inheritance logic
  • Modify RunBootstrap() to use inheritance logic
  • Add comprehensive unit tests for all scenarios

- How to verify it
Spin up a cluster with dual stream and techpreview enabled. Create custom pools that inherit from worker pool and that don't and verify that the osImageStream value on those nodes are what is expected

- Description for the changelog
Implement osImageStream inheritance for custom MCPs

@openshift-ci-robot openshift-ci-robot added the jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. label Feb 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 Feb 25, 2026
@openshift-ci-robot
Copy link
Contributor

openshift-ci-robot commented Feb 25, 2026

@umohnani8: This pull request references MCO-2136 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "4.22.0" version, but no target version was set.

Details

In response to this:

Custom MachineConfigPools now inherit the osImageStream setting from the worker pool when they don't explicitly define one. This aligns with the existing inheritance model where custom MCPs inherit all other settings from the worker pool.

Inheritance priority:

  1. Custom MCP's explicit spec.osImageStream.name (if set)
  2. Worker pool's spec.osImageStream.name (if custom MCP has none)
  3. OSImageStream.status.defaultStream (if neither specify one)

Changes:

  • Add isCustomPool() helper to identify custom pools (not master/worker/arbiter)
  • Add getOSImageStreamNameForPool() to implement inheritance logic at runtime
  • Add getOSImageStreamNameForPoolBootstrap() for bootstrap scenarios
  • Modify getOSImageStreamForPool() to use inheritance logic
  • Modify RunBootstrap() to use inheritance logic
  • Add comprehensive unit tests for all scenarios

- What I did

- How to verify it

- Description for the changelog

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 added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Feb 25, 2026
@ptalgulk01
Copy link

ptalgulk01 commented Feb 26, 2026

Pre-merge verification

Environment Setup:
OCP version: 4.22.0-0-2026-02-26-044836-test-ci-ln-5ct1s0k-latest
Platform: AWS TechPreview

Steps:

  • Created below MCP's
MCP for rhel9 (default)
oc create -f - << EOF
apiVersion: machineconfiguration.openshift.io/v1
kind: MachineConfigPool
metadata:
  name: rhel9
spec:
  machineConfigSelector:
    matchExpressions:
      - {key: machineconfiguration.openshift.io/role, operator: In, values: [worker,rhel9]}
  nodeSelector:
    matchLabels:
      node-role.kubernetes.io/rhel9: ""
EOF
machineconfigpool.machineconfiguration.openshift.io/rhel9 created
MCP for rhel10
oc create -f - << EOF
apiVersion: machineconfiguration.openshift.io/v1
kind: MachineConfigPool
metadata:
  name: rhel10
spec:
  osImageStream:
    name: rhel-10
  machineConfigSelector:
    matchExpressions:
      - {key: machineconfiguration.openshift.io/role, operator: In, values: [worker,rhel10]}
  nodeSelector:
    matchLabels:
      node-role.kubernetes.io/rhel10: ""
EOF
machineconfigpool.machineconfiguration.openshift.io/rhel10 created
  • Check the osstream of custom MCP
$ oc get mcp rhel9 -ojsonpath='{.status.osImageStream.name}'
empty

$ oc get mcp rhel10 -ojsonpath='{.status.osImageStream.name}'
rhel-10
  • Added the node in respective custom MCP
$ oc label node ip-10-0-13-255.us-east-2.compute.internal  node-role.kubernetes.io/rhel9=
node/ip-10-0-13-255.us-east-2.compute.internal labeled

$ oc label node ip-10-0-50-220.us-east-2.compute.internal  node-role.kubernetes.io/rhel10=
node/ip-10-0-50-220.us-east-2.compute.internal labeled
  • Check added node in respective MCP has the required MCP
$ oc debug node/ip-10-0-13-255.us-east-2.compute.internal -- chroot /host rpm-ostree status
Starting pod/ip-10-0-13-255us-east-2computeinternal-debug-m6qtc ...
To use host binaries, run `chroot /host`
State: idle
Deployments:
* ostree-unverified-registry:registry.build07.ci.openshift.org/ci-ln-5ct1s0k/stable@sha256:42e2e4d11674c603398469770700ef5a30432294ffa245ed1c67852e93fc380e
                   Digest: sha256:42e2e4d11674c603398469770700ef5a30432294ffa245ed1c67852e93fc380e
                  Version: 9.8.20260221-0 (2026-02-21T19:42:20Z)

Removing debug pod ...

$ oc debug node/ip-10-0-50-220.us-east-2.compute.internal -- chroot /host rpm-ostree status
Starting pod/ip-10-0-50-220us-east-2computeinternal-debug-tmpdw ...
To use host binaries, run `chroot /host`
State: idle
Deployments:
* ostree-unverified-registry:registry.build07.ci.openshift.org/ci-ln-5ct1s0k/stable@sha256:4a1798a3b92a794a69d56eaf78c1521a1c4d2e52fd05057072780ec19ccabd45
                   Digest: sha256:4a1798a3b92a794a69d56eaf78c1521a1c4d2e52fd05057072780ec19ccabd45
                  Version: 10.1.20260126-0 (2026-01-27T06:43:47Z)

Removing debug pod ...

Tested with existing TC

passed: (24.9s) 2026-02-26T09:56:31 "[sig-mco] MCO osImageStream Author:sregidor-NonHyperShiftHOST-Low-86924-[P1] Validate OS Image Streams value"
passed: (1m46s) 2026-02-26T09:57:52 "[sig-mco] MCO osImageStream Author:sregidor-NonHyperShiftHOST-Critical-86495-[P2] Check default OS Image Stream"
passed: (21m16s) 2026-02-26T10:19:24 "[sig-mco] MCO osImageStream Author:sregidor-NonHyperShiftHOST-Longduration-Medium-87097-[P2] Extensions from rhel9 stream to rhel10 stream [Disruptive] [Serial]"
passed: (19m12s) 2026-02-26T10:38:36 "[sig-mco] MCO osImageStream Author:sregidor-NonHyperShiftHOST-Longduration-Medium-87095-[P2] Realtime kernel from rhel9 stream to rhel10 stream [Disruptive] [Serial]"

@ptalgulk01
Copy link

ptalgulk01 commented Feb 26, 2026

There are some other scenarios considered too

Case 1

  • Worker pool is on rhel-9(default)
  • Created custom MCP infra
MCP
oc create -f - << EOF
apiVersion: machineconfiguration.openshift.io/v1
kind: MachineConfigPool
metadata:
  name: infra
spec:
  machineConfigSelector:
    matchExpressions:
      - {key: machineconfiguration.openshift.io/role, operator: In, values: [worker,infra]}
  nodeSelector:
    matchLabels:
      node-role.kubernetes.io/infra: ""
EOF
machineconfigpool.machineconfiguration.openshift.io/infra created
  • Patched the osstream rhel-10 on worker pool
  • Infra pool is still on rhel-9
  • Added node in infra pool it moves to rhel-9

Case-2

  • Patched the worker pool with rhel10 osstream
  • Created custom mcp
MCP
oc create -f - << EOF
apiVersion: machineconfiguration.openshift.io/v1
kind: MachineConfigPool
metadata:
  name: cmcp1
spec:
  machineConfigSelector:
    matchExpressions:
      - {key: machineconfiguration.openshift.io/role, operator: In, values: [worker,cmcp1]}
  nodeSelector:
    matchLabels:
      node-role.kubernetes.io/cmcp1: ""
EOF
machineconfigpool.machineconfiguration.openshift.io/cmcp1 created
- created anyother custom mcp with rhel9 osstream
MCP
oc create -f - << EOF
apiVersion: machineconfiguration.openshift.io/v1
kind: MachineConfigPool
metadata:
  name: cmcp2
spec:
  osImageStream:
    name: rhel-9
  machineConfigSelector:
    matchExpressions:
      - {key: machineconfiguration.openshift.io/role, operator: In, values: [worker,cmcp2]}
  nodeSelector:
    matchLabels:
      node-role.kubernetes.io/cmcp2: ""
EOF
machineconfigpool.machineconfiguration.openshift.io/cmcp2 created
- Checked the osstream version
$ oc get mcp cmcp1 -ojsonpath='{.spec.osImageStream.name}'
empty
$ oc get mcp cmcp2 -ojsonpath='{.spec.osImageStream.name}'
rhel-9
  • Added node in both pools
  • For cmcp1 the node added shows rhel-10 version
  • For cmcp2 the node added shows rhel-9 version

For case 2 the cmcp1 MCP does not show osstream mention but when we add the node it shows node on rhel-10

@umohnani8 umohnani8 force-pushed the osimgstream-spec branch 2 times, most recently from 831b6cd to 78d09b1 Compare February 26, 2026 23:12
@openshift-ci-robot
Copy link
Contributor

openshift-ci-robot commented Feb 27, 2026

@umohnani8: This pull request references MCO-2136 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "4.22.0" version, but no target version was set.

Details

In response to this:

- What I did
Custom MachineConfigPools now inherit the osImageStream setting from the worker pool when they don't explicitly define one. This aligns with the existing inheritance model where custom MCPs inherit all other settings from the worker pool.

Inheritance priority:

  1. Custom MCP's explicit spec.osImageStream.name (if set)
  2. Worker pool's spec.osImageStream.name (if custom MCP has none)
  3. OSImageStream.status.defaultStream (if neither specify one)

Changes:

  • Add isCustomPool() helper to identify custom pools (not master/worker/arbiter)
  • Add getOSImageStreamNameForPool() to implement inheritance logic at runtime
  • Add getOSImageStreamNameForPoolBootstrap() for bootstrap scenarios
  • Modify getOSImageStreamForPool() to use inheritance logic
  • Modify RunBootstrap() to use inheritance logic
  • Add comprehensive unit tests for all scenarios

- How to verify it
Spin up a cluster with dual stream and techpreview enabled. Create custom pools that inherit from worker pool and that don't and verify that the osImageStream value on those nodes are what is expected

- Description for the changelog
Implement osImageStream inheritance for custom MCPs

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.

@umohnani8 umohnani8 changed the title [WIP] MCO-2136: Implement osImageStream inheritance for custom MCPs MCO-2136: Implement osImageStream inheritance for custom MCPs Feb 27, 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 Feb 27, 2026
@umohnani8
Copy link
Contributor Author

/test unit

@ptalgulk01
Copy link

Re-tested for following scenarios:

Case1:

  • Worker MCP is on rhel-9 (default)
  • Created new custom MCP
    - MCP1 "rhel9" -> didnt mention osstream field in MCP
    - MCP2 "rhel10" -> explicitly mention rhel-10 osstream field in MCP
  • Added nodes in respective new created MCP
    - For "rhel9" MCP node shows rhel-9 version
    - For "rhel10" MCP node shows rhel-10 version

Case2:

  • Worker MCP is on rhel-9 (default)
  • Created new custom MCP "infra"
  • Patch the rhel-10 on worker MCP
  • Added node in infra pool
  • Able to see node is showing rhel-10 version

Question: Though node shows rhel10 version when added in infra mcp but when we check the osstream in it, it shows empty value

oc get mcp infra -o yaml | grep rhel
empty

oc debug node/ip-10-0-95-254.us-east-2.compute.internal -- chroot /host rpm-ostree status
Starting pod/ip-10-0-95-254us-east-2computeinternal-debug-sczpp ...
To use host binaries, run `chroot /host`
State: idle
Deployments:
* ostree-unverified-registry:registry.build07.ci.openshift.org/ci-ln-qfm3dgt/stable@sha256:4a1798a3b92a794a69d56eaf78c1521a1c4d2e52fd05057072780ec19ccabd45
                   Digest: sha256:4a1798a3b92a794a69d56eaf78c1521a1c4d2e52fd05057072780ec19ccabd45
                  Version: 10.1.20260126-0 (2026-01-27T06:43:47Z)

Removing debug pod ...

Case3

  • Worker MCP is on rhel10
  • Created custom MCP
    - MCP1 "cmcp1" -> didnt mention osstream field in MCP
    - MCP2 "cmcp2" -> explicitly mention rhel-9 osstream field in MCP
  • Added nodes in respective new created MCP
    - For "cmcp1" MCP node shows rhel-10 version
    - For "cmcp2" MCP node shows rhel-9 version

Question: Same here too for cmcp MCP not able to see the ossteam mention about rhel-10 though node is on rhel-10 version

oc get mcp cmcp1 -ojsonpath='{.spec.osImageStream.name}'
empty

oc get mcp cmcp2 -ojsonpath='{.spec.osImageStream.name}'
rhel-9

Copy link
Contributor

@pablintino pablintino left a comment

Choose a reason for hiding this comment

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

Important:

func (optr *Operator) getOsImageURLs(namespace, osImageStreamName string) (string, string, error) {
requires an update too. It's in the operator side.

This change allows custom MachineConfigPools (pools other than master,
worker, or arbiter) to inherit the osImageStream setting from the worker
pool when not explicitly set, aligning with the existing inheritance model
for custom MCPs.

Inheritance priority:
1. If custom MCP explicitly sets spec.osImageStream.name, use that value
2. If not set, inherit from worker pool's spec.osImageStream.name
3. If worker pool also doesn't set it, use OSImageStream.status.defaultStream

The implementation includes:
- GetEffectiveOSImageStreamName() helper in common/helpers.go for shared
  inheritance logic
- Modified render controller to use inheritance when determining OS images
  for rendered MachineConfigs
- Bootstrap scenario support with static helper function
- Automatic re-rendering of custom pools when worker pool's osImageStream
  changes
- Comprehensive unit tests for all inheritance scenarios

Note: This change only affects the render controller (spec → osImageURL).
Status field population is handled by PR openshift#5689, which automatically reflects
the inherited stream by matching deployed osImageURLs against available
streams.

Signed-off-by: Urvashi <umohnani@redhat.com>
@umohnani8
Copy link
Contributor Author

@pablintino I have addressed your reviews, this should be ready now. @ptalgulk01 will probably verify it when she is back tomorrow.

@pablintino
Copy link
Contributor

/lgtm

@openshift-ci openshift-ci bot added the lgtm Indicates that a PR is ready to be merged. label Mar 3, 2026
@openshift-ci
Copy link
Contributor

openshift-ci bot commented Mar 3, 2026

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: pablintino, umohnani8

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:
  • OWNERS [pablintino,umohnani8]

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

@pablintino
Copy link
Contributor

/retest-required

@umohnani8
Copy link
Contributor Author

@ptalgulk01 addressing your comment #5697 (comment):

It is expected for {.spec.osImageStream.name} to be empty for a custom pool when it is inheriting the ossStream from the worker pool. That value will only be populated when the custom pool explicitly sets an osStream for it, so it is not inheriting from the worker pool.

You will be able to see the effective osStream of any pool under the Status section once #5689 is merged. Feel free to wait for that merge in to verify again before adding the verified label for this PR.

@ptalgulk01
Copy link

/label qe-approved
/verified by @ptalgulk01

@openshift-ci openshift-ci bot added the qe-approved Signifies that QE has signed off on this PR label Mar 6, 2026
@openshift-ci-robot
Copy link
Contributor

openshift-ci-robot commented Mar 6, 2026

@umohnani8: This pull request references MCO-2136 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "4.22.0" version, but no target version was set.

Details

In response to this:

- What I did
Custom MachineConfigPools now inherit the osImageStream setting from the worker pool when they don't explicitly define one. This aligns with the existing inheritance model where custom MCPs inherit all other settings from the worker pool.

Inheritance priority:

  1. Custom MCP's explicit spec.osImageStream.name (if set)
  2. Worker pool's spec.osImageStream.name (if custom MCP has none)
  3. OSImageStream.status.defaultStream (if neither specify one)

Changes:

  • Add isCustomPool() helper to identify custom pools (not master/worker/arbiter)
  • Add getOSImageStreamNameForPool() to implement inheritance logic at runtime
  • Add getOSImageStreamNameForPoolBootstrap() for bootstrap scenarios
  • Modify getOSImageStreamForPool() to use inheritance logic
  • Modify RunBootstrap() to use inheritance logic
  • Add comprehensive unit tests for all scenarios

- How to verify it
Spin up a cluster with dual stream and techpreview enabled. Create custom pools that inherit from worker pool and that don't and verify that the osImageStream value on those nodes are what is expected

- Description for the changelog
Implement osImageStream inheritance for custom MCPs

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-robot openshift-ci-robot added the verified Signifies that the PR passed pre-merge verification criteria label Mar 6, 2026
@openshift-ci-robot
Copy link
Contributor

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

Details

In response to this:

/label qe-approved
/verified by @ptalgulk01

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.

@umohnani8
Copy link
Contributor Author

/test e2e-hypershift

@openshift-ci
Copy link
Contributor

openshift-ci bot commented Mar 6, 2026

@isabella-janssen: This PR was included in a payload test run from openshift/origin#30845
trigger 1 job(s) for the /payload-(with-prs|job|aggregate|job-with-prs|aggregate-with-prs) command

  • periodic-ci-openshift-release-main-ci-4.22-e2e-aws-ovn-rhcos10-techpreview-serial-1of3

See details on https://pr-payload-tests.ci.openshift.org/runs/ci/e5745130-198b-11f1-9d4f-fb2221c027fa-0

@openshift-ci
Copy link
Contributor

openshift-ci bot commented Mar 6, 2026

@isabella-janssen: This PR was included in a payload test run from openshift/origin#30845
trigger 1 job(s) for the /payload-(with-prs|job|aggregate|job-with-prs|aggregate-with-prs) command

  • periodic-ci-openshift-release-main-ci-4.22-e2e-aws-ovn-rhcos10-techpreview-serial-2of3

See details on https://pr-payload-tests.ci.openshift.org/runs/ci/ed76a400-198b-11f1-8a30-b929a0a0432d-0

@openshift-ci
Copy link
Contributor

openshift-ci bot commented Mar 6, 2026

@isabella-janssen: This PR was included in a payload test run from openshift/origin#30845
trigger 1 job(s) for the /payload-(with-prs|job|aggregate|job-with-prs|aggregate-with-prs) command

  • periodic-ci-openshift-release-main-ci-4.22-e2e-aws-ovn-rhcos10-techpreview-serial-3of3

See details on https://pr-payload-tests.ci.openshift.org/runs/ci/f27c3190-198b-11f1-8dd4-0f4d077ca52f-0

@isabella-janssen
Copy link
Member

/retest-required

1 similar comment
@isabella-janssen
Copy link
Member

/retest-required

@openshift-ci
Copy link
Contributor

openshift-ci bot commented Mar 8, 2026

@umohnani8: 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-gcp-op-2of2 c7f3249 link true /test e2e-gcp-op-2of2
ci/prow/e2e-hypershift f02ab03 link true /test e2e-hypershift

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.

@pablintino
Copy link
Contributor

/retest-required

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-reference Indicates that this PR references a valid Jira ticket of any type. lgtm Indicates that a PR is ready to be merged. qe-approved Signifies that QE has signed off on this PR verified Signifies that the PR passed pre-merge verification criteria

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants