Skip to content

Add mountOptions on volumeMounts#2681

Draft
nispriha wants to merge 2 commits into
openshift:masterfrom
nispriha:njagan/volumemount-options-openshift
Draft

Add mountOptions on volumeMounts#2681
nispriha wants to merge 2 commits into
openshift:masterfrom
nispriha:njagan/volumemount-options-openshift

Conversation

@nispriha

@nispriha nispriha commented Jun 5, 2026

Copy link
Copy Markdown

What type of PR is this?

What this PR does / why we need it:

Which issue(s) this PR is related to:

Special notes for your reviewer:

Does this PR introduce a user-facing change?


Additional documentation e.g., KEPs (Kubernetes Enhancement Proposals), usage docs, etc.:


Summary by CodeRabbit

Release Notes

  • New Features
    • Added support for specifying mount options on volume mounts (e.g., noexec, nodev, nosuid), controlled by the VolumeMountOptions feature gate (alpha, available in v1.37).

@openshift-ci-robot openshift-ci-robot added the backports/unvalidated-commits Indicates that not all commits come to merged upstream PRs. label Jun 5, 2026
@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 Jun 5, 2026
@openshift-ci

openshift-ci Bot commented Jun 5, 2026

Copy link
Copy Markdown

Skipping CI for Draft Pull Request.
If you want CI signal for your change, please convert it to an actual PR.
You can still manually trigger a test run with /test all

@openshift-ci-robot

Copy link
Copy Markdown

@nispriha: the contents of this pull request could not be automatically validated.

The following commits could not be validated and must be approved by a top-level approver:

Comment /validate-backports to re-evaluate validity of the upstream PRs, for example when they are merged upstream.

@coderabbitai

coderabbitai Bot commented Jun 5, 2026

Copy link
Copy Markdown

Walkthrough

This PR adds support for per-volume mount options via a new MountOptions []string field in the VolumeMount API type. The feature is gated by a new alpha feature gate (VolumeMountOptions in v1.37), validated to allow only noexec, nodev, and nosuid, and propagated through kubelet and CRI to container runtimes.

Changes

Volume Mount Options Support

