Skip to content

OCPBUGS-98744: compare post-upgrade RHCOS version against pre-upgrade instead of release metadata#9014

Open
jparrill wants to merge 1 commit into
openshift:mainfrom
jparrill:OCPBUGS-98744
Open

OCPBUGS-98744: compare post-upgrade RHCOS version against pre-upgrade instead of release metadata#9014
jparrill wants to merge 1 commit into
openshift:mainfrom
jparrill:OCPBUGS-98744

Conversation

@jparrill

@jparrill jparrill commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

Summary

  • TestKarpenterUpgradeControlPlane was failing ~27% of e2e-aws presubmit runs because the expected RHCOS version from the release payload did not match what nodes actually booted with
  • Neither the ImageStream machine-os annotation nor the stream metadata Release field reliably predicts the on-disk RHCOS version:
    • ImageStream: reflects the RHCOS the container images were built against — can be newer than the AMI (e.g. 9.8.20260713-1 vs AMI with 9.8.20260708-0)
    • Stream metadata: the Release field can be stale when the AMI ID is updated without refreshing the version string (e.g. 9.8.20260428-0 while the AMI actually boots 9.8.20260713-1)
  • Replace the version-list check with a before/after comparison: capture the pre-upgrade OSImage, then assert the post-upgrade RHCOS version is strictly newer
  • The RHCOS version string (e.g. 9.8.20260713-1) embeds a YYYYMMDD date, so lexicographic comparison gives correct ordering
  • Remove the now-unused machineOSVersions() helper

Root Cause

The CI release payload's metadata has two version sources that can both diverge from the actual node RHCOS:

  1. ImageStream io.openshift.build.versions machine-os=X — reflects RHCOS sources at build time, can be ahead of the published AMI
  2. Stream metadata Architectures[arch].Images.Aws.Regions[region].Release — can be stale (AMI ID updated but Release field not refreshed)

Neither source reflects what the AMI actually contains. A before/after comparison against the live node is the only reliable assertion.

Fixes

Test plan

  • e2e-aws presubmit passes (TestKarpenterUpgradeControlPlane)
  • No regressions in other Karpenter tests

Summary by CodeRabbit

  • Tests
    • Improved control plane upgrade validation by comparing RHCOS versions before and after upgrades.
    • Updated node readiness checks to recognize successful upgrades based on node OS image versions.
    • Removed reliance on external release image metadata when validating upgrade results.

@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

@coderabbitai

coderabbitai Bot commented Jul 15, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

The Karpenter control-plane upgrade test now extracts RHCOS versions directly from node OS image strings. It records the pre-upgrade version and verifies that post-upgrade node versions are not older. The previous release-image registry lookup and machineOSVersions helper were removed, along with their related parsing dependencies.

Suggested reviewers: bryan-cox, enxebre

