@@ -14,6 +14,7 @@ import (
1414 kubeAPI "k8s.io/api/core/v1"
1515
1616 "github.com/oracle/oci-cloud-controller-manager/pkg/csi-util"
17+ "github.com/oracle/oci-cloud-controller-manager/pkg/oci/client"
1718 "github.com/oracle/oci-cloud-controller-manager/pkg/util/disk"
1819)
1920
@@ -416,18 +417,21 @@ func getDevicePathAndAttachmentType(logger *zap.SugaredLogger, path []string) (s
416417
417418// NodeGetCapabilities returns the supported capabilities of the node server
418419func (d BlockVolumeNodeDriver ) NodeGetCapabilities (ctx context.Context , req * csi.NodeGetCapabilitiesRequest ) (* csi.NodeGetCapabilitiesResponse , error ) {
419- nscap := & csi.NodeServiceCapability {
420- Type : & csi.NodeServiceCapability_Rpc {
421- Rpc : & csi.NodeServiceCapability_RPC {
422- Type : csi .NodeServiceCapability_RPC_STAGE_UNSTAGE_VOLUME ,
420+ var nscaps []* csi.NodeServiceCapability
421+ nodeCaps := []csi.NodeServiceCapability_RPC_Type {csi .NodeServiceCapability_RPC_STAGE_UNSTAGE_VOLUME , csi .NodeServiceCapability_RPC_EXPAND_VOLUME }
422+ for _ , nodeCap := range nodeCaps {
423+ c := & csi.NodeServiceCapability {
424+ Type : & csi.NodeServiceCapability_Rpc {
425+ Rpc : & csi.NodeServiceCapability_RPC {
426+ Type : nodeCap ,
427+ },
423428 },
424- },
429+ }
430+ nscaps = append (nscaps , c )
425431 }
426432
427433 return & csi.NodeGetCapabilitiesResponse {
428- Capabilities : []* csi.NodeServiceCapability {
429- nscap ,
430- },
434+ Capabilities : nscaps ,
431435 }, nil
432436}
433437
@@ -461,5 +465,89 @@ func (d BlockVolumeNodeDriver) NodeGetVolumeStats(ctx context.Context, req *csi.
461465
462466//NodeExpandVolume returns the expand of the volume
463467func (d BlockVolumeNodeDriver ) NodeExpandVolume (ctx context.Context , req * csi.NodeExpandVolumeRequest ) (* csi.NodeExpandVolumeResponse , error ) {
464- return nil , status .Error (codes .Unimplemented , "NodeExpandVolume is not supported yet" )
468+ volumeID := req .GetVolumeId ()
469+ if len (volumeID ) == 0 {
470+ return nil , status .Error (codes .InvalidArgument , "Volume ID not provided" )
471+ }
472+ volumePath := req .GetVolumePath ()
473+ if len (volumePath ) == 0 {
474+ return nil , status .Error (codes .InvalidArgument , "volume path must be provided" )
475+ }
476+
477+ logger := d .logger .With ("volumeId" , req .VolumeId , "volumePath" , req .VolumePath )
478+
479+ if acquired := d .volumeLocks .TryAcquire (req .VolumeId ); ! acquired {
480+ logger .Error ("Could not acquire lock for NodeUnpublishVolume." )
481+ return nil , status .Errorf (codes .Aborted , volumeOperationAlreadyExistsFmt , req .VolumeId )
482+ }
483+
484+ defer d .volumeLocks .Release (req .VolumeId )
485+
486+ requestedSize , err := csi_util .ExtractStorage (req .CapacityRange )
487+ requestedSizeGB := csi_util .RoundUpSize (requestedSize , 1 * client .GiB )
488+
489+ if err != nil {
490+ logger .With (zap .Error (err )).Error ("invalid capacity range" )
491+ return nil , status .Errorf (codes .OutOfRange , "invalid capacity range: %v" , err )
492+ }
493+
494+ diskPath , err := disk .GetDiskPathFromMountPath (d .logger , volumePath )
495+ if err != nil {
496+ // do a clean exit in case of mount point not found
497+ if err == disk .ErrMountPointNotFound {
498+ logger .With (zap .Error (err )).With ("volumePath" , volumePath ).Warn ("unable to fetch mount point" )
499+ return & csi.NodeExpandVolumeResponse {}, nil
500+ }
501+ logger .With (zap .Error (err )).With ("volumePath" , volumePath ).Error ("unable to get diskPath from mount path" )
502+ return nil , status .Error (codes .Internal , err .Error ())
503+ }
504+
505+ attachmentType , devicePath , err := getDevicePathAndAttachmentType (d .logger , diskPath )
506+ if err != nil {
507+ logger .With (zap .Error (err )).With ("diskPath" , diskPath ).Error ("unable to determine the attachment type" )
508+ return nil , status .Error (codes .Internal , err .Error ())
509+ }
510+ logger .With ("diskPath" , diskPath , "attachmentType" , attachmentType , "devicePath" , devicePath ).Infof ("Extracted attachment type and device path" )
511+
512+ var mountHandler disk.Interface
513+ switch attachmentType {
514+ case attachmentTypeISCSI :
515+ scsiInfo , _ := csi_util .ExtractISCSIInformationFromMountPath (d .logger , diskPath )
516+ if scsiInfo == nil {
517+ logger .Warn ("unable to get the ISCSI info" )
518+ return & csi.NodeExpandVolumeResponse {}, nil
519+ }
520+ mountHandler = disk .NewFromISCSIDisk (d .logger , scsiInfo )
521+ d .logger .With ("ISCSIInfo" , scsiInfo , "mountPath" , volumePath ).Info ("Found ISCSIInfo for NodeExpandVolume." )
522+ case attachmentTypeParavirtualized :
523+ mountHandler = disk .NewFromPVDisk (d .logger )
524+ logger .Info ("starting to expand paravirtualized Mounting." )
525+ default :
526+ logger .Error ("unknown attachment type. supported attachment types are iscsi and paravirtualized" )
527+ return nil , status .Error (codes .InvalidArgument , "unknown attachment type. supported attachment types are iscsi and paravirtualized" )
528+ }
529+
530+ if err := mountHandler .Rescan (devicePath ); err != nil {
531+ return nil , status .Errorf (codes .Internal , "Failed to rescan volume %q (%q): %v" , volumeID , devicePath , err )
532+ }
533+ logger .With ("devicePath" , devicePath ).Debug ("Rescan completed" )
534+
535+ if _ , err := mountHandler .Resize (devicePath , volumePath ); err != nil {
536+ return nil , status .Errorf (codes .Internal , "Failed to resize volume %q (%q): %v" , volumeID , devicePath , err )
537+ }
538+
539+ allocatedSizeBytes , err := mountHandler .GetBlockSizeBytes (devicePath )
540+ if err != nil {
541+ return nil , status .Error (codes .Internal , fmt .Sprintf ("Failed to get size of block volume at path %s: %v" , devicePath , err ))
542+ }
543+
544+ allocatedSizeGB := csi_util .RoundUpSize (allocatedSizeBytes , 1 * client .GiB )
545+
546+ if allocatedSizeGB < requestedSizeGB {
547+ return nil , status .Error (codes .Internal , fmt .Sprintf ("Expand Volume Failed, requested size in GB %d but resize allocated only %d" , requestedSizeGB , allocatedSizeGB ))
548+ }
549+
550+ return & csi.NodeExpandVolumeResponse {
551+ CapacityBytes : allocatedSizeBytes ,
552+ }, nil
465553}
0 commit comments