Skip to content

Commit 75250eb

Browse files
authored
Merge pull request kubernetes#95177 from andyzhangx/detach-non-existing-vm
fix detach azure disk issue when vm not exist
2 parents 7029430 + ed82a6e commit 75250eb

File tree

2 files changed

+62
-18
lines changed

2 files changed

+62
-18
lines changed

staging/src/k8s.io/legacy-cloud-providers/azure/azure_controller_common.go

Lines changed: 33 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,9 @@ const (
4949
errLeaseFailed = "AcquireDiskLeaseFailed"
5050
errLeaseIDMissing = "LeaseIdMissing"
5151
errContainerNotFound = "ContainerNotFound"
52-
errDiskBlobNotFound = "DiskBlobNotFound"
52+
errStatusCode400 = "statuscode=400"
53+
errInvalidParameter = `code="invalidparameter"`
54+
errTargetInstanceIds = `target="instanceids"`
5355
sourceSnapshot = "snapshot"
5456
sourceVolume = "volume"
5557

@@ -214,24 +216,32 @@ func (c *controllerCommon) DetachDisk(diskName, diskURI string, nodeName types.N
214216
c.diskAttachDetachMap.Delete(strings.ToLower(diskURI))
215217
c.vmLockMap.UnlockEntry(strings.ToLower(string(nodeName)))
216218

217-
if err != nil && retry.IsErrorRetriable(err) && c.cloud.CloudProviderBackoff {
218-
klog.V(2).Infof("azureDisk - update backing off: detach disk(%s, %s), err: %v", diskName, diskURI, err)
219-
retryErr := kwait.ExponentialBackoff(c.cloud.RequestBackoff(), func() (bool, error) {
220-
c.vmLockMap.LockEntry(strings.ToLower(string(nodeName)))
221-
c.diskAttachDetachMap.Store(strings.ToLower(diskURI), "detaching")
222-
err := vmset.DetachDisk(diskName, diskURI, nodeName)
223-
c.diskAttachDetachMap.Delete(strings.ToLower(diskURI))
224-
c.vmLockMap.UnlockEntry(strings.ToLower(string(nodeName)))
225-
226-
retriable := false
227-
if err != nil && retry.IsErrorRetriable(err) {
228-
retriable = true
219+
if err != nil {
220+
if isInstanceNotFoundError(err) {
221+
// if host doesn't exist, no need to detach
222+
klog.Warningf("azureDisk - got InstanceNotFoundError(%v), DetachDisk(%s) will assume disk is already detached",
223+
err, diskURI)
224+
return nil
225+
}
226+
if retry.IsErrorRetriable(err) && c.cloud.CloudProviderBackoff {
227+
klog.Warningf("azureDisk - update backing off: detach disk(%s, %s), err: %v", diskName, diskURI, err)
228+
retryErr := kwait.ExponentialBackoff(c.cloud.RequestBackoff(), func() (bool, error) {
229+
c.vmLockMap.LockEntry(strings.ToLower(string(nodeName)))
230+
c.diskAttachDetachMap.Store(strings.ToLower(diskURI), "detaching")
231+
err := vmset.DetachDisk(diskName, diskURI, nodeName)
232+
c.diskAttachDetachMap.Delete(strings.ToLower(diskURI))
233+
c.vmLockMap.UnlockEntry(strings.ToLower(string(nodeName)))
234+
235+
retriable := false
236+
if err != nil && retry.IsErrorRetriable(err) {
237+
retriable = true
238+
}
239+
return !retriable, err
240+
})
241+
if retryErr != nil {
242+
err = retryErr
243+
klog.V(2).Infof("azureDisk - update abort backoff: detach disk(%s, %s), err: %v", diskName, diskURI, err)
229244
}
230-
return !retriable, err
231-
})
232-
if retryErr != nil {
233-
err = retryErr
234-
klog.V(2).Infof("azureDisk - update abort backoff: detach disk(%s, %s), err: %v", diskName, diskURI, err)
235245
}
236246
}
237247
if err != nil {
@@ -426,3 +436,8 @@ func getValidCreationData(subscriptionID, resourceGroup, sourceResourceID, sourc
426436
SourceResourceID: &sourceResourceID,
427437
}, nil
428438
}
439+
440+
func isInstanceNotFoundError(err error) bool {
441+
errMsg := strings.ToLower(err.Error())
442+
return strings.Contains(errMsg, errStatusCode400) && strings.Contains(errMsg, errInvalidParameter) && strings.Contains(errMsg, errTargetInstanceIds)
443+
}

staging/src/k8s.io/legacy-cloud-providers/azure/azure_controller_common_test.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -788,3 +788,32 @@ func TestFilterNonExistingDisksWithSpecialHTTPStatusCode(t *testing.T) {
788788
assert.Equal(t, 1, len(filteredDisks))
789789
assert.Equal(t, newDiskName, *filteredDisks[0].Name)
790790
}
791+
792+
func TestIsInstanceNotFoundError(t *testing.T) {
793+
testCases := []struct {
794+
errMsg string
795+
expectedResult bool
796+
}{
797+
{
798+
errMsg: "",
799+
expectedResult: false,
800+
},
801+
{
802+
errMsg: "other error",
803+
expectedResult: false,
804+
},
805+
{
806+
errMsg: "not an active Virtual Machine scale set vm",
807+
expectedResult: false,
808+
},
809+
{
810+
errMsg: `compute.VirtualMachineScaleSetVMsClient#Update: Failure sending request: StatusCode=400 -- Original Error: Code="InvalidParameter" Message="The provided instanceId 1181 is not an active Virtual Machine Scale Set VM instanceId." Target="instanceIds"`,
811+
expectedResult: true,
812+
},
813+
}
814+
815+
for i, test := range testCases {
816+
result := isInstanceNotFoundError(fmt.Errorf(test.errMsg))
817+
assert.Equal(t, test.expectedResult, result, "TestCase[%d]", i, result)
818+
}
819+
}

0 commit comments

Comments
 (0)