Skip to content

Commit 929d795

Browse files
authored
Merge pull request #637 from jingxu97/oct/resize
Add Volume Resize support for Windows
2 parents ff0b719 + 96b49ad commit 929d795

File tree

8 files changed

+132
-69
lines changed

8 files changed

+132
-69
lines changed

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

+4-23
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,6 @@ import (
1818
"fmt"
1919
"os"
2020
"runtime"
21-
"strconv"
22-
"strings"
2321

2422
"context"
2523

@@ -398,7 +396,7 @@ func (ns *GCENodeServer) NodeGetVolumeStats(ctx context.Context, req *csi.NodeGe
398396
return nil, status.Errorf(codes.Internal, "failed to determine whether %s is block device: %v", req.VolumePath, err)
399397
}
400398
if isBlock {
401-
bcap, err := ns.getBlockSizeBytes(req.VolumePath)
399+
bcap, err := getBlockSizeBytes(req.VolumePath, ns.Mounter)
402400
if err != nil {
403401
return nil, status.Errorf(codes.Internal, "failed to get block capacity on path %s: %v", req.VolumePath, err)
404402
}
@@ -482,14 +480,10 @@ func (ns *GCENodeServer) NodeExpandVolume(ctx context.Context, req *csi.NodeExpa
482480

483481
}
484482

485-
// Check the block size
486-
gotBlockSizeBytes, err := ns.getBlockSizeBytes(devicePath)
487-
if err != nil {
488-
return nil, status.Error(codes.Internal, fmt.Sprintf("error when getting size of block volume at path %s: %v", devicePath, err))
489-
}
490-
if gotBlockSizeBytes < reqBytes {
483+
diskSizeBytes, err := getBlockSizeBytes(devicePath, ns.Mounter)
484+
if diskSizeBytes < reqBytes {
491485
// It's possible that the somewhere the volume size was rounded up, getting more size than requested is a success :)
492-
return nil, status.Errorf(codes.Internal, "resize requested for %v but after resize volume was size %v", reqBytes, gotBlockSizeBytes)
486+
return nil, status.Errorf(codes.Internal, "resize requested for %v but after resize volume was size %v", reqBytes, diskSizeBytes)
493487
}
494488

495489
// TODO(dyzz) Some sort of formatted volume could also check the fs size.
@@ -531,16 +525,3 @@ func (ns *GCENodeServer) GetVolumeLimits() (int64, error) {
531525
}
532526
return volumeLimitBig, nil
533527
}
534-
535-
func (ns *GCENodeServer) getBlockSizeBytes(devicePath string) (int64, error) {
536-
output, err := ns.Mounter.Exec.Command("blockdev", "--getsize64", devicePath).CombinedOutput()
537-
if err != nil {
538-
return -1, fmt.Errorf("error when getting size of block volume at path %s: output: %s, err: %v", devicePath, string(output), err)
539-
}
540-
strOut := strings.TrimSpace(string(output))
541-
gotSizeBytes, err := strconv.ParseInt(strOut, 10, 64)
542-
if err != nil {
543-
return -1, fmt.Errorf("failed to parse %s into an int size", strOut)
544-
}
545-
return gotSizeBytes, nil
546-
}

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

+15
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ package gceGCEDriver
1818
import (
1919
"fmt"
2020
"os"
21+
"strconv"
22+
"strings"
2123

2224
"google.golang.org/grpc/codes"
2325
"google.golang.org/grpc/status"
@@ -64,3 +66,16 @@ func cleanupPublishPath(path string, m *mount.SafeFormatAndMount) error {
6466
func cleanupStagePath(path string, m *mount.SafeFormatAndMount) error {
6567
return cleanupPublishPath(path, m)
6668
}
69+
70+
func getBlockSizeBytes(devicePath string, m *mount.SafeFormatAndMount) (int64, error) {
71+
output, err := m.Exec.Command("blockdev", "--getsize64", devicePath).CombinedOutput()
72+
if err != nil {
73+
return -1, fmt.Errorf("error when getting size of block volume at path %s: output: %s, err: %v", devicePath, string(output), err)
74+
}
75+
strOut := strings.TrimSpace(string(output))
76+
gotSizeBytes, err := strconv.ParseInt(strOut, 10, 64)
77+
if err != nil {
78+
return -1, fmt.Errorf("failed to parse %s into an int size", strOut)
79+
}
80+
return gotSizeBytes, nil
81+
}

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

+9
Original file line numberDiff line numberDiff line change
@@ -87,3 +87,12 @@ func getDevicePath(ns *GCENodeServer, volumeID, partition string) (string, error
8787
}
8888
return proxy.GetDevicePath(deviceName, partition, volumeKey.Name)
8989
}
90+
91+
func getBlockSizeBytes(devicePath string, m *mount.SafeFormatAndMount) (int64, error) {
92+
proxy, ok := m.Interface.(*mounter.CSIProxyMounter)
93+
if !ok {
94+
return 0, fmt.Errorf("could not cast to csi proxy class")
95+
}
96+
97+
return proxy.GetBlockSizeBytes(devicePath)
98+
}

pkg/mount-manager/safe-mounter_windows.go

+8
Original file line numberDiff line numberDiff line change
@@ -277,3 +277,11 @@ func (mounter *CSIProxyMounter) ExistsPath(path string) (bool, error) {
277277
}
278278
return isExistsResponse.Exists, err
279279
}
280+
281+
func (mounter *CSIProxyMounter) GetBlockSizeBytes(diskId string) (int64, error) {
282+
DiskStatsResponse, err := mounter.DiskClient.DiskStats(context.Background(),
283+
&diskapi.DiskStatsRequest{
284+
DiskID: diskId,
285+
})
286+
return DiskStatsResponse.DiskSize, err
287+
}

pkg/resizefs/resizefs.go

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/*
2+
Copyright 2020 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
http://www.apache.org/licenses/LICENSE-2.0
8+
Unless required by applicable law or agreed to in writing, software
9+
distributed under the License is distributed on an "AS IS" BASIS,
10+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
See the License for the specific language governing permissions and
12+
limitations under the License.
13+
*/
14+
15+
package resizefs
16+
17+
type Resizefs interface {
18+
Resize(devicePath, deviceMountPath string) (bool, error)
19+
}

pkg/resizefs/resizefs_linux.go

+8-6
Original file line numberDiff line numberDiff line change
@@ -25,18 +25,20 @@ import (
2525
"k8s.io/utils/mount"
2626
)
2727

28+
var _ Resizefs = &resizeFs{}
29+
2830
// ResizeFs Provides support for resizing file systems
29-
type ResizeFs struct {
31+
type resizeFs struct {
3032
mounter *mount.SafeFormatAndMount
3133
}
3234

3335
// NewResizeFs returns new instance of resizer
34-
func NewResizeFs(mounter *mount.SafeFormatAndMount) *ResizeFs {
35-
return &ResizeFs{mounter: mounter}
36+
func NewResizeFs(mounter *mount.SafeFormatAndMount) *resizeFs {
37+
return &resizeFs{mounter: mounter}
3638
}
3739

3840
// Resize perform resize of file system
39-
func (resizefs *ResizeFs) Resize(devicePath string, deviceMountPath string) (bool, error) {
41+
func (resizefs *resizeFs) Resize(devicePath, deviceMountPath string) (bool, error) {
4042
format, err := resizefs.mounter.GetDiskFormat(devicePath)
4143

4244
if err != nil {
@@ -60,7 +62,7 @@ func (resizefs *ResizeFs) Resize(devicePath string, deviceMountPath string) (boo
6062
return false, fmt.Errorf("ResizeFS.Resize - resize of format %s is not supported for device %s mounted at %s", format, devicePath, deviceMountPath)
6163
}
6264

63-
func (resizefs *ResizeFs) extResize(devicePath string) (bool, error) {
65+
func (resizefs *resizeFs) extResize(devicePath string) (bool, error) {
6466
output, err := resizefs.mounter.Exec.Command("resize2fs", devicePath).CombinedOutput()
6567
if err == nil {
6668
klog.V(2).Infof("Device %s resized successfully", devicePath)
@@ -72,7 +74,7 @@ func (resizefs *ResizeFs) extResize(devicePath string) (bool, error) {
7274

7375
}
7476

75-
func (resizefs *ResizeFs) xfsResize(deviceMountPath string) (bool, error) {
77+
func (resizefs *resizeFs) xfsResize(deviceMountPath string) (bool, error) {
7678
args := []string{"-d", deviceMountPath}
7779
output, err := resizefs.mounter.Exec.Command("xfs_growfs", args...).CombinedOutput()
7880

pkg/resizefs/resizefs_unsupported.go

-40
This file was deleted.

pkg/resizefs/resizefs_windows.go

+69
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
// +build windows
2+
3+
/*
4+
Copyright 2020 The Kubernetes Authors.
5+
6+
Licensed under the Apache License, Version 2.0 (the "License");
7+
you may not use this file except in compliance with the License.
8+
You may obtain a copy of the License at
9+
10+
http://www.apache.org/licenses/LICENSE-2.0
11+
12+
Unless required by applicable law or agreed to in writing, software
13+
distributed under the License is distributed on an "AS IS" BASIS,
14+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
See the License for the specific language governing permissions and
16+
limitations under the License.
17+
*/
18+
19+
package resizefs
20+
21+
import (
22+
"context"
23+
"fmt"
24+
25+
volumeapi "github.com/kubernetes-csi/csi-proxy/client/api/volume/v1beta1"
26+
"k8s.io/klog"
27+
"k8s.io/utils/mount"
28+
mounter "sigs.k8s.io/gcp-compute-persistent-disk-csi-driver/pkg/mount-manager"
29+
)
30+
31+
var _ Resizefs = &resizeFs{}
32+
33+
// ResizeFs Provides support for resizing file systems
34+
type resizeFs struct {
35+
mounter *mount.SafeFormatAndMount
36+
}
37+
38+
// NewResizeFs returns new instance of resizer
39+
func NewResizeFs(mounter *mount.SafeFormatAndMount) *resizeFs {
40+
return &resizeFs{mounter: mounter}
41+
}
42+
43+
// resize perform resize of file system
44+
func (resizefs *resizeFs) Resize(devicePath string, deviceMountPath string) (bool, error) {
45+
klog.V(3).Infof("resizeFS.Resize - Expanding mounted volume %s", deviceMountPath)
46+
47+
proxy, ok := resizefs.mounter.Interface.(*mounter.CSIProxyMounter)
48+
if !ok {
49+
return false, fmt.Errorf("could not cast to csi proxy class")
50+
}
51+
52+
idRequest := &volumeapi.VolumeIDFromMountRequest{
53+
Mount: deviceMountPath,
54+
}
55+
idResponse, err := proxy.VolumeClient.GetVolumeIDFromMount(context.Background(), idRequest)
56+
if err != nil {
57+
return false, err
58+
}
59+
volumeId := idResponse.GetVolumeId()
60+
61+
request := &volumeapi.ResizeVolumeRequest{
62+
VolumeId: volumeId,
63+
}
64+
_, err = proxy.VolumeClient.ResizeVolume(context.Background(), request)
65+
if err != nil {
66+
return false, err
67+
}
68+
return true, nil
69+
}

0 commit comments

Comments
 (0)