diff --git a/hadoop-yarn-project/CHANGES.txt b/hadoop-yarn-project/CHANGES.txt index a4f9874781c..0ceb9057f4a 100644 --- a/hadoop-yarn-project/CHANGES.txt +++ b/hadoop-yarn-project/CHANGES.txt @@ -733,6 +733,9 @@ Release 2.8.0 - UNRELEASED YARN-4524. Cleanup AppSchedulingInfo. (Karthik Kambatla via wangda) + YARN-4371. "yarn application -kill" should take multiple application ids + (Sunil G via jlowe) + OPTIMIZATIONS YARN-3339. TestDockerContainerExecutor should pull a single image and not diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/main/java/org/apache/hadoop/yarn/client/cli/ApplicationCLI.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/main/java/org/apache/hadoop/yarn/client/cli/ApplicationCLI.java index 77e06885d68..caa4d466444 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/main/java/org/apache/hadoop/yarn/client/cli/ApplicationCLI.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/main/java/org/apache/hadoop/yarn/client/cli/ApplicationCLI.java @@ -23,6 +23,7 @@ import java.io.PrintWriter; import java.nio.charset.Charset; import java.text.DecimalFormat; +import java.util.Collection; import java.util.EnumSet; import java.util.HashSet; import java.util.List; @@ -103,7 +104,6 @@ public int run(String[] args) throws Exception { + "Supports optional use of -appTypes to filter applications " + "based on application type, " + "and -appStates to filter applications based on application state."); - opts.addOption(KILL_CMD, true, "Kills the application."); opts.addOption(MOVE_TO_QUEUE_CMD, true, "Moves the application to a " + "different queue."); opts.addOption(QUEUE_CMD, true, "Works with the movetoqueue command to" @@ -127,7 +127,12 @@ public int run(String[] args) throws Exception { opts.addOption(UPDATE_PRIORITY, true, "update priority of an application. ApplicationId can be" + " passed using 'appId' option."); - opts.getOption(KILL_CMD).setArgName("Application ID"); + Option killOpt = new Option(KILL_CMD, true, "Kills the application. " + + "Set of applications can be provided separated with space"); + killOpt.setValueSeparator(' '); + killOpt.setArgs(Option.UNLIMITED_VALUES); + killOpt.setArgName("Application ID"); + opts.addOption(killOpt); opts.getOption(MOVE_TO_QUEUE_CMD).setArgName("Application ID"); opts.getOption(QUEUE_CMD).setArgName("Queue Name"); opts.getOption(STATUS_CMD).setArgName("Application ID"); @@ -239,15 +244,11 @@ public int run(String[] args) throws Exception { listContainers(cliParser.getOptionValue(LIST_CMD)); } } else if (cliParser.hasOption(KILL_CMD)) { - if (args.length != 3) { + if (args.length < 3 || hasAnyOtherCLIOptions(cliParser, opts, KILL_CMD)) { printUsage(title, opts); return exitCode; } - try{ - killApplication(cliParser.getOptionValue(KILL_CMD)); - } catch (ApplicationNotFoundException e) { - return exitCode; - } + return killApplication(cliParser.getOptionValues(KILL_CMD)); } else if (cliParser.hasOption(MOVE_TO_QUEUE_CMD)) { if (!cliParser.hasOption(QUEUE_CMD)) { printUsage(title, opts); @@ -481,6 +482,30 @@ private void listApplications(Set appTypes, writer.flush(); } + /** + * Kills applications with the application id as appId + * + * @param Array of applicationIds + * @return errorCode + * @throws YarnException + * @throws IOException + */ + private int killApplication(String[] applicationIds) throws YarnException, + IOException { + int returnCode = -1; + for (String applicationId : applicationIds) { + try { + killApplication(applicationId); + returnCode = 0; + } catch (ApplicationNotFoundException e) { + // Suppress all ApplicationNotFoundException for now. + continue; + } + } + + return returnCode; + } + /** * Kills the application with the application id as appId * @@ -726,4 +751,20 @@ private void updateApplicationPriority(String applicationId, String priority) + " as application is in final states"); } } + + @SuppressWarnings("unchecked") + private boolean hasAnyOtherCLIOptions(CommandLine cliParser, Options opts, + String excludeOption) { + Collection