HADOOP-6385. dfs should support -rmdir (was HDFS-639). Contributed by Daryn Sharp.
git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/trunk@1150987 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
01cd616d17
commit
60e4947cc7
|
@ -60,6 +60,9 @@ Trunk (unreleased changes)
|
||||||
|
|
||||||
HADOOP-7460. Support pluggable trash policies. (Usman Masoon via suresh)
|
HADOOP-7460. Support pluggable trash policies. (Usman Masoon via suresh)
|
||||||
|
|
||||||
|
HADOOP-6385. dfs should support -rmdir (was HDFS-639). (Daryn Sharp
|
||||||
|
via mattf)
|
||||||
|
|
||||||
IMPROVEMENTS
|
IMPROVEMENTS
|
||||||
|
|
||||||
HADOOP-7042. Updates to test-patch.sh to include failed test names and
|
HADOOP-7042. Updates to test-patch.sh to include failed test names and
|
||||||
|
|
|
@ -27,6 +27,8 @@ import org.apache.hadoop.classification.InterfaceStability;
|
||||||
import org.apache.hadoop.fs.Trash;
|
import org.apache.hadoop.fs.Trash;
|
||||||
import org.apache.hadoop.fs.shell.PathExceptions.PathIOException;
|
import org.apache.hadoop.fs.shell.PathExceptions.PathIOException;
|
||||||
import org.apache.hadoop.fs.shell.PathExceptions.PathIsDirectoryException;
|
import org.apache.hadoop.fs.shell.PathExceptions.PathIsDirectoryException;
|
||||||
|
import org.apache.hadoop.fs.shell.PathExceptions.PathIsNotDirectoryException;
|
||||||
|
import org.apache.hadoop.fs.shell.PathExceptions.PathIsNotEmptyDirectoryException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Classes that delete paths
|
* Classes that delete paths
|
||||||
|
@ -34,9 +36,10 @@ import org.apache.hadoop.fs.shell.PathExceptions.PathIsDirectoryException;
|
||||||
@InterfaceAudience.Private
|
@InterfaceAudience.Private
|
||||||
@InterfaceStability.Evolving
|
@InterfaceStability.Evolving
|
||||||
|
|
||||||
class Delete extends FsCommand {
|
class Delete {
|
||||||
public static void registerCommands(CommandFactory factory) {
|
public static void registerCommands(CommandFactory factory) {
|
||||||
factory.addClass(Rm.class, "-rm");
|
factory.addClass(Rm.class, "-rm");
|
||||||
|
factory.addClass(Rmdir.class, "-rmdir");
|
||||||
factory.addClass(Rmr.class, "-rmr");
|
factory.addClass(Rmr.class, "-rmr");
|
||||||
factory.addClass(Expunge.class, "-expunge");
|
factory.addClass(Expunge.class, "-expunge");
|
||||||
}
|
}
|
||||||
|
@ -44,26 +47,35 @@ class Delete extends FsCommand {
|
||||||
/** remove non-directory paths */
|
/** remove non-directory paths */
|
||||||
public static class Rm extends FsCommand {
|
public static class Rm extends FsCommand {
|
||||||
public static final String NAME = "rm";
|
public static final String NAME = "rm";
|
||||||
public static final String USAGE = "[-r|-R] [-skipTrash] <src> ...";
|
public static final String USAGE = "[-f] [-r|-R] [-skipTrash] <src> ...";
|
||||||
public static final String DESCRIPTION =
|
public static final String DESCRIPTION =
|
||||||
"Delete all files that match the specified file pattern.\n" +
|
"Delete all files that match the specified file pattern.\n" +
|
||||||
"Equivalent to the Unix command \"rm <src>\"\n" +
|
"Equivalent to the Unix command \"rm <src>\"\n" +
|
||||||
"-skipTrash option bypasses trash, if enabled, and immediately\n" +
|
"-skipTrash option bypasses trash, if enabled, and immediately\n" +
|
||||||
"deletes <src>\n" +
|
"deletes <src>\n" +
|
||||||
|
" -f If the file does not exist, do not display a diagnostic\n" +
|
||||||
|
" message or modify the exit status to reflect an error.\n" +
|
||||||
" -[rR] Recursively deletes directories";
|
" -[rR] Recursively deletes directories";
|
||||||
|
|
||||||
private boolean skipTrash = false;
|
private boolean skipTrash = false;
|
||||||
private boolean deleteDirs = false;
|
private boolean deleteDirs = false;
|
||||||
|
private boolean ignoreFNF = false;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void processOptions(LinkedList<String> args) throws IOException {
|
protected void processOptions(LinkedList<String> args) throws IOException {
|
||||||
CommandFormat cf = new CommandFormat(
|
CommandFormat cf = new CommandFormat(
|
||||||
1, Integer.MAX_VALUE, "r", "R", "skipTrash");
|
1, Integer.MAX_VALUE, "f", "r", "R", "skipTrash");
|
||||||
cf.parse(args);
|
cf.parse(args);
|
||||||
|
ignoreFNF = cf.getOpt("f");
|
||||||
deleteDirs = cf.getOpt("r") || cf.getOpt("R");
|
deleteDirs = cf.getOpt("r") || cf.getOpt("R");
|
||||||
skipTrash = cf.getOpt("skipTrash");
|
skipTrash = cf.getOpt("skipTrash");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void processNonexistentPath(PathData item) throws IOException {
|
||||||
|
if (!ignoreFNF) super.processNonexistentPath(item);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void processPath(PathData item) throws IOException {
|
protected void processPath(PathData item) throws IOException {
|
||||||
if (item.stat.isDirectory() && !deleteDirs) {
|
if (item.stat.isDirectory() && !deleteDirs) {
|
||||||
|
@ -113,6 +125,39 @@ class Delete extends FsCommand {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** remove only empty directories */
|
||||||
|
static class Rmdir extends FsCommand {
|
||||||
|
public static final String NAME = "rmdir";
|
||||||
|
public static final String USAGE =
|
||||||
|
"[--ignore-fail-on-non-empty] <dir> ...";
|
||||||
|
public static final String DESCRIPTION =
|
||||||
|
"Removes the directory entry specified by each directory argument,\n" +
|
||||||
|
"provided it is empty.\n";
|
||||||
|
|
||||||
|
private boolean ignoreNonEmpty = false;
|
||||||
|
|
||||||
|
protected void processOptions(LinkedList<String> args) throws IOException {
|
||||||
|
CommandFormat cf = new CommandFormat(
|
||||||
|
1, Integer.MAX_VALUE, "-ignore-fail-on-non-empty");
|
||||||
|
cf.parse(args);
|
||||||
|
ignoreNonEmpty = cf.getOpt("-ignore-fail-on-non-empty");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void processPath(PathData item) throws IOException {
|
||||||
|
if (!item.stat.isDirectory()) {
|
||||||
|
throw new PathIsNotDirectoryException(item.toString());
|
||||||
|
}
|
||||||
|
if (item.fs.listStatus(item.path).length == 0) {
|
||||||
|
if (!item.fs.delete(item.path, false)) {
|
||||||
|
throw new PathIOException(item.toString());
|
||||||
|
}
|
||||||
|
} else if (!ignoreNonEmpty) {
|
||||||
|
throw new PathIsNotEmptyDirectoryException(item.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** empty the trash */
|
/** empty the trash */
|
||||||
static class Expunge extends FsCommand {
|
static class Expunge extends FsCommand {
|
||||||
public static final String NAME = "expunge";
|
public static final String NAME = "expunge";
|
||||||
|
|
|
@ -31,6 +31,7 @@ import org.apache.hadoop.fs.Path;
|
||||||
@InterfaceAudience.Private
|
@InterfaceAudience.Private
|
||||||
@InterfaceStability.Unstable
|
@InterfaceStability.Unstable
|
||||||
|
|
||||||
|
@SuppressWarnings("serial")
|
||||||
public class PathExceptions {
|
public class PathExceptions {
|
||||||
|
|
||||||
/** EIO */
|
/** EIO */
|
||||||
|
@ -165,6 +166,14 @@ public class PathExceptions {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Generated by rm commands */
|
||||||
|
public static class PathIsNotEmptyDirectoryException extends PathExistsException {
|
||||||
|
/** @param path for the exception */
|
||||||
|
public PathIsNotEmptyDirectoryException(String path) {
|
||||||
|
super(path, "Directory is not empty");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** EACCES */
|
/** EACCES */
|
||||||
public static class PathAccessDeniedException extends PathIOException {
|
public static class PathAccessDeniedException extends PathIOException {
|
||||||
static final long serialVersionUID = 0L;
|
static final long serialVersionUID = 0L;
|
||||||
|
|
|
@ -283,7 +283,7 @@
|
||||||
<comparators>
|
<comparators>
|
||||||
<comparator>
|
<comparator>
|
||||||
<type>RegexpComparator</type>
|
<type>RegexpComparator</type>
|
||||||
<expected-output>^-rm \[-r\|-R\] \[-skipTrash\] <src> \.\.\.:( |\t)*Delete all files that match the specified file pattern.( )*</expected-output>
|
<expected-output>^-rm \[-f\] \[-r\|-R\] \[-skipTrash\] <src> \.\.\.:( |\t)*Delete all files that match the specified file pattern.( )*</expected-output>
|
||||||
</comparator>
|
</comparator>
|
||||||
<comparator>
|
<comparator>
|
||||||
<type>RegexpComparator</type>
|
<type>RegexpComparator</type>
|
||||||
|
@ -297,6 +297,37 @@
|
||||||
<type>RegexpComparator</type>
|
<type>RegexpComparator</type>
|
||||||
<expected-output>^( |\t)*deletes <src>( )*</expected-output>
|
<expected-output>^( |\t)*deletes <src>( )*</expected-output>
|
||||||
</comparator>
|
</comparator>
|
||||||
|
<comparator>
|
||||||
|
<type>RegexpComparator</type>
|
||||||
|
<expected-output>^\s+-f\s+If the file does not exist, do not display a diagnostic</expected-output>
|
||||||
|
</comparator>
|
||||||
|
<comparator>
|
||||||
|
<type>RegexpComparator</type>
|
||||||
|
<expected-output>^\s+message or modify the exit status to reflect an error\.</expected-output>
|
||||||
|
</comparator>
|
||||||
|
<comparator>
|
||||||
|
<type>RegexpComparator</type>
|
||||||
|
<expected-output>^\s+-\[rR\]\s+Recursively deletes directories</expected-output>
|
||||||
|
</comparator>
|
||||||
|
</comparators>
|
||||||
|
</test>
|
||||||
|
|
||||||
|
<test> <!-- TESTED -->
|
||||||
|
<description>help: help for rmdir</description>
|
||||||
|
<test-commands>
|
||||||
|
<command>-help rmdir</command>
|
||||||
|
</test-commands>
|
||||||
|
<cleanup-commands>
|
||||||
|
</cleanup-commands>
|
||||||
|
<comparators>
|
||||||
|
<comparator>
|
||||||
|
<type>RegexpComparator</type>
|
||||||
|
<expected-output>^-rmdir \[--ignore-fail-on-non-empty\] <dir> \.\.\.:\s+Removes the directory entry specified by each directory argument,</expected-output>
|
||||||
|
</comparator>
|
||||||
|
<comparator>
|
||||||
|
<type>RegexpComparator</type>
|
||||||
|
<expected-output>\s+provided it is empty.</expected-output>
|
||||||
|
</comparator>
|
||||||
</comparators>
|
</comparators>
|
||||||
</test>
|
</test>
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue