Skip to content

CNTRLPLANE-3553: Wire usesRunc detection into RHEL stream resolution#8832

Merged
openshift-merge-bot[bot] merged 1 commit into
openshift:mainfrom
sdminonne:CNTRLPLANE-3553-usesRunc-detection
Jul 14, 2026
Merged

CNTRLPLANE-3553: Wire usesRunc detection into RHEL stream resolution#8832
openshift-merge-bot[bot] merged 1 commit into
openshift:mainfrom
sdminonne:CNTRLPLANE-3553-usesRunc-detection

Conversation

@sdminonne

@sdminonne sdminonne commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Thread 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
  • Add usesRuncRuntime() to scan NodePool spec.config ConfigMaps for ContainerRuntimeConfig with defaultRuntime: runc
  • Wire runc detection into getRHELStreamForBootImage(), validateOSImageStream(), and the config hash normalization in NewConfigGenerator()
  • When runc is detected: implicit stream on OCP >= 5.0 falls back to rhel-9; explicit rhel-10 + runc returns a validation error via ValidMachineConfig condition

Dependencies

#8675 (CNTRLPLANE-3022: Add osImageStream to NodePool spec/status) ✅ Merged
  └── #8719 (CNTRLPLANE-3023: CEL rule to prevent osImageStream removal) ✅ Merged
        └── #8730 (CNTRLPLANE-3553: Wire osImageStream into NodePool controller) 🔄 Open
              └── This PR (CNTRLPLANE-3553: Wire usesRunc detection) 🔄 Open
                    └── #8792 (CNTRLPLANE-3030: ignition-server os-stream consumption) 🔄 Open

Parallel dependency (no ordering constraint with this PR):

#8669 (CNTRLPLANE-3552: Multi-stream CoreOS metadata parsing) ✅ Merged
  └── #8699 (CNTRLPLANE-3026: Decouple AWS AMI resolution) ✅ Merged
        └── #8709 (CNTRLPLANE-3027: Decouple all platform boot image resolvers) 🔄 Open

Test plan

  • TestUsesRuncRuntime — 7 cases: no configs, runc, crun, empty runtime, MachineConfig, missing ConfigMap, multiple configs
  • TestGetRHELStreamForBootImage — 15 cases including 4 runc-aware: runc+5.0→rhel-9, runc+rhel-10→error, runc+4.x→rhel-9, missing ConfigMap
  • TestGetRHELStream (stream_test.go) — 20 cases including 9 runc-aware covering implicit/explicit stream × 4.x/5.0/5.1 × runc combinations
  • TestValidateOSImageStream — 7 cases including 2 runc-aware: rhel-10+runc→error, rhel-9+runc→ok
  • TestNewConfigGenerator — 2 additional cases exercising the runc ConfigMap path for config hash normalization on OCP 5.0
  • Platform-specific named stream test cases for Azure, KubeVirt, OpenStack, and PowerVS
  • make verify after rebase onto merged CNTRLPLANE-3553: Wire osImageStream into NodePool controller (hash, token, status, validation) #8730

JIRA: CNTRLPLANE-3553

🤖 Generated with Claude Code

