Skip to content

OCPNODE-4074: Add additional storage configuration support for CRI-O#5666

Merged
openshift-merge-bot[bot] merged 1 commit intoopenshift:mainfrom
saschagrunert:additional-storage-config-crio
Mar 17, 2026
Merged

OCPNODE-4074: Add additional storage configuration support for CRI-O#5666
openshift-merge-bot[bot] merged 1 commit intoopenshift:mainfrom
saschagrunert:additional-storage-config-crio

Conversation

@saschagrunert
Copy link
Copy Markdown
Member

@saschagrunert saschagrunert commented Feb 17, 2026

- What I did

Implement MCO support for the AdditionalStorageConfig feature gate, adding three new ContainerRuntimeConfig fields:

  • additionalLayerStores: configures extra read-only layer stores in storage.conf
  • additionalImageStores: configures extra read-only image stores in storage.conf
  • additionalArtifactStores: configures extra artifact stores via CRI-O drop-in

All fields are gated behind the AdditionalStorageConfig feature gate (DevPreviewNoUpgrade/TechPreviewNoUpgrade) in both the controller and bootstrap code paths, including internal gating in updateStorageConfig and createCRIODropinFiles helpers. Path validation (absolute paths, allowed character set, no consecutive forward slashes) runs regardless of gate state to catch invalid config early. Also fixes pre-existing klog format bugs. Bumps openshift/api to include the merged StorePath API types.

Refers to: openshift/enhancements#1934
Jira: https://issues.redhat.com/browse/OCPNODE-4074

- How to verify it

Unit tests cover storage config generation, CRI-O drop-in creation, path validation, and feature gate gating (both enabled and disabled). E2E tests will follow in a separate PR.

- Description for the changelog

Added support for configuring additional layer, image, and artifact stores via ContainerRuntimeConfig, gated behind the AdditionalStorageConfig feature gate.

@openshift-ci openshift-ci bot added the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Feb 17, 2026
@saschagrunert saschagrunert force-pushed the additional-storage-config-crio branch 2 times, most recently from ad2ac06 to d28f84f Compare February 17, 2026 10:27
@saschagrunert saschagrunert changed the title WIP: Add additional storage configuration support for CRI-O Add additional storage configuration support for CRI-O Mar 4, 2026
@openshift-ci openshift-ci bot removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Mar 4, 2026
@saschagrunert saschagrunert force-pushed the additional-storage-config-crio branch 6 times, most recently from f8f2e95 to 39db941 Compare March 5, 2026 09:08
Comment thread pkg/controller/container-runtime-config/container_runtime_config_bootstrap.go Outdated
@haircommander
Copy link
Copy Markdown
Member

couple of nits, but they can be ignored methinks. LGTM generally

@saschagrunert saschagrunert force-pushed the additional-storage-config-crio branch from 39db941 to b634714 Compare March 5, 2026 14:47
Comment thread pkg/controller/container-runtime-config/helpers.go
@saschagrunert saschagrunert force-pushed the additional-storage-config-crio branch from b634714 to dd5ad73 Compare March 5, 2026 15:07
@saschagrunert saschagrunert changed the title Add additional storage configuration support for CRI-O OCPNODE-4074: Add additional storage configuration support for CRI-O Mar 5, 2026
@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 5, 2026
@openshift-ci-robot
Copy link
Copy Markdown
Contributor

openshift-ci-robot commented Mar 5, 2026

@saschagrunert: This pull request references OCPNODE-4074 which is a valid jira issue.

Details

In response to this:

- What I did

Implement MCO support for the AdditionalStorageConfig feature gate, adding three new ContainerRuntimeConfig fields:

  • additionalLayerStores: configures extra read-only layer stores in storage.conf
  • additionalImageStores: configures extra read-only image stores in storage.conf
  • additionalArtifactStores: configures extra artifact stores via CRI-O drop-in

