diff --git a/CHANGELOG.md b/CHANGELOG.md index 7a0e3df7..b3f2206a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,8 @@ -## 2.3.0~preview.2 (Unreleased) +## 2.3.0 (Unreleased) **Bug Fixes** - For fuse minor version check rely on the fusermount3 command output rather then one exposed from fuse_common. - Fixed large number of threads from TLRU causing crash during disk eviction in block-cache. +- Fixed issue where get attributes was failing for directories in blob accounts when CPK flag was enabled. **Features** - Added support for authentication using Azure CLI. diff --git a/common/types.go b/common/types.go index e879e517..5933efee 100644 --- a/common/types.go +++ b/common/types.go @@ -47,7 +47,7 @@ import ( // Standard config default values const ( - blobfuse2Version_ = "2.3.0~preview.2" + blobfuse2Version_ = "2.3.0" DefaultMaxLogFileSize = 512 DefaultLogFileCount = 10 diff --git a/component/azstorage/block_blob.go b/component/azstorage/block_blob.go index 4cf621f4..8a7314b4 100644 --- a/component/azstorage/block_blob.go +++ b/component/azstorage/block_blob.go @@ -572,24 +572,32 @@ func (bb *BlockBlob) List(prefix string, marker *string, count int32) ([]*intern // For some directories 0 byte meta file may not exists so just create a map to figure out such directories var dirList = make(map[string]bool) - for _, blobInfo := range listBlob.Segment.BlobItems { - attr := &internal.ObjAttr{ - Path: split(bb.Config.prefixPath, *blobInfo.Name), - Name: filepath.Base(*blobInfo.Name), - Size: *blobInfo.Properties.ContentLength, - Mode: 0, - Mtime: *blobInfo.Properties.LastModified, - Atime: dereferenceTime(blobInfo.Properties.LastAccessedOn, *blobInfo.Properties.LastModified), - Ctime: *blobInfo.Properties.LastModified, - Crtime: dereferenceTime(blobInfo.Properties.CreationTime, *blobInfo.Properties.LastModified), - Flags: internal.NewFileBitMap(), - MD5: blobInfo.Properties.ContentMD5, + attr := &internal.ObjAttr{} + if blobInfo.Properties.CustomerProvidedKeySHA256 != nil && *blobInfo.Properties.CustomerProvidedKeySHA256 != "" { + log.Trace("BlockBlob::List : blob is encrypted with customer provided key so fetching metadata explicitly using REST") + attr, err = bb.getAttrUsingRest(*blobInfo.Name) + if err != nil { + log.Err("BlockBlob::List : Failed to get properties of blob %s", *blobInfo.Name) + return blobList, nil, err + } + } else { + attr = &internal.ObjAttr{ + Path: split(bb.Config.prefixPath, *blobInfo.Name), + Name: filepath.Base(*blobInfo.Name), + Size: *blobInfo.Properties.ContentLength, + Mode: 0, + Mtime: *blobInfo.Properties.LastModified, + Atime: dereferenceTime(blobInfo.Properties.LastAccessedOn, *blobInfo.Properties.LastModified), + Ctime: *blobInfo.Properties.LastModified, + Crtime: dereferenceTime(blobInfo.Properties.CreationTime, *blobInfo.Properties.LastModified), + Flags: internal.NewFileBitMap(), + MD5: blobInfo.Properties.ContentMD5, + } + parseMetadata(attr, blobInfo.Metadata) + attr.Flags.Set(internal.PropFlagMetadataRetrieved) + attr.Flags.Set(internal.PropFlagModeDefault) } - - parseMetadata(attr, blobInfo.Metadata) - attr.Flags.Set(internal.PropFlagMetadataRetrieved) - attr.Flags.Set(internal.PropFlagModeDefault) blobList = append(blobList, attr) if attr.IsDir() { diff --git a/component/azstorage/block_blob_test.go b/component/azstorage/block_blob_test.go index b8d2d224..88d15853 100644 --- a/component/azstorage/block_blob_test.go +++ b/component/azstorage/block_blob_test.go @@ -1958,6 +1958,26 @@ func (s *blockBlobTestSuite) TestGetAttrVirtualDirSubDir() { s.assert.False(props.IsSymlink()) } +func (s *blockBlobTestSuite) TestGetAttrDirWithCPKEnabled() { + defer s.cleanupTest() + CPKEncryptionKey, CPKEncryptionKeySHA256 := generateCPKInfo() + config := fmt.Sprintf("azstorage:\n account-name: %s\n endpoint: https://%s.blob.core.windows.net/\n type: block\n cpk-enabled: true\n cpk-encryption-key: %s\n cpk-encryption-key-sha256: %s\n account-key: %s\n mode: key\n container: %s\n", + storageTestConfigurationParameters.BlockAccount, storageTestConfigurationParameters.BlockAccount, CPKEncryptionKey, CPKEncryptionKeySHA256, storageTestConfigurationParameters.BlockKey, s.container) + + s.tearDownTestHelper(false) + s.setupTestHelper(config, s.container, false) + + name := generateDirectoryName() + s.az.CreateDir(internal.CreateDirOptions{Name: name}) + + props, err := s.az.GetAttr(internal.GetAttrOptions{Name: name}) + s.assert.Nil(err) + s.assert.NotNil(props) + s.assert.True(props.IsDir()) + s.assert.NotEmpty(props.Metadata) + s.assert.True(checkMetadata(props.Metadata, folderKey, "true")) +} + func (s *blockBlobTestSuite) TestGetAttrFile() { defer s.cleanupTest() vdConfig := fmt.Sprintf("azstorage:\n account-name: %s\n endpoint: https://%s.blob.core.windows.net/\n type: block\n account-key: %s\n mode: key\n container: %s\n fail-unsupported-op: true\n virtual-directory: true",