Skip to content

CNTRLPLANE-3553: feat(nodepool): thread streamName through all platform callers#8834

Draft
sdminonne wants to merge 3 commits into
openshift:mainfrom
sdminonne:CNTRLPLANE-3553-thread-streamName-all-platforms
Draft

CNTRLPLANE-3553: feat(nodepool): thread streamName through all platform callers#8834
sdminonne wants to merge 3 commits into
openshift:mainfrom
sdminonne:CNTRLPLANE-3553-thread-streamName-all-platforms

Conversation

@sdminonne

@sdminonne sdminonne commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

Summary

Wire the resolved RHEL stream name (streamName) through Azure, PowerVS, OpenStack, and KubeVirt platform resolvers so each platform selects boot image metadata from the correct OS stream (rhel-9 or rhel-10) instead of always using the legacy default StreamMetadata.

  • CAPI paths use c.resolvedRHELStreamForBootImage from ConfigGenerator; condition-setter paths resolve via getRHELStreamForBootImage().
  • All functions that previously accessed releaseImage.StreamMetadata directly now go through releaseImage.StreamForName(streamName).

PR Dependency Graph

#8675 (merged) ─► #8719 (merged) ─► #8730 (open) ─► This PR
                                        │
#8669 (merged) ─► #8699 (merged) ─► #8709 (open) ──┘
                                        │
                                    #8792 (open)
PR Title Status Relation
#8675 API: add OSImageStream field to NodePool merged grandparent
#8719 API: add GetRHELStream + stream constants merged parent
#8730 Wire osImageStream into NodePool controller (hash, token, status, validation) open direct parent
#8709 feat(nodepool): use stream metadata for platform image resolution open sibling
#8792 feat(nodepool): validate osImageStream in webhook open sibling
#8832 feat(nodepool): detect usesRunc from ContainerRuntimeConfig open (draft) sibling
This PR feat(nodepool): thread streamName through all platform callers open (draft) this PR

Platforms Updated

Platform Functions changed
Azure defaultAzureNodePoolImage, getAzureMarketplaceMetadata
PowerVS getPowerVSImage, ibmPowerVSMachineTemplateSpec, setPowerVSconditions
OpenStack OpenstackDefaultImage, OpenStackReleaseImage, MachineTemplateSpec, ReconcileOpenStackImageSpec, PrefixedClusterImageName, setOpenStackConditions, reconcileOpenStackImageCR
KubeVirt defaultImage, GetImage, MachineTemplateSpec, setKubevirtConditions

Test plan

  • All existing nodepool package tests pass with "" (empty/default) stream name
  • Verify multi-stream resolution with OSStreams populated on ReleaseImage (integration)
  • Run e2e-aws-upgrade-hypershift-operator to validate no spurious rollouts

Ref: CNTRLPLANE-3553

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added automatic RHEL OS stream detection from running machines and store it in NodePool status.
    • Improved image selection across AWS, Azure, GCP, OpenStack, KubeVirt, and PowerVS to use the detected or configured OS stream.
  • Bug Fixes

    • Fixed image defaulting and validation so stream-related issues are reported earlier and more clearly.
    • Improved rollout hashing to better handle default vs. non-default OS image streams, reducing unnecessary or missing updates.

@openshift-merge-bot

Copy link
Copy Markdown
Contributor

Pipeline controller notification
This repo is configured to use the pipeline controller. Second-stage tests will be triggered either automatically or after lgtm label is added, depending on the repository configuration. The pipeline controller will automatically detect which contexts are required and will utilize /test Prow commands to trigger the second stage.

For optional jobs, comment /test ? to see a list of all defined jobs. To trigger manually all jobs from second stage use /pipeline required command.

This repository is configured in: LGTM mode

@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 Jun 25, 2026
@openshift-ci

openshift-ci Bot commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

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

coderabbitai Bot commented Jun 25, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

Changes

This PR introduces explicit RHEL stream resolution (getRHELStream, validateOSImageStream, GetRHELStream default change) and threads a resolved stream name through AMI/image selection paths for AWS, Azure, GCP, KubeVirt, OpenStack, and PowerVS NodePool controllers and CAPI template generation. ConfigGenerator now includes resolvedRHELStream/rhelStream, affecting rollout hashes. Token Secrets gain a new os-stream data key. A new majority-vote mechanism infers and sets NodePool.Status.OSImageStream from observed Machine OS images. Corresponding unit tests were added/updated across all affected files.

