diff --git a/go.mod b/go.mod index f5933fd5..51a71c8f 100644 --- a/go.mod +++ b/go.mod @@ -15,7 +15,7 @@ require ( github.com/vmware/go-vcloud-director/v2 v2.14.0-rc.3 golang.org/x/net v0.0.0-20210520170846-37e1c6afe023 // indirect golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f // indirect - golang.org/x/sys v0.0.0-20210616094352-59db8d763f22 // indirect + golang.org/x/sys v0.0.0-20210616094352-59db8d763f22 google.golang.org/grpc v1.38.0 google.golang.org/protobuf v1.26.0 // indirect gopkg.in/yaml.v2 v2.4.0 diff --git a/go.sum b/go.sum index 66dd9b99..07d4015e 100644 --- a/go.sum +++ b/go.sum @@ -404,10 +404,6 @@ github.com/thecodeteam/gofsutil v0.1.2 h1:FL87mBzZeeuDMZm8hpYLFcYylQdq6bbm8UQ1oc github.com/thecodeteam/gofsutil v0.1.2/go.mod h1:7bDOpr2aMnmdm9RTdxBEeqdOr+8RpnQhsB/VUEI3DgM= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/vmware/cloud-provider-for-cloud-director v0.0.0-20220708214416-a03d0d9e871f h1:F8LqZ5luskCWYBWyZO1Oqen2LAI1xgY2egjdPZSwyzw= -github.com/vmware/cloud-provider-for-cloud-director v0.0.0-20220708214416-a03d0d9e871f/go.mod h1:E7pd/SaAz3M2PGN0T9BbByiwGia4SSJ7+cNZkpE6f60= -github.com/vmware/cloud-provider-for-cloud-director v0.0.0-20220712000405-2d29b326385f h1:dsd8CkrKS0bALuaZxvF3PagWdEEGtaiOt9AmZO7PY80= -github.com/vmware/cloud-provider-for-cloud-director v0.0.0-20220712000405-2d29b326385f/go.mod h1:E7pd/SaAz3M2PGN0T9BbByiwGia4SSJ7+cNZkpE6f60= github.com/vmware/cloud-provider-for-cloud-director v0.0.0-20220718184524-22ee9074d6aa h1:A7YLgknuHJsyDd+U/YBGFnoDe16EHnnw0WZCfxWX7s8= github.com/vmware/cloud-provider-for-cloud-director v0.0.0-20220718184524-22ee9074d6aa/go.mod h1:E7pd/SaAz3M2PGN0T9BbByiwGia4SSJ7+cNZkpE6f60= github.com/vmware/go-vcloud-director/v2 v2.14.0-rc.3 h1:VJolXzgomaRPrgzSr0EduuUtJIJEf5RdoLbktZFQqIc= diff --git a/pkg/csi/driver.go b/pkg/csi/driver.go index cff631a2..02e5d824 100644 --- a/pkg/csi/driver.go +++ b/pkg/csi/driver.go @@ -74,10 +74,11 @@ func NewDriver(nodeID string, endpoint string) (*VCDDriver, error) { nodeServiceCapabilityList := []csi.NodeServiceCapability_RPC_Type{ csi.NodeServiceCapability_RPC_STAGE_UNSTAGE_VOLUME, + csi.NodeServiceCapability_RPC_GET_VOLUME_STATS, } d.nodeServiceCapabilities = make([]*csi.NodeServiceCapability, len(nodeServiceCapabilityList)) for idx, nodeServiceCapability := range nodeServiceCapabilityList { - klog.Infof("Enabling node service capability: %v", nodeServiceCapability.String()) + klog.Infof("Enabling node service capability: [%s]", nodeServiceCapability.String()) d.nodeServiceCapabilities[idx] = &csi.NodeServiceCapability{ Type: &csi.NodeServiceCapability_Rpc{ Rpc: &csi.NodeServiceCapability_RPC{ diff --git a/pkg/csi/node.go b/pkg/csi/node.go index a460e83b..f6407d73 100644 --- a/pkg/csi/node.go +++ b/pkg/csi/node.go @@ -15,6 +15,7 @@ import ( "github.com/akutz/gofsutil" "github.com/container-storage-interface/spec/lib/go/csi" + "golang.org/x/sys/unix" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" "k8s.io/klog" @@ -341,11 +342,6 @@ func (ns *nodeService) NodeUnpublishVolume(ctx context.Context, return &csi.NodeUnpublishVolumeResponse{}, nil } -func (ns *nodeService) NodeGetVolumeStats(context.Context, - *csi.NodeGetVolumeStatsRequest) (*csi.NodeGetVolumeStatsResponse, error) { - return nil, status.Error(codes.Unimplemented, "not implemented...yet") -} - func (ns *nodeService) NodeExpandVolume(context.Context, *csi.NodeExpandVolumeRequest) (*csi.NodeExpandVolumeResponse, error) { return nil, status.Error(codes.Unimplemented, "not implemented...yet") } @@ -367,6 +363,41 @@ func (ns *nodeService) NodeGetInfo(ctx context.Context, req *csi.NodeGetInfoRequ } +func (ns *nodeService) NodeGetVolumeStats(ctx context.Context, + req *csi.NodeGetVolumeStatsRequest) (*csi.NodeGetVolumeStatsResponse, error) { + + klog.Infof("NodeGetVolumeStats called with req: %#v", req) + + volumePath := req.GetVolumePath() + if volumePath == "" { + klog.Errorf("unable to get volume path from request") + return nil, fmt.Errorf("unable to get volume path from request") + } + + var statFS unix.Statfs_t + if err := unix.Statfs(volumePath, &statFS); err != nil { + klog.Errorf("unable to get stats of volume [%s]: [%v]", volumePath, err) + return nil, fmt.Errorf("unable to get stats of volume [%s]: [%v]", volumePath, err) + } + + return &csi.NodeGetVolumeStatsResponse{ + Usage: []*csi.VolumeUsage{ + { + Available: int64(statFS.Bavail) * int64(statFS.Bsize), + Total: int64(statFS.Blocks) * int64(statFS.Bsize), + Used: (int64(statFS.Blocks) - int64(statFS.Bavail)) * int64(statFS.Bsize), + Unit: csi.VolumeUsage_BYTES, + }, + { + Available: int64(statFS.Ffree), + Total: int64(statFS.Files), + Used: int64(statFS.Files) - int64(statFS.Ffree), + Unit: csi.VolumeUsage_INODES, + }, + }, + }, nil +} + // getDiskPath looks for a device corresponding to vmName:diskName as stored in vSphere. It // enumerates devices in /dev/disk/by-path and returns a device with UUID matching the scsi UUID. // It needs disk.enableUUID to be set for the VM.