Skip to content

MCO-1906: Add Extra Validations - #6353

Closed
anandram2 wants to merge 1 commit into
openshift:mainfrom
anandram2:add-extra-validations
Closed

MCO-1906: Add Extra Validations #6353
anandram2 wants to merge 1 commit into
openshift:mainfrom
anandram2:add-extra-validations

Conversation

@anandram2

@anandram2 anandram2 commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

- What I did

  • validates the OCP version by fetching the os release file, then checking for a digest comparison against the clusters resolved base OS image when thats not available
  • Verifies registry accessibility as a side effect if it is not able to fetch the image at both steps
  • Extracted a shared newSysContextFactory helper and added an injectable imagesInspectorFactory on Bootstrap for testability.
  • Added unit tests covering version match/mismatch, digest fallback, missing-label warn-through, and registry-failure cases.

- How to verify it

-go test ./pkg/controller/bootstrap/...

or

  • Seed a MachineOSConfig with the machineconfiguration.openshift.io/pre-built-image annotation pointing at a digested image whose /etc/os-release OPENSHIFT_VERSION doesn't match the cluster's release version, bootstrap should fail with an error like pre-built image "..." OCP version "X.Y" does not match the cluster's OCP version "A.B".
  • Point the annotation at an unreachable/nonexistent registry, bootstrap should fail with could not access pre-built image "..." (registry unreachable or image not found): ....
  • Point the annotation at a correctly-versioned pre-built image, bootstrap should succeed as before.

- Description for the changelog
Add OCP-version-match and registry-accessibility validation for hybrid-OCL pre-built images at bootstrap time
MCO-1906

Summary by CodeRabbit

  • New Features
    • Added pre-built image validation during bootstrap, including OpenShift major/minor checks and digest-based fallback when the version can’t be determined.
  • Bug Fixes
    • OSImageStream bootstrapping is now controlled only by the OSStreams feature gate (removes prior mode-based exclusion).
    • Hardened bootstrap and generated-rendering logic so registry/image inspection failures block invalid configuration.
    • Improved MachineConfigPool “Updating” status reporting for layered/image-based pools.
  • Tests
    • Expanded coverage for image inspection/version/digest validation and OS stream label handling.

@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 Jul 30, 2026
@openshift-ci-robot

openshift-ci-robot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

@anandram2: This pull request references MCO-1906 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:

- What I did

  • validates the OCP version by fetching the os release file, then checking for a digest comparison against the clusters resolved base OS image when thats not available
  • Verifies registry accessibility as a side effect if it is not able to fetch the image at both steps
  • Extracted a shared newSysContextFactory helper and added an injectable imagesInspectorFactory on Bootstrap for testability.
  • Added unit tests covering version match/mismatch, digest fallback, missing-label warn-through, and registry-failure cases.

- How to verify it

-go test ./pkg/controller/bootstrap/...

or

  • Seed a MachineOSConfig with the machineconfiguration.openshift.io/pre-built-image annotation pointing at a digested image whose /etc/os-release OPENSHIFT_VERSION doesn't match the cluster's release version, bootstrap should fail with an error like pre-built image "..." OCP version "X.Y" does not match the cluster's OCP version "A.B".
  • Point the annotation at an unreachable/nonexistent registry, bootstrap should fail with could not access pre-built image "..." (registry unreachable or image not found): ....
  • Point the annotation at a correctly-versioned pre-built image, bootstrap should succeed as before.

- Description for the changelog
Add OCP-version-match and registry-accessibility validation for hybrid-OCL pre-built images at bootstrap time
MCO-1906

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 needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Jul 30, 2026
@openshift-ci

openshift-ci Bot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

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 commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: anandram2
Once this PR has been reviewed and has the lgtm label, please assign proietfb for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

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

@coderabbitai

coderabbitai Bot commented Jul 30, 2026

Copy link
Copy Markdown

Caution

Review failed

The pull request is closed.

Walkthrough

Bootstrap now validates pre-built images during hybrid OCL setup using OpenShift version metadata with base-image digest fallback. The change also adds injectable image inspection, Containerfile validation, stream-aware rendering, expanded build status reporting, dependency updates, and broader controller and end-to-end test coverage.

Changes

Image inspection and bootstrap/render integration