Sequence Diagram(s)

sequenceDiagram
    participant Reconciler as NodePoolReconciler
    participant Stream as getRHELStream
    participant Platform as Platform Image Resolver
    participant Machines as Machine List
    participant Status as NodePool.Status

    Reconciler->>Stream: resolve RHEL stream (NodePool, ReleaseImage)
    Stream-->>Reconciler: resolved stream name
    Reconciler->>Platform: resolveAMI/Image(streamName)
    Platform-->>Reconciler: image reference

    Reconciler->>Machines: list machines for NodePool
    Machines-->>Reconciler: machine OS image data
    Reconciler->>Reconciler: infer majority stream from OS images
    Reconciler->>Status: set OSImageStream (if majority found)
Loading

Compact metadata

  • Estimated review effort: High
  • Total lines changed: approximately +920/-90 across 33 files

Related issues: None specified in the provided summary.
Related PRs: None specified in the provided summary.

Suggested labels: area/nodepool, area/api, needs-tests-review

Suggested reviewers: hypershift-nodepool-maintainers

Poem

A rabbit hops through streams of RHEL,
Nine and ten, it knows so well,
AWS, Azure, GCP in tow,
KubeVirt and OpenStack also go,
Status now reflects what machines tell.

🚥 Pre-merge checks | ✅ 11
✅ Passed checks (11 passed)
Check name Status Explanation
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 Changed tests use static literal names; no Ginkgo It/Describe/Context/When titles or runtime-generated identifiers were found.
Test Structure And Quality ✅ Passed PASS: The changed tests are plain table-driven unit tests; no Ginkgo blocks, Eventually/Consistently waits, or resource lifecycle/cleanup issues were introduced.
Topology-Aware Scheduling Compatibility ✅ Passed Touched files only thread RHEL stream into image-resolution and hashing; no new anti-affinity, topology spread, nodeSelectors, PDBs, or replica logic were added.
Ipv6 And Disconnected Network Test Compatibility ✅ Passed No new Ginkgo e2e tests were added; the changed tests are standard TestX unit tests and don’t introduce public-network assumptions.
No-Weak-Crypto ✅ Passed No MD5/SHA1/DES/RC4/3DES/Blowfish/ECB or custom crypto code was added; hashing uses stdlib FNV for rollout IDs, and no secret/token comparisons use non-constant-time helpers.
Container-Privileges ✅ Passed The PR only changes Go controller logic; no manifests were modified and the diff contains no privileged/security-context additions.
No-Sensitive-Data-In-Logs ✅ Passed No new logs print secrets/PII; changed log sites only emit generic status, request names, architecture, or AMI discovery errors.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes the primary change: threading streamName through nodepool platform callers.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@openshift-ci openshift-ci Bot added area/hypershift-operator Indicates the PR includes changes for the hypershift operator and API - outside an OCP release area/platform/aws PR/issue for AWS (AWSPlatform) platform area/platform/azure PR/issue for Azure (AzurePlatform) platform area/platform/gcp PR/issue for GCP (GCPPlatform) platform area/platform/kubevirt PR/issue for KubeVirt (KubevirtPlatform) platform area/platform/openstack PR/issue for OpenStack (OpenStackPlatform) platform area/platform/powervs PR/issue for PowerVS (PowerVSPlatform) platform and removed do-not-merge/needs-area labels Jun 25, 2026
@codecov

codecov Bot commented Jun 25, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 63.35079% with 70 lines in your changes missing coverage. Please review.
✅ Project coverage is 43.37%. Comparing base (73da66e) to head (55f1400).
⚠️ Report is 50 commits behind head on main.

Files with missing lines Patch % Lines
...rshift-operator/controllers/nodepool/conditions.go 0.00% 13 Missing ⚠️
...ypershift-operator/controllers/nodepool/powervs.go 21.42% 10 Missing and 1 partial ⚠️
...ershift-operator/controllers/nodepool/openstack.go 0.00% 10 Missing ⚠️
...operator/controllers/nodepool/kubevirt/kubevirt.go 36.36% 6 Missing and 1 partial ⚠️
...erator/controllers/nodepool/openstack/openstack.go 63.15% 5 Missing and 2 partials ⚠️
hypershift-operator/controllers/nodepool/config.go 72.72% 4 Missing and 2 partials ⚠️
...pershift-operator/controllers/nodepool/kubevirt.go 0.00% 6 Missing ⚠️
...erator/controllers/nodepool/nodepool_controller.go 70.58% 3 Missing and 2 partials ⚠️
hypershift-operator/controllers/nodepool/azure.go 62.50% 1 Missing and 2 partials ⚠️
hypershift-operator/controllers/nodepool/gcp.go 75.00% 1 Missing ⚠️
... and 1 more
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #8834      +/-   ##
==========================================
+ Coverage   43.19%   43.37%   +0.17%     
==========================================
  Files         767      772       +5     
  Lines       94914    95648     +734     
==========================================
+ Hits        41001    41487     +486     
- Misses      51050    51272     +222     
- Partials     2863     2889      +26     
Files with missing lines Coverage Δ
hypershift-operator/controllers/nodepool/aws.go 80.22% <100.00%> (+0.05%) ⬆️
...pershift-operator/controllers/nodepool/osstream.go 100.00% <100.00%> (ø)
hypershift-operator/controllers/nodepool/stream.go 100.00% <100.00%> (ø)
...ypershift-operator/controllers/nodepool/version.go 100.00% <100.00%> (+4.91%) ⬆️
support/releaseinfo/releaseinfo.go 52.15% <ø> (ø)
hypershift-operator/controllers/nodepool/gcp.go 66.21% <75.00%> (-0.30%) ⬇️
hypershift-operator/controllers/nodepool/token.go 82.70% <83.33%> (+0.10%) ⬆️
hypershift-operator/controllers/nodepool/azure.go 88.46% <62.50%> (+0.05%) ⬆️
...erator/controllers/nodepool/nodepool_controller.go 43.34% <70.58%> (+0.23%) ⬆️
hypershift-operator/controllers/nodepool/config.go 84.23% <72.72%> (-1.29%) ⬇️
... and 6 more

... and 20 files with indirect coverage changes

Flag Coverage Δ
cmd-support 36.87% <ø> (+0.44%) ⬆️
cpo-hostedcontrolplane 45.31% <ø> (-0.01%) ⬇️
cpo-other 45.10% <ø> (ø)
hypershift-operator 53.65% <63.35%> (+0.11%) ⬆️
other 31.68% <ø> (-0.01%) ⬇️

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

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

@coderabbitai coderabbitai Bot 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.

🧹 Nitpick comments (2)
hypershift-operator/controllers/nodepool/openstack/openstack_test.go (1)

293-293: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Consider adding a named-stream test case.

All updated call sites pass "", which routes through the legacy StreamMetadata fallback in StreamForName. The new OSStreams/named-stream branch (e.g. "rhel-9"/"rhel-10") — the actual purpose of this PR — isn't exercised here. A table entry that populates OSStreams and passes a concrete stream name would close that gap.

Also applies to: 358-358, 472-472

🤖 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 `@hypershift-operator/controllers/nodepool/openstack/openstack_test.go` at line
293, Add a table-driven named-stream test case for OpenstackDefaultImage so the
new OSStreams path is covered instead of only the legacy StreamMetadata
fallback. Update the relevant test cases in openstack_test.go to populate
OSStreams and pass a concrete stream name like “rhel-9” or “rhel-10” through
OpenstackDefaultImage / StreamForName, and keep the existing empty-string cases
as fallback coverage. Ensure the added case exercises the branch introduced by
this PR at the updated call sites.
hypershift-operator/controllers/nodepool/config.go (1)

98-121: 📐 Maintainability & Code Quality | 🔵 Trivial

Factor out the default-stream derivation.

config.go re-parses the release version and recomputes the default RHEL stream with GetRHELStream("", version, false), duplicating the same version-aware logic used by getRHELStream. A shared helper, or returning the default alongside the resolved stream, would keep hash normalization and stream selection aligned if usesRunc handling changes later.

🤖 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 `@hypershift-operator/controllers/nodepool/config.go` around lines 98 - 121,
The config hash normalization in config.go duplicates the version-based default
RHEL stream logic by re-parsing the release version and calling
GetRHELStream("", version, false) separately from getRHELStream. Refactor this
so the default stream is derived through a shared helper or returned together
with the resolved stream from getRHELStream, and update the normalization logic
in the same Config function to use that shared result so hash behavior stays
aligned if usesRunc handling changes.
🤖 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 `@hypershift-operator/controllers/nodepool/config.go`:
- Around line 98-121: The config hash normalization in config.go duplicates the
version-based default RHEL stream logic by re-parsing the release version and
calling GetRHELStream("", version, false) separately from getRHELStream.
Refactor this so the default stream is derived through a shared helper or
returned together with the resolved stream from getRHELStream, and update the
normalization logic in the same Config function to use that shared result so
hash behavior stays aligned if usesRunc handling changes.

In `@hypershift-operator/controllers/nodepool/openstack/openstack_test.go`:
- Line 293: Add a table-driven named-stream test case for OpenstackDefaultImage
so the new OSStreams path is covered instead of only the legacy StreamMetadata
fallback. Update the relevant test cases in openstack_test.go to populate
OSStreams and pass a concrete stream name like “rhel-9” or “rhel-10” through
OpenstackDefaultImage / StreamForName, and keep the existing empty-string cases
as fallback coverage. Ensure the added case exercises the branch introduced by
this PR at the updated call sites.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Central YAML (inherited)

Review profile: CHILL

Plan: Enterprise

Run ID: 28adccd3-0671-4206-ac2d-917bb3007eb9

📥 Commits

Reviewing files that changed from the base of the PR and between 4c582e0 and ee9c4de.

📒 Files selected for processing (27)
  • hypershift-operator/controllers/nodepool/aws.go
  • hypershift-operator/controllers/nodepool/aws_test.go
  • hypershift-operator/controllers/nodepool/azure.go
  • hypershift-operator/controllers/nodepool/azure_test.go
  • hypershift-operator/controllers/nodepool/capi_test.go
  • hypershift-operator/controllers/nodepool/conditions.go
  • hypershift-operator/controllers/nodepool/config.go
  • hypershift-operator/controllers/nodepool/config_test.go
  • hypershift-operator/controllers/nodepool/gcp.go
  • hypershift-operator/controllers/nodepool/gcp_test.go
  • hypershift-operator/controllers/nodepool/kubevirt.go
  • hypershift-operator/controllers/nodepool/kubevirt/kubevirt.go
  • hypershift-operator/controllers/nodepool/kubevirt/kubevirt_test.go
  • hypershift-operator/controllers/nodepool/nodepool_controller.go
  • hypershift-operator/controllers/nodepool/openstack.go
  • hypershift-operator/controllers/nodepool/openstack/openstack.go
  • hypershift-operator/controllers/nodepool/openstack/openstack_test.go
  • hypershift-operator/controllers/nodepool/osstream.go
  • hypershift-operator/controllers/nodepool/osstream_test.go
  • hypershift-operator/controllers/nodepool/powervs.go
  • hypershift-operator/controllers/nodepool/powervs_test.go
  • hypershift-operator/controllers/nodepool/stream.go
  • hypershift-operator/controllers/nodepool/stream_test.go
  • hypershift-operator/controllers/nodepool/token.go
  • hypershift-operator/controllers/nodepool/token_test.go
  • hypershift-operator/controllers/nodepool/version.go
  • hypershift-operator/controllers/nodepool/version_test.go

@sdminonne sdminonne changed the title feat(nodepool): thread streamName through all platform callers CNTRLPLANE-3553: feat(nodepool): thread streamName through all platform callers Jun 25, 2026
@openshift-ci-robot openshift-ci-robot added the jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. label Jun 25, 2026
@openshift-ci-robot

openshift-ci-robot commented Jun 25, 2026

Copy link
Copy Markdown

@sdminonne: This pull request references CNTRLPLANE-3553 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 "5.0.0" version, but no target version was set.

Details

In response to this:

Summary

  • Wire the resolved RHEL stream name (streamName) through Azure, PowerVS, OpenStack, and KubeVirt platform resolvers so each platform selects boot image metadata from the correct OS stream (rhel-9 or rhel-10) instead of always using the legacy default StreamMetadata.
  • CAPI paths use c.resolvedRHELStream from ConfigGenerator; condition-setter paths resolve via getRHELStream().
  • All functions that previously accessed releaseImage.StreamMetadata directly now go through releaseImage.StreamForName(streamName).

PR Dependency Graph

#8675 (merged) ─► #8719 (merged) ─► #8730 (open) ─► This PR
                                       │
#8669 (merged) ─► #8699 (merged) ─► #8709 (open) ──┘ (merge conflict resolution needed)
                                       │
                                   #8792 (open)
PR Title Status Relation
#8675 API: add OSImageStream field to NodePool merged grandparent
#8719 API: add GetRHELStream + stream constants merged parent
#8730 feat(nodepool): integrate osImageStream into NodePool controller open direct parent
#8709 feat(nodepool): use stream metadata for platform image resolution open sibling (merge conflict with #8730)
#8792 feat(nodepool): validate osImageStream in webhook open sibling
#8832 feat(nodepool): detect usesRunc from ContainerRuntimeConfig open (draft) sibling (PR A)
This PR feat(nodepool): thread streamName through all platform callers open (draft) PR B

Platforms Updated

Platform Functions changed
Azure defaultAzureNodePoolImage, getAzureMarketplaceMetadata
PowerVS getPowerVSImage, ibmPowerVSMachineTemplateSpec, setPowerVSconditions
OpenStack OpenstackDefaultImage, OpenStackReleaseImage, MachineTemplateSpec, ReconcileOpenStackImageSpec, PrefixedClusterImageName, setOpenStackConditions, reconcileOpenStackImageCR
KubeVirt defaultImage, GetImage, MachineTemplateSpec, setKubevirtConditions

Test plan

  • All existing nodepool package tests pass with "" (empty/default) stream name
  • Verify multi-stream resolution with OSStreams populated on ReleaseImage (integration)
  • Run e2e-aws-upgrade-hypershift-operator to validate no spurious rollouts

Ref: CNTRLPLANE-3553

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

  • Node pools can now detect and report the active OS image stream from running machines.

  • Image selection is now stream-aware across supported platforms, improving alignment with the chosen RHEL stream.

  • Bug Fixes

  • Improved validation so invalid or mismatched OS image stream settings fail fast with clearer errors.

  • Fixed default image and rollout handling to keep updates stable when the default stream is selected, while still triggering changes for non-default streams.

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 needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Jun 28, 2026
@hypershift-jira-solve-ci

Copy link
Copy Markdown

Now I have the full picture. Let me compile the final analysis.

Test Failure Analysis Complete

Job Information

  • Prow Job: tide (openshift-merge-bot)
  • Build ID: N/A — no Prow CI job was triggered
  • PR: #8834CNTRLPLANE-3553: feat(nodepool): thread streamName through all platform callers
  • Branch: CNTRLPLANE-3553-thread-streamName-all-platforms
  • Head SHA: ee9c4de4f29c7a0fd4453948f7895ffbc94aa153
  • Status: error — "Not mergeable. PR has a merge conflict."

Test Failure Analysis

Error

tide: Not mergeable. PR has a merge conflict.
GitHub mergeability: CONFLICTING (mergeStateStatus: DIRTY, rebaseable: false)
Labels: needs-rebase, do-not-merge/work-in-progress

Summary

No Prow CI jobs ran. The tide status is in error state because the PR branch has unresolvable merge conflicts with the main branch. The PR (created Jun 25) modifies 27 files across hypershift-operator/controllers/nodepool/, and at least two PRs merged to main after the branch point touch overlapping files: PR #8687 (CAPO/ORC dep bump, merged Jun 26 — modifies openstack.go, openstack/openstack.go, openstack/openstack_test.go) and PR #8821 (stale conversion data fix, merged Jun 25 — modifies nodepool_controller.go, capi_test.go). GitHub has applied the needs-rebase label and reports the PR as non-rebaseable. Additionally, the PR carries do-not-merge/work-in-progress and is marked as a draft, indicating the author has not finalized it. All 9 Prow presubmit e2e jobs (e2e-aws, e2e-aks, e2e-v2-aws, etc.) remain in pending state with "Waiting for pipeline condition to trigger this job" — they will not execute until the merge conflict is resolved.

Root Cause

The tide error state is caused by a git merge conflict between PR #8834's branch and the current main branch. This is not a test failure or infrastructure issue — it is a source control conflict.

