-
Notifications
You must be signed in to change notification settings - Fork 594
HDDS-7828. Make Ozone fs rm symbolic links command support posix behaviour #4246
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
Conversation
…posix symlink delete behavior.
…r listing symbolic link buckets and for deleting symobolic link buckets with ozonefs -ls and -rm commands.
adoroszlai
left a comment
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.
Thanks @neils-dev for working on this. The change in BasicRootedOzoneFileSystem looks good. I wonder if we can avoid duplicating the Delete handler from Hadoop by fixing the symlink argument being passed to FileStatusAdapter (currently hard-coded to null) for link buckets.
Lines 1116 to 1119 in 0a377c6
| return new FileStatusAdapter(0L, 0L, path, true, (short)0, 0L, | |
| ozoneBucket.getCreationTime().getEpochSecond() * 1000, 0L, | |
| FsPermission.getDirDefault().toShort(), | |
| owner, group, null, new BlockLocation[0], |
|
Thanks @adoroszlai for your comment and for reviewing this.
Unfortunately, supporting filestatus symlink does not let us avoid binding in an Ozone Delete handler. The handler is used to set the delete behavior for I too wanted to enable symlink in the filestatus, currently |
hadoop-ozone/ozonefs-common/src/test/java/org/apache/hadoop/fs/ozone/TestOzoneFsShell.java
Outdated
Show resolved
Hide resolved
smengcl
left a comment
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.
overall looks good. nice test additions. minor comments inline.
| // if link, don't delete contents | ||
| if (isBucketLink) { | ||
| if (isBucketLink && !handleTrailingSlash) { |
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.
Need to update the comment above accordingly
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.
Thanks @smengcl for your review comments and for following up the PR. Latest commit to address review comments.
comment updated.
| // Handle delete bucket | ||
| if (ofsPath.isBucket()) { | ||
| if (ofsPath.isBucket() && !handleTrailingSlash) { |
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.
Same here
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.
comment updated.
| // commands, and then this method can be abstract | ||
| if (this.getClass().equals(OzoneFsShell.class)) { | ||
| factory.registerCommands(FsCommand.class); | ||
| // ozone delete rm command registration superscedes fs delete |
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.
nit
| // ozone delete rm command registration superscedes fs delete | |
| // ozone delete rm command registration. supercedes fs delete |
| @InterfaceAudience.Private | ||
| @InterfaceStability.Evolving | ||
|
|
||
| public final class OzoneDelete { |
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.
What about OzoneFsDelete?
| public final class OzoneDelete { | |
| public final class OzoneFsDelete { |
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.
Yes, renamed. Updated the class name and all references to OzoneFsDelete
| // TODO: if the user wants the trash to be used but there is any | ||
| // problem (ie. creating the trash dir, moving the item to be deleted, | ||
| // etc), then the path will just be deleted because moveToTrash returns | ||
| // false and it falls thru to fs.delete. this doesn't seem right | ||
| if (moveToTrash(item) || !canBeSafelyDeleted(item)) { | ||
| return; | ||
| } |
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.
I'm trying to understand this TODO here.
I think in this case (where skipTrash == false but moving to trash has issues) we should just return error to the user. So that they either need to deal with that trash issue first (maybe some ACL issue), or set -skipTrash.
I don't think falling back to to skipTrash would be the intended user behavior, cause they could lose keys when they think those would be moved to the trash.
Also it looks like moveToTrash() is already throwing exception appropriately? Do we need extra handling here? If not we can just fix the comment.
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.
Looked into the moveToTrash() comment.
just return error to the user. So that they either need to deal with that trash issue first (maybe some ACL issue), or set -skipTrash.
I suspect, like you that errors from creating the trash directory or renaming to trash will be handled properly with the exception thrown by trash - similar to
bash-4.2$ ozone fs -rm ofs://om/tmp/tmpfile
rm: Failed to move to trash: ofs://om/tmp/tmpfile: User testuser2/scm@EXAMPLE.COM
doesn't have DELETE permission to access key Volume:tmp Bucket:tmp Key:tmpfile.
Consider using -skipTrash option
Here errors occurring from trash unable to create trash dir or renaming file are handled by exception handling and the file is not outright deleted by fs.delete. File remains intact leaving the user to resolve the issue through permission settings or -skipTrash.
I'm looking to update the comment to reflect this.
| Assert.assertEquals(0, res); | ||
|
|
||
| try { | ||
| objectStore.getVolume(destVolume).getBucket(destVolume); |
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.
typo?
| objectStore.getVolume(destVolume).getBucket(destVolume); | |
| objectStore.getVolume(destVolume).getBucket(srcBucket); |
| // test symlink -rm -R -f destVol/destBucket -> srcVol/srcBucket | ||
| // should delete only link | ||
| // run toolrunner ozone fs shell commands | ||
| linkPathStr = rootPath + destVolume + OZONE_URI_DELIMITER + srcBucket; | ||
| res = ToolRunner.run(shell, new String[]{"-rm", "-skipTrash", | ||
| "-f", "-R", linkPathStr}); | ||
| Assert.assertEquals(0, res); | ||
|
|
||
| Assert.assertEquals(srcBucket, objectStore.getVolume(srcVolume) | ||
| .getBucket(srcBucket).getName()); |
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.
Can also check /srcVolume/srcBucket/key existence
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.
Added the test condition for
/srcVolume/srcBucket/key existence
thanks!
…ete, minor fixes and comment fixes to unit tests, minor comment fixes to BasicRootedOzoneFilesystem. Ammended comment on handling trash withing OzoneFsDelete command handler.
|
@neils-dev , thanks for working on this. I will take a close look later. I tried 'rm -R ' in Linux on a symbolic link to a directory. It looks like that not only the files under the source directory are deleted, symbolic link is also deleted. Shall we follow this behavior too? |
|
@ChenSammi thanks. With the example you mentioned, are you using a trailing slash with the command ie.
That behavior looks to be supported - delete contents of src directory leaving symlink intact. |
|
@neils-dev, I used the command "rm -R path-to-symbolic" without ending slash "/". So the path-to-symbolic is deleted. You are correct, "rm -R path-to-symbolic/" will delete the content in source directory only. Besides the "-rm" command, @neils-dev have you try the "-rmdir" command on the link bucket too? I'm not sure if it already works for link bucket now or not. |
| } | ||
|
|
||
| /** remove non-directory paths. */ | ||
| public static class Rm extends FsCommand { |
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.
Can this Rm extend Delete.Rm? Except expandArgument and processPath are different, other parts of the implementation are the same as Delete.Rm.
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.
Can this Rm extend Delete.Rm?
Thanks. Due to the interface, I found that none of the Delete class or any of the command handlers for the fs shells can be extended outside of the hadoop fs shell package.
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.
@neils-dev We can put the subclass in the org.apache.hadoop.fs.shell package if necessary. Similar solution is employed for reusing other classes from Hadoop (e.g. for EC).
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.
Can this Rm extend Delete.Rm?
After repackaging under the hadoop fs shell package, org.apache.hadoop.fs.shell, it is possible to extend Delete.Rm to a certain extent, however many of the properties and methods used in the subclass overriden methods are private in the base class. The private props and methods include all of the parsed command arguments (private variables in base class), and the garbage collection trash routines needed in the subclass override for processPath , The resulting subclass redefines those private methods to an extent and limits code reuse. It does not appear to be advantageous. This FsCommand does not lend itself to subclassing. Our ozone command handler OzoneFsDelete appears to be flexible and cleaner. We can open a jira to follow-up on looking into this further if it looks worth pursuing, Thoughts?
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.
Thanks @neils-dev for checking. We'll have to live with duplication then.
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.
@neils-dev , thanks for the checking. Then let's keep it.
The patch LGTM +1.
|
@neils-dev , the failed test looks like relevant. |
…links. Fixes CI build failure as a result of the recent symlink orphan node patch.
What changes were proposed in this pull request?
To make ofs symlink delete behavior similar to posix for ozone fs
-rmcommand requests. Specifically to have,i.
$ ozonefs -rm -skipTrash ofs://<omserviceid>/volume/<linked bucket symlink>delete symlink
ii.
$ ozonefs -rm --R -f skipTrash ofs://<omserviceid>/volume/<linked bucket symlink>/recursively delete the contents of the source bucket leaving the symlink and source bucket intact.
Currently, i.) results in an error indicating cannot remove directory and ii.) results in deleting the symlink.
To add posix like symlink
-rmcommand behavior an ozone specific-rmcommand handler,OzoneDelete, is implemented and binded with the fs shell commands.What is the link to the Apache JIRA
https://issues.apache.org/jira/browse/HDDS-7828
How was this patch tested?
Unit tests, for
-rmcommand handler. Integration tests for symlink delete behavior supporting -rm removing symlink and-rm-Rwith trailing slash to remove symlink resolved contents.Unit tests:
TestOzoneFsShell#testOzoneFsShellRegisterDeleteCmdIntegration tests:
TestRootedOzoneFileSystem.#testSymlinkPosixDeleteTestRootedOzoneFileSystem.#testSymlinkList(added test when testing symlink rm behavior)Manual tests:
docker dev cluster -