Skip to content

Reapply "MCO-2120: Rework OS Image Stream label classification"#5767

Open
cheesesashimi wants to merge 1 commit intoopenshift:mainfrom
cheesesashimi:zzlotnik/readd-osstream-label-changes
Open

Reapply "MCO-2120: Rework OS Image Stream label classification"#5767
cheesesashimi wants to merge 1 commit intoopenshift:mainfrom
cheesesashimi:zzlotnik/readd-osstream-label-changes

Conversation

@cheesesashimi
Copy link
Member

This reverts commit 59b22f2 and re-adds the reworked image label detection for OSImageStreams.

@openshift-ci-robot openshift-ci-robot added the jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. label Mar 16, 2026
@openshift-ci-robot
Copy link
Contributor

openshift-ci-robot commented Mar 16, 2026

@cheesesashimi: This pull request references MCO-2120 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 "4.22.0" version, but no target version was set.

Details

In response to this:

This reverts commit 59b22f2 and re-adds the reworked image label detection for OSImageStreams.

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

@coderabbitai
Copy link

coderabbitai bot commented Mar 16, 2026

Walkthrough

Refactors the OS image stream classification logic from a single hard-coded discriminator to a generalized matcher-based approach using a new ImageLabelMatcher type. Adds new label constants for extension images and bootc-based OS identification, and extends GetImageData to return nil when images cannot be classified. Test files are updated to use new label constants instead of hard-coded strings.

Changes

Cohort / File(s) Summary
Core logic refactoring
pkg/osimagestream/image_data.go
Introduces ImageLabelMatcher type and replaces single discriminator with matcher-based classification. Adds constants for extension and bootc label identification. Refactors classification switch logic and includes new helper functions labelEquals and matchesAny.
Test restructuring
pkg/osimagestream/image_data_test.go
Replaces single OS-image test with comprehensive table-driven test covering OS, Extensions, and negative classification cases. Adds test constants for label keys and values.
Test label constant updates
pkg/osimagestream/imagestream_source_test.go, pkg/osimagestream/osimagestream_test.go, pkg/osimagestream/urls_source_test.go
Replaces hard-coded label key strings with new test constants (testCoreOSLabelStreamClass, testCoreOSLabelBootc, testCoreOSLabelExtension) across multiple test cases.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
📝 Coding Plan
  • Generate coding plan for human review comments

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 golangci-lint (2.11.3)

Command failed


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

Tip

You can validate your CodeRabbit configuration file in your editor.

If your editor has YAML language server, you can enable auto-completion and validation by adding # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json at the top of your CodeRabbit configuration file.

@openshift-ci openshift-ci bot requested review from djoshy and yuqi-zhang March 16, 2026 16:31
@openshift-ci openshift-ci bot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Mar 16, 2026
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@pkg/osimagestream/image_data.go`:
- Around line 93-99: The switch currently checks matchesAny(labels,
e.osImageMatchers) before matchesAny(labels, e.extensionsImageMatchers), which
misclassifies images that have both OS and extensions labels; update the
ordering to check matchesAny(labels, e.extensionsImageMatchers) first so images
with extension markers are classified as ImageTypeExtensions, and ensure
ImageTypeOS remains fallback. Modify the logic in the same block referencing
e.osImageMatchers, e.extensionsImageMatchers, ImageTypeOS, and
ImageTypeExtensions to reflect this ordering change, and add a regression test
exercising GroupOSContainerImageMetadataToStream() with a single image that
carries both the extensions label and an OS label to assert it becomes an
extensions image (and does not produce duplicate OS images).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: f4307924-3beb-4eb8-8eb2-cec120de98a5

📥 Commits

Reviewing files that changed from the base of the PR and between 74fef05 and 360fab3.

📒 Files selected for processing (5)
  • pkg/osimagestream/image_data.go
  • pkg/osimagestream/image_data_test.go
  • pkg/osimagestream/imagestream_source_test.go
  • pkg/osimagestream/osimagestream_test.go
  • pkg/osimagestream/urls_source_test.go

Comment on lines +93 to +99
switch {
case matchesAny(labels, e.osImageMatchers):
imageData.Type = ImageTypeOS
} else {
case matchesAny(labels, e.extensionsImageMatchers):
imageData.Type = ImageTypeExtensions
default:
return nil
Copy link

@coderabbitai coderabbitai bot Mar 16, 2026

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Check extensions before OS matchers.

If an extensions image also carries containers.bootc, Line 94 classifies it as OS before Line 96 sees the extensions marker. GroupOSContainerImageMetadataToStream() then ends up with two OS images and drops the stream as incomplete. Please also add a regression case with both labels present.

Possible fix
 	switch {
-	case matchesAny(labels, e.osImageMatchers):
-		imageData.Type = ImageTypeOS
 	case matchesAny(labels, e.extensionsImageMatchers):
 		imageData.Type = ImageTypeExtensions
+	case matchesAny(labels, e.osImageMatchers):
+		imageData.Type = ImageTypeOS
 	default:
 		return nil
 	}
📝 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
switch {
case matchesAny(labels, e.osImageMatchers):
imageData.Type = ImageTypeOS
} else {
case matchesAny(labels, e.extensionsImageMatchers):
imageData.Type = ImageTypeExtensions
default:
return nil
switch {
case matchesAny(labels, e.extensionsImageMatchers):
imageData.Type = ImageTypeExtensions
case matchesAny(labels, e.osImageMatchers):
imageData.Type = ImageTypeOS
default:
return nil
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/osimagestream/image_data.go` around lines 93 - 99, The switch currently
checks matchesAny(labels, e.osImageMatchers) before matchesAny(labels,
e.extensionsImageMatchers), which misclassifies images that have both OS and
extensions labels; update the ordering to check matchesAny(labels,
e.extensionsImageMatchers) first so images with extension markers are classified
as ImageTypeExtensions, and ensure ImageTypeOS remains fallback. Modify the
logic in the same block referencing e.osImageMatchers,
e.extensionsImageMatchers, ImageTypeOS, and ImageTypeExtensions to reflect this
ordering change, and add a regression test exercising
GroupOSContainerImageMetadataToStream() with a single image that carries both
the extensions label and an OS label to assert it becomes an extensions image
(and does not produce duplicate OS images).

