@@ -12,6 +12,8 @@ import (
1212 "google.golang.org/grpc/codes"
1313 "google.golang.org/grpc/status"
1414 kubeAPI "k8s.io/api/core/v1"
15+ "k8s.io/kubernetes/pkg/volume"
16+ "k8s.io/kubernetes/pkg/volume/util/hostutil"
1517
1618 "github.com/oracle/oci-cloud-controller-manager/pkg/csi-util"
1719 "github.com/oracle/oci-cloud-controller-manager/pkg/oci/client"
@@ -436,7 +438,7 @@ func getDevicePathAndAttachmentType(logger *zap.SugaredLogger, path []string) (s
436438// NodeGetCapabilities returns the supported capabilities of the node server
437439func (d BlockVolumeNodeDriver ) NodeGetCapabilities (ctx context.Context , req * csi.NodeGetCapabilitiesRequest ) (* csi.NodeGetCapabilitiesResponse , error ) {
438440 var nscaps []* csi.NodeServiceCapability
439- nodeCaps := []csi.NodeServiceCapability_RPC_Type {csi .NodeServiceCapability_RPC_STAGE_UNSTAGE_VOLUME , csi .NodeServiceCapability_RPC_EXPAND_VOLUME }
441+ nodeCaps := []csi.NodeServiceCapability_RPC_Type {csi .NodeServiceCapability_RPC_STAGE_UNSTAGE_VOLUME , csi .NodeServiceCapability_RPC_GET_VOLUME_STATS , csi . NodeServiceCapability_RPC_EXPAND_VOLUME }
440442 for _ , nodeCap := range nodeCaps {
441443 c := & csi.NodeServiceCapability {
442444 Type : & csi.NodeServiceCapability_Rpc {
@@ -478,7 +480,53 @@ func (d BlockVolumeNodeDriver) NodeGetInfo(ctx context.Context, req *csi.NodeGet
478480
479481// NodeGetVolumeStats return the stats of the volume
480482func (d BlockVolumeNodeDriver ) NodeGetVolumeStats (ctx context.Context , req * csi.NodeGetVolumeStatsRequest ) (* csi.NodeGetVolumeStatsResponse , error ) {
481- return nil , status .Error (codes .Unimplemented , "NodeGetVolumeStats is not supported yet" )
483+ logger := d .logger .With ("volumeID" , req .VolumeId , "volumePath" , req .VolumePath )
484+
485+ volumeID := req .GetVolumeId ()
486+ if len (volumeID ) == 0 {
487+ logger .Errorf ("Volume ID not provided" )
488+ return nil , status .Error (codes .InvalidArgument , "Volume ID not provided" )
489+ }
490+ volumePath := req .GetVolumePath ()
491+ if len (volumePath ) == 0 {
492+ logger .Errorf ("Volume path not provided" )
493+ return nil , status .Error (codes .InvalidArgument , "volume path must be provided" )
494+ }
495+
496+ hostUtil := hostutil .NewHostUtil ()
497+ exists , err := hostUtil .PathExists (volumePath )
498+ if err != nil {
499+ logger .With (zap .Error (err )).Errorf ("Failed to find if path exists %s" , volumePath )
500+ return nil , status .Error (codes .Internal , err .Error ())
501+ }
502+ if ! exists {
503+ logger .Infof ("Path does not exist %s" , volumePath )
504+ return nil , status .Errorf (codes .NotFound , "path %s does not exist" , volumePath )
505+ }
506+
507+ metricsProvider := volume .NewMetricsStatFS (volumePath )
508+ metrics , err := metricsProvider .GetMetrics ()
509+ if err != nil {
510+ logger .With (zap .Error (err )).Errorf ("failed to get block volume info on path %s: %v" , volumePath , err )
511+ return nil , status .Error (codes .Internal , err .Error ())
512+ }
513+
514+ return & csi.NodeGetVolumeStatsResponse {
515+ Usage : []* csi.VolumeUsage {
516+ {
517+ Unit : csi .VolumeUsage_BYTES ,
518+ Available : metrics .Available .AsDec ().UnscaledBig ().Int64 (),
519+ Total : metrics .Capacity .AsDec ().UnscaledBig ().Int64 (),
520+ Used : metrics .Used .AsDec ().UnscaledBig ().Int64 (),
521+ },
522+ {
523+ Unit : csi .VolumeUsage_INODES ,
524+ Available : metrics .InodesFree .AsDec ().UnscaledBig ().Int64 (),
525+ Total : metrics .Inodes .AsDec ().UnscaledBig ().Int64 (),
526+ Used : metrics .InodesUsed .AsDec ().UnscaledBig ().Int64 (),
527+ },
528+ },
529+ }, nil
482530}
483531
484532//NodeExpandVolume returns the expand of the volume
0 commit comments