@@ -34,6 +34,7 @@ const (
3434 awsDevicePrefixWithH = "/dev/hd"
3535 awsDevicePrefixNvme = "/dev/nvme"
3636 contextTimeout = 30 * time .Second
37+ awsErrorModificationNotFound = "InvalidVolumeModification.NotFound"
3738)
3839
3940type awsOps struct {
@@ -942,6 +943,42 @@ func (s *awsOps) detachInternal(volumeID, instanceName string, options map[strin
942943 return err
943944}
944945
946+ func isErrorModificationNotFound (err error ) bool {
947+ return strings .HasPrefix (err .Error (), awsErrorModificationNotFound )
948+ }
949+
950+ func (s * awsOps ) AreVolumesReadyToExpand (volumeIDs []* string ) (bool , error ) {
951+ modificationStateRequest := & ec2.DescribeVolumesModificationsInput {
952+ VolumeIds : volumeIDs ,
953+ }
954+ describeOutput , err := s .ec2 .DescribeVolumesModifications (modificationStateRequest )
955+ if err != nil {
956+ // modification state not found, this indicates no change has occurred before.
957+ if isErrorModificationNotFound (err ) {
958+ return true , nil
959+ }
960+ return false , fmt .Errorf ("unable to get modification states for aws volumes: %v" , err )
961+ }
962+ states := describeOutput .VolumesModifications
963+
964+ var state string
965+ for i := 0 ; i < len (states ); i ++ {
966+ if states [i ] == nil || states [i ].ModificationState == nil {
967+ logrus .Debugf ("volume modification state is nil for volume id: %s" , * volumeIDs [i ])
968+ continue
969+ }
970+
971+ state = * states [i ].ModificationState
972+ logrus .Infof ("retrived volume modification state: %s for volume id: %s" , state , * volumeIDs [i ])
973+ if state == ec2 .VolumeModificationStateModifying ||
974+ state == ec2 .VolumeModificationStateOptimizing {
975+ return false , fmt .Errorf ("aws has not fully completed the last modification: " +
976+ "volume %s is in %s state. please retry later" , * volumeIDs [i ], state )
977+ }
978+ }
979+ return true , nil
980+ }
981+
945982func (s * awsOps ) Expand (
946983 volumeID string ,
947984 newSizeInGiB uint64 ,
0 commit comments