YARN-8638. Allow linux container runtimes to be pluggable. Contributed by Craig Condit

(cherry picked from commit dffb7bfe6c)
This commit is contained in:
Shane Kumpf 2018-09-05 06:47:54 -06:00
parent fde3b5ac22
commit 2d68708a1d
8 changed files with 225 additions and 45 deletions

View File

@ -1826,7 +1826,7 @@ public class YarnConfiguration extends Configuration {
/** /**
* Comma separated list of runtimes that are allowed when using * Comma separated list of runtimes that are allowed when using
* LinuxContainerExecutor. The allowed values are: * LinuxContainerExecutor. The standard values are:
* <ul> * <ul>
* <li>default</li> * <li>default</li>
* <li>docker</li> * <li>docker</li>
@ -1836,6 +1836,9 @@ public class YarnConfiguration extends Configuration {
public static final String LINUX_CONTAINER_RUNTIME_ALLOWED_RUNTIMES = public static final String LINUX_CONTAINER_RUNTIME_ALLOWED_RUNTIMES =
LINUX_CONTAINER_RUNTIME_PREFIX + "allowed-runtimes"; LINUX_CONTAINER_RUNTIME_PREFIX + "allowed-runtimes";
public static final String LINUX_CONTAINER_RUNTIME_CLASS_FMT =
LINUX_CONTAINER_RUNTIME_PREFIX + "%s.class";
/** The default list of allowed runtimes when using LinuxContainerExecutor. */ /** The default list of allowed runtimes when using LinuxContainerExecutor. */
public static final String[] DEFAULT_LINUX_CONTAINER_RUNTIME_ALLOWED_RUNTIMES public static final String[] DEFAULT_LINUX_CONTAINER_RUNTIME_ALLOWED_RUNTIMES
= {"default"}; = {"default"};

View File

@ -32,11 +32,13 @@ import org.apache.hadoop.yarn.server.nodemanager.containermanager.linux.privileg
import org.apache.hadoop.yarn.server.nodemanager.containermanager.linux.privileged.PrivilegedOperationExecutor; import org.apache.hadoop.yarn.server.nodemanager.containermanager.linux.privileged.PrivilegedOperationExecutor;
import org.apache.hadoop.yarn.server.nodemanager.containermanager.runtime.ContainerExecutionException; 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.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.containermanager.runtime.ContainerRuntimeContext;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import java.util.List; import java.util.List;
import java.util.Map;
import static org.apache.hadoop.yarn.server.nodemanager.containermanager.linux.runtime.LinuxContainerRuntimeConstants.*; import static org.apache.hadoop.yarn.server.nodemanager.containermanager.linux.runtime.LinuxContainerRuntimeConstants.*;
@ -66,6 +68,12 @@ public class DefaultLinuxContainerRuntime implements LinuxContainerRuntime {
this.privilegedOperationExecutor = privilegedOperationExecutor; this.privilegedOperationExecutor = privilegedOperationExecutor;
} }
@Override
public boolean isRuntimeRequested(Map<String, String> env) {
String type = env.get(ContainerRuntimeConstants.ENV_CONTAINER_TYPE);
return type == null || type.equals("default");
}
@Override @Override
public void initialize(Configuration conf, Context nmContext) public void initialize(Configuration conf, Context nmContext)
throws ContainerExecutionException { throws ContainerExecutionException {

View File

@ -24,6 +24,7 @@ import com.google.common.annotations.VisibleForTesting;
import org.apache.hadoop.classification.InterfaceAudience; import org.apache.hadoop.classification.InterfaceAudience;
import org.apache.hadoop.classification.InterfaceStability; import org.apache.hadoop.classification.InterfaceStability;
import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.util.ReflectionUtils;
import org.apache.hadoop.yarn.conf.YarnConfiguration; import org.apache.hadoop.yarn.conf.YarnConfiguration;
import org.apache.hadoop.yarn.server.nodemanager.Context; 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.container.Container;
@ -34,28 +35,32 @@ import org.apache.hadoop.yarn.server.nodemanager.containermanager.runtime.Contai
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import java.util.EnumSet; import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
/** /**
* This class is a {@link ContainerRuntime} implementation that delegates all * This class is a {@link ContainerRuntime} implementation that delegates all
* operations to a {@link DefaultLinuxContainerRuntime} instance, a * operations to a {@link DefaultLinuxContainerRuntime} instance, a
* {@link DockerLinuxContainerRuntime} instance, or a * {@link DockerLinuxContainerRuntime} instance, a
* {@link JavaSandboxLinuxContainerRuntime} instance depending on whether * {@link JavaSandboxLinuxContainerRuntime} instance, or a custom instance
* each instance believes the operation to be within its scope. * depending on whether each instance believes the operation to be within its
* scope.
* *
* @see DockerLinuxContainerRuntime#isDockerContainerRequested * @see LinuxContainerRuntime#isRuntimeRequested
*/ */
@InterfaceAudience.Private @InterfaceAudience.Private
@InterfaceStability.Unstable @InterfaceStability.Unstable
public class DelegatingLinuxContainerRuntime implements LinuxContainerRuntime { public class DelegatingLinuxContainerRuntime implements LinuxContainerRuntime {
private static final Logger LOG = private static final Logger LOG =
LoggerFactory.getLogger(DelegatingLinuxContainerRuntime.class); LoggerFactory.getLogger(DelegatingLinuxContainerRuntime.class);
private DefaultLinuxContainerRuntime defaultLinuxContainerRuntime; private DefaultLinuxContainerRuntime defaultLinuxContainerRuntime;
private DockerLinuxContainerRuntime dockerLinuxContainerRuntime; private DockerLinuxContainerRuntime dockerLinuxContainerRuntime;
private JavaSandboxLinuxContainerRuntime javaSandboxLinuxContainerRuntime; private JavaSandboxLinuxContainerRuntime javaSandboxLinuxContainerRuntime;
private EnumSet<LinuxContainerRuntimeConstants.RuntimeType> allowedRuntimes = private Set<String> allowedRuntimes = new HashSet<>();
EnumSet.noneOf(LinuxContainerRuntimeConstants.RuntimeType.class); private List<LinuxContainerRuntime> pluggableRuntimes = new ArrayList<>();
@Override @Override
public void initialize(Configuration conf, Context nmContext) public void initialize(Configuration conf, Context nmContext)
@ -64,52 +69,62 @@ public class DelegatingLinuxContainerRuntime implements LinuxContainerRuntime {
YarnConfiguration.LINUX_CONTAINER_RUNTIME_ALLOWED_RUNTIMES, YarnConfiguration.LINUX_CONTAINER_RUNTIME_ALLOWED_RUNTIMES,
YarnConfiguration.DEFAULT_LINUX_CONTAINER_RUNTIME_ALLOWED_RUNTIMES); YarnConfiguration.DEFAULT_LINUX_CONTAINER_RUNTIME_ALLOWED_RUNTIMES);
for (String configuredRuntime : configuredRuntimes) { for (String configuredRuntime : configuredRuntimes) {
try { String normRuntime = configuredRuntime.toUpperCase();
allowedRuntimes.add( allowedRuntimes.add(normRuntime);
LinuxContainerRuntimeConstants.RuntimeType.valueOf( if (isPluggableRuntime(normRuntime)) {
configuredRuntime.toUpperCase())); LinuxContainerRuntime runtime = createPluggableRuntime(conf,
} catch (IllegalArgumentException e) { configuredRuntime);
throw new ContainerExecutionException("Invalid runtime set in " runtime.initialize(conf, nmContext);
+ YarnConfiguration.LINUX_CONTAINER_RUNTIME_ALLOWED_RUNTIMES + " : " pluggableRuntimes.add(runtime);
+ configuredRuntime);
} }
} }
if (isRuntimeAllowed( if (isRuntimeAllowed(
LinuxContainerRuntimeConstants.RuntimeType.JAVASANDBOX)) { LinuxContainerRuntimeConstants.RuntimeType.JAVASANDBOX.name())) {
javaSandboxLinuxContainerRuntime = new JavaSandboxLinuxContainerRuntime( javaSandboxLinuxContainerRuntime = new JavaSandboxLinuxContainerRuntime(
PrivilegedOperationExecutor.getInstance(conf)); PrivilegedOperationExecutor.getInstance(conf));
javaSandboxLinuxContainerRuntime.initialize(conf, nmContext); javaSandboxLinuxContainerRuntime.initialize(conf, nmContext);
} }
if (isRuntimeAllowed( if (isRuntimeAllowed(
LinuxContainerRuntimeConstants.RuntimeType.DOCKER)) { LinuxContainerRuntimeConstants.RuntimeType.DOCKER.name())) {
dockerLinuxContainerRuntime = new DockerLinuxContainerRuntime( dockerLinuxContainerRuntime = new DockerLinuxContainerRuntime(
PrivilegedOperationExecutor.getInstance(conf)); PrivilegedOperationExecutor.getInstance(conf));
dockerLinuxContainerRuntime.initialize(conf, nmContext); dockerLinuxContainerRuntime.initialize(conf, nmContext);
} }
if (isRuntimeAllowed( if (isRuntimeAllowed(
LinuxContainerRuntimeConstants.RuntimeType.DEFAULT)) { LinuxContainerRuntimeConstants.RuntimeType.DEFAULT.name())) {
defaultLinuxContainerRuntime = new DefaultLinuxContainerRuntime( defaultLinuxContainerRuntime = new DefaultLinuxContainerRuntime(
PrivilegedOperationExecutor.getInstance(conf)); PrivilegedOperationExecutor.getInstance(conf));
defaultLinuxContainerRuntime.initialize(conf, nmContext); defaultLinuxContainerRuntime.initialize(conf, nmContext);
} }
} }
@Override
public boolean isRuntimeRequested(Map<String, String> env) {
return true;
}
@VisibleForTesting @VisibleForTesting
LinuxContainerRuntime pickContainerRuntime( LinuxContainerRuntime pickContainerRuntime(
Map<String, String> environment) throws ContainerExecutionException { Map<String, String> environment) throws ContainerExecutionException {
LinuxContainerRuntime runtime; LinuxContainerRuntime runtime;
//Sandbox checked first to ensure DockerRuntime doesn't circumvent controls //Sandbox checked first to ensure DockerRuntime doesn't circumvent controls
if (javaSandboxLinuxContainerRuntime != null && if (javaSandboxLinuxContainerRuntime != null &&
javaSandboxLinuxContainerRuntime.isSandboxContainerRequested()){ javaSandboxLinuxContainerRuntime.isRuntimeRequested(environment)){
runtime = javaSandboxLinuxContainerRuntime; runtime = javaSandboxLinuxContainerRuntime;
} else if (dockerLinuxContainerRuntime != null && } else if (dockerLinuxContainerRuntime != null &&
DockerLinuxContainerRuntime.isDockerContainerRequested(environment)){ dockerLinuxContainerRuntime.isRuntimeRequested(environment)) {
runtime = dockerLinuxContainerRuntime; runtime = dockerLinuxContainerRuntime;
} else if (defaultLinuxContainerRuntime != null &&
!DockerLinuxContainerRuntime.isDockerContainerRequested(environment)) {
runtime = defaultLinuxContainerRuntime;
} else { } else {
throw new ContainerExecutionException("Requested runtime not allowed."); LinuxContainerRuntime pluggableRuntime = pickPluggableRuntime(
environment);
if (pluggableRuntime != null) {
runtime = pluggableRuntime;
} else if (defaultLinuxContainerRuntime != null &&
defaultLinuxContainerRuntime.isRuntimeRequested(environment)) {
runtime = defaultLinuxContainerRuntime;
} else {
throw new ContainerExecutionException("Requested runtime not allowed.");
}
} }
if (LOG.isDebugEnabled()) { if (LOG.isDebugEnabled()) {
@ -120,6 +135,16 @@ public class DelegatingLinuxContainerRuntime implements LinuxContainerRuntime {
return runtime; return runtime;
} }
private LinuxContainerRuntime pickPluggableRuntime(
Map<String, String> environment) {
for (LinuxContainerRuntime runtime : pluggableRuntimes) {
if (runtime.isRuntimeRequested(environment)) {
return runtime;
}
}
return null;
}
private LinuxContainerRuntime pickContainerRuntime(Container container) private LinuxContainerRuntime pickContainerRuntime(Container container)
throws ContainerExecutionException { throws ContainerExecutionException {
return pickContainerRuntime(container.getLaunchContext().getEnvironment()); return pickContainerRuntime(container.getLaunchContext().getEnvironment());
@ -175,9 +200,33 @@ public class DelegatingLinuxContainerRuntime implements LinuxContainerRuntime {
return runtime.getIpAndHost(container); return runtime.getIpAndHost(container);
} }
private boolean isPluggableRuntime(String runtimeType) {
for (LinuxContainerRuntimeConstants.RuntimeType type :
LinuxContainerRuntimeConstants.RuntimeType.values()) {
if (type.name().equalsIgnoreCase(runtimeType)) {
return false;
}
}
return true;
}
private LinuxContainerRuntime createPluggableRuntime(Configuration conf,
String runtimeType) throws ContainerExecutionException {
String confKey = String.format(
YarnConfiguration.LINUX_CONTAINER_RUNTIME_CLASS_FMT, runtimeType);
Class<? extends LinuxContainerRuntime> clazz = conf.getClass(
confKey, null, LinuxContainerRuntime.class);
if (clazz == null) {
throw new ContainerExecutionException("Invalid runtime set in "
+ YarnConfiguration.LINUX_CONTAINER_RUNTIME_ALLOWED_RUNTIMES + " : "
+ runtimeType + " : Missing configuration " + confKey);
}
return ReflectionUtils.newInstance(clazz, conf);
}
@VisibleForTesting @VisibleForTesting
boolean isRuntimeAllowed( boolean isRuntimeAllowed(String runtimeType) {
LinuxContainerRuntimeConstants.RuntimeType runtimeType) { return runtimeType != null && allowedRuntimes.contains(
return allowedRuntimes.contains(runtimeType); runtimeType.toUpperCase());
} }
} }

View File

@ -377,6 +377,11 @@ public class DockerLinuxContainerRuntime implements LinuxContainerRuntime {
YarnConfiguration.NM_DOCKER_DEFAULT_TMPFS_MOUNTS))); YarnConfiguration.NM_DOCKER_DEFAULT_TMPFS_MOUNTS)));
} }
@Override
public boolean isRuntimeRequested(Map<String, String> env) {
return isDockerContainerRequested(env);
}
private Set<String> getDockerCapabilitiesFromConf() throws private Set<String> getDockerCapabilitiesFromConf() throws
ContainerExecutionException { ContainerExecutionException {
Set<String> caps = new HashSet<>(Arrays.asList( Set<String> caps = new HashSet<>(Arrays.asList(

View File

@ -282,9 +282,11 @@ public class JavaSandboxLinuxContainerRuntime
* Determine if JVMSandboxLinuxContainerRuntime should be used. This is * Determine if JVMSandboxLinuxContainerRuntime should be used. This is
* decided based on the value of * decided based on the value of
* {@value YarnConfiguration#YARN_CONTAINER_SANDBOX} * {@value YarnConfiguration#YARN_CONTAINER_SANDBOX}
* @param env the environment variable settings for the operation
* @return true if Sandbox is requested, false otherwise * @return true if Sandbox is requested, false otherwise
*/ */
boolean isSandboxContainerRequested() { @Override
public boolean isRuntimeRequested(Map<String, String> env) {
return sandboxMode != SandboxMode.disabled; return sandboxMode != SandboxMode.disabled;
} }

View File

@ -27,6 +27,8 @@ import org.apache.hadoop.yarn.server.nodemanager.Context;
import org.apache.hadoop.yarn.server.nodemanager.containermanager.runtime.ContainerExecutionException; 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.ContainerRuntime;
import java.util.Map;
/** /**
* Linux-specific container runtime implementations must implement this * Linux-specific container runtime implementations must implement this
* interface. * interface.
@ -44,5 +46,14 @@ public interface LinuxContainerRuntime extends ContainerRuntime {
* the runtime * the runtime
*/ */
void initialize(Configuration conf, Context nmContext) throws ContainerExecutionException; void initialize(Configuration conf, Context nmContext) throws ContainerExecutionException;
/**
* Return whether the given environment variables indicate that the operation
* is requesting this runtime.
*
* @param env the environment variable settings for the operation
* @return whether this runtime is requested
*/
boolean isRuntimeRequested(Map<String, String> env);
} }

View File

@ -0,0 +1,61 @@
/*
* 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;
import org.apache.hadoop.conf.Configuration;
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.ContainerRuntimeConstants;
import org.apache.hadoop.yarn.server.nodemanager.containermanager.runtime.ContainerRuntimeContext;
import java.util.Map;
public class MockLinuxContainerRuntime implements LinuxContainerRuntime {
@Override
public void initialize(Configuration conf, Context nmContext) {}
@Override
public boolean isRuntimeRequested(Map<String, String> env) {
if (env == null) {
return false;
}
String type = env.get(ContainerRuntimeConstants.ENV_CONTAINER_TYPE);
return type != null && type.equals("mock");
}
@Override
public void prepareContainer(ContainerRuntimeContext ctx) {}
@Override
public void launchContainer(ContainerRuntimeContext ctx) {}
@Override
public void relaunchContainer(ContainerRuntimeContext ctx) {}
@Override
public void signalContainer(ContainerRuntimeContext ctx) {}
@Override
public void reapContainer(ContainerRuntimeContext ctx) {}
@Override
public String[] getIpAndHost(Container container) {
return new String[0];
}
}

View File

@ -18,6 +18,7 @@ package org.apache.hadoop.yarn.server.nodemanager.containermanager.linux.runtime
import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.yarn.conf.YarnConfiguration; import org.apache.hadoop.yarn.conf.YarnConfiguration;
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.ContainerRuntime;
import org.apache.hadoop.yarn.server.nodemanager.containermanager.runtime.ContainerRuntimeConstants; import org.apache.hadoop.yarn.server.nodemanager.containermanager.runtime.ContainerRuntimeConstants;
import org.junit.Before; import org.junit.Before;
@ -52,11 +53,11 @@ public class TestDelegatingLinuxContainerRuntime {
YarnConfiguration.LINUX_CONTAINER_RUNTIME_ALLOWED_RUNTIMES)); YarnConfiguration.LINUX_CONTAINER_RUNTIME_ALLOWED_RUNTIMES));
delegatingLinuxContainerRuntime.initialize(conf, null); delegatingLinuxContainerRuntime.initialize(conf, null);
assertTrue(delegatingLinuxContainerRuntime.isRuntimeAllowed( assertTrue(delegatingLinuxContainerRuntime.isRuntimeAllowed(
LinuxContainerRuntimeConstants.RuntimeType.DEFAULT)); LinuxContainerRuntimeConstants.RuntimeType.DEFAULT.name()));
assertFalse(delegatingLinuxContainerRuntime.isRuntimeAllowed( assertFalse(delegatingLinuxContainerRuntime.isRuntimeAllowed(
LinuxContainerRuntimeConstants.RuntimeType.DOCKER)); LinuxContainerRuntimeConstants.RuntimeType.DOCKER.name()));
assertFalse(delegatingLinuxContainerRuntime.isRuntimeAllowed( assertFalse(delegatingLinuxContainerRuntime.isRuntimeAllowed(
LinuxContainerRuntimeConstants.RuntimeType.JAVASANDBOX)); LinuxContainerRuntimeConstants.RuntimeType.JAVASANDBOX.name()));
} }
@Test @Test
@ -65,11 +66,11 @@ public class TestDelegatingLinuxContainerRuntime {
"docker"); "docker");
delegatingLinuxContainerRuntime.initialize(conf, null); delegatingLinuxContainerRuntime.initialize(conf, null);
assertTrue(delegatingLinuxContainerRuntime.isRuntimeAllowed( assertTrue(delegatingLinuxContainerRuntime.isRuntimeAllowed(
LinuxContainerRuntimeConstants.RuntimeType.DOCKER)); LinuxContainerRuntimeConstants.RuntimeType.DOCKER.name()));
assertFalse(delegatingLinuxContainerRuntime.isRuntimeAllowed( assertFalse(delegatingLinuxContainerRuntime.isRuntimeAllowed(
LinuxContainerRuntimeConstants.RuntimeType.DEFAULT)); LinuxContainerRuntimeConstants.RuntimeType.DEFAULT.name()));
assertFalse(delegatingLinuxContainerRuntime.isRuntimeAllowed( assertFalse(delegatingLinuxContainerRuntime.isRuntimeAllowed(
LinuxContainerRuntimeConstants.RuntimeType.JAVASANDBOX)); LinuxContainerRuntimeConstants.RuntimeType.JAVASANDBOX.name()));
} }
@Test @Test
@ -78,11 +79,11 @@ public class TestDelegatingLinuxContainerRuntime {
"javasandbox"); "javasandbox");
delegatingLinuxContainerRuntime.initialize(conf, null); delegatingLinuxContainerRuntime.initialize(conf, null);
assertTrue(delegatingLinuxContainerRuntime.isRuntimeAllowed( assertTrue(delegatingLinuxContainerRuntime.isRuntimeAllowed(
LinuxContainerRuntimeConstants.RuntimeType.JAVASANDBOX)); LinuxContainerRuntimeConstants.RuntimeType.JAVASANDBOX.name()));
assertFalse(delegatingLinuxContainerRuntime.isRuntimeAllowed( assertFalse(delegatingLinuxContainerRuntime.isRuntimeAllowed(
LinuxContainerRuntimeConstants.RuntimeType.DEFAULT)); LinuxContainerRuntimeConstants.RuntimeType.DEFAULT.name()));
assertFalse(delegatingLinuxContainerRuntime.isRuntimeAllowed( assertFalse(delegatingLinuxContainerRuntime.isRuntimeAllowed(
LinuxContainerRuntimeConstants.RuntimeType.DOCKER)); LinuxContainerRuntimeConstants.RuntimeType.DOCKER.name()));
} }
@Test @Test
@ -91,11 +92,11 @@ public class TestDelegatingLinuxContainerRuntime {
"docker,javasandbox"); "docker,javasandbox");
delegatingLinuxContainerRuntime.initialize(conf, null); delegatingLinuxContainerRuntime.initialize(conf, null);
assertTrue(delegatingLinuxContainerRuntime.isRuntimeAllowed( assertTrue(delegatingLinuxContainerRuntime.isRuntimeAllowed(
LinuxContainerRuntimeConstants.RuntimeType.DOCKER)); LinuxContainerRuntimeConstants.RuntimeType.DOCKER.name()));
assertTrue(delegatingLinuxContainerRuntime.isRuntimeAllowed( assertTrue(delegatingLinuxContainerRuntime.isRuntimeAllowed(
LinuxContainerRuntimeConstants.RuntimeType.JAVASANDBOX)); LinuxContainerRuntimeConstants.RuntimeType.JAVASANDBOX.name()));
assertFalse(delegatingLinuxContainerRuntime.isRuntimeAllowed( assertFalse(delegatingLinuxContainerRuntime.isRuntimeAllowed(
LinuxContainerRuntimeConstants.RuntimeType.DEFAULT)); LinuxContainerRuntimeConstants.RuntimeType.DEFAULT.name()));
} }
@Test @Test
@ -104,11 +105,38 @@ public class TestDelegatingLinuxContainerRuntime {
"default,docker,javasandbox"); "default,docker,javasandbox");
delegatingLinuxContainerRuntime.initialize(conf, null); delegatingLinuxContainerRuntime.initialize(conf, null);
assertTrue(delegatingLinuxContainerRuntime.isRuntimeAllowed( assertTrue(delegatingLinuxContainerRuntime.isRuntimeAllowed(
LinuxContainerRuntimeConstants.RuntimeType.DEFAULT)); LinuxContainerRuntimeConstants.RuntimeType.DEFAULT.name()));
assertTrue(delegatingLinuxContainerRuntime.isRuntimeAllowed( assertTrue(delegatingLinuxContainerRuntime.isRuntimeAllowed(
LinuxContainerRuntimeConstants.RuntimeType.DOCKER)); LinuxContainerRuntimeConstants.RuntimeType.DOCKER.name()));
assertTrue(delegatingLinuxContainerRuntime.isRuntimeAllowed( assertTrue(delegatingLinuxContainerRuntime.isRuntimeAllowed(
LinuxContainerRuntimeConstants.RuntimeType.JAVASANDBOX)); LinuxContainerRuntimeConstants.RuntimeType.JAVASANDBOX.name()));
}
@Test
public void testInitializeMissingRuntimeClass() throws Exception {
conf.set(YarnConfiguration.LINUX_CONTAINER_RUNTIME_ALLOWED_RUNTIMES,
"mock");
try {
delegatingLinuxContainerRuntime.initialize(conf, null);
fail("initialize should fail");
} catch (ContainerExecutionException e) {
assert(e.getMessage().contains("Invalid runtime set"));
}
}
@Test
public void testIsRuntimeAllowedMock() throws Exception {
conf.set(YarnConfiguration.LINUX_CONTAINER_RUNTIME_ALLOWED_RUNTIMES,
"mock");
conf.set(String.format(YarnConfiguration.LINUX_CONTAINER_RUNTIME_CLASS_FMT,
"mock"), MockLinuxContainerRuntime.class.getName());
delegatingLinuxContainerRuntime.initialize(conf, null);
assertFalse(delegatingLinuxContainerRuntime.isRuntimeAllowed(
LinuxContainerRuntimeConstants.RuntimeType.DEFAULT.name()));
assertFalse(delegatingLinuxContainerRuntime.isRuntimeAllowed(
LinuxContainerRuntimeConstants.RuntimeType.DOCKER.name()));
assertFalse(delegatingLinuxContainerRuntime.isRuntimeAllowed(
LinuxContainerRuntimeConstants.RuntimeType.JAVASANDBOX.name()));
assertTrue(delegatingLinuxContainerRuntime.isRuntimeAllowed("mock"));
} }
@Test @Test
@ -134,4 +162,17 @@ public class TestDelegatingLinuxContainerRuntime {
delegatingLinuxContainerRuntime.pickContainerRuntime(env); delegatingLinuxContainerRuntime.pickContainerRuntime(env);
assertTrue(runtime instanceof DockerLinuxContainerRuntime); assertTrue(runtime instanceof DockerLinuxContainerRuntime);
} }
@Test
public void testMockRuntimeSelected() throws Exception {
env.put(ContainerRuntimeConstants.ENV_CONTAINER_TYPE, "mock");
conf.set(String.format(YarnConfiguration.LINUX_CONTAINER_RUNTIME_CLASS_FMT,
"mock"), MockLinuxContainerRuntime.class.getName());
conf.set(YarnConfiguration.LINUX_CONTAINER_RUNTIME_ALLOWED_RUNTIMES,
"mock");
delegatingLinuxContainerRuntime.initialize(conf, null);
ContainerRuntime runtime =
delegatingLinuxContainerRuntime.pickContainerRuntime(env);
assertTrue(runtime instanceof MockLinuxContainerRuntime);
}
} }