Skip to content

Commit

Permalink
Refactor NodePublishBlock into standard NodePublish
Browse files Browse the repository at this point in the history
* Use common standard/mkdir path to make block codepath less special
* Fixup examples to be more similar to existing non-block examples
  • Loading branch information
srust committed Oct 24, 2023
1 parent 6804a46 commit 1773c8d
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 88 deletions.
2 changes: 1 addition & 1 deletion e2e/test/framework/pod.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,5 +127,5 @@ func (f *Invocation) CheckIfFileIsInPod(filename string, pod *core.Pod) error {
}

func MkfsInPod(pod *core.Pod) error {
return runCommand("kubectl", "exec", "--kubeconfig", KubeConfigFile, "-it", "-n", pod.Namespace, pod.Name, "--", "/bin/bash", "-c", "mkfs.ext3 -F /dev/block")
return runCommand("kubectl", "exec", "--kubeconfig", KubeConfigFile, "-it", "-n", pod.Namespace, pod.Name, "--", "/bin/bash", "-c", "mkfs.ext4 -F /dev/block")
}
6 changes: 3 additions & 3 deletions pkg/linode-bs/controllerserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import (
const gigabyte = 1024 * 1024 * 1024
const minProviderVolumeBytes = 10 * gigabyte
const waitTimeout = 300
const DevicePathKey = "devicePath"
const devicePathKey = "devicePath"

type LinodeControllerServer struct {
Driver *LinodeDriver
Expand Down Expand Up @@ -270,9 +270,9 @@ func (linodeCS *LinodeControllerServer) ControllerPublishVolume(ctx context.Cont
if err != nil {
return nil, err
}
glog.V(4).Infof("volume %d is attached to instance %d", volume.ID, *volume.LinodeID)
glog.V(4).Infof("volume %d is attached to instance %d with path '%s'", volume.ID, *volume.LinodeID, volume.FilesystemPath)

pvInfo := map[string]string{DevicePathKey: volume.FilesystemPath}
pvInfo := map[string]string{devicePathKey: volume.FilesystemPath}
return &csi.ControllerPublishVolumeResponse{PublishContext: pvInfo}, nil
}

Expand Down
40 changes: 15 additions & 25 deletions pkg/linode-bs/examples/kubernetes/csi-app-block.yaml
Original file line number Diff line number Diff line change
@@ -1,27 +1,17 @@
apiVersion: apps/v1
kind: Deployment
kind: Pod
apiVersion: v1
metadata:
name: nginx-block
labels:
app: nginx
name: csi-block-example-pod
spec:
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80
volumeDevices:
- name: disk-pvc
devicePath: /dev/sdc
volumes:
- name: disk-pvc
persistentVolumeClaim:
claimName: block-pvc
containers:
- name: csi-block-example-container
image: busybox
volumeMounts:
volumeDevices:
- name: csi-block-example-volume
devicePath: /dev/linode/csi-block-example-dev
command: [ "/bin/sh", "-c", "stat /dev/linode/csi-block-example-dev && sleep 1000000" ]
volumes:
- name: csi-block-example-volume
persistentVolumeClaim:
claimName: csi-block-example-pvc
6 changes: 3 additions & 3 deletions pkg/linode-bs/examples/kubernetes/csi-pvc-block.yaml
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: block-pvc
name: csi-block-example-pvc
spec:
accessModes:
- ReadWriteOnce
volumeMode: Block
storageClassName: linode-block-storage
storageClassName: linode-block-storage-retain
resources:
requests:
storage: 10Gi
storage: 10Gi
98 changes: 42 additions & 56 deletions pkg/linode-bs/nodeserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ import (
"github.com/linode/linode-blockstorage-csi-driver/pkg/common"
linodeclient "github.com/linode/linode-blockstorage-csi-driver/pkg/linode-client"
"github.com/linode/linode-blockstorage-csi-driver/pkg/metadata"
"github.com/linode/linode-blockstorage-csi-driver/pkg/mount-manager"
mountmanager "github.com/linode/linode-blockstorage-csi-driver/pkg/mount-manager"
"golang.org/x/net/context"
"golang.org/x/sys/unix"
Expand Down Expand Up @@ -61,10 +60,12 @@ func (ns *LinodeNodeServer) NodePublishVolume(ctx context.Context, req *csi.Node

// Validate Arguments
targetPath := req.GetTargetPath()
targetPathDir := filepath.Dir(targetPath)
stagingTargetPath := req.GetStagingTargetPath()
readOnly := req.GetReadonly()
volumeID := req.GetVolumeId()
volumeCapability := req.GetVolumeCapability()

if len(volumeID) == 0 {
return nil, status.Error(codes.InvalidArgument, "NodePublishVolume Volume ID must be provided")
}
Expand All @@ -78,21 +79,14 @@ func (ns *LinodeNodeServer) NodePublishVolume(ctx context.Context, req *csi.Node
return nil, status.Error(codes.InvalidArgument, "NodePublishVolume Volume Capability must be provided")
}

var err error

// Perform a bind mount to the full path to allow duplicate mounts of the same PD.
// Set mount options:
// - bind mount to the full path to allow duplicate mounts of the same PD.
// - read-only if specified
options := []string{"bind"}
if readOnly {
options = append(options, "ro")
}

if blk := volumeCapability.GetBlock(); blk != nil {
if err = ns.nodePublishVolumeForBlock(req, options); err != nil {
return nil, err
}
return &csi.NodePublishVolumeResponse{}, nil
}

notMnt, err := ns.Mounter.Interface.IsLikelyNotMountPoint(targetPath)
if err != nil && !os.IsNotExist(err) {
glog.Errorf("cannot validate mount point: %s %v", targetPath, err)
Expand All @@ -109,10 +103,38 @@ func (ns *LinodeNodeServer) NodePublishVolume(ctx context.Context, req *csi.Node
return &csi.NodePublishVolumeResponse{}, nil
}

if err := os.MkdirAll(targetPath, os.FileMode(0755)); err != nil {
glog.Errorf("mkdir failed on disk %s (%v)", targetPath, err)
return nil, err
if blk := volumeCapability.GetBlock(); blk != nil {
// VolumeMode: Block
glog.V(5).Infof("NodePublishVolume[block]: making targetPathDir %s", targetPathDir)
if err := os.MkdirAll(targetPathDir, os.FileMode(0755)); err != nil {
glog.Errorf("mkdir failed on disk %s (%v)", targetPathDir, err)
return nil, err
}

// Update staging path to devicePath
stagingTargetPath = req.PublishContext["devicePath"]
glog.V(5).Infof("NodePublishVolume[block]: set stagingTargetPath to devicePath %s", stagingTargetPath)

// Make file to bind mount device to file
glog.V(5).Infof("NodePublishVolume[block]: making target block bind mount device file %s", targetPath)
file, err := os.OpenFile(targetPath, os.O_CREATE, 0660)
if err != nil {
if removeErr := os.Remove(targetPath); removeErr != nil {
return nil, status.Errorf(codes.Internal, "Failed remove mount target %s: %v", targetPath, err)
}
return nil, status.Errorf(codes.Internal, "Failed to create file %s: %v", targetPath, err)
}
file.Close()
} else {
// VolumeMode: Filesystem
glog.V(5).Infof("NodePublishVolume[filesystem]: making targetPath %s", targetPath)
if err := os.MkdirAll(targetPath, os.FileMode(0755)); err != nil {
glog.Errorf("mkdir failed on disk %s (%v)", targetPath, err)
return nil, err
}
}

// Mount Source to Target
err = ns.Mounter.Interface.Mount(stagingTargetPath, targetPath, "ext4", options)
if err != nil {
notMnt, mntErr := ns.Mounter.Interface.IsLikelyNotMountPoint(targetPath)
Expand Down Expand Up @@ -141,7 +163,7 @@ func (ns *LinodeNodeServer) NodePublishVolume(ctx context.Context, req *csi.Node
return nil, status.Error(codes.Internal, fmt.Sprintf("NodePublishVolume mount of disk failed: %v", err))
}

glog.V(4).Infof("Successfully mounted %s", targetPath)
glog.V(4).Infof("NodePublishVolume successfully mounted %s", targetPath)
return &csi.NodePublishVolumeResponse{}, nil
}

Expand All @@ -165,44 +187,6 @@ func getMountSources(target string) ([]string, error) {
return strings.Split(string(out), "\n"), nil
}

func (ns *LinodeNodeServer) nodePublishVolumeForBlock(req *csi.NodePublishVolumeRequest, mountOptions []string) error {
glog.V(4).Infof("nodePublishVolumeForBlock called with req: %#v", req)
target := req.GetTargetPath()
source := req.PublishContext["devicePath"]
podVolumePath := filepath.Dir(target)

// create the pod volume path if it is missing
// Path in the form of /var/lib/kubelet/plugins/kubernetes.io/csi/volumeDevices/publish/{volumeName}
exists, err := ns.Mounter.Interface.ExistsPath(podVolumePath)
if err != nil {
return status.Errorf(codes.Internal, "Failed to check path: %v", err)
}

if !exists {
if err := ns.Mounter.Interface.MakeDir(podVolumePath); err != nil {
return status.Errorf(codes.Internal, "Failed to create path: %v", err)
}
}

glog.V(5).Infof("NodePublishVolume [block]: making target file %s", target)
err = ns.Mounter.Interface.MakeFile(target)
if err != nil {
if removeErr := os.Remove(target); removeErr != nil {
return status.Errorf(codes.Internal, "Failed remove mount target %s: %v", target, err)
}
return status.Errorf(codes.Internal, "Failed to create file %s: %v", target, err)
}

glog.V(5).Infof("NodePublishVolume [block]: mounting %s at %s", source, target)
if err := ns.Mounter.Interface.Mount(source, target, "ext4", mountOptions); err != nil {
if removeErr := os.Remove(target); removeErr != nil {
return status.Errorf(codes.Internal, "Failed remove mount target %s: %v", target, err)
}
return status.Errorf(codes.Internal, "Could not mount %s at %s: %v", source, target, err)
}
return nil
}

func (ns *LinodeNodeServer) NodeUnpublishVolume(ctx context.Context, req *csi.NodeUnpublishVolumeRequest) (*csi.NodeUnpublishVolumeResponse, error) {
ns.mux.Lock()
defer ns.mux.Unlock()
Expand Down Expand Up @@ -296,7 +280,12 @@ func (ns *LinodeNodeServer) NodeStageVolume(ctx context.Context, req *csi.NodeSt
*/
return &csi.NodeStageVolumeResponse{}, nil
}

// VolumeMode=block
// Do nothing else with the mount point for stage
if blk := volumeCapability.GetBlock(); blk != nil {
return &csi.NodeStageVolumeResponse{}, nil
}

// Part 3: Mount device to stagingTargetPath
Expand All @@ -308,9 +297,6 @@ func (ns *LinodeNodeServer) NodeStageVolume(ctx context.Context, req *csi.NodeSt
fstype = mnt.FsType
}
options = append(options, mnt.MountFlags...)
} else if blk := volumeCapability.GetBlock(); blk != nil {
// If the access type is block, do nothing for stage
return &csi.NodeStageVolumeResponse{}, nil
}

fmtAndMountSource := devicePath
Expand Down

0 comments on commit 1773c8d

Please sign in to comment.