Conflicting PRs merged to main after the branch point:

  1. PR OSASINFRA-4368, OCPBUGS-84114: Update CAPO to latest stable release #8687 (shiftstack/capo-bump — "chore(deps): Update CAPO, ORC to latest version") — merged Jun 26, modifies:

    • hypershift-operator/controllers/nodepool/openstack.go
    • hypershift-operator/controllers/nodepool/openstack/openstack.go
    • hypershift-operator/controllers/nodepool/openstack/openstack_test.go
  2. PR OCPBUGS-92013: fix NodePool stuck in UpdatingVersion/UpdatingConfig due to stale conversion-data annotation #8821 (csrwng/fix/ocpbugs-92013-stale-conversion-data) — merged Jun 25, modifies:

    • hypershift-operator/controllers/nodepool/nodepool_controller.go
    • hypershift-operator/controllers/nodepool/capi_test.go

PR #8834 touches all of these files as part of threading streamName through all platform callers. The overlapping modifications in openstack.go, openstack/openstack.go, nodepool_controller.go, and capi_test.go produce merge conflicts that GitHub cannot auto-resolve.

Additional blocking factors:

  • The do-not-merge/work-in-progress label is present (applied because the PR is a draft)
  • The needs-rebase label was automatically applied by the merge bot
  • The PR is in draft state, signaling the author hasn't finalized it

Because of the merge conflict, tide cannot merge the PR and all Prow presubmit jobs remain gated in pending — they never executed.