Layer / File(s) Summary
Bootstrap image validation
pkg/controller/bootstrap/bootstrap.go, pkg/controller/bootstrap/bootstrap_test.go
Adds injectable image inspection, shared system-context construction, OpenShift version validation, digest fallback, and related test coverage.
OS stream inspection and render wiring
pkg/osimagestream/*, pkg/controller/render/*, pkg/controller/common/*, cmd/machine-config-controller/start.go
Adds stream-class inspection, passes inspectors through render and bootstrap paths, and validates overridden OS image URLs.
OSImageStream controller refactoring
pkg/controller/osimagestream/osimagestream_controller.go, pkg/osimagestream/helpers.go
Centralizes system-context creation and gates OSImageStreams solely on the feature gate.

Containerfile validation and build status

Layer / File(s) Summary
Containerfile validation
pkg/controller/build/buildrequest/*
Validates parsed Containerfile syntax, instruction arguments, malformed ENV/LABEL entries, and unknown instructions.
Build failure status handling
pkg/controller/build/reconciler.go
Marks MachineOSBuild objects failed when rendered Containerfile validation fails without propagating that typed validation error.

MachineOSBuild status and test coverage

Layer / File(s) Summary
Build-state reporting
pkg/controller/node/status.go, test/helpers/machineosbuildbuilder.go
Reports active, paused, successful, failed, interrupted, and initial MachineOSBuild states in MCP Updating conditions.
Controller and end-to-end tests
pkg/controller/bootimage/*, test/e2e-ocl-2of2/*, test/extended-priv/*
Adds OS stream, paused MCP, network policy, password configuration, stream-aware image resolution, cleanup, and resource deletion coverage.

Toolchain and dependency updates

Layer / File(s) Summary
Go and module updates
go.mod
Updates the Go toolchain directive and a broad set of direct and indirect module versions.

Estimated code review effort: 4 (Complex) | ~60 minutes

Possibly related PRs

Suggested labels: do-not-merge/hold

Suggested reviewers: umohnani8, isabella-janssen


Important

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

❌ Failed checks (1 error, 1 warning, 1 inconclusive)

Check name Status Explanation Resolution
No-Sensitive-Data-In-Logs ❌ Error PR adds klog warnings/info that print pre-built image URLs/OSImageURL, which can include internal registry hostnames. Remove or redact image refs from logs; log only opaque IDs or sanitized registry names, and keep fallback details out of warnings/info.
Test Structure And Quality ⚠️ Warning The new tests are focused, but many assertions are bare require.NoError/Error/Len calls without diagnostic messages, violating the review requirement. Add descriptive failure messages to the key assertions (especially errors/length checks) and split any broad test cases if needed.
Title check ❓ Inconclusive The title is related to the change, but "Add Extra Validations" is too vague to describe the specific bootstrap image validation work. Rename it to mention the main change, such as bootstrap validation for hybrid-OCL pre-built images or OCP version/digest checks.
✅ Passed checks (12 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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 All added test titles are static strings or fixed literals (e.g. master/worker); none contain generated IDs, timestamps, IPs, or other run-specific data.
Microshift Test Compatibility ✅ Passed Added tests are plain Go unit tests, not Ginkgo e2e tests, and they don't use MicroShift-unsupported APIs.
Single Node Openshift (Sno) Test Compatibility ✅ Passed No new Ginkgo e2e tests were added; bootstrap_test.go is standard unit tests and shows no multi-node/HA assumptions or SNO-specific skips needed.
Topology-Aware Scheduling Compatibility ✅ Passed Only bootstrap image-validation logic and tests changed; no pod specs, replicas, affinity, node selectors, or topology-based scheduling constraints were added.
Ote Binary Stdout Contract ✅ Passed The patch only changes library code and test helpers; no main/init/TestMain/RunSpecs setup or direct stdout writes were added in the modified files.
Ipv6 And Disconnected Network Test Compatibility ✅ Passed No new Ginkgo/e2e tests were added; bootstrap_test.go uses plain Go tests and only mocks image access, with no IPv4 assumptions or external connectivity requirements.
No-Weak-Crypto ✅ Passed No weak crypto is introduced: the code only accepts SHA256 digests, and the sole MD5 reference is a negative test case.
Container-Privileges ✅ Passed PR only changes bootstrap.go and its tests; no container/K8s manifests or privileged settings (privileged, hostPID, hostNetwork, hostIPC, allowPrivilegeEscalation, SYS_ADMIN) were added.
✨ Finishing Touches 💡 2
⚔️ Resolve merge conflicts 💡
  • Resolve merge conflict in branch add-extra-validations
🛠️ Fix failing CI checks 💡
  • Fix failing CI checks
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

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 (2)
pkg/controller/bootstrap/bootstrap.go (2)

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

Surface the version-check bailout at default verbosity.

When FetchImageFile fails (auth, transport, missing file), the reason is only logged at V(4), so in a real install log you see neither why the primary check was skipped nor that validation degraded to a digest comparison. klog.Warningf would make this diagnosable without extra verbosity.

🤖 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 `@pkg/controller/bootstrap/bootstrap.go` around lines 834 - 846, The fallback
log in validatePreBuiltImageVersion should be visible at default verbosity.
Replace the V(4) Infof call that reports openshiftVersionFromImage failure with
klog.Warningf, preserving the existing message and versionErr details.

361-367: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Shared 1-minute deadline covers every pre-built image validation.

preBuiltImageCtx is a single 1-minute budget for all machineOSConfigs, and each validation does a remote FetchImageFile (layer fetch) plus a possible Inspect. With multiple pools or slow/mirrored registries this can time out and hard-fail bootstrap. Consider a per-image timeout (or a budget scaled by len(machineOSConfigs)).

🤖 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 `@pkg/controller/bootstrap/bootstrap.go` around lines 361 - 367, Update the
pre-built image validation flow around createPreBuiltImageMachineConfigs so each
machineOSConfig validation receives its own timeout, or scale the overall
deadline according to the number of machineOSConfigs. Ensure remote
FetchImageFile and Inspect operations for every image have sufficient
independent time to complete instead of sharing a fixed one-minute budget.
🤖 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 `@pkg/controller/bootstrap/bootstrap.go`:
- Around line 806-825: Update validatePreBuiltImageDigestFallback so an invalid
or non-digested expectedBaseOSImage logs a warning and skips verification
instead of returning an error, matching the missing-label behavior; retain fatal
errors for invalid label digests and mismatched digests. Update the
corresponding invalid expected base OS image case in
TestValidatePreBuiltImageDigestFallback to assert the fallback succeeds.

---

Nitpick comments:
In `@pkg/controller/bootstrap/bootstrap.go`:
- Around line 834-846: The fallback log in validatePreBuiltImageVersion should
be visible at default verbosity. Replace the V(4) Infof call that reports
openshiftVersionFromImage failure with klog.Warningf, preserving the existing
message and versionErr details.
- Around line 361-367: Update the pre-built image validation flow around
createPreBuiltImageMachineConfigs so each machineOSConfig validation receives
its own timeout, or scale the overall deadline according to the number of
machineOSConfigs. Ensure remote FetchImageFile and Inspect operations for every
image have sufficient independent time to complete instead of sharing a fixed
one-minute budget.
🪄 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: openshift/coderabbit/.coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: e4a05e7d-d1f0-42af-87ac-f974d53dbb1d

📥 Commits

Reviewing files that changed from the base of the PR and between 23687b4 and 534ef0e.

📒 Files selected for processing (2)
  • pkg/controller/bootstrap/bootstrap.go
  • pkg/controller/bootstrap/bootstrap_test.go

Comment on lines +806 to +825
func validatePreBuiltImageDigestFallback(labels map[string]string, imageSpec, expectedBaseOSImage string) error {
label := labels[preBuiltImageBaseOSLabelKey]
if label == "" {
klog.Warningf("pre-built image %q has no OPENSHIFT_VERSION and no %q label; skipping version verification", imageSpec, preBuiltImageBaseOSLabelKey)
return nil
}
labelDigest, err := imageDigest(label)
if err != nil {
return fmt.Errorf("pre-built image %q has an invalid %q label: %w", imageSpec, preBuiltImageBaseOSLabelKey, err)
}
expectedDigest, err := imageDigest(expectedBaseOSImage)
if err != nil {
return fmt.Errorf("cluster's resolved base OS image %q is invalid: %w", expectedBaseOSImage, err)
}
if labelDigest != expectedDigest {
return fmt.Errorf("pre-built image %q base OS image %q (digest %s) does not match the cluster's resolved base OS image %q (digest %s)",
imageSpec, label, labelDigest, expectedBaseOSImage, expectedDigest)
}
return nil
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Non-digested cluster base OS image makes fallback fatal.

expectedBaseOSImage comes from cconfig.Spec.BaseOSContainerImage, which is not guaranteed to be digested — the OSImageStream override in Run can set a tagged reference (the bootstrap testdata itself uses registry.host.com/os:latest). In that case imageDigest fails and the whole install fails on a condition the user can't act on, even though the pre-built image may be perfectly valid. Given the missing-label case only warns, treating an unverifiable cluster reference the same way seems more consistent.

♻️ Suggested change
 	expectedDigest, err := imageDigest(expectedBaseOSImage)
 	if err != nil {
-		return fmt.Errorf("cluster's resolved base OS image %q is invalid: %w", expectedBaseOSImage, err)
+		klog.Warningf("cluster's resolved base OS image %q is not digested (%v); skipping digest verification for pre-built image %q", expectedBaseOSImage, err, imageSpec)
+		return nil
 	}

Note this would need the corresponding invalid expected base OS image case in TestValidatePreBuiltImageDigestFallback (bootstrap_test.go Lines 573-580) updated.

📝 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
func validatePreBuiltImageDigestFallback(labels map[string]string, imageSpec, expectedBaseOSImage string) error {
label := labels[preBuiltImageBaseOSLabelKey]
if label == "" {
klog.Warningf("pre-built image %q has no OPENSHIFT_VERSION and no %q label; skipping version verification", imageSpec, preBuiltImageBaseOSLabelKey)
return nil
}
labelDigest, err := imageDigest(label)
if err != nil {
return fmt.Errorf("pre-built image %q has an invalid %q label: %w", imageSpec, preBuiltImageBaseOSLabelKey, err)
}
expectedDigest, err := imageDigest(expectedBaseOSImage)
if err != nil {
return fmt.Errorf("cluster's resolved base OS image %q is invalid: %w", expectedBaseOSImage, err)
}
if labelDigest != expectedDigest {
return fmt.Errorf("pre-built image %q base OS image %q (digest %s) does not match the cluster's resolved base OS image %q (digest %s)",
imageSpec, label, labelDigest, expectedBaseOSImage, expectedDigest)
}
return nil
}
func validatePreBuiltImageDigestFallback(labels map[string]string, imageSpec, expectedBaseOSImage string) error {
label := labels[preBuiltImageBaseOSLabelKey]
if label == "" {
klog.Warningf("pre-built image %q has no OPENSHIFT_VERSION and no %q label; skipping version verification", imageSpec, preBuiltImageBaseOSLabelKey)
return nil
}
labelDigest, err := imageDigest(label)
if err != nil {
return fmt.Errorf("pre-built image %q has an invalid %q label: %w", imageSpec, preBuiltImageBaseOSLabelKey, err)
}
expectedDigest, err := imageDigest(expectedBaseOSImage)
if err != nil {
klog.Warningf("cluster's resolved base OS image %q is not digested (%v); skipping digest verification for pre-built image %q", expectedBaseOSImage, err, imageSpec)
return nil
}
if labelDigest != expectedDigest {
return fmt.Errorf("pre-built image %q base OS image %q (digest %s) does not match the cluster's resolved base OS image %q (digest %s)",
imageSpec, label, labelDigest, expectedBaseOSImage, expectedDigest)
}
return nil
}
🤖 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 `@pkg/controller/bootstrap/bootstrap.go` around lines 806 - 825, Update
validatePreBuiltImageDigestFallback so an invalid or non-digested
expectedBaseOSImage logs a warning and skips verification instead of returning
an error, matching the missing-label behavior; retain fatal errors for invalid
label digests and mismatched digests. Update the corresponding invalid expected
base OS image case in TestValidatePreBuiltImageDigestFallback to assert the
fallback succeeds.

Merges latest main (inspectorFactory/buildSysContextFactory refactor,
render.RunBootstrap signature change) and adapts the pre-built image
validation for hybrid OCL to use the shared inspector factory.
@anandram2
anandram2 force-pushed the add-extra-validations branch from 534ef0e to 0eb2602 Compare July 30, 2026 18:49
@openshift-ci

openshift-ci Bot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

@anandram2: 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/okd-scos-images 0eb2602 link true /test okd-scos-images
ci/prow/verify-deps 0eb2602 link true /test verify-deps
ci/prow/unit 0eb2602 link true /test unit
ci/prow/security 0eb2602 link false /test security
ci/prow/bootstrap-unit 0eb2602 link true /test bootstrap-unit
ci/prow/images 0eb2602 link true /test images
ci/prow/verify 0eb2602 link true /test verify

Full PR test history. Your PR dashboard.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants