fix: support mountOptions in CreateVolume

This commit is contained in:
andyzhangx 2020-12-27 03:59:09 +00:00
parent 9d781a9180
commit a0ad5ca5b6
4 changed files with 37 additions and 58 deletions

View File

@ -1,28 +0,0 @@
// +build linux darwin
/*
Copyright 2020 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package mounter
import (
utilexec "k8s.io/utils/exec"
"k8s.io/utils/mount"
)
func NewSafeMounter() (*mount.SafeFormatAndMount, error) {
return &mount.SafeFormatAndMount{
Interface: mount.New(""),
Exec: utilexec.New(),
}, nil
}

View File

@ -82,8 +82,12 @@ func (cs *ControllerServer) CreateVolume(ctx context.Context, req *csi.CreateVol
return nil, status.Error(codes.InvalidArgument, err.Error()) return nil, status.Error(codes.InvalidArgument, err.Error())
} }
var volCap *csi.VolumeCapability
if len(req.GetVolumeCapabilities()) > 0 {
volCap = req.GetVolumeCapabilities()[0]
}
// Mount nfs base share so we can create a subdirectory // Mount nfs base share so we can create a subdirectory
if err = cs.internalMount(ctx, nfsVol); 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()) return nil, status.Errorf(codes.Internal, "failed to mount nfs server: %v", err.Error())
} }
defer func() { defer func() {
@ -116,7 +120,7 @@ func (cs *ControllerServer) DeleteVolume(ctx context.Context, req *csi.DeleteVol
} }
// Mount nfs base share so we can delete the subdirectory // Mount nfs base share so we can delete the subdirectory
if err = cs.internalMount(ctx, nfsVol); err != nil { if err = cs.internalMount(ctx, nfsVol, nil); err != nil {
return nil, status.Errorf(codes.Internal, "failed to mount nfs server: %v", err.Error()) return nil, status.Errorf(codes.Internal, "failed to mount nfs server: %v", err.Error())
} }
defer func() { defer func() {
@ -230,13 +234,16 @@ func (cs *ControllerServer) validateVolumeCapability(c *csi.VolumeCapability) er
} }
// Mount nfs server at base-dir // Mount nfs server at base-dir
func (cs *ControllerServer) internalMount(ctx context.Context, vol *nfsVolume) error { func (cs *ControllerServer) internalMount(ctx context.Context, vol *nfsVolume, volCap *csi.VolumeCapability) error {
sharePath := filepath.Join(string(filepath.Separator) + vol.baseDir) sharePath := filepath.Join(string(filepath.Separator) + vol.baseDir)
targetPath := cs.getInternalMountPath(vol) targetPath := cs.getInternalMountPath(vol)
stdVolCap := csi.VolumeCapability{
AccessType: &csi.VolumeCapability_Mount{ if volCap == nil {
Mount: &csi.VolumeCapability_MountVolume{}, volCap = &csi.VolumeCapability{
}, AccessType: &csi.VolumeCapability_Mount{
Mount: &csi.VolumeCapability_MountVolume{},
},
}
} }
glog.V(4).Infof("internally mounting %v:%v at %v", vol.server, sharePath, targetPath) glog.V(4).Infof("internally mounting %v:%v at %v", vol.server, sharePath, targetPath)
@ -246,7 +253,7 @@ func (cs *ControllerServer) internalMount(ctx context.Context, vol *nfsVolume) e
paramServer: vol.server, paramServer: vol.server,
paramShare: sharePath, paramShare: sharePath,
}, },
VolumeCapability: &stdVolCap, VolumeCapability: volCap,
VolumeId: vol.id, VolumeId: vol.id,
}) })
return err return err

View File

@ -18,11 +18,8 @@ package nfs
import ( import (
"fmt" "fmt"
"runtime"
"strings" "strings"
"github.com/kubernetes-csi/csi-driver-nfs/pkg/mounter"
"k8s.io/utils/mount" "k8s.io/utils/mount"
) )
@ -64,9 +61,6 @@ func (f *fakeMounter) IsLikelyNotMountPoint(file string) (bool, error) {
} }
func NewFakeMounter() (*mount.SafeFormatAndMount, error) { func NewFakeMounter() (*mount.SafeFormatAndMount, error) {
if runtime.GOOS == "windows" {
return mounter.NewSafeMounter()
}
return &mount.SafeFormatAndMount{ return &mount.SafeFormatAndMount{
Interface: &fakeMounter{}, Interface: &fakeMounter{},
}, nil }, nil

View File

@ -21,28 +21,29 @@ import (
"os" "os"
"strings" "strings"
"github.com/golang/glog"
"github.com/container-storage-interface/spec/lib/go/csi" "github.com/container-storage-interface/spec/lib/go/csi"
"github.com/golang/glog"
"golang.org/x/net/context" "golang.org/x/net/context"
"google.golang.org/grpc/codes" "google.golang.org/grpc/codes"
"google.golang.org/grpc/status" "google.golang.org/grpc/status"
"k8s.io/utils/mount" "k8s.io/utils/mount"
) )
// NodeServer driver
type NodeServer struct { type NodeServer struct {
Driver *Driver Driver *Driver
mounter mount.Interface mounter mount.Interface
} }
// NodePublishVolume mount the volume
func (ns *NodeServer) NodePublishVolume(ctx context.Context, req *csi.NodePublishVolumeRequest) (*csi.NodePublishVolumeResponse, error) { func (ns *NodeServer) NodePublishVolume(ctx context.Context, req *csi.NodePublishVolumeRequest) (*csi.NodePublishVolumeResponse, error) {
if req.GetVolumeCapability() == nil { if req.GetVolumeCapability() == nil {
return nil, status.Error(codes.InvalidArgument, "Volume capability missing in request") return nil, status.Error(codes.InvalidArgument, "Volume capability missing in request")
} }
if len(req.GetVolumeId()) == 0 { volumeID := req.GetVolumeId()
if len(volumeID) == 0 {
return nil, status.Error(codes.InvalidArgument, "Volume ID missing in request") return nil, status.Error(codes.InvalidArgument, "Volume ID missing in request")
} }
targetPath := req.GetTargetPath() targetPath := req.GetTargetPath()
if len(targetPath) == 0 { if len(targetPath) == 0 {
return nil, status.Error(codes.InvalidArgument, "Target path not provided") return nil, status.Error(codes.InvalidArgument, "Target path not provided")
@ -59,21 +60,21 @@ func (ns *NodeServer) NodePublishVolume(ctx context.Context, req *csi.NodePublis
return nil, status.Error(codes.Internal, err.Error()) return nil, status.Error(codes.Internal, err.Error())
} }
} }
if !notMnt { if !notMnt {
return &csi.NodePublishVolumeResponse{}, nil return &csi.NodePublishVolumeResponse{}, nil
} }
mo := req.GetVolumeCapability().GetMount().GetMountFlags() mountOptions := req.GetVolumeCapability().GetMount().GetMountFlags()
if req.GetReadonly() { if req.GetReadonly() {
mo = append(mo, "ro") mountOptions = append(mountOptions, "ro")
} }
s := req.GetVolumeContext()[paramServer] s := req.GetVolumeContext()[paramServer]
ep := req.GetVolumeContext()[paramShare] ep := req.GetVolumeContext()[paramShare]
source := fmt.Sprintf("%s:%s", s, ep) source := fmt.Sprintf("%s:%s", s, ep)
err = ns.mounter.Mount(source, targetPath, "nfs", mo) glog.V(2).Infof("source(%s) targetPath(%s) volumeID(%v) mountflags(%v)", source, targetPath, volumeID, mountOptions)
err = ns.mounter.Mount(source, targetPath, "nfs", mountOptions)
if err != nil { if err != nil {
if os.IsPermission(err) { if os.IsPermission(err) {
return nil, status.Error(codes.PermissionDenied, err.Error()) return nil, status.Error(codes.PermissionDenied, err.Error())
@ -93,14 +94,16 @@ func (ns *NodeServer) NodePublishVolume(ctx context.Context, req *csi.NodePublis
return &csi.NodePublishVolumeResponse{}, nil return &csi.NodePublishVolumeResponse{}, nil
} }
// NodeUnpublishVolume unmount the volume
func (ns *NodeServer) NodeUnpublishVolume(ctx context.Context, req *csi.NodeUnpublishVolumeRequest) (*csi.NodeUnpublishVolumeResponse, error) { func (ns *NodeServer) NodeUnpublishVolume(ctx context.Context, req *csi.NodeUnpublishVolumeRequest) (*csi.NodeUnpublishVolumeResponse, error) {
if len(req.GetVolumeId()) == 0 { volumeID := req.GetVolumeId()
if len(volumeID) == 0 {
return nil, status.Error(codes.InvalidArgument, "Volume ID missing in request") return nil, status.Error(codes.InvalidArgument, "Volume ID missing in request")
} }
if len(req.GetTargetPath()) == 0 { targetPath := req.GetTargetPath()
if len(targetPath) == 0 {
return nil, status.Error(codes.InvalidArgument, "Target path missing in request") return nil, status.Error(codes.InvalidArgument, "Target path missing in request")
} }
targetPath := req.GetTargetPath()
notMnt, err := ns.mounter.IsLikelyNotMountPoint(targetPath) notMnt, err := ns.mounter.IsLikelyNotMountPoint(targetPath)
if err != nil { if err != nil {
@ -113,7 +116,8 @@ func (ns *NodeServer) NodeUnpublishVolume(ctx context.Context, req *csi.NodeUnpu
return nil, status.Error(codes.NotFound, "Volume not mounted") return nil, status.Error(codes.NotFound, "Volume not mounted")
} }
err = mount.CleanupMountPoint(req.GetTargetPath(), ns.mounter, false) glog.V(2).Infof("NodeUnpublishVolume(%s): CleanupMountPoint %s", volumeID, targetPath)
err = mount.CleanupMountPoint(targetPath, ns.mounter, false)
if err != nil { if err != nil {
return nil, status.Error(codes.Internal, err.Error()) return nil, status.Error(codes.Internal, err.Error())
} }
@ -121,17 +125,15 @@ func (ns *NodeServer) NodeUnpublishVolume(ctx context.Context, req *csi.NodeUnpu
return &csi.NodeUnpublishVolumeResponse{}, nil return &csi.NodeUnpublishVolumeResponse{}, nil
} }
// NodeGetInfo return info of the node on which this plugin is running
func (ns *NodeServer) NodeGetInfo(ctx context.Context, req *csi.NodeGetInfoRequest) (*csi.NodeGetInfoResponse, error) { func (ns *NodeServer) NodeGetInfo(ctx context.Context, req *csi.NodeGetInfoRequest) (*csi.NodeGetInfoResponse, error) {
glog.V(5).Infof("Using default NodeGetInfo")
return &csi.NodeGetInfoResponse{ return &csi.NodeGetInfoResponse{
NodeId: ns.Driver.nodeID, NodeId: ns.Driver.nodeID,
}, nil }, nil
} }
// NodeGetCapabilities return the capabilities of the Node plugin
func (ns *NodeServer) NodeGetCapabilities(ctx context.Context, req *csi.NodeGetCapabilitiesRequest) (*csi.NodeGetCapabilitiesResponse, error) { func (ns *NodeServer) NodeGetCapabilities(ctx context.Context, req *csi.NodeGetCapabilitiesRequest) (*csi.NodeGetCapabilitiesResponse, error) {
glog.V(5).Infof("Using default NodeGetCapabilities")
return &csi.NodeGetCapabilitiesResponse{ return &csi.NodeGetCapabilitiesResponse{
Capabilities: []*csi.NodeServiceCapability{ Capabilities: []*csi.NodeServiceCapability{
{ {
@ -145,18 +147,22 @@ func (ns *NodeServer) NodeGetCapabilities(ctx context.Context, req *csi.NodeGetC
}, nil }, nil
} }
// NodeGetVolumeStats get volume stats
func (ns *NodeServer) NodeGetVolumeStats(ctx context.Context, in *csi.NodeGetVolumeStatsRequest) (*csi.NodeGetVolumeStatsResponse, error) { func (ns *NodeServer) NodeGetVolumeStats(ctx context.Context, in *csi.NodeGetVolumeStatsRequest) (*csi.NodeGetVolumeStatsResponse, error) {
return nil, status.Error(codes.Unimplemented, "") return nil, status.Error(codes.Unimplemented, "")
} }
// NodeUnstageVolume unstage volume
func (ns *NodeServer) NodeUnstageVolume(ctx context.Context, req *csi.NodeUnstageVolumeRequest) (*csi.NodeUnstageVolumeResponse, error) { func (ns *NodeServer) NodeUnstageVolume(ctx context.Context, req *csi.NodeUnstageVolumeRequest) (*csi.NodeUnstageVolumeResponse, error) {
return &csi.NodeUnstageVolumeResponse{}, nil return &csi.NodeUnstageVolumeResponse{}, nil
} }
// NodeStageVolume stage volume
func (ns *NodeServer) NodeStageVolume(ctx context.Context, req *csi.NodeStageVolumeRequest) (*csi.NodeStageVolumeResponse, error) { func (ns *NodeServer) NodeStageVolume(ctx context.Context, req *csi.NodeStageVolumeRequest) (*csi.NodeStageVolumeResponse, error) {
return &csi.NodeStageVolumeResponse{}, nil return &csi.NodeStageVolumeResponse{}, nil
} }
// NodeExpandVolume node expand volume
func (ns *NodeServer) NodeExpandVolume(ctx context.Context, req *csi.NodeExpandVolumeRequest) (*csi.NodeExpandVolumeResponse, error) { func (ns *NodeServer) NodeExpandVolume(ctx context.Context, req *csi.NodeExpandVolumeRequest) (*csi.NodeExpandVolumeResponse, error) {
return nil, status.Error(codes.Unimplemented, "") return nil, status.Error(codes.Unimplemented, "")
} }