-
Couldn't load subscription status.
- Fork 239
Handled chown Scenario #1655
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Handled chown Scenario #1655
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This pull request adds chown (change ownership) handling for ADLS accounts, building on existing framework to support file ownership operations. The implementation includes proper error handling, metadata management, and comprehensive test coverage.
- Implements chown functionality for both ADLS and blob storage backends with proper owner/group metadata handling
- Adds owner and group information tracking in file attributes with corresponding flags for detection
- Extends libfuse handlers to properly route chown operations through the component chain with appropriate error mapping
Reviewed Changes
Copilot reviewed 22 out of 22 changed files in this pull request and generated 9 comments.
Show a summary per file
| File | Description |
|---|---|
| internal/attribute.go | Adds owner/group fields and detection flags to ObjAttr structure |
| component/azstorage/datalake.go | Implements actual chown functionality for ADLS using SetAccessControl API |
| component/azstorage/block_blob.go | Implements chown for blob storage using metadata approach |
| component/libfuse/*.go | Updates FUSE handlers to route chown operations and handle errors |
| test files | Adds comprehensive test coverage for chown scenarios and error cases |
Comments suppressed due to low confidence (2)
test/e2e_tests/file_test.go:677
- The test function
TestFileChownandTestFileChownADLShave identical implementations. Consider renaming one to clarify the difference or consolidating if they serve the same purpose.
func (suite *fileTestSuite) TestFileChown() {
| stat := info.Sys().(*syscall.Stat_t) | ||
| suite.Equal(nil, err) | ||
| suite.Equal(1000, stat.Uid) | ||
| suite.Equal(1000, stat.Gid) |
Copilot
AI
Jul 29, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The type assertion (*syscall.Stat_t) could panic if info.Sys() returns a different type. Consider using a safe type assertion with the comma ok idiom: stat, ok := info.Sys().(*syscall.Stat_t); if !ok { ... }
| stat := info.Sys().(*syscall.Stat_t) | |
| suite.Equal(nil, err) | |
| suite.Equal(1000, stat.Uid) | |
| suite.Equal(1000, stat.Gid) | |
| stat, ok := info.Sys().(*syscall.Stat_t) | |
| suite.True(ok, "info.Sys() did not return *syscall.Stat_t") | |
| suite.Equal(nil, err) | |
| if ok { | |
| suite.Equal(1000, stat.Uid) | |
| suite.Equal(1000, stat.Gid) | |
| } |
| stat := info.Sys().(*syscall.Stat_t) | ||
| suite.Equal(nil, err) |
Copilot
AI
Jul 29, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The type assertion (*syscall.Stat_t) could panic if info.Sys() returns a different type. Consider using a safe type assertion with the comma ok idiom: stat, ok := info.Sys().(*syscall.Stat_t); if !ok { ... }
| stat := info.Sys().(*syscall.Stat_t) | |
| suite.Equal(nil, err) | |
| stat, ok := info.Sys().(*syscall.Stat_t) | |
| suite.Equal(nil, err) | |
| if !ok { | |
| suite.Fail("Failed to assert type *syscall.Stat_t for file info.Sys()") | |
| return | |
| } |
| return attr.Flags.IsSet(PropFlagModeDefault) | ||
| } | ||
|
|
||
| // OwnerDetected : |
Copilot
AI
Jul 29, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The comment // OwnerDetected : is incomplete and doesn't describe what the function does. Consider updating it to: // OwnerInfoFound returns true if owner information was found in the object attributes
| // OwnerDetected : | |
| // OwnerInfoFound returns true if owner information was found in the object attributes. |
| return attr.Flags.IsSet(PropFlagOwnerInfoFound) | ||
| } | ||
|
|
||
| // GroupDetected : |
Copilot
AI
Jul 29, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The comment // GroupDetected : is incomplete and doesn't describe what the function does. Consider updating it to: // GroupInfoFound returns true if group information was found in the object attributes
| // GroupDetected : | |
| // GroupInfoFound returns true if group information was found in the object attributes |
component/azstorage/datalake.go
Outdated
| var uidStr, gidStr string | ||
| if uid != -1 { | ||
| uidStr = fmt.Sprintf("%d", uid) | ||
| opts.Owner = &uidStr | ||
| } | ||
|
|
||
| if gid != -1 { | ||
| gidStr = fmt.Sprintf("%d", gid) |
Copilot
AI
Jul 29, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nitpick] The variables uidStr and gidStr are declared but gidStr is only used conditionally. Consider declaring them closer to their usage or within the conditional blocks to improve code clarity.
| var uidStr, gidStr string | |
| if uid != -1 { | |
| uidStr = fmt.Sprintf("%d", uid) | |
| opts.Owner = &uidStr | |
| } | |
| if gid != -1 { | |
| gidStr = fmt.Sprintf("%d", gid) | |
| var uidStr string | |
| if uid != -1 { | |
| uidStr = fmt.Sprintf("%d", uid) | |
| opts.Owner = &uidStr | |
| } | |
| if gid != -1 { | |
| gidStr := fmt.Sprintf("%d", gid) |
| if uid != 0xffffffff { | ||
| // Update only if user has explicitly set the uid | ||
| updatedOwner = AddMetadata(prop.Metadata, common.POSIXOwnerMeta, strconv.FormatUint(uint64(uid), 10)) | ||
| } | ||
| if gid != 0xffffffff { |
Copilot
AI
Jul 29, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The magic number 0xffffffff is used to check for invalid UID/GID. Consider defining a constant like InvalidUID = 0xffffffff to make the code more readable and maintainable.
| if uid != 0xffffffff { | |
| // Update only if user has explicitly set the uid | |
| updatedOwner = AddMetadata(prop.Metadata, common.POSIXOwnerMeta, strconv.FormatUint(uint64(uid), 10)) | |
| } | |
| if gid != 0xffffffff { | |
| if uid != InvalidUID { | |
| // Update only if user has explicitly set the uid | |
| updatedOwner = AddMetadata(prop.Metadata, common.POSIXOwnerMeta, strconv.FormatUint(uint64(uid), 10)) | |
| } | |
| if gid != InvalidUID { |
| if uid != 0xffffffff { | ||
| // Update only if user has explicitly set the uid | ||
| updatedOwner = AddMetadata(prop.Metadata, common.POSIXOwnerMeta, strconv.FormatUint(uint64(uid), 10)) | ||
| } | ||
| if gid != 0xffffffff { |
Copilot
AI
Jul 29, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The magic number 0xffffffff is used to check for invalid UID/GID. Consider defining a constant like InvalidGID = 0xffffffff to make the code more readable and maintainable.
| if uid != 0xffffffff { | |
| // Update only if user has explicitly set the uid | |
| updatedOwner = AddMetadata(prop.Metadata, common.POSIXOwnerMeta, strconv.FormatUint(uint64(uid), 10)) | |
| } | |
| if gid != 0xffffffff { | |
| if uid != InvalidUIDGID { | |
| // Update only if user has explicitly set the uid | |
| updatedOwner = AddMetadata(prop.Metadata, common.POSIXOwnerMeta, strconv.FormatUint(uint64(uid), 10)) | |
| } | |
| if gid != InvalidUIDGID { |
| if owner != 0xffffffff { | ||
| value.attr.Metadata[common.POSIXOwnerMeta] = &ownerStr | ||
| } | ||
|
|
||
| if group != 0xffffffff { |
Copilot
AI
Jul 29, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The magic number 0xffffffff is used to check for invalid owner. Consider defining a constant like InvalidOwner = 0xffffffff to make the code more readable and maintainable.
| if owner != 0xffffffff { | |
| value.attr.Metadata[common.POSIXOwnerMeta] = &ownerStr | |
| } | |
| if group != 0xffffffff { | |
| if owner != InvalidOwner { | |
| value.attr.Metadata[common.POSIXOwnerMeta] = &ownerStr | |
| } | |
| if group != InvalidOwner { |
| if owner != 0xffffffff { | ||
| value.attr.Metadata[common.POSIXOwnerMeta] = &ownerStr | ||
| } | ||
|
|
||
| if group != 0xffffffff { |
Copilot
AI
Jul 29, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The magic number 0xffffffff is used to check for invalid group. Consider defining a constant like InvalidGroup = 0xffffffff to make the code more readable and maintainable.
| if owner != 0xffffffff { | |
| value.attr.Metadata[common.POSIXOwnerMeta] = &ownerStr | |
| } | |
| if group != 0xffffffff { | |
| if owner != InvalidGroup { | |
| value.attr.Metadata[common.POSIXOwnerMeta] = &ownerStr | |
| } | |
| if group != InvalidGroup { |
| if err != nil { | ||
| return 0 | ||
| } | ||
| return int(val) |
Check failure
Code scanning / CodeQL
Incorrect conversion between integer types High
strconv.ParseUint
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 11 days ago
General Fix:
Ensure that the converted value from ParseUint fits in the range of int (which is at least [0, math.MaxInt32] on 32-bit systems; could be up to math.MaxInt64 on 64 bit but safest is to restrict to math.MaxInt).
Detailed Fix:
- After parsing, check whether
valis less than or equal tomath.MaxInt.- If so, safely convert to
int(val)and return. - If not, return 0 or another sentinel value.
- If so, safely convert to
- As
math.MaxIntis available via themathpackage, ensure it's imported. - The code should look like:
val, err := strconv.ParseUint(s, 10, 32)
if err != nil {
return 0
}
if val > uint64(math.MaxInt) {
return 0
}
return int(val)Region/lines to change:
Edit within the function ParseInt in common/util.go (lines 527–536).
-
Copy modified line R47 -
Copy modified lines R536-R538
| @@ -44,6 +44,7 @@ | ||
| "fmt" | ||
| "hash/crc64" | ||
| "io" | ||
| "math" | ||
| "os" | ||
| "os/exec" | ||
| "os/user" | ||
| @@ -532,6 +533,9 @@ | ||
| if err != nil { | ||
| return 0 | ||
| } | ||
| if val > uint64(math.MaxInt) { | ||
| return 0 | ||
| } | ||
| return int(val) | ||
| } | ||
|
|
Type of Change
Description
This pull request introduces changes to add chown handling handling for adls account, and includes corresponding tests.
How Has This Been Tested?
Tested locally and with unit testing.
Still have to cover file_cache handling
Checklist