@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-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

  • Add usesRuncRuntime() to scan NodePool spec.config ConfigMaps for ContainerRuntimeConfig with defaultRuntime: runc
  • Wire actual runc detection into getRHELStream(), validateOSImageStream(), and the config hash normalization in NewConfigGenerator()
  • When runc is detected: implicit stream on OCP >= 5.0 falls back to rhel-9; explicit rhel-10 + runc returns a validation error via ValidMachineConfig condition
  • Removes all TODO([CNTRLPLANE-3553](https://redhat.atlassian.net/browse/CNTRLPLANE-3553)): pass actual usesRunc placeholders

Dependencies

#8675 ([CNTRLPLANE-3022](https://redhat.atlassian.net/browse/CNTRLPLANE-3022): Add osImageStream to NodePool spec/status) ✅ Merged
 └── #8719 ([CNTRLPLANE-3023](https://redhat.atlassian.net/browse/CNTRLPLANE-3023): CEL rule to prevent osImageStream removal) ✅ Merged
       └── #8730 ([CNTRLPLANE-3553](https://redhat.atlassian.net/browse/CNTRLPLANE-3553): Wire osImageStream into NodePool controller) 🔄 Open
             └── This PR ([CNTRLPLANE-3553](https://redhat.atlassian.net/browse/CNTRLPLANE-3553): Wire usesRunc detection) 🔄 Open
                   └── #8792 ([CNTRLPLANE-3030](https://redhat.atlassian.net/browse/CNTRLPLANE-3030): ignition-server os-stream consumption) 🔄 Open

Parallel dependency (no ordering constraint with this PR):

#8669 ([CNTRLPLANE-3552](https://redhat.atlassian.net/browse/CNTRLPLANE-3552): Multi-stream CoreOS metadata parsing) ✅ Merged
 └── #8699 ([CNTRLPLANE-3026](https://redhat.atlassian.net/browse/CNTRLPLANE-3026): Decouple AWS AMI resolution) ✅ Merged
       └── #8709 ([CNTRLPLANE-3027](https://redhat.atlassian.net/browse/CNTRLPLANE-3027): Decouple all platform boot image resolvers) 🔄 Open

Test plan

  • TestUsesRuncRuntime — 7 cases: no configs, runc, crun, empty runtime, MachineConfig, missing ConfigMap, multiple configs
  • Test_getRHELStream — extended with 5 runc-aware cases: runc+5.0→rhel-9, runc+rhel-10→error, crun+5.0→rhel-10, runc+4.x→rhel-9, missing config
  • TestValidateOSImageStream — extended with 2 runc-aware cases: rhel-10+runc→error, rhel-9+runc→ok
  • make verify after rebase onto merged CNTRLPLANE-3553: Wire osImageStream into NodePool controller (hash, token, status, validation) #8730

JIRA: CNTRLPLANE-3553

🤖 Generated with Claude Code

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 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

NodePool reconciliation now infers status.osImageStream from machine OS images, validates requested OS image streams before machine config generation, and resolves RHEL stream values through shared helpers. The resolved stream is stored on ConfigGenerator, included in hash inputs, and passed into AWS and GCP image selection as well as token secret and Karpenter AMI label generation. GetRHELStream now defaults older releases with no explicit stream to StreamRHEL9, and tests were updated for the new stream resolution, validation, status, and hashing behavior.

Sequence Diagram(s)

Status and validation

sequenceDiagram
  participant "NodePoolReconciler.reconcile" as Reconcile
  participant "setOSImageStreamStatus" as SetOSImageStreamStatus
  participant "osImageStreamFromMachines" as OsImageStreamFromMachines
  participant "validMachineConfigCondition" as ValidMachineConfigCondition
  participant "validateOSImageStream" as ValidateOSImageStream
  participant "GetRHELStream" as GetRHELStream

  Reconcile->>SetOSImageStreamStatus: infer status.osImageStream
  SetOSImageStreamStatus->>OsImageStreamFromMachines: inspect Machine NodeInfo.OSImage
  OsImageStreamFromMachines-->>SetOSImageStreamStatus: majority stream or empty
  Reconcile->>ValidMachineConfigCondition: validate requested OS image stream
  ValidMachineConfigCondition->>ValidateOSImageStream: check spec.osImageStream.name
  ValidateOSImageStream->>GetRHELStream: resolve stream from release image and runtime
  GetRHELStream-->>ValidateOSImageStream: stream or error
  ValidateOSImageStream-->>ValidMachineConfigCondition: validation result
Loading

AWS and GCP image resolution

sequenceDiagram
  participant "awsMachineTemplate" as AwsMachineTemplate
  participant "awsMachineTemplateSpec" as AwsMachineTemplateSpec
  participant "resolveAWSAMI" as ResolveAWSAMI
  participant "defaultNodePoolAMI" as DefaultNodePoolAMI
  participant "gcpMachineTemplate" as GcpMachineTemplate
  participant "gcpMachineTemplateSpec" as GcpMachineTemplateSpec
  participant "resolveGCPImage" as ResolveGCPImage
  participant "defaultNodePoolGCPImage" as DefaultNodePoolGCPImage

  AwsMachineTemplate->>AwsMachineTemplateSpec: pass c.resolvedRHELStream
  AwsMachineTemplateSpec->>ResolveAWSAMI: resolve AMI
  ResolveAWSAMI->>DefaultNodePoolAMI: default Linux/RHCOS AMI

  GcpMachineTemplate->>GcpMachineTemplateSpec: pass c.resolvedRHELStream
  GcpMachineTemplateSpec->>ResolveGCPImage: resolve image
  ResolveGCPImage->>DefaultNodePoolGCPImage: default GCP image
Loading

Token secret and AMI labels

sequenceDiagram
  participant "token secret reconciliation" as TokenSecretReconciliation
  participant "tokenSecret" as TokenSecret
  participant "setKarpenterAMILabels" as SetKarpenterAMILabels
  participant "defaultNodePoolAMI" as DefaultNodePoolAMI

  TokenSecretReconciliation->>TokenSecret: store TokenSecretOSStreamKey
  TokenSecretReconciliation->>SetKarpenterAMILabels: pass t.resolvedRHELStream
  SetKarpenterAMILabels->>DefaultNodePoolAMI: resolve AMI labels
Loading

Possibly related PRs

  • openshift/hypershift#8699: Also changes AWS AMI resolution to carry stream metadata through defaultNodePoolAMI and resolveAWSAMI.

Suggested reviewers

  • devguyio
  • muraee
🚥 Pre-merge checks | ✅ 11
✅ Passed checks (11 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: wiring usesRunc detection into RHEL stream resolution.
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 Touched test titles are static string literals; no generated names, timestamps, UUIDs, or runtime-derived values appear in any modified test title.
Test Structure And Quality ✅ Passed PASS: The PR only updates table-driven unit tests; no Ginkgo specs, cluster resources, or Eventually/BeforeEach patterns were added, so the checklist items don’t apply.
Topology-Aware Scheduling Compatibility ✅ Passed PR only changes RHEL-stream resolution/status/hash plumbing; no new affinity, topology-spread, nodeSelector, toleration, or replica scheduling logic appears in the PR files.
Ipv6 And Disconnected Network Test Compatibility ✅ Passed Not applicable: the PR adds only controller unit tests (testing/Gomega), not Ginkgo e2e tests, and I found no IPv4-only or external connectivity assumptions.
No-Weak-Crypto ✅ Passed Touched files add no MD5/SHA1/DES/RC4/3DES/Blowfish/ECB usage or secret/token comparisons; hashing still uses shared FNV helper.
Container-Privileges ✅ Passed PR files are controller Go changes only; no added privileged/hostPID/hostNetwork/hostIPC/SYS_ADMIN/allowPrivilegeEscalation settings were found in them.
No-Sensitive-Data-In-Logs ✅ Passed New logs are generic status/error messages; no added logging prints tokens, passwords, PII, hostnames, or customer data.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ 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/gcp PR/issue for GCP (GCPPlatform) 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 55.26316% with 51 lines in your changes missing coverage. Please review.
✅ Project coverage is 43.81%. Comparing base (845ed6f) to head (ef295ce).
⚠️ Report is 15 commits behind head on main.

Files with missing lines Patch % Lines
...ypershift-operator/controllers/nodepool/powervs.go 23.07% 9 Missing and 1 partial ⚠️
...ershift-operator/controllers/nodepool/openstack.go 0.00% 9 Missing ⚠️
...pershift-operator/controllers/nodepool/osstream.go 79.54% 6 Missing and 3 partials ⚠️
...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/azure.go 62.50% 1 Missing and 2 partials ⚠️
hypershift-operator/controllers/nodepool/config.go 57.14% 2 Missing and 1 partial ⚠️
...pershift-operator/controllers/nodepool/kubevirt.go 0.00% 2 Missing ⚠️
...rshift-operator/controllers/nodepool/conditions.go 0.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #8832      +/-   ##
==========================================
+ Coverage   43.79%   43.81%   +0.01%     
==========================================
  Files         772      772              
  Lines       96037    96105      +68     
==========================================
+ Hits        42061    42106      +45     
- Misses      51061    51075      +14     
- Partials     2915     2924       +9     
Files with missing lines Coverage Δ
...rshift-operator/controllers/nodepool/conditions.go 55.55% <0.00%> (ø)
...pershift-operator/controllers/nodepool/kubevirt.go 0.00% <0.00%> (ø)
hypershift-operator/controllers/nodepool/azure.go 88.46% <62.50%> (-0.06%) ⬇️
hypershift-operator/controllers/nodepool/config.go 83.33% <57.14%> (-0.90%) ⬇️
...operator/controllers/nodepool/kubevirt/kubevirt.go 69.01% <36.36%> (-0.45%) ⬇️
...erator/controllers/nodepool/openstack/openstack.go 73.07% <63.15%> (-3.91%) ⬇️
...ershift-operator/controllers/nodepool/openstack.go 0.00% <0.00%> (ø)
...pershift-operator/controllers/nodepool/osstream.go 82.69% <79.54%> (-17.31%) ⬇️
...ypershift-operator/controllers/nodepool/powervs.go 11.32% <23.07%> (+4.82%) ⬆️

... and 1 file with indirect coverage changes

Flag Coverage Δ
cmd-support 37.43% <ø> (ø)
cpo-hostedcontrolplane 45.91% <ø> (ø)
cpo-other 45.11% <ø> (ø)
hypershift-operator 54.09% <55.26%> (+0.02%) ⬆️
other 32.12% <ø> (+0.03%) ⬆️

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.

Actionable comments posted: 2

🧹 Nitpick comments (4)
hypershift-operator/controllers/nodepool/aws_test.go (1)

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

Cover the non-empty stream path in the AWS tests.

These call sites still only exercise rhelStream == "". Since the production change is about selecting AWS images from the resolved stream, add a case with OSStreams["rhel-10"] and a non-empty stream argument so awsMachineTemplateSpec/resolveAWSAMI prove they read named-stream metadata instead of the legacy default path.

As per coding guidelines, **/*_test.go: Unit test code changes and additions; include e2e tests when changes impact consumer behaviour.

Also applies to: 1344-1344

🤖 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/aws_test.go` at line 301, The AWS
test coverage still only exercises the empty rhelStream path, so add a non-empty
stream case using OSStreams["rhel-10"] to verify the AWS image selection logic.
Update the relevant test call sites around awsMachineTemplateSpec and
resolveAWSAMI so they assert the resolved stream metadata is used instead of the
legacy default path, and keep the existing empty-stream case as a separate
baseline.

Source: Coding guidelines

hypershift-operator/controllers/nodepool/token_test.go (1)

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

Add a named-stream Karpenter label case.

This signature update still only tests the empty-stream path. Please add a case with per-stream AWS metadata and a non-empty rhelStream so setKarpenterAMILabels is pinned to resolvedRHELStream rather than the legacy default lookup.

As per coding guidelines, **/*_test.go: Unit test code changes and additions; include e2e tests when changes impact consumer behaviour.

🤖 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/token_test.go` at line 1184, The
test coverage for setKarpenterAMILabels only exercises the empty-stream path, so
add a new table-driven case in token_test.go with per-stream AWS metadata and a
non-empty rhelStream to verify the function uses resolvedRHELStream instead of
falling back to the legacy default lookup. Extend the existing
setKarpenterAMILabels call path in the test to pass the named stream scenario
and assert the expected Karpenter AMI label resolution for that case.

Source: Coding guidelines

hypershift-operator/controllers/nodepool/config.go (1)

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

Avoid shadowing err in the normalization block.

Line 109 creates a new err scoped to the if, which makes this already branchy path harder to scan and goes against the repo’s Go guidance. Reusing the outer err keeps the flow clearer.

As per coding guidelines, **/!(*.pb).go: Avoid variable shadowing.

Suggested cleanup
  if rhelStream != "" {
-		version, err := semver.Parse(releaseImage.Version())
+		var version semver.Version
+		version, err = semver.Parse(releaseImage.Version())
 		if err != nil {
 			return nil, fmt.Errorf("failed to parse release image version %q: %w", releaseImage.Version(), err)
 		}
🤖 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 107 - 116,
The normalization block in the NodePool config path is shadowing the outer err
variable by redeclaring it inside the rhelStream branch, which goes against the
Go guidance for avoiding shadowing. Update the logic in the config normalization
flow around rhelStream, semver.Parse, and usesRuncRuntime to reuse the existing
err variable instead of introducing a new scoped one, while preserving the same
error handling and return behavior.

Source: Coding guidelines

hypershift-operator/controllers/nodepool/config_test.go (1)

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

Add a usesRuncRuntime normalization case here.

These new cases only pin the release-version branch. NewConfigGenerator now also normalizes against usesRuncRuntime(...), so please add a 5.x case with a ContainerRuntimeConfig setting defaultRuntime: runc and assert that explicit rhel-9 hashes like the implicit default. That is the new branch this PR introduces.

As per coding guidelines, **/*_test.go: Unit test code changes and additions; include e2e tests when changes impact consumer behaviour.

🤖 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_test.go` around lines 250 -
305, The hash test table in config_test.go only covers release-version-based
normalization, but NewConfigGenerator also normalizes through
usesRuncRuntime(...). Add a 5.x test case that includes a ContainerRuntimeConfig
with defaultRuntime set to runc and verify that an explicit rhel-9 OSImageStream
hashes the same as the implicit default path. Use the existing test table around
the NodePool, releaseImage, and hostedCluster cases to extend coverage for this
new normalization branch.

Source: Coding guidelines

🤖 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.

Inline comments:
In `@hypershift-operator/controllers/nodepool/osstream.go`:
- Around line 40-46: The ConfigMap lookup in the osstream logic is swallowing
all c.Get failures instead of only missing objects, which can hide transient
API/RBAC errors; update the error handling around the client Get call to skip
only NotFound and return all other errors so the failure propagates through
validateOSImageStream and getRHELStream. Add the needed
k8s.io/apimachinery/pkg/api/errors import and use the existing
ref.Name/nodePool.Namespace lookup path to keep the behavior limited to true
absent ConfigMaps.

In `@hypershift-operator/controllers/nodepool/version.go`:
- Around line 165-174: In setOSImageStreamStatus, the
NodePool.Status.OSImageStream field is only ever set and never cleared, which
can leave stale status behind. Update this helper to resolve the default stream
via GetRHELStream using the release version and usesRunc context, compare it
with osImageStreamFromMachines(machines), and assign an empty
OSImageStreamReference when there is no majority or the observed stream matches
the default. Keep the existing getMachinesForNodePool and
osImageStreamFromMachines flow, but ensure the status field is omitted whenever
the pool is on the release-default OS images.

---

Nitpick comments:
In `@hypershift-operator/controllers/nodepool/aws_test.go`:
- Line 301: The AWS test coverage still only exercises the empty rhelStream
path, so add a non-empty stream case using OSStreams["rhel-10"] to verify the
AWS image selection logic. Update the relevant test call sites around
awsMachineTemplateSpec and resolveAWSAMI so they assert the resolved stream
metadata is used instead of the legacy default path, and keep the existing
empty-stream case as a separate baseline.

In `@hypershift-operator/controllers/nodepool/config_test.go`:
- Around line 250-305: The hash test table in config_test.go only covers
release-version-based normalization, but NewConfigGenerator also normalizes
through usesRuncRuntime(...). Add a 5.x test case that includes a
ContainerRuntimeConfig with defaultRuntime set to runc and verify that an
explicit rhel-9 OSImageStream hashes the same as the implicit default path. Use
the existing test table around the NodePool, releaseImage, and hostedCluster
cases to extend coverage for this new normalization branch.

In `@hypershift-operator/controllers/nodepool/config.go`:
- Around line 107-116: The normalization block in the NodePool config path is
shadowing the outer err variable by redeclaring it inside the rhelStream branch,
which goes against the Go guidance for avoiding shadowing. Update the logic in
the config normalization flow around rhelStream, semver.Parse, and
usesRuncRuntime to reuse the existing err variable instead of introducing a new
scoped one, while preserving the same error handling and return behavior.

In `@hypershift-operator/controllers/nodepool/token_test.go`:
- Line 1184: The test coverage for setKarpenterAMILabels only exercises the
empty-stream path, so add a new table-driven case in token_test.go with
per-stream AWS metadata and a non-empty rhelStream to verify the function uses
resolvedRHELStream instead of falling back to the legacy default lookup. Extend
the existing setKarpenterAMILabels call path in the test to pass the named
stream scenario and assert the expected Karpenter AMI label resolution for that
case.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

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

Review profile: CHILL

Plan: Enterprise

Run ID: b26364bd-aea7-431e-9260-ca7e560c480c

📥 Commits

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

📒 Files selected for processing (17)
  • hypershift-operator/controllers/nodepool/aws.go
  • hypershift-operator/controllers/nodepool/aws_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/nodepool_controller.go
  • hypershift-operator/controllers/nodepool/osstream.go
  • hypershift-operator/controllers/nodepool/osstream_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

Comment thread hypershift-operator/controllers/nodepool/osstream.go
Comment on lines +165 to +174
func (r *NodePoolReconciler) setOSImageStreamStatus(ctx context.Context, nodePool *hyperv1.NodePool) error {
machines, err := r.getMachinesForNodePool(ctx, nodePool)
if err != nil {
return fmt.Errorf("failed to get Machines for OSImageStream status: %w", err)
}

stream := osImageStreamFromMachines(machines)
if stream != "" {
nodePool.Status.OSImageStream = hyperv1.OSImageStreamReference{Name: stream}
}

@coderabbitai coderabbitai Bot Jun 25, 2026

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.

🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

status.osImageStream can become sticky and violate the API contract.

This helper only writes nodePool.Status.OSImageStream when it finds a majority and never clears it otherwise. Once set, the value survives scale-to-zero, split rollouts, and pools that are simply running the release-default stream. The NodePoolStatus.OSImageStream contract says the field should be omitted when the pool is using the release version’s default OS images, so this will publish stale/non-actionable status to clients.

This path needs enough context to compare the observed stream against the resolved default (GetRHELStream("", releaseVersion, usesRunc)) and clear the field whenever there is no majority or the observed stream matches that default.

🤖 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/version.go` around lines 165 - 174,
In setOSImageStreamStatus, the NodePool.Status.OSImageStream field is only ever
set and never cleared, which can leave stale status behind. Update this helper
to resolve the default stream via GetRHELStream using the release version and
usesRunc context, compare it with osImageStreamFromMachines(machines), and
assign an empty OSImageStreamReference when there is no majority or the observed
stream matches the default. Keep the existing getMachinesForNodePool and
osImageStreamFromMachines flow, but ensure the status field is omitted whenever
the pool is on the release-default OS images.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This comment is about setOSImageStreamStatus in version.go, which is not modified by this PR — it was introduced in the parent PR #8730 (already merged). The sticky-status concern is valid but out of scope here; tracking separately if needed.

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.

@sdminonne, understood — thanks for the context. Since setOSImageStreamStatus was introduced in #8730 (already merged) and isn't touched by this PR's diff, I'll treat this as out of scope here rather than blocking this PR.

Since the sticky-status concern still stands, would you like me to open a follow-up issue to track it separately? If so, just confirm and I'll file it against this repository with a summary of the concern and a link back to this discussion.

@sdminonne
sdminonne force-pushed the CNTRLPLANE-3553-usesRunc-detection branch from 6a62ea3 to acb6e22 Compare July 6, 2026 10:13
sdminonne added a commit to sdminonne/hypershift that referenced this pull request Jul 10, 2026
Add usesRuncRuntime() to scan NodePool spec.config ConfigMaps for
ContainerRuntimeConfig with defaultRuntime=runc. Wire this into
getRHELStreamForBootImage, validateOSImageStream, and the config hash
normalization in NewConfigGenerator so that runc-using NodePools on
OCP 5.x fall back to rhel-9 instead of rhel-10 (since RHEL 10 does
not ship runc).

Address CodeRabbit review feedback from PR openshift#8832:
- Only skip apierrors.IsNotFound on ConfigMap get failures; propagate
  RBAC and transient API errors.
- Avoid shadowing outer err in NewConfigGenerator by using distinct
  variable names (runcErr, streamErr) and var declaration for version.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@sdminonne
sdminonne force-pushed the CNTRLPLANE-3553-usesRunc-detection branch from acb6e22 to 40d24ca Compare July 10, 2026 17:06
@openshift-ci openshift-ci Bot added area/platform/azure PR/issue for Azure (AzurePlatform) 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 labels Jul 10, 2026
sdminonne added a commit to sdminonne/hypershift that referenced this pull request Jul 10, 2026
Add usesRuncRuntime() to scan NodePool spec.config ConfigMaps for
ContainerRuntimeConfig with defaultRuntime=runc. Wire this into
getRHELStreamForBootImage, validateOSImageStream, and the config hash
normalization in NewConfigGenerator so that runc-using NodePools on
OCP 5.x fall back to rhel-9 instead of rhel-10 (since RHEL 10 does
not ship runc).

Address CodeRabbit review feedback from PR openshift#8832:
- Only skip apierrors.IsNotFound on ConfigMap get failures; propagate
  RBAC and transient API errors.
- Avoid shadowing outer err in NewConfigGenerator by using distinct
  variable names (runcErr, streamErr) and var declaration for version.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@sdminonne
sdminonne force-pushed the CNTRLPLANE-3553-usesRunc-detection branch from 40d24ca to b2d3928 Compare July 10, 2026 17:22
@sdminonne
sdminonne marked this pull request as ready for review July 10, 2026 17:31
@openshift-ci openshift-ci Bot removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Jul 10, 2026
@openshift-ci
openshift-ci Bot requested review from cblecker and devguyio July 10, 2026 17:32

@cblecker cblecker left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

NewConfigGenerator now uses usesRuncRuntime() for hash normalization (config.go:111-113), but TestNewConfigGenerator doesn't exercise this path with a runc ConfigMap — usesRunc is always false in existing tests. Consider adding a case with OSImageStream.Name="rhel-9" + runc ContainerRuntimeConfig on 5.0.0 to verify the hash normalizes correctly and doesn't trigger spurious rollouts.

yamlReader := yaml.NewYAMLReader(bufio.NewReader(strings.NewReader(payload)))
for {
raw, err := yamlReader.Read()
if err != nil && !coreerrors.Is(err, io.EOF) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This break silently discards non-EOF errors from yamlReader.Read(). If the ConfigMap contains malformed YAML before a valid ContainerRuntimeConfig, the function returns false without reporting the error — potentially causing incorrect rhel-10 stream selection on OCP 5.0+ when runc is actually configured.

The established pattern in config.go parse() propagates YAML read errors. Suggest doing the same here:

if err != nil && !coreerrors.Is(err, io.EOF) {
    return false, fmt.Errorf("failed to read YAML from ConfigMap %s/%s: %w", nodePool.Namespace, ref.Name, err)
}

@sdminonne sdminonne Jul 12, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Totally! — changed the break to return the error, following the same pattern as config.go parse():

if err != nil && !coreerrors.Is(err, io.EOF) {
    return false, fmt.Errorf("failed to read YAML from ConfigMap %s/%s: %w", nodePool.Namespace, ref.Name, err)
}

Note: with a strings.Reader backing the YAML reader, non-EOF errors can't actually be triggered in unit tests (the only error is io.EOF). The fix is still correct as a defensive measure and for consistency with the established pattern.

@sdminonne

Copy link
Copy Markdown
Contributor Author

@cblecker — addressed both review items:

1. TestNewConfigGenerator coverage for runc hash normalization

Added two new test cases that exercise the usesRuncRuntime() → hash normalization path in NewConfigGenerator:

  • "When runc ContainerRuntimeConfig on 5.0.0 with explicit rhel-9, it should normalize rhelStream to empty" — runc + explicit rhel-9 on 5.0.0 normalizes rhelStream to "" (since the runc-aware default for 5.0 is rhel-9), producing hash 72ea1773.
  • "When runc ContainerRuntimeConfig on 5.0.0 with no osImageStream, it should match explicit rhel-9 hash" — same hash 72ea1773, proving no spurious rollout when explicitly setting the stream that matches the runc-aware default.

Both use a real runcContainerRuntimeConfigMap in the fake client so usesRunc=true flows through the full NewConfigGenerator constructor.

2. Silent error swallowing in usesRuncRuntime

Changed the break on non-EOF YAML read errors to propagate the error, matching the established pattern in config.go parse():

if err != nil && !coreerrors.Is(err, io.EOF) {
    return false, fmt.Errorf("failed to read YAML from ConfigMap %s/%s: %w", nodePool.Namespace, ref.Name, err)
}

streamMeta, err := releaseImage.StreamForName(streamName)
if err != nil {
return nil, fmt.Errorf("couldn't resolve stream metadata for stream %q: %w", streamName, err)
}

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.

Heads up: the old code returned (nil, nil) when StreamMetadata == nil, which let the caller in defaultAzureNodePoolImage fall through silently (no marketplace, no error, continue to AzureDiskImage). The new code returns an error from StreamForName.

Is this intentional? For pre-4.20 payloads or release images that legitimately have no stream metadata, this would now surface as "failed to get Azure Marketplace metadata" instead of silently skipping marketplace defaulting. The version guard at line 48 (< 4.20 returns early) may protect against this, but worth double-checking.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

It is, adding a comment

t.Run(tc.name, func(t *testing.T) {
g := NewWithT(t)
_, _, err := getPowerVSImage(tc.region, tc.releaseImage)
_, _, err := getPowerVSImage(tc.region, tc.releaseImage, "")

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.

Azure, KubeVirt, and OpenStack all got a "When named stream is used with multi-stream ReleaseImage..." test case. PowerVS is missing one. Would be good to add for consistency — especially since getPowerVSImage now uses StreamForName too and the existing tests only cover error paths with "".

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Added the test case, matching the pattern from Azure/KubeVirt/OpenStack

sdminonne added a commit to sdminonne/hypershift that referenced this pull request Jul 13, 2026
- Hoist ContainerRuntimeConfig decoder to package-level var using
  api.Scheme to avoid per-call Scheme+CodecFactory allocation
- Add comment explaining why decode errors are intentionally swallowed
  in usesRuncRuntime (non-ContainerRuntimeConfig resources are expected)
- Use idiomatic Go err with := instead of runcErr/streamErr in
  NewConfigGenerator
- Remove init() panic for stream constant assertions; the existing
  TestStreamConstantsMatch test provides sufficient CI coverage without
  risking operator crash on bad rebases
- Document intentional behavior change in getAzureMarketplaceMetadata:
  returns error instead of (nil, nil) when StreamMetadata is missing;
  version guard (< 4.20) protects older payloads
- Add PowerVS named stream test case for consistency with Azure,
  KubeVirt, and OpenStack

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
sdminonne added a commit to sdminonne/hypershift that referenced this pull request Jul 13, 2026
- Hoist ContainerRuntimeConfig decoder to package-level var using
  api.Scheme to avoid per-call Scheme+CodecFactory allocation
- Add comment explaining why decode errors are intentionally swallowed
  in usesRuncRuntime (non-ContainerRuntimeConfig resources are expected)
- Use idiomatic Go err with := instead of runcErr/streamErr in
  NewConfigGenerator
- Remove init() panic for stream constant assertions; the existing
  TestStreamConstantsMatch test provides sufficient CI coverage without
  risking operator crash on bad rebases
- Document intentional behavior change in getAzureMarketplaceMetadata:
  returns error instead of (nil, nil) when StreamMetadata is missing;
  version guard (< 4.20) protects older payloads
- Add PowerVS named stream test case for consistency with Azure,
  KubeVirt, and OpenStack

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@sdminonne
sdminonne force-pushed the CNTRLPLANE-3553-usesRunc-detection branch from a2ee3a8 to 77af5f2 Compare July 13, 2026 13:20
@jparrill

Copy link
Copy Markdown
Contributor

/approve

@openshift-ci

openshift-ci Bot commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: jparrill, sdminonne

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 Jul 13, 2026
sdminonne added a commit to sdminonne/hypershift that referenced this pull request Jul 13, 2026
Add usesRuncRuntime() to scan NodePool spec.config ConfigMaps for
ContainerRuntimeConfig with defaultRuntime=runc. Wire this into
getRHELStreamForBootImage, validateOSImageStream, and the config hash
normalization in NewConfigGenerator so that runc-using NodePools on
OCP 5.x fall back to rhel-9 instead of rhel-10 (since RHEL 10 does
not ship runc).

Address CodeRabbit review feedback from PR openshift#8832:
- Only skip apierrors.IsNotFound on ConfigMap get failures; propagate
  RBAC and transient API errors.
- Avoid shadowing outer err in NewConfigGenerator by using distinct
  variable names (runcErr, streamErr) and var declaration for version.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
sdminonne added a commit to sdminonne/hypershift that referenced this pull request Jul 13, 2026
Propagate non-EOF YAML read errors in usesRuncRuntime instead of
silently breaking, matching the established pattern in config.go parse().
Add two TestNewConfigGenerator cases exercising the runc ConfigMap path
for config hash normalization on OCP 5.0.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@sdminonne
sdminonne force-pushed the CNTRLPLANE-3553-usesRunc-detection branch from 77af5f2 to e24d722 Compare July 13, 2026 15:15
sdminonne added a commit to sdminonne/hypershift that referenced this pull request Jul 13, 2026
- Hoist ContainerRuntimeConfig decoder to package-level var using
  api.Scheme to avoid per-call Scheme+CodecFactory allocation
- Add comment explaining why decode errors are intentionally swallowed
  in usesRuncRuntime (non-ContainerRuntimeConfig resources are expected)
- Use idiomatic Go err with := instead of runcErr/streamErr in
  NewConfigGenerator
- Remove init() panic for stream constant assertions; the existing
  TestStreamConstantsMatch test provides sufficient CI coverage without
  risking operator crash on bad rebases
- Document intentional behavior change in getAzureMarketplaceMetadata:
  returns error instead of (nil, nil) when StreamMetadata is missing;
  version guard (< 4.20) protects older payloads
- Add PowerVS named stream test case for consistency with Azure,
  KubeVirt, and OpenStack

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@sdminonne
sdminonne force-pushed the CNTRLPLANE-3553-usesRunc-detection branch from e24d722 to edf9c8a Compare July 13, 2026 15:21
…EL stream resolution

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).

Add usesRuncRuntime() to scan NodePool spec.config ConfigMaps for
ContainerRuntimeConfig with defaultRuntime=runc, so that runc-using
NodePools on OCP 5.x fall back to rhel-9 instead of rhel-10 (since
RHEL 10 does not ship runc). Wire this into getRHELStreamForBootImage,
validateOSImageStream, and the config hash normalization in
NewConfigGenerator.

Ref: CNTRLPLANE-3553

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@sdminonne
sdminonne force-pushed the CNTRLPLANE-3553-usesRunc-detection branch from edf9c8a to ef295ce Compare July 13, 2026 15:28
@enxebre

enxebre commented Jul 13, 2026

Copy link
Copy Markdown
Member

/lgtm

@openshift-ci openshift-ci Bot added the lgtm Indicates that a PR is ready to be merged. label Jul 13, 2026
@openshift-merge-bot

Copy link
Copy Markdown
Contributor

Scheduling tests matching the pipeline_run_if_changed or not excluded by pipeline_skip_if_only_changed parameters:
/test e2e-aks-4-22
/test e2e-aws-4-22
/test e2e-aks
/test e2e-aws
/test e2e-aws-upgrade-hypershift-operator
/test e2e-azure-v2-self-managed
/test e2e-kubevirt-aws-ovn-reduced
/test e2e-v2-aws
/test e2e-v2-gke

@hypershift-jira-solve-ci

hypershift-jira-solve-ci Bot commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Test Failure Analysis Complete

Job Information

Test Failure Analysis

Error

TestCreateClusterRequestServingIsolation/Teardown:
  fixture.go:338: Failed to wait for infra resources in guest cluster to be deleted: context deadline exceeded
  fixture.go:345: Failed to clean up 4 remaining resources for guest cluster
  - 3x EC2 volumes (vol-0ca453e2f2100f8e6, vol-0f5a210911a2a17f6, vol-07396a851d27cdeb8)
  - 1x NLB (net/a780f61be09fd45fcb5eebd63e994cdd/5dc5b06510af0471)

Summary

This failure is unrelated to PR #8832 and is a pre-existing flaky teardown issue. The test TestCreateClusterRequestServingIsolation passed all 24 of its functional validations (ValidateHostedCluster, EnsureHostedCluster, Main sub-tests) successfully. The hosted cluster was created and operated correctly. The failure occurred exclusively in the Teardown sub-test, which timed out after ~22 minutes (1329.89s) waiting for 4 AWS infrastructure resources (3 EBS volumes attached to CAPA-managed worker nodes and 1 Network Load Balancer for the router-default ingress service) to be deleted from the request-serving-isolation-978kg guest cluster. PR #8832 modifies only NodePool controller logic for RHEL stream resolution in hypershift-operator/controllers/nodepool/ and does not touch any test framework, teardown, or AWS cleanup code.

Root Cause

The root cause is an AWS infrastructure resource cleanup timeout during test teardown — a known flaky behavior in HyperShift e2e tests, not a regression introduced by this PR.

Detailed chain of events:

  1. The test successfully created hosted cluster e2e-clusters-qvcdf/request-serving-isolation-978kg with 2 request-serving and 3 non-request-serving NodePools
  2. All functional validations passed (node readiness, pod health, network policies, webhook validation, metrics, etc.)
  3. During teardown, the cluster was destroyed at the Kubernetes level (hypershift_framework.go:591: Destroyed cluster)
  4. However, the post-destroy AWS infrastructure cleanup hit a context deadline exceeded waiting for 4 AWS resources to be released:
    • 3 EBS volumes (one per AZ: us-east-1a, us-east-1b, us-east-1c) — these are worker node root volumes tagged with CAPA ownership
    • 1 Network Load Balancer (for openshift-ingress/router-default) — AWS NLB deletion is asynchronous and can be slow
  5. The fixture.go cleanup code (line 338) timed out after the allotted deadline, causing the Teardown sub-test to fail

Why this is unrelated to PR #8832:

  • PR CNTRLPLANE-3553: Wire usesRunc detection into RHEL stream resolution #8832 modifies 16 files, all within hypershift-operator/controllers/nodepool/ — specifically osstream.go, config.go, conditions.go, and platform-specific resolvers (Azure, KubeVirt, OpenStack, PowerVS)
  • The failing code is in test/e2e/fixture.go (test infrastructure cleanup) and the AWS resource lifecycle
  • The test's functional assertions all passed, confirming the NodePool controller changes work correctly
  • The AWS resource cleanup timeout is an environmental/infrastructure issue unrelated to NodePool RHEL stream resolution

Additional environmental issue observed: The AWS account hit its EC2 KeyPair limit (5000 maximum), causing KeyPairLimitExceeded errors during journal collection — this is nonfatal but indicates AWS account resource pressure.

Recommendations
  1. Retry the job — This is a flaky teardown timeout, not a code regression. A /retest should pass.
  2. No code changes needed in PR CNTRLPLANE-3553: Wire usesRunc detection into RHEL stream resolution #8832 — The PR's changes are functionally correct (all 24 validation sub-tests passed). The failure is in test infrastructure cleanup timing.
  3. Track the flaky teardown — The TestCreateClusterRequestServingIsolation/Teardown timeout (waiting for AWS resources to be deleted) is a known pattern. The 22-minute teardown duration suggests AWS API latency or resource dependency ordering issues during NLB and volume deletion.
  4. AWS account hygiene — The KeyPairLimitExceeded error (5000 keypairs) indicates the shared CI AWS account needs keypair cleanup, though this did not directly cause this failure.
Evidence
Evidence Detail
Failing test TestCreateClusterRequestServingIsolation/Teardown (1329.89s / ~22 min)
Test result All 24 functional sub-tests PASSED; only Teardown FAILED
Error fixture.go:338: Failed to wait for infra resources in guest cluster to be deleted: context deadline exceeded
Stuck resources 3 EBS volumes (us-east-1a/b/c) + 1 NLB (router-default) for cluster request-serving-isolation-978kg
Cluster lifecycle Created in 41s, rolled out in 3m54s, destroyed successfully — only post-destroy AWS cleanup timed out
PR scope 16 files in hypershift-operator/controllers/nodepool/ — RHEL stream resolution logic only
PR touches test code? No — no changes to fixture.go, requestserving.go, hypershift_framework.go, or any teardown logic
Overall test health 591 passed, 2 failed (same test + its Teardown), 29 skipped out of 622 total
AWS account issue KeyPairLimitExceeded: Maximum of 5000 keypairs reached (nonfatal, journal collection)

@sdminonne

Copy link
Copy Markdown
Contributor Author

/test e2e-aws-4-22

@openshift-ci

openshift-ci Bot commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

@sdminonne: all tests passed!

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.

@sdminonne

Copy link
Copy Markdown
Contributor Author

/verified by unit-tests

@openshift-ci-robot openshift-ci-robot added the verified Signifies that the PR passed pre-merge verification criteria label Jul 14, 2026
@openshift-ci-robot

Copy link
Copy Markdown

@sdminonne: This PR has been marked as verified by unit-tests.

Details

In response to this:

/verified by unit-tests

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.

@jparrill

Copy link
Copy Markdown
Contributor

/label acknowledge-critical-fixes-only

@openshift-ci openshift-ci Bot added the acknowledge-critical-fixes-only Indicates if the issuer of the label is OK with the policy. label Jul 14, 2026
@openshift-merge-bot
openshift-merge-bot Bot merged commit 9a747c4 into openshift:main Jul 14, 2026
41 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

acknowledge-critical-fixes-only Indicates if the issuer of the label is OK with the policy. approved Indicates a PR has been approved by an approver from all required OWNERS files. 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 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. 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