Layer / File(s) Summary
Feature gate and API type definitions
pkg/features/kube_features.go, pkg/apis/core/types.go, staging/src/k8s.io/api/core/v1/types.go, staging/src/k8s.io/api/core/v1/generated.proto, staging/src/k8s.io/api/core/v1/types_swagger_doc_generated.go
Declares VolumeMountOptions feature gate (alpha, v1.37, default false) and adds optional MountOptions []string field to VolumeMount across API definitions with feature-gate protection and schema documentation.
Mount options validation
pkg/apis/core/validation/validation.go
ValidateVolumeMounts enforces feature gate requirement and restricts allowed mount options to noexec, nodev, and nosuid; returns Forbidden error when gate is disabled and NotSupported for disallowed values.
Kubelet runtime integration
pkg/kubelet/container/runtime.go, pkg/kubelet/kubelet_pods.go, pkg/kubelet/kuberuntime/kuberuntime_container.go
Mount struct extended with MountOptions field; makeMounts in kubelet_pods copies options from pod spec; kuberuntime makeMounts propagates to runtimeapi.Mount and toKubeContainerStatus copies from CRI mount status.
Client library and CRI API
staging/src/k8s.io/client-go/applyconfigurations/core/v1/volumemount.go, staging/src/k8s.io/client-go/applyconfigurations/internal/internal.go, staging/src/k8s.io/cri-api/pkg/apis/runtime/v1/api.proto
VolumeMountApplyConfiguration gains MountOptions field and WithMountOptions() builder method; internal merge schema updated; CRI Mount message extended with mount_options field.
Test fixtures and generated files
staging/src/k8s.io/api/testdata/HEAD/*.json, staging/src/k8s.io/api/testdata/HEAD/*.yaml, test/compatibility_lifecycle/reference/versioned_feature_list.yaml
All Kubernetes resource test fixtures (Pod, Deployment, StatefulSet, DaemonSet, Job, CronJob, ReplicaSet, ReplicationController, PodTemplate) updated with example mountOptions entries across init, regular, and ephemeral containers; feature list reference added.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

🚥 Pre-merge checks | ✅ 15
✅ Passed checks (15 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Add mountOptions on volumeMounts' accurately and specifically describes the main change: adding a mountOptions field to volumeMounts across the codebase.
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 PR adds no new Ginkgo tests. It modifies source code files (validation, types, runtime) and test data fixtures (JSON/YAML), not actual Ginkgo test code, so the stable test names check does not apply.
Test Structure And Quality ✅ Passed PR does not include any Ginkgo test files (*_test.go). Changes are limited to API types, validation logic, and testdata—no test code present to assess against quality requirements.
Microshift Test Compatibility ✅ Passed This PR does not add any new Ginkgo e2e tests. Changes are limited to API types, validation logic, feature gates, kubelet plumbing, and test data fixtures - no test files were added.
Single Node Openshift (Sno) Test Compatibility ✅ Passed PR adds no new Ginkgo e2e tests; changes are API types, validation, feature gates, proto definitions, and testdata fixtures only. SNO check not applicable.
Topology-Aware Scheduling Compatibility ✅ Passed This PR adds a MountOptions field to VolumeMount API types and related validation/infrastructure. No deployment manifests, operator code, or topology-dependent scheduling constraints are introduced.
Ote Binary Stdout Contract ✅ Passed No process-level stdout writes detected. Changes are API types, validation logic, feature gates, and kubelet implementation—no test binary or logging configuration modifications.
Ipv6 And Disconnected Network Test Compatibility ✅ Passed This PR does not add any new Ginkgo e2e tests. Changes are API definitions, validation logic, feature gates, and testdata fixtures only; check does not apply.
No-Weak-Crypto ✅ Passed No weak cryptography patterns detected. PR adds volume mount options (noexec, nodev, nosuid) with no MD5, SHA1, DES, RC4, 3DES, Blowfish, ECB, custom crypto, or insecure comparison code.
Container-Privileges ✅ Passed PR adds mount-level security options (noexec, nodev, nosuid) that restrict privileges. No privilege escalation settings or container privilege flags are introduced.
No-Sensitive-Data-In-Logs ✅ Passed Mount options values are constrained to three public Linux flags (noexec, nodev, nosuid) and do not expose passwords, tokens, API keys, PII, session IDs, internal hostnames, or customer data.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 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 and usage tips.

@openshift-ci openshift-ci Bot added the vendor-update Touching vendor dir or related files label Jun 5, 2026
@openshift-ci

openshift-ci Bot commented Jun 5, 2026

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: nispriha
Once this PR has been reviewed and has the lgtm label, please assign deads2k 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 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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
pkg/kubelet/kubelet_pods.go (1)

402-413: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Enforce the feature gate before propagating MountOptions.

makeMounts forwards mount.MountOptions unconditionally. This bypasses gate intent for kubelet-managed static pods (which do not go through apiserver validation). Add a local check mirroring the RecursiveReadOnlyMounts pattern and reject non-empty mountOptions when VolumeMountOptions is disabled.

Suggested fix
 		rro, err := resolveRecursiveReadOnly(mount, supportsRRO)
 		if err != nil {
 			return nil, cleanupAction, fmt.Errorf("failed to resolve recursive read-only mode: %w", err)
 		}
 		if rro && !utilfeature.DefaultFeatureGate.Enabled(features.RecursiveReadOnlyMounts) {
 			return nil, cleanupAction, fmt.Errorf("recursive read-only mount needs feature gate %q to be enabled", features.RecursiveReadOnlyMounts)
 		}
+		if len(mount.MountOptions) > 0 && !utilfeature.DefaultFeatureGate.Enabled(features.VolumeMountOptions) {
+			return nil, cleanupAction, fmt.Errorf("mount options require feature gate %q to be enabled", features.VolumeMountOptions)
+		}
 
 		mounts = append(mounts, kubecontainer.Mount{
🤖 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/kubelet/kubelet_pods.go` around lines 402 - 413, In makeMounts, enforce
the VolumeMountOptions feature gate before propagating mount.MountOptions into
the kubecontainer.Mount; mirror the RecursiveReadOnlyMounts pattern used
elsewhere: check
utilfeature.DefaultFeatureGate.Enabled(features.VolumeMountOptions) and if the
gate is disabled and the incoming mount.MountOptions is non-empty, reject it
(return an error or otherwise fail pod validation) instead of unconditionally
assigning MountOptions, otherwise safely assign mount.MountOptions to
kubecontainer.Mount.MountOptions.
🧹 Nitpick comments (2)
staging/src/k8s.io/api/testdata/HEAD/extensions.v1beta1.ReplicaSet.json (1)

620-624: 💤 Low value

Consider using valid mount option values in test fixtures.

The mountOptions field contains "mountOptionsValue", which is not a valid mount option. According to the API definition, only VFS-level options like "noexec", "nodev", or "nosuid" are permitted. While test fixtures commonly use placeholder values, using a semantically valid value would better exercise validation logic and serve as a clearer example.

📝 Suggested improvement
                 "subPathExpr": "subPathExprValue",
                 "mountOptions": [
-                  "mountOptionsValue"
+                  "noexec"
                 ]
🤖 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 `@staging/src/k8s.io/api/testdata/HEAD/extensions.v1beta1.ReplicaSet.json`
around lines 620 - 624, The test fixture uses an invalid placeholder
"mountOptionsValue" for the mountOptions array; update the "mountOptions" entry
in the extensions.v1beta1.ReplicaSet test JSON to use a semantically valid
VFS-level option (e.g., "noexec", "nodev" or "nosuid") so validation logic is
exercised—locate the JSON object containing "subPathExpr" and "mountOptions" and
replace the placeholder string with one of those valid option values.
staging/src/k8s.io/api/testdata/HEAD/extensions.v1beta1.ReplicaSet.yaml (1)

421-429: 💤 Low value

Inconsistent field ordering between JSON and YAML fixtures.

In the JSON fixture, mountOptions is placed at the end of the volumeMounts object (after subPathExpr), but in this YAML fixture, mountOptions appears at the beginning (before mountPath). While field order doesn't affect functionality, test fixtures should maintain consistent ordering across formats for maintainability and to serve as canonical examples.

🔄 Suggested alignment

Consider reordering fields to match the JSON fixture structure:

         volumeMounts:
-        - mountOptions:
-          - mountOptionsValue
-          mountPath: mountPathValue
+        - mountPath: mountPathValue
           mountPropagation: mountPropagationValue
           name: nameValue
           readOnly: true
           recursiveReadOnly: recursiveReadOnlyValue
           subPath: subPathValue
           subPathExpr: subPathExprValue
+          mountOptions:
+          - mountOptionsValue
🤖 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 `@staging/src/k8s.io/api/testdata/HEAD/extensions.v1beta1.ReplicaSet.yaml`
around lines 421 - 429, Move the mountOptions entry within the volumeMounts
mapping so its key order matches the JSON fixture: place mountOptions after
subPathExpr (i.e., reorder the fields in the volumeMounts block so the sequence
is mountPath, mountPropagation, name, readOnly, recursiveReadOnly, subPath,
subPathExpr, then mountOptions). Update the YAML fixture's volumeMounts section
(look for the mountOptions and subPathExpr keys) to reflect this ordering for
consistency across fixtures.
🤖 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 `@staging/src/k8s.io/api/testdata/HEAD/batch.v1.CronJob.yaml`:
- Around line 481-483: Update the fixture to use allowlisted mountOptions values
instead of the placeholder "mountOptionsValue": replace each occurrence of the
mountOptions entry that uses "mountOptionsValue" (the YAML key "mountOptions"
with value "mountOptionsValue") with one or more of the validated options
("noexec", "nodev", or "nosuid") so the CronJob fixture passes validation;
ensure the corresponding mountPaths (e.g., the block containing "mountPath:
mountPathValue") remain unchanged.

---

Outside diff comments:
In `@pkg/kubelet/kubelet_pods.go`:
- Around line 402-413: In makeMounts, enforce the VolumeMountOptions feature
gate before propagating mount.MountOptions into the kubecontainer.Mount; mirror
the RecursiveReadOnlyMounts pattern used elsewhere: check
utilfeature.DefaultFeatureGate.Enabled(features.VolumeMountOptions) and if the
gate is disabled and the incoming mount.MountOptions is non-empty, reject it
(return an error or otherwise fail pod validation) instead of unconditionally
assigning MountOptions, otherwise safely assign mount.MountOptions to
kubecontainer.Mount.MountOptions.

---

Nitpick comments:
In `@staging/src/k8s.io/api/testdata/HEAD/extensions.v1beta1.ReplicaSet.json`:
- Around line 620-624: The test fixture uses an invalid placeholder
"mountOptionsValue" for the mountOptions array; update the "mountOptions" entry
in the extensions.v1beta1.ReplicaSet test JSON to use a semantically valid
VFS-level option (e.g., "noexec", "nodev" or "nosuid") so validation logic is
exercised—locate the JSON object containing "subPathExpr" and "mountOptions" and
replace the placeholder string with one of those valid option values.

In `@staging/src/k8s.io/api/testdata/HEAD/extensions.v1beta1.ReplicaSet.yaml`:
- Around line 421-429: Move the mountOptions entry within the volumeMounts
mapping so its key order matches the JSON fixture: place mountOptions after
subPathExpr (i.e., reorder the fields in the volumeMounts block so the sequence
is mountPath, mountPropagation, name, readOnly, recursiveReadOnly, subPath,
subPathExpr, then mountOptions). Update the YAML fixture's volumeMounts section
(look for the mountOptions and subPathExpr keys) to reflect this ordering for
consistency across fixtures.
🪄 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: Enterprise

Run ID: a0eff700-c5c8-4fa8-8873-e4907f4e7318

📥 Commits

Reviewing files that changed from the base of the PR and between 872bd37 and f7c4f96.

⛔ Files ignored due to path filters (5)
  • pkg/apis/core/v1/zz_generated.conversion.go is excluded by !**/zz_generated*
  • pkg/apis/core/zz_generated.deepcopy.go is excluded by !**/zz_generated*
  • pkg/generated/openapi/zz_generated.openapi.go is excluded by !**/generated/**, !**/zz_generated*
  • staging/src/k8s.io/api/core/v1/generated.pb.go is excluded by !**/*.pb.go
  • staging/src/k8s.io/api/core/v1/zz_generated.deepcopy.go is excluded by !**/zz_generated*
