Skip to content

Commit

Permalink
filesystem is not resized when restoring from snapshot/cloning to lar…
Browse files Browse the repository at this point in the history
…ger size than origin (#100)

* remove unnecessary code

VolumeMountUtils is already instantiated in init() of ibmcsidriver
module so there is no need for this line of code.

* allow creating driver with fake commands

In order to allow testing of code that includes command sequence we
need to change the driver so it can accept a list of fake commands.

* resize fs in NodeStageVolume

This is the actual fix for resizing filesystem when volume is restored
from a snapshot to larger size

* resize with mounter during node expand

* cleanup resize code

* update to latest ibm-csi-common
  • Loading branch information
RomanBednar committed Jan 9, 2023
1 parent 886f02c commit 50dc6d1
Show file tree
Hide file tree
Showing 9 changed files with 124 additions and 48 deletions.
4 changes: 2 additions & 2 deletions go.mod
Expand Up @@ -3,7 +3,7 @@ module github.com/kubernetes-sigs/ibm-vpc-block-csi-driver
go 1.18

require (
github.com/IBM/ibm-csi-common v1.1.2
github.com/IBM/ibm-csi-common v1.1.3
github.com/IBM/ibmcloud-volume-interface v1.1.1
github.com/IBM/ibmcloud-volume-vpc v1.1.2
github.com/container-storage-interface/spec v1.6.0
Expand All @@ -19,6 +19,7 @@ require (
google.golang.org/protobuf v1.28.1
k8s.io/kubernetes v1.25.4
k8s.io/mount-utils v0.25.4
k8s.io/utils v0.0.0-20220728103510-ee6ede2d64ed
)

require (
Expand Down Expand Up @@ -102,7 +103,6 @@ require (
k8s.io/component-base v0.25.4 // indirect
k8s.io/klog/v2 v2.70.1 // indirect
k8s.io/kube-openapi v0.0.0-20220803162953-67bda5d908f1 // indirect
k8s.io/utils v0.0.0-20220728103510-ee6ede2d64ed // indirect
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect
sigs.k8s.io/yaml v1.2.0 // indirect
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Expand Up @@ -39,8 +39,8 @@ github.com/IBM-Cloud/ibm-cloud-cli-sdk v0.6.7 h1:eHgfQl6IeSmzWUyiSi13CvoFYsovoyq
github.com/IBM-Cloud/ibm-cloud-cli-sdk v0.6.7/go.mod h1:RiUvKuHKTBmBApDMUQzBL14pQUGKcx/IioKQPIcRQjs=
github.com/IBM/go-sdk-core/v5 v5.9.1 h1:06pXbD9Rgmqqe2HA5YAeQbB4eYRRFgIoOT+Kh3cp1zo=
github.com/IBM/go-sdk-core/v5 v5.9.1/go.mod h1:axE2JrRq79gIJTjKPBwV6gWHswvVptBjbcvvCPIxARM=
github.com/IBM/ibm-csi-common v1.1.2 h1:g74+5uIaKZnZ3aIJyBZkpA2///wsG0fyDCJB8AQJW0Q=
github.com/IBM/ibm-csi-common v1.1.2/go.mod h1:5Ld7WgeLVO8uLoQtqGZhJgHQyCqwUEv1fBq1YpwIqQ0=
github.com/IBM/ibm-csi-common v1.1.3 h1:03vsgi46mFWcp66D2+DR6bkXyBKK/9TbYhm8Qyvrx7s=
github.com/IBM/ibm-csi-common v1.1.3/go.mod h1:5Ld7WgeLVO8uLoQtqGZhJgHQyCqwUEv1fBq1YpwIqQ0=
github.com/IBM/ibmcloud-volume-interface v1.1.1 h1:RlwEj8bq+aASdb90Lng4rINMYR96/G6yUvyk/ATmptA=
github.com/IBM/ibmcloud-volume-interface v1.1.1/go.mod h1:coaQ/FD5NRgFfaAnjkoxv+e6MNSl2UAeQwC38szQ5G8=
github.com/IBM/ibmcloud-volume-vpc v1.1.2 h1:LbgRC/CQRptt6+lfg6k/LL2W2GyDNrxirzJXZtDY9ik=
Expand Down
12 changes: 10 additions & 2 deletions pkg/ibmcsidriver/ibm_csi_driver_test.go
Expand Up @@ -18,6 +18,7 @@ limitations under the License.
package ibmcsidriver

import (
testingexec "k8s.io/utils/exec/testing"
"testing"

cloudProvider "github.com/IBM/ibm-csi-common/pkg/ibmcloudprovider"
Expand All @@ -27,7 +28,7 @@ import (
"github.com/stretchr/testify/assert"
)

func initIBMCSIDriver(t *testing.T) *IBMCSIDriver {
func initIBMCSIDriver(t *testing.T, fakeActions ...testingexec.FakeCommandAction) *IBMCSIDriver {
vendorVersion := "test-vendor-version-1.1.2"
driver := "mydriver"
// Creating test logger
Expand All @@ -36,7 +37,14 @@ func initIBMCSIDriver(t *testing.T) *IBMCSIDriver {
icDriver := GetIBMCSIDriver()
// Create fake provider and mounter
provider, _ := cloudProvider.NewFakeIBMCloudStorageProvider("", logger)
mounter := mountManager.NewFakeNodeMounter()

var mounter mountManager.Mounter
if len(fakeActions) != 0 {
mounter = mountManager.NewFakeNodeMounterWithCustomActions(fakeActions)
} else {
mounter = mountManager.NewFakeNodeMounter()
}

statsUtil := &MockStatUtils{}

fakeNodeData := nodeMetadata.FakeNodeMetadata{}
Expand Down
25 changes: 5 additions & 20 deletions pkg/ibmcsidriver/node.go
Expand Up @@ -60,11 +60,6 @@ type StatsUtils interface {
IsDevicePathNotExist(devicePath string) bool
}

// MountUtils ...
type MountUtils interface {
Resize(mounter mountmanager.Mounter, devicePath string, deviceMountPath string) (bool, error)
}

// VolumeStatUtils ...
type VolumeStatUtils struct {
}
Expand Down Expand Up @@ -105,11 +100,6 @@ const (
)

var _ csi.NodeServer = &CSINodeServer{}
var mountmgr MountUtils

func init() {
mountmgr = &VolumeMountUtils{}
}

// NodePublishVolume ...
func (csiNS *CSINodeServer) NodePublishVolume(ctx context.Context, req *csi.NodePublishVolumeRequest) (*csi.NodePublishVolumeResponse, error) {
Expand Down Expand Up @@ -307,6 +297,10 @@ func (csiNS *CSINodeServer) NodeStageVolume(ctx context.Context, req *csi.NodeSt
return nil, commonError.GetCSIError(ctxLogger, commonError.FormatAndMountFailed, requestID, err, source, stagingTargetPath)
}

if _, err := csiNS.Mounter.Resize(devicePath, stagingTargetPath); err != nil {
return nil, commonError.GetCSIError(ctxLogger, commonError.FileSystemResizeFailed, requestID, err)
}

nodeStageVolumeResponse := &csi.NodeStageVolumeResponse{}
return nodeStageVolumeResponse, err
}
Expand Down Expand Up @@ -497,7 +491,7 @@ func (csiNS *CSINodeServer) NodeExpandVolume(ctx context.Context, req *csi.NodeE
return nil, commonError.GetCSIError(ctxLogger, commonError.EmptyDevicePath, requestID, err)
}

if _, err := mountmgr.Resize(csiNS.Mounter, devicePath, volumePath); err != nil {
if _, err := csiNS.Mounter.Resize(devicePath, volumePath); err != nil {
return nil, commonError.GetCSIError(ctxLogger, commonError.FileSystemResizeFailed, requestID, err)
}
return &csi.NodeExpandVolumeResponse{CapacityBytes: req.CapacityRange.RequiredBytes}, nil
Expand Down Expand Up @@ -541,12 +535,3 @@ func (su *VolumeStatUtils) IsDevicePathNotExist(devicePath string) bool {
}
return false
}

// Resize expands the fs
func (volMountUtils *VolumeMountUtils) Resize(mounter mountmanager.Mounter, devicePath string, deviceMountPath string) (bool, error) {
r := mount.NewResizeFs(mounter.GetSafeFormatAndMount().Exec)
if _, err := r.Resize(devicePath, deviceMountPath); err != nil {
return false, err
}
return true, nil
}
117 changes: 100 additions & 17 deletions pkg/ibmcsidriver/node_test.go
Expand Up @@ -20,13 +20,14 @@ package ibmcsidriver
import (
"errors"
"fmt"
"k8s.io/utils/exec"
testingexec "k8s.io/utils/exec/testing"
"os"
"reflect"
"runtime"
"strings"
"testing"

"github.com/IBM/ibm-csi-common/pkg/mountmanager"
"github.com/IBM/ibm-csi-common/pkg/utils"
csi "github.com/container-storage-interface/spec/lib/go/csi"
"github.com/stretchr/testify/assert"
Expand All @@ -47,19 +48,6 @@ const notBlockDevice = "/for/notblocktest"
type MockStatUtils struct {
}

type MockMountUtils struct {
}

// Resize expands the fs
func (mu *MockMountUtils) Resize(mounter mountmanager.Mounter, devicePath string, deviceMountPath string) (bool, error) {
if strings.Contains(deviceMountPath, "fake-") {
return false, fmt.Errorf("failed to resize fs")
} else if strings.Contains(deviceMountPath, "valid-") {
return true, nil
}
return false, fmt.Errorf("failed to resize fs")
}

func (su *MockStatUtils) FSInfo(path string) (int64, int64, int64, int64, int64, int64, error) {
return 1, 1, 1, 1, 1, 1, nil
}
Expand Down Expand Up @@ -347,7 +335,60 @@ func TestNodeStageVolume(t *testing.T) {
},
}

icDriver := initIBMCSIDriver(t)
actionList := []testingexec.FakeCommandAction{
makeFakeCmd(
&testingexec.FakeCmd{
CombinedOutputScript: []testingexec.FakeAction{
func() ([]byte, []byte, error) {
return []byte("DEVNAME=/dev/sdb\nTYPE=ext4"), nil, nil
},
},
},
"blkid",
),
makeFakeCmd(
&testingexec.FakeCmd{
CombinedOutputScript: []testingexec.FakeAction{
func() ([]byte, []byte, error) {
return []byte("1"), nil, nil
},
},
},
"mkfs.ext2",
),
makeFakeCmd(
&testingexec.FakeCmd{
CombinedOutputScript: []testingexec.FakeAction{
func() ([]byte, []byte, error) {
return []byte("1"), nil, nil
},
},
},
"blockdev",
),
makeFakeCmd(
&testingexec.FakeCmd{
CombinedOutputScript: []testingexec.FakeAction{
func() ([]byte, []byte, error) {
return []byte("DEVNAME=/dev/sdb\nTYPE=ext4"), nil, nil
},
},
},
"blkid",
),
makeFakeCmd(
&testingexec.FakeCmd{
CombinedOutputScript: []testingexec.FakeAction{
func() ([]byte, []byte, error) {
return []byte("block size: 1\nblock count: 1"), nil, nil
},
},
},
"dumpe2fs",
),
}

icDriver := initIBMCSIDriver(t, actionList...)
for _, tc := range testCases {
t.Logf("Test case: %s", tc.name)
_, err := icDriver.ns.NodeStageVolume(context.Background(), tc.req)
Expand Down Expand Up @@ -649,10 +690,43 @@ func TestNodeExpandVolume(t *testing.T) {
expErrCode: codes.NotFound,
},
}
icDriver := initIBMCSIDriver(t)

actionList := []testingexec.FakeCommandAction{
makeFakeCmd(
&testingexec.FakeCmd{
CombinedOutputScript: []testingexec.FakeAction{
func() ([]byte, []byte, error) {
return []byte("1"), nil, nil
},
},
},
"blockdev",
),
makeFakeCmd(
&testingexec.FakeCmd{
CombinedOutputScript: []testingexec.FakeAction{
func() ([]byte, []byte, error) {
return []byte("DEVNAME=/dev/sdb\nTYPE=ext4"), nil, nil
},
},
},
"blkid",
),
makeFakeCmd(
&testingexec.FakeCmd{
CombinedOutputScript: []testingexec.FakeAction{
func() ([]byte, []byte, error) {
return []byte("block size: 1\nblock count: 1"), nil, nil
},
},
},
"dumpe2fs",
),
}

icDriver := initIBMCSIDriver(t, actionList...)
_ = os.MkdirAll("valid-vol-path", os.FileMode(0755))
_ = icDriver.ns.Mounter.Mount("valid-devicePath", "valid-vol-path", "ext4", []string{})
mountmgr = &MockMountUtils{}
for _, tc := range testCases {
t.Logf("Test case: %s", tc.name)
_, err := icDriver.ns.NodeExpandVolume(context.Background(), tc.req)
Expand Down Expand Up @@ -762,3 +836,12 @@ func TestDeviceInfo(t *testing.T) {
}*/
}
}

func makeFakeCmd(fakeCmd *testingexec.FakeCmd, cmd string, args ...string) testingexec.FakeCommandAction {
c := cmd
a := args
return func(cmd string, args ...string) exec.Cmd {
command := testingexec.InitFakeCmd(fakeCmd, c, a...)
return command
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion vendor/modules.txt
Expand Up @@ -8,7 +8,7 @@ github.com/IBM-Cloud/ibm-cloud-cli-sdk/common/rest
# github.com/IBM/go-sdk-core/v5 v5.9.1
## explicit; go 1.14
github.com/IBM/go-sdk-core/v5/core
# github.com/IBM/ibm-csi-common v1.1.2
# github.com/IBM/ibm-csi-common v1.1.3
## explicit; go 1.18
github.com/IBM/ibm-csi-common/pkg/ibmcloudprovider
github.com/IBM/ibm-csi-common/pkg/messages
Expand Down

0 comments on commit 50dc6d1

Please sign in to comment.