All fields are gated behind the AdditionalStorageConfig feature gate (DevPreviewNoUpgrade/TechPreviewNoUpgrade) in both the controller and bootstrap code paths, including internal gating in updateStorageConfig and createCRIODropinFiles helpers. Path validation (absolute paths, allowed character set, no consecutive forward slashes) runs regardless of gate state to catch invalid config early. Also fixes pre-existing klog format bugs. Bumps openshift/api to include the merged StorePath API types.

Refers to: openshift/enhancements#1934
Jira: https://issues.redhat.com/browse/OCPNODE-4074

- How to verify it

Unit tests cover storage config generation, CRI-O drop-in creation, path validation, and feature gate gating (both enabled and disabled). E2E tests will follow in a separate PR.

- Description for the changelog

Added support for configuring additional layer, image, and artifact stores via ContainerRuntimeConfig, gated behind the AdditionalStorageConfig feature gate.

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.

Copy link
Copy Markdown
Member

@QiWang19 QiWang19 left a comment

Choose a reason for hiding this comment

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

/lgtm

@haircommander
Copy link
Copy Markdown
Member

/approve
/lgtm

@openshift-ci openshift-ci bot added the lgtm Indicates that a PR is ready to be merged. label Mar 5, 2026
@saschagrunert
Copy link
Copy Markdown
Member Author

@dkhater-redhat
Copy link
Copy Markdown
Contributor

/hold

We have a kube rebase in the pipeline that's high priority. Will unhold once that merges.

@openshift-ci openshift-ci bot added the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Mar 6, 2026
@isabella-janssen
Copy link
Copy Markdown
Member

/unhold

Kube rebase landed, so this can go whenever it is ready now.

@openshift-ci openshift-ci bot removed the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Mar 13, 2026
@openshift-merge-robot openshift-merge-robot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Mar 13, 2026
Extract helper functions for storage and CRI-O drop-in condition
checks to deduplicate logic between controller and bootstrap paths.

Signed-off-by: Sascha Grunert <sgrunert@redhat.com>
@saschagrunert saschagrunert force-pushed the additional-storage-config-crio branch from dd5ad73 to 2dd1904 Compare March 13, 2026 19:12
@openshift-ci openshift-ci bot removed the lgtm Indicates that a PR is ready to be merged. label Mar 13, 2026
@saschagrunert
Copy link
Copy Markdown
Member Author

/unhold

Kube rebase landed, so this can go whenever it is ready now.

Thanks! Rebased on top of the latest main branch.

@openshift-merge-robot openshift-merge-robot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Mar 13, 2026
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 13, 2026

Walkthrough

This PR implements feature-gated support for additional container runtime storage configuration. It propagates a feature gates handler through bootstrap and controller layers, introduces conditional logic for storage and CRI-O drop-in updates based on the AdditionalStorageConfig feature gate, extends CRIO configuration to support additional artifact stores, adds path validation for storage entries, and includes comprehensive test coverage for both gated and ungated scenarios.

Changes

Cohort / File(s) Summary
Manifest and Dependency Updates
examples/containerruntimeconfig.crd.yaml, go.mod
Adds a new ContainerRuntimeConfig resource example with additionalLayerStores, additionalImageStores, and additionalArtifactStores fields. Updates github.com/openshift/api dependency version.
Bootstrap Layer
pkg/controller/bootstrap/bootstrap.go, pkg/controller/container-runtime-config/container_runtime_config_bootstrap.go, pkg/controller/container-runtime-config/container_runtime_config_bootstrap_test.go
Propagates fgHandler parameter through RunContainerRuntimeBootstrap signature, wires feature-gate logic for storage and CRI-O drop-in updates, replaces direct condition checks with needsStorageUpdate and needsCRIODropinUpdate guards.
Controller Layer
pkg/controller/container-runtime-config/container_runtime_config_controller.go, pkg/controller/container-runtime-config/container_runtime_config_controller_test.go
Adds additionalStorageConfigEnabled() method to check feature gate state, guards storage and CRI-O drop-in operations with conditionals, includes new tests validating behavior with feature gate enabled and disabled.
Helper Functions and Validation
pkg/controller/container-runtime-config/helpers.go, pkg/controller/container-runtime-config/helpers_test.go
Introduces needsStorageUpdate and needsCRIODropinUpdate functions, adds tomlConfigCRIOAdditionalArtifactStores type, updates updateStorageConfig and createCRIODropinFiles signatures to accept additionalStorageEnabled flag, adds validateStorePath validation with regex enforcement. Extends test coverage with additional store, artifact store, and path validation tests.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 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

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