Copy link
Contributor

Choose a reason for hiding this comment

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

then ends up with two OS images and drops the stream as incomplete

And that's exactly what we want for a malformed image set. This is fine.

Copy link

Choose a reason for hiding this comment

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

@pablintino, understood — an image carrying both containers.bootc and io.openshift.os.extensions is considered malformed, and letting it be classified as OS (resulting in two OS images and the stream being silently dropped by GroupOSContainerImageMetadataToStream) is the intentional handling. I'll retract my concern.

(^・o・^)ノ"


📝 Learnings were identified and not saved (knowledge base disabled). Enable

@pablintino
Copy link
Contributor

/retest-required

1 similar comment
@pablintino
Copy link
Contributor

/retest-required

@pablintino
Copy link
Contributor

/lgtm

@openshift-ci openshift-ci bot added the lgtm Indicates that a PR is ready to be merged. label Mar 17, 2026
@openshift-ci
Copy link
Contributor

openshift-ci bot commented Mar 17, 2026

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: cheesesashimi, pablintino

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:
  • OWNERS [cheesesashimi,pablintino]

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@ptalgulk01
Copy link

Pre-merge tested:

Environment Variable:
Platform: AWS
Version: 4.22.0-0-2026-03-18-043113-test-ci-ln-5ytmki2-latest

Steps:

  • Get the image references from the stream
$ oc get osimagestream cluster -o json | jq '.status.availableStreams'
[
  {
    "name": "rhel-9",
    "osExtensionsImage": "registry.build11.ci.openshift.org/ci-ln-5ytmki2/stable@sha256:35b261673caa1bc92861d3f85ab549fe5e175246646aaca9baddbccd6281676d",
    "osImage": "registry.build11.ci.openshift.org/ci-ln-5ytmki2/stable@sha256:fe9b41b68fa15547b45123785f14ca88828c8442a9882334b34da13f0b14c360"
  },
  {
    "name": "rhel-10",
    "osExtensionsImage": "registry.build11.ci.openshift.org/ci-ln-5ytmki2/stable@sha256:8aadae660efea658d5b14c5a1d381983ab882ee5126227291f6835e4c089f753",
    "osImage": "registry.build11.ci.openshift.org/ci-ln-5ytmki2/stable@sha256:4740daf76d0919be012ec8c26a496230bc5e455fa2a63bbd692c670b8b1e4745"
  }
]
  • Inspect OS image labels
