commit 2c13288c0d33c3438ccb5c2feff99477290277eb Author: Eric Yang Date: Tue Dec 11 13:13:54 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 ff8142a..be3c7db 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 @@ -335,7 +335,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 " + @@ -584,7 +585,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 8c59a61..a58855c 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 @@ -2314,7 +2314,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 8b00d4c..f7dffc9 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 @@ -267,7 +267,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 225bc19..99a8a66 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 @@ -1178,7 +1178,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 0a2228f..1e0cfda 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 @@ -35,6 +35,7 @@ private final String user; private final String appId; private final Container container; + private String command; private final LocalDirsHandlerService localDirsHandler; /** @@ -44,6 +45,7 @@ private String user; private String appId; private Container container; + private String command; private LocalDirsHandlerService localDirsHandler; public Builder() { @@ -73,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,6 +102,10 @@ 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 b1c389b..2fc1d16 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) {