Tip

You can make CodeRabbit's review stricter and more nitpicky using the `assertive` profile, if that's what you prefer.

Change the reviews.profile setting to assertive to make CodeRabbit's nitpick more issues in your PRs.

@QiWang19
Copy link
Copy Markdown
Member

/lgtm

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

@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/controller/container-runtime-config/container_runtime_config_controller.go`:
- Around line 366-368: The controller currently only checks the feature gate in
additionalStorageConfigEnabled()
(ctrl.fgHandler.Enabled(features.FeatureGateAdditionalStorageConfig) in
ContainerRuntimeConfig controller) but does not watch FeatureGate changes, so
flipping the gate later won't re-enqueue existing ContainerRuntimeConfig CRs;
either add a FeatureGate watch and enqueue existing ContainerRuntimeConfig
objects on FeatureGate change (follow the kubelet controller pattern: add a
FeatureGate informer/handler and enqueue relevant CRs when FeatureGate toggles)
or enforce the gate at admission/reconcile by rejecting or clearing gated fields
when FeatureGateAdditionalStorageConfig is disabled (validate/return error in
the create/update path or strip/reject the additional storage fields in
reconcile), and apply the same change to the other gated-field handling code
paths referenced around the other gated-field helpers in this file.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 006f35d2-b0fb-44c3-ab3e-f225056ac8a3

📥 Commits

Reviewing files that changed from the base of the PR and between 5f0d9d7 and 2dd1904.

⛔ Files ignored due to path filters (14)
  • go.sum is excluded by !**/*.sum
  • vendor/github.com/openshift/api/AGENTS.md is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/api/features.md is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/api/features/features.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/api/machineconfiguration/v1/types.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/api/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_containerruntimeconfigs-CustomNoUpgrade.crd.yaml is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/api/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_containerruntimeconfigs-Default.crd.yaml is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/api/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_containerruntimeconfigs-DevPreviewNoUpgrade.crd.yaml is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/api/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_containerruntimeconfigs-OKD.crd.yaml is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/api/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_containerruntimeconfigs-TechPreviewNoUpgrade.crd.yaml is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/api/machineconfiguration/v1/zz_generated.deepcopy.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/api/machineconfiguration/v1/zz_generated.featuregated-crd-manifests.yaml is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/api/machineconfiguration/v1/zz_generated.swagger_doc_generated.go is excluded by !vendor/**, !**/vendor/**
  • vendor/modules.txt is excluded by !vendor/**, !**/vendor/**
📒 Files selected for processing (9)
  • examples/containerruntimeconfig.crd.yaml
  • go.mod
  • pkg/controller/bootstrap/bootstrap.go
  • pkg/controller/container-runtime-config/container_runtime_config_bootstrap.go
  • pkg/controller/container-runtime-config/container_runtime_config_bootstrap_test.go
  • pkg/controller/container-runtime-config/container_runtime_config_controller.go
  • pkg/controller/container-runtime-config/container_runtime_config_controller_test.go
  • pkg/controller/container-runtime-config/helpers.go
  • pkg/controller/container-runtime-config/helpers_test.go

Comment on lines +366 to +368
func (ctrl *Controller) additionalStorageConfigEnabled() bool {
return ctrl.fgHandler.Enabled(features.FeatureGateAdditionalStorageConfig)
}
Copy link
Copy Markdown

@coderabbitai coderabbitai bot Mar 13, 2026

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Re-enabling AdditionalStorageConfig will not reprocess existing CRs.

This only samples the gate during reconcile, but this controller never watches FeatureGate changes and FeatureGatesHandler is read-only. A ContainerRuntimeConfig created while the gate is off becomes a no-op/empty MC, and flipping the gate on later will not enqueue it again, so the additional stores stay unapplied until the CR is edited. Please either add a FeatureGate trigger here (similar to the kubelet controller pattern) or reject these gated fields while the gate is disabled.

Also applies to: 760-776

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@pkg/controller/container-runtime-config/container_runtime_config_controller.go`
around lines 366 - 368, The controller currently only checks the feature gate in
additionalStorageConfigEnabled()
(ctrl.fgHandler.Enabled(features.FeatureGateAdditionalStorageConfig) in
ContainerRuntimeConfig controller) but does not watch FeatureGate changes, so
flipping the gate later won't re-enqueue existing ContainerRuntimeConfig CRs;
either add a FeatureGate watch and enqueue existing ContainerRuntimeConfig
objects on FeatureGate change (follow the kubelet controller pattern: add a
FeatureGate informer/handler and enqueue relevant CRs when FeatureGate toggles)
or enforce the gate at admission/reconcile by rejecting or clearing gated fields
when FeatureGateAdditionalStorageConfig is disabled (validate/return error in
the create/update path or strip/reject the additional storage fields in
reconcile), and apply the same change to the other gated-field handling code
paths referenced around the other gated-field helpers in this file.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

