From e3160bef6a5018f624dd872ce6a7c7bd1753c1fa Mon Sep 17 00:00:00 2001 From: sujeet01 Date: Tue, 24 Sep 2024 21:42:50 +0530 Subject: [PATCH] Add mkfs options parameter to volume context --- Makefile | 2 +- pkg/driver/constants.go | 2 ++ pkg/driver/controller.go | 6 ++++++ pkg/driver/node.go | 16 ++++++++++++---- pkg/driver/node_test.go | 4 ++-- pkg/utils/mount/mock_mountutils_unix.go | 12 ++++++------ pkg/utils/mount/mountutils_unix.go | 2 +- 7 files changed, 30 insertions(+), 14 deletions(-) diff --git a/Makefile b/Makefile index 0549467..76bece4 100755 --- a/Makefile +++ b/Makefile @@ -53,7 +53,7 @@ build-linux: CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o $(BINARY_NAME) -v ./cmd/ docker-build: - docker build $(BUILDARGS) -t ${IMG} -f Dockerfile . + docker build $(BUILDARGS) -t ${IMG} -f Dockerfile . --load docker-push: docker push ${IMG} diff --git a/pkg/driver/constants.go b/pkg/driver/constants.go index f37b8fe..d82ef41 100644 --- a/pkg/driver/constants.go +++ b/pkg/driver/constants.go @@ -33,6 +33,8 @@ const ( ParameterNodeID = "node_id" // ParameterDeviceName is the device name parameter ParameterDeviceName = "device_name" + // ParameterMkfsOptions is the name of the parameter used to specify the options for the mkfs command + ParameterMkfsOptions = "mkfs_options" CSIDriverName = "csi.ironcore.dev" topologyKey = "topology." + CSIDriverName + "/zone" diff --git a/pkg/driver/controller.go b/pkg/driver/controller.go index 39b6fdf..79e952d 100755 --- a/pkg/driver/controller.go +++ b/pkg/driver/controller.go @@ -57,6 +57,11 @@ func (d *driver) CreateVolume(ctx context.Context, req *csi.CreateVolumeRequest) fstype = FSTypeExt4 } + mkfsOptions, ok := params[ParameterMkfsOptions] + if !ok { + mkfsOptions = "" + } + volumeClass, ok := params[ParameterType] if !ok { return nil, status.Errorf(codes.Internal, "Required parameter %s is missing", ParameterType) @@ -136,6 +141,7 @@ func (d *driver) CreateVolume(ctx context.Context, req *csi.CreateVolumeRequest) ParameterVolumePool: volumePoolName, ParameterCreationTime: time.Unix(volume.CreationTimestamp.Unix(), 0).String(), ParameterFSType: fstype, + ParameterMkfsOptions: mkfsOptions, }, ContentSource: req.GetVolumeContentSource(), AccessibleTopology: accessibleTopology, diff --git a/pkg/driver/node.go b/pkg/driver/node.go index 53f725b..38e1049 100755 --- a/pkg/driver/node.go +++ b/pkg/driver/node.go @@ -9,6 +9,7 @@ import ( "io" "os" "path/filepath" + "strings" "github.com/container-storage-interface/spec/lib/go/csi" "golang.org/x/sys/unix" @@ -33,7 +34,8 @@ var ( func (d *driver) NodeStageVolume(_ context.Context, req *csi.NodeStageVolumeRequest) (*csi.NodeStageVolumeResponse, error) { klog.InfoS("Staging volume on node ", "Volume", req.GetVolumeId(), "StagingTargetPath", req.GetStagingTargetPath()) - fstype := req.GetVolumeContext()[ParameterFSType] + volumeContext := req.GetVolumeContext() + fstype := volumeContext[ParameterFSType] devicePath := req.PublishContext[ParameterDeviceName] klog.InfoS("Check if the device path exists") @@ -47,7 +49,7 @@ func (d *driver) NodeStageVolume(_ context.Context, req *csi.NodeStageVolumeRequ } readOnly := false - if req.GetVolumeContext()["readOnly"] == "true" { + if volumeContext["readOnly"] == "true" { readOnly = true } mountOptions := req.GetVolumeCapability().GetMount().GetMountFlags() @@ -69,15 +71,21 @@ func (d *driver) NodeStageVolume(_ context.Context, req *csi.NodeStageVolumeRequ } var options []string - if readOnly { options = append(options, "ro") } else { options = append(options, "rw") } options = append(options, mountOptions...) + + var formatOptions []string + mkfsOptions, exists := volumeContext[ParameterMkfsOptions] + if exists && mkfsOptions != "" { + formatOptions = append(formatOptions, strings.Split(mkfsOptions, " ")...) + } + klog.InfoS("Format and mount the volume") - if err = d.mounter.FormatAndMount(devicePath, targetPath, fstype, options); err != nil { + if err = d.mounter.FormatAndMountSensitiveWithFormatOptions(devicePath, targetPath, fstype, options, nil, formatOptions); err != nil { return nil, status.Errorf(codes.Internal, "Failed to mount volume %s [%s] to %s: %v", devicePath, fstype, targetPath, err) } klog.InfoS("Staged volume on node", "Volume", req.GetVolumeId()) diff --git a/pkg/driver/node_test.go b/pkg/driver/node_test.go index 51efed4..0badeff 100644 --- a/pkg/driver/node_test.go +++ b/pkg/driver/node_test.go @@ -114,7 +114,7 @@ var _ = Describe("Node", func() { It("should fail if the mount operation fails", func(ctx SpecContext) { mockMounter.EXPECT().IsLikelyNotMountPoint(targetPath).Return(true, nil) mockOS.EXPECT().MkdirAll(targetPath, os.FileMode(0750)).Return(nil) - mockMounter.EXPECT().FormatAndMount(devicePath, targetPath, fstype, mountOptions).Return(errors.New("failed to mount volume")) + mockMounter.EXPECT().FormatAndMountSensitiveWithFormatOptions(devicePath, targetPath, fstype, mountOptions, nil, nil).Return(errors.New("failed to mount volume")) _, err := drv.NodeStageVolume(ctx, req) Expect(err).To(HaveOccurred()) Expect(err.Error()).To(ContainSubstring("Failed to mount volume")) @@ -126,7 +126,7 @@ var _ = Describe("Node", func() { It("should stage the volume", func(ctx SpecContext) { mockMounter.EXPECT().IsLikelyNotMountPoint(targetPath).Return(true, nil) mockOS.EXPECT().MkdirAll(targetPath, os.FileMode(0750)).Return(nil) - mockMounter.EXPECT().FormatAndMount(devicePath, targetPath, fstype, mountOptions).Return(nil) + mockMounter.EXPECT().FormatAndMountSensitiveWithFormatOptions(devicePath, targetPath, fstype, mountOptions, nil, nil).Return(nil) _, err := drv.NodeStageVolume(ctx, req) Expect(err).NotTo(HaveOccurred()) }) diff --git a/pkg/utils/mount/mock_mountutils_unix.go b/pkg/utils/mount/mock_mountutils_unix.go index c23fbb6..d2e0b50 100644 --- a/pkg/utils/mount/mock_mountutils_unix.go +++ b/pkg/utils/mount/mock_mountutils_unix.go @@ -58,18 +58,18 @@ func (mr *MockMountWrapperMockRecorder) CanSafelySkipMountPointCheck() *gomock.C return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CanSafelySkipMountPointCheck", reflect.TypeOf((*MockMountWrapper)(nil).CanSafelySkipMountPointCheck)) } -// FormatAndMount mocks base method. -func (m *MockMountWrapper) FormatAndMount(source, target, fstype string, options []string) error { +// FormatAndMountSensitiveWithFormatOptions mocks base method. +func (m *MockMountWrapper) FormatAndMountSensitiveWithFormatOptions(source, target, fstype string, options, sensitiveOptions, formatOptions []string) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "FormatAndMount", source, target, fstype, options) + ret := m.ctrl.Call(m, "FormatAndMountSensitiveWithFormatOptions", source, target, fstype, options, sensitiveOptions, formatOptions) ret0, _ := ret[0].(error) return ret0 } -// FormatAndMount indicates an expected call of FormatAndMount. -func (mr *MockMountWrapperMockRecorder) FormatAndMount(source, target, fstype, options any) *gomock.Call { +// FormatAndMountSensitiveWithFormatOptions indicates an expected call of FormatAndMountSensitiveWithFormatOptions. +func (mr *MockMountWrapperMockRecorder) FormatAndMountSensitiveWithFormatOptions(source, target, fstype, options, sensitiveOptions, formatOptions any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FormatAndMount", reflect.TypeOf((*MockMountWrapper)(nil).FormatAndMount), source, target, fstype, options) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FormatAndMountSensitiveWithFormatOptions", reflect.TypeOf((*MockMountWrapper)(nil).FormatAndMountSensitiveWithFormatOptions), source, target, fstype, options, sensitiveOptions, formatOptions) } // GetMountRefs mocks base method. diff --git a/pkg/utils/mount/mountutils_unix.go b/pkg/utils/mount/mountutils_unix.go index 4582909..c0c3f51 100644 --- a/pkg/utils/mount/mountutils_unix.go +++ b/pkg/utils/mount/mountutils_unix.go @@ -18,7 +18,7 @@ import ( // SafeFormatAndMount). Defined it explicitly so that it can be mocked. type MountWrapper interface { k8smountutils.Interface - FormatAndMount(source string, target string, fstype string, options []string) error + FormatAndMountSensitiveWithFormatOptions(source string, target string, fstype string, options []string, sensitiveOptions []string, formatOptions []string) error NewResizeFs() (Resizefs, error) }