Skip to content

METAL-1731: baremetal: Add coreos.openshift.io/stream label to BMH and hostSelector#10502

Open
honza wants to merge 1 commit intoopenshift:mainfrom
honza:dual-stream
Open

METAL-1731: baremetal: Add coreos.openshift.io/stream label to BMH and hostSelector#10502
honza wants to merge 1 commit intoopenshift:mainfrom
honza:dual-stream

Conversation

@honza
Copy link
Copy Markdown
Member

@honza honza commented Apr 14, 2026

Set the coreos.openshift.io/stream label on all generated BareMetalHost objects (control-plane, worker, and arbiter) based on the install-config's OSImageStream setting, defaulting to rhel-9. Configure HostSelector on BareMetalMachineProviderSpec so MachineSets only claim BMHs with the matching stream label.

How it works

The coreos.openshift.io/stream label on a BareMetalHost determines
which kernel, initrd, and rootfs files are used during PXE boot. For
example, a BMH labeled coreos.openshift.io/stream: rhel-10 will PXE
boot with ironic-python-agent-rhel-10.kernel,
ironic-python-agent-rhel-10.initramfs, and
ironic-python-agent-rhel-10.rootfs instead of the unqualified defaults.

The per-node coreos.live.rootfs_url kernel parameter set via ICC's
ExtraKernelParams overrides the global one from ironic-image because
dracut's getarg returns the last value for duplicate parameters.

Changes across repos

installer (openshift/installer#10502)
pkg/asset/machines/baremetal/: Sets the coreos.openshift.io/stream
label on all generated BareMetalHost objects (control-plane, worker,
arbiter) based on the install-config's OSImageStream setting, defaulting
to rhel-9. Configures hostSelector.matchLabels on
BareMetalMachineProviderSpec so MachineSets only claim BMHs with the
matching stream label.

cluster-baremetal-operator (openshift/cluster-baremetal-operator#590)
provisioning/image_customization.go: Passes three new environment
variables to the ICC container: DEPLOY_KERNEL (path to the kernel file),
IMAGE_SHARED_DIR (path to the shared images directory where
stream-prefixed files are discovered), and IRONIC_ROOTFS_URL (base URL
for the rootfs served by httpd). These enable ICC to discover multi-stream
images and construct per-node kernel/rootfs URLs.

machine-os-images (openshift/machine-os-images#83)
scripts/copy-metal: Creates stream-prefixed IPA symlinks (e.g.
ironic-python-agent-rhel-9.iso, ironic-python-agent-rhel-10.kernel)
for all available CoreOS versions, allowing ICC to discover images by
stream. Also fixes missing initramfs symlinks in the fixed=true (PXE)
block — without these, a stream-specific kernel would be paired with the
default-stream initrd, causing a version mismatch that crashes immediately
on PXE boot.

image-customization-controller (openshift/image-customization-controller#175)
pkg/imagehandler/, pkg/imageprovider/rhcos.go: Adds OS stream
selection so ICC can serve different CoreOS base images based on the
coreos.openshift.io/stream label. Images are indexed by (stream,
architecture) and discovered from stream-prefixed filenames. Key changes:

  • streamArchSpecificURL() transforms the base rootfs URL into a stream-
    and arch-specific URL
  • BuildImage() passes the stream to ServeKernel() and uses the
    stream-specific rootfs URL in ExtraKernelParams
  • imageKey() includes the stream in the cache key so that changing a
    BMH's stream label invalidates the cached image

Summary by CodeRabbit

  • Refactor
    • Improved OS image stream configuration handling for bare metal hosts, ensuring consistent stream selection and label application across control-plane, worker, and arbiter host types. OS image stream is now properly propagated throughout host creation and machine provider specifications.

Set the coreos.openshift.io/stream label on all generated BareMetalHost
objects (control-plane, worker, and arbiter) based on the install-config's
OSImageStream setting, defaulting to rhel-9. Configure HostSelector on
BareMetalMachineProviderSpec so MachineSets only claim BMHs with the
matching stream label.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@openshift-ci openshift-ci bot requested review from dtantsur and iurygregory April 14, 2026 17:34
@openshift-ci
Copy link
Copy Markdown
Contributor

openshift-ci bot commented Apr 14, 2026

[APPROVALNOTIFIER] This PR is NOT APPROVED

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

@honza honza changed the title baremetal: Add coreos.openshift.io/stream label to BMH and hostSelector METAL-1731: baremetal: Add coreos.openshift.io/stream label to BMH and hostSelector Apr 14, 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 Apr 14, 2026
@openshift-ci-robot
Copy link
Copy Markdown
Contributor

openshift-ci-robot commented Apr 14, 2026

@honza: This pull request references METAL-1731 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:

Set the coreos.openshift.io/stream label on all generated BareMetalHost objects (control-plane, worker, and arbiter) based on the install-config's OSImageStream setting, defaulting to rhel-9. Configure HostSelector on BareMetalMachineProviderSpec so MachineSets only claim BMHs with the matching stream label.

How it works

The coreos.openshift.io/stream label on a BareMetalHost determines
which kernel, initrd, and rootfs files are used during PXE boot. For
example, a BMH labeled coreos.openshift.io/stream: rhel-10 will PXE
boot with ironic-python-agent-rhel-10.kernel,
ironic-python-agent-rhel-10.initramfs, and
ironic-python-agent-rhel-10.rootfs instead of the unqualified defaults.

The per-node coreos.live.rootfs_url kernel parameter set via ICC's
ExtraKernelParams overrides the global one from ironic-image because
dracut's getarg returns the last value for duplicate parameters.

Changes across repos

installer (openshift/installer#10502)
pkg/asset/machines/baremetal/: Sets the coreos.openshift.io/stream
label on all generated BareMetalHost objects (control-plane, worker,
arbiter) based on the install-config's OSImageStream setting, defaulting
to rhel-9. Configures hostSelector.matchLabels on
BareMetalMachineProviderSpec so MachineSets only claim BMHs with the
matching stream label.

cluster-baremetal-operator (openshift/cluster-baremetal-operator#590)
provisioning/image_customization.go: Passes three new environment
variables to the ICC container: DEPLOY_KERNEL (path to the kernel file),
IMAGE_SHARED_DIR (path to the shared images directory where
stream-prefixed files are discovered), and IRONIC_ROOTFS_URL (base URL
for the rootfs served by httpd). These enable ICC to discover multi-stream
images and construct per-node kernel/rootfs URLs.

machine-os-images (openshift/machine-os-images#83)
scripts/copy-metal: Creates stream-prefixed IPA symlinks (e.g.
ironic-python-agent-rhel-9.iso, ironic-python-agent-rhel-10.kernel)
for all available CoreOS versions, allowing ICC to discover images by
stream. Also fixes missing initramfs symlinks in the fixed=true (PXE)
block — without these, a stream-specific kernel would be paired with the
default-stream initrd, causing a version mismatch that crashes immediately
on PXE boot.

image-customization-controller (openshift/image-customization-controller#175)
pkg/imagehandler/, pkg/imageprovider/rhcos.go: Adds OS stream
selection so ICC can serve different CoreOS base images based on the
coreos.openshift.io/stream label. Images are indexed by (stream,
architecture) and discovered from stream-prefixed filenames. Key changes:

  • streamArchSpecificURL() transforms the base rootfs URL into a stream-
    and arch-specific URL
  • BuildImage() passes the stream to ServeKernel() and uses the
    stream-specific rootfs URL in ExtraKernelParams
  • imageKey() includes the stream in the cache key so that changing a
    BMH's stream label invalidates the cached image

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.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 14, 2026

Walkthrough

OS image stream labeling is introduced throughout the baremetal provisioning pipeline. A helper function selects the configured OS image stream, and this value is attached as labels to BareMetalHost objects and used in HostSelector label matching for machines.

Changes

Cohort / File(s) Summary
Host Configuration
pkg/asset/machines/baremetal/hosts.go, pkg/asset/machines/baremetal/hosts_test.go
Added streamLabelValue helper that resolves to configured OS image stream or default. Control-plane, worker, and arbiter hosts now include coreos.openshift.io/stream label. Test expectations updated across all scenarios (default, network-config, role sets, architecture variants) to include the new stream label.
Machine Provider Configuration
pkg/asset/machines/baremetal/machines.go, pkg/asset/machines/baremetal/machinesets.go
provider helper now accepts osImageStream parameter, computes stream value, and populates BareMetalMachineProviderSpec.HostSelector.MatchLabels with coreos.openshift.io/stream to match labeled hosts. Updated invocation in machinesets.go to pass config.OSImageStream argument.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

🚥 Pre-merge checks | ✅ 8 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 71.43% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Microshift Test Compatibility ❓ Inconclusive Unable to execute shell commands to analyze the PR's modified test files and identify Ginkgo e2e tests. Please provide the PR diff output or the content of modified test files to assess whether new Ginkgo e2e tests were added and if they use MicroShift-incompatible APIs.
✅ Passed checks (8 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly and accurately describes the main change: adding the coreos.openshift.io/stream label to BareMetalHost objects and configuring hostSelector matching based on this label, which is the core objective of the PR.
Stable And Deterministic Test Names ✅ Passed The custom check for stable and deterministic Ginkgo test names is not applicable to this pull request. The modified test file uses the standard Go testing framework with table-driven tests, not Ginkgo. All test scenario names are static strings without dynamic information.
Test Structure And Quality ✅ Passed The PR modifies hosts_test.go using standard Go testing with testify assertions, not Ginkgo tests, so the Ginkgo quality check is not applicable.
Single Node Openshift (Sno) Test Compatibility ✅ Passed PR modifies only standard Go unit tests in testing package, not Ginkgo e2e tests. SNO Test Compatibility check applies only to Ginkgo tests.
Topology-Aware Scheduling Compatibility ✅ Passed Changes add coreos.openshift.io/stream labels to BareMetalHost objects and configure host selector match labels without introducing pod-level scheduling constraints across any OpenShift topology.
Ote Binary Stdout Contract ✅ Passed PR changes affect asset generation code in pkg/asset/machines/baremetal/ that generates Kubernetes manifests for bare metal clusters. No process-level code writes to stdout.
Ipv6 And Disconnected Network Test Compatibility ✅ Passed No new Ginkgo e2e tests found in this PR; changes are standard Go unit tests in asset generation code.

✏️ 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.11.4)

Error: can't load config: unsupported version of the configuration: "" See https://golangci-lint.run/docs/product/migration-guide for migration instructions
The command is terminated due to an error: can't load config: unsupported version of the configuration: "" See https://golangci-lint.run/docs/product/migration-guide for migration instructions


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

@openshift-ci-robot
Copy link
Copy Markdown
Contributor

openshift-ci-robot commented Apr 14, 2026

@honza: This pull request references METAL-1731 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:

Set the coreos.openshift.io/stream label on all generated BareMetalHost objects (control-plane, worker, and arbiter) based on the install-config's OSImageStream setting, defaulting to rhel-9. Configure HostSelector on BareMetalMachineProviderSpec so MachineSets only claim BMHs with the matching stream label.

How it works

The coreos.openshift.io/stream label on a BareMetalHost determines
which kernel, initrd, and rootfs files are used during PXE boot. For
example, a BMH labeled coreos.openshift.io/stream: rhel-10 will PXE
boot with ironic-python-agent-rhel-10.kernel,
ironic-python-agent-rhel-10.initramfs, and
ironic-python-agent-rhel-10.rootfs instead of the unqualified defaults.

The per-node coreos.live.rootfs_url kernel parameter set via ICC's
ExtraKernelParams overrides the global one from ironic-image because
dracut's getarg returns the last value for duplicate parameters.

Changes across repos

installer (openshift/installer#10502)
pkg/asset/machines/baremetal/: Sets the coreos.openshift.io/stream
label on all generated BareMetalHost objects (control-plane, worker,
arbiter) based on the install-config's OSImageStream setting, defaulting
to rhel-9. Configures hostSelector.matchLabels on
BareMetalMachineProviderSpec so MachineSets only claim BMHs with the
matching stream label.

cluster-baremetal-operator (openshift/cluster-baremetal-operator#590)
provisioning/image_customization.go: Passes three new environment
variables to the ICC container: DEPLOY_KERNEL (path to the kernel file),
IMAGE_SHARED_DIR (path to the shared images directory where
stream-prefixed files are discovered), and IRONIC_ROOTFS_URL (base URL
for the rootfs served by httpd). These enable ICC to discover multi-stream
images and construct per-node kernel/rootfs URLs.

machine-os-images (openshift/machine-os-images#83)
scripts/copy-metal: Creates stream-prefixed IPA symlinks (e.g.
ironic-python-agent-rhel-9.iso, ironic-python-agent-rhel-10.kernel)
for all available CoreOS versions, allowing ICC to discover images by
stream. Also fixes missing initramfs symlinks in the fixed=true (PXE)
block — without these, a stream-specific kernel would be paired with the
default-stream initrd, causing a version mismatch that crashes immediately
on PXE boot.

image-customization-controller (openshift/image-customization-controller#175)
pkg/imagehandler/, pkg/imageprovider/rhcos.go: Adds OS stream
selection so ICC can serve different CoreOS base images based on the
coreos.openshift.io/stream label. Images are indexed by (stream,
architecture) and discovered from stream-prefixed filenames. Key changes:

  • streamArchSpecificURL() transforms the base rootfs URL into a stream-
    and arch-specific URL
  • BuildImage() passes the stream to ServeKernel() and uses the
    stream-specific rootfs URL in ExtraKernelParams
  • imageKey() includes the stream in the cache key so that changing a
    BMH's stream label invalidates the cached image

Summary by CodeRabbit

  • Refactor
  • Improved OS image stream configuration handling for bare metal hosts, ensuring consistent stream selection and label application across control-plane, worker, and arbiter host types. OS image stream is now properly propagated throughout host creation and machine provider specifications.

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.

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.

🧹 Nitpick comments (2)
pkg/asset/machines/baremetal/machines.go (1)

82-84: Use the shared stream label constant to avoid key drift.

Functionally correct, but this literal duplicates streamLabelKey defined in pkg/asset/machines/baremetal/hosts.go. Reusing the constant keeps selector/label contracts safer over time.

♻️ Proposed refactor
 		HostSelector: baremetalprovider.HostSelector{
 			MatchLabels: map[string]string{
-				"coreos.openshift.io/stream": stream,
+				streamLabelKey: stream,
 			},
 		},
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/asset/machines/baremetal/machines.go` around lines 82 - 84, Replace the
literal label key "coreos.openshift.io/stream" in the MatchLabels map with the
shared constant streamLabelKey (defined in
pkg/asset/machines/baremetal/hosts.go) to avoid key drift; update the
MatchLabels entry in machines.go to use streamLabelKey so both selector and
label use the same canonical constant.
pkg/asset/machines/baremetal/hosts_test.go (1)

32-790: Add one explicit non-default stream test case (rhel-10).

Current updates validate the default path well, but there’s no direct assertion that config.OSImageStream override propagates to host labels. A dedicated rhel-10 scenario would lock down the new feature behavior.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/asset/machines/baremetal/hosts_test.go` around lines 32 - 790, Add a
focused test case that verifies an OS image stream override (rhel-10) is
propagated to host labels: create a new scenario (e.g. "stream-rhel-10") in the
test table that uses machines(machine("machine-0")) and a Config built with the
OS image stream override (set Config.OSImageStream or use
config().withOSImageStream("rhel-10") / configHosts helper if available) and a
hostType("master-0").bmc(...).role("master"), then assert ExpectedSetting hosts
include label "coreos.openshift.io/stream" with value "rhel-10" (and
corresponding secret/userData/consumerRef as in other control-plane tests) so
the override is explicitly covered by host label assertions.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@pkg/asset/machines/baremetal/hosts_test.go`:
- Around line 32-790: Add a focused test case that verifies an OS image stream
override (rhel-10) is propagated to host labels: create a new scenario (e.g.
"stream-rhel-10") in the test table that uses machines(machine("machine-0")) and
a Config built with the OS image stream override (set Config.OSImageStream or
use config().withOSImageStream("rhel-10") / configHosts helper if available) and
a hostType("master-0").bmc(...).role("master"), then assert ExpectedSetting
hosts include label "coreos.openshift.io/stream" with value "rhel-10" (and
corresponding secret/userData/consumerRef as in other control-plane tests) so
the override is explicitly covered by host label assertions.

In `@pkg/asset/machines/baremetal/machines.go`:
- Around line 82-84: Replace the literal label key "coreos.openshift.io/stream"
in the MatchLabels map with the shared constant streamLabelKey (defined in
pkg/asset/machines/baremetal/hosts.go) to avoid key drift; update the
MatchLabels entry in machines.go to use streamLabelKey so both selector and
label use the same canonical constant.

ℹ️ Review info
⚙️ Run configuration

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

Review profile: CHILL

Plan: Pro Plus

Run ID: 74800e99-5d37-4905-8d0a-17a5d54b31e4

📥 Commits

Reviewing files that changed from the base of the PR and between 075b809 and 8a0406e.

📒 Files selected for processing (4)
  • pkg/asset/machines/baremetal/hosts.go
  • pkg/asset/machines/baremetal/hosts_test.go
  • pkg/asset/machines/baremetal/machines.go
  • pkg/asset/machines/baremetal/machinesets.go

@openshift-ci
Copy link
Copy Markdown
Contributor

openshift-ci bot commented Apr 14, 2026

@honza: 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-metal-ipi-ovn-dualstack 8a0406e link false /test e2e-metal-ipi-ovn-dualstack
ci/prow/e2e-metal-assisted 8a0406e link false /test e2e-metal-assisted
ci/prow/e2e-metal-ipi-ovn-virtualmedia 8a0406e link false /test e2e-metal-ipi-ovn-virtualmedia
ci/prow/e2e-aws-ovn 8a0406e link true /test e2e-aws-ovn
ci/prow/e2e-metal-ovn-two-node-fencing 8a0406e link false /test e2e-metal-ovn-two-node-fencing
ci/prow/e2e-metal-ipi-ovn-swapped-hosts 8a0406e link false /test e2e-metal-ipi-ovn-swapped-hosts
ci/prow/okd-scos-images 8a0406e link true /test okd-scos-images
ci/prow/e2e-metal-ipi-ovn-ipv6 8a0406e link true /test e2e-metal-ipi-ovn-ipv6
ci/prow/e2e-metal-ipi-ovn 8a0406e link false /test e2e-metal-ipi-ovn
ci/prow/e2e-metal-ovn-two-node-arbiter 8a0406e link false /test e2e-metal-ovn-two-node-arbiter

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

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