hmm @saschagrunert this seems legit to me, PTAL?

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Seems like the humans are having a chat. I'll hop back into my burrow for now. If you need me again, just tag @coderabbitai in a new comment, and I'll come hopping out!

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

@coderabbitai

The FeatureGatesHandler is read-only and populated once during Connect(). It does not update dynamically when the FeatureGate CR changes at runtime. The kubelet controller's featInformer watch serves a different purpose: it regenerates kubelet configs because feature gate values are embedded directly in KubeletConfiguration. It's not about toggling MCO's own gating behavior.

The existing sigstoreAPIEnabled() in this same controller follows the same pattern.

OpenShift feature gates are not designed to be toggled at runtime. They are set at install time or through TechPreviewNoUpgrade/CustomNoUpgrade feature sets.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

@saschagrunert, thank you for the detailed explanation. You're right — FeatureGatesHandler is snapshot-style and read-only after Connect(), and OpenShift feature gates are not runtime-toggleable. The kubelet controller's informer watch is specifically to re-render KubeletConfiguration content (where gate values appear inline), not to re-trigger gate-guarded behavior. The existing sigstoreAPIEnabled() precedent in this same controller confirms the established pattern. My concern was misplaced — there's nothing to fix here.


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

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

cc @haircommander ☝️

Copy link
Copy Markdown
Member

@isabella-janssen isabella-janssen left a comment

Choose a reason for hiding this comment

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

/approve

Code changes look clean to me, added unit tests are passing, and node team has extensively reviewed the functionality of the PR.

@openshift-ci
Copy link
Copy Markdown
Contributor

openshift-ci bot commented Mar 16, 2026

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: haircommander, isabella-janssen, QiWang19, saschagrunert

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

The pull request process is described here

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

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

@openshift-ci openshift-ci bot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Mar 16, 2026
@haircommander
Copy link
Copy Markdown
Member

/verified later @BhargaviGudi

@openshift-ci-robot openshift-ci-robot added verified-later verified Signifies that the PR passed pre-merge verification criteria labels Mar 16, 2026
@openshift-ci-robot
Copy link
Copy Markdown
Contributor

@haircommander: This PR has been marked to be verified later by @BhargaviGudi.

Details

In response to this:

/verified later @BhargaviGudi

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.

@saschagrunert
Copy link
Copy Markdown
Member Author

/retest

@openshift-merge-bot openshift-merge-bot bot merged commit b06051f into openshift:main Mar 17, 2026
18 checks passed
@saschagrunert saschagrunert deleted the additional-storage-config-crio branch March 17, 2026 08:05
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. verified Signifies that the PR passed pre-merge verification criteria verified-later

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants