YARN-8776. Implement Container Exec feature in LinuxContainerExecutor. Contributed by Eric Yang
This commit is contained in:
parent
18fe65d756
commit
1f9c4f32e8
@ -38,7 +38,6 @@
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
|
||||
|
||||
import org.apache.hadoop.hdfs.protocol.datatransfer.IOStreamPair;
|
||||
import org.apache.hadoop.yarn.server.nodemanager.executor.ContainerExecContext;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@ -59,6 +58,7 @@
|
||||
import org.apache.hadoop.yarn.server.nodemanager.containermanager.runtime.ContainerExecutionException;
|
||||
import org.apache.hadoop.yarn.server.nodemanager.executor.ContainerPrepareContext;
|
||||
import org.apache.hadoop.yarn.server.nodemanager.util.NodeManagerHardwareUtils;
|
||||
import org.apache.hadoop.yarn.server.nodemanager.executor.ContainerExecContext;
|
||||
import org.apache.hadoop.yarn.server.nodemanager.executor.ContainerLivenessContext;
|
||||
import org.apache.hadoop.yarn.server.nodemanager.executor.ContainerReacquisitionContext;
|
||||
import org.apache.hadoop.yarn.server.nodemanager.executor.ContainerReapContext;
|
||||
|
@ -62,15 +62,10 @@
|
||||
import org.apache.hadoop.yarn.server.nodemanager.util.CgroupsLCEResourcesHandler;
|
||||
import org.apache.hadoop.yarn.server.nodemanager.util.DefaultLCEResourcesHandler;
|
||||
import org.apache.hadoop.yarn.server.nodemanager.util.LCEResourcesHandler;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
@ -801,20 +796,22 @@ public boolean reapContainer(ContainerReapContext ctx) throws IOException {
|
||||
@Override
|
||||
public IOStreamPair execContainer(ContainerExecContext ctx)
|
||||
throws ContainerExecutionException {
|
||||
// TODO: calls PrivilegedOperationExecutor and return IOStream pairs
|
||||
InputStream in = null;
|
||||
OutputStream out = null;
|
||||
int byteSize = 4000;
|
||||
IOStreamPair res;
|
||||
try {
|
||||
in = new ByteArrayInputStream(
|
||||
"This is input command".getBytes(Charset.forName("UTF-8")));
|
||||
out = new ByteArrayOutputStream(byteSize);
|
||||
} catch (IllegalArgumentException e) {
|
||||
LOG.error("Failed to execute command to container runtime", e);
|
||||
res = linuxContainerRuntime.execContainer(ctx);
|
||||
} catch (ContainerExecutionException e) {
|
||||
int retCode = e.getExitCode();
|
||||
if (retCode != 0) {
|
||||
return new IOStreamPair(null, null);
|
||||
}
|
||||
LOG.warn("Error in executing container interactive shell"
|
||||
+ ctx + " exit = " + retCode, e);
|
||||
logOutput(e.getOutput());
|
||||
throw new ContainerExecutionException(
|
||||
"Error in executing container interactive shel" + ctx.getContainer()
|
||||
.getContainerId().toString() + " exit = " + retCode);
|
||||
}
|
||||
IOStreamPair pair = new IOStreamPair(in, out);
|
||||
System.out.println(pair);
|
||||
return new IOStreamPair(in, out);
|
||||
return res;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -44,6 +44,7 @@ public enum OperationType {
|
||||
INITIALIZE_CONTAINER(""), //no CLI switch supported yet
|
||||
LAUNCH_CONTAINER(""), //no CLI switch supported yet
|
||||
SIGNAL_CONTAINER(""), //no CLI switch supported yet
|
||||
EXEC_CONTAINER("--run-docker"), //no CLI switch supported yet
|
||||
DELETE_AS_USER(""), //no CLI switch supported yet
|
||||
LAUNCH_DOCKER_CONTAINER(""), //no CLI switch supported yet
|
||||
TC_MODIFY_STATE("--tc-modify-state"),
|
||||
|
@ -20,8 +20,8 @@
|
||||
|
||||
package org.apache.hadoop.yarn.server.nodemanager.containermanager.linux.privileged;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.hadoop.hdfs.protocol.datatransfer.IOStreamPair;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.apache.hadoop.classification.InterfaceAudience;
|
||||
@ -34,6 +34,8 @@
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
@ -207,6 +209,59 @@ public String executePrivilegedOperation(PrivilegedOperation operation,
|
||||
false);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param prefixCommands
|
||||
* @param operation
|
||||
* @return stdin and stdout of container exec
|
||||
* @throws PrivilegedOperationException
|
||||
*/
|
||||
public IOStreamPair executePrivilegedInteractiveOperation(
|
||||
List<String> prefixCommands, PrivilegedOperation operation)
|
||||
throws PrivilegedOperationException, InterruptedException {
|
||||
String[] fullCommandArray = getPrivilegedOperationExecutionCommand(
|
||||
prefixCommands, operation);
|
||||
ProcessBuilder pb = new ProcessBuilder(fullCommandArray);
|
||||
OutputStream stdin;
|
||||
InputStream stdout;
|
||||
try {
|
||||
pb.redirectErrorStream(true);
|
||||
Process p = pb.start();
|
||||
stdin = p.getOutputStream();
|
||||
stdout = p.getInputStream();
|
||||
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("command array:");
|
||||
LOG.debug(Arrays.toString(fullCommandArray));
|
||||
}
|
||||
} catch (ExitCodeException e) {
|
||||
if (operation.isFailureLoggingEnabled()) {
|
||||
StringBuilder logBuilder = new StringBuilder(
|
||||
"Interactive Shell execution returned exit code: ")
|
||||
.append(e.getExitCode())
|
||||
.append(". Privileged Interactive Operation Stderr: ")
|
||||
.append(System.lineSeparator())
|
||||
.append(e.getMessage())
|
||||
.append(System.lineSeparator());
|
||||
logBuilder.append("Full command array for failed execution: ")
|
||||
.append(System.lineSeparator());
|
||||
logBuilder.append(Arrays.toString(fullCommandArray));
|
||||
|
||||
LOG.warn(logBuilder.toString());
|
||||
}
|
||||
|
||||
//stderr from shell executor seems to be stuffed into the exception
|
||||
//'message' - so, we have to extract it and set it as the error out
|
||||
throw new PrivilegedOperationException(e, e.getExitCode(),
|
||||
pb.redirectError().toString(), e.getMessage());
|
||||
} catch (IOException e) {
|
||||
LOG.warn("IOException executing command: ", e);
|
||||
throw new PrivilegedOperationException(e);
|
||||
}
|
||||
|
||||
return new IOStreamPair(stdout, stdin);
|
||||
}
|
||||
|
||||
//Utility functions for squashing together operations in supported ways
|
||||
//At some point, we need to create a generalized mechanism that uses a set
|
||||
//of squashing 'rules' to squash an set of PrivilegedOperations of varying
|
||||
|
@ -24,6 +24,7 @@
|
||||
import org.apache.hadoop.classification.InterfaceStability;
|
||||
import org.apache.hadoop.conf.Configuration;
|
||||
import org.apache.hadoop.fs.Path;
|
||||
import org.apache.hadoop.hdfs.protocol.datatransfer.IOStreamPair;
|
||||
import org.apache.hadoop.util.StringUtils;
|
||||
import org.apache.hadoop.yarn.conf.YarnConfiguration;
|
||||
import org.apache.hadoop.yarn.server.nodemanager.ContainerExecutor;
|
||||
@ -36,6 +37,7 @@
|
||||
import org.apache.hadoop.yarn.server.nodemanager.containermanager.runtime.ContainerRuntime;
|
||||
import org.apache.hadoop.yarn.server.nodemanager.containermanager.runtime.ContainerRuntimeConstants;
|
||||
import org.apache.hadoop.yarn.server.nodemanager.containermanager.runtime.ContainerRuntimeContext;
|
||||
import org.apache.hadoop.yarn.server.nodemanager.executor.ContainerExecContext;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@ -194,4 +196,10 @@ public void reapContainer(ContainerRuntimeContext ctx)
|
||||
public String[] getIpAndHost(Container container) {
|
||||
return ContainerExecutor.getLocalIpAndHost(container);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IOStreamPair execContainer(ContainerExecContext containerExecContext)
|
||||
throws ContainerExecutionException {
|
||||
throw new ContainerExecutionException("Unsupported operation.");
|
||||
}
|
||||
}
|
||||
|
@ -24,6 +24,7 @@
|
||||
import org.apache.hadoop.classification.InterfaceAudience;
|
||||
import org.apache.hadoop.classification.InterfaceStability;
|
||||
import org.apache.hadoop.conf.Configuration;
|
||||
import org.apache.hadoop.hdfs.protocol.datatransfer.IOStreamPair;
|
||||
import org.apache.hadoop.util.ReflectionUtils;
|
||||
import org.apache.hadoop.yarn.conf.YarnConfiguration;
|
||||
import org.apache.hadoop.yarn.server.nodemanager.Context;
|
||||
@ -32,6 +33,7 @@
|
||||
import org.apache.hadoop.yarn.server.nodemanager.containermanager.runtime.ContainerExecutionException;
|
||||
import org.apache.hadoop.yarn.server.nodemanager.containermanager.runtime.ContainerRuntime;
|
||||
import org.apache.hadoop.yarn.server.nodemanager.containermanager.runtime.ContainerRuntimeContext;
|
||||
import org.apache.hadoop.yarn.server.nodemanager.executor.ContainerExecContext;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@ -229,4 +231,12 @@ boolean isRuntimeAllowed(String runtimeType) {
|
||||
return runtimeType != null && allowedRuntimes.contains(
|
||||
runtimeType.toUpperCase());
|
||||
}
|
||||
|
||||
@Override
|
||||
public IOStreamPair execContainer(ContainerExecContext ctx)
|
||||
throws ContainerExecutionException {
|
||||
Container container = ctx.getContainer();
|
||||
LinuxContainerRuntime runtime = pickContainerRuntime(container);
|
||||
return runtime.execContainer(ctx);
|
||||
}
|
||||
}
|
@ -21,12 +21,14 @@
|
||||
package org.apache.hadoop.yarn.server.nodemanager.containermanager.linux.runtime;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import org.apache.hadoop.hdfs.protocol.datatransfer.IOStreamPair;
|
||||
import org.apache.hadoop.security.Credentials;
|
||||
import org.apache.hadoop.yarn.api.ApplicationConstants.Environment;
|
||||
import org.apache.hadoop.yarn.api.records.ContainerId;
|
||||
import org.apache.hadoop.yarn.server.nodemanager.Context;
|
||||
import org.apache.hadoop.yarn.server.nodemanager.containermanager.linux.runtime.docker.DockerCommand;
|
||||
import org.apache.hadoop.yarn.server.nodemanager.containermanager.linux.runtime.docker.DockerCommandExecutor;
|
||||
import org.apache.hadoop.yarn.server.nodemanager.containermanager.linux.runtime.docker.DockerExecCommand;
|
||||
import org.apache.hadoop.yarn.server.nodemanager.containermanager.linux.runtime.docker.DockerKillCommand;
|
||||
import org.apache.hadoop.yarn.server.nodemanager.containermanager.linux.runtime.docker.DockerRmCommand;
|
||||
import org.apache.hadoop.yarn.server.nodemanager.containermanager.linux.runtime.docker.DockerStartCommand;
|
||||
@ -62,6 +64,7 @@
|
||||
import org.apache.hadoop.yarn.server.nodemanager.containermanager.runtime.ContainerRuntime;
|
||||
import org.apache.hadoop.yarn.server.nodemanager.containermanager.runtime.ContainerRuntimeConstants;
|
||||
import org.apache.hadoop.yarn.server.nodemanager.containermanager.runtime.ContainerRuntimeContext;
|
||||
import org.apache.hadoop.yarn.server.nodemanager.executor.ContainerExecContext;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
@ -1144,6 +1147,48 @@ public void reapContainer(ContainerRuntimeContext ctx)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform docker exec command into running container
|
||||
*
|
||||
* @param ctx container exec context
|
||||
* @return IOStreams of docker exec
|
||||
* @throws ContainerExecutionException
|
||||
*/
|
||||
@Override
|
||||
public IOStreamPair execContainer(ContainerExecContext ctx)
|
||||
throws ContainerExecutionException {
|
||||
String containerId = ctx.getContainer().getContainerId().toString();
|
||||
DockerExecCommand dockerExecCommand = new DockerExecCommand(containerId);
|
||||
dockerExecCommand.setInteractive();
|
||||
dockerExecCommand.setTTY();
|
||||
List<String> command = new ArrayList<String>();
|
||||
command.add("bash");
|
||||
dockerExecCommand.setOverrideCommandWithArgs(command);
|
||||
String commandFile = dockerClient.writeCommandToTempFile(dockerExecCommand,
|
||||
ContainerId.fromString(containerId), nmContext);
|
||||
PrivilegedOperation privOp = new PrivilegedOperation(
|
||||
PrivilegedOperation.OperationType.EXEC_CONTAINER);
|
||||
privOp.appendArgs(commandFile);
|
||||
privOp.disableFailureLogging();
|
||||
|
||||
IOStreamPair output;
|
||||
try {
|
||||
output =
|
||||
privilegedOperationExecutor.executePrivilegedInteractiveOperation(
|
||||
null, privOp);
|
||||
LOG.info("ContainerId=" + containerId + ", docker exec output for "
|
||||
+ dockerExecCommand + ": " + output);
|
||||
} catch (PrivilegedOperationException e) {
|
||||
throw new ContainerExecutionException(
|
||||
"Execute container interactive shell failed", e.getExitCode(),
|
||||
e.getOutput(), e.getErrorOutput());
|
||||
} catch (InterruptedException ie) {
|
||||
LOG.warn("InterruptedException executing command: ", ie);
|
||||
throw new ContainerExecutionException(ie.getMessage());
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
|
||||
// ipAndHost[0] contains comma separated list of IPs
|
||||
// ipAndHost[1] contains the hostname.
|
||||
|
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hadoop.yarn.server.nodemanager.containermanager.linux.runtime.docker;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Encapsulates the docker exec command and its command
|
||||
* line arguments.
|
||||
*/
|
||||
public class DockerExecCommand extends DockerCommand {
|
||||
private static final String EXEC_COMMAND = "exec";
|
||||
private final Map<String, String> userEnv;
|
||||
|
||||
public DockerExecCommand(String containerId) {
|
||||
super(EXEC_COMMAND);
|
||||
super.addCommandArguments("name", containerId);
|
||||
this.userEnv = new LinkedHashMap<String, String>();
|
||||
}
|
||||
|
||||
public DockerExecCommand setInteractive() {
|
||||
super.addCommandArguments("interactive", "true");
|
||||
return this;
|
||||
}
|
||||
|
||||
public DockerExecCommand setTTY() {
|
||||
super.addCommandArguments("tty", "true");
|
||||
return this;
|
||||
}
|
||||
|
||||
public DockerExecCommand setOverrideCommandWithArgs(
|
||||
List<String> overrideCommandWithArgs) {
|
||||
for(String override: overrideCommandWithArgs) {
|
||||
super.addCommandArguments("launch-command", override);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, List<String>> getDockerCommandWithArguments() {
|
||||
return super.getDockerCommandWithArguments();
|
||||
}
|
||||
|
||||
}
|
@ -22,7 +22,9 @@
|
||||
|
||||
import org.apache.hadoop.classification.InterfaceAudience;
|
||||
import org.apache.hadoop.classification.InterfaceStability;
|
||||
import org.apache.hadoop.hdfs.protocol.datatransfer.IOStreamPair;
|
||||
import org.apache.hadoop.yarn.server.nodemanager.containermanager.container.Container;
|
||||
import org.apache.hadoop.yarn.server.nodemanager.executor.ContainerExecContext;
|
||||
|
||||
/**
|
||||
* An abstraction for various container runtime implementations. Examples
|
||||
@ -86,7 +88,17 @@ void reapContainer(ContainerRuntimeContext ctx)
|
||||
throws ContainerExecutionException;
|
||||
|
||||
/**
|
||||
* Return the host and ip of the container
|
||||
* Run a program in container.
|
||||
*
|
||||
* @param ctx the {@link ContainerExecContext}
|
||||
* @return stdin and stdout of container exec
|
||||
* @throws ContainerExecutionException
|
||||
*/
|
||||
IOStreamPair execContainer(ContainerExecContext ctx)
|
||||
throws ContainerExecutionException;
|
||||
|
||||
/**
|
||||
* Return the host and ip of the container.
|
||||
*
|
||||
* @param container the {@link Container}
|
||||
* @throws ContainerExecutionException if an error occurs while getting the ip
|
||||
|
@ -22,6 +22,7 @@
|
||||
|
||||
import org.apache.hadoop.classification.InterfaceAudience;
|
||||
import org.apache.hadoop.classification.InterfaceStability;
|
||||
import org.apache.hadoop.yarn.server.nodemanager.containermanager.container.Container;
|
||||
|
||||
/**
|
||||
* Encapsulates information required for starting/launching containers.
|
||||
@ -32,7 +33,7 @@
|
||||
public final class ContainerExecContext {
|
||||
private final String user;
|
||||
private final String appId;
|
||||
private final String container;
|
||||
private final Container container;
|
||||
|
||||
/**
|
||||
* Builder for ContainerExecContext.
|
||||
@ -40,13 +41,13 @@ public final class ContainerExecContext {
|
||||
public static final class Builder {
|
||||
private String user;
|
||||
private String appId;
|
||||
private String container;
|
||||
private Container container;
|
||||
|
||||
public Builder() {
|
||||
}
|
||||
|
||||
public Builder setContainer(String container) {
|
||||
this.container = container;
|
||||
public Builder setContainer(Container c) {
|
||||
this.container = c;
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -79,7 +80,7 @@ public String getAppId() {
|
||||
return this.appId;
|
||||
}
|
||||
|
||||
public String getContainerId() {
|
||||
public Container getContainer() {
|
||||
return this.container;
|
||||
}
|
||||
}
|
||||
|
@ -24,8 +24,10 @@
|
||||
|
||||
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.Context;
|
||||
import org.apache.hadoop.yarn.server.nodemanager.ContainerExecutor;
|
||||
import org.apache.hadoop.yarn.server.nodemanager.LinuxContainerExecutor;
|
||||
import org.apache.hadoop.yarn.server.nodemanager.containermanager.container.Container;
|
||||
import org.apache.hadoop.yarn.server.nodemanager.executor.ContainerExecContext;
|
||||
import org.eclipse.jetty.websocket.api.Session;
|
||||
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketClose;
|
||||
@ -47,31 +49,43 @@
|
||||
public class ContainerShellWebSocket {
|
||||
private static final Logger LOG =
|
||||
LoggerFactory.getLogger(ContainerShellWebSocket.class);
|
||||
private static Context nmContext;
|
||||
|
||||
private final ContainerExecutor exec = new LinuxContainerExecutor();
|
||||
|
||||
private final ContainerExecutor exec;
|
||||
private IOStreamPair pair;
|
||||
|
||||
public ContainerShellWebSocket() {
|
||||
exec = nmContext.getContainerExecutor();
|
||||
}
|
||||
|
||||
public static void init(Context nm) {
|
||||
ContainerShellWebSocket.nmContext = nm;
|
||||
}
|
||||
|
||||
@OnWebSocketMessage
|
||||
public void onText(Session session, String message) throws IOException {
|
||||
LOG.info("Message received: " + message);
|
||||
|
||||
try {
|
||||
byte[] buffer = new byte[4000];
|
||||
if (session.isOpen()) {
|
||||
int ni = message.length();
|
||||
if (ni > 0) {
|
||||
pair.out.write(message.getBytes(Charset.forName("UTF-8")));
|
||||
pair.out.flush();
|
||||
if (!message.equals("1{}")) {
|
||||
// Send keystroke to process input
|
||||
byte[] payload;
|
||||
payload = message.getBytes(Charset.forName("UTF-8"));
|
||||
if (payload != null) {
|
||||
pair.out.write(payload);
|
||||
pair.out.flush();
|
||||
}
|
||||
}
|
||||
// Render process output
|
||||
int no = pair.in.available();
|
||||
pair.in.read(buffer, 0, Math.min(no, buffer.length));
|
||||
String formatted = new String(buffer, Charset.forName("UTF-8"))
|
||||
.replaceAll("\n", "\r\n");
|
||||
session.getRemote().sendString(formatted);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOG.error("Failed to parse WebSocket message from Client", e);
|
||||
} catch (IOException e) {
|
||||
onClose(session, 1001, "Shutdown");
|
||||
}
|
||||
|
||||
}
|
||||
@ -84,12 +98,14 @@ public void onConnect(Session session) {
|
||||
URI containerURI = session.getUpgradeRequest().getRequestURI();
|
||||
String[] containerPath = containerURI.getPath().split("/");
|
||||
String cId = containerPath[2];
|
||||
Container container = nmContext.getContainers().get(ContainerId
|
||||
.fromString(cId));
|
||||
LOG.info(
|
||||
"Making interactive connection to running docker container with ID: "
|
||||
+ cId);
|
||||
ContainerExecContext execContext = new ContainerExecContext
|
||||
.Builder()
|
||||
.setContainer(cId)
|
||||
.setContainer(container)
|
||||
.build();
|
||||
pair = exec.execContainer(execContext);
|
||||
} catch (Exception e) {
|
||||
@ -100,7 +116,14 @@ public void onConnect(Session session) {
|
||||
|
||||
@OnWebSocketClose
|
||||
public void onClose(Session session, int status, String reason) {
|
||||
LOG.info(session.getRemoteAddress().getHostString() + " closed!");
|
||||
try {
|
||||
LOG.info(session.getRemoteAddress().getHostString() + " closed!");
|
||||
pair.in.close();
|
||||
pair.out.close();
|
||||
} catch (IOException e) {
|
||||
} finally {
|
||||
session.close();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -99,6 +99,7 @@ protected void serviceStart() throws Exception {
|
||||
targets.add(AuthenticationFilterInitializer.class.getName());
|
||||
conf.set(filterInitializerConfKey, StringUtils.join(",", targets));
|
||||
}
|
||||
ContainerShellWebSocket.init(nmContext);
|
||||
LOG.info("Instantiating NMWebApp at " + bindAddress);
|
||||
try {
|
||||
this.webApp =
|
||||
|
@ -1485,8 +1485,13 @@ int run_docker_with_pty(const char *command_file) {
|
||||
}
|
||||
} else {
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "Error %d on read master PTY\n", errno);
|
||||
exit(DOCKER_EXEC_FAILED);
|
||||
if (errno==5) {
|
||||
fprintf(stderr, "Remote Connection Closed.\n");
|
||||
exit(0);
|
||||
} else {
|
||||
fprintf(stderr, "Error %d on read master PTY\n", errno);
|
||||
exit(DOCKER_EXEC_FAILED);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -181,9 +181,10 @@ public void testReapContainer() throws Exception {
|
||||
|
||||
@Test
|
||||
public void testExecContainer() throws Exception {
|
||||
Container container = mock(Container.class);
|
||||
try {
|
||||
ContainerExecContext.Builder builder = new ContainerExecContext.Builder();
|
||||
builder.setUser("foo").setAppId("app1").setContainer("container1");
|
||||
builder.setUser("foo").setAppId("app1").setContainer(container);
|
||||
ContainerExecContext ctx = builder.build();
|
||||
containerExecutor.execContainer(ctx);
|
||||
} catch (Exception e) {
|
||||
|
@ -44,7 +44,6 @@
|
||||
import java.io.PrintWriter;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
@ -697,10 +696,11 @@ public void testRelaunchContainer() throws Exception {
|
||||
|
||||
@Test
|
||||
public void testExecContainer() throws Exception {
|
||||
Container container = mock(Container.class);
|
||||
LinuxContainerExecutor lce = mock(LinuxContainerExecutor.class);
|
||||
ContainerExecContext.Builder builder =
|
||||
new ContainerExecContext.Builder();
|
||||
builder.setUser("foo").setAppId("app1").setContainer("container1");
|
||||
builder.setUser("foo").setAppId("app1").setContainer(container);
|
||||
ContainerExecContext ctx = builder.build();
|
||||
lce.execContainer(ctx);
|
||||
verify(lce, times(1)).execContainer(ctx);
|
||||
|
@ -17,10 +17,13 @@
|
||||
package org.apache.hadoop.yarn.server.nodemanager.containermanager.linux.runtime;
|
||||
|
||||
import org.apache.hadoop.conf.Configuration;
|
||||
import org.apache.hadoop.hdfs.protocol.datatransfer.IOStreamPair;
|
||||
import org.apache.hadoop.yarn.server.nodemanager.Context;
|
||||
import org.apache.hadoop.yarn.server.nodemanager.containermanager.container.Container;
|
||||
import org.apache.hadoop.yarn.server.nodemanager.containermanager.runtime.ContainerExecutionException;
|
||||
import org.apache.hadoop.yarn.server.nodemanager.containermanager.runtime.ContainerRuntimeConstants;
|
||||
import org.apache.hadoop.yarn.server.nodemanager.containermanager.runtime.ContainerRuntimeContext;
|
||||
import org.apache.hadoop.yarn.server.nodemanager.executor.ContainerExecContext;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@ -58,4 +61,10 @@ public void reapContainer(ContainerRuntimeContext ctx) {}
|
||||
public String[] getIpAndHost(Container container) {
|
||||
return new String[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public IOStreamPair execContainer(ContainerExecContext ctx)
|
||||
throws ContainerExecutionException {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -103,11 +103,13 @@ public boolean reapContainer(ContainerReapContext ctx)
|
||||
throws IOException {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IOStreamPair execContainer(ContainerExecContext ctx)
|
||||
throws ContainerExecutionException {
|
||||
return new IOStreamPair(null, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteAsUser(DeletionAsUserContext ctx)
|
||||
throws IOException, InterruptedException {
|
||||
|
Loading…
Reference in New Issue
Block a user