From fa2c9e82cb27e759c52e80b41de26495768ac5cc Mon Sep 17 00:00:00 2001 From: Chris Nauroth Date: Wed, 16 Jul 2014 05:19:57 +0000 Subject: [PATCH] HADOOP-10845. Merging change r1610911 from trunk to branch-2. git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/branches/branch-2@1610912 13f79535-47bb-0310-9956-ffa450edef68 --- .../hadoop-common/CHANGES.txt | 3 + .../apache/hadoop/fs/viewfs/ChRootedFs.java | 34 +++++++ .../hadoop/fs/viewfs/ViewFileSystem.java | 42 +++++++++ .../org/apache/hadoop/fs/viewfs/ViewFs.java | 89 +++++++++++++++++++ .../fs/viewfs/ViewFileSystemBaseTest.java | 55 +++++++++++- .../hadoop/fs/viewfs/ViewFsBaseTest.java | 52 +++++++++++ 6 files changed, 274 insertions(+), 1 deletion(-) diff --git a/hadoop-common-project/hadoop-common/CHANGES.txt b/hadoop-common-project/hadoop-common/CHANGES.txt index 540f676fe66..bd82fe06972 100644 --- a/hadoop-common-project/hadoop-common/CHANGES.txt +++ b/hadoop-common-project/hadoop-common/CHANGES.txt @@ -19,6 +19,9 @@ Release 2.6.0 - UNRELEASED HADOOP-10673. Update rpc metrics when the call throws an exception. (Ming Ma via jing9) + HADOOP-10845. Add common tests for ACLs in combination with viewfs. + (Stephen Chu via cnauroth) + OPTIMIZATIONS BUG FIXES diff --git a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/viewfs/ChRootedFs.java b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/viewfs/ChRootedFs.java index 2c184f6bb05..f1975eae1b2 100644 --- a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/viewfs/ChRootedFs.java +++ b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/viewfs/ChRootedFs.java @@ -37,6 +37,8 @@ import org.apache.hadoop.fs.FsStatus; import org.apache.hadoop.fs.Options.ChecksumOpt; import org.apache.hadoop.fs.Path; import org.apache.hadoop.fs.UnresolvedLinkException; +import org.apache.hadoop.fs.permission.AclEntry; +import org.apache.hadoop.fs.permission.AclStatus; import org.apache.hadoop.fs.permission.FsPermission; import org.apache.hadoop.security.token.Token; import org.apache.hadoop.util.Progressable; @@ -279,6 +281,38 @@ class ChRootedFs extends AbstractFileSystem { myFs.setTimes(fullPath(f), mtime, atime); } + @Override + public void modifyAclEntries(Path path, List aclSpec) + throws IOException { + myFs.modifyAclEntries(fullPath(path), aclSpec); + } + + @Override + public void removeAclEntries(Path path, List aclSpec) + throws IOException { + myFs.removeAclEntries(fullPath(path), aclSpec); + } + + @Override + public void removeDefaultAcl(Path path) throws IOException { + myFs.removeDefaultAcl(fullPath(path)); + } + + @Override + public void removeAcl(Path path) throws IOException { + myFs.removeAcl(fullPath(path)); + } + + @Override + public void setAcl(Path path, List aclSpec) throws IOException { + myFs.setAcl(fullPath(path), aclSpec); + } + + @Override + public AclStatus getAclStatus(Path path) throws IOException { + return myFs.getAclStatus(fullPath(path)); + } + @Override public void setVerifyChecksum(final boolean verifyChecksum) throws IOException, UnresolvedLinkException { diff --git a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/viewfs/ViewFileSystem.java b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/viewfs/ViewFileSystem.java index b2f2bed5a28..34a9afc5499 100644 --- a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/viewfs/ViewFileSystem.java +++ b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/viewfs/ViewFileSystem.java @@ -50,6 +50,7 @@ import org.apache.hadoop.fs.UnsupportedFileSystemException; import org.apache.hadoop.fs.XAttrSetFlag; import org.apache.hadoop.fs.permission.AclEntry; import org.apache.hadoop.fs.permission.AclStatus; +import org.apache.hadoop.fs.permission.AclUtil; import org.apache.hadoop.fs.permission.FsPermission; import org.apache.hadoop.fs.viewfs.InodeTree.INode; import org.apache.hadoop.fs.viewfs.InodeTree.INodeLink; @@ -871,5 +872,46 @@ public class ViewFileSystem extends FileSystem { public short getDefaultReplication(Path f) { throw new NotInMountpointException(f, "getDefaultReplication"); } + + @Override + public void modifyAclEntries(Path path, List aclSpec) + throws IOException { + checkPathIsSlash(path); + throw readOnlyMountTable("modifyAclEntries", path); + } + + @Override + public void removeAclEntries(Path path, List aclSpec) + throws IOException { + checkPathIsSlash(path); + throw readOnlyMountTable("removeAclEntries", path); + } + + @Override + public void removeDefaultAcl(Path path) throws IOException { + checkPathIsSlash(path); + throw readOnlyMountTable("removeDefaultAcl", path); + } + + @Override + public void removeAcl(Path path) throws IOException { + checkPathIsSlash(path); + throw readOnlyMountTable("removeAcl", path); + } + + @Override + public void setAcl(Path path, List aclSpec) throws IOException { + checkPathIsSlash(path); + throw readOnlyMountTable("setAcl", path); + } + + @Override + public AclStatus getAclStatus(Path path) throws IOException { + checkPathIsSlash(path); + return new AclStatus.Builder().owner(ugi.getUserName()) + .group(ugi.getGroupNames()[0]) + .addEntries(AclUtil.getMinimalAcl(PERMISSION_555)) + .stickyBit(false).build(); + } } } diff --git a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/viewfs/ViewFs.java b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/viewfs/ViewFs.java index f2a433b95f8..232fcbbb409 100644 --- a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/viewfs/ViewFs.java +++ b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/viewfs/ViewFs.java @@ -49,6 +49,9 @@ import org.apache.hadoop.fs.RemoteIterator; import org.apache.hadoop.fs.UnresolvedLinkException; import org.apache.hadoop.fs.UnsupportedFileSystemException; import org.apache.hadoop.fs.local.LocalConfigKeys; +import org.apache.hadoop.fs.permission.AclEntry; +import org.apache.hadoop.fs.permission.AclUtil; +import org.apache.hadoop.fs.permission.AclStatus; import org.apache.hadoop.fs.permission.FsPermission; import org.apache.hadoop.fs.viewfs.InodeTree.INode; import org.apache.hadoop.fs.viewfs.InodeTree.INodeLink; @@ -603,6 +606,51 @@ public class ViewFs extends AbstractFileSystem { return true; } + @Override + public void modifyAclEntries(Path path, List aclSpec) + throws IOException { + InodeTree.ResolveResult res = + fsState.resolve(getUriPath(path), true); + res.targetFileSystem.modifyAclEntries(res.remainingPath, aclSpec); + } + + @Override + public void removeAclEntries(Path path, List aclSpec) + throws IOException { + InodeTree.ResolveResult res = + fsState.resolve(getUriPath(path), true); + res.targetFileSystem.removeAclEntries(res.remainingPath, aclSpec); + } + + @Override + public void removeDefaultAcl(Path path) + throws IOException { + InodeTree.ResolveResult res = + fsState.resolve(getUriPath(path), true); + res.targetFileSystem.removeDefaultAcl(res.remainingPath); + } + + @Override + public void removeAcl(Path path) + throws IOException { + InodeTree.ResolveResult res = + fsState.resolve(getUriPath(path), true); + res.targetFileSystem.removeAcl(res.remainingPath); + } + + @Override + public void setAcl(Path path, List aclSpec) throws IOException { + InodeTree.ResolveResult res = + fsState.resolve(getUriPath(path), true); + res.targetFileSystem.setAcl(res.remainingPath, aclSpec); + } + + @Override + public AclStatus getAclStatus(Path path) throws IOException { + InodeTree.ResolveResult res = + fsState.resolve(getUriPath(path), true); + return res.targetFileSystem.getAclStatus(res.remainingPath); + } /* @@ -832,5 +880,46 @@ public class ViewFs extends AbstractFileSystem { throws AccessControlException { throw readOnlyMountTable("setVerifyChecksum", ""); } + + @Override + public void modifyAclEntries(Path path, List aclSpec) + throws IOException { + checkPathIsSlash(path); + throw readOnlyMountTable("modifyAclEntries", path); + } + + @Override + public void removeAclEntries(Path path, List aclSpec) + throws IOException { + checkPathIsSlash(path); + throw readOnlyMountTable("removeAclEntries", path); + } + + @Override + public void removeDefaultAcl(Path path) throws IOException { + checkPathIsSlash(path); + throw readOnlyMountTable("removeDefaultAcl", path); + } + + @Override + public void removeAcl(Path path) throws IOException { + checkPathIsSlash(path); + throw readOnlyMountTable("removeAcl", path); + } + + @Override + public void setAcl(Path path, List aclSpec) throws IOException { + checkPathIsSlash(path); + throw readOnlyMountTable("setAcl", path); + } + + @Override + public AclStatus getAclStatus(Path path) throws IOException { + checkPathIsSlash(path); + return new AclStatus.Builder().owner(ugi.getUserName()) + .group(ugi.getGroupNames()[0]) + .addEntries(AclUtil.getMinimalAcl(PERMISSION_555)) + .stickyBit(false).build(); + } } } diff --git a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/viewfs/ViewFileSystemBaseTest.java b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/viewfs/ViewFileSystemBaseTest.java index 2d3cb270f11..e1a440d0614 100644 --- a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/viewfs/ViewFileSystemBaseTest.java +++ b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/viewfs/ViewFileSystemBaseTest.java @@ -20,6 +20,7 @@ package org.apache.hadoop.fs.viewfs; import java.io.FileNotFoundException; import java.io.IOException; import java.util.Arrays; +import java.util.ArrayList; import java.util.List; @@ -28,9 +29,16 @@ import org.apache.hadoop.fs.BlockLocation; import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.FileSystemTestHelper; import static org.apache.hadoop.fs.FileSystemTestHelper.*; +import org.apache.hadoop.fs.permission.AclEntry; +import static org.apache.hadoop.fs.viewfs.Constants.PERMISSION_555; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; + import org.apache.hadoop.fs.FileStatus; import org.apache.hadoop.fs.FsConstants; import org.apache.hadoop.fs.Path; +import org.apache.hadoop.fs.permission.AclStatus; +import org.apache.hadoop.fs.permission.AclUtil; import org.apache.hadoop.fs.permission.FsAction; import org.apache.hadoop.fs.permission.FsPermission; import org.apache.hadoop.fs.viewfs.ConfigUtil; @@ -38,6 +46,7 @@ import org.apache.hadoop.fs.viewfs.ViewFileSystem; import org.apache.hadoop.fs.viewfs.ViewFileSystem.MountPoint; import org.apache.hadoop.security.AccessControlException; import org.apache.hadoop.security.Credentials; +import org.apache.hadoop.security.UserGroupInformation; import org.apache.hadoop.security.token.Token; import org.junit.After; import org.junit.Assert; @@ -96,7 +105,6 @@ public class ViewFileSystemBaseTest { // in the test root // Set up the defaultMT in the config with our mount point links - //Configuration conf = new Configuration(); conf = ViewFileSystemTestSetup.createConfig(); setupMountPoints(); fsView = FileSystem.get(FsConstants.VIEWFS_URI, conf); @@ -720,4 +728,49 @@ public class ViewFileSystemBaseTest { Assert.assertTrue("Other-readable permission not set!", perms.getOtherAction().implies(FsAction.READ)); } + + /** + * Verify the behavior of ACL operations on paths above the root of + * any mount table entry. + */ + + @Test(expected=AccessControlException.class) + public void testInternalModifyAclEntries() throws IOException { + fsView.modifyAclEntries(new Path("/internalDir"), + new ArrayList()); + } + + @Test(expected=AccessControlException.class) + public void testInternalRemoveAclEntries() throws IOException { + fsView.removeAclEntries(new Path("/internalDir"), + new ArrayList()); + } + + @Test(expected=AccessControlException.class) + public void testInternalRemoveDefaultAcl() throws IOException { + fsView.removeDefaultAcl(new Path("/internalDir")); + } + + @Test(expected=AccessControlException.class) + public void testInternalRemoveAcl() throws IOException { + fsView.removeAcl(new Path("/internalDir")); + } + + @Test(expected=AccessControlException.class) + public void testInternalSetAcl() throws IOException { + fsView.setAcl(new Path("/internalDir"), new ArrayList()); + } + + @Test + public void testInternalGetAclStatus() throws IOException { + final UserGroupInformation currentUser = + UserGroupInformation.getCurrentUser(); + AclStatus aclStatus = fsView.getAclStatus(new Path("/internalDir")); + assertEquals(aclStatus.getOwner(), currentUser.getUserName()); + assertEquals(aclStatus.getGroup(), currentUser.getGroupNames()[0]); + assertEquals(aclStatus.getEntries(), + AclUtil.getMinimalAcl(PERMISSION_555)); + assertFalse(aclStatus.isStickyBit()); + } + } diff --git a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/viewfs/ViewFsBaseTest.java b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/viewfs/ViewFsBaseTest.java index 0f771cd3ba5..2813c34bef4 100644 --- a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/viewfs/ViewFsBaseTest.java +++ b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/viewfs/ViewFsBaseTest.java @@ -22,10 +22,14 @@ import static org.apache.hadoop.fs.FileContextTestHelper.checkFileStatus; import static org.apache.hadoop.fs.FileContextTestHelper.exists; import static org.apache.hadoop.fs.FileContextTestHelper.isDir; import static org.apache.hadoop.fs.FileContextTestHelper.isFile; +import static org.apache.hadoop.fs.viewfs.Constants.PERMISSION_555; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import java.io.FileNotFoundException; import java.io.IOException; import java.net.URI; +import java.util.ArrayList; import java.util.List; import org.apache.hadoop.conf.Configuration; @@ -39,8 +43,12 @@ import org.apache.hadoop.fs.FileStatus; import org.apache.hadoop.fs.FsConstants; import org.apache.hadoop.fs.Path; import org.apache.hadoop.fs.UnresolvedLinkException; +import org.apache.hadoop.fs.permission.AclEntry; +import org.apache.hadoop.fs.permission.AclStatus; +import org.apache.hadoop.fs.permission.AclUtil; import org.apache.hadoop.fs.viewfs.ViewFs.MountPoint; import org.apache.hadoop.security.AccessControlException; +import org.apache.hadoop.security.UserGroupInformation; import org.apache.hadoop.security.token.Token; import org.junit.After; import org.junit.Assert; @@ -695,4 +703,48 @@ public class ViewFsBaseTest { public void testInternalSetOwner() throws IOException { fcView.setOwner(new Path("/internalDir"), "foo", "bar"); } + + /** + * Verify the behavior of ACL operations on paths above the root of + * any mount table entry. + */ + + @Test(expected=AccessControlException.class) + public void testInternalModifyAclEntries() throws IOException { + fcView.modifyAclEntries(new Path("/internalDir"), + new ArrayList()); + } + + @Test(expected=AccessControlException.class) + public void testInternalRemoveAclEntries() throws IOException { + fcView.removeAclEntries(new Path("/internalDir"), + new ArrayList()); + } + + @Test(expected=AccessControlException.class) + public void testInternalRemoveDefaultAcl() throws IOException { + fcView.removeDefaultAcl(new Path("/internalDir")); + } + + @Test(expected=AccessControlException.class) + public void testInternalRemoveAcl() throws IOException { + fcView.removeAcl(new Path("/internalDir")); + } + + @Test(expected=AccessControlException.class) + public void testInternalSetAcl() throws IOException { + fcView.setAcl(new Path("/internalDir"), new ArrayList()); + } + + @Test + public void testInternalGetAclStatus() throws IOException { + final UserGroupInformation currentUser = + UserGroupInformation.getCurrentUser(); + AclStatus aclStatus = fcView.getAclStatus(new Path("/internalDir")); + assertEquals(aclStatus.getOwner(), currentUser.getUserName()); + assertEquals(aclStatus.getGroup(), currentUser.getGroupNames()[0]); + assertEquals(aclStatus.getEntries(), + AclUtil.getMinimalAcl(PERMISSION_555)); + assertFalse(aclStatus.isStickyBit()); + } }