Merge pull request #262 from andyzhangx/deletevolume-mountoptions

feat: support mountOptions in DeleteVolume
This commit is contained in:
Andy Zhang 2022-01-03 10:50:00 +08:00 committed by GitHub
commit 3b85b325a0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 76 additions and 6 deletions

View File

@ -151,6 +151,8 @@ endif
.PHONY: install-nfs-server
install-nfs-server:
kubectl apply -f ./deploy/example/nfs-provisioner/nfs-server.yaml
kubectl delete secret mount-options --ignore-not-found
kubectl create secret generic mount-options --from-literal mountOptions="nfsvers=4.1"
.PHONY: install-helm
install-helm:

View File

@ -37,6 +37,9 @@ rules:
- apiGroups: ["coordination.k8s.io"]
resources: ["leases"]
verbs: ["get", "list", "watch", "create", "update", "patch"]
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1

View File

@ -33,6 +33,9 @@ rules:
- apiGroups: ["coordination.k8s.io"]
resources: ["leases"]
verbs: ["get", "list", "watch", "create", "update", "patch"]
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get"]
---
kind: ClusterRoleBinding

View File

@ -1,5 +1,5 @@
## Driver Parameters
> This plugin driver itself only provides a communication layer between resources in the cluser and the NFS server, you need to bring your own NFS server before using this driver.
> This driver requires existing and already configured NFSv3 or NFSv4 server, it supports dynamic provisioning of Persistent Volumes via Persistent Volume Claims by creating a new sub directory under NFS server.
### Storage Class Usage (Dynamic Provisioning)
> [`StorageClass` example](../deploy/example/storageclass-nfs.yaml)

View File

@ -127,8 +127,21 @@ func (cs *ControllerServer) DeleteVolume(ctx context.Context, req *csi.DeleteVol
return &csi.DeleteVolumeResponse{}, nil
}
var volCap *csi.VolumeCapability
mountOptions := getMountOptions(req.GetSecrets())
if mountOptions != "" {
klog.V(2).Infof("DeleteVolume: found mountOptions(%s) for volume(%s)", mountOptions, volumeID)
volCap = &csi.VolumeCapability{
AccessType: &csi.VolumeCapability_Mount{
Mount: &csi.VolumeCapability_MountVolume{
MountFlags: []string{mountOptions},
},
},
}
}
// Mount nfs base share so we can delete the subdirectory
if err = cs.internalMount(ctx, nfsVol, nil); err != nil {
if err = cs.internalMount(ctx, nfsVol, volCap); err != nil {
return nil, status.Errorf(codes.Internal, "failed to mount nfs server: %v", err.Error())
}
defer func() {
@ -285,8 +298,7 @@ func (cs *ControllerServer) newNFSVolume(name string, size int64, params map[str
baseDir string
)
// Validate parameters (case-insensitive).
// TODO do more strict validation.
// validate parameters (case-insensitive)
for k, v := range params {
switch strings.ToLower(k) {
case paramServer:
@ -298,7 +310,7 @@ func (cs *ControllerServer) newNFSVolume(name string, size int64, params map[str
}
}
// Validate required parameters
// validate required parameters
if server == "" {
return nil, fmt.Errorf("%v is a required parameter", paramServer)
}

View File

@ -50,6 +50,7 @@ const (
// The root directory is omitted from the string, for example:
// "base" instead of "/base"
paramShare = "share"
mountOptionsField = "mountoptions"
)
func NewDriver(nodeID, driverName, endpoint string, perm *uint32) *Driver {

View File

@ -121,3 +121,14 @@ func (vl *VolumeLocks) Release(volumeID string) {
defer vl.mux.Unlock()
vl.locks.Delete(volumeID)
}
// getMountOptions get mountOptions value from a map
func getMountOptions(context map[string]string) string {
for k, v := range context {
switch strings.ToLower(k) {
case mountOptionsField:
return v
}
}
return ""
}

View File

@ -118,3 +118,39 @@ func TestGetLogLevel(t *testing.T) {
}
}
}
func TestGetMountOptions(t *testing.T) {
tests := []struct {
desc string
context map[string]string
result string
}{
{
desc: "nil context",
context: nil,
result: "",
},
{
desc: "empty context",
context: map[string]string{},
result: "",
},
{
desc: "valid mountOptions",
context: map[string]string{"mountOptions": "nfsvers=3"},
result: "nfsvers=3",
},
{
desc: "valid mountOptions(lowercase)",
context: map[string]string{"mountoptions": "nfsvers=4"},
result: "nfsvers=4",
},
}
for _, test := range tests {
result := getMountOptions(test.context)
if result != test.result {
t.Errorf("Unexpected result: %s, expected: %s", result, test.result)
}
}
}

View File

@ -47,6 +47,8 @@ var (
defaultStorageClassParameters = map[string]string{
"server": "nfs-server.default.svc.cluster.local",
"share": "/",
"csi.storage.k8s.io/provisioner-secret-name": "mount-options",
"csi.storage.k8s.io/provisioner-secret-namespace": "default",
}
controllerServer *nfs.ControllerServer
)