mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-29 22:46:12 +00:00
Fix #59601: AWS: Check error code returned from describeVolume
The errors returned by the describeVolume call are not all equal: if the error is of InvalidVolume.NotFound type it does not necessarily mean the desired operation cannot be finished successfully. Fixes #59601
This commit is contained in:
parent
8eae0a8a37
commit
6832d3a056
@ -1660,6 +1660,20 @@ func newAWSDisk(aws *Cloud, name KubernetesVolumeID) (*awsDisk, error) {
|
||||
return disk, nil
|
||||
}
|
||||
|
||||
// Helper function for describeVolume callers. Tries to retype given error to AWS error
|
||||
// and returns true in case the AWS error is "InvalidVolume.NotFound", false otherwise
|
||||
func isAWSErrorVolumeNotFound(err error) bool {
|
||||
if err != nil {
|
||||
if awsError, ok := err.(awserr.Error); ok {
|
||||
// https://docs.aws.amazon.com/AWSEC2/latest/APIReference/errors-overview.html
|
||||
if awsError.Code() == "InvalidVolume.NotFound" {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Gets the full information about this volume from the EC2 API
|
||||
func (d *awsDisk) describeVolume() (*ec2.Volume, error) {
|
||||
volumeID := d.awsID
|
||||
@ -1670,13 +1684,13 @@ func (d *awsDisk) describeVolume() (*ec2.Volume, error) {
|
||||
|
||||
volumes, err := d.ec2.DescribeVolumes(request)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error querying ec2 for volume %q: %q", volumeID, err)
|
||||
return nil, err
|
||||
}
|
||||
if len(volumes) == 0 {
|
||||
return nil, fmt.Errorf("no volumes found for volume %q", volumeID)
|
||||
return nil, fmt.Errorf("no volumes found")
|
||||
}
|
||||
if len(volumes) > 1 {
|
||||
return nil, fmt.Errorf("multiple volumes found for volume %q", volumeID)
|
||||
return nil, fmt.Errorf("multiple volumes found")
|
||||
}
|
||||
return volumes[0], nil
|
||||
}
|
||||
@ -1780,12 +1794,29 @@ func (d *awsDisk) waitForAttachmentStatus(status string) (*ec2.VolumeAttachment,
|
||||
err := wait.ExponentialBackoff(backoff, func() (bool, error) {
|
||||
info, err := d.describeVolume()
|
||||
if err != nil {
|
||||
// The VolumeNotFound error is special -- we don't need to wait for it to repeat
|
||||
if isAWSErrorVolumeNotFound(err) {
|
||||
if status == "detached" {
|
||||
// The disk doesn't exist, assume it's detached, log warning and stop waiting
|
||||
glog.Warningf("Waiting for volume %q to be detached but the volume does not exist", d.awsID)
|
||||
stateStr := "detached"
|
||||
attachment = &ec2.VolumeAttachment{
|
||||
State: &stateStr,
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
if status == "attached" {
|
||||
// The disk doesn't exist, complain, give up waiting and report error
|
||||
glog.Warningf("Waiting for volume %q to be attached but the volume does not exist", d.awsID)
|
||||
return false, err
|
||||
}
|
||||
}
|
||||
describeErrorCount++
|
||||
if describeErrorCount > volumeAttachmentStatusConsecutiveErrorLimit {
|
||||
// report the error
|
||||
return false, err
|
||||
} else {
|
||||
glog.Warningf("Ignoring error from describe volume; will retry: %q", err)
|
||||
glog.Warningf("Ignoring error from describe volume for volume %q; will retry: %q", d.awsID, err)
|
||||
return false, nil
|
||||
}
|
||||
} else {
|
||||
@ -2013,7 +2044,13 @@ func (c *Cloud) AttachDisk(diskName KubernetesVolumeID, nodeName types.NodeName,
|
||||
func (c *Cloud) DetachDisk(diskName KubernetesVolumeID, nodeName types.NodeName) (string, error) {
|
||||
diskInfo, attached, err := c.checkIfAttachedToNode(diskName, nodeName)
|
||||
if err != nil {
|
||||
return "", err
|
||||
if isAWSErrorVolumeNotFound(err) {
|
||||
// Someone deleted the volume being detached; complain, but do nothing else and return success
|
||||
glog.Warningf("DetachDisk %s called for node %s but volume does not exist; assuming the volume is detached", diskName, nodeName)
|
||||
return "", nil
|
||||
} else {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
|
||||
if !attached && diskInfo.ec2Instance != nil {
|
||||
@ -2308,9 +2345,15 @@ func (c *Cloud) GetDiskPath(volumeName KubernetesVolumeID) (string, error) {
|
||||
|
||||
// DiskIsAttached implements Volumes.DiskIsAttached
|
||||
func (c *Cloud) DiskIsAttached(diskName KubernetesVolumeID, nodeName types.NodeName) (bool, error) {
|
||||
diskInfo, attached, err := c.checkIfAttachedToNode(diskName, nodeName)
|
||||
if diskInfo == nil {
|
||||
return true, err
|
||||
_, attached, err := c.checkIfAttachedToNode(diskName, nodeName)
|
||||
if err != nil {
|
||||
if isAWSErrorVolumeNotFound(err) {
|
||||
// The disk doesn't exist, can't be attached
|
||||
glog.Warningf("DiskIsAttached called for volume %s on node %s but the volume does not exist", diskName, nodeName)
|
||||
return false, nil
|
||||
} else {
|
||||
return true, err
|
||||
}
|
||||
}
|
||||
|
||||
return attached, nil
|
||||
|
@ -119,10 +119,9 @@ func (c *Cloud) checkIfAttachedToNode(diskName KubernetesVolumeID, nodeName type
|
||||
info, err := disk.describeVolume()
|
||||
|
||||
if err != nil {
|
||||
describeError := fmt.Errorf("Error describing volume %s with %v", diskName, err)
|
||||
glog.Warning(describeError)
|
||||
glog.Warning("Error describing volume %s with %v", diskName, err)
|
||||
awsDiskInfo.volumeState = "unknown"
|
||||
return awsDiskInfo, false, describeError
|
||||
return awsDiskInfo, false, err
|
||||
}
|
||||
|
||||
awsDiskInfo.volumeState = aws.StringValue(info.State)
|
||||
|
Loading…
Reference in New Issue
Block a user