Recommendations
  1. Rebase the branch onto current main — resolve conflicts in openstack.go, openstack/openstack.go, openstack/openstack_test.go (from the CAPO/ORC bump in OSASINFRA-4368, OCPBUGS-84114: Update CAPO to latest stable release #8687) and nodepool_controller.go, capi_test.go (from the stale-conversion-data fix in OCPBUGS-92013: fix NodePool stuck in UpdatingVersion/UpdatingConfig due to stale conversion-data annotation #8821). Thread streamName through the updated OpenStack and nodepool controller code.

  2. Mark PR as ready for review — once the rebase is complete and conflicts resolved, un-draft the PR to remove the do-not-merge/work-in-progress label. The needs-rebase label will be automatically removed once the branch is conflict-free.

  3. No action needed on CI — the 9 pending Prow presubmit jobs (e2e-aws, e2e-aks, e2e-v2-aws, e2e-v2-gke, e2e-azure-v2-self-managed, e2e-kubevirt-aws-ovn-reduced, e2e-aws-upgrade-hypershift-operator, e2e-aws-4-22, e2e-aks-4-22) will be automatically triggered once the rebase is pushed and GitHub reports the branch as mergeable.

Evidence
Evidence Detail
Tide status error — "Not mergeable. PR has a merge conflict." (updated 2026-06-28T09:54:52Z)
GitHub mergeability mergeable: false, mergeable_state: dirty, rebaseable: false
Labels needs-rebase, do-not-merge/work-in-progress
PR state Draft (isDraft: true)
Conflicting PR #8687 Merged Jun 26 — updates CAPO/ORC deps, modifies openstack.go, openstack/openstack.go, openstack/openstack_test.go
Conflicting PR #8821 Merged Jun 25 — fixes stale conversion data, modifies nodepool_controller.go, capi_test.go
Prow presubmit jobs All 9 jobs in pending state — "Waiting for pipeline condition to trigger this job"
PR #8834 scope 27 files in hypershift-operator/controllers/nodepool/ — threads streamName through AWS, Azure, GCP, OpenStack, PowerVS, KubeVirt platform callers
GitHub Actions CI All passing (lint, verify, unit tests, codespell, gitlint) — GitHub Actions run independently of tide merge status

sdminonne and others added 3 commits July 2, 2026 11:34
Wire spec.osImageStream into the NodePool reconciliation loop:
validation, config hash, boot image resolution, token secret
propagation, and observation-based status reporting.

Behavior matches the dual-stream RHEL NodePool enhancement:
https://github.com/openshift/enhancements/blob/master/enhancements/hypershift/dual-stream-rhel-nodepool.md

Stream resolution (osstream.go, stream.go):
- getRHELStreamForBootImage delegates to GetRHELStream for
  version-aware default resolution: rhel-9 for OCP < 5.0, rhel-10
  for OCP >= 5.0 when spec.osImageStream is unset. On upgrade to
  OCP 5.0+, existing NodePools with unset spec.osImageStream will
  implicitly transition to rhel-10 boot images as intended by the
  enhancement.
- GetRHELStream always returns a concrete stream name ("rhel-9" or
  "rhel-10") and is used for validation and default resolution.
- validateOSImageStream delegates to GetRHELStream; runs before
  NewConfigGenerator in validMachineConfigCondition for fail-fast.

Config hash (config.go):
- Add rhelStream to rolloutConfig and Hash()/HashWithoutVersion().
  Normalized so that setting the version-derived default (e.g. "rhel-9"
  on 4.x) keeps rhelStream empty — no spurious rollout.
- resolvedRHELStreamForBootImage lives on ConfigGenerator outside
  rolloutConfig since it does not participate in the hash.

Boot image resolution (aws.go, gcp.go):
- AWS and GCP machine template paths use resolvedRHELStreamForBootImage
  via StreamForName for consistent AMI/image lookup.
- setAWSConditions uses getRHELStreamForBootImage for consistency with
  the CAPI path.

Token secret (token.go):
- Write os-stream key with resolved stream for future ignition-server
  consumption (CNTRLPLANE-3553).

Status reporting (version.go):
- setOSImageStreamStatus infers the observed RHEL stream from Machine
  NodeInfo.OSImage (RHCOS 4xx → rhel-9, 5xx → rhel-10) using majority
  vote across pool machines.
- setNodesInfoStatus aggregates node version and health from CAPI
  Machines into status.nodesInfo.

Tests (osstream_test.go):
- Test_getRHELStreamForBootImage covers all combinations of
  osImageStream.Name × release version per the enhancement behavior
  table.
- TestGetRHELStreamForBootImage proves that on OCP 5.0+ multi-stream
  payloads, the resolved rhel-10 default produces the correct AMI
  and machine template hash, confirming the intended boot image
  transition.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…s rhel-10

The MCO cannot install rhel-10 OS images yet (the ExternalTopologyMode
guard in MCC bootstrap skips OSImageStream processing for HyperShift).
Hardcode resolvedRHELStreamForBootImage to StreamRHEL9 so that all
NodePools resolve rhel-9 boot AMIs regardless of release version.

Without this, NodePools on OCP 5.0+ payloads would boot a rhel-10 AMI
while the MCO installs rhel-9, and the HyperShift Operator upgrade test
would fail because the template hash changes from StreamForName("") to
StreamForName("rhel-10").

Once the MCO removes the ExternalTopologyMode guard (MCO PR openshift#5750),
getRHELStreamForBootImage should be wired back in for version-aware
stream resolution.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Wire the resolved RHEL stream name through Azure, PowerVS, OpenStack,
and KubeVirt platform resolvers so that each platform selects boot image
metadata from the correct OS stream (rhel-9 or rhel-10) instead of
always using the legacy default.

CAPI paths use c.resolvedRHELStream from ConfigGenerator. Condition
setter paths resolve the stream via getRHELStream(). All functions that
previously accessed releaseImage.StreamMetadata directly now go through
releaseImage.StreamForName(streamName).

Ref: CNTRLPLANE-3553

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@sdminonne sdminonne force-pushed the CNTRLPLANE-3553-thread-streamName-all-platforms branch from ee9c4de to 55f1400 Compare July 4, 2026 10:35
@openshift-ci openshift-ci Bot added area/api Indicates the PR includes changes for the API area/control-plane-operator Indicates the PR includes changes for the control plane operator - in an OCP release and removed needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. labels Jul 4, 2026
@openshift-ci

openshift-ci Bot commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: sdminonne
Once this PR has been reviewed and has the lgtm label, please assign enxebre 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

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

Labels

area/api Indicates the PR includes changes for the API area/control-plane-operator Indicates the PR includes changes for the control plane operator - in an OCP release area/hypershift-operator Indicates the PR includes changes for the hypershift operator and API - outside an OCP release area/platform/aws PR/issue for AWS (AWSPlatform) platform area/platform/azure PR/issue for Azure (AzurePlatform) platform area/platform/gcp PR/issue for GCP (GCPPlatform) platform area/platform/kubevirt PR/issue for KubeVirt (KubevirtPlatform) platform area/platform/openstack PR/issue for OpenStack (OpenStackPlatform) platform area/platform/powervs PR/issue for PowerVS (PowerVSPlatform) platform do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. 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.

2 participants