$ oc image info --filter-by-os linux/amd64 -o json \
        "registry.build11.ci.openshift.org/ci-ln-5ytmki2/stable@sha256:fe9b41b68fa15547b45123785f14ca88828c8442a9882334b34da13f0b14c360" \
        2>/dev/null | jq '.config.config.Labels | {
          "containers.bootc": .["containers.bootc"],
          "ostree.linux": .["ostree.linux"],
          "io.openshift.os.streamclass": .["io.openshift.os.streamclass"],
          "io.openshift.os.extensions": .["io.openshift.os.extensions"]
        }'
{
  "containers.bootc": "1",
  "ostree.linux": "true",
  "io.openshift.os.streamclass": "rhel-9",
  "io.openshift.os.extensions": null
}

$ oc image info --filter-by-os linux/amd64 -o json \
        "registry.build11.ci.openshift.org/ci-ln-5ytmki2/stable@sha256:35b261673caa1bc92861d3f85ab549fe5e175246646aaca9baddbccd6281676d" \
        2>/dev/null | jq '.config.config.Labels | {
          "containers.bootc": .["containers.bootc"],
          "ostree.linux": .["ostree.linux"],
          "io.openshift.os.streamclass": .["io.openshift.os.streamclass"],
          "io.openshift.os.extensions": .["io.openshift.os.extensions"]
        }'
{
  "containers.bootc": null,
  "ostree.linux": null,
  "io.openshift.os.streamclass": "rhel-9",
  "io.openshift.os.extensions": "true"
}

$ oc image info --filter-by-os linux/amd64 -o json \
        "registry.build11.ci.openshift.org/ci-ln-5ytmki2/stable@sha256:4740daf76d0919be012ec8c26a496230bc5e455fa2a63bbd692c670b8b1e4745" \
        2>/dev/null | jq '.config.config.Labels | {
          "containers.bootc": .["containers.bootc"],
          "ostree.linux": .["ostree.linux"],
          "io.openshift.os.streamclass": .["io.openshift.os.streamclass"],
          "io.openshift.os.extensions": .["io.openshift.os.extensions"]
        }'
{
  "containers.bootc": "1",
  "ostree.linux": "true",
  "io.openshift.os.streamclass": "rhel-10",
  "io.openshift.os.extensions": null
}

$ oc image info --filter-by-os linux/amd64 -o json \
        "registry.build11.ci.openshift.org/ci-ln-5ytmki2/stable@sha256:8aadae660efea658d5b14c5a1d381983ab882ee5126227291f6835e4c089f753" \
        2>/dev/null | jq '.config.config.Labels | {
          "containers.bootc": .["containers.bootc"],
          "ostree.linux": .["ostree.linux"],
          "io.openshift.os.streamclass": .["io.openshift.os.streamclass"],
          "io.openshift.os.extensions": .["io.openshift.os.extensions"]
        }'
{
  "containers.bootc": null,
  "ostree.linux": null,
  "io.openshift.os.streamclass": "rhel-10",
  "io.openshift.os.extensions": "true"
}

@ptalgulk01
Copy link

/label qe-approved
/verified by @ptalgulk01

@openshift-ci openshift-ci bot added the qe-approved Signifies that QE has signed off on this PR label Mar 19, 2026
@openshift-ci-robot
Copy link
Contributor

openshift-ci-robot commented Mar 19, 2026

@cheesesashimi: This pull request references MCO-2120 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 "4.22.0" version, but no target version was set.

Details

In response to this:

This reverts commit 59b22f2 and re-adds the reworked image label detection for OSImageStreams.

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 added the verified Signifies that the PR passed pre-merge verification criteria label Mar 19, 2026
@openshift-ci-robot
Copy link
Contributor

@ptalgulk01: This PR has been marked as verified by @ptalgulk01.

Details

In response to this:

/label qe-approved
/verified by @ptalgulk01

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.

@pablintino
Copy link
Contributor

/test e2e-aws-ovn-upgrade
/test security

@openshift-ci
Copy link
Contributor

openshift-ci bot commented Mar 19, 2026

@cheesesashimi: 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-hypershift 360fab3 link unknown /test e2e-hypershift
ci/prow/e2e-aws-ovn-upgrade 360fab3 link true /test e2e-aws-ovn-upgrade

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.

@openshift-ci
Copy link
Contributor

openshift-ci bot commented Mar 19, 2026

PR needs rebase.

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.

@openshift-ci openshift-ci bot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Mar 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved Indicates a PR has been approved by an approver from all required OWNERS files. 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. needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. qe-approved Signifies that QE has signed off on this PR verified Signifies that the PR passed pre-merge verification criteria

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants