Skip to content

Add storage capabilities for rancher.io/local-path - #4319

Merged
kubevirt-prow[bot] merged 3 commits into
kubevirt:mainfrom
fjvbn2003:local-path-capabilities
Oct 26, 2026
Merged

kubevirt-prow[bot] merged 3 commits into
kubevirt:mainfrom
fjvbn2003:local-path-capabilities

Conversation

@fjvbn2003

@fjvbn2003 fjvbn2003 commented Oct 17, 2026 •

Copy link
Copy Markdown
Contributor

What this PR does / why we need it:

Adds rancher.io/local-path (local-path-provisioner) to
CapabilitiesByProvisionerKey with {{rwo, file}}.

local-path-provisioner is the default provisioner in k3s and kind (CDI's own
cluster-up/cluster/kind/manifests/local-storage-class.yaml uses it too). Today its StorageProfiles come out
empty. On my homelab cluster (CDI v1.66.0, local-path-provisioner v0.0.32):

$ kubectl get storageprofile local-path -o jsonpath='{.status}'
{"cloneStrategy":"copy","conditions":[{...,"message":"Provisioner is not recognized","reason":"UnrecognizedProvisioner","status":"False","type":"Recognized"}],"dataImportCronSourceFormat":"pvc","provisioner":"rancher.io/local-path","storageClass":"local-path"}

and cdi-deployment keeps reporting Set metric:local-path complete:false ..., which is what
CDIStorageProfilesIncomplete alerts on. A DataVolume on this class that relies on spec.storage defaults
fails with ErrClaimNotValid: no accessMode specified in StorageProfile local-path.

Why {{rwo, file}}, from the provisioner source (same in v0.0.32 and v0.0.37):

  • node-path volumes reject any access mode other than RWO/RWOP:
    NodePath only supports ReadWriteOnce and ReadWriteOncePod (1.22+) access modes
    (provisioner.go)
  • every PV it creates has VolumeMode: &fs with fs := v1.PersistentVolumeFilesystem, so Block is never offered.

RWX is only possible when a shared filesystem path is configured for the provisioner, which is not the
default and cannot be seen from the StorageClass; those users can keep setting spec.claimPropertySets on the
StorageProfile. No clone strategy is advised: the provisioner has no snapshot or CSI clone support, so the
existing default (host-assisted copy, already chosen today) stays.

Which issue(s) this PR fixes:
Fixes #3005

Special notes for your reviewer:

  • Same shape as storagecapabilities: add OpenEBS Replicated PV Mayastor #4286 (Mayastor). Tests: a claimPropertySets check for the new provisioner and a Recognized
    entry.
  • CDI's kind provider uses this provisioner for its default local StorageClass. After this change that
    StorageProfile becomes complete. If a functional lane depends on that profile being incomplete, please
    point me to it and I will adjust.
  • Test results (Go 1.27.2, linux/amd64, GOFLAGS=-mod=vendor, on main @ 9cd4fbd): the new specs fail without the capability entry (7 ran, 2 failed) and pass with it; go test ./pkg/controller/ gives 385 passed / 3 failed with this change and 383 passed / 3 failed without it — the same three Update PVC from POD VDDK specs fail in that environment either way; ./pkg/storagecapabilities/... passes.

AI disclosure: I used Claude (Anthropic) to help read the provisioner source and draft the change and tests.
I reviewed every line, and the StorageProfile output above is from my own cluster. The commit carries an
Assisted-by trailer.

Release note:

Add StorageProfile defaults for the local-path-provisioner (rancher.io/local-path) used by k3s and kind

🤖 Generated with Claude Code

local-path-provisioner is the default provisioner in k3s and kind,
and the kind provider in cluster-up uses it for its default
StorageClass. It has no entry in CapabilitiesByProvisionerKey, so its
StorageProfiles get no claimPropertySets and the Recognized condition
is False with UnrecognizedProvisioner. A DataVolume that uses
spec.storage without accessModes on such a StorageClass then fails
with "no accessMode specified in StorageProfile".

local-path-provisioner only accepts ReadWriteOnce and ReadWriteOncePod
for node paths and always creates Filesystem PVs, so advertise
ReadWriteOnce with Filesystem.

Assisted-by: Claude <[email protected]>
Signed-off-by: YoungjuKim <[email protected]>
@kubevirt-prow kubevirt-prow Bot added release-note Denotes a PR that will be considered when it comes time to generate release notes. dco-signoff: yes Indicates the PR's author has DCO signed all their commits. labels Oct 17, 2026
@kubevirt-prow

kubevirt-prow Bot commented Oct 17, 2026

Copy link
Copy Markdown

Hi @fjvbn2003. Thanks for your PR.

PRs from untrusted users cannot be marked as trusted with /ok-to-test in this repo meaning untrusted PR authors can never trigger tests themselves. Collaborators can still trigger tests on the PR using /test all.

I understand the commands that are listed here.

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.

@akalenyu akalenyu left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

thank you!

Comment on lines +44 to +47
"k8s.io/minikube-hostpath": {{rwo, file}},
// local-path-provisioner (default in k3s and kind); node-local directories,
// so only RWO filesystem volumes unless a shared filesystem is configured
"rancher.io/local-path": {{rwo, file}},

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I think we can do some aggregation of these local path provisioners which all ultimately give out rwo,file

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Thanks for the review! Done in the second commit: I added a createLocalPathCapabilities() helper and switched the node-local path provisioners to it (hostpath-provisioner CSI and legacy, k8s.io/minikube-hostpath, rancher.io/local-path). The hostpath-provisioner overlay variant stays RWX filesystem.

I left DirectPV (directpv-min-io) out, since it hands out whole local drives rather than directories, but I can fold it in as well if you'd prefer.

Unit tests: go test ./pkg/controller/ runs 388 of 388 specs, all passing.

hostpath-provisioner (CSI and legacy), minikube-hostpath and
local-path-provisioner all back a volume with a directory on one
node, so each of them only offers ReadWriteOnce Filesystem volumes.
Use a single createLocalPathCapabilities helper for them instead of
repeating the literal, as suggested in review.

Assisted-by: Claude <[email protected]>
Signed-off-by: YoungjuKim <[email protected]>
@kubevirt-prow kubevirt-prow Bot added size/M and removed size/S labels Oct 18, 2026
@akalenyu

Copy link
Copy Markdown
Collaborator

/approve
/test all

@kubevirt-prow

kubevirt-prow Bot commented Oct 19, 2026

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: akalenyu

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

@kubevirt-prow kubevirt-prow Bot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Oct 19, 2026
@coveralls

coveralls commented Oct 19, 2026 •

Copy link
Copy Markdown

Coverage Status

coverage: 50.288% (+0.08%) from 50.213% — fjvbn2003:local-path-capabilities into kubevirt:main

@fjvbn2003

Copy link
Copy Markdown
Contributor Author

Hi @alromeros @arnongilboa, this already has an /approve from @akalenyu and /test all passed on 58b2277, so it only needs an /lgtm. Could one of you take a look when you get a chance? Thanks!

Comment on lines +189 to +202
It("Should create storage profile with RWO filesystem claim property set for local-path-provisioner", func() {
reconciler = createStorageProfileReconciler(CreateStorageClassWithProvisioner(storageClassName, nil, nil, localPathProvisioner))
_, err := reconciler.Reconcile(context.TODO(), reconcile.Request{NamespacedName: types.NamespacedName{Name: storageClassName}})
Expect(err).ToNot(HaveOccurred())

sp := &cdiv1.StorageProfile{}
err = reconciler.client.Get(context.TODO(), types.NamespacedName{Name: storageClassName}, sp, &client.GetOptions{})
Expect(err).ToNot(HaveOccurred())
Expect(*sp.Status.Provisioner).To(Equal(localPathProvisioner))
Expect(sp.Status.ClaimPropertySets).To(Equal([]cdiv1.ClaimPropertySet{
{AccessModes: []v1.PersistentVolumeAccessMode{v1.ReadWriteOnce}, VolumeMode: ptr.To(v1.PersistentVolumeFilesystem)},
}))
})

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Not sure why 2 additional utests are needed for this provisioner, as it has nothing new in the logic which is already well covered.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Thanks @arnongilboa, fair point. The provisioner only reuses createLocalPathCapabilities, which the existing hostpath tests already cover, so I dropped both tests in 39e13da.

rancher.io/local-path only reuses createLocalPathCapabilities, which the
existing hostpath-provisioner tests already cover, so the extra reconcile
test and the recognized-provisioner table entry did not exercise any new
logic.

Signed-off-by: YoungjuKim <[email protected]>
Assisted-by: Claude <[email protected]>
@kubevirt-prow kubevirt-prow Bot added size/S and removed size/M labels Oct 25, 2026
@arnongilboa

Copy link
Copy Markdown
Collaborator

/lgtm

@kubevirt-prow kubevirt-prow Bot added the lgtm Indicates that a PR is ready to be merged. label Oct 26, 2026
@kubevirt-prow
kubevirt-prow Bot merged commit fd4146a into kubevirt:main Oct 26, 2026
21 checks passed
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. dco-signoff: yes Indicates the PR's author has DCO signed all their commits. lgtm Indicates that a PR is ready to be merged. release-note Denotes a PR that will be considered when it comes time to generate release notes. size/S

Projects

None yet

Development

Successfully merging this pull request may close these issues.

StorageProfile needs to be patched for the rancher local-path provisioner

4 participants