Add block supports to rbd driver

This commit is contained in:
Masaki Kimura 2018-11-01 01:03:03 +00:00 committed by Huamin Chen
parent 1ac0757aab
commit 165b82a44c
3 changed files with 65 additions and 35 deletions

View File

@ -24,6 +24,9 @@ rules:
- apiGroups: [""] - apiGroups: [""]
resources: ["events"] resources: ["events"]
verbs: ["list", "watch", "create", "update", "patch"] verbs: ["list", "watch", "create", "update", "patch"]
- apiGroups: [""]
resources: ["endpoints"]
verbs: ["get", "create", "update"]
--- ---
kind: ClusterRoleBinding kind: ClusterRoleBinding

View File

@ -86,6 +86,10 @@ spec:
hostPath: hostPath:
path: /var/lib/kubelet/plugins_registry/csi-rbdplugin path: /var/lib/kubelet/plugins_registry/csi-rbdplugin
type: DirectoryOrCreate type: DirectoryOrCreate
- name: plugin-mount-dir
hostPath:
path: /var/lib/kubelet/plugins/kubernetes.io/csi/volumeDevices/
type: DirectoryOrCreate
- name: registration-dir - name: registration-dir
hostPath: hostPath:
path: /var/lib/kubelet/plugins_registry/ path: /var/lib/kubelet/plugins_registry/

View File

@ -40,30 +40,53 @@ type nodeServer struct {
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) {
targetPath := req.GetTargetPath() targetPath := req.GetTargetPath()
if !strings.HasSuffix(targetPath, "/mount") {
return nil, fmt.Errorf("rnd: malformed the value of target path: %s", targetPath)
}
s := strings.Split(strings.TrimSuffix(targetPath, "/mount"), "/")
volName := s[len(s)-1]
targetPathMutex.LockKey(targetPath) targetPathMutex.LockKey(targetPath)
defer targetPathMutex.UnlockKey(targetPath) defer targetPathMutex.UnlockKey(targetPath)
notMnt, err := ns.mounter.IsLikelyNotMountPoint(targetPath) var volName string
if err != nil { isBlock := req.GetVolumeCapability().GetBlock() != nil
if os.IsNotExist(err) {
if err = os.MkdirAll(targetPath, 0750); err != nil { if isBlock {
return nil, status.Error(codes.Internal, err.Error()) // Get volName from targetPath
s := strings.Split(targetPath, "/")
volName = s[len(s)-1]
// Check if that target path exists properly
// targetPath should exists and should be a file
st, err := os.Stat(targetPath)
if err != nil {
if os.IsNotExist(err) {
return nil, status.Error(codes.NotFound, "targetPath not mounted")
} }
notMnt = true
} else {
return nil, status.Error(codes.Internal, err.Error()) return nil, status.Error(codes.Internal, err.Error())
} }
} if !st.Mode().IsRegular() {
return nil, status.Error(codes.Internal, "targetPath is not regular file")
}
} else {
// Get volName from targetPath
if !strings.HasSuffix(targetPath, "/mount") {
return nil, fmt.Errorf("rnd: malformed the value of target path: %s", targetPath)
}
s := strings.Split(strings.TrimSuffix(targetPath, "/mount"), "/")
volName = s[len(s)-1]
if !notMnt { // Check if that target path exists properly
return &csi.NodePublishVolumeResponse{}, nil notMnt, err := ns.mounter.IsLikelyNotMountPoint(targetPath)
if err != nil {
if os.IsNotExist(err) {
if err = os.MkdirAll(targetPath, 0750); err != nil {
return nil, status.Error(codes.Internal, err.Error())
}
notMnt = true
} else {
return nil, status.Error(codes.Internal, err.Error())
}
}
if !notMnt {
return &csi.NodePublishVolumeResponse{}, nil
}
} }
volOptions, err := getRBDVolumeOptions(req.GetVolumeContext()) volOptions, err := getRBDVolumeOptions(req.GetVolumeContext())
if err != nil { if err != nil {
@ -76,23 +99,31 @@ func (ns *nodeServer) NodePublishVolume(ctx context.Context, req *csi.NodePublis
return nil, err return nil, err
} }
glog.V(4).Infof("rbd image: %s/%s was successfully mapped at %s\n", req.GetVolumeId(), volOptions.Pool, devicePath) glog.V(4).Infof("rbd image: %s/%s was successfully mapped at %s\n", req.GetVolumeId(), volOptions.Pool, devicePath)
fsType := req.GetVolumeCapability().GetMount().GetFsType()
// Publish Path
fsType := req.GetVolumeCapability().GetMount().GetFsType()
readOnly := req.GetReadonly() readOnly := req.GetReadonly()
attrib := req.GetVolumeContext() attrib := req.GetVolumeContext()
mountFlags := req.GetVolumeCapability().GetMount().GetMountFlags() mountFlags := req.GetVolumeCapability().GetMount().GetMountFlags()
glog.V(4).Infof("target %v\nfstype %v\ndevice %v\nreadonly %v\nattributes %v\n mountflags %v\n", glog.V(4).Infof("target %v\nisBlock %v\nfstype %v\ndevice %v\nreadonly %v\nattributes %v\n mountflags %v\n",
targetPath, fsType, devicePath, readOnly, attrib, mountFlags) targetPath, isBlock, fsType, devicePath, readOnly, attrib, mountFlags)
options := []string{}
if readOnly {
options = append(options, "ro")
}
diskMounter := &mount.SafeFormatAndMount{Interface: ns.mounter, Exec: mount.NewOsExec()} diskMounter := &mount.SafeFormatAndMount{Interface: ns.mounter, Exec: mount.NewOsExec()}
if err := diskMounter.FormatAndMount(devicePath, targetPath, fsType, options); err != nil { if isBlock {
return nil, err options := []string{"bind"}
if err := diskMounter.Mount(devicePath, targetPath, fsType, options); err != nil {
return nil, err
}
} else {
options := []string{}
if readOnly {
options = append(options, "ro")
}
if err := diskMounter.FormatAndMount(devicePath, targetPath, fsType, options); err != nil {
return nil, err
}
} }
return &csi.NodePublishVolumeResponse{}, nil return &csi.NodePublishVolumeResponse{}, nil
@ -103,14 +134,6 @@ func (ns *nodeServer) NodeUnpublishVolume(ctx context.Context, req *csi.NodeUnpu
targetPathMutex.LockKey(targetPath) targetPathMutex.LockKey(targetPath)
defer targetPathMutex.UnlockKey(targetPath) defer targetPathMutex.UnlockKey(targetPath)
notMnt, err := ns.mounter.IsLikelyNotMountPoint(targetPath)
if err != nil {
return nil, status.Error(codes.Internal, err.Error())
}
if notMnt {
return nil, status.Error(codes.NotFound, "Volume not mounted")
}
devicePath, cnt, err := mount.GetDeviceNameFromMount(ns.mounter, targetPath) devicePath, cnt, err := mount.GetDeviceNameFromMount(ns.mounter, targetPath)
if err != nil { if err != nil {
return nil, status.Error(codes.Internal, err.Error()) return nil, status.Error(codes.Internal, err.Error())