YARN-1117. Improved help messages for "yarn application" and "yarn node" commands. Contributed by Xuan Gong.
svn merge --ignore-ancestry -c 1519117 ../../trunk/ git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/branches/branch-2@1519118 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
148db9d4f5
commit
3fea164bb1
|
@ -57,6 +57,9 @@ Release 2.1.1-beta - UNRELEASED
|
||||||
YARN-771. AMRMClient support for resource blacklisting (Junping Du via
|
YARN-771. AMRMClient support for resource blacklisting (Junping Du via
|
||||||
bikas)
|
bikas)
|
||||||
|
|
||||||
|
YARN-1117. Improved help messages for "yarn application" and "yarn node"
|
||||||
|
commands. (Xuan Gong via vinodkv)
|
||||||
|
|
||||||
OPTIMIZATIONS
|
OPTIMIZATIONS
|
||||||
|
|
||||||
BUG FIXES
|
BUG FIXES
|
||||||
|
|
|
@ -29,6 +29,7 @@ import java.util.Set;
|
||||||
import org.apache.commons.cli.CommandLine;
|
import org.apache.commons.cli.CommandLine;
|
||||||
import org.apache.commons.cli.GnuParser;
|
import org.apache.commons.cli.GnuParser;
|
||||||
import org.apache.commons.cli.HelpFormatter;
|
import org.apache.commons.cli.HelpFormatter;
|
||||||
|
import org.apache.commons.cli.MissingArgumentException;
|
||||||
import org.apache.commons.cli.Option;
|
import org.apache.commons.cli.Option;
|
||||||
import org.apache.commons.cli.Options;
|
import org.apache.commons.cli.Options;
|
||||||
import org.apache.hadoop.classification.InterfaceAudience.Private;
|
import org.apache.hadoop.classification.InterfaceAudience.Private;
|
||||||
|
@ -70,32 +71,38 @@ public class ApplicationCLI extends YarnCLI {
|
||||||
Options opts = new Options();
|
Options opts = new Options();
|
||||||
opts.addOption(STATUS_CMD, true, "Prints the status of the application.");
|
opts.addOption(STATUS_CMD, true, "Prints the status of the application.");
|
||||||
opts.addOption(LIST_CMD, false, "List applications from the RM. " +
|
opts.addOption(LIST_CMD, false, "List applications from the RM. " +
|
||||||
"Supports optional use of --appTypes to filter applications " +
|
"Supports optional use of -appTypes to filter applications " +
|
||||||
"based on application type, " +
|
"based on application type, " +
|
||||||
"and --appStates to filter applications based on application state");
|
"and -appStates to filter applications based on application state");
|
||||||
opts.addOption(KILL_CMD, true, "Kills the application.");
|
opts.addOption(KILL_CMD, true, "Kills the application.");
|
||||||
opts.addOption(HELP_CMD, false, "Displays help for all commands.");
|
opts.addOption(HELP_CMD, false, "Displays help for all commands.");
|
||||||
Option appTypeOpt = new Option(APP_TYPE_CMD, true,
|
Option appTypeOpt = new Option(APP_TYPE_CMD, true, "Works with -list to " +
|
||||||
"Works with --list to filter applications based on their type.");
|
"filter applications based on " +
|
||||||
|
"input comma-separated list of application types.");
|
||||||
appTypeOpt.setValueSeparator(',');
|
appTypeOpt.setValueSeparator(',');
|
||||||
appTypeOpt.setArgs(Option.UNLIMITED_VALUES);
|
appTypeOpt.setArgs(Option.UNLIMITED_VALUES);
|
||||||
appTypeOpt.setArgName("Comma-separated list of application types");
|
appTypeOpt.setArgName("Types");
|
||||||
opts.addOption(appTypeOpt);
|
opts.addOption(appTypeOpt);
|
||||||
Option appStateOpt =
|
Option appStateOpt = new Option(APP_STATE_CMD, true, "Works with -list " +
|
||||||
new Option(
|
"to filter applications based on input comma-separated list of " +
|
||||||
APP_STATE_CMD,
|
"application states. " + getAllValidApplicationStates());
|
||||||
true,
|
|
||||||
"Works with --list to filter applications based on their state. "
|
|
||||||
+ getAllValidApplicationStates());
|
|
||||||
appStateOpt.setValueSeparator(',');
|
appStateOpt.setValueSeparator(',');
|
||||||
appStateOpt.setArgs(Option.UNLIMITED_VALUES);
|
appStateOpt.setArgs(Option.UNLIMITED_VALUES);
|
||||||
appStateOpt.setArgName("Comma-separated list of application states");
|
appStateOpt.setArgName("States");
|
||||||
opts.addOption(appStateOpt);
|
opts.addOption(appStateOpt);
|
||||||
opts.getOption(KILL_CMD).setArgName("Application ID");
|
opts.getOption(KILL_CMD).setArgName("Application ID");
|
||||||
opts.getOption(STATUS_CMD).setArgName("Application ID");
|
opts.getOption(STATUS_CMD).setArgName("Application ID");
|
||||||
CommandLine cliParser = new GnuParser().parse(opts, args);
|
|
||||||
|
|
||||||
int exitCode = -1;
|
int exitCode = -1;
|
||||||
|
CommandLine cliParser = null;
|
||||||
|
try {
|
||||||
|
cliParser = new GnuParser().parse(opts, args);
|
||||||
|
} catch (MissingArgumentException ex) {
|
||||||
|
sysout.println("Missing argument for options");
|
||||||
|
printUsage(opts);
|
||||||
|
return exitCode;
|
||||||
|
}
|
||||||
|
|
||||||
if (cliParser.hasOption(STATUS_CMD)) {
|
if (cliParser.hasOption(STATUS_CMD)) {
|
||||||
if (args.length != 2) {
|
if (args.length != 2) {
|
||||||
printUsage(opts);
|
printUsage(opts);
|
||||||
|
|
|
@ -28,6 +28,7 @@ import java.util.Set;
|
||||||
import org.apache.commons.cli.CommandLine;
|
import org.apache.commons.cli.CommandLine;
|
||||||
import org.apache.commons.cli.GnuParser;
|
import org.apache.commons.cli.GnuParser;
|
||||||
import org.apache.commons.cli.HelpFormatter;
|
import org.apache.commons.cli.HelpFormatter;
|
||||||
|
import org.apache.commons.cli.MissingArgumentException;
|
||||||
import org.apache.commons.cli.Option;
|
import org.apache.commons.cli.Option;
|
||||||
import org.apache.commons.cli.Options;
|
import org.apache.commons.cli.Options;
|
||||||
import org.apache.commons.lang.time.DateFormatUtils;
|
import org.apache.commons.lang.time.DateFormatUtils;
|
||||||
|
@ -64,20 +65,29 @@ public class NodeCLI extends YarnCLI {
|
||||||
Options opts = new Options();
|
Options opts = new Options();
|
||||||
opts.addOption(STATUS_CMD, true, "Prints the status report of the node.");
|
opts.addOption(STATUS_CMD, true, "Prints the status report of the node.");
|
||||||
opts.addOption(LIST_CMD, false, "List all running nodes. " +
|
opts.addOption(LIST_CMD, false, "List all running nodes. " +
|
||||||
"Supports optional use of --states to filter nodes " +
|
"Supports optional use of -states to filter nodes " +
|
||||||
"based on node state, all --all to list all nodes.");
|
"based on node state, all -all to list all nodes.");
|
||||||
Option nodeStateOpt = new Option(NODE_STATE_CMD, true,
|
Option nodeStateOpt = new Option(NODE_STATE_CMD, true,
|
||||||
"Works with -list to filter nodes based on their states.");
|
"Works with -list to filter nodes based on input comma-separated list of node states.");
|
||||||
nodeStateOpt.setValueSeparator(',');
|
nodeStateOpt.setValueSeparator(',');
|
||||||
nodeStateOpt.setArgs(Option.UNLIMITED_VALUES);
|
nodeStateOpt.setArgs(Option.UNLIMITED_VALUES);
|
||||||
nodeStateOpt.setArgName("Comma-separated list of node states");
|
nodeStateOpt.setArgName("States");
|
||||||
opts.addOption(nodeStateOpt);
|
opts.addOption(nodeStateOpt);
|
||||||
Option allOpt = new Option(NODE_ALL, false,
|
Option allOpt = new Option(NODE_ALL, false,
|
||||||
"Works with -list to list all nodes.");
|
"Works with -list to list all nodes.");
|
||||||
opts.addOption(allOpt);
|
opts.addOption(allOpt);
|
||||||
CommandLine cliParser = new GnuParser().parse(opts, args);
|
opts.getOption(STATUS_CMD).setArgName("NodeId");
|
||||||
|
|
||||||
int exitCode = -1;
|
int exitCode = -1;
|
||||||
|
CommandLine cliParser = null;
|
||||||
|
try {
|
||||||
|
cliParser = new GnuParser().parse(opts, args);
|
||||||
|
} catch (MissingArgumentException ex) {
|
||||||
|
sysout.println("Missing argument for options");
|
||||||
|
printUsage(opts);
|
||||||
|
return exitCode;
|
||||||
|
}
|
||||||
|
|
||||||
if (cliParser.hasOption("status")) {
|
if (cliParser.hasOption("status")) {
|
||||||
if (args.length != 2) {
|
if (args.length != 2) {
|
||||||
printUsage(opts);
|
printUsage(opts);
|
||||||
|
|
|
@ -86,6 +86,7 @@ public class TestYarnClient {
|
||||||
client.init(conf);
|
client.init(conf);
|
||||||
client.start();
|
client.start();
|
||||||
client.stop();
|
client.stop();
|
||||||
|
rm.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test (timeout = 30000)
|
@Test (timeout = 30000)
|
||||||
|
|
|
@ -29,6 +29,7 @@ import static org.mockito.Mockito.when;
|
||||||
import static org.mockito.Mockito.doThrow;
|
import static org.mockito.Mockito.doThrow;
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
import java.io.PrintStream;
|
import java.io.PrintStream;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -72,6 +73,7 @@ public class TestYarnCLI {
|
||||||
sysOut = spy(new PrintStream(sysOutStream));
|
sysOut = spy(new PrintStream(sysOutStream));
|
||||||
sysErrStream = new ByteArrayOutputStream();
|
sysErrStream = new ByteArrayOutputStream();
|
||||||
sysErr = spy(new PrintStream(sysErrStream));
|
sysErr = spy(new PrintStream(sysErrStream));
|
||||||
|
System.setOut(sysOut);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -456,21 +458,40 @@ public class TestYarnCLI {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test (timeout = 10000)
|
@Test (timeout = 10000)
|
||||||
public void testHelpCommand() throws Exception {
|
public void testAppsHelpCommand() throws Exception {
|
||||||
ApplicationCLI cli = createAndGetAppCLI();
|
ApplicationCLI cli = createAndGetAppCLI();
|
||||||
ApplicationCLI spyCli = spy(cli);
|
ApplicationCLI spyCli = spy(cli);
|
||||||
int result = spyCli.run(new String[] { "-help" });
|
int result = spyCli.run(new String[] { "-help" });
|
||||||
Assert.assertTrue(result == 0);
|
Assert.assertTrue(result == 0);
|
||||||
verify(spyCli).printUsage(any(Options.class));
|
verify(spyCli).printUsage(any(Options.class));
|
||||||
|
Assert.assertEquals(createApplicationCLIHelpMessage(),
|
||||||
|
sysOutStream.toString());
|
||||||
|
|
||||||
|
sysOutStream.reset();
|
||||||
ApplicationId applicationId = ApplicationId.newInstance(1234, 5);
|
ApplicationId applicationId = ApplicationId.newInstance(1234, 5);
|
||||||
result =
|
result =
|
||||||
cli.run(new String[] { "-kill", applicationId.toString(), "args" });
|
cli.run(new String[] { "-kill", applicationId.toString(), "args" });
|
||||||
verify(spyCli).printUsage(any(Options.class));
|
verify(spyCli).printUsage(any(Options.class));
|
||||||
|
Assert.assertEquals(createApplicationCLIHelpMessage(),
|
||||||
|
sysOutStream.toString());
|
||||||
|
|
||||||
|
sysOutStream.reset();
|
||||||
NodeId nodeId = NodeId.newInstance("host0", 0);
|
NodeId nodeId = NodeId.newInstance("host0", 0);
|
||||||
result = cli.run(new String[] { "-status", nodeId.toString(), "args" });
|
result = cli.run(new String[] { "-status", nodeId.toString(), "args" });
|
||||||
verify(spyCli).printUsage(any(Options.class));
|
verify(spyCli).printUsage(any(Options.class));
|
||||||
|
Assert.assertEquals(createApplicationCLIHelpMessage(),
|
||||||
|
sysOutStream.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test (timeout = 5000)
|
||||||
|
public void testNodesHelpCommand() throws Exception {
|
||||||
|
NodeCLI nodeCLI = new NodeCLI();
|
||||||
|
nodeCLI.setClient(client);
|
||||||
|
nodeCLI.setSysOutPrintStream(sysOut);
|
||||||
|
nodeCLI.setSysErrPrintStream(sysErr);
|
||||||
|
nodeCLI.run(new String[] {});
|
||||||
|
Assert.assertEquals(createNodeCLIHelpMessage(),
|
||||||
|
sysOutStream.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -806,6 +827,25 @@ public class TestYarnCLI {
|
||||||
verifyUsageInfo(new NodeCLI());
|
verifyUsageInfo(new NodeCLI());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMissingArguments() throws Exception {
|
||||||
|
ApplicationCLI cli = createAndGetAppCLI();
|
||||||
|
int result = cli.run(new String[] { "-status" });
|
||||||
|
Assert.assertEquals(result, -1);
|
||||||
|
Assert.assertEquals("Missing argument for options\n"
|
||||||
|
+ createApplicationCLIHelpMessage(), sysOutStream.toString());
|
||||||
|
|
||||||
|
sysOutStream.reset();
|
||||||
|
NodeCLI nodeCLI = new NodeCLI();
|
||||||
|
nodeCLI.setClient(client);
|
||||||
|
nodeCLI.setSysOutPrintStream(sysOut);
|
||||||
|
nodeCLI.setSysErrPrintStream(sysErr);
|
||||||
|
result = nodeCLI.run(new String[] { "-status" });
|
||||||
|
Assert.assertEquals(result, -1);
|
||||||
|
Assert.assertEquals("Missing argument for options\n"
|
||||||
|
+ createNodeCLIHelpMessage(), sysOutStream.toString());
|
||||||
|
}
|
||||||
|
|
||||||
private void verifyUsageInfo(YarnCLI cli) throws Exception {
|
private void verifyUsageInfo(YarnCLI cli) throws Exception {
|
||||||
cli.setSysErrPrintStream(sysErr);
|
cli.setSysErrPrintStream(sysErr);
|
||||||
cli.run(new String[0]);
|
cli.run(new String[0]);
|
||||||
|
@ -832,4 +872,45 @@ public class TestYarnCLI {
|
||||||
return cli;
|
return cli;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String createApplicationCLIHelpMessage() throws IOException {
|
||||||
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
|
PrintWriter pw = new PrintWriter(baos);
|
||||||
|
pw.println("usage: application");
|
||||||
|
pw.println(" -appStates <States> Works with -list to filter applications based");
|
||||||
|
pw.println(" on input comma-separated list of application");
|
||||||
|
pw.println(" states. The valid application state can be one");
|
||||||
|
pw.println(" of the following:");
|
||||||
|
pw.println(" ALL,NEW,NEW_SAVING,SUBMITTED,ACCEPTED,RUNNING,");
|
||||||
|
pw.println(" FINISHED,FAILED,KILLED");
|
||||||
|
pw.println(" -appTypes <Types> Works with -list to filter applications based");
|
||||||
|
pw.println(" on input comma-separated list of application");
|
||||||
|
pw.println(" types.");
|
||||||
|
pw.println(" -help Displays help for all commands.");
|
||||||
|
pw.println(" -kill <Application ID> Kills the application.");
|
||||||
|
pw.println(" -list List applications from the RM. Supports");
|
||||||
|
pw.println(" optional use of -appTypes to filter");
|
||||||
|
pw.println(" applications based on application type, and");
|
||||||
|
pw.println(" -appStates to filter applications based on");
|
||||||
|
pw.println(" application state");
|
||||||
|
pw.println(" -status <Application ID> Prints the status of the application.");
|
||||||
|
pw.close();
|
||||||
|
String appsHelpStr = baos.toString("UTF-8");
|
||||||
|
return appsHelpStr;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String createNodeCLIHelpMessage() throws IOException {
|
||||||
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
|
PrintWriter pw = new PrintWriter(baos);
|
||||||
|
pw.println("usage: node");
|
||||||
|
pw.println(" -all Works with -list to list all nodes.");
|
||||||
|
pw.println(" -list List all running nodes. Supports optional use of");
|
||||||
|
pw.println(" -states to filter nodes based on node state, all -all");
|
||||||
|
pw.println(" to list all nodes.");
|
||||||
|
pw.println(" -states <States> Works with -list to filter nodes based on input");
|
||||||
|
pw.println(" comma-separated list of node states.");
|
||||||
|
pw.println(" -status <NodeId> Prints the status report of the node.");
|
||||||
|
pw.close();
|
||||||
|
String nodesHelpStr = baos.toString("UTF-8");
|
||||||
|
return nodesHelpStr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -198,7 +198,8 @@ public class ConverterUtils {
|
||||||
Iterator<String> it = _split(appIdStr).iterator();
|
Iterator<String> it = _split(appIdStr).iterator();
|
||||||
if (!it.next().equals(APPLICATION_PREFIX)) {
|
if (!it.next().equals(APPLICATION_PREFIX)) {
|
||||||
throw new IllegalArgumentException("Invalid ApplicationId prefix: "
|
throw new IllegalArgumentException("Invalid ApplicationId prefix: "
|
||||||
+ appIdStr);
|
+ appIdStr + ". The valid ApplicationId should start with prefix "
|
||||||
|
+ APPLICATION_PREFIX);
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
return toApplicationId(it);
|
return toApplicationId(it);
|
||||||
|
|
Loading…
Reference in New Issue