Skip to content

Commit d4e7aeb

Browse files
Merge pull request #495 from apoorvajagtap/8916-214-backport
[backport v2.14] Adds retry logic for reserved NICs during cleanup
2 parents fa6312e + 089e5d4 commit d4e7aeb

1 file changed

Lines changed: 41 additions & 1 deletion

File tree

drivers/azure/azureutil/azureutil.go

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -367,7 +367,47 @@ func (a AzureClient) CreateNetworkInterface(ctx context.Context, deploymentCtx *
367367

368368
// DeleteNetworkInterfaceIfExists deletes a network interface if it exists
369369
func (a AzureClient) DeleteNetworkInterfaceIfExists(ctx context.Context, resourceGroup, name string) error {
370-
return a.cleanupResourceIfExists(ctx, &networkInterfaceCleanup{rg: resourceGroup, name: name})
370+
err := a.cleanupResourceIfExists(ctx, &networkInterfaceCleanup{rg: resourceGroup, name: name})
371+
372+
if err == nil || !strings.Contains(err.Error(), "NicReservedForAnotherVm") {
373+
return err
374+
}
375+
376+
return a.retryNICDeletionWithBackOff(ctx, resourceGroup, name)
377+
}
378+
379+
// retryNICDeletionWithBackOff deletes a reserved NIC with exponential backoff retries up to 180 seconds.
380+
func (a AzureClient) retryNICDeletionWithBackOff(ctx context.Context, resourceGroup, name string) error {
381+
const (
382+
initialBackoff = 5 * time.Second
383+
backoffFactor = 2
384+
maxBackOff = time.Second * 180
385+
)
386+
387+
startTime := time.Now()
388+
backoff := initialBackoff
389+
for {
390+
log.Warnf("NIC reserved, waiting %v before retry", backoff)
391+
waitTimer := time.NewTimer(backoff)
392+
select {
393+
case <-waitTimer.C:
394+
elapsed := time.Since(startTime)
395+
if err := a.cleanupResourceIfExists(ctx, &networkInterfaceCleanup{rg: resourceGroup, name: name}); err == nil {
396+
log.Info("Successfully removed NIC")
397+
return nil
398+
}
399+
if elapsed > maxBackOff {
400+
return fmt.Errorf("failed to remove NIC after %v", elapsed)
401+
}
402+
backoff *= backoffFactor
403+
log.Warnf("NIC still reserved (elapsed: %v), retrying with backoff: %v", elapsed, backoff)
404+
case <-ctx.Done():
405+
if !waitTimer.Stop() {
406+
<-waitTimer.C
407+
}
408+
return fmt.Errorf("context cancelled while waiting for NIC deletion: %w", ctx.Err())
409+
}
410+
}
371411
}
372412

373413
// CreateStorageAccount sees if the storage account provided exists or otherwise creates a storage account for you and stores the data into DeploymentContext

0 commit comments

Comments
 (0)