From 68e98d918bce7e37025ffc9a6890d9e6c70797b9 Mon Sep 17 00:00:00 2001 From: tangyoupeng Date: Wed, 20 Mar 2024 10:16:08 +0800 Subject: [PATCH] add more test --- pkg/fs/fs.go | 19 + sdk/java/libjfs/main.go | 8 +- sdk/java/pom.xml | 6 + .../java/io/juicefs/JuiceFileSystemImpl.java | 29 +- .../juicefs/utils/FsPermissionExtension.java | 63 + .../java/io/juicefs/utils/ReflectionUtil.java | 53 + .../java/io/juicefs/JuiceFileSystemTest.java | 20 + .../test/java/io/juicefs/acl/TestAclCLI.java | 79 ++ sdk/java/src/test/resources/testAclCLI.xml | 1075 +++++++++++++++++ 9 files changed, 1347 insertions(+), 5 deletions(-) create mode 100644 sdk/java/src/main/java/io/juicefs/utils/FsPermissionExtension.java create mode 100644 sdk/java/src/main/java/io/juicefs/utils/ReflectionUtil.java create mode 100644 sdk/java/src/test/java/io/juicefs/acl/TestAclCLI.java create mode 100644 sdk/java/src/test/resources/testAclCLI.xml diff --git a/pkg/fs/fs.go b/pkg/fs/fs.go index a9ef77099bfa..95ae19c08849 100644 --- a/pkg/fs/fs.go +++ b/pkg/fs/fs.go @@ -87,6 +87,9 @@ func (fs *FileStat) Mode() os.FileMode { if attr.Mode&01000 != 0 { mode |= os.ModeSticky } + if attr.AccessACL+attr.DefaultACL > 0 { + mode |= 1 << 18 + } switch attr.Typ { case meta.TypeDirectory: mode |= os.ModeDir @@ -650,6 +653,22 @@ func (fs *FileSystem) SetFacl(ctx meta.Context, p string, acltype uint8, rule *a if err != 0 { return } + if acltype == acl.TypeDefault && fi.Mode().IsRegular() { + if rule.IsEmpty() { + return + } else { + return syscall.ENOTSUP + } + } + if rule.IsEmpty() { + oldRule := acl.EmptyRule() + if err = fs.m.GetFacl(ctx, fi.inode, acltype, oldRule); err != 0 { + return err + } + rule.Owner = oldRule.Owner + rule.Other = oldRule.Other + rule.Group = oldRule.Group & oldRule.Mask + } err = fs.m.SetFacl(ctx, fi.inode, acltype, rule) return } diff --git a/sdk/java/libjfs/main.go b/sdk/java/libjfs/main.go index feb2400ad47c..cdd045d6b845 100644 --- a/sdk/java/libjfs/main.go +++ b/sdk/java/libjfs/main.go @@ -889,8 +889,8 @@ func jfs_getfacl(pid int, h int64, path *C.char, acltype int, buf uintptr, blen if w == nil { return EINVAL } - var rule acl.Rule - err := w.GetFacl(w.withPid(pid), C.GoString(path), uint8(acltype), &rule) + rule := acl.EmptyRule() + err := w.GetFacl(w.withPid(pid), C.GoString(path), uint8(acltype), rule) if err != 0 { return errno(err) } @@ -925,7 +925,7 @@ func jfs_setfacl(pid int, h int64, path *C.char, acltype int, buf uintptr, alen if w == nil { return EINVAL } - var rule acl.Rule + rule := acl.EmptyRule() r := utils.NewNativeBuffer(toBuf(buf, alen)) rule.Owner = r.Get16() rule.Group = r.Get16() @@ -945,7 +945,7 @@ func jfs_setfacl(pid int, h int64, path *C.char, acltype int, buf uintptr, alen rule.NamedGroups = append(rule.NamedGroups, entry) } } - return errno(w.SetFacl(w.withPid(pid), C.GoString(path), uint8(acltype), &rule)) + return errno(w.SetFacl(w.withPid(pid), C.GoString(path), uint8(acltype), rule)) } //export jfs_readlink diff --git a/sdk/java/pom.xml b/sdk/java/pom.xml index 8359c228904a..31340d73c79a 100644 --- a/sdk/java/pom.xml +++ b/sdk/java/pom.xml @@ -42,6 +42,9 @@ ${argLine} false + + ${project.build.directory}/test-classes + @@ -217,6 +220,9 @@ conf + + src/test/resources + diff --git a/sdk/java/src/main/java/io/juicefs/JuiceFileSystemImpl.java b/sdk/java/src/main/java/io/juicefs/JuiceFileSystemImpl.java index cb39171c1472..374cb8f79ae7 100644 --- a/sdk/java/src/main/java/io/juicefs/JuiceFileSystemImpl.java +++ b/sdk/java/src/main/java/io/juicefs/JuiceFileSystemImpl.java @@ -99,6 +99,8 @@ public class JuiceFileSystemImpl extends FileSystem { * hadoop compatibility */ private boolean withStreamCapability; + private Constructor fileStatusConstructor; + // constructor for BufferedFSOutputStreamWithStreamCapabilities private Constructor constructor; private Method setStorageIds; @@ -432,6 +434,17 @@ public void initialize(URI uri, Configuration conf) throws IOException { throw new RuntimeException(e); } } + // for hadoop compatibility + boolean hasAclMtd = ReflectionUtil.hasMethod(FileStatus.class.getName(), "hasAcl", (String[]) null); + if (hasAclMtd) { + fileStatusConstructor = ReflectionUtil.getConstructor(FileStatus.class, + long.class, boolean.class, int.class, long.class, long.class, + long.class, FsPermission.class, String.class, String.class, Path.class, + Path.class, boolean.class, boolean.class, boolean.class); + if (fileStatusConstructor == null) { + throw new IOException("incompatible hadoop version"); + } + } uMask = FsPermission.getUMask(conf); String umaskStr = getConf(conf, "umask", null); @@ -1433,14 +1446,25 @@ private FileStatus newFileStatus(Path p, Pointer buf, int size, boolean readlink int mode = buf.getInt(0); boolean isdir = ((mode >>> 31) & 1) == 1; // Go int stickybit = (mode >>> 20) & 1; + boolean hasAcl = (mode >> 18 & 1) == 1; FsPermission perm = new FsPermission((short) ((mode & 0777) | (stickybit << 9))); + perm = new FsPermissionExtension(perm, hasAcl, false); long length = buf.getLongLong(4); long mtime = buf.getLongLong(12); long atime = buf.getLongLong(20); String user = buf.getString(28); String group = buf.getString(28 + user.length() + 1); assert (30 + user.length() + group.length() == size); - return new FileStatus(length, isdir, 1, blocksize, mtime, atime, perm, user, group, p); + + if (fileStatusConstructor == null) { + return new FileStatus(length, isdir, 1, blocksize, mtime, atime, perm, user, group, p); + } else { + try { + return fileStatusConstructor.newInstance(length, isdir, 1, blocksize, mtime, atime, perm, user, group, null, p, hasAcl, false, false); + } catch (Exception e) { + throw new IOException("construct fileStatus failed", e); + } + } } @Override @@ -1821,6 +1845,9 @@ private void setAclInternal(Path path, AclEntryScope scope, List aclSp } int r = lib.jfs_setfacl(Thread.currentThread().getId(), handle, normalizePath(path), scope.ordinal() + 1, buf, 12 + namedaclsize); + if (r == ENOTSUP) { + throw new IOException("Invalid ACL: only directories may have a default ACL"); + } if (r < 0) throw error(r, path); } diff --git a/sdk/java/src/main/java/io/juicefs/utils/FsPermissionExtension.java b/sdk/java/src/main/java/io/juicefs/utils/FsPermissionExtension.java new file mode 100644 index 000000000000..c0dee7e0f0df --- /dev/null +++ b/sdk/java/src/main/java/io/juicefs/utils/FsPermissionExtension.java @@ -0,0 +1,63 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.juicefs.utils; + +import org.apache.hadoop.classification.InterfaceAudience; +import org.apache.hadoop.fs.permission.FsPermission; + +/** + * HDFS permission subclass used to indicate an ACL is present and/or that the + * underlying file/dir is encrypted. The ACL/encrypted bits are not visible + * directly to users of {@link FsPermission} serialization. This is + * done for backwards compatibility in case any existing clients assume the + * value of FsPermission is in a particular range. + */ +@InterfaceAudience.Private +public class FsPermissionExtension extends FsPermission { + private final static short ACL_BIT = 1 << 12; + private final static short ENCRYPTED_BIT = 1 << 13; + private final boolean aclBit; + private final boolean encryptedBit; + + /** + * Constructs a new FsPermissionExtension based on the given FsPermission. + * + * @param perm FsPermission containing permission bits + */ + public FsPermissionExtension(FsPermission perm, boolean hasAcl, + boolean isEncrypted) { + super(perm.toShort()); + aclBit = hasAcl; + encryptedBit = isEncrypted; + } + + @Override + public short toExtendedShort() { + return (short) (toShort() | + (aclBit ? ACL_BIT : 0) | (encryptedBit ? ENCRYPTED_BIT : 0)); + } + + public boolean getAclBit() { + return aclBit; + } + + @Override + public boolean getEncryptedBit() { + return encryptedBit; + } +} \ No newline at end of file diff --git a/sdk/java/src/main/java/io/juicefs/utils/ReflectionUtil.java b/sdk/java/src/main/java/io/juicefs/utils/ReflectionUtil.java new file mode 100644 index 000000000000..418be1736022 --- /dev/null +++ b/sdk/java/src/main/java/io/juicefs/utils/ReflectionUtil.java @@ -0,0 +1,53 @@ +/* + * JuiceFS, Copyright 2024 Juicedata, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.juicefs.utils; + +import java.lang.reflect.Constructor; + +public class ReflectionUtil { + public static boolean hasMethod(String className, String method, String[] params) { + try { + Class[] classes = null; + if (params != null) { + classes = new Class[params.length]; + for (int i = 0; i < params.length; i++) { + classes[i] = Class.forName(params[i], false, Thread.currentThread().getContextClassLoader()); + } + } + return hasMethod(className, method, classes); + } catch (ClassNotFoundException e) { + return false; + } + } + + public static boolean hasMethod(String className, String method, Class[] params) { + try { + Class clazz = Class.forName(className, false, Thread.currentThread().getContextClassLoader()); + clazz.getDeclaredMethod(method, params); + } catch (ClassNotFoundException | NoSuchMethodException e) { + return false; + } + return true; + } + + public static Constructor getConstructor(Class clazz, Class... params) { + try { + return clazz.getConstructor(params); + } catch (NoSuchMethodException e) { + return null; + } + } +} diff --git a/sdk/java/src/test/java/io/juicefs/JuiceFileSystemTest.java b/sdk/java/src/test/java/io/juicefs/JuiceFileSystemTest.java index eb5cde7f15d1..c9ad0891f9b3 100644 --- a/sdk/java/src/test/java/io/juicefs/JuiceFileSystemTest.java +++ b/sdk/java/src/test/java/io/juicefs/JuiceFileSystemTest.java @@ -1100,4 +1100,24 @@ public void testAccessAclNotInherited() throws IOException { fs.delete(parent, true); } + public void testFileStatusWithAcl() throws Exception { + List acls = Lists.newArrayList( + aclEntry(ACCESS, USER, ALL), + aclEntry(ACCESS, USER, "foo", ALL), + aclEntry(ACCESS, OTHER, ALL), + aclEntry(ACCESS, GROUP, ALL) + ); + Path p = new Path("/test_acl_status"); + fs.delete(p, true); + fs.mkdirs(p); + FileStatus pStatus = fs.getFileStatus(p); + assertFalse(pStatus.hasAcl()); + + Path f = new Path(p, "f"); + fs.create(f).close(); + fs.setAcl(f, acls); + FileStatus[] fileStatuses = fs.listStatus(p); + assertTrue(fileStatuses[0].getPermission().getAclBit()); + assertTrue(fileStatuses[0].hasAcl()); + } } diff --git a/sdk/java/src/test/java/io/juicefs/acl/TestAclCLI.java b/sdk/java/src/test/java/io/juicefs/acl/TestAclCLI.java new file mode 100644 index 000000000000..e03999d5efff --- /dev/null +++ b/sdk/java/src/test/java/io/juicefs/acl/TestAclCLI.java @@ -0,0 +1,79 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.juicefs.acl; + +import org.apache.hadoop.cli.CLITestHelperDFS; +import org.apache.hadoop.cli.util.CLICommand; +import org.apache.hadoop.cli.util.CommandExecutor.Result; +import org.apache.hadoop.hdfs.DFSConfigKeys; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +public class TestAclCLI extends CLITestHelperDFS { + private String vol = null; + private String username = null; + + protected void initConf() { + conf.setBoolean(DFSConfigKeys.DFS_NAMENODE_ACLS_ENABLED_KEY, true); + conf.setBoolean( + DFSConfigKeys.DFS_NAMENODE_POSIX_ACL_INHERITANCE_ENABLED_KEY, false); + } + + @Before + @Override + public void setUp() throws Exception { + super.setUp(); + initConf(); + vol = "jfs://dev/"; + username = System.getProperty("user.name"); + } + + @After + @Override + public void tearDown() throws Exception { + super.tearDown(); + } + + @Override + protected String getTestFile() { + return "testAclCLI.xml"; + } + + @Override + protected String expandCommand(final String cmd) { + String expCmd = cmd; + expCmd = expCmd.replaceAll("NAMENODE", vol); + expCmd = expCmd.replaceAll("USERNAME", username); + expCmd = expCmd.replaceAll("#LF#", + System.getProperty("line.separator")); + expCmd = super.expandCommand(expCmd); + return expCmd; + } + + @Override + protected Result execute(CLICommand cmd) throws Exception { + return cmd.getExecutor(vol, conf).executeCommand(cmd.getCmd()); + } + + @Test + @Override + public void testAll() { + super.testAll(); + } +} diff --git a/sdk/java/src/test/resources/testAclCLI.xml b/sdk/java/src/test/resources/testAclCLI.xml new file mode 100644 index 000000000000..120da68e4f69 --- /dev/null +++ b/sdk/java/src/test/resources/testAclCLI.xml @@ -0,0 +1,1075 @@ + + + + + + + + test + + + + + + getfacl: basic permissions + + -fs NAMENODE -touchz /file1 + -fs NAMENODE -getfacl /file1 + + + -fs NAMENODE -rm /file1 + + + + SubstringComparator + # file: /file1 + + + SubstringComparator + # owner: USERNAME + + + SubstringComparator + # group: supergroup + + + SubstringComparator + user::rw- + + + SubstringComparator + group::r-- + + + SubstringComparator + other::r-- + + + + + getfacl: basic permissions for directory + + -fs NAMENODE -mkdir /dir1 + -fs NAMENODE -getfacl /dir1 + + + -fs NAMENODE -rm /dir1 + + + + SubstringComparator + # file: /dir1 + + + SubstringComparator + # owner: USERNAME + + + SubstringComparator + # group: supergroup + + + SubstringComparator + user::rwx + + + SubstringComparator + group::r-x + + + SubstringComparator + other::r-x + + + + + setfacl : Add an ACL + + -fs NAMENODE -touchz /file1 + -fs NAMENODE -setfacl -m user:bob:r-- /file1 + -fs NAMENODE -getfacl /file1 + + + -fs NAMENODE -rm /file1 + + + + SubstringComparator + # file: /file1 + + + SubstringComparator + # owner: USERNAME + + + SubstringComparator + # group: supergroup + + + SubstringComparator + user::rw- + + + SubstringComparator + user:bob:r-- + + + SubstringComparator + group::r-- + + + SubstringComparator + mask::r-- + + + SubstringComparator + other::r-- + + + + + setfacl : Add multiple ACLs at once + + -fs NAMENODE -touchz /file1 + -fs NAMENODE -setfacl -m user:bob:r--,group:users:r-x /file1 + -fs NAMENODE -getfacl /file1 + + + -fs NAMENODE -rm /file1 + + + + SubstringComparator + # file: /file1 + + + SubstringComparator + # owner: USERNAME + + + SubstringComparator + # group: supergroup + + + SubstringComparator + user::rw- + + + SubstringComparator + user:bob:r-- + + + SubstringComparator + group::r-- + + + SubstringComparator + group:users:r-x + + + SubstringComparator + mask::r-x + + + SubstringComparator + other::r-- + + + + + setfacl : Remove an ACL + + -fs NAMENODE -touchz /file1 + -fs NAMENODE -setfacl -m user:bob:r--,user:charlie:r-x /file1 + -fs NAMENODE -setfacl -x user:bob /file1 + -fs NAMENODE -getfacl /file1 + + + -fs NAMENODE -rm /file1 + + + + SubstringComparator + # file: /file1 + + + SubstringComparator + # owner: USERNAME + + + SubstringComparator + # group: supergroup + + + SubstringComparator + user::rw- + + + SubstringComparator + user:charlie:r-x + + + SubstringComparator + group::r-- + + + SubstringComparator + other::r-- + + + RegexpAcrossOutputComparator + .*(?!bob)* + + + + + setfacl : Add default ACL + + -fs NAMENODE -mkdir /dir1 + -fs NAMENODE -setfacl -m user:bob:r--,group:users:r-x /dir1 + -fs NAMENODE -setfacl -m default:user:charlie:r-x,default:group:admin:rwx /dir1 + -fs NAMENODE -getfacl /dir1 + + + -fs NAMENODE -rm -R /dir1 + + + + SubstringComparator + # file: /dir1 + + + SubstringComparator + # owner: USERNAME + + + SubstringComparator + # group: supergroup + + + SubstringComparator + user::rwx + + + SubstringComparator + user:bob:r-- + + + SubstringComparator + group::r-x + + + SubstringComparator + group:users:r-x + + + SubstringComparator + mask::r-x + + + SubstringComparator + other::r-x + + + SubstringComparator + default:user::rwx + + + SubstringComparator + default:user:charlie:r-x + + + SubstringComparator + default:group::r-x + + + SubstringComparator + default:group:admin:rwx + + + SubstringComparator + default:mask::rwx + + + SubstringComparator + default:other::r-x + + + + + setfacl : Add minimal default ACL + + -fs NAMENODE -mkdir /dir1 + -fs NAMENODE -setfacl -m default:user::rwx /dir1 + -fs NAMENODE -getfacl /dir1 + + + -fs NAMENODE -rm -R /dir1 + + + + SubstringComparator + # file: /dir1 + + + SubstringComparator + # owner: USERNAME + + + SubstringComparator + # group: supergroup + + + SubstringComparator + user::rwx + + + SubstringComparator + group::r-x + + + SubstringComparator + other::r-x + + + SubstringComparator + default:user::rwx + + + SubstringComparator + default:group::r-x + + + SubstringComparator + default:other::r-x + + + RegexpAcrossOutputComparator + .*(?!default\:mask)* + + + + + setfacl : try adding default ACL to file + + -fs NAMENODE -touchz /file1 + -fs NAMENODE -setfacl -m default:user:charlie:r-x /file1 + + + -fs NAMENODE -rm /file1 + + + + SubstringComparator + setfacl: Invalid ACL: only directories may have a default ACL + + + + + setfacl : Remove one default ACL + + -fs NAMENODE -mkdir /dir1 + -fs NAMENODE -setfacl -m user:bob:r--,group:users:r-x /dir1 + -fs NAMENODE -setfacl -m default:user:charlie:r-x,default:group:admin:rwx /dir1 + -fs NAMENODE -setfacl -x default:user:charlie /dir1 + -fs NAMENODE -getfacl /dir1 + + + -fs NAMENODE -rm -R /dir1 + + + + SubstringComparator + # file: /dir1 + + + SubstringComparator + # owner: USERNAME + + + SubstringComparator + # group: supergroup + + + SubstringComparator + user::rwx + + + SubstringComparator + user:bob:r-- + + + SubstringComparator + group::r-x + + + SubstringComparator + group:users:r-x + + + SubstringComparator + mask::r-x + + + SubstringComparator + other::r-x + + + SubstringComparator + default:user::rwx + + + SubstringComparator + default:group::r-x + + + SubstringComparator + default:group:admin:rwx + + + SubstringComparator + default:mask::rwx + + + SubstringComparator + default:other::r-x + + + RegexpAcrossOutputComparator + .*(?!default:user:charlie).* + + + + + setfacl : Remove all default ACL + + -fs NAMENODE -mkdir /dir1 + -fs NAMENODE -setfacl -m user:bob:r--,group:users:r-x /dir1 + -fs NAMENODE -setfacl -m default:user:charlie:r-x,default:group:admin:rwx /dir1 + -fs NAMENODE -setfacl -k /dir1 + -fs NAMENODE -getfacl /dir1 + + + -fs NAMENODE -rm -R /dir1 + + + + SubstringComparator + # file: /dir1 + + + SubstringComparator + # owner: USERNAME + + + SubstringComparator + # group: supergroup + + + SubstringComparator + user::rwx + + + SubstringComparator + user:bob:r-- + + + SubstringComparator + group::r-x + + + SubstringComparator + group:users:r-x + + + SubstringComparator + mask::r-x + + + SubstringComparator + other::r-x + + + RegexpAcrossOutputComparator + .*(?!default).* + + + + + setfacl : Remove all but base ACLs for a directory + + -fs NAMENODE -mkdir /dir1 + -fs NAMENODE -setfacl -m user:charlie:r-x,default:group:admin:rwx /dir1 + -fs NAMENODE -setfacl -b /dir1 + -fs NAMENODE -getfacl /dir1 + + + -fs NAMENODE -rm -R /dir1 + + + + SubstringComparator + # file: /dir1 + + + SubstringComparator + # owner: USERNAME + + + SubstringComparator + # group: supergroup + + + SubstringComparator + user::rwx + + + SubstringComparator + group::r-x + + + SubstringComparator + other::r-x + + + RegexpAcrossOutputComparator + .*(?!charlie).* + + + RegexpAcrossOutputComparator + .*(?!default).* + + + RegexpAcrossOutputComparator + .*(?!admin).* + + + + + setfacl : Remove all but base ACLs for a file + + -fs NAMENODE -touchz /file1 + -fs NAMENODE -setfacl -m user:charlie:r-x,group:admin:rwx /file1 + -fs NAMENODE -setfacl -b /file1 + -fs NAMENODE -getfacl /file1 + + + -fs NAMENODE -rm /file1 + + + + SubstringComparator + # file: /file1 + + + SubstringComparator + # owner: USERNAME + + + SubstringComparator + # group: supergroup + + + SubstringComparator + user::rw- + + + SubstringComparator + group::r-- + + + SubstringComparator + other::r-- + + + RegexpAcrossOutputComparator + .*(?!charlie).* + + + RegexpAcrossOutputComparator + .*(?!admin).* + + + + + setfacl : check inherit default ACL to file + + -fs NAMENODE -mkdir /dir1 + -fs NAMENODE -setfacl -m default:user:charlie:r-x,default:group:admin:rwx /dir1 + -fs NAMENODE -touchz /dir1/file + -fs NAMENODE -getfacl /dir1/file + + + -fs NAMENODE -rm -R /dir1 + + + + SubstringComparator + # file: /dir1/file + + + SubstringComparator + # owner: USERNAME + + + SubstringComparator + # group: supergroup + + + SubstringComparator + user::rw- + + + SubstringComparator + user:charlie:r-x + + + SubstringComparator + group::r-x + + + SubstringComparator + group:admin:rwx + + + SubstringComparator + mask::rw- + + + SubstringComparator + other::r-- + + + RegexpAcrossOutputComparator + .*(?!default).* + + + + + setfacl : check inherit default ACL to dir + + -fs NAMENODE -mkdir /dir1 + -fs NAMENODE -setfacl -m default:user:charlie:r-x,default:group:admin:rwx /dir1 + -fs NAMENODE -mkdir /dir1/dir2 + -fs NAMENODE -getfacl /dir1/dir2 + + + -fs NAMENODE -rm -R /dir1 + + + + ExactLineComparator + # file: /dir1/dir2 + + + ExactLineComparator + # owner: USERNAME + + + ExactLineComparator + # group: supergroup + + + ExactLineComparator + user::rwx + + + ExactLineComparator + user:charlie:r-x + + + ExactLineComparator + group::r-x + + + RegexpComparator + ^group:admin:rwx\b.* + + + ExactLineComparator + mask::rwx + + + ExactLineComparator + default:user::rwx + + + ExactLineComparator + default:user:charlie:r-x + + + ExactLineComparator + default:group::r-x + + + ExactLineComparator + default:group:admin:rwx + + + ExactLineComparator + default:mask::rwx + + + ExactLineComparator + default:other::r-x + + + ExactLineComparator + other::r-x + + + + + getfacl -R : recursive + + -fs NAMENODE -mkdir /dir1 + -fs NAMENODE -setfacl -m user:charlie:r-x,group:admin:rwx /dir1 + -fs NAMENODE -mkdir /dir1/dir2 + -fs NAMENODE -setfacl -m user:user1:r-x,group:users:rwx /dir1/dir2 + -fs NAMENODE -getfacl -R /dir1 + + + -fs NAMENODE -rm -R /dir1 + + + + ExactComparator + # file: /dir1#LF## owner: USERNAME#LF## group: supergroup#LF#user::rwx#LF#user:charlie:r-x#LF#group::r-x#LF#group:admin:rwx#LF#mask::rwx#LF#other::r-x#LF##LF## file: /dir1/dir2#LF## owner: USERNAME#LF## group: supergroup#LF#user::rwx#LF#user:user1:r-x#LF#group::r-x#LF#group:users:rwx#LF#mask::rwx#LF#other::r-x#LF##LF# + + + + + setfacl -R : recursive + + -fs NAMENODE -mkdir /dir1 + -fs NAMENODE -mkdir /dir1/dir2 + -fs NAMENODE -setfacl -R -m user:charlie:r-x,group:admin:rwx /dir1 + -fs NAMENODE -getfacl -R /dir1 + + + -fs NAMENODE -rm -R /dir1 + + + + ExactComparator + # file: /dir1#LF## owner: USERNAME#LF## group: supergroup#LF#user::rwx#LF#user:charlie:r-x#LF#group::r-x#LF#group:admin:rwx#LF#mask::rwx#LF#other::r-x#LF##LF## file: /dir1/dir2#LF## owner: USERNAME#LF## group: supergroup#LF#user::rwx#LF#user:charlie:r-x#LF#group::r-x#LF#group:admin:rwx#LF#mask::rwx#LF#other::r-x#LF##LF# + + + + + setfacl --set : Set full set of ACLs + + -fs NAMENODE -mkdir /dir1 + -fs NAMENODE -setfacl -m user:charlie:r-x,group:admin:rwx /dir1 + -fs NAMENODE -setfacl --set user::rw-,group::r--,other::r--,user:user1:r-x,group:users:rw- /dir1 + -fs NAMENODE -getfacl /dir1 + + + -fs NAMENODE -rm -R /dir1 + + + + ExactComparator + # file: /dir1#LF## owner: USERNAME#LF## group: supergroup#LF#user::rw-#LF#user:user1:r-x#LF#group::r--#LF#group:users:rw-#LF#mask::rwx#LF#other::r--#LF##LF# + + + + + setfacl -x mask : remove mask entry along with other ACL entries + + -fs NAMENODE -mkdir /dir1 + -fs NAMENODE -setfacl -m user:charlie:r-x,group:admin:rwx /dir1 + -fs NAMENODE -setfacl -x mask::,user:charlie,group:admin /dir1 + -fs NAMENODE -getfacl /dir1 + + + -fs NAMENODE -rm -R /dir1 + + + + ExactComparator + # file: /dir1#LF## owner: USERNAME#LF## group: supergroup#LF#user::rwx#LF#group::r-x#LF#other::r-x#LF##LF# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +