You are viewing a plain text version of this content. The canonical link for it is here.
Posted to common-commits@hadoop.apache.org by cn...@apache.org on 2014/02/27 00:02:01 UTC
svn commit: r1572325 - in
/hadoop/common/branches/branch-2.4/hadoop-common-project/hadoop-common: ./
src/main/docs/ src/main/java/ src/main/java/org/apache/hadoop/fs/
src/main/java/org/apache/hadoop/fs/permission/
src/main/java/org/apache/hadoop/fs/she...
Author: cnauroth
Date: Wed Feb 26 23:01:58 2014
New Revision: 1572325
URL: http://svn.apache.org/r1572325
Log:
HDFS-4685. Merging change r1572308 and r1572315 from branch-2 to branch-2.4
Added:
hadoop/common/branches/branch-2.4/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/permission/AclEntry.java
- copied unchanged from r1572308, hadoop/common/branches/branch-2/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/permission/AclEntry.java
hadoop/common/branches/branch-2.4/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/permission/AclEntryScope.java
- copied unchanged from r1572308, hadoop/common/branches/branch-2/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/permission/AclEntryScope.java
hadoop/common/branches/branch-2.4/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/permission/AclEntryType.java
- copied unchanged from r1572308, hadoop/common/branches/branch-2/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/permission/AclEntryType.java
hadoop/common/branches/branch-2.4/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/permission/AclStatus.java
- copied unchanged from r1572308, hadoop/common/branches/branch-2/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/permission/AclStatus.java
hadoop/common/branches/branch-2.4/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/shell/AclCommands.java
- copied unchanged from r1572308, hadoop/common/branches/branch-2/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/shell/AclCommands.java
hadoop/common/branches/branch-2.4/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/permission/TestAcl.java
- copied unchanged from r1572308, hadoop/common/branches/branch-2/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/permission/TestAcl.java
hadoop/common/branches/branch-2.4/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/shell/TestAclCommands.java
- copied unchanged from r1572308, hadoop/common/branches/branch-2/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/shell/TestAclCommands.java
Modified:
hadoop/common/branches/branch-2.4/hadoop-common-project/hadoop-common/CHANGES.txt
hadoop/common/branches/branch-2.4/hadoop-common-project/hadoop-common/src/main/docs/ (props changed)
hadoop/common/branches/branch-2.4/hadoop-common-project/hadoop-common/src/main/java/ (props changed)
hadoop/common/branches/branch-2.4/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/FileSystem.java
hadoop/common/branches/branch-2.4/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/FilterFileSystem.java
hadoop/common/branches/branch-2.4/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/RawLocalFileSystem.java
hadoop/common/branches/branch-2.4/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/permission/FsAction.java
hadoop/common/branches/branch-2.4/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/permission/FsPermission.java
hadoop/common/branches/branch-2.4/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/shell/FsCommand.java
hadoop/common/branches/branch-2.4/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/shell/Ls.java
hadoop/common/branches/branch-2.4/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/viewfs/ChRootedFileSystem.java
hadoop/common/branches/branch-2.4/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/viewfs/ViewFileSystem.java
hadoop/common/branches/branch-2.4/hadoop-common-project/hadoop-common/src/site/apt/FileSystemShell.apt.vm
hadoop/common/branches/branch-2.4/hadoop-common-project/hadoop-common/src/test/core/ (props changed)
hadoop/common/branches/branch-2.4/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/TestHarFileSystem.java
hadoop/common/branches/branch-2.4/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/permission/TestFsPermission.java
hadoop/common/branches/branch-2.4/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/viewfs/TestChRootedFileSystem.java
hadoop/common/branches/branch-2.4/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/viewfs/TestViewFileSystemDelegation.java
Modified: hadoop/common/branches/branch-2.4/hadoop-common-project/hadoop-common/CHANGES.txt
URL: http://svn.apache.org/viewvc/hadoop/common/branches/branch-2.4/hadoop-common-project/hadoop-common/CHANGES.txt?rev=1572325&r1=1572324&r2=1572325&view=diff
==============================================================================
--- hadoop/common/branches/branch-2.4/hadoop-common-project/hadoop-common/CHANGES.txt (original)
+++ hadoop/common/branches/branch-2.4/hadoop-common-project/hadoop-common/CHANGES.txt Wed Feb 26 23:01:58 2014
@@ -6,6 +6,9 @@ Release 2.4.0 - UNRELEASED
NEW FEATURES
+ HADOOP-10184. Hadoop Common changes required to support HDFS ACLs. (See
+ breakdown of tasks below for features and contributors)
+
IMPROVEMENTS
HADOOP-10139. Update and improve the Single Cluster Setup document.
@@ -60,6 +63,41 @@ Release 2.4.0 - UNRELEASED
HADOOP-10368. InputStream is not closed in VersionInfo ctor.
(Tsuyoshi OZAWA via szetszwo)
+ BREAKDOWN OF HADOOP-10184 SUBTASKS AND RELATED JIRAS
+
+ HADOOP-10185. FileSystem API for ACLs. (cnauroth)
+
+ HADOOP-10186. Remove AclReadFlag and AclWriteFlag in FileSystem API.
+ (Haohui Mai via cnauroth)
+
+ HADOOP-10187. FsShell CLI: add getfacl and setfacl with minimal support for
+ getting and setting ACLs. (Vinay via cnauroth)
+
+ HADOOP-10192. FileSystem#getAclStatus has incorrect JavaDocs. (cnauroth)
+
+ HADOOP-10220. Add ACL indicator bit to FsPermission. (cnauroth)
+
+ HADOOP-10241. Clean up output of FsShell getfacl. (Chris Nauroth via wheat9)
+
+ HADOOP-10213. Fix bugs parsing ACL spec in FsShell setfacl.
+ (Vinay via cnauroth)
+
+ HADOOP-10277. setfacl -x fails to parse ACL spec if trying to remove the
+ mask entry. (Vinay via cnauroth)
+
+ HADOOP-10270. getfacl does not display effective permissions of masked
+ entries. (cnauroth)
+
+ HADOOP-10344. Fix TestAclCommands after merging HADOOP-10338 patch.
+ (cnauroth)
+
+ HADOOP-10352. Recursive setfacl erroneously attempts to apply default ACL to
+ files. (cnauroth)
+
+ HADOOP-10354. TestWebHDFS fails after merge of HDFS-4685 to trunk. (cnauroth)
+
+ HADOOP-10361. Correct alignment in CLI output for ACLs. (cnauroth)
+
Release 2.3.1 - UNRELEASED
INCOMPATIBLE CHANGES
Propchange: hadoop/common/branches/branch-2.4/hadoop-common-project/hadoop-common/src/main/docs/
------------------------------------------------------------------------------
Merged /hadoop/common/branches/HDFS-4685/hadoop-common-project/hadoop-common/src/main/docs:r1547224-1569863
Propchange: hadoop/common/branches/branch-2.4/hadoop-common-project/hadoop-common/src/main/java/
------------------------------------------------------------------------------
Merged /hadoop/common/branches/HDFS-4685/hadoop-common-project/hadoop-common/src/main/java:r1547224-1569863
Modified: hadoop/common/branches/branch-2.4/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/FileSystem.java
URL: http://svn.apache.org/viewvc/hadoop/common/branches/branch-2.4/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/FileSystem.java?rev=1572325&r1=1572324&r2=1572325&view=diff
==============================================================================
--- hadoop/common/branches/branch-2.4/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/FileSystem.java (original)
+++ hadoop/common/branches/branch-2.4/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/FileSystem.java Wed Feb 26 23:01:58 2014
@@ -25,8 +25,6 @@ import java.net.URI;
import java.net.URISyntaxException;
import java.security.PrivilegedExceptionAction;
import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.HashSet;
@@ -40,7 +38,6 @@ import java.util.ServiceLoader;
import java.util.Set;
import java.util.Stack;
import java.util.TreeSet;
-import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import org.apache.commons.logging.Log;
@@ -51,6 +48,8 @@ import org.apache.hadoop.conf.Configurat
import org.apache.hadoop.conf.Configured;
import org.apache.hadoop.fs.Options.ChecksumOpt;
import org.apache.hadoop.fs.Options.Rename;
+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.io.MultipleIOException;
import org.apache.hadoop.io.Text;
@@ -2270,6 +2269,88 @@ public abstract class FileSystem extends
+ " doesn't support deleteSnapshot");
}
+ /**
+ * Modifies ACL entries of files and directories. This method can add new ACL
+ * entries or modify the permissions on existing ACL entries. All existing
+ * ACL entries that are not specified in this call are retained without
+ * changes. (Modifications are merged into the current ACL.)
+ *
+ * @param path Path to modify
+ * @param aclSpec List<AclEntry> describing modifications
+ * @throws IOException if an ACL could not be modified
+ */
+ public void modifyAclEntries(Path path, List<AclEntry> aclSpec)
+ throws IOException {
+ throw new UnsupportedOperationException(getClass().getSimpleName()
+ + " doesn't support modifyAclEntries");
+ }
+
+ /**
+ * Removes ACL entries from files and directories. Other ACL entries are
+ * retained.
+ *
+ * @param path Path to modify
+ * @param aclSpec List<AclEntry> describing entries to remove
+ * @throws IOException if an ACL could not be modified
+ */
+ public void removeAclEntries(Path path, List<AclEntry> aclSpec)
+ throws IOException {
+ throw new UnsupportedOperationException(getClass().getSimpleName()
+ + " doesn't support removeAclEntries");
+ }
+
+ /**
+ * Removes all default ACL entries from files and directories.
+ *
+ * @param path Path to modify
+ * @throws IOException if an ACL could not be modified
+ */
+ public void removeDefaultAcl(Path path)
+ throws IOException {
+ throw new UnsupportedOperationException(getClass().getSimpleName()
+ + " doesn't support removeDefaultAcl");
+ }
+
+ /**
+ * Removes all but the base ACL entries of files and directories. The entries
+ * for user, group, and others are retained for compatibility with permission
+ * bits.
+ *
+ * @param path Path to modify
+ * @throws IOException if an ACL could not be removed
+ */
+ public void removeAcl(Path path)
+ throws IOException {
+ throw new UnsupportedOperationException(getClass().getSimpleName()
+ + " doesn't support removeAcl");
+ }
+
+ /**
+ * Fully replaces ACL of files and directories, discarding all existing
+ * entries.
+ *
+ * @param path Path to modify
+ * @param aclSpec List<AclEntry> describing modifications, must include entries
+ * for user, group, and others for compatibility with permission bits.
+ * @throws IOException if an ACL could not be modified
+ */
+ public void setAcl(Path path, List<AclEntry> aclSpec) throws IOException {
+ throw new UnsupportedOperationException(getClass().getSimpleName()
+ + " doesn't support setAcl");
+ }
+
+ /**
+ * Gets the ACL of a file or directory.
+ *
+ * @param path Path to get
+ * @return AclStatus describing the ACL of the file or directory
+ * @throws IOException if an ACL could not be read
+ */
+ public AclStatus getAclStatus(Path path) throws IOException {
+ throw new UnsupportedOperationException(getClass().getSimpleName()
+ + " doesn't support getAclStatus");
+ }
+
// making it volatile to be able to do a double checked locking
private volatile static boolean FILE_SYSTEMS_LOADED = false;
Modified: hadoop/common/branches/branch-2.4/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/FilterFileSystem.java
URL: http://svn.apache.org/viewvc/hadoop/common/branches/branch-2.4/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/FilterFileSystem.java?rev=1572325&r1=1572324&r2=1572325&view=diff
==============================================================================
--- hadoop/common/branches/branch-2.4/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/FilterFileSystem.java (original)
+++ hadoop/common/branches/branch-2.4/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/FilterFileSystem.java Wed Feb 26 23:01:58 2014
@@ -22,9 +22,13 @@ import java.io.*;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.EnumSet;
+import java.util.List;
+
import org.apache.hadoop.classification.InterfaceAudience;
import org.apache.hadoop.classification.InterfaceStability;
import org.apache.hadoop.conf.Configuration;
+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.fs.ContentSummary;
import org.apache.hadoop.fs.Options.ChecksumOpt;
@@ -507,4 +511,36 @@ public class FilterFileSystem extends Fi
throws IOException {
fs.deleteSnapshot(path, snapshotName);
}
+
+ @Override
+ public void modifyAclEntries(Path path, List<AclEntry> aclSpec)
+ throws IOException {
+ fs.modifyAclEntries(path, aclSpec);
+ }
+
+ @Override
+ public void removeAclEntries(Path path, List<AclEntry> aclSpec)
+ throws IOException {
+ fs.removeAclEntries(path, aclSpec);
+ }
+
+ @Override
+ public void removeDefaultAcl(Path path) throws IOException {
+ fs.removeDefaultAcl(path);
+ }
+
+ @Override
+ public void removeAcl(Path path) throws IOException {
+ fs.removeAcl(path);
+ }
+
+ @Override
+ public void setAcl(Path path, List<AclEntry> aclSpec) throws IOException {
+ fs.setAcl(path, aclSpec);
+ }
+
+ @Override
+ public AclStatus getAclStatus(Path path) throws IOException {
+ return fs.getAclStatus(path);
+ }
}
Modified: hadoop/common/branches/branch-2.4/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/RawLocalFileSystem.java
URL: http://svn.apache.org/viewvc/hadoop/common/branches/branch-2.4/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/RawLocalFileSystem.java?rev=1572325&r1=1572324&r2=1572325&view=diff
==============================================================================
--- hadoop/common/branches/branch-2.4/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/RawLocalFileSystem.java (original)
+++ hadoop/common/branches/branch-2.4/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/RawLocalFileSystem.java Wed Feb 26 23:01:58 2014
@@ -563,8 +563,10 @@ public class RawLocalFileSystem extends
//expected format
//-rw------- 1 username groupname ...
String permission = t.nextToken();
- if (permission.length() > 10) { //files with ACLs might have a '+'
- permission = permission.substring(0, 10);
+ if (permission.length() > FsPermission.MAX_PERMISSION_LENGTH) {
+ //files with ACLs might have a '+'
+ permission = permission.substring(0,
+ FsPermission.MAX_PERMISSION_LENGTH);
}
setPermission(FsPermission.valueOf(permission));
t.nextToken();
Modified: hadoop/common/branches/branch-2.4/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/permission/FsAction.java
URL: http://svn.apache.org/viewvc/hadoop/common/branches/branch-2.4/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/permission/FsAction.java?rev=1572325&r1=1572324&r2=1572325&view=diff
==============================================================================
--- hadoop/common/branches/branch-2.4/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/permission/FsAction.java (original)
+++ hadoop/common/branches/branch-2.4/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/permission/FsAction.java Wed Feb 26 23:01:58 2014
@@ -23,8 +23,8 @@ import org.apache.hadoop.classification.
/**
* File system actions, e.g. read, write, etc.
*/
-@InterfaceAudience.LimitedPrivate({"HDFS"})
-@InterfaceStability.Unstable
+@InterfaceAudience.Public
+@InterfaceStability.Stable
public enum FsAction {
// POSIX style
NONE("---"),
@@ -69,4 +69,21 @@ public enum FsAction {
public FsAction not() {
return vals[7 - ordinal()];
}
+
+ /**
+ * Get the FsAction enum for String representation of permissions
+ *
+ * @param permission
+ * 3-character string representation of permission. ex: rwx
+ * @return Returns FsAction enum if the corresponding FsAction exists for permission.
+ * Otherwise returns null
+ */
+ public static FsAction getFsAction(String permission) {
+ for (FsAction fsAction : vals) {
+ if (fsAction.SYMBOL.equals(permission)) {
+ return fsAction;
+ }
+ }
+ return null;
+ }
}
Modified: hadoop/common/branches/branch-2.4/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/permission/FsPermission.java
URL: http://svn.apache.org/viewvc/hadoop/common/branches/branch-2.4/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/permission/FsPermission.java?rev=1572325&r1=1572324&r2=1572325&view=diff
==============================================================================
--- hadoop/common/branches/branch-2.4/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/permission/FsPermission.java (original)
+++ hadoop/common/branches/branch-2.4/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/permission/FsPermission.java Wed Feb 26 23:01:58 2014
@@ -48,6 +48,9 @@ public class FsPermission implements Wri
WritableFactories.setFactory(ImmutableFsPermission.class, FACTORY);
}
+ /** Maximum acceptable length of a permission string to parse */
+ public static final int MAX_PERMISSION_LENGTH = 10;
+
/** Create an immutable {@link FsPermission} object. */
public static FsPermission createImmutable(short permission) {
return new ImmutableFsPermission(permission);
@@ -319,9 +322,10 @@ public class FsPermission implements Wri
if (unixSymbolicPermission == null) {
return null;
}
- else if (unixSymbolicPermission.length() != 10) {
- throw new IllegalArgumentException("length != 10(unixSymbolicPermission="
- + unixSymbolicPermission + ")");
+ else if (unixSymbolicPermission.length() != MAX_PERMISSION_LENGTH) {
+ throw new IllegalArgumentException(String.format(
+ "length != %d(unixSymbolicPermission=%s)", MAX_PERMISSION_LENGTH,
+ unixSymbolicPermission));
}
int n = 0;
Modified: hadoop/common/branches/branch-2.4/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/shell/FsCommand.java
URL: http://svn.apache.org/viewvc/hadoop/common/branches/branch-2.4/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/shell/FsCommand.java?rev=1572325&r1=1572324&r2=1572325&view=diff
==============================================================================
--- hadoop/common/branches/branch-2.4/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/shell/FsCommand.java (original)
+++ hadoop/common/branches/branch-2.4/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/shell/FsCommand.java Wed Feb 26 23:01:58 2014
@@ -43,6 +43,7 @@ abstract public class FsCommand extends
* @param factory where to register the class
*/
public static void registerCommands(CommandFactory factory) {
+ factory.registerCommands(AclCommands.class);
factory.registerCommands(CopyCommands.class);
factory.registerCommands(Count.class);
factory.registerCommands(Delete.class);
Modified: hadoop/common/branches/branch-2.4/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/shell/Ls.java
URL: http://svn.apache.org/viewvc/hadoop/common/branches/branch-2.4/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/shell/Ls.java?rev=1572325&r1=1572324&r2=1572325&view=diff
==============================================================================
--- hadoop/common/branches/branch-2.4/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/shell/Ls.java (original)
+++ hadoop/common/branches/branch-2.4/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/shell/Ls.java Wed Feb 26 23:01:58 2014
@@ -19,15 +19,22 @@
package org.apache.hadoop.fs.shell;
import java.io.IOException;
+import java.net.URI;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.LinkedList;
+import java.util.Set;
import org.apache.hadoop.util.StringUtils;
import org.apache.hadoop.classification.InterfaceAudience;
import org.apache.hadoop.classification.InterfaceStability;
import org.apache.hadoop.fs.FileStatus;
+import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
+import org.apache.hadoop.ipc.RemoteException;
+import org.apache.hadoop.ipc.RpcNoSuchMethodException;
+
+import com.google.common.collect.Sets;
/**
* Get a listing of all files in that match the file patterns.
@@ -65,6 +72,8 @@ class Ls extends FsCommand {
protected boolean dirRecurse;
protected boolean humanReadable = false;
+ private Set<URI> aclNotSupportedFsSet = Sets.newHashSet();
+
protected String formatSize(long size) {
return humanReadable
? StringUtils.TraditionalBinaryPrefix.long2String(size, "", 1)
@@ -107,7 +116,7 @@ class Ls extends FsCommand {
FileStatus stat = item.stat;
String line = String.format(lineFormat,
(stat.isDirectory() ? "d" : "-"),
- stat.getPermission(),
+ stat.getPermission() + (hasAcl(item) ? "+" : " "),
(stat.isFile() ? stat.getReplication() : "-"),
stat.getOwner(),
stat.getGroup(),
@@ -132,7 +141,7 @@ class Ls extends FsCommand {
}
StringBuilder fmt = new StringBuilder();
- fmt.append("%s%s "); // permission string
+ fmt.append("%s%s"); // permission string
fmt.append("%" + maxRepl + "s ");
// Do not use '%-0s' as a formatting conversion, since it will throw a
// a MissingFormatWidthException if it is used in String.format().
@@ -144,6 +153,49 @@ class Ls extends FsCommand {
lineFormat = fmt.toString();
}
+ /**
+ * Calls getAclStatus to determine if the given item has an ACL. For
+ * compatibility, this method traps errors caused by the RPC method missing
+ * from the server side. This would happen if the client was connected to an
+ * old NameNode that didn't have the ACL APIs. This method also traps the
+ * case of the client-side FileSystem not implementing the ACL APIs.
+ * FileSystem instances that do not support ACLs are remembered. This
+ * prevents the client from sending multiple failing RPC calls during a
+ * recursive ls.
+ *
+ * @param item PathData item to check
+ * @return boolean true if item has an ACL
+ * @throws IOException if there is a failure
+ */
+ private boolean hasAcl(PathData item) throws IOException {
+ FileSystem fs = item.fs;
+ if (aclNotSupportedFsSet.contains(fs.getUri())) {
+ // This FileSystem failed to run the ACL API in an earlier iteration.
+ return false;
+ }
+ try {
+ return !fs.getAclStatus(item.path).getEntries().isEmpty();
+ } catch (RemoteException e) {
+ // If this is a RpcNoSuchMethodException, then the client is connected to
+ // an older NameNode that doesn't support ACLs. Keep going.
+ IOException e2 = e.unwrapRemoteException(RpcNoSuchMethodException.class);
+ if (!(e2 instanceof RpcNoSuchMethodException)) {
+ throw e;
+ }
+ } catch (IOException e) {
+ // The NameNode supports ACLs, but they are not enabled. Keep going.
+ String message = e.getMessage();
+ if (message != null && !message.contains("ACLs has been disabled")) {
+ throw e;
+ }
+ } catch (UnsupportedOperationException e) {
+ // The underlying FileSystem doesn't implement ACLs. Keep going.
+ }
+ // Remember that this FileSystem cannot support ACLs.
+ aclNotSupportedFsSet.add(fs.getUri());
+ return false;
+ }
+
private int maxLength(int n, Object value) {
return Math.max(n, (value != null) ? String.valueOf(value).length() : 0);
}
Modified: hadoop/common/branches/branch-2.4/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/viewfs/ChRootedFileSystem.java
URL: http://svn.apache.org/viewvc/hadoop/common/branches/branch-2.4/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/viewfs/ChRootedFileSystem.java?rev=1572325&r1=1572324&r2=1572325&view=diff
==============================================================================
--- hadoop/common/branches/branch-2.4/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/viewfs/ChRootedFileSystem.java (original)
+++ hadoop/common/branches/branch-2.4/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/viewfs/ChRootedFileSystem.java Wed Feb 26 23:01:58 2014
@@ -20,6 +20,7 @@ import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URI;
import java.util.EnumSet;
+import java.util.List;
import org.apache.hadoop.classification.InterfaceAudience;
import org.apache.hadoop.classification.InterfaceStability;
@@ -36,6 +37,8 @@ import org.apache.hadoop.fs.FilterFileSy
import org.apache.hadoop.fs.FsServerDefaults;
import org.apache.hadoop.fs.FsStatus;
import org.apache.hadoop.fs.Path;
+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.util.Progressable;
@@ -277,7 +280,39 @@ class ChRootedFileSystem extends FilterF
throws IOException {
super.setTimes(fullPath(f), mtime, atime);
}
-
+
+ @Override
+ public void modifyAclEntries(Path path, List<AclEntry> aclSpec)
+ throws IOException {
+ super.modifyAclEntries(fullPath(path), aclSpec);
+ }
+
+ @Override
+ public void removeAclEntries(Path path, List<AclEntry> aclSpec)
+ throws IOException {
+ super.removeAclEntries(fullPath(path), aclSpec);
+ }
+
+ @Override
+ public void removeDefaultAcl(Path path) throws IOException {
+ super.removeDefaultAcl(fullPath(path));
+ }
+
+ @Override
+ public void removeAcl(Path path) throws IOException {
+ super.removeAcl(fullPath(path));
+ }
+
+ @Override
+ public void setAcl(Path path, List<AclEntry> aclSpec) throws IOException {
+ super.setAcl(fullPath(path), aclSpec);
+ }
+
+ @Override
+ public AclStatus getAclStatus(Path path) throws IOException {
+ return super.getAclStatus(fullPath(path));
+ }
+
@Override
public Path resolvePath(final Path p) throws IOException {
return super.resolvePath(fullPath(p));
Modified: hadoop/common/branches/branch-2.4/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/viewfs/ViewFileSystem.java
URL: http://svn.apache.org/viewvc/hadoop/common/branches/branch-2.4/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/viewfs/ViewFileSystem.java?rev=1572325&r1=1572324&r2=1572325&view=diff
==============================================================================
--- hadoop/common/branches/branch-2.4/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/viewfs/ViewFileSystem.java (original)
+++ hadoop/common/branches/branch-2.4/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/viewfs/ViewFileSystem.java Wed Feb 26 23:01:58 2014
@@ -28,7 +28,6 @@ import java.util.EnumSet;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
-import java.util.StringTokenizer;
import java.util.Map.Entry;
import org.apache.hadoop.classification.InterfaceAudience;
@@ -45,9 +44,10 @@ import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.FsConstants;
import org.apache.hadoop.fs.FsServerDefaults;
-import org.apache.hadoop.fs.InvalidPathException;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.fs.UnsupportedFileSystemException;
+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.fs.viewfs.InodeTree.INode;
import org.apache.hadoop.fs.viewfs.InodeTree.INodeLink;
@@ -474,6 +474,52 @@ public class ViewFileSystem extends File
}
@Override
+ public void modifyAclEntries(Path path, List<AclEntry> aclSpec)
+ throws IOException {
+ InodeTree.ResolveResult<FileSystem> res = fsState.resolve(getUriPath(path),
+ true);
+ res.targetFileSystem.modifyAclEntries(res.remainingPath, aclSpec);
+ }
+
+ @Override
+ public void removeAclEntries(Path path, List<AclEntry> aclSpec)
+ throws IOException {
+ InodeTree.ResolveResult<FileSystem> res = fsState.resolve(getUriPath(path),
+ true);
+ res.targetFileSystem.removeAclEntries(res.remainingPath, aclSpec);
+ }
+
+ @Override
+ public void removeDefaultAcl(Path path)
+ throws IOException {
+ InodeTree.ResolveResult<FileSystem> res =
+ fsState.resolve(getUriPath(path), true);
+ res.targetFileSystem.removeDefaultAcl(res.remainingPath);
+ }
+
+ @Override
+ public void removeAcl(Path path)
+ throws IOException {
+ InodeTree.ResolveResult<FileSystem> res =
+ fsState.resolve(getUriPath(path), true);
+ res.targetFileSystem.removeAcl(res.remainingPath);
+ }
+
+ @Override
+ public void setAcl(Path path, List<AclEntry> aclSpec) throws IOException {
+ InodeTree.ResolveResult<FileSystem> res =
+ fsState.resolve(getUriPath(path), true);
+ res.targetFileSystem.setAcl(res.remainingPath, aclSpec);
+ }
+
+ @Override
+ public AclStatus getAclStatus(Path path) throws IOException {
+ InodeTree.ResolveResult<FileSystem> res =
+ fsState.resolve(getUriPath(path), true);
+ return res.targetFileSystem.getAclStatus(res.remainingPath);
+ }
+
+ @Override
public void setVerifyChecksum(final boolean verifyChecksum) {
List<InodeTree.MountPoint<FileSystem>> mountPoints =
fsState.getMountPoints();
Modified: hadoop/common/branches/branch-2.4/hadoop-common-project/hadoop-common/src/site/apt/FileSystemShell.apt.vm
URL: http://svn.apache.org/viewvc/hadoop/common/branches/branch-2.4/hadoop-common-project/hadoop-common/src/site/apt/FileSystemShell.apt.vm?rev=1572325&r1=1572324&r2=1572325&view=diff
==============================================================================
--- hadoop/common/branches/branch-2.4/hadoop-common-project/hadoop-common/src/site/apt/FileSystemShell.apt.vm (original)
+++ hadoop/common/branches/branch-2.4/hadoop-common-project/hadoop-common/src/site/apt/FileSystemShell.apt.vm Wed Feb 26 23:01:58 2014
@@ -231,6 +231,29 @@ get
Returns 0 on success and -1 on error.
+getfacl
+
+ Usage: <<<hdfs dfs -getfacl [-R] <path> >>>
+
+ Displays the Access Control Lists (ACLs) of files and directories. If a
+ directory has a default ACL, then getfacl also displays the default ACL.
+
+ Options:
+
+ * -R: List the ACLs of all files and directories recursively.
+
+ * <path>: File or directory to list.
+
+ Examples:
+
+ * <<<hdfs dfs -getfacl /file>>>
+
+ * <<<hdfs dfs -getfacl -R /dir>>>
+
+ Exit Code:
+
+ Returns 0 on success and non-zero on error.
+
getmerge
Usage: <<<hdfs dfs -getmerge <src> <localdst> [addnl]>>>
@@ -379,6 +402,54 @@ rmr
Returns 0 on success and -1 on error.
+setfacl
+
+ Usage: <<<hdfs dfs -setfacl [-R] [{-b|-k} {-m|-x <acl_spec>} <path>]|[--set <acl_spec> <path>] >>>
+
+ Sets Access Control Lists (ACLs) of files and directories.
+
+ Options:
+
+ * -b: Remove all but the base ACL entries. The entries for user, group and
+ others are retained for compatibility with permission bits.
+
+ * -k: Remove the default ACL.
+
+ * -R: Apply operations to all files and directories recursively.
+
+ * -m: Modify ACL. New entries are added to the ACL, and existing entries
+ are retained.
+
+ * -x: Remove specified ACL entries. Other ACL entries are retained.
+
+ * --set: Fully replace the ACL, discarding all existing entries. The
+ <acl_spec> must include entries for user, group, and others for
+ compatibility with permission bits.
+
+ * <acl_spec>: Comma separated list of ACL entries.
+
+ * <path>: File or directory to modify.
+
+ Examples:
+
+ * <<<hdfs dfs -setfacl -m user:hadoop:rw- /file>>>
+
+ * <<<hdfs dfs -setfacl -x user:hadoop /file>>>
+
+ * <<<hdfs dfs -setfacl -b /file>>>
+
+ * <<<hdfs dfs -setfacl -k /dir>>>
+
+ * <<<hdfs dfs -setfacl --set user::rw-,user:hadoop:rw-,group::r--,other::r-- /file>>>
+
+ * <<<hdfs dfs -setfacl -R -m user:hadoop:r-x /dir>>>
+
+ * <<<hdfs dfs -setfacl -m default:user:hadoop:r-x /dir>>>
+
+ Exit Code:
+
+ Returns 0 on success and non-zero on error.
+
setrep
Usage: <<<hdfs dfs -setrep [-R] [-w] <numReplicas> <path> >>>
Propchange: hadoop/common/branches/branch-2.4/hadoop-common-project/hadoop-common/src/test/core/
------------------------------------------------------------------------------
Merged /hadoop/common/branches/HDFS-4685/hadoop-common-project/hadoop-common/src/test/core:r1547224-1569863
Modified: hadoop/common/branches/branch-2.4/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/TestHarFileSystem.java
URL: http://svn.apache.org/viewvc/hadoop/common/branches/branch-2.4/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/TestHarFileSystem.java?rev=1572325&r1=1572324&r2=1572325&view=diff
==============================================================================
--- hadoop/common/branches/branch-2.4/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/TestHarFileSystem.java (original)
+++ hadoop/common/branches/branch-2.4/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/TestHarFileSystem.java Wed Feb 26 23:01:58 2014
@@ -21,6 +21,8 @@ package org.apache.hadoop.fs;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.conf.Configuration;
+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.Credentials;
import org.apache.hadoop.security.token.Token;
@@ -33,6 +35,7 @@ import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.EnumSet;
import java.util.Iterator;
+import java.util.List;
import static org.apache.hadoop.fs.Options.ChecksumOpt;
import static org.apache.hadoop.fs.Options.CreateOpts;
@@ -165,6 +168,20 @@ public class TestHarFileSystem {
String snapshotNewName) throws IOException;
public void deleteSnapshot(Path path, String snapshotName)
throws IOException;
+
+ public void modifyAclEntries(Path path, List<AclEntry> aclSpec)
+ throws IOException;
+
+ public void removeAclEntries(Path path, List<AclEntry> aclSpec)
+ throws IOException;
+
+ public void removeDefaultAcl(Path path) throws IOException;
+
+ public void removeAcl(Path path) throws IOException;
+
+ public void setAcl(Path path, List<AclEntry> aclSpec) throws IOException;
+
+ public AclStatus getAclStatus(Path path) throws IOException;
}
@Test
Modified: hadoop/common/branches/branch-2.4/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/permission/TestFsPermission.java
URL: http://svn.apache.org/viewvc/hadoop/common/branches/branch-2.4/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/permission/TestFsPermission.java?rev=1572325&r1=1572324&r2=1572325&view=diff
==============================================================================
--- hadoop/common/branches/branch-2.4/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/permission/TestFsPermission.java (original)
+++ hadoop/common/branches/branch-2.4/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/permission/TestFsPermission.java Wed Feb 26 23:01:58 2014
@@ -54,7 +54,7 @@ public class TestFsPermission extends Te
* the expected values back out for all combinations
*/
public void testConvertingPermissions() {
- for(short s = 0; s < 01777; s++) {
+ for(short s = 0; s <= 01777; s++) {
assertEquals(s, new FsPermission(s).toShort());
}
@@ -64,10 +64,12 @@ public class TestFsPermission extends Te
for(FsAction u : FsAction.values()) {
for(FsAction g : FsAction.values()) {
for(FsAction o : FsAction.values()) {
+ // Cover constructor with sticky bit.
FsPermission f = new FsPermission(u, g, o, sb);
assertEquals(s, f.toShort());
FsPermission f2 = new FsPermission(f);
assertEquals(s, f2.toShort());
+
s++;
}
}
@@ -75,48 +77,57 @@ public class TestFsPermission extends Te
}
}
- public void testStickyBitToString() {
- // Check that every permission has its sticky bit represented correctly
- for(boolean sb : new boolean [] { false, true }) {
- for(FsAction u : FsAction.values()) {
- for(FsAction g : FsAction.values()) {
- for(FsAction o : FsAction.values()) {
+ public void testSpecialBitsToString() {
+ for (boolean sb : new boolean[] { false, true }) {
+ for (FsAction u : FsAction.values()) {
+ for (FsAction g : FsAction.values()) {
+ for (FsAction o : FsAction.values()) {
FsPermission f = new FsPermission(u, g, o, sb);
- if(f.getStickyBit() && f.getOtherAction().implies(EXECUTE))
- assertEquals('t', f.toString().charAt(8));
- else if(f.getStickyBit() && !f.getOtherAction().implies(EXECUTE))
- assertEquals('T', f.toString().charAt(8));
- else if(!f.getStickyBit() && f.getOtherAction().implies(EXECUTE))
- assertEquals('x', f.toString().charAt(8));
+ String fString = f.toString();
+
+ // Check that sticky bit is represented correctly.
+ if (f.getStickyBit() && f.getOtherAction().implies(EXECUTE))
+ assertEquals('t', fString.charAt(8));
+ else if (f.getStickyBit() && !f.getOtherAction().implies(EXECUTE))
+ assertEquals('T', fString.charAt(8));
+ else if (!f.getStickyBit() && f.getOtherAction().implies(EXECUTE))
+ assertEquals('x', fString.charAt(8));
else
- assertEquals('-', f.toString().charAt(8));
+ assertEquals('-', fString.charAt(8));
+
+ assertEquals(9, fString.length());
}
}
+
}
}
}
public void testFsPermission() {
- String symbolic = "-rwxrwxrwx";
- StringBuilder b = new StringBuilder("-123456789");
-
- for(int i = 0; i < (1<<9); i++) {
- for(int j = 1; j < 10; j++) {
- b.setCharAt(j, '-');
- }
- String binary = Integer.toBinaryString(i);
+ String symbolic = "-rwxrwxrwx";
- int len = binary.length();
- for(int j = 0; j < len; j++) {
- if (binary.charAt(j) == '1') {
- int k = 9 - (len - 1 - j);
- b.setCharAt(k, symbolic.charAt(k));
- }
+ for(int i = 0; i < (1 << 10); i++) {
+ StringBuilder b = new StringBuilder("----------");
+ String binary = String.format("%11s", Integer.toBinaryString(i));
+ String permBinary = binary.substring(2, binary.length());
+
+ int len = permBinary.length();
+ for(int j = 0; j < len; j++) {
+ if (permBinary.charAt(j) == '1') {
+ int k = 9 - (len - 1 - j);
+ b.setCharAt(k, symbolic.charAt(k));
}
+ }
- assertEquals(i, FsPermission.valueOf(b.toString()).toShort());
+ // Check for sticky bit.
+ if (binary.charAt(1) == '1') {
+ char replacement = b.charAt(9) == 'x' ? 't' : 'T';
+ b.setCharAt(9, replacement);
}
+
+ assertEquals(i, FsPermission.valueOf(b.toString()).toShort());
}
+ }
public void testUMaskParser() throws IOException {
Configuration conf = new Configuration();
Modified: hadoop/common/branches/branch-2.4/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/viewfs/TestChRootedFileSystem.java
URL: http://svn.apache.org/viewvc/hadoop/common/branches/branch-2.4/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/viewfs/TestChRootedFileSystem.java?rev=1572325&r1=1572324&r2=1572325&view=diff
==============================================================================
--- hadoop/common/branches/branch-2.4/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/viewfs/TestChRootedFileSystem.java (original)
+++ hadoop/common/branches/branch-2.4/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/viewfs/TestChRootedFileSystem.java Wed Feb 26 23:01:58 2014
@@ -20,6 +20,8 @@ package org.apache.hadoop.fs.viewfs;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URI;
+import java.util.Collections;
+import java.util.List;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileStatus;
@@ -29,6 +31,7 @@ import org.apache.hadoop.fs.FileSystemTe
import org.apache.hadoop.fs.FilterFileSystem;
import org.apache.hadoop.fs.FsConstants;
import org.apache.hadoop.fs.Path;
+import org.apache.hadoop.fs.permission.AclEntry;
import org.apache.hadoop.fs.viewfs.ChRootedFileSystem;
import org.junit.After;
import org.junit.Assert;
@@ -354,6 +357,44 @@ public class TestChRootedFileSystem {
new ChRootedFileSystem(chrootUri, conf);
}
+ /**
+ * Tests that ChRootedFileSystem delegates calls for every ACL method to the
+ * underlying FileSystem with all Path arguments translated as required to
+ * enforce chroot.
+ */
+ @Test
+ public void testAclMethodsPathTranslation() throws IOException {
+ Configuration conf = new Configuration();
+ conf.setClass("fs.mockfs.impl", MockFileSystem.class, FileSystem.class);
+
+ URI chrootUri = URI.create("mockfs://foo/a/b");
+ ChRootedFileSystem chrootFs = new ChRootedFileSystem(chrootUri, conf);
+ FileSystem mockFs = ((FilterFileSystem)chrootFs.getRawFileSystem())
+ .getRawFileSystem();
+
+ Path chrootPath = new Path("/c");
+ Path rawPath = new Path("/a/b/c");
+ List<AclEntry> entries = Collections.emptyList();
+
+ chrootFs.modifyAclEntries(chrootPath, entries);
+ verify(mockFs).modifyAclEntries(rawPath, entries);
+
+ chrootFs.removeAclEntries(chrootPath, entries);
+ verify(mockFs).removeAclEntries(rawPath, entries);
+
+ chrootFs.removeDefaultAcl(chrootPath);
+ verify(mockFs).removeDefaultAcl(rawPath);
+
+ chrootFs.removeAcl(chrootPath);
+ verify(mockFs).removeAcl(rawPath);
+
+ chrootFs.setAcl(chrootPath, entries);
+ verify(mockFs).setAcl(rawPath, entries);
+
+ chrootFs.getAclStatus(chrootPath);
+ verify(mockFs).getAclStatus(rawPath);
+ }
+
static class MockFileSystem extends FilterFileSystem {
MockFileSystem() {
super(mock(FileSystem.class));
@@ -361,4 +402,4 @@ public class TestChRootedFileSystem {
@Override
public void initialize(URI name, Configuration conf) throws IOException {}
}
-}
\ No newline at end of file
+}
Modified: hadoop/common/branches/branch-2.4/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/viewfs/TestViewFileSystemDelegation.java
URL: http://svn.apache.org/viewvc/hadoop/common/branches/branch-2.4/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/viewfs/TestViewFileSystemDelegation.java?rev=1572325&r1=1572324&r2=1572325&view=diff
==============================================================================
--- hadoop/common/branches/branch-2.4/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/viewfs/TestViewFileSystemDelegation.java (original)
+++ hadoop/common/branches/branch-2.4/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/viewfs/TestViewFileSystemDelegation.java Wed Feb 26 23:01:58 2014
@@ -20,14 +20,19 @@ package org.apache.hadoop.fs.viewfs;
import java.io.IOException;
import java.net.URI;
+import java.util.Collections;
+import java.util.List;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.FileSystemTestHelper;
import org.apache.hadoop.fs.FsConstants;
import org.apache.hadoop.fs.LocalFileSystem;
import org.apache.hadoop.fs.Path;
+import org.apache.hadoop.fs.permission.AclEntry;
+import org.apache.hadoop.fs.viewfs.TestChRootedFileSystem.MockFileSystem;
import org.junit.*;
import static org.junit.Assert.*;
+import static org.mockito.Mockito.*;
/**
* Verify that viewfs propagates certain methods to the underlying fs
@@ -57,6 +62,15 @@ public class TestViewFileSystemDelegatio
return fs;
}
+ private static FileSystem setupMockFileSystem(Configuration conf, URI uri)
+ throws Exception {
+ String scheme = uri.getScheme();
+ conf.set("fs." + scheme + ".impl", MockFileSystem.class.getName());
+ FileSystem fs = FileSystem.get(uri, conf);
+ ConfigUtil.addLink(conf, "/mounts/" + scheme, uri);
+ return ((MockFileSystem)fs).getRawFileSystem();
+ }
+
@Test
public void testSanity() {
assertEquals("fs1:/", fs1.getUri().toString());
@@ -69,6 +83,55 @@ public class TestViewFileSystemDelegatio
checkVerifyChecksum(true);
}
+ /**
+ * Tests that ViewFileSystem dispatches calls for every ACL method through the
+ * mount table to the correct underlying FileSystem with all Path arguments
+ * translated as required.
+ */
+ @Test
+ public void testAclMethods() throws Exception {
+ Configuration conf = ViewFileSystemTestSetup.createConfig();
+ FileSystem mockFs1 = setupMockFileSystem(conf, new URI("mockfs1:/"));
+ FileSystem mockFs2 = setupMockFileSystem(conf, new URI("mockfs2:/"));
+ FileSystem viewFs = FileSystem.get(FsConstants.VIEWFS_URI, conf);
+
+ Path viewFsPath1 = new Path("/mounts/mockfs1/a/b/c");
+ Path mockFsPath1 = new Path("/a/b/c");
+ Path viewFsPath2 = new Path("/mounts/mockfs2/d/e/f");
+ Path mockFsPath2 = new Path("/d/e/f");
+ List<AclEntry> entries = Collections.emptyList();
+
+ viewFs.modifyAclEntries(viewFsPath1, entries);
+ verify(mockFs1).modifyAclEntries(mockFsPath1, entries);
+ viewFs.modifyAclEntries(viewFsPath2, entries);
+ verify(mockFs2).modifyAclEntries(mockFsPath2, entries);
+
+ viewFs.removeAclEntries(viewFsPath1, entries);
+ verify(mockFs1).removeAclEntries(mockFsPath1, entries);
+ viewFs.removeAclEntries(viewFsPath2, entries);
+ verify(mockFs2).removeAclEntries(mockFsPath2, entries);
+
+ viewFs.removeDefaultAcl(viewFsPath1);
+ verify(mockFs1).removeDefaultAcl(mockFsPath1);
+ viewFs.removeDefaultAcl(viewFsPath2);
+ verify(mockFs2).removeDefaultAcl(mockFsPath2);
+
+ viewFs.removeAcl(viewFsPath1);
+ verify(mockFs1).removeAcl(mockFsPath1);
+ viewFs.removeAcl(viewFsPath2);
+ verify(mockFs2).removeAcl(mockFsPath2);
+
+ viewFs.setAcl(viewFsPath1, entries);
+ verify(mockFs1).setAcl(mockFsPath1, entries);
+ viewFs.setAcl(viewFsPath2, entries);
+ verify(mockFs2).setAcl(mockFsPath2, entries);
+
+ viewFs.getAclStatus(viewFsPath1);
+ verify(mockFs1).getAclStatus(mockFsPath1);
+ viewFs.getAclStatus(viewFsPath2);
+ verify(mockFs2).getAclStatus(mockFsPath2);
+ }
+
void checkVerifyChecksum(boolean flag) {
viewFs.setVerifyChecksum(flag);
assertEquals(flag, fs1.getVerifyChecksum());