Skip to content

Commit 346837a

Browse files
adreed-msftnakulkar-msft
authored andcommitted
Implement container-level ACL copies (#2049)
* Implement container-level ACL copies * Prevent AssertNoErr from crashing test suite * Fix delete functionality & testing * Grab subdir in a different way * Fix Build * Lint
1 parent 8d1cebd commit 346837a

19 files changed

+128
-51
lines changed

cmd/copyEnumeratorInit.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ func (cca *CookedCopyCmdArgs) initEnumerator(jobPartOrder common.CopyJobPartOrde
7171
traverser, err = InitResourceTraverser(cca.Source, cca.FromTo.From(), &ctx, &srcCredInfo,
7272
cca.SymlinkHandling, cca.ListOfFilesChannel, cca.Recursive, getRemoteProperties,
7373
cca.IncludeDirectoryStubs, cca.permanentDeleteOption, func(common.EntityType) {}, cca.ListOfVersionIDs,
74-
cca.S2sPreserveBlobTags, common.ESyncHashType.None(), azcopyLogVerbosity.ToPipelineLogLevel(), cca.CpkOptions, nil /* errorChannel */)
74+
cca.S2sPreserveBlobTags, common.ESyncHashType.None(), cca.preservePermissions, azcopyLogVerbosity.ToPipelineLogLevel(), cca.CpkOptions, nil /* errorChannel */)
7575

7676
if err != nil {
7777
return nil, err
@@ -117,8 +117,8 @@ func (cca *CookedCopyCmdArgs) initEnumerator(jobPartOrder common.CopyJobPartOrde
117117
return nil, errors.New("cannot use --as-subdir=false with a service level destination")
118118
}
119119

120-
// When copying a container directly to a container, strip the top directory
121-
if srcLevel == ELocationLevel.Container() && dstLevel == ELocationLevel.Container() && cca.FromTo.From().IsRemote() && cca.FromTo.To().IsRemote() {
120+
// When copying a container directly to a container, strip the top directory, unless we're attempting to persist permissions.
121+
if srcLevel == ELocationLevel.Container() && dstLevel == ELocationLevel.Container() && cca.FromTo.From().IsRemote() && cca.FromTo.To().IsRemote() && !cca.preservePermissions.IsTruthy() {
122122
cca.StripTopDir = true
123123
}
124124

@@ -338,7 +338,7 @@ func (cca *CookedCopyCmdArgs) isDestDirectory(dst common.ResourceString, ctx *co
338338

339339
rt, err := InitResourceTraverser(dst, cca.FromTo.To(), ctx, &dstCredInfo, common.ESymlinkHandlingType.Skip(),
340340
nil, false, false, false, common.EPermanentDeleteOption.None(),
341-
func(common.EntityType) {}, cca.ListOfVersionIDs, false, common.ESyncHashType.None(), pipeline.LogNone, cca.CpkOptions, nil /* errorChannel */)
341+
func(common.EntityType) {}, cca.ListOfVersionIDs, false, common.ESyncHashType.None(), cca.preservePermissions, pipeline.LogNone, cca.CpkOptions, nil /* errorChannel */)
342342

343343
if err != nil {
344344
return false

cmd/copyEnumeratorInit_test.go

+5-5
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ func (ce *copyEnumeratorSuite) TestValidateSourceDirThatExists(c *chk.C) {
4949

5050
// List
5151
rawBlobURLWithSAS := scenarioHelper{}.getRawBlobURLWithSAS(c, containerName, dirName)
52-
blobTraverser := newBlobTraverser(&rawBlobURLWithSAS, p, ctx, true, true, func(common.EntityType) {}, false, common.CpkOptions{}, false, false, false)
52+
blobTraverser := newBlobTraverser(&rawBlobURLWithSAS, p, ctx, true, true, func(common.EntityType) {}, false, common.CpkOptions{}, false, false, false, common.EPreservePermissionsOption.None())
5353

5454
// dir but recursive flag not set - fail
5555
cca := CookedCopyCmdArgs{StripTopDir: false, Recursive: false}
@@ -78,7 +78,7 @@ func (ce *copyEnumeratorSuite) TestValidateSourceDirDoesNotExist(c *chk.C) {
7878

7979
// List
8080
rawBlobURLWithSAS := scenarioHelper{}.getRawBlobURLWithSAS(c, containerName, dirName)
81-
blobTraverser := newBlobTraverser(&rawBlobURLWithSAS, p, ctx, true, true, func(common.EntityType) {}, false, common.CpkOptions{}, false, false, false)
81+
blobTraverser := newBlobTraverser(&rawBlobURLWithSAS, p, ctx, true, true, func(common.EntityType) {}, false, common.CpkOptions{}, false, false, false, common.EPreservePermissionsOption.None())
8282

8383
// dir but recursive flag not set - fail
8484
cca := CookedCopyCmdArgs{StripTopDir: false, Recursive: false}
@@ -108,7 +108,7 @@ func (ce *copyEnumeratorSuite) TestValidateSourceFileExists(c *chk.C) {
108108

109109
// List
110110
rawBlobURLWithSAS := scenarioHelper{}.getRawBlobURLWithSAS(c, containerName, fileName)
111-
blobTraverser := newBlobTraverser(&rawBlobURLWithSAS, p, ctx, true, true, func(common.EntityType) {}, false, common.CpkOptions{}, false, false, false)
111+
blobTraverser := newBlobTraverser(&rawBlobURLWithSAS, p, ctx, true, true, func(common.EntityType) {}, false, common.CpkOptions{}, false, false, false, common.EPreservePermissionsOption.None())
112112

113113
cca := CookedCopyCmdArgs{StripTopDir: false, Recursive: false}
114114
err := cca.validateSourceDir(blobTraverser)
@@ -131,7 +131,7 @@ func (ce *copyEnumeratorSuite) TestValidateSourceFileDoesNotExist(c *chk.C) {
131131

132132
// List
133133
rawBlobURLWithSAS := scenarioHelper{}.getRawBlobURLWithSAS(c, containerName, fileName)
134-
blobTraverser := newBlobTraverser(&rawBlobURLWithSAS, p, ctx, true, true, func(common.EntityType) {}, false, common.CpkOptions{}, false, false, false)
134+
blobTraverser := newBlobTraverser(&rawBlobURLWithSAS, p, ctx, true, true, func(common.EntityType) {}, false, common.CpkOptions{}, false, false, false, common.EPreservePermissionsOption.None())
135135

136136
cca := CookedCopyCmdArgs{StripTopDir: false, Recursive: false}
137137
err := cca.validateSourceDir(blobTraverser)
@@ -154,7 +154,7 @@ func (ce *copyEnumeratorSuite) TestValidateSourceWithWildCard(c *chk.C) {
154154

155155
// List
156156
rawBlobURLWithSAS := scenarioHelper{}.getRawBlobURLWithSAS(c, containerName, dirName)
157-
blobTraverser := newBlobTraverser(&rawBlobURLWithSAS, p, ctx, true, true, func(common.EntityType) {}, false, common.CpkOptions{}, false, false, false)
157+
blobTraverser := newBlobTraverser(&rawBlobURLWithSAS, p, ctx, true, true, func(common.EntityType) {}, false, common.CpkOptions{}, false, false, false, common.EPreservePermissionsOption.None())
158158

159159
// dir but recursive flag not set - fail
160160
cca := CookedCopyCmdArgs{StripTopDir: true, Recursive: false}

cmd/list.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ func (cooked cookedListCmdArgs) HandleListContainerCommand() (err error) {
224224

225225
traverser, err := InitResourceTraverser(source, cooked.location, &ctx, &credentialInfo, common.ESymlinkHandlingType.Skip(), nil,
226226
true, false, false, common.EPermanentDeleteOption.None(), func(common.EntityType) {},
227-
nil, false, common.ESyncHashType.None(), pipeline.LogNone, common.CpkOptions{}, nil /* errorChannel */)
227+
nil, false, common.ESyncHashType.None(), common.EPreservePermissionsOption.None(), pipeline.LogNone, common.CpkOptions{}, nil /* errorChannel */)
228228

229229
if err != nil {
230230
return fmt.Errorf("failed to initialize traverser: %s", err.Error())

cmd/removeEnumerator.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ func newRemoveEnumerator(cca *CookedCopyCmdArgs) (enumerator *CopyEnumerator, er
5151
sourceTraverser, err = InitResourceTraverser(cca.Source, cca.FromTo.From(), &ctx, &cca.credentialInfo,
5252
common.ESymlinkHandlingType.Skip(), cca.ListOfFilesChannel, cca.Recursive, false, cca.IncludeDirectoryStubs,
5353
cca.permanentDeleteOption, func(common.EntityType) {}, cca.ListOfVersionIDs, false,
54-
common.ESyncHashType.None(), azcopyLogVerbosity.ToPipelineLogLevel(), cca.CpkOptions, nil /* errorChannel */)
54+
common.ESyncHashType.None(), common.EPreservePermissionsOption.None(), azcopyLogVerbosity.ToPipelineLogLevel(), cca.CpkOptions, nil /* errorChannel */)
5555

5656
// report failure to create traverser
5757
if err != nil {

cmd/setPropertiesEnumerator.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ func setPropertiesEnumerator(cca *CookedCopyCmdArgs) (enumerator *CopyEnumerator
5151
common.ESymlinkHandlingType.Preserve(), // preserve because we want to index all blobs, including symlink blobs
5252
cca.ListOfFilesChannel, cca.Recursive, false, cca.IncludeDirectoryStubs,
5353
cca.permanentDeleteOption, func(common.EntityType) {}, cca.ListOfVersionIDs, false,
54-
common.ESyncHashType.None(), azcopyLogVerbosity.ToPipelineLogLevel(), cca.CpkOptions, nil /* errorChannel */)
54+
common.ESyncHashType.None(), common.EPreservePermissionsOption.None(), azcopyLogVerbosity.ToPipelineLogLevel(), cca.CpkOptions, nil /* errorChannel */)
5555

5656
// report failure to create traverser
5757
if err != nil {

cmd/syncEnumerator.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ func (cca *cookedSyncCmdArgs) initEnumerator(ctx context.Context) (enumerator *s
6565
if entityType == common.EEntityType.File() {
6666
atomic.AddUint64(&cca.atomicSourceFilesScanned, 1)
6767
}
68-
}, nil, cca.s2sPreserveBlobTags, cca.compareHash, azcopyLogVerbosity.ToPipelineLogLevel(), cca.cpkOptions, nil /* errorChannel */)
68+
}, nil, cca.s2sPreserveBlobTags, cca.compareHash, cca.preservePermissions, azcopyLogVerbosity.ToPipelineLogLevel(), cca.cpkOptions, nil /* errorChannel */)
6969

7070
if err != nil {
7171
return nil, err
@@ -86,7 +86,7 @@ func (cca *cookedSyncCmdArgs) initEnumerator(ctx context.Context) (enumerator *s
8686
if entityType == common.EEntityType.File() {
8787
atomic.AddUint64(&cca.atomicDestinationFilesScanned, 1)
8888
}
89-
}, nil, cca.s2sPreserveBlobTags, cca.compareHash, azcopyLogVerbosity.ToPipelineLogLevel(), cca.cpkOptions, nil /* errorChannel */)
89+
}, nil, cca.s2sPreserveBlobTags, cca.compareHash, cca.preservePermissions, azcopyLogVerbosity.ToPipelineLogLevel(), cca.cpkOptions, nil /* errorChannel */)
9090
if err != nil {
9191
return nil, err
9292
}

cmd/zc_enumerator.go

100644100755
+5-5
Original file line numberDiff line numberDiff line change
@@ -332,7 +332,7 @@ type enumerationCounterFunc func(entityType common.EntityType)
332332
func InitResourceTraverser(resource common.ResourceString, location common.Location, ctx *context.Context,
333333
credential *common.CredentialInfo, symlinkHandling common.SymlinkHandlingType, listOfFilesChannel chan string, recursive, getProperties,
334334
includeDirectoryStubs bool, permanentDeleteOption common.PermanentDeleteOption, incrementEnumerationCounter enumerationCounterFunc, listOfVersionIds chan string,
335-
s2sPreserveBlobTags bool, syncHashType common.SyncHashType, logLevel pipeline.LogLevel, cpkOptions common.CpkOptions, errorChannel chan ErrorFileInfo) (ResourceTraverser, error) {
335+
s2sPreserveBlobTags bool, syncHashType common.SyncHashType, preservePermissions common.PreservePermissionsOption, logLevel pipeline.LogLevel, cpkOptions common.CpkOptions, errorChannel chan ErrorFileInfo) (ResourceTraverser, error) {
336336
var output ResourceTraverser
337337
var p *pipeline.Pipeline
338338

@@ -380,7 +380,7 @@ func InitResourceTraverser(resource common.ResourceString, location common.Locat
380380
}
381381

382382
output = newListTraverser(resource, location, credential, ctx, recursive, symlinkHandling, getProperties,
383-
listOfFilesChannel, includeDirectoryStubs, incrementEnumerationCounter, s2sPreserveBlobTags, logLevel, cpkOptions)
383+
listOfFilesChannel, includeDirectoryStubs, incrementEnumerationCounter, s2sPreserveBlobTags, logLevel, cpkOptions, syncHashType, preservePermissions)
384384
return output, nil
385385
}
386386

@@ -408,7 +408,7 @@ func InitResourceTraverser(resource common.ResourceString, location common.Locat
408408

409409
baseResource := resource.CloneWithValue(cleanLocalPath(basePath))
410410
output = newListTraverser(baseResource, location, nil, nil, recursive, symlinkHandling, getProperties,
411-
globChan, includeDirectoryStubs, incrementEnumerationCounter, s2sPreserveBlobTags, logLevel, cpkOptions)
411+
globChan, includeDirectoryStubs, incrementEnumerationCounter, s2sPreserveBlobTags, logLevel, cpkOptions, syncHashType, preservePermissions)
412412
} else {
413413
if ctx != nil {
414414
output = newLocalTraverser(*ctx, resource.ValueLocal(), recursive, symlinkHandling, syncHashType, incrementEnumerationCounter, errorChannel)
@@ -443,11 +443,11 @@ func InitResourceTraverser(resource common.ResourceString, location common.Locat
443443
return nil, errors.New(accountTraversalInherentlyRecursiveError)
444444
}
445445

446-
output = newBlobAccountTraverser(resourceURL, *p, *ctx, includeDirectoryStubs, incrementEnumerationCounter, s2sPreserveBlobTags, cpkOptions)
446+
output = newBlobAccountTraverser(resourceURL, *p, *ctx, includeDirectoryStubs, incrementEnumerationCounter, s2sPreserveBlobTags, cpkOptions, preservePermissions)
447447
} else if listOfVersionIds != nil {
448448
output = newBlobVersionsTraverser(resourceURL, *p, *ctx, recursive, includeDirectoryStubs, incrementEnumerationCounter, listOfVersionIds, cpkOptions)
449449
} else {
450-
output = newBlobTraverser(resourceURL, *p, *ctx, recursive, includeDirectoryStubs, incrementEnumerationCounter, s2sPreserveBlobTags, cpkOptions, includeDeleted, includeSnapshot, includeVersion)
450+
output = newBlobTraverser(resourceURL, *p, *ctx, recursive, includeDirectoryStubs, incrementEnumerationCounter, s2sPreserveBlobTags, cpkOptions, includeDeleted, includeSnapshot, includeVersion, preservePermissions)
451451
}
452452
case common.ELocation.File():
453453
resourceURL, err := resource.FullURL()

cmd/zc_traverser_blob.go

+34-2
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import (
2525
"fmt"
2626
"net/url"
2727
"strings"
28+
"time"
2829

2930
"github.com/Azure/azure-storage-azcopy/v10/common/parallel"
3031

@@ -56,6 +57,8 @@ type blobTraverser struct {
5657

5758
cpkOptions common.CpkOptions
5859

60+
preservePermissions common.PreservePermissionsOption
61+
5962
includeDeleted bool
6063

6164
includeSnapshot bool
@@ -222,7 +225,7 @@ func (t *blobTraverser) Traverse(preprocessor objectMorpher, processor objectPro
222225
}
223226
}
224227
if t.incrementEnumerationCounter != nil {
225-
t.incrementEnumerationCounter(common.EEntityType.File())
228+
t.incrementEnumerationCounter(storedObject.entityType)
226229
}
227230

228231
err := processIfPassedFilters(filters, storedObject, processor)
@@ -232,6 +235,34 @@ func (t *blobTraverser) Traverse(preprocessor objectMorpher, processor objectPro
232235
if !t.includeDeleted && (isBlob || err != nil) {
233236
return err
234237
}
238+
} else if blobUrlParts.BlobName == "" && t.preservePermissions.IsTruthy() {
239+
// if the root is a container and we're copying "folders", we should persist the ACLs there too.
240+
if azcopyScanningLogger != nil {
241+
azcopyScanningLogger.Log(pipeline.LogDebug, "Detected the root as a container.")
242+
}
243+
244+
storedObject := newStoredObject(
245+
preprocessor,
246+
"",
247+
"",
248+
common.EEntityType.Folder(),
249+
time.Now(),
250+
0,
251+
noContentProps,
252+
noBlobProps,
253+
common.Metadata{},
254+
blobUrlParts.ContainerName,
255+
)
256+
257+
if t.incrementEnumerationCounter != nil {
258+
t.incrementEnumerationCounter(common.EEntityType.Folder())
259+
}
260+
261+
err := processIfPassedFilters(filters, storedObject, processor)
262+
_, err = getProcessingError(err)
263+
if err != nil {
264+
return err
265+
}
235266
}
236267

237268
// get the container URL so that we can list the blobs
@@ -487,7 +518,7 @@ func (t *blobTraverser) serialList(containerURL azblob.ContainerURL, containerNa
487518
return nil
488519
}
489520

490-
func newBlobTraverser(rawURL *url.URL, p pipeline.Pipeline, ctx context.Context, recursive, includeDirectoryStubs bool, incrementEnumerationCounter enumerationCounterFunc, s2sPreserveSourceTags bool, cpkOptions common.CpkOptions, includeDeleted, includeSnapshot, includeVersion bool) (t *blobTraverser) {
521+
func newBlobTraverser(rawURL *url.URL, p pipeline.Pipeline, ctx context.Context, recursive, includeDirectoryStubs bool, incrementEnumerationCounter enumerationCounterFunc, s2sPreserveSourceTags bool, cpkOptions common.CpkOptions, includeDeleted, includeSnapshot, includeVersion bool, preservePermissions common.PreservePermissionsOption) (t *blobTraverser) {
491522
t = &blobTraverser{
492523
rawURL: rawURL,
493524
p: p,
@@ -501,6 +532,7 @@ func newBlobTraverser(rawURL *url.URL, p pipeline.Pipeline, ctx context.Context,
501532
includeDeleted: includeDeleted,
502533
includeSnapshot: includeSnapshot,
503534
includeVersion: includeVersion,
535+
preservePermissions: preservePermissions,
504536
}
505537

506538
disableHierarchicalScanning := strings.ToLower(glcm.GetEnvironmentVariable(common.EEnvironmentVariable.DisableHierarchicalScanning()))

cmd/zc_traverser_blob_account.go

+4-2
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ type blobAccountTraverser struct {
4545
s2sPreserveSourceTags bool
4646

4747
cpkOptions common.CpkOptions
48+
preservePermissions common.PreservePermissionsOption
4849
}
4950

5051
func (t *blobAccountTraverser) IsDirectory(_ bool) (bool, error) {
@@ -100,7 +101,7 @@ func (t *blobAccountTraverser) Traverse(preprocessor objectMorpher, processor ob
100101

101102
for _, v := range cList {
102103
containerURL := t.accountURL.NewContainerURL(v).URL()
103-
containerTraverser := newBlobTraverser(&containerURL, t.p, t.ctx, true, t.includeDirectoryStubs, t.incrementEnumerationCounter, t.s2sPreserveSourceTags, t.cpkOptions, false, false, false)
104+
containerTraverser := newBlobTraverser(&containerURL, t.p, t.ctx, true, t.includeDirectoryStubs, t.incrementEnumerationCounter, t.s2sPreserveSourceTags, t.cpkOptions, false, false, false, t.preservePermissions)
104105

105106
preprocessorForThisChild := preprocessor.FollowedBy(newContainerDecorator(v))
106107

@@ -115,7 +116,7 @@ func (t *blobAccountTraverser) Traverse(preprocessor objectMorpher, processor ob
115116
return nil
116117
}
117118

118-
func newBlobAccountTraverser(rawURL *url.URL, p pipeline.Pipeline, ctx context.Context, includeDirectoryStubs bool, incrementEnumerationCounter enumerationCounterFunc, s2sPreserveSourceTags bool, cpkOptions common.CpkOptions) (t *blobAccountTraverser) {
119+
func newBlobAccountTraverser(rawURL *url.URL, p pipeline.Pipeline, ctx context.Context, includeDirectoryStubs bool, incrementEnumerationCounter enumerationCounterFunc, s2sPreserveSourceTags bool, cpkOptions common.CpkOptions, preservePermissions common.PreservePermissionsOption) (t *blobAccountTraverser) {
119120
bURLParts := azblob.NewBlobURLParts(*rawURL)
120121
cPattern := bURLParts.ContainerName
121122

@@ -133,6 +134,7 @@ func newBlobAccountTraverser(rawURL *url.URL, p pipeline.Pipeline, ctx context.C
133134
includeDirectoryStubs: includeDirectoryStubs,
134135
s2sPreserveSourceTags: s2sPreserveSourceTags,
135136
cpkOptions: cpkOptions,
137+
preservePermissions: preservePermissions,
136138
}
137139

138140
return

cmd/zc_traverser_list.go

+2-3
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,7 @@ func (l *listTraverser) Traverse(preprocessor objectMorpher, processor objectPro
9292
func newListTraverser(parent common.ResourceString, parentType common.Location, credential *common.CredentialInfo,
9393
ctx *context.Context, recursive bool, handleSymlinks common.SymlinkHandlingType, getProperties bool, listChan chan string,
9494
includeDirectoryStubs bool, incrementEnumerationCounter enumerationCounterFunc, s2sPreserveBlobTags bool,
95-
logLevel pipeline.LogLevel, cpkOptions common.CpkOptions) ResourceTraverser {
96-
95+
logLevel pipeline.LogLevel, cpkOptions common.CpkOptions, syncHashType common.SyncHashType, preservePermissions common.PreservePermissionsOption) ResourceTraverser {
9796
traverserGenerator := func(relativeChildPath string) (ResourceTraverser, error) {
9897
source := parent.Clone()
9998
if parentType != common.ELocation.Local() {
@@ -109,7 +108,7 @@ func newListTraverser(parent common.ResourceString, parentType common.Location,
109108
// Construct a traverser that goes through the child
110109
traverser, err := InitResourceTraverser(source, parentType, ctx, credential, handleSymlinks,
111110
nil, recursive, getProperties, includeDirectoryStubs, common.EPermanentDeleteOption.None(), incrementEnumerationCounter,
112-
nil, s2sPreserveBlobTags, common.ESyncHashType.None(), logLevel, cpkOptions, nil /* errorChannel */)
111+
nil, s2sPreserveBlobTags, syncHashType, preservePermissions, logLevel, cpkOptions, nil /* errorChannel */)
113112
if err != nil {
114113
return nil, err
115114
}

cmd/zt_copy_blob_download_test.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ func (s *cmdIntegrationSuite) TestDownloadAccount(c *chk.C) {
174174

175175
// Traverse the account ahead of time and determine the relative paths for testing.
176176
relPaths := make([]string, 0) // Use a map for easy lookup
177-
blobTraverser := newBlobAccountTraverser(&rawBSU, p, ctx, false, func(common.EntityType) {}, false, common.CpkOptions{})
177+
blobTraverser := newBlobAccountTraverser(&rawBSU, p, ctx, false, func(common.EntityType) {}, false, common.CpkOptions{}, common.EPreservePermissionsOption.None())
178178
processor := func(object StoredObject) error {
179179
// Append the container name to the relative path
180180
relPath := "/" + object.ContainerName + "/" + object.relativePath
@@ -222,7 +222,7 @@ func (s *cmdIntegrationSuite) TestDownloadAccountWildcard(c *chk.C) {
222222

223223
// Traverse the account ahead of time and determine the relative paths for testing.
224224
relPaths := make([]string, 0) // Use a map for easy lookup
225-
blobTraverser := newBlobAccountTraverser(&rawBSU, p, ctx, false, func(common.EntityType) {}, false, common.CpkOptions{})
225+
blobTraverser := newBlobAccountTraverser(&rawBSU, p, ctx, false, func(common.EntityType) {}, false, common.CpkOptions{}, common.EPreservePermissionsOption.None())
226226
processor := func(object StoredObject) error {
227227
// Append the container name to the relative path
228228
relPath := "/" + object.ContainerName + "/" + object.relativePath

0 commit comments

Comments
 (0)