diff --git a/pkg/gce-pd-csi-driver/node.go b/pkg/gce-pd-csi-driver/node.go index b5ce9938e..e6c7c19d1 100644 --- a/pkg/gce-pd-csi-driver/node.go +++ b/pkg/gce-pd-csi-driver/node.go @@ -18,8 +18,6 @@ import ( "fmt" "os" "runtime" - "strconv" - "strings" "context" @@ -398,7 +396,7 @@ func (ns *GCENodeServer) NodeGetVolumeStats(ctx context.Context, req *csi.NodeGe return nil, status.Errorf(codes.Internal, "failed to determine whether %s is block device: %v", req.VolumePath, err) } if isBlock { - bcap, err := ns.getBlockSizeBytes(req.VolumePath) + bcap, err := getBlockSizeBytes(req.VolumePath, ns.Mounter) if err != nil { return nil, status.Errorf(codes.Internal, "failed to get block capacity on path %s: %v", req.VolumePath, err) } @@ -482,14 +480,10 @@ func (ns *GCENodeServer) NodeExpandVolume(ctx context.Context, req *csi.NodeExpa } - // Check the block size - gotBlockSizeBytes, err := ns.getBlockSizeBytes(devicePath) - if err != nil { - return nil, status.Error(codes.Internal, fmt.Sprintf("error when getting size of block volume at path %s: %v", devicePath, err)) - } - if gotBlockSizeBytes < reqBytes { + diskSizeBytes, err := getBlockSizeBytes(devicePath, ns.Mounter) + if diskSizeBytes < reqBytes { // It's possible that the somewhere the volume size was rounded up, getting more size than requested is a success :) - return nil, status.Errorf(codes.Internal, "resize requested for %v but after resize volume was size %v", reqBytes, gotBlockSizeBytes) + return nil, status.Errorf(codes.Internal, "resize requested for %v but after resize volume was size %v", reqBytes, diskSizeBytes) } // TODO(dyzz) Some sort of formatted volume could also check the fs size. @@ -531,16 +525,3 @@ func (ns *GCENodeServer) GetVolumeLimits() (int64, error) { } return volumeLimitBig, nil } - -func (ns *GCENodeServer) getBlockSizeBytes(devicePath string) (int64, error) { - output, err := ns.Mounter.Exec.Command("blockdev", "--getsize64", devicePath).CombinedOutput() - if err != nil { - return -1, fmt.Errorf("error when getting size of block volume at path %s: output: %s, err: %v", devicePath, string(output), err) - } - strOut := strings.TrimSpace(string(output)) - gotSizeBytes, err := strconv.ParseInt(strOut, 10, 64) - if err != nil { - return -1, fmt.Errorf("failed to parse %s into an int size", strOut) - } - return gotSizeBytes, nil -} diff --git a/pkg/gce-pd-csi-driver/utils_linux.go b/pkg/gce-pd-csi-driver/utils_linux.go index f4ea59489..c6f813855 100644 --- a/pkg/gce-pd-csi-driver/utils_linux.go +++ b/pkg/gce-pd-csi-driver/utils_linux.go @@ -18,6 +18,8 @@ package gceGCEDriver import ( "fmt" "os" + "strconv" + "strings" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" @@ -64,3 +66,16 @@ func cleanupPublishPath(path string, m *mount.SafeFormatAndMount) error { func cleanupStagePath(path string, m *mount.SafeFormatAndMount) error { return cleanupPublishPath(path, m) } + +func getBlockSizeBytes(devicePath string, m *mount.SafeFormatAndMount) (int64, error) { + output, err := m.Exec.Command("blockdev", "--getsize64", devicePath).CombinedOutput() + if err != nil { + return -1, fmt.Errorf("error when getting size of block volume at path %s: output: %s, err: %v", devicePath, string(output), err) + } + strOut := strings.TrimSpace(string(output)) + gotSizeBytes, err := strconv.ParseInt(strOut, 10, 64) + if err != nil { + return -1, fmt.Errorf("failed to parse %s into an int size", strOut) + } + return gotSizeBytes, nil +} diff --git a/pkg/gce-pd-csi-driver/utils_windows.go b/pkg/gce-pd-csi-driver/utils_windows.go index cfcd0c833..9146c468f 100644 --- a/pkg/gce-pd-csi-driver/utils_windows.go +++ b/pkg/gce-pd-csi-driver/utils_windows.go @@ -87,3 +87,12 @@ func getDevicePath(ns *GCENodeServer, volumeID, partition string) (string, error } return proxy.GetDevicePath(deviceName, partition, volumeKey.Name) } + +func getBlockSizeBytes(devicePath string, m *mount.SafeFormatAndMount) (int64, error) { + proxy, ok := m.Interface.(*mounter.CSIProxyMounter) + if !ok { + return 0, fmt.Errorf("could not cast to csi proxy class") + } + + return proxy.GetBlockSizeBytes(devicePath) +} diff --git a/pkg/mount-manager/safe-mounter_windows.go b/pkg/mount-manager/safe-mounter_windows.go index fbc278809..eb827c505 100644 --- a/pkg/mount-manager/safe-mounter_windows.go +++ b/pkg/mount-manager/safe-mounter_windows.go @@ -251,3 +251,11 @@ func (mounter *CSIProxyMounter) ExistsPath(path string) (bool, error) { }) return isExistsResponse.Exists, err } + +func (mounter *CSIProxyMounter) GetBlockSizeBytes(diskId string) (int64, error) { + DiskStatsResponse, err := mounter.DiskClient.DiskStats(context.Background(), + &diskapi.DiskStatsRequest{ + DiskID: diskId, + }) + return DiskStatsResponse.DiskSize, err +} diff --git a/pkg/resizefs/resizefs.go b/pkg/resizefs/resizefs.go new file mode 100644 index 000000000..50326a773 --- /dev/null +++ b/pkg/resizefs/resizefs.go @@ -0,0 +1,19 @@ +/* +Copyright 2020 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package resizefs + +type Resizefs interface { + Resize(devicePath, deviceMountPath string) (bool, error) +} diff --git a/pkg/resizefs/resizefs_linux.go b/pkg/resizefs/resizefs_linux.go index 5ec8a3877..9478913e6 100644 --- a/pkg/resizefs/resizefs_linux.go +++ b/pkg/resizefs/resizefs_linux.go @@ -25,18 +25,20 @@ import ( "k8s.io/utils/mount" ) +var _ Resizefs = &resizeFs{} + // ResizeFs Provides support for resizing file systems -type ResizeFs struct { +type resizeFs struct { mounter *mount.SafeFormatAndMount } // NewResizeFs returns new instance of resizer -func NewResizeFs(mounter *mount.SafeFormatAndMount) *ResizeFs { - return &ResizeFs{mounter: mounter} +func NewResizeFs(mounter *mount.SafeFormatAndMount) *resizeFs { + return &resizeFs{mounter: mounter} } // Resize perform resize of file system -func (resizefs *ResizeFs) Resize(devicePath string, deviceMountPath string) (bool, error) { +func (resizefs *resizeFs) Resize(devicePath, deviceMountPath string) (bool, error) { format, err := resizefs.mounter.GetDiskFormat(devicePath) if err != nil { @@ -60,7 +62,7 @@ func (resizefs *ResizeFs) Resize(devicePath string, deviceMountPath string) (boo return false, fmt.Errorf("ResizeFS.Resize - resize of format %s is not supported for device %s mounted at %s", format, devicePath, deviceMountPath) } -func (resizefs *ResizeFs) extResize(devicePath string) (bool, error) { +func (resizefs *resizeFs) extResize(devicePath string) (bool, error) { output, err := resizefs.mounter.Exec.Command("resize2fs", devicePath).CombinedOutput() if err == nil { klog.V(2).Infof("Device %s resized successfully", devicePath) @@ -72,7 +74,7 @@ func (resizefs *ResizeFs) extResize(devicePath string) (bool, error) { } -func (resizefs *ResizeFs) xfsResize(deviceMountPath string) (bool, error) { +func (resizefs *resizeFs) xfsResize(deviceMountPath string) (bool, error) { args := []string{"-d", deviceMountPath} output, err := resizefs.mounter.Exec.Command("xfs_growfs", args...).CombinedOutput() diff --git a/pkg/resizefs/resizefs_unsupported.go b/pkg/resizefs/resizefs_unsupported.go deleted file mode 100644 index cde1d4ca0..000000000 --- a/pkg/resizefs/resizefs_unsupported.go +++ /dev/null @@ -1,40 +0,0 @@ -// +build !linux - -/* -Copyright 2017 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package resizefs - -import ( - "fmt" - - "k8s.io/utils/mount" -) - -// ResizeFs Provides support for resizing file systems -type ResizeFs struct { - mounter *mount.SafeFormatAndMount -} - -// NewResizeFs returns new instance of resizer -func NewResizeFs(mounter *mount.SafeFormatAndMount) *ResizeFs { - return &ResizeFs{mounter: mounter} -} - -// Resize perform resize of file system -func (resizefs *ResizeFs) Resize(devicePath string, deviceMountPath string) (bool, error) { - return false, fmt.Errorf("Resize is not supported for this build") -} diff --git a/pkg/resizefs/resizefs_windows.go b/pkg/resizefs/resizefs_windows.go new file mode 100644 index 000000000..4e5423cf6 --- /dev/null +++ b/pkg/resizefs/resizefs_windows.go @@ -0,0 +1,69 @@ +// +build windows + +/* +Copyright 2020 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package resizefs + +import ( + "context" + "fmt" + + volumeapi "github.com/kubernetes-csi/csi-proxy/client/api/volume/v1beta1" + "k8s.io/klog" + "k8s.io/utils/mount" + mounter "sigs.k8s.io/gcp-compute-persistent-disk-csi-driver/pkg/mount-manager" +) + +var _ Resizefs = &resizeFs{} + +// ResizeFs Provides support for resizing file systems +type resizeFs struct { + mounter *mount.SafeFormatAndMount +} + +// NewResizeFs returns new instance of resizer +func NewResizeFs(mounter *mount.SafeFormatAndMount) *resizeFs { + return &resizeFs{mounter: mounter} +} + +// resize perform resize of file system +func (resizefs *resizeFs) Resize(devicePath string, deviceMountPath string) (bool, error) { + klog.V(3).Infof("resizeFS.Resize - Expanding mounted volume %s", deviceMountPath) + + proxy, ok := resizefs.mounter.Interface.(*mounter.CSIProxyMounter) + if !ok { + return false, fmt.Errorf("could not cast to csi proxy class") + } + + idRequest := &volumeapi.VolumeIDFromMountRequest{ + Mount: deviceMountPath, + } + idResponse, err := proxy.VolumeClient.GetVolumeIDFromMount(context.Background(), idRequest) + if err != nil { + return false, err + } + volumeId := idResponse.GetVolumeId() + + request := &volumeapi.ResizeVolumeRequest{ + VolumeId: volumeId, + } + _, err = proxy.VolumeClient.ResizeVolume(context.Background(), request) + if err != nil { + return false, err + } + return true, nil +}