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 sz...@apache.org on 2011/05/24 22:28:41 UTC
svn commit: r1127269 - in /hadoop/common/branches/yahoo-merge: ./
src/contrib/ec2/ src/docs/ src/java/ src/java/org/apache/hadoop/fs/
src/java/org/apache/hadoop/fs/shell/ src/test/core/
src/test/core/org/apache/hadoop/cli/ src/test/core/org/apache/hado...
Author: szetszwo
Date: Tue May 24 20:28:40 2011
New Revision: 1127269
URL: http://svn.apache.org/viewvc?rev=1127269&view=rev
Log:
Merge 1100356 and 1100400 from trunk for HADOOP-7249.
Modified:
hadoop/common/branches/yahoo-merge/ (props changed)
hadoop/common/branches/yahoo-merge/CHANGES.txt (contents, props changed)
hadoop/common/branches/yahoo-merge/src/contrib/ec2/ (props changed)
hadoop/common/branches/yahoo-merge/src/docs/ (props changed)
hadoop/common/branches/yahoo-merge/src/java/ (props changed)
hadoop/common/branches/yahoo-merge/src/java/org/apache/hadoop/fs/FsShell.java
hadoop/common/branches/yahoo-merge/src/java/org/apache/hadoop/fs/FsShellPermissions.java
hadoop/common/branches/yahoo-merge/src/java/org/apache/hadoop/fs/shell/Command.java
hadoop/common/branches/yahoo-merge/src/java/org/apache/hadoop/fs/shell/CommandFormat.java
hadoop/common/branches/yahoo-merge/src/java/org/apache/hadoop/fs/shell/FsCommand.java
hadoop/common/branches/yahoo-merge/src/java/org/apache/hadoop/fs/shell/Ls.java
hadoop/common/branches/yahoo-merge/src/test/core/ (props changed)
hadoop/common/branches/yahoo-merge/src/test/core/org/apache/hadoop/cli/testConf.xml
hadoop/common/branches/yahoo-merge/src/test/core/org/apache/hadoop/fs/TestFsShellReturnCode.java
Propchange: hadoop/common/branches/yahoo-merge/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Tue May 24 20:28:40 2011
@@ -1,2 +1,2 @@
-/hadoop/common/trunk:1043117,1076296,1078148,1080396,1081598,1082329,1082787-1082788,1084415,1084769,1085043,1085122,1086309,1087159,1087844,1090039,1090485,1091618,1091902,1091970,1092519,1092565,1094750,1095121,1095761,1096522,1096988,1099612,1099633,1100026
+/hadoop/common/trunk:1043117,1076296,1078148,1080396,1081598,1082329,1082787-1082788,1084415,1084769,1085043,1085122,1086309,1087159,1087844,1090039,1090485,1091618,1091902,1091970,1092519,1092565,1094750,1095121,1095761,1096522,1096988,1099612,1099633,1100026,1100356,1100400
/hadoop/core/branches/branch-0.19/core:713112
Modified: hadoop/common/branches/yahoo-merge/CHANGES.txt
URL: http://svn.apache.org/viewvc/hadoop/common/branches/yahoo-merge/CHANGES.txt?rev=1127269&r1=1127268&r2=1127269&view=diff
==============================================================================
--- hadoop/common/branches/yahoo-merge/CHANGES.txt (original)
+++ hadoop/common/branches/yahoo-merge/CHANGES.txt Tue May 24 20:28:40 2011
@@ -41,11 +41,14 @@ Trunk (unreleased changes)
HADOOP-7236. Refactor the mkdir command to conform to new FsCommand class.
(Daryn Sharp via szetszwo)
+ HADOOP-7114. FsShell should dump all exceptions at DEBUG level.
+ (todd via tomwhite)
+
HADOOP-7250. Refactor the setrep command to conform to new FsCommand class.
(Daryn Sharp via szetszwo)
- HADOOP-7114. FsShell should dump all exceptions at DEBUG level.
- (todd via tomwhite)
+ HADOOP-7249. Refactor the chmod/chown/chgrp command to conform to new
+ FsCommand class. (Daryn Sharp via szetszwo)
OPTIMIZATIONS
Propchange: hadoop/common/branches/yahoo-merge/CHANGES.txt
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Tue May 24 20:28:40 2011
@@ -1,4 +1,4 @@
-/hadoop/common/trunk/CHANGES.txt:1043117,1076296,1078148,1080396,1081598,1082329,1082787-1082788,1084415,1084769,1085043,1085122,1086309,1087159,1087844,1090039,1090485,1091618,1091902,1091970,1092519,1092565,1092832,1094750,1095121,1095761,1096522,1096988,1099612,1099633,1100026
+/hadoop/common/trunk/CHANGES.txt:1043117,1076296,1078148,1080396,1081598,1082329,1082787-1082788,1084415,1084769,1085043,1085122,1086309,1087159,1087844,1090039,1090485,1091618,1091902,1091970,1092519,1092565,1092832,1094750,1095121,1095761,1096522,1096988,1099612,1099633,1100026,1100356,1100400
/hadoop/core/branches/branch-0.18/CHANGES.txt:727226
/hadoop/core/branches/branch-0.19/CHANGES.txt:713112
/hadoop/core/trunk/CHANGES.txt:776175-785643,785929-786278
Propchange: hadoop/common/branches/yahoo-merge/src/contrib/ec2/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Tue May 24 20:28:40 2011
@@ -1,3 +1,3 @@
-/hadoop/common/trunk/src/contrib/ec2:1043117,1076296,1078148,1081598,1082329,1082787-1082788,1084415,1084769,1085043,1085122,1086309,1087159,1087844,1090039,1090485,1091618,1091902,1091970,1092519,1092565,1094750,1095121,1095761,1096522,1096988,1099612,1099633,1100026
+/hadoop/common/trunk/src/contrib/ec2:1043117,1076296,1078148,1081598,1082329,1082787-1082788,1084415,1084769,1085043,1085122,1086309,1087159,1087844,1090039,1090485,1091618,1091902,1091970,1092519,1092565,1094750,1095121,1095761,1096522,1096988,1099612,1099633,1100026,1100356,1100400
/hadoop/core/branches/branch-0.19/core/src/contrib/ec2:713112
/hadoop/core/trunk/src/contrib/ec2:776175-784663
Propchange: hadoop/common/branches/yahoo-merge/src/docs/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Tue May 24 20:28:40 2011
@@ -1,2 +1,2 @@
-/hadoop/common/trunk/src/docs:1043117,1076296,1078148,1080396,1081598,1082329,1082787-1082788,1084415,1084769,1085043,1085122,1086309,1087159,1087844,1090039,1090485,1091618,1091902,1091970,1092519,1092565,1094750,1095121,1095761,1096522,1096988,1099612,1099633,1100026
+/hadoop/common/trunk/src/docs:1043117,1076296,1078148,1080396,1081598,1082329,1082787-1082788,1084415,1084769,1085043,1085122,1086309,1087159,1087844,1090039,1090485,1091618,1091902,1091970,1092519,1092565,1094750,1095121,1095761,1096522,1096988,1099612,1099633,1100026,1100356,1100400
/hadoop/core/branches/branch-0.19/src/docs:713112
Propchange: hadoop/common/branches/yahoo-merge/src/java/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Tue May 24 20:28:40 2011
@@ -1,3 +1,3 @@
-/hadoop/common/trunk/src/java:1043117,1076296,1078148,1080396,1081598,1082329,1082787-1082788,1084415,1084769,1085043,1085122,1086309,1087159,1087844,1090039,1090485,1091618,1091902,1091970,1092519,1092565,1094750,1095121,1095761,1096522,1096988,1099612,1099633,1100026
+/hadoop/common/trunk/src/java:1043117,1076296,1078148,1080396,1081598,1082329,1082787-1082788,1084415,1084769,1085043,1085122,1086309,1087159,1087844,1090039,1090485,1091618,1091902,1091970,1092519,1092565,1094750,1095121,1095761,1096522,1096988,1099612,1099633,1100026,1100356,1100400
/hadoop/core/branches/branch-0.19/core/src/java:713112
/hadoop/core/trunk/src/core:776175-785643,785929-786278
Modified: hadoop/common/branches/yahoo-merge/src/java/org/apache/hadoop/fs/FsShell.java
URL: http://svn.apache.org/viewvc/hadoop/common/branches/yahoo-merge/src/java/org/apache/hadoop/fs/FsShell.java?rev=1127269&r1=1127268&r2=1127269&view=diff
==============================================================================
--- hadoop/common/branches/yahoo-merge/src/java/org/apache/hadoop/fs/FsShell.java (original)
+++ hadoop/common/branches/yahoo-merge/src/java/org/apache/hadoop/fs/FsShell.java Tue May 24 20:28:40 2011
@@ -969,114 +969,6 @@ public class FsShell extends Configured
}
/**
- * This class runs a command on a given FileStatus. This can be used for
- * running various commands like chmod, chown etc.
- */
- static abstract class CmdHandler {
-
- protected int errorCode = 0;
- protected boolean okToContinue = true;
- protected String cmdName;
-
- int getErrorCode() { return errorCode; }
- boolean okToContinue() { return okToContinue; }
- String getName() { return cmdName; }
-
- protected CmdHandler(String cmdName) {
- this.cmdName = cmdName;
- }
-
- public abstract void run(FileStatus file, FileSystem fs) throws IOException;
- }
-
- /** helper returns listStatus() */
- private static FileStatus[] shellListStatus(String cmd,
- FileSystem srcFs,
- FileStatus src) {
- if (src.isFile()) {
- FileStatus[] files = { src };
- return files;
- }
- Path path = src.getPath();
- try {
- FileStatus[] files = srcFs.listStatus(path);
-
- return files;
- } catch(FileNotFoundException fnfe) {
- System.err.println(cmd + ": could not get listing for '" + path + "'");
- } catch (IOException e) {
- LOG.debug("Error listing " + path, e);
- System.err.println(cmd +
- ": could not get get listing for '" + path + "' : " +
- e.getMessage().split("\n")[0]);
- }
- return null;
- }
-
-
- /**
- * Runs the command on a given file with the command handler.
- * If recursive is set, command is run recursively.
- */
- private static int runCmdHandler(CmdHandler handler, FileStatus stat,
- FileSystem srcFs,
- boolean recursive) throws IOException {
- int errors = 0;
- handler.run(stat, srcFs);
- if (recursive && stat.isDirectory() && handler.okToContinue()) {
- FileStatus[] files = shellListStatus(handler.getName(), srcFs, stat);
- if (files == null) {
- return 1;
- }
- for(FileStatus file : files ) {
- errors += runCmdHandler(handler, file, srcFs, recursive);
- }
- }
- return errors;
- }
-
- ///top level runCmdHandler
- int runCmdHandler(CmdHandler handler, String[] args,
- int startIndex, boolean recursive)
- throws IOException {
- int errors = 0;
-
- for (int i=startIndex; i<args.length; i++) {
- Path srcPath = new Path(args[i]);
- FileSystem srcFs = srcPath.getFileSystem(getConf());
- Path[] paths = FileUtil.stat2Paths(srcFs.globStatus(srcPath), srcPath);
- // if nothing matches to given glob pattern then increment error count
- if(paths.length==0) {
- System.err.println(handler.getName() +
- ": could not get status for '" + args[i] + "'");
- errors++;
- }
- for(Path path : paths) {
- try {
- FileStatus file = srcFs.getFileStatus(path);
- if (file == null) {
- System.err.println(handler.getName() +
- ": could not get status for '" + path + "'");
- errors++;
- } else {
- errors += runCmdHandler(handler, file, srcFs, recursive);
- }
- } catch (IOException e) {
- LOG.debug("Error getting status for " + path, e);
- String msg = (e.getMessage() != null ? e.getLocalizedMessage() :
- (e.getCause().getMessage() != null ?
- e.getCause().getLocalizedMessage() : "null"));
- System.err.println(handler.getName() + ": could not get status for '"
- + path + "': " + msg.split("\n")[0]);
- errors++;
- }
- }
- }
-
- return (errors > 0 || handler.getErrorCode() != 0) ? 1 : 0;
- }
-
- /**
* Return an abbreviated English-language desc of the byte length
* @deprecated Consider using {@link org.apache.hadoop.util.StringUtils#byteDesc} instead.
*/
@@ -1106,10 +998,7 @@ public class FsShell extends Configured
"[" + COPYTOLOCAL_SHORT_USAGE + "] [-moveToLocal <src> <localdst>]\n\t" +
"[-report]\n\t" +
"[-touchz <path>] [-test -[ezd] <path>] [-stat [format] <path>]\n\t" +
- "[-text <path>]\n\t" +
- "[" + FsShellPermissions.CHMOD_USAGE + "]\n\t" +
- "[" + FsShellPermissions.CHOWN_USAGE + "]\n\t" +
- "[" + FsShellPermissions.CHGRP_USAGE + "]";
+ "[-text <path>]";
String conf ="-conf <configuration file>: Specify an application configuration file.";
@@ -1204,39 +1093,7 @@ public class FsShell extends Configured
String stat = "-stat [format] <path>: Print statistics about the file/directory at <path>\n" +
"\t\tin the specified format. Format accepts filesize in blocks (%b), filename (%n),\n" +
"\t\tblock size (%o), replication (%r), modification date (%y, %Y)\n";
-
- String chmod = FsShellPermissions.CHMOD_USAGE + "\n" +
- "\t\tChanges permissions of a file.\n" +
- "\t\tThis works similar to shell's chmod with a few exceptions.\n\n" +
- "\t-R\tmodifies the files recursively. This is the only option\n" +
- "\t\tcurrently supported.\n\n" +
- "\tMODE\tMode is same as mode used for chmod shell command.\n" +
- "\t\tOnly letters recognized are 'rwxXt'. E.g. +t,a+r,g-w,+rwx,o=r\n\n" +
- "\tOCTALMODE Mode specifed in 3 or 4 digits. If 4 digits, the first may\n" +
- "\tbe 1 or 0 to turn the sticky bit on or off, respectively. Unlike " +
- "\tshell command, it is not possible to specify only part of the mode\n" +
- "\t\tE.g. 754 is same as u=rwx,g=rx,o=r\n\n" +
- "\t\tIf none of 'augo' is specified, 'a' is assumed and unlike\n" +
- "\t\tshell command, no umask is applied.\n";
-
- String chown = FsShellPermissions.CHOWN_USAGE + "\n" +
- "\t\tChanges owner and group of a file.\n" +
- "\t\tThis is similar to shell's chown with a few exceptions.\n\n" +
- "\t-R\tmodifies the files recursively. This is the only option\n" +
- "\t\tcurrently supported.\n\n" +
- "\t\tIf only owner or group is specified then only owner or\n" +
- "\t\tgroup is modified.\n\n" +
- "\t\tThe owner and group names may only cosists of digits, alphabet,\n"+
- "\t\tand any of '-_.@/' i.e. [-_.@/a-zA-Z0-9]. The names are case\n" +
- "\t\tsensitive.\n\n" +
- "\t\tWARNING: Avoid using '.' to separate user name and group though\n" +
- "\t\tLinux allows it. If user names have dots in them and you are\n" +
- "\t\tusing local file system, you might see surprising results since\n" +
- "\t\tshell command 'chown' is used for local files.\n";
- String chgrp = FsShellPermissions.CHGRP_USAGE + "\n" +
- "\t\tThis is equivalent to -chown ... :GROUP ...\n";
-
String expunge = "-expunge: Empty the Trash.\n";
String help = "-help [cmd]: \tDisplays help for given command or all commands if none\n" +
@@ -1293,12 +1150,6 @@ public class FsShell extends Configured
System.out.println(text);
} else if ("stat".equals(cmd)) {
System.out.println(stat);
- } else if ("chmod".equals(cmd)) {
- System.out.println(chmod);
- } else if ("chown".equals(cmd)) {
- System.out.println(chown);
- } else if ("chgrp".equals(cmd)) {
- System.out.println(chgrp);
} else if ("help".equals(cmd)) {
System.out.println(help);
} else {
@@ -1329,9 +1180,6 @@ public class FsShell extends Configured
System.out.println(test);
System.out.println(text);
System.out.println(stat);
- System.out.println(chmod);
- System.out.println(chown);
- System.out.println(chgrp);
for (String thisCmdName : commandFactory.getNames()) {
printHelp(commandFactory.getInstance(thisCmdName));
@@ -1502,9 +1350,6 @@ public class FsShell extends Configured
System.err.println(" [-touchz <path>]");
System.err.println(" [-test -[ezd] <path>]");
System.err.println(" [-stat [format] <path>]");
- System.err.println(" [" + FsShellPermissions.CHMOD_USAGE + "]");
- System.err.println(" [" + FsShellPermissions.CHOWN_USAGE + "]");
- System.err.println(" [" + FsShellPermissions.CHGRP_USAGE + "]");
for (String name : commandFactory.getNames()) {
instance = commandFactory.getInstance(name);
System.err.println(" [" + instance.getUsage() + "]");
@@ -1614,10 +1459,6 @@ public class FsShell extends Configured
exitCode = doall(cmd, argv, i);
} else if ("-moveToLocal".equals(cmd)) {
moveToLocal(argv[i++], new Path(argv[i++]));
- } else if ("-chmod".equals(cmd) ||
- "-chown".equals(cmd) ||
- "-chgrp".equals(cmd)) {
- exitCode = FsShellPermissions.changePermissions(cmd, argv, i, this);
} else if ("-mv".equals(cmd)) {
exitCode = rename(argv, getConf());
} else if ("-cp".equals(cmd)) {
Modified: hadoop/common/branches/yahoo-merge/src/java/org/apache/hadoop/fs/FsShellPermissions.java
URL: http://svn.apache.org/viewvc/hadoop/common/branches/yahoo-merge/src/java/org/apache/hadoop/fs/FsShellPermissions.java?rev=1127269&r1=1127268&r2=1127269&view=diff
==============================================================================
--- hadoop/common/branches/yahoo-merge/src/java/org/apache/hadoop/fs/FsShellPermissions.java (original)
+++ hadoop/common/branches/yahoo-merge/src/java/org/apache/hadoop/fs/FsShellPermissions.java Tue May 24 20:28:40 2011
@@ -18,15 +18,19 @@
package org.apache.hadoop.fs;
import java.io.IOException;
+import java.util.LinkedList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.logging.Log;
import org.apache.hadoop.classification.InterfaceAudience;
import org.apache.hadoop.classification.InterfaceStability;
-import org.apache.hadoop.fs.FsShell.CmdHandler;
-import org.apache.hadoop.fs.permission.FsPermission;
import org.apache.hadoop.fs.permission.ChmodParser;
+import org.apache.hadoop.fs.permission.FsPermission;
+import org.apache.hadoop.fs.shell.CommandFactory;
+import org.apache.hadoop.fs.shell.CommandFormat;
+import org.apache.hadoop.fs.shell.FsCommand;
+import org.apache.hadoop.fs.shell.PathData;
/**
@@ -35,80 +39,131 @@ import org.apache.hadoop.fs.permission.C
*/
@InterfaceAudience.Private
@InterfaceStability.Unstable
-class FsShellPermissions {
+public class FsShellPermissions extends FsCommand {
static Log LOG = FsShell.LOG;
- /*========== chmod ==========*/
+ /**
+ * Register the permission related commands with the factory
+ * @param factory the command factory
+ */
+ public static void registerCommands(CommandFactory factory) {
+ factory.addClass(Chmod.class, "-chmod");
+ factory.addClass(Chown.class, "-chown");
+ factory.addClass(Chgrp.class, "-chgrp");
+ }
+
+ @Override
+ protected String getFnfText(Path path) {
+ // TODO: printing the path twice is silly for backwards compatibility
+ return "could not get status for '"+path+"': File does not exist: "+path;
+ }
- /*
+ /**
* The pattern is almost as flexible as mode allowed by chmod shell command.
* The main restriction is that we recognize only rwxXt. To reduce errors we
* also enforce octal mode specifications of either 3 digits without a sticky
* bit setting or four digits with a sticky bit setting.
*/
+ public static class Chmod extends FsShellPermissions {
+ public static final String NAME = "chmod";
+ public static final String USAGE = "[-R] <MODE[,MODE]... | OCTALMODE> PATH...";
+ public static final String DESCRIPTION =
+ "Changes permissions of a file.\n" +
+ "\tThis works similar to shell's chmod with a few exceptions.\n\n" +
+ "-R\tmodifies the files recursively. This is the only option\n" +
+ "\tcurrently supported.\n\n" +
+ "MODE\tMode is same as mode used for chmod shell command.\n" +
+ "\tOnly letters recognized are 'rwxXt'. E.g. +t,a+r,g-w,+rwx,o=r\n\n" +
+ "OCTALMODE Mode specifed in 3 or 4 digits. If 4 digits, the first may\n" +
+ "be 1 or 0 to turn the sticky bit on or off, respectively. Unlike " +
+ "shell command, it is not possible to specify only part of the mode\n" +
+ "\tE.g. 754 is same as u=rwx,g=rx,o=r\n\n" +
+ "\tIf none of 'augo' is specified, 'a' is assumed and unlike\n" +
+ "\tshell command, no umask is applied.";
- static String CHMOD_USAGE =
- "-chmod [-R] <MODE[,MODE]... | OCTALMODE> PATH...";
+ protected ChmodParser pp;
- private static ChmodParser pp;
-
- private static class ChmodHandler extends CmdHandler {
+ @Override
+ protected void processOptions(LinkedList<String> args) throws IOException {
+ CommandFormat cf = new CommandFormat(null, 2, Integer.MAX_VALUE, "R", null);
+ cf.parse(args);
+ setRecursive(cf.getOpt("R"));
- ChmodHandler(String modeStr) throws IOException {
- super("chmod");
+ String modeStr = args.removeFirst();
try {
pp = new ChmodParser(modeStr);
- } catch(IllegalArgumentException iea) {
- patternError(iea.getMessage());
+ } catch (IllegalArgumentException iea) {
+ // TODO: remove "chmod : " so it's not doubled up in output, but it's
+ // here for backwards compatibility...
+ throw new IllegalArgumentException(
+ "chmod : mode '" + modeStr + "' does not match the expected pattern.");
}
}
-
- private void patternError(String mode) throws IOException {
- throw new IOException("chmod : mode '" + mode +
- "' does not match the expected pattern.");
- }
@Override
- public void run(FileStatus file, FileSystem srcFs) throws IOException {
- int newperms = pp.applyNewPermission(file);
-
- if (file.getPermission().toShort() != newperms) {
+ protected void processPath(PathData item) throws IOException {
+ short newperms = pp.applyNewPermission(item.stat);
+ if (item.stat.getPermission().toShort() != newperms) {
try {
- srcFs.setPermission(file.getPath(),
- new FsPermission((short)newperms));
+ item.fs.setPermission(item.path, new FsPermission(newperms));
} catch (IOException e) {
- LOG.debug("Error changing permissions of " + file.getPath(), e);
- System.err.println(getName() + ": changing permissions of '" +
- file.getPath() + "':" + e.getMessage());
+ LOG.debug("Error changing permissions of " + item, e);
+ throw new IOException(
+ "changing permissions of '" + item + "': " + e.getMessage());
}
}
- }
+ }
}
-
- /*========== chown ==========*/
-
- static private String allowedChars = "[-_./@a-zA-Z0-9]";
- ///allows only "allowedChars" above in names for owner and group
- static private Pattern chownPattern =
- Pattern.compile("^\\s*(" + allowedChars + "+)?" +
- "([:](" + allowedChars + "*))?\\s*$");
- static private Pattern chgrpPattern =
- Pattern.compile("^\\s*(" + allowedChars + "+)\\s*$");
- static String CHOWN_USAGE = "-chown [-R] [OWNER][:[GROUP]] PATH...";
- static String CHGRP_USAGE = "-chgrp [-R] GROUP PATH...";
+ // used by chown/chgrp
+ static private String allowedChars = "[-_./@a-zA-Z0-9]";
+
+ /**
+ * Used to change owner and/or group of files
+ */
+ public static class Chown extends FsShellPermissions {
+ public static final String NAME = "chown";
+ public static final String USAGE = "[-R] [OWNER][:[GROUP]] PATH...";
+ public static final String DESCRIPTION =
+ "Changes owner and group of a file.\n" +
+ "\tThis is similar to shell's chown with a few exceptions.\n\n" +
+ "\t-R\tmodifies the files recursively. This is the only option\n" +
+ "\tcurrently supported.\n\n" +
+ "\tIf only owner or group is specified then only owner or\n" +
+ "\tgroup is modified.\n\n" +
+ "\tThe owner and group names may only cosists of digits, alphabet,\n"+
+ "\tand any of '-_.@/' i.e. [-_.@/a-zA-Z0-9]. The names are case\n" +
+ "\tsensitive.\n\n" +
+ "\tWARNING: Avoid using '.' to separate user name and group though\n" +
+ "\tLinux allows it. If user names have dots in them and you are\n" +
+ "\tusing local file system, you might see surprising results since\n" +
+ "\tshell command 'chown' is used for local files.";
+
+ ///allows only "allowedChars" above in names for owner and group
+ static private final Pattern chownPattern = Pattern.compile(
+ "^\\s*(" + allowedChars + "+)?([:](" + allowedChars + "*))?\\s*$");
- private static class ChownHandler extends CmdHandler {
protected String owner = null;
protected String group = null;
- ChownHandler(String ownerStr) throws IOException {
- super("chown");
+ @Override
+ protected void processOptions(LinkedList<String> args) throws IOException {
+ CommandFormat cf = new CommandFormat(null, 2, Integer.MAX_VALUE, "R");
+ cf.parse(args);
+ setRecursive(cf.getOpt("R"));
+ parseOwnerGroup(args.removeFirst());
+ }
+
+ /**
+ * Parse the first argument into an owner and group
+ * @param ownerStr string describing new ownership
+ */
+ protected void parseOwnerGroup(String ownerStr) {
Matcher matcher = chownPattern.matcher(ownerStr);
if (!matcher.matches()) {
- throw new IOException("'" + ownerStr + "' does not match " +
- "expected pattern for [owner][:group].");
+ throw new IllegalArgumentException(
+ "'" + ownerStr + "' does not match expected pattern for [owner][:group].");
}
owner = matcher.group(1);
group = matcher.group(3);
@@ -116,91 +171,52 @@ class FsShellPermissions {
group = null;
}
if (owner == null && group == null) {
- throw new IOException("'" + ownerStr + "' does not specify " +
- " onwer or group.");
- }
+ throw new IllegalArgumentException(
+ "'" + ownerStr + "' does not specify owner or group.");
+ }
}
-
+
@Override
- public void run(FileStatus file, FileSystem srcFs) throws IOException {
- //Should we do case insensitive match?
- String newOwner = (owner == null || owner.equals(file.getOwner())) ?
+ protected void processPath(PathData item) throws IOException {
+ //Should we do case insensitive match?
+ String newOwner = (owner == null || owner.equals(item.stat.getOwner())) ?
null : owner;
- String newGroup = (group == null || group.equals(file.getGroup())) ?
+ String newGroup = (group == null || group.equals(item.stat.getGroup())) ?
null : group;
if (newOwner != null || newGroup != null) {
try {
- srcFs.setOwner(file.getPath(), newOwner, newGroup);
+ item.fs.setOwner(item.path, newOwner, newGroup);
} catch (IOException e) {
- LOG.debug("Error changing ownership of " + file.getPath(), e);
- System.err.println(getName() + ": changing ownership of '" +
- file.getPath() + "':" + e.getMessage());
-
+ LOG.debug("Error changing ownership of " + item, e);
+ throw new IOException(
+ "changing ownership of '" + item + "': " + e.getMessage());
}
}
}
}
- /*========== chgrp ==========*/
-
- private static class ChgrpHandler extends CmdHandler {
- protected String group = null;
- ChgrpHandler(String groupStr) throws IOException {
- super("chgrp");
+ /**
+ * Used to change group of files
+ */
+ public static class Chgrp extends Chown {
+ public static final String NAME = "chgrp";
+ public static final String USAGE = "[-R] GROUP PATH...";
+ public static final String DESCRIPTION =
+ "This is equivalent to -chown ... :GROUP ...";
+
+ static private final Pattern chgrpPattern =
+ Pattern.compile("^\\s*(" + allowedChars + "+)\\s*$");
+ @Override
+ protected void parseOwnerGroup(String groupStr) {
Matcher matcher = chgrpPattern.matcher(groupStr);
if (!matcher.matches()) {
- throw new IOException("'" + groupStr + "' does not match " +
- "expected pattern for group");
+ throw new IllegalArgumentException(
+ "'" + groupStr + "' does not match expected pattern for group");
}
+ owner = null;
group = matcher.group(1);
}
-
- @Override
- public void run(FileStatus file, FileSystem srcFs) throws IOException {
-
- String newGroup = (group.equals(file.getGroup())) ?
- null : group;
-
- if (newGroup != null) {
- try {
- srcFs.setOwner(file.getPath(), null, newGroup);
- } catch (IOException e) {
- LOG.debug("Error changing ownership of " + file.getPath(), e);
- System.err.println(getName() + ": changing ownership of '" +
- file.getPath() + "':" + e.getMessage());
-
- }
- }
- }
-
}
-
- static int changePermissions(String cmd,
- String argv[], int startIndex, FsShell shell)
- throws IOException {
- CmdHandler handler = null;
- boolean recursive = false;
-
- // handle common arguments, currently only "-R"
- for (; startIndex < argv.length && argv[startIndex].equals("-R");
- startIndex++) {
- recursive = true;
- }
-
- if ( startIndex >= argv.length ) {
- throw new IOException("Not enough arguments for the command");
- }
-
- if (cmd.equals("-chmod")) {
- handler = new ChmodHandler(argv[startIndex++]);
- } else if (cmd.equals("-chown")) {
- handler = new ChownHandler(argv[startIndex++]);
- } else if (cmd.equals("-chgrp")) {
- handler = new ChgrpHandler(argv[startIndex++]);
- }
-
- return shell.runCmdHandler(handler, argv, startIndex, recursive);
- }
}
Modified: hadoop/common/branches/yahoo-merge/src/java/org/apache/hadoop/fs/shell/Command.java
URL: http://svn.apache.org/viewvc/hadoop/common/branches/yahoo-merge/src/java/org/apache/hadoop/fs/shell/Command.java?rev=1127269&r1=1127268&r2=1127269&view=diff
==============================================================================
--- hadoop/common/branches/yahoo-merge/src/java/org/apache/hadoop/fs/shell/Command.java (original)
+++ hadoop/common/branches/yahoo-merge/src/java/org/apache/hadoop/fs/shell/Command.java Tue May 24 20:28:40 2011
@@ -144,11 +144,18 @@ abstract public class Command extends Co
displayError(e);
}
- // TODO: -1 should be reserved for syntax error, 1 should be failure
- return (numErrors == 0) ? exitCode : -1;
+ return (numErrors == 0) ? exitCode : exitCodeForError();
}
/**
+ * The exit code to be returned if any errors occur during execution.
+ * This method is needed to account for the inconsistency in the exit
+ * codes returned by various commands.
+ * @return a non-zero exit code
+ */
+ protected int exitCodeForError() { return 1; }
+
+ /**
* Must be implemented by commands to process the command line flags and
* check the bounds of the remaining arguments. If an
* IllegalArgumentException is thrown, the FsShell object will print the
Modified: hadoop/common/branches/yahoo-merge/src/java/org/apache/hadoop/fs/shell/CommandFormat.java
URL: http://svn.apache.org/viewvc/hadoop/common/branches/yahoo-merge/src/java/org/apache/hadoop/fs/shell/CommandFormat.java?rev=1127269&r1=1127268&r2=1127269&view=diff
==============================================================================
--- hadoop/common/branches/yahoo-merge/src/java/org/apache/hadoop/fs/shell/CommandFormat.java (original)
+++ hadoop/common/branches/yahoo-merge/src/java/org/apache/hadoop/fs/shell/CommandFormat.java Tue May 24 20:28:40 2011
@@ -32,14 +32,20 @@ public class CommandFormat {
final String name;
final int minPar, maxPar;
final Map<String, Boolean> options = new HashMap<String, Boolean>();
-
+ boolean ignoreUnknownOpts = false;
+
/** constructor */
public CommandFormat(String n, int min, int max, String ... possibleOpt) {
name = n;
minPar = min;
maxPar = max;
- for(String opt : possibleOpt)
- options.put(opt, Boolean.FALSE);
+ for (String opt : possibleOpt) {
+ if (opt == null) {
+ ignoreUnknownOpts = true;
+ } else {
+ options.put(opt, Boolean.FALSE);
+ }
+ }
}
/** Parse parameters starting from the given position
@@ -67,14 +73,14 @@ public class CommandFormat {
String arg = args.get(pos);
if (arg.startsWith("-") && arg.length() > 1) {
String opt = arg.substring(1);
- if (!options.containsKey(opt)) {
- throw new UnknownOptionException(arg);
+ if (options.containsKey(opt)) {
+ args.remove(pos);
+ options.put(opt, Boolean.TRUE);
+ continue;
}
- args.remove(pos);
- options.put(opt, Boolean.TRUE);
- } else {
- pos++;
+ if (!ignoreUnknownOpts) throw new UnknownOptionException(arg);
}
+ pos++;
}
int psize = args.size();
if (psize < minPar) {
Modified: hadoop/common/branches/yahoo-merge/src/java/org/apache/hadoop/fs/shell/FsCommand.java
URL: http://svn.apache.org/viewvc/hadoop/common/branches/yahoo-merge/src/java/org/apache/hadoop/fs/shell/FsCommand.java?rev=1127269&r1=1127268&r2=1127269&view=diff
==============================================================================
--- hadoop/common/branches/yahoo-merge/src/java/org/apache/hadoop/fs/shell/FsCommand.java (original)
+++ hadoop/common/branches/yahoo-merge/src/java/org/apache/hadoop/fs/shell/FsCommand.java Tue May 24 20:28:40 2011
@@ -23,6 +23,7 @@ import java.io.IOException;
import org.apache.hadoop.classification.InterfaceAudience;
import org.apache.hadoop.classification.InterfaceStability;
import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.fs.FsShellPermissions;
import org.apache.hadoop.fs.Path;
/**
@@ -43,6 +44,7 @@ abstract public class FsCommand extends
*/
public static void registerCommands(CommandFactory factory) {
factory.registerCommands(Count.class);
+ factory.registerCommands(FsShellPermissions.class);
factory.registerCommands(Ls.class);
factory.registerCommands(Mkdir.class);
factory.registerCommands(SetReplication.class);
Modified: hadoop/common/branches/yahoo-merge/src/java/org/apache/hadoop/fs/shell/Ls.java
URL: http://svn.apache.org/viewvc/hadoop/common/branches/yahoo-merge/src/java/org/apache/hadoop/fs/shell/Ls.java?rev=1127269&r1=1127268&r2=1127269&view=diff
==============================================================================
--- hadoop/common/branches/yahoo-merge/src/java/org/apache/hadoop/fs/shell/Ls.java (original)
+++ hadoop/common/branches/yahoo-merge/src/java/org/apache/hadoop/fs/shell/Ls.java Tue May 24 20:28:40 2011
@@ -132,6 +132,9 @@ class Ls extends FsCommand {
return "Cannot access " + path.toUri() + ": No such file or directory.";
}
+ @Override
+ protected int exitCodeForError() { return -1; }
+
/**
* Get a recursive listing of all files in that match the file patterns.
* Same as "-ls -R"
Propchange: hadoop/common/branches/yahoo-merge/src/test/core/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Tue May 24 20:28:40 2011
@@ -1,3 +1,3 @@
-/hadoop/common/trunk/src/test/core:1043117,1076296,1078148,1080396,1081598,1082329,1082787-1082788,1084415,1084769,1085043,1085122,1086309,1087159,1087844,1090039,1090485,1091618,1091902,1091970,1092519,1092565,1094750,1095121,1095761,1096522,1096988,1099612,1099633,1100026
+/hadoop/common/trunk/src/test/core:1043117,1076296,1078148,1080396,1081598,1082329,1082787-1082788,1084415,1084769,1085043,1085122,1086309,1087159,1087844,1090039,1090485,1091618,1091902,1091970,1092519,1092565,1094750,1095121,1095761,1096522,1096988,1099612,1099633,1100026,1100356,1100400
/hadoop/core/branches/branch-0.19/core/src/test/core:713112
/hadoop/core/trunk/src/test/core:776175-785643,785929-786278
Modified: hadoop/common/branches/yahoo-merge/src/test/core/org/apache/hadoop/cli/testConf.xml
URL: http://svn.apache.org/viewvc/hadoop/common/branches/yahoo-merge/src/test/core/org/apache/hadoop/cli/testConf.xml?rev=1127269&r1=1127268&r2=1127269&view=diff
==============================================================================
--- hadoop/common/branches/yahoo-merge/src/test/core/org/apache/hadoop/cli/testConf.xml (original)
+++ hadoop/common/branches/yahoo-merge/src/test/core/org/apache/hadoop/cli/testConf.xml Tue May 24 20:28:40 2011
@@ -625,11 +625,7 @@
<comparators>
<comparator>
<type>RegexpComparator</type>
- <expected-output>^-chmod \[-R\] <MODE\[,MODE\]... \| OCTALMODE> PATH...( )*</expected-output>
- </comparator>
- <comparator>
- <type>RegexpComparator</type>
- <expected-output>^( |\t)*Changes permissions of a file.( )*</expected-output>
+ <expected-output>^-chmod \[-R\] <MODE\[,MODE\]... \| OCTALMODE> PATH...:( |\t)*Changes permissions of a file.( )*</expected-output>
</comparator>
<comparator>
<type>RegexpComparator</type>
@@ -684,11 +680,7 @@
<comparators>
<comparator>
<type>RegexpComparator</type>
- <expected-output>^-chown \[-R\] \[OWNER\]\[:\[GROUP\]\] PATH...( )*</expected-output>
- </comparator>
- <comparator>
- <type>RegexpComparator</type>
- <expected-output>^( |\t)*Changes owner and group of a file.( )*</expected-output>
+ <expected-output>^-chown \[-R\] \[OWNER\]\[:\[GROUP\]\] PATH...:( |\t)*Changes owner and group of a file.( )*</expected-output>
</comparator>
<comparator>
<type>RegexpComparator</type>
@@ -751,11 +743,7 @@
<comparators>
<comparator>
<type>RegexpComparator</type>
- <expected-output>^-chgrp \[-R\] GROUP PATH...( )*</expected-output>
- </comparator>
- <comparator>
- <type>RegexpComparator</type>
- <expected-output>^( |\t)*This is equivalent to -chown ... :GROUP ...( )*</expected-output>
+ <expected-output>^-chgrp \[-R\] GROUP PATH...:( |\t)*This is equivalent to -chown ... :GROUP ...( )*</expected-output>
</comparator>
</comparators>
</test>
Modified: hadoop/common/branches/yahoo-merge/src/test/core/org/apache/hadoop/fs/TestFsShellReturnCode.java
URL: http://svn.apache.org/viewvc/hadoop/common/branches/yahoo-merge/src/test/core/org/apache/hadoop/fs/TestFsShellReturnCode.java?rev=1127269&r1=1127268&r2=1127269&view=diff
==============================================================================
--- hadoop/common/branches/yahoo-merge/src/test/core/org/apache/hadoop/fs/TestFsShellReturnCode.java (original)
+++ hadoop/common/branches/yahoo-merge/src/test/core/org/apache/hadoop/fs/TestFsShellReturnCode.java Tue May 24 20:28:40 2011
@@ -18,18 +18,22 @@
package org.apache.hadoop.fs;
+import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.PrintStream;
-import java.net.URI;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.io.IOUtils;
-import org.junit.Assert;
+import org.junit.BeforeClass;
import org.junit.Test;
/**
@@ -41,7 +45,16 @@ public class TestFsShellReturnCode {
.getLog("org.apache.hadoop.fs.TestFsShellReturnCode");
private static final Configuration conf = new Configuration();
-
+ private static FileSystem fileSys;
+ private static FsShell fsShell;
+
+ @BeforeClass
+ public static void setup() throws IOException {
+ conf.setClass("fs.file.impl", LocalFileSystemExtn.class, RawLocalFileSystem.class);
+ fileSys = FileSystem.get(conf);
+ fsShell = new FsShell(conf);
+ }
+
private static String TEST_ROOT_DIR = System.getProperty("test.build.data",
"build/test/data/testCHReturnCode");
@@ -51,11 +64,47 @@ public class TestFsShellReturnCode {
stm.close();
}
- public void verify(String cmd, String argv[], int cmdIndex,
- FsShell fsShell, int exitCode) throws Exception {
- int ec;
- ec = FsShellPermissions.changePermissions(cmd, argv, cmdIndex, fsShell);
- Assert.assertEquals(ec, exitCode);
+ private void change(int exit, String owner, String group, String...files)
+ throws Exception {
+ FileStatus[][] oldStats = new FileStatus[files.length][];
+ for (int i=0; i < files.length; i++) {
+ oldStats[i] = fileSys.globStatus(new Path(files[i]));
+ }
+
+ List<String>argv = new LinkedList<String>();
+ if (owner != null) {
+ argv.add("-chown");
+
+ String chown = owner;
+ if (group != null) {
+ chown += ":" + group;
+ if (group.isEmpty()) group = null; // avoid testing for it later
+ }
+ argv.add(chown);
+ } else {
+ argv.add("-chgrp");
+ argv.add(group);
+ }
+
+ Collections.addAll(argv, files);
+
+ assertEquals(exit, fsShell.run(argv.toArray(new String[0])));
+
+ for (int i=0; i < files.length; i++) {
+ FileStatus[] stats = fileSys.globStatus(new Path(files[i]));
+ if (stats != null) {
+ for (int j=0; j < stats.length; j++) {
+ assertEquals("check owner of " + files[i],
+ ((owner != null) ? "STUB-"+owner : oldStats[i][j].getOwner()),
+ stats[j].getOwner()
+ );
+ assertEquals("check group of " + files[i],
+ ((group != null) ? "STUB-"+group : oldStats[i][j].getGroup()),
+ stats[j].getGroup()
+ );
+ }
+ }
+ }
}
/**
@@ -70,8 +119,6 @@ public class TestFsShellReturnCode {
@Test
public void testChmod() throws Exception {
- FsShell fsShell = new FsShell(conf);
-
final String f1 = TEST_ROOT_DIR + "/" + "testChmod/fileExists";
final String f2 = TEST_ROOT_DIR + "/" + "testChmod/fileDoesNotExist";
final String f3 = TEST_ROOT_DIR + "/" + "testChmod/nonExistingfiles*";
@@ -84,23 +131,21 @@ public class TestFsShellReturnCode {
final String f7 = TEST_ROOT_DIR + "/" + "testChmod/file*";
- FileSystem fileSys = FileSystem.getLocal(conf);
-
// create and write test file
writeFile(fileSys, p1);
assertTrue(fileSys.exists(p1));
// Test 1: Test 1: exit code for chmod on existing is 0
String argv[] = { "-chmod", "777", f1 };
- verify("-chmod", argv, 1, fsShell, 0);
+ assertEquals(0, fsShell.run(argv));
// Test 2: exit code for chmod on non-existing path is 1
String argv2[] = { "-chmod", "777", f2 };
- verify("-chmod", argv2, 1, fsShell, 1);
+ assertEquals(1, fsShell.run(argv2));
// Test 3: exit code for chmod on non-existing path with globbed input is 1
String argv3[] = { "-chmod", "777", f3 };
- verify("-chmod", argv3, 1, fsShell, 1);
+ assertEquals(1, fsShell.run(argv3));
// create required files
writeFile(fileSys, p4);
@@ -112,7 +157,7 @@ public class TestFsShellReturnCode {
// Test 4: exit code for chmod on existing path with globbed input is 0
String argv4[] = { "-chmod", "777", f7 };
- verify("-chmod", argv4, 1, fsShell, 0);
+ assertEquals(0, fsShell.run(argv4));
}
@@ -128,8 +173,6 @@ public class TestFsShellReturnCode {
@Test
public void testChown() throws Exception {
- FsShell fsShell = new FsShell(conf);
-
final String f1 = TEST_ROOT_DIR + "/" + "testChown/fileExists";
final String f2 = TEST_ROOT_DIR + "/" + "testChown/fileDoesNotExist";
final String f3 = TEST_ROOT_DIR + "/" + "testChown/nonExistingfiles*";
@@ -142,23 +185,18 @@ public class TestFsShellReturnCode {
final String f7 = TEST_ROOT_DIR + "/" + "testChown/file*";
- FileSystem fileSys = FileSystem.getLocal(conf);
-
// create and write test file
writeFile(fileSys, p1);
assertTrue(fileSys.exists(p1));
// Test 1: exit code for chown on existing file is 0
- String argv[] = { "-chown", "admin", f1 };
- verify("-chown", argv, 1, fsShell, 0);
+ change(0, "admin", null, f1);
// Test 2: exit code for chown on non-existing path is 1
- String argv2[] = { "-chown", "admin", f2 };
- verify("-chown", argv2, 1, fsShell, 1);
+ change(1, "admin", null, f2);
// Test 3: exit code for chown on non-existing path with globbed input is 1
- String argv3[] = { "-chown", "admin", f3 };
- verify("-chown", argv3, 1, fsShell, 1);
+ change(1, "admin", null, f3);
// create required files
writeFile(fileSys, p4);
@@ -169,22 +207,11 @@ public class TestFsShellReturnCode {
assertTrue(fileSys.exists(p6));
// Test 4: exit code for chown on existing path with globbed input is 0
- String argv4[] = { "-chown", "admin", f7 };
- verify("-chown", argv4, 1, fsShell, 0);
+ change(0, "admin", null, f7);
//Test 5: test for setOwner invocation on FS from command handler.
- conf.set("fs.testfs.impl","org.apache.hadoop.fs.TestFsShellReturnCode$LocalFileSystemExtn");
- final String file = "testfs:///testFile";
- LocalFileSystemExtn fileSystem = (LocalFileSystemExtn)FileSystem.get(new URI(file), conf);
- String argv5[] = { "-chown", "admin:Test", file };
- FsShellPermissions.changePermissions("-chown", argv5, 1, fsShell);
- assertTrue("Not invoked the setOwner on Fs",fileSystem.groupname.equals("Test"));
- assertTrue("Not invoked the setOwner on Fs",fileSystem.username.equals("admin"));
- String argv6[] = { "-chown", "admin:", file };
- FsShellPermissions.changePermissions("-chown", argv6, 1, fsShell);
- assertTrue("Not invoked the setOwner on Fs",fileSystem.groupname == null);
- assertTrue("Not invoked the setOwner on Fs",fileSystem.username.equals("admin"));
-
+ change(0, "admin", "Test", f1);
+ change(0, "admin", "", f1);
}
/**
@@ -199,8 +226,6 @@ public class TestFsShellReturnCode {
@Test
public void testChgrp() throws Exception {
- FsShell fsShell = new FsShell(conf);
-
final String f1 = TEST_ROOT_DIR + "/" + "testChgrp/fileExists";
final String f2 = TEST_ROOT_DIR + "/" + "testChgrp/fileDoesNotExist";
final String f3 = TEST_ROOT_DIR + "/" + "testChgrp/nonExistingfiles*";
@@ -213,23 +238,20 @@ public class TestFsShellReturnCode {
final String f7 = TEST_ROOT_DIR + "/" + "testChgrp/file*";
- FileSystem fileSys = FileSystem.getLocal(conf);
-
// create and write test file
writeFile(fileSys, p1);
assertTrue(fileSys.exists(p1));
// Test 1: exit code for chgrp on existing file is 0
- String argv[] = { "-chgrp", "admin", f1 };
- verify("-chgrp", argv, 1, fsShell, 0);
+ change(0, null, "admin", f1);
// Test 2: exit code for chgrp on non existing path is 1
- String argv2[] = { "-chgrp", "admin", f2 };
- verify("-chgrp", argv2, 1, fsShell, 1);
+ change(1, null, "admin", f2);
+ change(1, null, "admin", f2, f1); // exit code used to be for last item
// Test 3: exit code for chgrp on non-existing path with globbed input is 1
- String argv3[] = { "-chgrp", "admin", f3 };
- verify("-chgrp", argv3, 1, fsShell, 1);
+ change(1, null, "admin", f3);
+ change(1, null, "admin", f3, f1);
// create required files
writeFile(fileSys, p4);
@@ -240,9 +262,8 @@ public class TestFsShellReturnCode {
assertTrue(fileSys.exists(p6));
// Test 4: exit code for chgrp on existing path with globbed input is 0
- String argv4[] = { "-chgrp", "admin", f7 };
- verify("-chgrp", argv4, 1, fsShell, 0);
-
+ change(0, null, "admin", f7);
+ change(1, null, "admin", f2, f7);
}
@Test
@@ -257,7 +278,6 @@ public class TestFsShellReturnCode {
System.setErr(out);
final String results;
try {
- FileSystem fileSys = FileSystem.getLocal(conf);
String[] args = new String[3];
args[0] = "-get";
args[1] = "/invalidPath";
@@ -275,7 +295,7 @@ public class TestFsShellReturnCode {
}
@Test
- public void testInvalidDefautlFS() throws Exception {
+ public void testInvalidDefaultFS() throws Exception {
// if default fs doesn't exist or is invalid, but the path provided in
// arguments is valid - fsshell should work
FsShell shell = new FsShell();
@@ -306,22 +326,45 @@ public class TestFsShellReturnCode {
}
static class LocalFileSystemExtn extends RawLocalFileSystem {
+ protected static HashMap<String,String> owners = new HashMap<String,String>();
+ protected static HashMap<String,String> groups = new HashMap<String,String>();
- private String username;
- private String groupname;
+ @Override
+ public FSDataOutputStream create(Path p) throws IOException {
+ //owners.remove(p);
+ //groups.remove(p);
+ return super.create(p);
+ }
@Override
public void setOwner(Path p, String username, String groupname)
throws IOException {
- this.username = username;
- this.groupname = groupname;
-
+ String f = makeQualified(p).toString();
+ if (username != null) {
+ owners.put(f, username);
+ }
+ if (groupname != null) {
+ groups.put(f, groupname);
+ }
}
@Override
- public FileStatus getFileStatus(Path f) throws IOException {
- return new FileStatus();
+ public FileStatus getFileStatus(Path p) throws IOException {
+ String f = makeQualified(p).toString();
+ FileStatus stat = super.getFileStatus(p);
+
+ stat.getPermission();
+ if (owners.containsKey(f)) {
+ stat.setOwner("STUB-"+owners.get(f));
+ } else {
+ stat.setOwner("REAL-"+stat.getOwner());
+ }
+ if (groups.containsKey(f)) {
+ stat.setGroup("STUB-"+groups.get(f));
+ } else {
+ stat.setGroup("REAL-"+stat.getGroup());
+ }
+ return stat;
}
}
-
}