commit 446b62653b6cd49caee07a3a2f53d778a1d28544 Author: Eric Yang Date: Fri Nov 16 20:19:24 2018 -0500 YARN-9032. Fixed shell parameter passing for interactive shell. Contributed by Eric Yang diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/main/java/org/apache/hadoop/yarn/client/api/impl/YarnClientImpl.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/main/java/org/apache/hadoop/yarn/client/api/impl/YarnClientImpl.java index f920ebb..a7487f6 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/main/java/org/apache/hadoop/yarn/client/api/impl/YarnClientImpl.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/main/java/org/apache/hadoop/yarn/client/api/impl/YarnClientImpl.java @@ -1104,10 +1104,11 @@ public void shellToContainer(ContainerId containerId, } WebSocketClient client = new WebSocketClient(); URI uri = URI.create(protocol + host + ":" + port + "/container/" + - containerId); + containerId + "/" + command); if (!UserGroupInformation.isSecurityEnabled()) { uri = URI.create(protocol + host + ":" + port + "/container/" + - containerId + "?user.name=" + System.getProperty("user.name")); + containerId + "/" + command + "?user.name=" + + System.getProperty("user.name")); } try { client.start(); 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 2b34154..5a1d128 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 @@ -327,7 +327,8 @@ public int run(String[] args) throws Exception { "app version, -components to filter instances based on component " + "names, -states to filter instances based on instance state."); opts.addOption(HELP_CMD, false, "Displays help for all commands."); - opts.getOption(SHELL_CMD).setArgName("Container ID"); + opts.getOption(SHELL_CMD).setArgName("Container ID [bash|sh]"); + opts.getOption(SHELL_CMD).setArgs(3); opts.getOption(STATUS_CMD).setArgName("Container ID"); opts.getOption(LIST_CMD).setArgName("Application Name or Attempt ID"); opts.addOption(APP_TYPE_CMD, true, "Works with -list to " + @@ -567,7 +568,7 @@ public int run(String[] args) throws Exception { ShellContainerCommand command = ShellContainerCommand.BASH; if (shellArgs.length == 2) { - command = ShellContainerCommand.valueOf(shellArgs[1]); + command = ShellContainerCommand.valueOf(shellArgs[1].toUpperCase()); } shellToContainer(containerId, command); } else if (cliParser.hasOption(LAUNCH_CMD)) { diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/test/java/org/apache/hadoop/yarn/client/cli/TestYarnCLI.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/test/java/org/apache/hadoop/yarn/client/cli/TestYarnCLI.java index 672e3d7..c838fd1 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/test/java/org/apache/hadoop/yarn/client/cli/TestYarnCLI.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/test/java/org/apache/hadoop/yarn/client/cli/TestYarnCLI.java @@ -2317,7 +2317,7 @@ private String createContainerCLIHelpMessage() throws IOException { pw.println(" -components Works with -list to filter instances based on input comma-separated list of component names."); pw.println(" -help Displays help for all commands."); pw.println(" -list List containers for application attempt when application attempt ID is provided. When application name is provided, then it finds the instances of the application based on app's own implementation, and -appTypes option must be specified unless it is the default yarn-service type. With app name, it supports optional use of -version to filter instances based on app version, -components to filter instances based on component names, -states to filter instances based on instance state."); - pw.println(" -shell Run a shell in the container."); + pw.println(" -shell Run a shell in the container."); pw.println(" -signal Signal the container."); pw.println("The available signal commands are "); pw.println(java.util.Arrays.asList(SignalContainerCommand.values())); diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/linux/runtime/DefaultLinuxContainerRuntime.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/linux/runtime/DefaultLinuxContainerRuntime.java index 8d46fa4..f55da55 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/linux/runtime/DefaultLinuxContainerRuntime.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/linux/runtime/DefaultLinuxContainerRuntime.java @@ -270,7 +270,10 @@ private String writeCommandToTempFile(ContainerExecContext ctx) cmd.put("user", user); // launch-command = bash,-i List commands = new ArrayList(); - commands.add("/bin/bash"); + StringBuilder sb = new StringBuilder(); + sb.append("/bin/"); + sb.append(ctx.getShell()); + commands.add(sb.toString()); commands.add("-ir"); cmd.put("launch-command", commands); // workdir = ../nm-local-dir/usercache/appcache/appid/containerid diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/linux/runtime/DockerLinuxContainerRuntime.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/linux/runtime/DockerLinuxContainerRuntime.java index 83460fc..87a5227 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/linux/runtime/DockerLinuxContainerRuntime.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/linux/runtime/DockerLinuxContainerRuntime.java @@ -1162,7 +1162,11 @@ public IOStreamPair execContainer(ContainerExecContext ctx) dockerExecCommand.setInteractive(); dockerExecCommand.setTTY(); List command = new ArrayList(); - command.add("bash"); + StringBuilder sb = new StringBuilder(); + sb.append("/bin/"); + sb.append(ctx.getShell()); + command.add(sb.toString()); + command.add("-i"); dockerExecCommand.setOverrideCommandWithArgs(command); String commandFile = dockerClient.writeCommandToTempFile(dockerExecCommand, ContainerId.fromString(containerId), nmContext); diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/executor/ContainerExecContext.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/executor/ContainerExecContext.java index 70b2a7f..1437115 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/executor/ContainerExecContext.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/executor/ContainerExecContext.java @@ -22,7 +22,6 @@ import org.apache.hadoop.classification.InterfaceAudience; import org.apache.hadoop.classification.InterfaceStability; -import org.apache.hadoop.yarn.api.records.ContainerId; import org.apache.hadoop.yarn.server.nodemanager.LocalDirsHandlerService; import org.apache.hadoop.yarn.server.nodemanager.containermanager.container.Container; @@ -36,6 +35,7 @@ private final String user; private final String appId; private final Container container; + private String command; private final LocalDirsHandlerService localDirsHandler; /** @@ -45,6 +45,7 @@ private String user; private String appId; private Container container; + private String command; private LocalDirsHandlerService localDirsHandler; public Builder() { @@ -74,12 +75,18 @@ public Builder setNMLocalPath( this.localDirsHandler = ldhs; return this; } + + public Builder setShell(String command) { + this.command = command; + return this; + } } private ContainerExecContext(Builder builder) { - this.container = builder.container; this.user = builder.user; this.appId = builder.appId; + this.container = builder.container; + this.command = builder.command; this.localDirsHandler = builder.localDirsHandler; } @@ -94,8 +101,13 @@ public String getAppId() { public Container getContainer() { return this.container; } - + + public String getShell() { + return this.command; + } + public LocalDirsHandlerService getLocalDirsHandlerService() { return this.localDirsHandler; } + } diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/webapp/ContainerShellWebSocket.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/webapp/ContainerShellWebSocket.java index 21fb782..d8a602e 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/webapp/ContainerShellWebSocket.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/webapp/ContainerShellWebSocket.java @@ -27,6 +27,7 @@ import org.apache.hadoop.classification.InterfaceAudience; import org.apache.hadoop.classification.InterfaceStability; import org.apache.hadoop.yarn.api.records.ContainerId; +import org.apache.hadoop.yarn.api.records.ShellContainerCommand; import org.apache.hadoop.yarn.server.nodemanager.Context; import org.apache.hadoop.yarn.server.nodemanager.ContainerExecutor; import org.apache.hadoop.yarn.server.nodemanager.containermanager.container.Container; @@ -98,8 +99,16 @@ public void onText(Session session, String message) throws IOException { public void onConnect(Session session) { try { URI containerURI = session.getUpgradeRequest().getRequestURI(); + String command = "bash"; String[] containerPath = containerURI.getPath().split("/"); String cId = containerPath[2]; + if (containerPath.length==4) { + for (ShellContainerCommand c : ShellContainerCommand.values()) { + if (c.name().equalsIgnoreCase(containerPath[3])) { + command = containerPath[3].toLowerCase(); + } + } + } Container container = nmContext.getContainers().get(ContainerId .fromString(cId)); if (!checkAuthorization(session, container)) { @@ -113,6 +122,7 @@ public void onConnect(Session session) { .Builder() .setContainer(container) .setNMLocalPath(nmContext.getLocalDirsHandler()) + .setShell(command) .build(); pair = exec.execContainer(execContext); } catch (Exception e) {