Skip to content

Commit 6e361e2

Browse files
committed
Add support for raw block devices and enable block device tests on external k8s testing
1 parent ebd0c0f commit 6e361e2

File tree

3 files changed

+81
-27
lines changed

3 files changed

+81
-27
lines changed

pkg/gce-pd-csi-driver/node.go

+74-20
Original file line numberDiff line numberDiff line change
@@ -95,18 +95,60 @@ func (ns *GCENodeServer) NodePublishVolume(ctx context.Context, req *csi.NodePub
9595
return &csi.NodePublishVolumeResponse{}, nil
9696
}
9797

98-
if err := ns.Mounter.Interface.MakeDir(targetPath); err != nil {
99-
glog.Errorf("mkdir failed on disk %s (%v)", targetPath, err)
100-
return nil, err
101-
}
102-
10398
// Perform a bind mount to the full path to allow duplicate mounts of the same PD.
99+
fstype := ""
100+
sourcePath := ""
104101
options := []string{"bind"}
105102
if readOnly {
106103
options = append(options, "ro")
107104
}
108105

109-
err = ns.Mounter.Interface.Mount(stagingTargetPath, targetPath, "ext4", options)
106+
if mnt := volumeCapability.GetMount(); mnt != nil {
107+
if mnt.FsType != "" {
108+
fstype = mnt.FsType
109+
} else {
110+
// Default fstype is ext4
111+
fstype = "ext4"
112+
}
113+
114+
glog.V(4).Infof("NodePublishVolume with filesystem %s", fstype)
115+
116+
for _, flag := range mnt.MountFlags {
117+
options = append(options, flag)
118+
}
119+
120+
sourcePath = stagingTargetPath
121+
122+
if err := ns.Mounter.Interface.MakeDir(targetPath); err != nil {
123+
glog.Errorf("mkdir failed on disk %s (%v)", targetPath, err)
124+
return nil, err
125+
}
126+
} else if blk := volumeCapability.GetBlock(); blk != nil {
127+
glog.V(4).Infof("NodePublishVolume with block volume mode")
128+
129+
partition := ""
130+
if part, ok := req.GetVolumeContext()[common.VolumeAttributePartition]; ok {
131+
partition = part
132+
}
133+
134+
sourcePath, err = ns.getDevicePath(volumeID, partition)
135+
if err != nil {
136+
return nil, status.Error(codes.Internal, fmt.Sprintf("Error when getting device path: %v", err))
137+
}
138+
139+
// Expose block volume as file at target path
140+
err = ns.Mounter.MakeFile(targetPath)
141+
if err != nil {
142+
if removeErr := os.Remove(targetPath); removeErr != nil {
143+
return nil, status.Error(codes.Internal, fmt.Sprintf("Error removing block file at target path %v: %v", targetPath, removeErr))
144+
}
145+
return nil, status.Error(codes.Internal, fmt.Sprintf("Failed to create block file at target path %v: %v", targetPath, err))
146+
}
147+
} else {
148+
return nil, status.Error(codes.InvalidArgument, fmt.Sprintf("NodePublishVolume volume capability must specify either mount or block mode"))
149+
}
150+
151+
err = ns.Mounter.Interface.Mount(sourcePath, targetPath, fstype, options)
110152
if err != nil {
111153
notMnt, mntErr := ns.Mounter.Interface.IsLikelyNotMountPoint(targetPath)
112154
if mntErr != nil {
@@ -197,19 +239,9 @@ func (ns *GCENodeServer) NodeStageVolume(ctx context.Context, req *csi.NodeStage
197239
partition = part
198240
}
199241

200-
deviceName, err := common.GetDeviceName(volumeKey)
242+
devicePath, err := ns.getDevicePath(volumeID, partition)
201243
if err != nil {
202-
status.Error(codes.Internal, fmt.Sprintf("error getting device name: %v", err))
203-
}
204-
205-
devicePaths := ns.DeviceUtils.GetDiskByIdPaths(deviceName, partition)
206-
devicePath, err := ns.DeviceUtils.VerifyDevicePath(devicePaths)
207-
208-
if err != nil {
209-
return nil, status.Error(codes.Internal, fmt.Sprintf("Error verifying GCE PD (%q) is attached: %v", volumeKey.Name, err))
210-
}
211-
if devicePath == "" {
212-
return nil, status.Error(codes.Internal, fmt.Sprintf("Unable to find device path out of attempted paths: %v", devicePaths))
244+
return nil, status.Error(codes.Internal, fmt.Sprintf("Error when getting device path: %v", err))
213245
}
214246

215247
glog.V(4).Infof("Successfully found attached GCE PD %q at device path %s.", volumeKey.Name, devicePath)
@@ -251,8 +283,8 @@ func (ns *GCENodeServer) NodeStageVolume(ctx context.Context, req *csi.NodeStage
251283
options = append(options, flag)
252284
}
253285
} else if blk := volumeCapability.GetBlock(); blk != nil {
254-
// TODO(#64): Block volume support
255-
return nil, status.Error(codes.Unimplemented, fmt.Sprintf("Block volume support is not yet implemented"))
286+
// Noop for Block NodeStageVolume
287+
return &csi.NodeStageVolumeResponse{}, nil
256288
}
257289

258290
err = ns.Mounter.FormatAndMount(devicePath, stagingTargetPath, fstype, options)
@@ -333,3 +365,25 @@ func (ns *GCENodeServer) GetVolumeLimits() (int64, error) {
333365
}
334366
return volumeLimits, nil
335367
}
368+
369+
func (ns *GCENodeServer) getDevicePath(volumeID string, partition string) (string, error) {
370+
volumeKey, err := common.VolumeIDToKey(volumeID)
371+
if err != nil {
372+
return "", err
373+
}
374+
deviceName, err := common.GetDeviceName(volumeKey)
375+
if err != nil {
376+
return "", fmt.Errorf("error getting device name: %v", err)
377+
}
378+
379+
devicePaths := ns.DeviceUtils.GetDiskByIdPaths(deviceName, partition)
380+
devicePath, err := ns.DeviceUtils.VerifyDevicePath(devicePaths)
381+
382+
if err != nil {
383+
return "", fmt.Errorf("error verifying GCE PD (%q) is attached: %v", volumeKey.Name, err)
384+
}
385+
if devicePath == "" {
386+
return "", fmt.Errorf("unable to find device path out of attempted paths: %v", devicePaths)
387+
}
388+
return devicePath, nil
389+
}

pkg/gce-pd-csi-driver/utils.go

+6-6
Original file line numberDiff line numberDiff line change
@@ -104,13 +104,13 @@ func validateVolumeCapability(vc *csi.VolumeCapability) error {
104104
if err := validateAccessMode(vc.GetAccessMode()); err != nil {
105105
return err
106106
}
107-
if blk := vc.GetBlock(); blk != nil {
108-
// TODO(#64): Block volume support
109-
return errors.New("Block volume support is not yet implemented")
107+
blk := vc.GetBlock()
108+
mnt := vc.GetMount()
109+
if mnt == nil && blk == nil {
110+
return errors.New("must specify an access type")
110111
}
111-
if mnt := vc.GetMount(); mnt == nil {
112-
// TODO(#64): Change error message after block volume support
113-
return errors.New("Must specify an access type of Mount")
112+
if mnt != nil && blk != nil {
113+
return errors.New("specified both Mount and Block access types")
114114
}
115115
return nil
116116
}

test/k8s-integration/config/test-config-template.in

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,6 @@ DriverInfo:
1616
multipods: true
1717
fsGroup: true
1818
exec: true
19-
# block: true
19+
block: true
2020
# dataSource: true
2121
# RWX: true

0 commit comments

Comments
 (0)