in pkg/nfs/controllerserver.go [116:202]
func (cs *ControllerServer) CreateVolume(ctx context.Context, req *csi.CreateVolumeRequest) (*csi.CreateVolumeResponse, error) {
name := req.GetName()
if len(name) == 0 {
return nil, status.Error(codes.InvalidArgument, "CreateVolume name must be provided")
}
if err := isValidVolumeCapabilities(req.GetVolumeCapabilities()); err != nil {
return nil, status.Error(codes.InvalidArgument, err.Error())
}
mountPermissions := cs.Driver.mountPermissions
reqCapacity := req.GetCapacityRange().GetRequiredBytes()
parameters := req.GetParameters()
if parameters == nil {
parameters = make(map[string]string)
}
// validate parameters (case-insensitive)
for k, v := range parameters {
switch strings.ToLower(k) {
case paramServer:
case paramShare:
case paramSubDir:
case paramOnDelete:
case pvcNamespaceKey:
case pvcNameKey:
case pvNameKey:
// no op
case mountPermissionsField:
if v != "" {
var err error
if mountPermissions, err = strconv.ParseUint(v, 8, 32); err != nil {
return nil, status.Errorf(codes.InvalidArgument, fmt.Sprintf("invalid mountPermissions %s in storage class", v))
}
}
default:
return nil, status.Errorf(codes.InvalidArgument, fmt.Sprintf("invalid parameter %q in storage class", k))
}
}
nfsVol, err := newNFSVolume(name, reqCapacity, parameters, cs.Driver.defaultOnDeletePolicy)
if err != nil {
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
if err = cs.internalMount(ctx, nfsVol, parameters, volCap); err != nil {
return nil, status.Errorf(codes.Internal, "failed to mount nfs server: %v", err.Error())
}
defer func() {
if err = cs.internalUnmount(ctx, nfsVol); err != nil {
klog.Warningf("failed to unmount nfs server: %v", err.Error())
}
}()
// Create subdirectory under base-dir
internalVolumePath := getInternalVolumePath(cs.Driver.workingMountDir, nfsVol)
if err = os.MkdirAll(internalVolumePath, 0777); err != nil {
return nil, status.Errorf(codes.Internal, "failed to make subdirectory: %v", err.Error())
}
if mountPermissions > 0 {
// Reset directory permissions because of umask problems
if err = os.Chmod(internalVolumePath, os.FileMode(mountPermissions)); err != nil {
klog.Warningf("failed to chmod subdirectory: %v", err.Error())
}
}
if req.GetVolumeContentSource() != nil {
if err := cs.copyVolume(ctx, req, nfsVol); err != nil {
return nil, err
}
}
setKeyValueInMap(parameters, paramSubDir, nfsVol.subDir)
return &csi.CreateVolumeResponse{
Volume: &csi.Volume{
VolumeId: nfsVol.id,
CapacityBytes: 0, // by setting it to zero, Provisioner will use PVC requested size as PV size
VolumeContext: parameters,
ContentSource: req.GetVolumeContentSource(),
},
}, nil
}