diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/api/ApplicationConstants.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/api/ApplicationConstants.java index b63fe614130..5a11f883f8d 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/api/ApplicationConstants.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/api/ApplicationConstants.java @@ -251,7 +251,14 @@ * Final, Docker run support ENTRY_POINT. */ YARN_CONTAINER_RUNTIME_DOCKER_RUN_OVERRIDE_DISABLE( - "YARN_CONTAINER_RUNTIME_DOCKER_RUN_OVERRIDE_DISABLE"); + "YARN_CONTAINER_RUNTIME_DOCKER_RUN_OVERRIDE_DISABLE"), + + /** + * $CONTAINER_HOSTNAME + * Final, exported by NodeManager and non-modifiable by users. + * Contains the hostname for the container being launched + */ + CONTAINER_HOSTNAME("CONTAINER_HOSTNAME"); private final String variable; private Environment(String variable) { diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/DefaultContainerExecutor.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/DefaultContainerExecutor.java index 27224a599e3..166bbedb1b6 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/DefaultContainerExecutor.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/DefaultContainerExecutor.java @@ -20,6 +20,23 @@ import static org.apache.hadoop.fs.CreateFlag.CREATE; import static org.apache.hadoop.fs.CreateFlag.OVERWRITE; +import static org.apache.hadoop.yarn.server.nodemanager.containermanager + .linux.runtime.LinuxContainerRuntimeConstants.CONTAINER_ID_STR; +import static org.apache.hadoop.yarn.server.nodemanager.containermanager + .linux.runtime.LinuxContainerRuntimeConstants.CONTAINER_LOCAL_DIRS; +import static org.apache.hadoop.yarn.server.nodemanager.containermanager + .linux.runtime.LinuxContainerRuntimeConstants.CONTAINER_RUN_CMDS; +import static org.apache.hadoop.yarn.server.nodemanager.containermanager + .linux.runtime.LinuxContainerRuntimeConstants.LOCALIZED_RESOURCES; +import static org.apache.hadoop.yarn.server.nodemanager.containermanager + .linux.runtime.LinuxContainerRuntimeConstants.USER; + +import org.apache.hadoop.yarn.api.ApplicationConstants; +import org.apache.hadoop.yarn.server.nodemanager.containermanager.runtime + .ContainerExecutionException; +import org.apache.hadoop.yarn.server.nodemanager.containermanager.runtime + .ContainerRuntimeContext; +import org.apache.hadoop.yarn.server.nodemanager.executor.ContainerPrepareContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -208,6 +225,25 @@ protected ContainerLocalizer createContainerLocalizer(String user, return localizer; } + @Override + public void prepareContainer(ContainerPrepareContext ctx) throws IOException { + Container container = ctx.getContainer(); + + setContainerHostnameinEnv(container); + } + + private void setContainerHostnameinEnv(Container container) { + //Update container launch environment to set the FQ Hostname + Map environment = container.getLaunchContext() + .getEnvironment(); + + final String hostName = environment.get(ApplicationConstants.Environment + .NM_HOST.name()); + + environment.put(ApplicationConstants.Environment.CONTAINER_HOSTNAME.name(), + hostName); + } + @Override public int launchContainer(ContainerStartContext ctx) throws IOException, ConfigurationException { 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 b5c933aff23..c5d3b018bea 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 @@ -24,12 +24,20 @@ import org.apache.hadoop.classification.InterfaceStability; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.util.StringUtils; +import org.apache.hadoop.yarn.api.ApplicationConstants; import org.apache.hadoop.yarn.server.nodemanager.ContainerExecutor; 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.linux.privileged.PrivilegedOperation; import org.apache.hadoop.yarn.server.nodemanager.containermanager.linux.privileged.PrivilegedOperationException; import org.apache.hadoop.yarn.server.nodemanager.containermanager.linux.privileged.PrivilegedOperationExecutor; + +import org.apache.hadoop.yarn.server.nodemanager.containermanager.linux + .runtime.docker.DockerVolumeCommand; +import org.apache.hadoop.yarn.server.nodemanager.containermanager + .resourceplugin.DockerCommandPlugin; +import org.apache.hadoop.yarn.server.nodemanager.containermanager + .resourceplugin.ResourcePlugin; 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; @@ -37,6 +45,7 @@ import org.slf4j.LoggerFactory; import java.util.List; +import java.util.Map; import static org.apache.hadoop.yarn.server.nodemanager.containermanager.linux.runtime.LinuxContainerRuntimeConstants.*; @@ -75,7 +84,22 @@ public void initialize(Configuration conf, Context nmContext) @Override public void prepareContainer(ContainerRuntimeContext ctx) throws ContainerExecutionException { - //nothing to do here at the moment. + + Container container = ctx.getContainer(); + setContainerHostnameinEnv(container); + } + + private void setContainerHostnameinEnv(Container container) { + + //Update container launch environment to set the FQ Hostname + Map environment = container.getLaunchContext() + .getEnvironment(); + + final String hostName = environment.get(ApplicationConstants.Environment + .NM_HOST.name()); + + environment.put(ApplicationConstants.Environment.CONTAINER_HOSTNAME.name(), + hostName); } @Override 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 c89d5fb136e..a02468a3a69 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 @@ -22,6 +22,7 @@ import com.google.common.annotations.VisibleForTesting; import org.apache.hadoop.security.Credentials; +import org.apache.hadoop.yarn.api.ApplicationConstants; import org.apache.hadoop.yarn.api.ApplicationConstants.Environment; import org.apache.hadoop.yarn.api.records.ContainerId; import org.apache.hadoop.yarn.server.nodemanager.Context; @@ -431,6 +432,7 @@ public void prepareContainer(ContainerRuntimeContext ctx) } } } + setContainerHostnameinEnv(container); } private void checkDockerVolumeCreated( @@ -544,22 +546,87 @@ public static void validateHostname(String hostname) throws } } - /** Set a DNS friendly hostname. */ - private void setHostname(DockerRunCommand runCommand, String - containerIdStr, String name) + /** Construct a DNS friendly hostname */ + private String getContainerHostName(Container container) throws ContainerExecutionException { - if (name == null || name.isEmpty()) { - name = RegistryPathUtils.encodeYarnID(containerIdStr); - String domain = conf.get(RegistryConstants.KEY_DNS_DOMAIN); - if (domain != null) { - name += ("." + domain); + String hostName = null; + Map environment = container.getLaunchContext() + .getEnvironment(); + + String specifiedHostName = environment.get + (ENV_DOCKER_CONTAINER_HOSTNAME); + + if ( specifiedHostName == null || specifiedHostName.isEmpty()) { + String network = getDockerNetworkType(container); + boolean useHostNetwork = network.equalsIgnoreCase("host"); + if (useHostNetwork) { + //NM_HOST already has the NM's host address which is set in + // ContainerLaunch.sanitizeEnv before preparing container runtime for + // launch + hostName = environment.get(Environment.NM_HOST.name()); + } else{ + hostName = getFQContainerName(container.getContainerId().toString(), conf); } - validateHostname(name); + } else { + hostName = specifiedHostName; + } + return hostName; + } + + private String getDockerNetworkType(Container container) { + String network; + network = container.getLaunchContext().getEnvironment().get( + "YARN_CONTAINER_RUNTIME_DOCKER_CONTAINER_NETWORK"); + if (network == null || network.isEmpty()) { + network = defaultNetwork; + } + return network; + } + + public static String getFQContainerName(String containerIdStr, + Configuration conf) + throws ContainerExecutionException { + String name = RegistryPathUtils.encodeYarnID(containerIdStr); + + String domain = conf.get(RegistryConstants.KEY_DNS_DOMAIN); + if (domain != null) { + name += ("." + domain); + } + validateHostname(name); + return name; + } + + /** Set a DNS friendly hostname. */ + private void setHostname(DockerRunCommand runCommand, Container container) + throws ContainerExecutionException { + + String hostName = null; + //Pick up from the environment if already set in prepareContainer + Map environment = container.getLaunchContext() + .getEnvironment(); + + if (environment.get(Environment.CONTAINER_HOSTNAME.name()) != null) { + hostName = environment.get(Environment + .CONTAINER_HOSTNAME + .name()); + } else{ + hostName = getContainerHostName(container); } + LOG.info("setting hostname in container to: " + hostName); + runCommand.setHostname(hostName); + } - LOG.info("setting hostname in container to: " + name); - runCommand.setHostname(name); + private void setContainerHostnameinEnv(Container container) + throws ContainerExecutionException { + //Update container launch environment to set the FQ Hostname + Map environment = container.getLaunchContext() + .getEnvironment(); + + String hostName = getContainerHostName(container); + + environment.put(ApplicationConstants.Environment.CONTAINER_HOSTNAME.name(), + hostName); } /** @@ -822,7 +889,7 @@ public void launchContainer(ContainerRuntimeContext ctx) if (!network.equalsIgnoreCase("host") || conf.getBoolean(RegistryConstants.KEY_DNS_ENABLED, RegistryConstants.DEFAULT_DNS_ENABLED)) { - setHostname(runCommand, containerIdStr, hostname); + setHostname(runCommand, container); } runCommand.setCapabilities(capabilities); @@ -1093,16 +1160,7 @@ public void reapContainer(ContainerRuntimeContext ctx) String ips = output.substring(0, index).trim(); String host = output.substring(index+1).trim(); if (ips.equals("")) { - String network; - try { - network = container.getLaunchContext().getEnvironment() - .get("YARN_CONTAINER_RUNTIME_DOCKER_CONTAINER_NETWORK"); - if (network == null || network.isEmpty()) { - network = defaultNetwork; - } - } catch (NullPointerException e) { - network = defaultNetwork; - } + String network = getDockerNetworkType(container); boolean useHostNetwork = network.equalsIgnoreCase("host"); if (useHostNetwork) { // Report back node manager IP in the event where docker diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/TestLinuxContainerExecutor.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/TestLinuxContainerExecutor.java index ddbf3b90568..e824e142008 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/TestLinuxContainerExecutor.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/TestLinuxContainerExecutor.java @@ -30,6 +30,8 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import org.apache.hadoop.yarn.server.nodemanager.executor + .ContainerPrepareContext; import org.apache.hadoop.yarn.server.nodemanager.executor.ContainerReapContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/linux/runtime/TestDockerContainerRuntime.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/linux/runtime/TestDockerContainerRuntime.java index 855ec44c2ae..c91db4bd1a3 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/linux/runtime/TestDockerContainerRuntime.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/linux/runtime/TestDockerContainerRuntime.java @@ -32,6 +32,7 @@ import org.apache.hadoop.yarn.api.records.ApplicationAttemptId; import org.apache.hadoop.yarn.api.records.ContainerId; import org.apache.hadoop.yarn.api.records.ContainerLaunchContext; +import org.apache.hadoop.yarn.server.nodemanager.LinuxContainerExecutor; import org.apache.hadoop.yarn.server.nodemanager.LocalDirsHandlerService; import org.apache.hadoop.yarn.util.DockerClientConfigHandler; import org.apache.hadoop.yarn.conf.YarnConfiguration; @@ -52,6 +53,12 @@ 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 static org.apache.hadoop.test.PlatformAssumptions.assumeNotWindows; +import static org.apache.hadoop.yarn.api.ApplicationConstants.Environment.NM_HOST; +import org.apache.hadoop.yarn.api.ApplicationConstants.Environment; + import org.junit.Assert; import org.junit.Before; import org.junit.Rule; @@ -65,10 +72,15 @@ import java.io.BufferedWriter; import java.io.File; import java.io.FileInputStream; +import java.io.FileOutputStream; import java.io.FileWriter; import java.io.IOException; +import java.io.OutputStream; +import java.net.InetAddress; +import java.net.UnknownHostException; import java.nio.ByteBuffer; import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Paths; import java.nio.file.attribute.FileAttribute; @@ -78,6 +90,7 @@ import java.util.Collections; import java.util.HashMap; import java.util.Iterator; +import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Random; @@ -160,7 +173,7 @@ public TemporaryFolder tempDir = new TemporaryFolder(); @Before - public void setup() { + public void setup() throws UnknownHostException { String tmpPath = new StringBuffer(System.getProperty("test.build.data")) .append('/').append("hadoop.tmp.dir").toString(); @@ -185,6 +198,8 @@ public void setup() { YarnConfiguration.DEFAULT_NM_DOCKER_STOP_GRACE_PERIOD); env.put(DockerLinuxContainerRuntime.ENV_DOCKER_CONTAINER_IMAGE, image); + env.put(NM_HOST.name(), InetAddress.getLocalHost().getHostName()); + when(container.getContainerId()).thenReturn(cId); when(cId.toString()).thenReturn(containerId); when(cId.getApplicationAttemptId()).thenReturn(appAttemptId); @@ -385,7 +400,9 @@ public void testDockerContainerLaunch() DockerLinuxContainerRuntime runtime = new DockerLinuxContainerRuntime( mockExecutor, mockCGroupsHandler); runtime.initialize(conf, nmContext); - runtime.launchContainer(builder.build()); + ContainerRuntimeContext runtimeContext = builder.build(); + runtime.prepareContainer(runtimeContext); + runtime.launchContainer(runtimeContext); PrivilegedOperation op = capturePrivilegedOperationAndVerifyArgs(); List args = op.getArguments(); @@ -425,6 +442,14 @@ public void testDockerContainerLaunch() Assert.assertEquals(" user=" + uidGidPair, dockerCommands.get(counter++)); Assert.assertEquals(" workdir=/test_container_work_dir", dockerCommands.get(counter)); + final Map environment = + runtimeContext.getContainer().getLaunchContext() + .getEnvironment(); + String nmHostName = environment.get(NM_HOST.name()); + Assert + .assertEquals("Container Hostname : ", environment.get( + Environment.CONTAINER_HOSTNAME.name()), + nmHostName); } @Test @@ -680,7 +705,10 @@ public void testContainerLaunchWithCustomNetworks() //this should cause no failures. runtime.initialize(conf, nmContext); - runtime.launchContainer(builder.build()); + ContainerRuntimeContext ctx = builder.build(); + runtime.prepareContainer(ctx); + runtime.launchContainer(ctx); + PrivilegedOperation op = capturePrivilegedOperationAndVerifyArgs(); List args = op.getArguments(); String dockerCommandFile = args.get(11); @@ -692,6 +720,11 @@ public void testContainerLaunchWithCustomNetworks() int expected = 15; int counter = 0; + + final Map environment = + ctx.getContainer().getLaunchContext().getEnvironment(); + String nmHostName = environment.get(NM_HOST.name()); + Assert.assertEquals(expected, dockerCommands.size()); Assert.assertEquals("[docker-command-execution]", dockerCommands.get(counter++)); @@ -725,6 +758,12 @@ public void testContainerLaunchWithCustomNetworks() Assert.assertEquals(" workdir=/test_container_work_dir", dockerCommands.get(counter)); + Assert + .assertEquals("Container Hostname : ", environment.get( + Environment.CONTAINER_HOSTNAME.name()), + "ctr-e11-1518975676334-14532816-01-000001" + ); + //now set an explicit (non-default) allowedNetwork and ensure that it is // used. @@ -775,6 +814,12 @@ public void testContainerLaunchWithCustomNetworks() Assert.assertEquals(" workdir=/test_container_work_dir", dockerCommands.get(counter)); + Assert + .assertEquals("Container Hostname : ", environment.get( + Environment.CONTAINER_HOSTNAME.name()), + "ctr-e11-1518975676334-14532816-01-000001" + ); + //disallowed network should trigger a launch failure @@ -851,7 +896,8 @@ public void testLaunchPidNamespaceContainersEnabled() env.put(DockerLinuxContainerRuntime .ENV_DOCKER_CONTAINER_PID_NAMESPACE, "host"); - runtime.launchContainer(builder.build()); + ContainerRuntimeContext ctx = builder.build(); + runtime.launchContainer(ctx); PrivilegedOperation op = capturePrivilegedOperationAndVerifyArgs(); List args = op.getArguments(); String dockerCommandFile = args.get(11); @@ -861,6 +907,10 @@ public void testLaunchPidNamespaceContainersEnabled() int expected = 15; int counter = 0; + + final Map environment = + ctx.getContainer().getLaunchContext().getEnvironment(); + String nmHostName = environment.get(NM_HOST.name()); Assert.assertEquals(expected, dockerCommands.size()); Assert.assertEquals("[docker-command-execution]", dockerCommands.get(counter++)); @@ -1013,7 +1063,9 @@ public void testLaunchPrivilegedContainersWithEnabledSettingAndDefaultACL() env.put(DockerLinuxContainerRuntime .ENV_DOCKER_CONTAINER_RUN_PRIVILEGED_CONTAINER, "true"); - runtime.launchContainer(builder.build()); + ContainerRuntimeContext ctx = builder.build(); + runtime.launchContainer(ctx); + PrivilegedOperation op = capturePrivilegedOperationAndVerifyArgs(); List args = op.getArguments(); String dockerCommandFile = args.get(11); @@ -1242,7 +1294,8 @@ public void testUserMounts() DockerLinuxContainerRuntime.ENV_DOCKER_CONTAINER_MOUNTS, "/tmp/foo:/tmp/foo:ro,/tmp/bar:/tmp/bar:rw"); - runtime.launchContainer(builder.build()); + ContainerRuntimeContext ctx = builder.build(); + runtime.launchContainer(ctx); PrivilegedOperation op = capturePrivilegedOperationAndVerifyArgs(); List args = op.getArguments(); String dockerCommandFile = args.get(11); @@ -2122,7 +2175,9 @@ public void testLaunchContainerWithDockerTokens() Files.createTempDirectory("docker-client-config-out", attr).toUri() .getPath() + "/launch_container.sh"); builder.setExecutionAttribute(NM_PRIVATE_CONTAINER_SCRIPT_PATH, outDir); - runtime.launchContainer(builder.build()); + + ContainerRuntimeContext ctx = builder.build(); + runtime.launchContainer(ctx); PrivilegedOperation op = capturePrivilegedOperation(); Assert.assertEquals( PrivilegedOperation.OperationType.LAUNCH_DOCKER_CONTAINER, @@ -2219,4 +2274,42 @@ public void testDockerContainerRelaunch() " name=container_e11_1518975676334_14532816_01_000001", dockerCommands.get(counter)); } + + @Test(timeout = 20000) + public void testWriteEnvExportDocker() throws Exception { + // Valid only for unix + assumeNotWindows(); + File tmpDir = new File("target", + this.getClass().getSimpleName() + "-tmpDir"); + tmpDir.mkdir(); + File shellFile = Shell.appendScriptExtension(tmpDir, "hello"); + FileOutputStream fos = new FileOutputStream(shellFile); + DockerLinuxContainerRuntime dockerRuntime = new DockerLinuxContainerRuntime( + mock(PrivilegedOperationExecutor.class)); + dockerRuntime.initialize(conf, null); + ContainerRuntimeContext runtimeContext = builder.build(); + + dockerRuntime.prepareContainer(runtimeContext); + LinuxContainerExecutor lce = new LinuxContainerExecutor(dockerRuntime); + YarnConfiguration conf = new YarnConfiguration(); + lce.setConf(conf); + List commands = new ArrayList(); + Map> resources = new HashMap>(); + lce.writeLaunchEnv(fos, + runtimeContext.getContainer().getLaunchContext().getEnvironment(), + resources, commands, new Path(logDirs.get(0)), "user", + new LinkedHashSet<>()); + + String shellContent = new String( + Files.readAllBytes(Paths.get(shellFile.getAbsolutePath())), + StandardCharsets.UTF_8); + + final Map environment = + runtimeContext.getContainer().getLaunchContext().getEnvironment(); + String nmHostName = environment.get(NM_HOST.name()); + Assert.assertTrue("CONTAINER_HOSTNAME should be set", shellContent + .contains("export CONTAINER_HOSTNAME=\"" + nmHostName + "\"")); + fos.flush(); + fos.close(); + } }