CNTRLPLANE-3553: Wire usesRunc detection into RHEL stream resolution#8832
Conversation
|
Pipeline controller notification For optional jobs, comment This repository is configured in: LGTM mode |
|
@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. DetailsIn response to this:
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. |
|
Skipping CI for Draft Pull Request. |
📝 WalkthroughWalkthroughNodePool reconciliation now infers 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
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
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
Possibly related PRs
Suggested reviewers
🚥 Pre-merge checks | ✅ 11✅ Passed checks (11 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (4)
hypershift-operator/controllers/nodepool/aws_test.go (1)
301-301: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winCover 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 withOSStreams["rhel-10"]and a non-empty stream argument soawsMachineTemplateSpec/resolveAWSAMIprove 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 winAdd 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
rhelStreamsosetKarpenterAMILabelsis pinned toresolvedRHELStreamrather 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 winAvoid shadowing
errin the normalization block.Line 109 creates a new
errscoped to theif, which makes this already branchy path harder to scan and goes against the repo’s Go guidance. Reusing the outererrkeeps 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 winAdd a
usesRuncRuntimenormalization case here.These new cases only pin the release-version branch.
NewConfigGeneratornow also normalizes againstusesRuncRuntime(...), so please add a 5.x case with aContainerRuntimeConfigsettingdefaultRuntime: runcand assert that explicitrhel-9hashes 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
📒 Files selected for processing (17)
hypershift-operator/controllers/nodepool/aws.gohypershift-operator/controllers/nodepool/aws_test.gohypershift-operator/controllers/nodepool/capi_test.gohypershift-operator/controllers/nodepool/conditions.gohypershift-operator/controllers/nodepool/config.gohypershift-operator/controllers/nodepool/config_test.gohypershift-operator/controllers/nodepool/gcp.gohypershift-operator/controllers/nodepool/gcp_test.gohypershift-operator/controllers/nodepool/nodepool_controller.gohypershift-operator/controllers/nodepool/osstream.gohypershift-operator/controllers/nodepool/osstream_test.gohypershift-operator/controllers/nodepool/stream.gohypershift-operator/controllers/nodepool/stream_test.gohypershift-operator/controllers/nodepool/token.gohypershift-operator/controllers/nodepool/token_test.gohypershift-operator/controllers/nodepool/version.gohypershift-operator/controllers/nodepool/version_test.go
| 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} | ||
| } |
There was a problem hiding this comment.
🗄️ 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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
@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.
6a62ea3 to
acb6e22
Compare
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>
acb6e22 to
40d24ca
Compare
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>
40d24ca to
b2d3928
Compare
cblecker
left a comment
There was a problem hiding this comment.
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) { |
There was a problem hiding this comment.
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)
}There was a problem hiding this comment.
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.
|
@cblecker — addressed both review items: 1. Added two new test cases that exercise the
Both use a real 2. Silent error swallowing in Changed the 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) | ||
| } |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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, "") |
There was a problem hiding this comment.
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 "".
There was a problem hiding this comment.
Added the test case, matching the pattern from Azure/KubeVirt/OpenStack
- 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>
- 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>
a2ee3a8 to
77af5f2
Compare
|
/approve |
|
[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 DetailsNeeds approval from an approver in each of these files:
Approvers can indicate their approval by writing |
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>
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>
77af5f2 to
e24d722
Compare
- 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>
e24d722 to
edf9c8a
Compare
…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>
edf9c8a to
ef295ce
Compare
|
/lgtm |
|
Scheduling tests matching the |
Test Failure Analysis CompleteJob Information
Test Failure AnalysisErrorSummaryThis failure is unrelated to PR #8832 and is a pre-existing flaky teardown issue. The test Root CauseThe 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:
Why this is unrelated to PR #8832:
Additional environmental issue observed: The AWS account hit its EC2 KeyPair limit (5000 maximum), causing Recommendations
Evidence
|
|
/test e2e-aws-4-22 |
|
@sdminonne: all tests passed! Full PR test history. Your PR dashboard. DetailsInstructions 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. |
|
/verified by unit-tests |
|
@sdminonne: This PR has been marked as verified by DetailsIn response to this:
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. |
|
/label acknowledge-critical-fixes-only |
Summary
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 defaultusesRuncRuntime()to scan NodePoolspec.configConfigMaps forContainerRuntimeConfigwithdefaultRuntime: runcgetRHELStreamForBootImage(),validateOSImageStream(), and the config hash normalization inNewConfigGenerator()rhel-9; explicitrhel-10+ runc returns a validation error viaValidMachineConfigconditionDependencies
Parallel dependency (no ordering constraint with this PR):
Test plan
TestUsesRuncRuntime— 7 cases: no configs, runc, crun, empty runtime, MachineConfig, missing ConfigMap, multiple configsTestGetRHELStreamForBootImage— 15 cases including 4 runc-aware: runc+5.0→rhel-9, runc+rhel-10→error, runc+4.x→rhel-9, missing ConfigMapTestGetRHELStream(stream_test.go) — 20 cases including 9 runc-aware covering implicit/explicit stream × 4.x/5.0/5.1 × runc combinationsTestValidateOSImageStream— 7 cases including 2 runc-aware: rhel-10+runc→error, rhel-9+runc→okTestNewConfigGenerator— 2 additional cases exercising the runc ConfigMap path for config hash normalization on OCP 5.0make verifyafter rebase onto merged CNTRLPLANE-3553: Wire osImageStream into NodePool controller (hash, token, status, validation) #8730JIRA: CNTRLPLANE-3553
🤖 Generated with Claude Code