YARN-9032. Support sh shell for interactive container shell at command line. Contributed by Eric Yang
Project: http://git-wip-us.apache.org/repos/asf/hadoop/repo Commit: http://git-wip-us.apache.org/repos/asf/hadoop/commit/ca90b248 Tree: http://git-wip-us.apache.org/repos/asf/hadoop/tree/ca90b248 Diff: http://git-wip-us.apache.org/repos/asf/hadoop/diff/ca90b248 Branch: refs/heads/HDFS-13891 Commit: ca90b2480ecb9a627914e7a463b6293024ad6e4d Parents: 00d5e63 Author: Billie Rinaldi <[email protected]> Authored: Fri Dec 14 14:08:22 2018 -0800 Committer: Billie Rinaldi <[email protected]> Committed: Fri Dec 14 14:08:22 2018 -0800 ---------------------------------------------------------------------- .../hadoop/yarn/client/api/impl/YarnClientImpl.java | 5 +++-- .../apache/hadoop/yarn/client/cli/ApplicationCLI.java | 5 +++-- .../apache/hadoop/yarn/client/cli/TestYarnCLI.java | 2 +- .../linux/runtime/DefaultLinuxContainerRuntime.java | 5 ++++- .../linux/runtime/DockerLinuxContainerRuntime.java | 6 +++++- .../nodemanager/executor/ContainerExecContext.java | 14 +++++++++++++- .../nodemanager/webapp/ContainerShellWebSocket.java | 10 ++++++++++ 7 files changed, 39 insertions(+), 8 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/hadoop/blob/ca90b248/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/main/java/org/apache/hadoop/yarn/client/api/impl/YarnClientImpl.java ---------------------------------------------------------------------- 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 class YarnClientImpl extends YarnClient { } 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(); http://git-wip-us.apache.org/repos/asf/hadoop/blob/ca90b248/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/main/java/org/apache/hadoop/yarn/client/cli/ApplicationCLI.java ---------------------------------------------------------------------- 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 class ApplicationCLI extends YarnCLI { "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 class ApplicationCLI extends YarnCLI { 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)) { http://git-wip-us.apache.org/repos/asf/hadoop/blob/ca90b248/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/test/java/org/apache/hadoop/yarn/client/cli/TestYarnCLI.java ---------------------------------------------------------------------- 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 @@ public class TestYarnCLI { pw.println(" -components <arg> 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 <Application Name or Attempt ID> 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 <Container ID> Run a shell in the container."); + pw.println(" -shell <Container ID [bash|sh]> Run a shell in the container."); pw.println(" -signal <container ID [signal command]> Signal the container."); pw.println("The available signal commands are "); pw.println(java.util.Arrays.asList(SignalContainerCommand.values())); http://git-wip-us.apache.org/repos/asf/hadoop/blob/ca90b248/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 ---------------------------------------------------------------------- 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 @@ public class DefaultLinuxContainerRuntime implements LinuxContainerRuntime { cmd.put("user", user); // launch-command = bash,-i List<String> commands = new ArrayList<String>(); - 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 http://git-wip-us.apache.org/repos/asf/hadoop/blob/ca90b248/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 ---------------------------------------------------------------------- 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 class DockerLinuxContainerRuntime implements LinuxContainerRuntime { dockerExecCommand.setInteractive(); dockerExecCommand.setTTY(); List<String> command = new ArrayList<String>(); - 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); http://git-wip-us.apache.org/repos/asf/hadoop/blob/ca90b248/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/executor/ContainerExecContext.java ---------------------------------------------------------------------- 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 @@ public final class ContainerExecContext { private final String user; private final String appId; private final Container container; + private String command; private final LocalDirsHandlerService localDirsHandler; /** @@ -44,6 +45,7 @@ public final class ContainerExecContext { private String user; private String appId; private Container container; + private String command; private LocalDirsHandlerService localDirsHandler; public Builder() { @@ -73,12 +75,18 @@ public final class ContainerExecContext { 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 final class ContainerExecContext { return this.container; } + public String getShell() { + return this.command; + } + public LocalDirsHandlerService getLocalDirsHandlerService() { return this.localDirsHandler; } http://git-wip-us.apache.org/repos/asf/hadoop/blob/ca90b248/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/webapp/ContainerShellWebSocket.java ---------------------------------------------------------------------- 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 java.util.Map; 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 class ContainerShellWebSocket { 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 class ContainerShellWebSocket { .Builder() .setContainer(container) .setNMLocalPath(nmContext.getLocalDirsHandler()) + .setShell(command) .build(); pair = exec.execContainer(execContext); } catch (Exception e) { --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