📒 Files selected for processing (51)
  • pkg/apis/core/types.go
  • pkg/apis/core/validation/validation.go
  • pkg/features/kube_features.go
  • pkg/kubelet/container/runtime.go
  • pkg/kubelet/kubelet_pods.go
  • pkg/kubelet/kuberuntime/kuberuntime_container.go
  • staging/src/k8s.io/api/core/v1/generated.proto
  • staging/src/k8s.io/api/core/v1/types.go
  • staging/src/k8s.io/api/core/v1/types_swagger_doc_generated.go
  • staging/src/k8s.io/api/testdata/HEAD/apps.v1.DaemonSet.json
  • staging/src/k8s.io/api/testdata/HEAD/apps.v1.DaemonSet.yaml
  • staging/src/k8s.io/api/testdata/HEAD/apps.v1.Deployment.json
  • staging/src/k8s.io/api/testdata/HEAD/apps.v1.Deployment.yaml
  • staging/src/k8s.io/api/testdata/HEAD/apps.v1.ReplicaSet.json
  • staging/src/k8s.io/api/testdata/HEAD/apps.v1.ReplicaSet.yaml
  • staging/src/k8s.io/api/testdata/HEAD/apps.v1.StatefulSet.json
  • staging/src/k8s.io/api/testdata/HEAD/apps.v1.StatefulSet.yaml
  • staging/src/k8s.io/api/testdata/HEAD/apps.v1beta1.Deployment.json
  • staging/src/k8s.io/api/testdata/HEAD/apps.v1beta1.Deployment.yaml
  • staging/src/k8s.io/api/testdata/HEAD/apps.v1beta1.StatefulSet.json
  • staging/src/k8s.io/api/testdata/HEAD/apps.v1beta1.StatefulSet.yaml
  • staging/src/k8s.io/api/testdata/HEAD/apps.v1beta2.DaemonSet.json
  • staging/src/k8s.io/api/testdata/HEAD/apps.v1beta2.DaemonSet.yaml
  • staging/src/k8s.io/api/testdata/HEAD/apps.v1beta2.Deployment.json
  • staging/src/k8s.io/api/testdata/HEAD/apps.v1beta2.Deployment.yaml
  • staging/src/k8s.io/api/testdata/HEAD/apps.v1beta2.ReplicaSet.json
  • staging/src/k8s.io/api/testdata/HEAD/apps.v1beta2.ReplicaSet.yaml
  • staging/src/k8s.io/api/testdata/HEAD/apps.v1beta2.StatefulSet.json
  • staging/src/k8s.io/api/testdata/HEAD/apps.v1beta2.StatefulSet.yaml
  • staging/src/k8s.io/api/testdata/HEAD/batch.v1.CronJob.json
  • staging/src/k8s.io/api/testdata/HEAD/batch.v1.CronJob.yaml
  • staging/src/k8s.io/api/testdata/HEAD/batch.v1.Job.json
  • staging/src/k8s.io/api/testdata/HEAD/batch.v1.Job.yaml
  • staging/src/k8s.io/api/testdata/HEAD/batch.v1beta1.CronJob.json
  • staging/src/k8s.io/api/testdata/HEAD/batch.v1beta1.CronJob.yaml
  • staging/src/k8s.io/api/testdata/HEAD/core.v1.Pod.json
  • staging/src/k8s.io/api/testdata/HEAD/core.v1.Pod.yaml
  • staging/src/k8s.io/api/testdata/HEAD/core.v1.PodTemplate.json
  • staging/src/k8s.io/api/testdata/HEAD/core.v1.PodTemplate.yaml
  • staging/src/k8s.io/api/testdata/HEAD/core.v1.ReplicationController.json
  • staging/src/k8s.io/api/testdata/HEAD/core.v1.ReplicationController.yaml
  • staging/src/k8s.io/api/testdata/HEAD/extensions.v1beta1.DaemonSet.json
  • staging/src/k8s.io/api/testdata/HEAD/extensions.v1beta1.DaemonSet.yaml
  • staging/src/k8s.io/api/testdata/HEAD/extensions.v1beta1.Deployment.json
  • staging/src/k8s.io/api/testdata/HEAD/extensions.v1beta1.Deployment.yaml
  • staging/src/k8s.io/api/testdata/HEAD/extensions.v1beta1.ReplicaSet.json
  • staging/src/k8s.io/api/testdata/HEAD/extensions.v1beta1.ReplicaSet.yaml
  • staging/src/k8s.io/client-go/applyconfigurations/core/v1/volumemount.go
  • staging/src/k8s.io/client-go/applyconfigurations/internal/internal.go
  • staging/src/k8s.io/cri-api/pkg/apis/runtime/v1/api.proto
  • test/compatibility_lifecycle/reference/versioned_feature_list.yaml

Comment on lines +481 to +483
- mountOptions:
- mountOptionsValue
mountPath: mountPathValue

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Use allowlisted mountOptions values in fixtures.

Line 481, Line 712, and Line 944 set mountOptionsValue, but validation only accepts noexec, nodev, and nosuid for mountOptions. This can break validation-aligned fixture usage.

Suggested patch
-            - mountOptions:
-              - mountOptionsValue
+            - mountOptions:
+              - noexec
               mountPath: mountPathValue
...
-            - mountOptions:
-              - mountOptionsValue
+            - mountOptions:
+              - noexec
               mountPath: mountPathValue
...
-            - mountOptions:
-              - mountOptionsValue
+            - mountOptions:
+              - noexec
               mountPath: mountPathValue

Also applies to: 712-714, 944-946

🤖 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 `@staging/src/k8s.io/api/testdata/HEAD/batch.v1.CronJob.yaml` around lines 481
- 483, Update the fixture to use allowlisted mountOptions values instead of the
placeholder "mountOptionsValue": replace each occurrence of the mountOptions
entry that uses "mountOptionsValue" (the YAML key "mountOptions" with value
"mountOptionsValue") with one or more of the validated options ("noexec",
"nodev", or "nosuid") so the CronJob fixture passes validation; ensure the
corresponding mountPaths (e.g., the block containing "mountPath:
mountPathValue") remain unchanged.

@openshift-ci-robot

Copy link
Copy Markdown

@nispriha: the contents of this pull request could not be automatically validated.

The following commits could not be validated and must be approved by a top-level approver:

Comment /validate-backports to re-evaluate validity of the upstream PRs, for example when they are merged upstream.

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

🤖 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 `@staging/src/k8s.io/api/testdata/HEAD/batch.v1.CronJob.json`:
- Around line 702-705: The fixture uses an invalid mount option token
"mountOptionsValue" under the JSON key "mountOptions" (adjacent to
"subPathExpr"); replace it with one or more allowlisted values accepted by
ValidateVolumeMounts (e.g., "noexec", "nodev", or "nosuid") and ensure each
occurrence (including the other two similar places) is updated to use only those
allowed strings so the fixture passes validation.

In `@staging/src/k8s.io/api/testdata/HEAD/batch.v1.Job.json`:
- Around line 653-656: The test fixture uses an invalid mountOptions value
"mountOptionsValue"; locate the occurrences of the "mountOptions" array (near
the "subPathExpr" entry) in
staging/src/k8s.io/api/testdata/HEAD/batch.v1.Job.json and replace the
placeholder with one of the server-allowed strings ("noexec", "nodev", or
"nosuid") so the JSON conforms to server validation for mount options; apply the
same replacement to the other reported occurrences in the file.

In `@staging/src/k8s.io/api/testdata/HEAD/batch.v1.Job.yaml`:
- Around line 445-447: Replace the placeholder mount option value
"mountOptionsValue" with an allowed mount option (one of noexec, nodev, or
nosuid) wherever a mountOptions list is defined in this YAML (look for the
"mountOptions:" entries paired with "mountPath:" and the VolumeMount examples);
update each occurrence (the three places with "- mountOptionsValue") to a valid
value such as "noexec" so the entries conform to VolumeMount validation.
🪄 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: Enterprise

Run ID: 10350882-81fa-484a-870a-448acea55467

📥 Commits

Reviewing files that changed from the base of the PR and between 872bd37 and 516f2b8.

⛔ Files ignored due to path filters (6)
  • pkg/apis/core/v1/zz_generated.conversion.go is excluded by !**/zz_generated*
  • pkg/apis/core/zz_generated.deepcopy.go is excluded by !**/zz_generated*
  • pkg/generated/openapi/zz_generated.openapi.go is excluded by !**/generated/**, !**/zz_generated*
  • staging/src/k8s.io/api/core/v1/generated.pb.go is excluded by !**/*.pb.go
  • staging/src/k8s.io/api/core/v1/zz_generated.deepcopy.go is excluded by !**/zz_generated*
  • staging/src/k8s.io/cri-api/pkg/apis/runtime/v1/api.pb.go is excluded by !**/*.pb.go
📒 Files selected for processing (51)
  • pkg/apis/core/types.go
  • pkg/apis/core/validation/validation.go
  • pkg/features/kube_features.go
  • pkg/kubelet/container/runtime.go
  • pkg/kubelet/kubelet_pods.go
  • pkg/kubelet/kuberuntime/kuberuntime_container.go
  • staging/src/k8s.io/api/core/v1/generated.proto
  • staging/src/k8s.io/api/core/v1/types.go
  • staging/src/k8s.io/api/core/v1/types_swagger_doc_generated.go
  • staging/src/k8s.io/api/testdata/HEAD/apps.v1.DaemonSet.json
  • staging/src/k8s.io/api/testdata/HEAD/apps.v1.DaemonSet.yaml
  • staging/src/k8s.io/api/testdata/HEAD/apps.v1.Deployment.json
  • staging/src/k8s.io/api/testdata/HEAD/apps.v1.Deployment.yaml
  • staging/src/k8s.io/api/testdata/HEAD/apps.v1.ReplicaSet.json
  • staging/src/k8s.io/api/testdata/HEAD/apps.v1.ReplicaSet.yaml
  • staging/src/k8s.io/api/testdata/HEAD/apps.v1.StatefulSet.json
  • staging/src/k8s.io/api/testdata/HEAD/apps.v1.StatefulSet.yaml
  • staging/src/k8s.io/api/testdata/HEAD/apps.v1beta1.Deployment.json
  • staging/src/k8s.io/api/testdata/HEAD/apps.v1beta1.Deployment.yaml
  • staging/src/k8s.io/api/testdata/HEAD/apps.v1beta1.StatefulSet.json
  • staging/src/k8s.io/api/testdata/HEAD/apps.v1beta1.StatefulSet.yaml
  • staging/src/k8s.io/api/testdata/HEAD/apps.v1beta2.DaemonSet.json
  • staging/src/k8s.io/api/testdata/HEAD/apps.v1beta2.DaemonSet.yaml
  • staging/src/k8s.io/api/testdata/HEAD/apps.v1beta2.Deployment.json
  • staging/src/k8s.io/api/testdata/HEAD/apps.v1beta2.Deployment.yaml
  • staging/src/k8s.io/api/testdata/HEAD/apps.v1beta2.ReplicaSet.json
  • staging/src/k8s.io/api/testdata/HEAD/apps.v1beta2.ReplicaSet.yaml
  • staging/src/k8s.io/api/testdata/HEAD/apps.v1beta2.StatefulSet.json
  • staging/src/k8s.io/api/testdata/HEAD/apps.v1beta2.StatefulSet.yaml
  • staging/src/k8s.io/api/testdata/HEAD/batch.v1.CronJob.json
  • staging/src/k8s.io/api/testdata/HEAD/batch.v1.CronJob.yaml
  • staging/src/k8s.io/api/testdata/HEAD/batch.v1.Job.json
  • staging/src/k8s.io/api/testdata/HEAD/batch.v1.Job.yaml
  • staging/src/k8s.io/api/testdata/HEAD/batch.v1beta1.CronJob.json
  • staging/src/k8s.io/api/testdata/HEAD/batch.v1beta1.CronJob.yaml
  • staging/src/k8s.io/api/testdata/HEAD/core.v1.Pod.json
  • staging/src/k8s.io/api/testdata/HEAD/core.v1.Pod.yaml
  • staging/src/k8s.io/api/testdata/HEAD/core.v1.PodTemplate.json
  • staging/src/k8s.io/api/testdata/HEAD/core.v1.PodTemplate.yaml
  • staging/src/k8s.io/api/testdata/HEAD/core.v1.ReplicationController.json
  • staging/src/k8s.io/api/testdata/HEAD/core.v1.ReplicationController.yaml
  • staging/src/k8s.io/api/testdata/HEAD/extensions.v1beta1.DaemonSet.json
  • staging/src/k8s.io/api/testdata/HEAD/extensions.v1beta1.DaemonSet.yaml
  • staging/src/k8s.io/api/testdata/HEAD/extensions.v1beta1.Deployment.json
  • staging/src/k8s.io/api/testdata/HEAD/extensions.v1beta1.Deployment.yaml
  • staging/src/k8s.io/api/testdata/HEAD/extensions.v1beta1.ReplicaSet.json
  • staging/src/k8s.io/api/testdata/HEAD/extensions.v1beta1.ReplicaSet.yaml
  • staging/src/k8s.io/client-go/applyconfigurations/core/v1/volumemount.go
  • staging/src/k8s.io/client-go/applyconfigurations/internal/internal.go
  • staging/src/k8s.io/cri-api/pkg/apis/runtime/v1/api.proto
  • test/compatibility_lifecycle/reference/versioned_feature_list.yaml

Comment on lines +3150 to +3160
if len(mnt.MountOptions) > 0 {
if !utilfeature.DefaultFeatureGate.Enabled(features.VolumeMountOptions) {
allErrs = append(allErrs, field.Forbidden(idxPath.Child("mountOptions"), "mount options require the VolumeMountOptions feature gate to be enabled"))
} else {
allowedOptions := sets.New("noexec", "nodev", "nosuid")
for j, opt := range mnt.MountOptions {
if !allowedOptions.Has(opt) {
allErrs = append(allErrs, field.NotSupported(idxPath.Child("mountOptions").Index(j), opt, sets.List(allowedOptions)))
}
}
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== References to VolumeMountOptions feature gate =="
rg -n -C3 'VolumeMountOptions|MountOptions' pkg staging/src/k8s.io 2>/dev/null || true

echo
echo "== Pod strategy/drop-disabled handling =="
rg -n -C4 'dropDisabled|DropDisabled|VolumeMountOptions|mountOptions' pkg/registry/core 2>/dev/null || true

echo
echo "== Pod validation options plumbing for create/update =="
rg -n -C4 'PodValidationOptions|ValidationOptionsForPod|ValidatePod(Create|Update|TemplateSpec)' pkg/apis/core 2>/dev/null || true

Repository: openshift/kubernetes

Length of output: 50377


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Locate ValidateVolumeMounts call sites =="
rg -n "ValidateVolumeMounts" pkg/apis/core/validation/validation.go pkg/apis/core/validation -S || true

echo
echo "== Feature gate check usage (VolumeMountOptions) =="
rg -n "VolumeMountOptions" pkg/apis/core/validation/validation.go pkg/apis/core/validation -S || true

echo
echo "== Pod validation entrypoints (create/update/template) =="
rg -n "ValidatePod(Create|Update|TemplateSpec)" pkg/apis/core/validation -S || true
rg -n "type PodValidationOptions|PodValidationOptions" pkg/apis/core/validation -S || true

echo
echo "== Any pod field-dropping / dropDisabled logic touching mountOptions =="
rg -n "(dropDisabled|DropDisabled)" pkg/registry/core -S || true
rg -n "mountOptions" pkg/registry/core -S | head -n 80 || true

Repository: openshift/kubernetes

Length of output: 37115


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Search for mountOptions in pod disabled field dropping =="
rg -n "mountOptions|VolumeMountOptions" pkg/registry/core/pod pkg/registry/core/podtemplate pkg/registry/core/replicationcontroller pkg/registry/core -S || true

echo
echo "== Locate podutil.DropDisabledPodFields implementation =="
rg -n "func DropDisabledPodFields" -S pkg | head -n 50

echo
# Search for the helper that might drop mountOptions inside podutil or related utils
rg -n "DropDisabledPodFields" -S pkg | head -n 50

echo
echo "== Search for VolumeMountOptions feature gate in registry pod util code =="
rg -n "VolumeMountOptions" -S pkg/registry pkg/util pkg/apis | head -n 200

Repository: openshift/kubernetes

Length of output: 1823


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Show DropDisabledPodFields logic around where spec fields might be dropped
nl -ba pkg/api/pod/util.go | sed -n '650,780p'

echo
echo "== Search for mountOptions/VolumeMountOptions inside util.go =="
rg -n "mountOptions|VolumeMountOptions" pkg/api/pod/util.go -S || true

Repository: openshift/kubernetes

Length of output: 107


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== DropDisabledPodFields implementation (pkg/api/pod/util.go) =="
cat -n pkg/api/pod/util.go | sed -n '660,780p'

echo
echo "== Search for mountOptions/VolumeMountOptions inside util.go =="
rg -n "mountOptions|VolumeMountOptions" pkg/api/pod/util.go -S || true

Repository: openshift/kubernetes

Length of output: 5813


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Does podutil/dropDisabled handle mountOptions? =="
rg -n "mountOptions" pkg/api/pod -S || true
rg -n "VolumeMountOptions" pkg/api/pod -S || true

echo
echo "== Remaining part of dropDisabledFields (look for any mountOptions-related helpers) =="
rg -n "dropDisabledFields|dropDisabled.*mount|mountOptions" pkg/api/pod/util.go -S || true

echo
echo "== PodValidationOptions fields mentioning mountOptions / gate =="
rg -n "type PodValidationOptions" -n pkg/apis/core/validation/validation.go
sed -n '4450,4555p' pkg/apis/core/validation/validation.go

echo
echo "== Any other uses of VolumeMountOptions beyond ValidateVolumeMounts =="
rg -n "VolumeMountOptions" pkg/apis/core/validation -S || true

echo
echo "== Any other gate-drop / field-drop logic for mountOptions elsewhere =="
rg -n "mountOptions.*featuregate|featuregate.*mountOptions|VolumeMountOptions.*drop" -S pkg | head -n 200 || true

Repository: openshift/kubernetes

Length of output: 6360


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Search for VolumeMountOptions in pod util (pkg/api/pod/util.go) =="
rg -n "VolumeMountOptions" pkg/api/pod/util.go pkg/api/pod -S || true

echo
echo "== Inspect GetValidationOptionsFromPodSpecAndMeta in pkg/api/pod/util.go =="
rg -n "func GetValidationOptionsFromPodSpecAndMeta" pkg/api/pod/util.go -S
# print a window around the function
start=$(rg -n "func GetValidationOptionsFromPodSpecAndMeta" pkg/api/pod/util.go -n | head -n1 | cut -d: -f1)
end=$((start+260))
sed -n "${start},${end}p" pkg/api/pod/util.go

echo
echo "== Inspect pod strategy PrepareForUpdate/PrepareForCreate calling DropDisabledPodFields =="
rg -n "PrepareForUpdate|PrepareForCreate|DropDisabledPodFields" pkg/registry/core/pod/strategy.go -S
cat -n pkg/registry/core/pod/strategy.go | sed -n '60,180p'

echo
echo "== Inspect ValidateVolumeMounts call site in ValidateVolumeMounts flow (validateContainerCommon) =="
cat -n pkg/apis/core/validation/validation.go | sed -n '3870,3960p'

Repository: openshift/kubernetes

Length of output: 22390


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Search for mountOptions / VolumeMountOptions in pod drop-disabled code =="
rg -n "mountOptions|VolumeMountOptions|MountOptions" pkg/api/pod -S || true

echo
echo "== Search for DropDisabledTemplateFields call sites (pods embedded in controllers) =="
rg -n "DropDisabledTemplateFields" pkg/registry/core -S

echo
echo "== Search for PodTemplate validation update flow and whether it uses old spec for gating =="
rg -n "ValidatePodTemplateUpdate" pkg/apis/core/validation/validation.go
# show the function body window
start=$(rg -n "func ValidatePodTemplateUpdate" pkg/apis/core/validation/validation.go | head -n1 | cut -d: -f1)
end=$((start+220))
sed -n "${start},${end}p" pkg/apis/core/validation/validation.go

Repository: openshift/kubernetes

Length of output: 11216


Fix/update compatibility when disabling the VolumeMountOptions feature gate

ValidateVolumeMounts hard-forbids volumeMount.mountOptions whenever features.VolumeMountOptions is disabled. Pod/controller create/update flows call podutil.DropDisabledPodFields/DropDisabledTemplateFields, but those drop helpers have no mountOptions/VolumeMountOptions handling, and GetValidationOptionsFromPodSpecAndMeta has no update-mode allowance for previously-set mountOptions.
So disabling the gate can make API updates to existing pods/templates that still contain mountOptions fail.

Comment on lines +702 to +705
"subPathExpr": "subPathExprValue",
"mountOptions": [
"mountOptionsValue"
]

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Use allowlisted mountOptions values in this fixture.

mountOptionsValue is not accepted by ValidateVolumeMounts; only noexec, nodev, and nosuid are allowed. Keeping this token can break validation-aligned fixture paths.

Suggested patch
-                    "mountOptions": [
-                      "mountOptionsValue"
-                    ]
+                    "mountOptions": [
+                      "noexec"
+                    ]

Also applies to: 1019-1022, 1336-1339

🤖 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 `@staging/src/k8s.io/api/testdata/HEAD/batch.v1.CronJob.json` around lines 702
- 705, The fixture uses an invalid mount option token "mountOptionsValue" under
the JSON key "mountOptions" (adjacent to "subPathExpr"); replace it with one or
more allowlisted values accepted by ValidateVolumeMounts (e.g., "noexec",
"nodev", or "nosuid") and ensure each occurrence (including the other two
similar places) is updated to use only those allowed strings so the fixture
passes validation.

Comment on lines +653 to +656
"subPathExpr": "subPathExprValue",
"mountOptions": [
"mountOptionsValue"
]

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

mountOptions fixture value is outside server validation allowlist.

mountOptionsValue is rejected by validation; use one of noexec, nodev, or nosuid so this testdata stays contract-aligned.

Suggested patch
-                "mountOptions": [
-                  "mountOptionsValue"
-                ]
+                "mountOptions": [
+                  "noexec"
+                ]

Also applies to: 970-973, 1287-1290

🤖 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 `@staging/src/k8s.io/api/testdata/HEAD/batch.v1.Job.json` around lines 653 -
656, The test fixture uses an invalid mountOptions value "mountOptionsValue";
locate the occurrences of the "mountOptions" array (near the "subPathExpr"
entry) in staging/src/k8s.io/api/testdata/HEAD/batch.v1.Job.json and replace the
placeholder with one of the server-allowed strings ("noexec", "nodev", or
"nosuid") so the JSON conforms to server validation for mount options; apply the
same replacement to the other reported occurrences in the file.

Comment on lines +445 to +447
- mountOptions:
- mountOptionsValue
mountPath: mountPathValue

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Replace placeholder mountOptionsValue with an allowed mount option.

These entries should use an allowlisted option (noexec, nodev, nosuid) to match VolumeMount validation behavior.

Suggested patch
-        - mountOptions:
-          - mountOptionsValue
+        - mountOptions:
+          - noexec
           mountPath: mountPathValue

Also applies to: 676-678, 908-910

🤖 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 `@staging/src/k8s.io/api/testdata/HEAD/batch.v1.Job.yaml` around lines 445 -
447, Replace the placeholder mount option value "mountOptionsValue" with an
allowed mount option (one of noexec, nodev, or nosuid) wherever a mountOptions
list is defined in this YAML (look for the "mountOptions:" entries paired with
"mountPath:" and the VolumeMount examples); update each occurrence (the three
places with "- mountOptionsValue") to a valid value such as "noexec" so the
entries conform to VolumeMount validation.

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

Labels

backports/unvalidated-commits Indicates that not all commits come to merged upstream PRs. do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. vendor-update Touching vendor dir or related files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants