Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Set default volume type in storage class #311

Merged
merged 8 commits into from
Mar 22, 2023
Merged
18 changes: 18 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,24 @@ If the reload fails, the provisioner will log the error and **continue using the

>time="2018-10-03T06:39:28Z" level=error msg="failed to load the new config file: config canonicalization failed: duplicate node yasker-lp-dev3"

### Volume Types

To specify the type of volume you want the provisioner to create, add either of the following annotations;

- PVC:
```yaml
annotations:
volumeType: <local or hostPath>
```

- StorageClass:
```yaml
annotations:
defaultVolumeType: <local or hostPath>
```

A few things to note; the annotation for the `StorageClass` will apply to all volumes using it and is superseded by the annotation on the PVC if one is provided. If neither of the annotations was provided then we default to `hostPath`.

## Uninstall

Before uninstallation, make sure the PVs created by the provisioner have already been deleted. Use `kubectl get pv` and make sure no PV with StorageClass `local-path`.
Expand Down
52 changes: 39 additions & 13 deletions provisioner.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ const (

const (
defaultCmdTimeoutSeconds = 120
defaultVolumeType = "hostPath"
)

var (
Expand Down Expand Up @@ -282,20 +283,18 @@ func (p *LocalPathProvisioner) Provision(ctx context.Context, opts pvController.
fs := v1.PersistentVolumeFilesystem

var pvs v1.PersistentVolumeSource
if val, ok := opts.PVC.GetAnnotations()["volumeType"]; ok && strings.ToLower(val) == "local" {
pvs = v1.PersistentVolumeSource{
Local: &v1.LocalVolumeSource{
Path: path,
},
}
var volumeType string
if dVal, ok := opts.StorageClass.GetAnnotations()["defaultVolumeType"]; ok {
volumeType = dVal
} else {
hostPathType := v1.HostPathDirectoryOrCreate
pvs = v1.PersistentVolumeSource{
HostPath: &v1.HostPathVolumeSource{
Path: path,
Type: &hostPathType,
},
}
volumeType = defaultVolumeType
}
if val, ok := opts.PVC.GetAnnotations()["volumeType"]; ok {
volumeType = val
}
pvs, err = createPersistentVolumeSource(volumeType, path)
if err != nil {
return nil, pvController.ProvisioningFinished, err
}

var nodeAffinity *v1.VolumeNodeAffinity
Expand Down Expand Up @@ -655,3 +654,30 @@ func canonicalizeConfig(data *ConfigData) (cfg *Config, err error) {
}
return cfg, nil
}

func createPersistentVolumeSource(volumeType string, path string) (pvs v1.PersistentVolumeSource, err error) {
defer func() {
err = errors.Wrapf(err, "failed to create persistent volume source")
}()

switch strings.ToLower(volumeType) {
case "local":
pvs = v1.PersistentVolumeSource{
Local: &v1.LocalVolumeSource{
Path: path,
},
}
case "hostpath":
hostPathType := v1.HostPathDirectoryOrCreate
pvs = v1.PersistentVolumeSource{
HostPath: &v1.HostPathVolumeSource{
Path: path,
Type: &hostPathType,
},
}
default:
return pvs, fmt.Errorf("\"%s\" is not a recognised volume type", volumeType)
}

return pvs, nil
}
9 changes: 8 additions & 1 deletion test/pod_test.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//go:build e2e
// +build e2e

package test
Expand All @@ -6,9 +7,9 @@ import (
"fmt"
"github.com/kelseyhightower/envconfig"
"github.com/stretchr/testify/suite"
"strings"
"testing"
"time"
"strings"
)

const (
Expand Down Expand Up @@ -89,6 +90,12 @@ func (p *PodTestSuite) TestPodWithLocalVolume() {
runTest(p, []string{p.config.IMAGE}, "ready", localVolumeType)
}

func (p *PodTestSuite) TestPodWithLocalVolumeDefault() {
p.kustomizeDir = "pod-with-default-local-volume"

runTest(p, []string{p.config.IMAGE}, "ready", localVolumeType)
}

func (p *PodTestSuite) TestPodWithNodeAffinity() {
p.kustomizeDir = "pod-with-node-affinity"

Expand Down
12 changes: 12 additions & 0 deletions test/testdata/pod-with-default-local-volume/kustomization.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../../../deploy
- ../../../examples/pod
patches:
- path: patch.yaml
commonLabels:
app: local-path-provisioner
images:
- name: rancher/local-path-provisioner
newTag: dev
9 changes: 9 additions & 0 deletions test/testdata/pod-with-default-local-volume/patch.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: local-path
annotations:
defaultVolumeType: local
provisioner: rancher.io/local-path
reclaimPolicy: Delete
volumeBindingMode: WaitForFirstConsumer