🚥 Pre-merge checks | ✅ 9 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Test Structure And Quality ⚠️ Warning The new upgrade predicate still lacks a pre-upgrade version guard, and the regex is overly strict (\\d{8}), so the test can mis-validate or never match actual OSImage strings. Add a fatal check when extractRHCOSVersion(preUpgradeOSImage) is empty, and broaden the regex to the real RHCOS version format used by node OSImage strings.
Ipv6 And Disconnected Network Test Compatibility ⚠️ Warning TestKarpenterUpgradeControlPlane still uses testWorkload(), which hardcodes quay.io/openshift/origin-pod:4.22.0 and requires public registry access. Use a mirrored/internal image or skip in disconnected jobs; verify in /payload-job periodic-ci-openshift-release-master-nightly-4.22-e2e-metal-ipi-ovn-ipv6.
✅ Passed checks (9 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: comparing post-upgrade RHCOS against the pre-upgrade version instead of release metadata.
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 No dynamic or generated values appear in any test titles; the changed files only use static subtest names and non-title log/predicate messages.
Topology-Aware Scheduling Compatibility ✅ Passed PASS: PR only changes an e2e version-check and removes a helper; no manifests, controllers, replicas, affinity, selectors, or topology assumptions were added.
No-Weak-Crypto ✅ Passed Modified files only add OSImage version parsing/comparison; no MD5/SHA1/DES/RC4/3DES, cipher APIs, or secret/token comparisons are present.
Container-Privileges ✅ Passed PR only changes Go e2e tests; the diff adds no container/K8s manifests or securityContext settings like privileged/hostNetwork/SYS_ADMIN.
No-Sensitive-Data-In-Logs ✅ Passed The patch only logs release images, node names, and RHCOS/OSImage values; no passwords, tokens, PII, or secrets were added.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@jparrill jparrill changed the title fix(OCPBUGS-98744): read expected RHCOS version from stream metadata AMI OCPBUGS-98744: read expected RHCOS version from stream metadata AMI Jul 15, 2026
@openshift-ci-robot openshift-ci-robot added jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. jira/invalid-bug Indicates that a referenced Jira bug is invalid for the branch this PR is targeting. labels Jul 15, 2026
@openshift-ci-robot

Copy link
Copy Markdown

@jparrill: This pull request references Jira Issue OCPBUGS-98744, which is invalid:

  • expected the bug to target the "5.0.0" version, but no target version was set

Comment /jira refresh to re-evaluate validity if changes to the Jira bug are made, or edit the title of this pull request to link to a different bug.

The bug has been updated to refer to the pull request using the external bug tracker.

Details

In response to this:

Summary

  • machineOSVersions() was reading the expected RHCOS version from the ImageStream machine-os annotation, which reflects the version container images were built against
  • The actual AMI that nodes boot from comes from stream metadata, and its RHCOS version can lag behind when AWS AMI publication is delayed
  • This mismatch caused TestKarpenterUpgradeControlPlane to fail 27% of the time (3/11) in e2e-aws presubmit — nodes booted with the correct AMI but reported an older RHCOS version than the ImageStream advertised
  • Switch machineOSVersions() to read the Release field from the stream metadata AWS region entries, which is the same source that provides the AMI ID

Root Cause

The CI release payload's ImageStream tags contain io.openshift.build.versions annotations with machine-os=9.8.20260713-1 (Jul 13 build), but the AMI baked into the stream metadata still points to 9.8.20260708-0 (Jul 8 build) because AWS AMI publication lags behind the RHCOS build. Nodes boot correctly with the AMI, but the test compared the node's OSImage against the ImageStream annotation rather than the AMI's actual release version.

Fixes

Test plan

  • e2e-aws presubmit passes (includes TestKarpenterUpgradeControlPlane)
  • No regressions in other Karpenter 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.

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

🧹 Nitpick comments (1)
test/e2e/karpenter_test.go (1)

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

Use a two-value lookup for the deduplication set.

The repository guidelines require explicit map-existence checks. Prefer map[string]struct{} with if _, ok := seen[release]; ok.

Proposed change
- seen := map[string]bool{}
+ seen := make(map[string]struct{})
...
- if !seen[regionData.Release] {
-   seen[regionData.Release] = true
+ if _, ok := seen[regionData.Release]; !ok {
+   seen[regionData.Release] = struct{}{}

As per coding guidelines, check map existence with the two-value assignment.

🤖 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 `@test/e2e/karpenter_test.go` around lines 1885 - 1887, Update the
deduplication check in the versions collection to use an explicit two-value
lookup on the seen map, such as checking whether the release key exists, while
preserving the existing behavior of marking unseen releases and appending them
to versions.

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 `@test/e2e/karpenter_test.go`:
- Around line 1862-1892: Add focused unit tests for machineOSVersions covering
nil and default streams, multiple OSStreams, missing AWS or region data, empty
releases, and duplicate release values. Construct minimal releaseinfo and stream
fixtures for each case, assert the returned versions, and keep the tests scoped
to this helper’s behavior.

---

Nitpick comments:
In `@test/e2e/karpenter_test.go`:
- Around line 1885-1887: Update the deduplication check in the versions
collection to use an explicit two-value lookup on the seen map, such as checking
whether the release key exists, while preserving the existing behavior of
marking unseen releases and appending them to versions.
🪄 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: 0d580540-a03f-40e1-a9ed-f16569b53e32

📥 Commits

Reviewing files that changed from the base of the PR and between 7eb0da0 and cfa7a2e.

📒 Files selected for processing (2)
  • test/e2e/karpenter_control_plane_upgrade_test.go
  • test/e2e/karpenter_test.go

Comment thread test/e2e/karpenter_test.go Outdated
Comment on lines 1862 to 1892
func machineOSVersions(releaseImage *releaseinfo.ReleaseImage, region string) []string {
seen := map[string]bool{}
var versions []string
for _, tag := range releaseImage.ImageStream.Spec.Tags {
buildVersions, ok := tag.Annotations["io.openshift.build.versions"]
if !ok {

streams := []*stream.Stream{releaseImage.StreamMetadata}
for _, s := range releaseImage.OSStreams {
if s != nil {
streams = append(streams, s)
}
}

for _, s := range streams {
if s == nil {
continue
}
for _, pair := range strings.Split(buildVersions, ",") {
parts := strings.SplitN(strings.TrimSpace(pair), "=", 2)
if len(parts) == 2 && parts[0] == "machine-os" {
versions = append(versions, parts[1])
for _, arch := range s.Architectures {
if arch.Images.Aws == nil {
continue
}
regionData, ok := arch.Images.Aws.Regions[region]
if !ok || regionData.Release == "" {
continue
}
if !seen[regionData.Release] {
seen[regionData.Release] = true
versions = append(versions, regionData.Release)
}
}
}

return versions

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.

📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

Add focused tests for machineOSVersions.

Cover nil/default streams, multiple OSStreams, missing AWS or region entries, empty releases, and deduplication. As per coding guidelines, all Go code changes and additions must be unit tested.

🤖 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 `@test/e2e/karpenter_test.go` around lines 1862 - 1892, Add focused unit tests
for machineOSVersions covering nil and default streams, multiple OSStreams,
missing AWS or region data, empty releases, and duplicate release values.
Construct minimal releaseinfo and stream fixtures for each case, assert the
returned versions, and keep the tests scoped to this helper’s behavior.

Source: Coding guidelines

@jparrill

Copy link
Copy Markdown
Contributor Author

/area testing

@jparrill

Copy link
Copy Markdown
Contributor Author

/acknowledge-critical-fixes-only

@jparrill

Copy link
Copy Markdown
Contributor Author

/jira refresh

@openshift-ci-robot

Copy link
Copy Markdown

@jparrill: This pull request references Jira Issue OCPBUGS-98744, which is invalid:

  • expected the bug to target the "5.0.0" version, but no target version was set

Comment /jira refresh to re-evaluate validity if changes to the Jira bug are made, or edit the title of this pull request to link to a different bug.

Details

In response to this:

/jira refresh

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 area/testing Indicates the PR includes changes for e2e testing label Jul 15, 2026
@openshift-ci
openshift-ci Bot requested review from bryan-cox and enxebre July 15, 2026 15:36
@openshift-ci openshift-ci Bot added approved Indicates a PR has been approved by an approver from all required OWNERS files. and removed do-not-merge/needs-area labels Jul 15, 2026
@codecov

codecov Bot commented Jul 15, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 44.11%. Comparing base (efc9e04) to head (8b2073c).
⚠️ Report is 34 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff            @@
##             main    #9014     +/-   ##
=========================================
  Coverage   44.11%   44.11%             
=========================================
  Files         772      779      +7     
  Lines       96226    98077   +1851     
=========================================
+ Hits        42448    43269    +821     
- Misses      50832    51773    +941     
- Partials     2946     3035     +89     

see 27 files with indirect coverage changes

Flag Coverage Δ
cmd-support 38.23% <ø> (-0.01%) ⬇️
cpo-hostedcontrolplane 46.27% <ø> (+0.10%) ⬆️
cpo-other 45.22% <ø> (+0.08%) ⬆️
hypershift-operator 54.14% <ø> (+0.04%) ⬆️
other 33.59% <ø> (+1.47%) ⬆️

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.

@csrwng csrwng added the acknowledge-critical-fixes-only Indicates if the issuer of the label is OK with the policy. label Jul 15, 2026

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

Clean, well-targeted fix. Aligning the expected RHCOS version with the stream metadata AMI source (rather than ImageStream annotations) eliminates the flake from AMI publication lag. Both fields (StreamMetadata, OSStreams) are properly used, the single caller is updated, and the dedup logic is correct.

/lgtm

@openshift-ci openshift-ci Bot added the lgtm Indicates that a PR is ready to be merged. label Jul 15, 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

@openshift-ci

openshift-ci Bot commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

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

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

@cwbotbot

cwbotbot commented Jul 15, 2026

Copy link
Copy Markdown

Test Results

e2e-aws

Failed Tests

Total failed tests: 4

  • TestAutoscaling
  • TestAutoscaling/Teardown
  • TestKarpenterUpgradeControlPlane
  • TestKarpenterUpgradeControlPlane/Main

e2e-aks

@openshift-ci openshift-ci Bot removed the lgtm Indicates that a PR is ready to be merged. label Jul 16, 2026
@openshift-ci

openshift-ci Bot commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

New changes are detected. LGTM label has been removed.

@jparrill jparrill changed the title OCPBUGS-98744: read expected RHCOS version from stream metadata AMI fix(OCPBUGS-98744): compare post-upgrade RHCOS version against pre-upgrade instead of release metadata Jul 16, 2026
@openshift-ci-robot openshift-ci-robot removed the jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. label Jul 16, 2026
@openshift-ci-robot openshift-ci-robot removed the jira/invalid-bug Indicates that a referenced Jira bug is invalid for the branch this PR is targeting. label Jul 16, 2026
@openshift-ci-robot

Copy link
Copy Markdown

@jparrill: No Jira issue is referenced in the title of this pull request.
To reference a jira issue, add 'XYZ-NNN:' to the title of this pull request and request another refresh with /jira refresh.

Details

In response to this:

Summary

  • TestKarpenterUpgradeControlPlane was failing ~27% of e2e-aws presubmit runs because the expected RHCOS version from the release payload did not match what nodes actually booted with
  • Neither the ImageStream machine-os annotation nor the stream metadata Release field reliably predicts the on-disk RHCOS version:
  • ImageStream: reflects the RHCOS the container images were built against — can be newer than the AMI (e.g. 9.8.20260713-1 vs AMI with 9.8.20260708-0)
  • Stream metadata: the Release field can be stale when the AMI ID is updated without refreshing the version string (e.g. 9.8.20260428-0 while the AMI actually boots 9.8.20260713-1)
  • Replace the version-list check with a before/after comparison: capture the pre-upgrade OSImage, then assert the post-upgrade RHCOS version is strictly newer
  • The RHCOS version string (e.g. 9.8.20260713-1) embeds a YYYYMMDD date, so lexicographic comparison gives correct ordering
  • Remove the now-unused machineOSVersions() helper

Root Cause

The CI release payload's metadata has two version sources that can both diverge from the actual node RHCOS:

  1. ImageStream io.openshift.build.versions machine-os=X — reflects RHCOS sources at build time, can be ahead of the published AMI
  2. Stream metadata Architectures[arch].Images.Aws.Regions[region].Release — can be stale (AMI ID updated but Release field not refreshed)

Neither source reflects what the AMI actually contains. A before/after comparison against the live node is the only reliable assertion.

Fixes

Test plan

  • e2e-aws presubmit passes (TestKarpenterUpgradeControlPlane)
  • No regressions in other Karpenter 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 jparrill changed the title fix(OCPBUGS-98744): compare post-upgrade RHCOS version against pre-upgrade instead of release metadata OCPBUGS-98744: compare post-upgrade RHCOS version against pre-upgrade instead of release metadata Jul 16, 2026
@jparrill

Copy link
Copy Markdown
Contributor Author

Thanks for the review @csrwng — the approach changed since your approval, so I want to explain why.

Why the stream metadata approach didn't work either:

The initial fix (reading Release from stream metadata) solved one direction of the mismatch but introduced the opposite problem. In CI payloads:

  • The ImageStream machine-os annotation can be newer than the AMI (container images built against a newer RHCOS than what the published AMI contains)
  • The stream metadata Release field can be older than the AMI (the AMI ID gets updated but the Release version string is not refreshed — e.g. Release: 9.8.20260428-0 while the AMI actually boots 9.8.20260713-1)

The first CI run after the initial fix confirmed this: nodes reported 9.8.20260713-1 but the stream metadata said 9.8.20260428-0. Neither metadata source reliably predicts the actual on-disk RHCOS version.

Why the before/after comparison works:

Instead of depending on any release metadata source, the test now captures the pre-upgrade OSImage and asserts the post-upgrade RHCOS version is strictly newer. The RHCOS version string embeds a YYYYMMDD date (e.g. 9.8.20260713-1), so lexicographic comparison gives correct ordering. This validates the upgrade succeeded regardless of metadata drift.

@openshift-ci-robot openshift-ci-robot added jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. jira/invalid-bug Indicates that a referenced Jira bug is invalid for the branch this PR is targeting. labels Jul 16, 2026
@openshift-ci-robot

Copy link
Copy Markdown

@jparrill: This pull request references Jira Issue OCPBUGS-98744, which is invalid:

  • expected the bug to target the "5.0.0" version, but no target version was set

Comment /jira refresh to re-evaluate validity if changes to the Jira bug are made, or edit the title of this pull request to link to a different bug.

The bug has been updated to refer to the pull request using the external bug tracker.

Details

In response to this:

Summary

  • TestKarpenterUpgradeControlPlane was failing ~27% of e2e-aws presubmit runs because the expected RHCOS version from the release payload did not match what nodes actually booted with
  • Neither the ImageStream machine-os annotation nor the stream metadata Release field reliably predicts the on-disk RHCOS version:
  • ImageStream: reflects the RHCOS the container images were built against — can be newer than the AMI (e.g. 9.8.20260713-1 vs AMI with 9.8.20260708-0)
  • Stream metadata: the Release field can be stale when the AMI ID is updated without refreshing the version string (e.g. 9.8.20260428-0 while the AMI actually boots 9.8.20260713-1)
  • Replace the version-list check with a before/after comparison: capture the pre-upgrade OSImage, then assert the post-upgrade RHCOS version is strictly newer
  • The RHCOS version string (e.g. 9.8.20260713-1) embeds a YYYYMMDD date, so lexicographic comparison gives correct ordering
  • Remove the now-unused machineOSVersions() helper

Root Cause

The CI release payload's metadata has two version sources that can both diverge from the actual node RHCOS:

  1. ImageStream io.openshift.build.versions machine-os=X — reflects RHCOS sources at build time, can be ahead of the published AMI
  2. Stream metadata Architectures[arch].Images.Aws.Regions[region].Release — can be stale (AMI ID updated but Release field not refreshed)

Neither source reflects what the AMI actually contains. A before/after comparison against the live node is the only reliable assertion.

Fixes

Test plan

  • e2e-aws presubmit passes (TestKarpenterUpgradeControlPlane)
  • No regressions in other Karpenter 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.

@openshift-ci

openshift-ci Bot commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

@jparrill: 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-aws cfa7a2e link true /test e2e-aws
ci/prow/e2e-azure-v2-self-managed cfa7a2e link true /test e2e-azure-v2-self-managed
ci/prow/e2e-aws-4-22 cfa7a2e link true /test e2e-aws-4-22
ci/prow/e2e-aws-upgrade-hypershift-operator cfa7a2e link true /test e2e-aws-upgrade-hypershift-operator

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.

@jparrill

Copy link
Copy Markdown
Contributor Author

/jira refresh

@openshift-ci-robot openshift-ci-robot added the jira/valid-bug Indicates that a referenced Jira bug is valid for the branch this PR is targeting. label Jul 16, 2026
@openshift-ci-robot

Copy link
Copy Markdown

@jparrill: This pull request references Jira Issue OCPBUGS-98744, which is valid.

3 validation(s) were run on this bug
  • bug is open, matching expected state (open)
  • bug target version (5.0.0) matches configured target version for branch (5.0.0)
  • bug is in the state POST, which is one of the valid states (NEW, ASSIGNED, POST)
Details

In response to this:

/jira refresh

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@openshift-ci-robot openshift-ci-robot removed the jira/invalid-bug Indicates that a referenced Jira bug is invalid for the branch this PR is targeting. label Jul 16, 2026
}

return false, fmt.Sprintf("expected node OS image %q to contain one of %v", fullOSImageString, expectedRHCOSVersions), nil
if postVersion <= preUpgradeRHCOSVersion {

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.

Can we confirm that the rhcos version will always change on a newer OCP release? If not, then at most all we could check is that it's not older after upgrade.

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.

Good point — z-stream upgrades may ship the same RHCOS. Changed from strict greater-than to not-older (>= instead of >). The check now only fails if the post-upgrade RHCOS is strictly older than the pre-upgrade version.

…grade instead of release metadata

TestKarpenterUpgradeControlPlane was failing because the expected RHCOS
version from the release payload did not match what nodes actually booted
with. Neither the ImageStream machine-os annotation (reflects build-time
RHCOS, can be newer than the AMI) nor the stream metadata Release field
(can be stale when the AMI ID is updated without refreshing the version
string) reliably predicts the on-disk RHCOS version.

Replace the version-list check with a before/after comparison: capture
the pre-upgrade node OSImage, then after the Replace upgrade assert that
the new node's RHCOS version is not older. The RHCOS version string
(e.g. 9.8.20260713-1) embeds a YYYYMMDD date, so lexicographic
comparison gives correct ordering. The check uses >= (not >) because
z-stream upgrades may ship the same RHCOS version.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Juan Manuel Parrilla Madrid <jparrill@redhat.com>

@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

🤖 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 `@test/e2e/karpenter_control_plane_upgrade_test.go`:
- Around line 99-101: Validate that preUpgradeRHCOSVersion returned by
extractRHCOSVersion is non-empty before the later version comparison. Add a
fail-fast assertion or test error immediately after extraction, preserving the
existing logging and comparison flow only when a valid version is present.
- Around line 163-172: Update rhcosVersionRe used by extractRHCOSVersion to
accept the 12-digit build timestamp by removing the fixed eight-digit
requirement and matching the full numeric build segment with
(\d+\.\d+\.\d+-\d+). Preserve the existing extraction and empty-result behavior.
🪄 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: 22b2c1bd-ccf6-4b14-b617-f7906abb55e5

📥 Commits

Reviewing files that changed from the base of the PR and between cfa7a2e and 8b2073c.

📒 Files selected for processing (2)
  • test/e2e/karpenter_control_plane_upgrade_test.go
  • test/e2e/karpenter_test.go
💤 Files with no reviewable changes (1)
  • test/e2e/karpenter_test.go

Comment on lines +99 to +101
preUpgradeRHCOSVersion := extractRHCOSVersion(preUpgradeOSImage)
t.Logf("Pre-upgrade RHCOS version: %s", preUpgradeRHCOSVersion)

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.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Validate that preUpgradeRHCOSVersion is non-empty before using it for comparison.

If extractRHCOSVersion returns "" for the pre-upgrade OSImage (e.g., unexpected format), the comparison at line 116 (postVersion < preUpgradeRHCOSVersion) becomes postVersion < "", which is always false for any non-empty postVersion. The test would silently pass without actually verifying the version ordering. Add a guard after extraction.

🛡️ Proposed fix: fail fast on empty pre-upgrade version
	preUpgradeRHCOSVersion := extractRHCOSVersion(preUpgradeOSImage)
+	if preUpgradeRHCOSVersion == "" {
+		t.Fatalf("could not extract pre-upgrade RHCOS version from OS image %q", preUpgradeOSImage)
+	}
	t.Logf("Pre-upgrade RHCOS version: %s", preUpgradeRHCOSVersion)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
preUpgradeRHCOSVersion := extractRHCOSVersion(preUpgradeOSImage)
t.Logf("Pre-upgrade RHCOS version: %s", preUpgradeRHCOSVersion)
preUpgradeRHCOSVersion := extractRHCOSVersion(preUpgradeOSImage)
if preUpgradeRHCOSVersion == "" {
t.Fatalf("could not extract pre-upgrade RHCOS version from OS image %q", preUpgradeOSImage)
}
t.Logf("Pre-upgrade RHCOS version: %s", preUpgradeRHCOSVersion)
🧰 Tools
🪛 ast-grep (0.44.1)

[warning] 101-101: Narrowing a non-constant integer to a smaller fixed-width type (int8/int16/int32, uint8/uint16/uint32) can silently overflow or wrap, yielding negative or truncated values that are dangerous in size, length, or index logic. Validate the source value is within the target type's range before converting (e.g. bounds-check, or use a checked helper), and avoid narrowing untrusted or len()/parsed values.
Context: int32(replicas)
Note: [CWE-190] Integer Overflow or Wraparound.

(integer-overflow-narrowing-conversion-go)

🤖 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 `@test/e2e/karpenter_control_plane_upgrade_test.go` around lines 99 - 101,
Validate that preUpgradeRHCOSVersion returned by extractRHCOSVersion is
non-empty before the later version comparison. Add a fail-fast assertion or test
error immediately after extraction, preserving the existing logging and
comparison flow only when a valid version is present.

Comment on lines +163 to +172

var rhcosVersionRe = regexp.MustCompile(`Red Hat Enterprise Linux CoreOS (\d+\.\d+\.\d{8}-\d+)`)

func extractRHCOSVersion(osImage string) string {
matches := rhcosVersionRe.FindStringSubmatch(osImage)
if len(matches) < 2 {
return ""
}
return matches[1]
}

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.

🎯 Functional Correctness | 🔴 Critical | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify the regex against known OSImage formats from upstream test vectors
cat <<'EOF' | go run -
package main

import (
	"fmt"
	"regexp"
)

func main() {
	re := regexp.MustCompile(`Red Hat Enterprise Linux CoreOS (\d+\.\d+\.\d{8}-\d+)`)
	reFixed := regexp.MustCompile(`Red Hat Enterprise Linux CoreOS (\d+\.\d+\.\d+-\d+)`)
	cases := []string{
		"Red Hat Enterprise Linux CoreOS 419.97.202505081234-0 (Plow)",
		"Red Hat Enterprise Linux CoreOS 510.97.202506011200-0 (Plow)",
		"Red Hat Enterprise Linux CoreOS 418.94.202501011200-0 (Plow)",
	}
	for _, c := range cases {
		m := re.FindStringSubmatch(c)
		mf := reFixed.FindStringSubmatch(c)
		fmt.Printf("input: %s\n  \\d{8} match: %q\n  \\d+  match: %q\n", c, m, mf)
	}
}
EOF

Repository: openshift/hypershift

Length of output: 181


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n== target file excerpt ==\n'
sed -n '1,240p' test/e2e/karpenter_control_plane_upgrade_test.go | cat -n

printf '\n== upstream OSImage examples ==\n'
rg -n "Red Hat Enterprise Linux CoreOS" -S . | sed -n '1,120p'

Repository: openshift/hypershift

Length of output: 13631


🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
import re

re_bad = re.compile(r'Red Hat Enterprise Linux CoreOS (\d+\.\d+\.\d{8}-\d+)')
re_fixed = re.compile(r'Red Hat Enterprise Linux CoreOS (\d+\.\d+\.\d+-\d+)')

cases = [
    "Red Hat Enterprise Linux CoreOS 419.97.202505081234-0 (Plow)",
    "Red Hat Enterprise Linux CoreOS 510.97.202506011200-0 (Plow)",
    "Red Hat Enterprise Linux CoreOS 418.94.202501011200-0 (Plow)",
]
for c in cases:
    print(c)
    print(" bad  ->", re_bad.search(c).groups() if re_bad.search(c) else None)
    print(" fixed->", re_fixed.search(c).groups() if re_fixed.search(c) else None)

print("\ncall sites:")
PY

rg -n "extractRHCOSVersion|preUpgradeRHCOSVersion|postUpgradeRHCOSVersion|postVersion <|postVersion == \"\"" test/e2e/karpenter_control_plane_upgrade_test.go

Repository: openshift/hypershift

Length of output: 1121


Fix the RHCOS version regex The current pattern requires an 8-digit build timestamp, but these OSImage strings use a 12-digit timestamp (202505081234), so extractRHCOSVersion returns "" and the upgrade wait never matches. Use (\d+\.\d+\.\d+-\d+) instead.

🤖 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 `@test/e2e/karpenter_control_plane_upgrade_test.go` around lines 163 - 172,
Update rhcosVersionRe used by extractRHCOSVersion to accept the 12-digit build
timestamp by removing the fixed eight-digit requirement and matching the full
numeric build segment with (\d+\.\d+\.\d+-\d+). Preserve the existing extraction
and empty-result behavior.

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/testing Indicates the PR includes changes for e2e testing jira/valid-bug Indicates that a referenced Jira bug is valid for the branch this PR is targeting. 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.

4 participants