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 64bcc440d00..abcbb3bb79d 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 @@ -234,7 +234,14 @@ * Comma separate list of directories that the container should use for * logging. */ - LOG_DIRS("LOG_DIRS"); + LOG_DIRS("LOG_DIRS"), + + /** + * $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/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 401fc4ac128..ed9b02195ad 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,8 @@ 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.server.nodemanager.Context; import org.apache.hadoop.yarn.server.nodemanager.containermanager.linux.runtime.docker.DockerCommandExecutor; import org.apache.hadoop.yarn.server.nodemanager.containermanager.linux.runtime.docker.DockerKillCommand; @@ -435,6 +437,7 @@ public void prepareContainer(ContainerRuntimeContext ctx) } } } + setHostnameinEnv(container); } private void checkDockerVolumeCreated( @@ -543,22 +546,98 @@ 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) { + InetAddress address; + try { + address = InetAddress.getLocalHost(); + hostName = address.getHostName(); + } catch (UnknownHostException e) { + LOG.error("Can not determine IP for container:" + container.getContainerId() + .toString()); + throw new ContainerExecutionException(e); + } + } else{ + hostName = getFQContainerName(container.getContainerId().toString(), conf); + } + } else { + hostName = specifiedHostName; + } + return hostName; + } + + private String getDockerNetworkType(Container container) { + String network; + try { + network = container.getLaunchContext().getEnvironment().get( + "YARN_CONTAINER_RUNTIME_DOCKER_CONTAINER_NETWORK"); + if (network == null || network.isEmpty()) { + network = defaultNetwork; } - validateHostname(name); + } catch (NullPointerException e) { + network = defaultNetwork; } + return network; + } - LOG.info("setting hostname in container to: " + name); - runCommand.setHostname(name); + 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); + } + + private void setHostnameinEnv(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); } /** @@ -792,7 +871,7 @@ public void launchContainer(ContainerRuntimeContext ctx) .detachOnRun() .setContainerWorkDir(containerWorkDir.toString()) .setNetworkType(network); - setHostname(runCommand, containerIdStr, hostname); + setHostname(runCommand, container); runCommand.setCapabilities(capabilities); runCommand.addAllReadWriteMountLocations(containerLogDirs); @@ -1013,16 +1092,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/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 4c53eb117c3..e8ef3151962 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 @@ -25,12 +25,13 @@ import org.apache.hadoop.fs.FileUtil; import org.apache.hadoop.fs.Path; import org.apache.hadoop.io.DataOutputBuffer; -import org.apache.hadoop.registry.client.binding.RegistryPathUtils; import org.apache.hadoop.security.Credentials; import org.apache.hadoop.util.Shell; import org.apache.hadoop.util.StringUtils; +import org.apache.hadoop.yarn.api.ApplicationConstants.Environment; 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.util.DockerClientConfigHandler; import org.apache.hadoop.yarn.conf.YarnConfiguration; import org.apache.hadoop.yarn.security.TestDockerClientConfigHandler; @@ -64,10 +65,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; @@ -77,11 +83,15 @@ 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; import java.util.Set; +import static org.apache.hadoop.test.PlatformAssumptions.assumeNotWindows; +import static org.apache.hadoop.yarn.api.ApplicationConstants.Environment + .NM_HOST; import static org.apache.hadoop.yarn.server.nodemanager.containermanager.linux.runtime.LinuxContainerRuntimeConstants.APPID; import static org.apache.hadoop.yarn.server.nodemanager.containermanager.linux.runtime.LinuxContainerRuntimeConstants.APPLICATION_LOCAL_DIRS; import static org.apache.hadoop.yarn.server.nodemanager.containermanager.linux.runtime.LinuxContainerRuntimeConstants.CONTAINER_ID_STR; @@ -147,7 +157,7 @@ private final String signalPid = "1234"; @Before - public void setup() { + public void setup() throws Exception { String tmpPath = new StringBuffer(System.getProperty("test.build.data")) .append('/').append("hadoop.tmp.dir").toString(); @@ -158,7 +168,9 @@ public void setup() { .mock(PrivilegedOperationExecutor.class); mockCGroupsHandler = Mockito.mock(CGroupsHandler.class); containerId = "container_id"; - container = mock(Container.class); + container = mock + (Container.class); + cId = mock(ContainerId.class); context = mock(ContainerLaunchContext.class); env = new HashMap(); @@ -166,6 +178,7 @@ public void setup() { image = "busybox:latest"; 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(container.getLaunchContext()).thenReturn(context); @@ -331,7 +344,9 @@ public void testDockerContainerLaunch() DockerLinuxContainerRuntime runtime = new DockerLinuxContainerRuntime( mockExecutor, mockCGroupsHandler); runtime.initialize(conf, null); - runtime.launchContainer(builder.build()); + ContainerRuntimeContext runtimeContext = builder.build(); + runtime.prepareContainer(runtimeContext); + runtime.launchContainer(runtimeContext); PrivilegedOperation op = capturePrivilegedOperationAndVerifyArgs(); List args = op.getArguments(); @@ -352,7 +367,18 @@ public void testDockerContainerLaunch() Assert.assertEquals(" docker-command=run", dockerCommands.get(counter++)); Assert.assertEquals(" group-add=" + String.join(",", groups), dockerCommands.get(counter++)); - Assert.assertEquals(" hostname=ctr-id", dockerCommands.get(counter++)); + + final Map environment = + runtimeContext.getContainer().getLaunchContext() + .getEnvironment(); + String nmHostName = environment.get(NM_HOST.name()); + Assert.assertEquals(" hostname=" + nmHostName, dockerCommands.get + (counter++)); + + Assert + .assertEquals("Container Hostname : ", environment.get( + Environment.CONTAINER_HOSTNAME.name()), + nmHostName); Assert .assertEquals(" image=busybox:latest", dockerCommands.get(counter++)); Assert.assertEquals( @@ -381,7 +407,8 @@ public void testContainerLaunchWithUserRemapping() DockerLinuxContainerRuntime runtime = new DockerLinuxContainerRuntime( mockExecutor, mockCGroupsHandler); runtime.initialize(conf, null); - runtime.launchContainer(builder.build()); + ContainerRuntimeContext ctx = builder.build(); + runtime.launchContainer(ctx); PrivilegedOperation op = capturePrivilegedOperationAndVerifyArgs(); List args = op.getArguments(); @@ -401,7 +428,11 @@ public void testContainerLaunchWithUserRemapping() Assert.assertEquals(" docker-command=run", dockerCommands.get(counter++)); Assert.assertEquals(" group-add=" + String.join(",", groups), dockerCommands.get(counter++)); - Assert.assertEquals(" hostname=ctr-id", + + final Map environment = + ctx.getContainer().getLaunchContext().getEnvironment(); + String nmHostName = environment.get(NM_HOST.name()); + Assert.assertEquals(" hostname=" + nmHostName, dockerCommands.get(counter++)); Assert .assertEquals(" image=busybox:latest", dockerCommands.get(counter++)); @@ -729,7 +760,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); @@ -739,6 +771,9 @@ public void testLaunchPidNamespaceContainersEnabled() int expected = 16; 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++)); @@ -749,7 +784,7 @@ public void testLaunchPidNamespaceContainersEnabled() Assert.assertEquals(" docker-command=run", dockerCommands.get(counter++)); Assert.assertEquals(" group-add=" + String.join(",", groups), dockerCommands.get(counter++)); - Assert.assertEquals(" hostname=ctr-id", dockerCommands.get(counter++)); + Assert.assertEquals(" hostname=" + nmHostName, dockerCommands.get(counter++)); Assert .assertEquals(" image=busybox:latest", dockerCommands.get(counter++)); Assert.assertEquals( @@ -887,7 +922,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); @@ -897,6 +934,7 @@ public void testLaunchPrivilegedContainersWithEnabledSettingAndDefaultACL() int expected = 16; int counter = 0; + Assert.assertEquals(expected, dockerCommands.size()); Assert.assertEquals("[docker-command-execution]", dockerCommands.get(counter++)); @@ -907,7 +945,12 @@ public void testLaunchPrivilegedContainersWithEnabledSettingAndDefaultACL() Assert.assertEquals(" docker-command=run", dockerCommands.get(counter++)); Assert.assertEquals(" group-add=" + String.join(",", groups), dockerCommands.get(counter++)); - Assert.assertEquals(" hostname=ctr-id", dockerCommands.get(counter++)); + + final Map environment = + ctx.getContainer().getLaunchContext().getEnvironment(); + String nmHostName = environment.get(NM_HOST.name()); + Assert.assertEquals(" hostname=" + nmHostName, dockerCommands.get + (counter++)); Assert .assertEquals(" image=busybox:latest", dockerCommands.get(counter++)); Assert.assertEquals( @@ -1004,7 +1047,8 @@ public void testMountSourceTarget() DockerLinuxContainerRuntime.ENV_DOCKER_CONTAINER_LOCAL_RESOURCE_MOUNTS, "test_dir/test_resource_file:test_mount"); - runtime.launchContainer(builder.build()); + ContainerRuntimeContext ctx = builder.build(); + runtime.launchContainer(ctx); PrivilegedOperation op = capturePrivilegedOperationAndVerifyArgs(); List args = op.getArguments(); String dockerCommandFile = args.get(11); @@ -1024,7 +1068,12 @@ public void testMountSourceTarget() Assert.assertEquals(" docker-command=run", dockerCommands.get(counter++)); Assert.assertEquals(" group-add=" + String.join(",", groups), dockerCommands.get(counter++)); - Assert.assertEquals(" hostname=ctr-id", dockerCommands.get(counter++)); + + final Map environment = + ctx.getContainer().getLaunchContext().getEnvironment(); + String nmHostName = environment.get(NM_HOST.name()); + Assert.assertEquals(" hostname=" + nmHostName, dockerCommands.get + (counter++)); Assert.assertEquals(" image=busybox:latest", dockerCommands.get(counter++)); Assert.assertEquals( @@ -1077,7 +1126,8 @@ public void testMountMultiple() "test_dir/test_resource_file:test_mount1," + "test_dir/test_resource_file:test_mount2"); - runtime.launchContainer(builder.build()); + ContainerRuntimeContext ctx = builder.build(); + runtime.launchContainer(ctx); PrivilegedOperation op = capturePrivilegedOperationAndVerifyArgs(); List args = op.getArguments(); String dockerCommandFile = args.get(11); @@ -1087,6 +1137,10 @@ public void testMountMultiple() 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++)); @@ -1097,7 +1151,7 @@ public void testMountMultiple() Assert.assertEquals(" docker-command=run", dockerCommands.get(counter++)); Assert.assertEquals(" group-add=" + String.join(",", groups), dockerCommands.get(counter++)); - Assert.assertEquals(" hostname=ctr-id", dockerCommands.get(counter++)); + Assert.assertEquals(" hostname=" + nmHostName, dockerCommands.get(counter++)); Assert.assertEquals(" image=busybox:latest", dockerCommands.get(counter++)); Assert.assertEquals( @@ -1132,7 +1186,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); @@ -1142,6 +1197,11 @@ public void testUserMounts() 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++)); @@ -1152,7 +1212,8 @@ public void testUserMounts() Assert.assertEquals(" docker-command=run", dockerCommands.get(counter++)); Assert.assertEquals(" group-add=" + String.join(",", groups), dockerCommands.get(counter++)); - Assert.assertEquals(" hostname=ctr-id", dockerCommands.get(counter++)); + Assert.assertEquals(" hostname="+nmHostName, dockerCommands.get + (counter++)); Assert.assertEquals(" image=busybox:latest", dockerCommands.get(counter++)); Assert.assertEquals( @@ -1637,6 +1698,11 @@ public void testDockerCommandPlugin() throws Exception { int expected = 16; int counter = 0; + + final Map environment = + containerRuntimeContext.getContainer().getLaunchContext() + .getEnvironment(); + String nmHostName = environment.get(NM_HOST.name()); Assert.assertEquals(expected, dockerCommands.size()); Assert.assertEquals("[docker-command-execution]", dockerCommands.get(counter++)); @@ -1647,7 +1713,8 @@ public void testDockerCommandPlugin() throws Exception { Assert.assertEquals(" docker-command=run", dockerCommands.get(counter++)); Assert.assertEquals(" group-add=" + String.join(",", groups), dockerCommands.get(counter++)); - Assert.assertEquals(" hostname=ctr-id", dockerCommands.get(counter++)); + Assert.assertEquals(" hostname=" +nmHostName, dockerCommands.get + (counter++)); Assert .assertEquals(" image=busybox:latest", dockerCommands.get(counter++)); Assert.assertEquals( @@ -1744,7 +1811,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, @@ -1777,6 +1846,10 @@ public void testLaunchContainerWithDockerTokens() int expected = 16; 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++)); @@ -1789,7 +1862,9 @@ public void testLaunchContainerWithDockerTokens() dockerCommands.get(counter++)); Assert.assertEquals(" group-add=" + String.join(",", groups), dockerCommands.get(counter++)); - Assert.assertEquals(" hostname=ctr-id", dockerCommands.get(counter++)); + + + Assert.assertEquals(" hostname=" + nmHostName, dockerCommands.get(counter++)); Assert.assertEquals(" image=busybox:latest", dockerCommands.get(counter++)); Assert.assertEquals( @@ -1874,4 +1949,42 @@ public void reapContainer(ContainerRuntimeContext ctx) } } } + + @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"); + + 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", shellContent + .contains("export CONTAINER_HOSTNAME=\"" + nmHostName + "\"")); + fos.flush(); + fos.close(); + } }