Skip to content

Commit

Permalink
Fixed issue where deleting a blob with a snapshot would hang (#2295)
Browse files Browse the repository at this point in the history
  • Loading branch information
gapra-msft authored Jul 19, 2023
1 parent 166e3ca commit 8fe5d55
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 3 deletions.
3 changes: 3 additions & 0 deletions e2etest/declarativeHelpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -533,6 +533,9 @@ type hookHelper interface {

// GetDestination returns the destination Resource Manager
GetDestination() resourceManager

// GetSource returns the source Resource Manager
GetSource() resourceManager
}

// /////
Expand Down
4 changes: 4 additions & 0 deletions e2etest/declarativeScenario.go
Original file line number Diff line number Diff line change
Expand Up @@ -858,3 +858,7 @@ func (s *scenario) GetAsserter() asserter {
func (s *scenario) GetDestination() resourceManager {
return s.state.dest
}

func (s *scenario) GetSource() resourceManager {
return s.state.source
}
42 changes: 41 additions & 1 deletion e2etest/zt_remove_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@
package e2etest

import (
"github.com/Azure/azure-sdk-for-go/sdk/azcore/to"
"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/blob"
"github.com/Azure/azure-storage-azcopy/v10/common"
"github.com/Azure/azure-storage-file-go/azfile"
"testing"
"time"
Expand Down Expand Up @@ -65,4 +68,41 @@ func TestRemove_IncludeAfter(t *testing.T) {
shouldTransfer: recreateFiles,
shouldIgnore: skippedFiles,
}, EAccountType.Standard(), EAccountType.Standard(), "")
}
}

func TestRemove_WithSnapshotsBlob(t *testing.T) {
blobRemove := TestFromTo{
desc: "AllRemove",
useAllTos: true,
froms: []common.Location{
common.ELocation.Blob(),
},
tos: []common.Location{
common.ELocation.Unknown(),
},
}
RunScenarios(t, eOperation.Remove(), blobRemove, eValidate.Auto(), anonymousAuthOnly, anonymousAuthOnly, params{
recursive: true,
}, &hooks{
beforeRunJob: func(h hookHelper) {
blobClient := h.GetSource().(*resourceBlobContainer).containerClient.NewBlobClient("filea")
_, err := blobClient.CreateSnapshot(ctx, nil)
if err != nil {
t.Errorf("error creating snapshot %s", err)
}
},
afterValidation: func(h hookHelper) {
blobClient := h.GetSource().(*resourceBlobContainer).containerClient.NewBlobClient("filea")
_, err := blobClient.Delete(ctx, &blob.DeleteOptions{DeleteSnapshots: to.Ptr(blob.DeleteSnapshotsOptionTypeInclude)})
if err != nil {
t.Errorf("error deleting blob %s", err)
}
},
}, testFiles{
defaultSize: "1K",
shouldSkip: []interface{}{
f("filea"),
},
objectTarget: "filea",
}, EAccountType.Standard(), EAccountType.Standard(), "")
}
4 changes: 2 additions & 2 deletions ste/xfer-deleteBlob.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,15 +62,14 @@ func doDeleteBlob(jptm IJobPartTransferMgr, p pipeline.Pipeline) {
// we still count this delete operation as successful since we accomplished the desired outcome
_, err := blobClient.Delete(jptm.Context(), &blob.DeleteOptions{
DeleteSnapshots: jptm.DeleteSnapshotsOption().ToDeleteSnapshotsOptionType(),
BlobDeleteType: jptm.PermanentDeleteOption().ToPermanentDeleteOptionType(),
BlobDeleteType: jptm.PermanentDeleteOption().ToPermanentDeleteOptionType(),
})
if err != nil {
var respErr *azcore.ResponseError
if errors.As(err, &respErr) {
// if the delete failed with err 404, i.e resource not found, then mark the transfer as success.
if respErr.StatusCode == http.StatusNotFound {
transferDone(common.ETransferStatus.Success(), nil)
}
return
}
// if the delete failed because the blob has snapshots, then skip it
Expand All @@ -85,6 +84,7 @@ func doDeleteBlob(jptm IJobPartTransferMgr, p pipeline.Pipeline) {
jptm.Log(pipeline.LogError, errMsg)
common.GetLifecycleMgr().Error(errMsg)
}
}
// in all other cases, make the transfer as failed
transferDone(common.ETransferStatus.Failed(), err)
} else {
Expand Down

0 comments on commit 8fe5d55

Please sign in to comment.