dockerCommands = Files.readAllLines(Paths.get
+ (dockerCommandFile), Charset.forName("UTF-8"));
+
+ int expected = 15;
+ int counter = 0;
+ Assert.assertEquals(expected, dockerCommands.size());
+ Assert.assertEquals("[docker-command-execution]",
+ dockerCommands.get(counter++));
+ Assert.assertEquals(" cap-add=SYS_CHROOT,NET_BIND_SERVICE",
+ dockerCommands.get(counter++));
+ Assert.assertEquals(" cap-drop=ALL", dockerCommands.get(counter++));
+ Assert.assertEquals(" detach=true", dockerCommands.get(counter++));
+ Assert.assertEquals(" docker-command=run", dockerCommands.get(counter++));
+ Assert.assertEquals(" hostname=ctr-id", dockerCommands.get(counter++));
+ Assert
+ .assertEquals(" image=busybox:latest", dockerCommands.get(counter++));
+ Assert.assertEquals(
+ " launch-command=bash,/test_container_work_dir/launch_container.sh",
+ dockerCommands.get(counter++));
+ Assert.assertEquals(" name=container_id", dockerCommands.get(counter++));
+ Assert.assertEquals(" net=host", dockerCommands.get(counter++));
+ Assert.assertEquals(" ro-mounts=/source/path:/destination/path",
+ dockerCommands.get(counter++));
+ Assert.assertEquals(
+ " rw-mounts=/test_container_local_dir:/test_container_local_dir,"
+ + "/test_filecache_dir:/test_filecache_dir,"
+ + "/test_container_work_dir:/test_container_work_dir,"
+ + "/test_container_log_dir:/test_container_log_dir,"
+ + "/test_user_local_dir:/test_user_local_dir",
+ dockerCommands.get(counter++));
+ Assert.assertEquals(" user=run_as_user", dockerCommands.get(counter++));
+
+ // Verify volume-driver is set to expected value.
+ Assert.assertEquals(" volume-driver=driver-1",
+ dockerCommands.get(counter++));
+ Assert.assertEquals(" workdir=/test_container_work_dir",
+ dockerCommands.get(counter++));
+ }
}
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/TestJavaSandboxLinuxContainerRuntime.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/TestJavaSandboxLinuxContainerRuntime.java
index bdd435eb2ae..67252ea6515 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/TestJavaSandboxLinuxContainerRuntime.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/TestJavaSandboxLinuxContainerRuntime.java
@@ -55,7 +55,6 @@
import java.util.regex.Pattern;
import static org.apache.hadoop.yarn.api.ApplicationConstants.Environment.JAVA_HOME;
-import static org.apache.hadoop.yarn.server.nodemanager.containermanager.linux.runtime.JavaSandboxLinuxContainerRuntime.NMContainerPolicyUtils.LOG;
import static org.apache.hadoop.yarn.server.nodemanager.containermanager.linux.runtime.JavaSandboxLinuxContainerRuntime.NMContainerPolicyUtils.MULTI_COMMAND_REGEX;
import static org.apache.hadoop.yarn.server.nodemanager.containermanager.linux.runtime.JavaSandboxLinuxContainerRuntime.NMContainerPolicyUtils.CLEAN_CMD_REGEX;
import static org.apache.hadoop.yarn.server.nodemanager.containermanager.linux.runtime.JavaSandboxLinuxContainerRuntime.NMContainerPolicyUtils.CONTAINS_JAVA_CMD;
@@ -134,7 +133,7 @@ public void setup() throws Exception {
mockExecutor = mock(PrivilegedOperationExecutor.class);
runtime = new JavaSandboxLinuxContainerRuntime(mockExecutor);
- runtime.initialize(conf);
+ runtime.initialize(conf, null);
resources = new HashMap<>();
grantDir = new File(baseTestDirectory, "grantDir");
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/docker/TestDockerCommandExecutor.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/docker/TestDockerCommandExecutor.java
index 05b44b8a93c..c362787b5c4 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/docker/TestDockerCommandExecutor.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/docker/TestDockerCommandExecutor.java
@@ -85,7 +85,8 @@ public void setUp() throws Exception {
builder.setExecutionAttribute(CONTAINER_ID_STR, MOCK_CONTAINER_ID);
runtime.initialize(
- TestDockerContainerRuntime.enableMockContainerExecutor(configuration));
+ TestDockerContainerRuntime.enableMockContainerExecutor(configuration),
+ null);
}
@Test
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/docker/TestDockerVolumeCommand.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/docker/TestDockerVolumeCommand.java
new file mode 100644
index 00000000000..4d07c0a26b2
--- /dev/null
+++ 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/docker/TestDockerVolumeCommand.java
@@ -0,0 +1,45 @@
+/*
+ * 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 org.junit.Assert;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+public class TestDockerVolumeCommand {
+ @Test
+ public void testDockerVolumeCommand() {
+ DockerVolumeCommand dockerVolumeCommand = new DockerVolumeCommand("create");
+ assertEquals("volume", dockerVolumeCommand.getCommandOption());
+ Assert.assertTrue(
+ dockerVolumeCommand.getDockerCommandWithArguments().get("sub-command")
+ .contains("create"));
+
+ dockerVolumeCommand.setDriverName("driver1");
+ dockerVolumeCommand.setVolumeName("volume1");
+
+ Assert.assertTrue(
+ dockerVolumeCommand.getDockerCommandWithArguments().get("driver")
+ .contains("driver1"));
+
+ Assert.assertTrue(
+ dockerVolumeCommand.getDockerCommandWithArguments().get("volume")
+ .contains("volume1"));
+ }
+}
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/resourceplugin/gpu/TestGpuDockerCommandPlugin.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/resourceplugin/gpu/TestGpuDockerCommandPlugin.java
new file mode 100644
index 00000000000..83e4943db7c
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/resourceplugin/gpu/TestGpuDockerCommandPlugin.java
@@ -0,0 +1,216 @@
+/**
+ * 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.resourceplugin.gpu;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Sets;
+import com.sun.net.httpserver.HttpExchange;
+import com.sun.net.httpserver.HttpHandler;
+import com.sun.net.httpserver.HttpServer;
+import org.apache.commons.math3.stat.inference.TestUtils;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.yarn.api.records.ResourceInformation;
+import org.apache.hadoop.yarn.conf.YarnConfiguration;
+import org.apache.hadoop.yarn.server.nodemanager.containermanager.container.Container;
+import org.apache.hadoop.yarn.server.nodemanager.containermanager.container.ResourceMappings;
+import org.apache.hadoop.yarn.server.nodemanager.containermanager.linux.runtime.docker.DockerRunCommand;
+import org.apache.hadoop.yarn.server.nodemanager.containermanager.linux.runtime.docker.DockerVolumeCommand;
+import org.apache.hadoop.yarn.server.nodemanager.containermanager.runtime.ContainerExecutionException;
+import org.apache.hadoop.yarn.util.resource.TestResourceUtils;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.InetSocketAddress;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class TestGpuDockerCommandPlugin {
+ private Map> copyCommandLine(
+ Map> map) {
+ Map> ret = new HashMap<>();
+ for (Map.Entry> entry : map.entrySet()) {
+ ret.put(entry.getKey(), new ArrayList<>(entry.getValue()));
+ }
+ return ret;
+ }
+
+ private boolean commandlinesEquals(Map> cli1,
+ Map> cli2) {
+ if (!Sets.symmetricDifference(cli1.keySet(), cli2.keySet()).isEmpty()) {
+ return false;
+ }
+
+ for (String key : cli1.keySet()) {
+ List value1 = cli1.get(key);
+ List value2 = cli2.get(key);
+ if (!value1.equals(value2)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ static class MyHandler implements HttpHandler {
+ String response = "This is the response";
+
+ @Override
+ public void handle(HttpExchange t) throws IOException {
+ t.sendResponseHeaders(200, response.length());
+ OutputStream os = t.getResponseBody();
+ os.write(response.getBytes());
+ os.close();
+ }
+ }
+
+ static class MyGpuDockerCommandPlugin extends GpuDockerCommandPlugin {
+ private boolean requestsGpu = false;
+
+ public MyGpuDockerCommandPlugin(Configuration conf) {
+ super(conf);
+ }
+
+ public void setRequestsGpu(boolean r) {
+ requestsGpu = r;
+ }
+
+ @Override
+ protected boolean requestsGpu(Container container) {
+ return requestsGpu;
+ }
+ }
+
+ @Test
+ public void testPlugin() throws Exception {
+ Configuration conf = new Configuration();
+
+ DockerRunCommand runCommand = new DockerRunCommand("container_1", "user",
+ "fakeimage");
+
+ Map> originalCommandline = copyCommandLine(
+ runCommand.getDockerCommandWithArguments());
+
+ MyGpuDockerCommandPlugin commandPlugin = new MyGpuDockerCommandPlugin(conf);
+
+ Container nmContainer = mock(Container.class);
+
+ // getResourceMapping is null, so commandline won't be updated
+ commandPlugin.updateDockerRunCommand(runCommand, nmContainer);
+ Assert.assertTrue(commandlinesEquals(originalCommandline,
+ runCommand.getDockerCommandWithArguments()));
+
+ // no GPU resource assigned, so commandline won't be updated
+ ResourceMappings resourceMappings = new ResourceMappings();
+ when(nmContainer.getResourceMappings()).thenReturn(resourceMappings);
+ commandPlugin.updateDockerRunCommand(runCommand, nmContainer);
+ Assert.assertTrue(commandlinesEquals(originalCommandline,
+ runCommand.getDockerCommandWithArguments()));
+
+ // Assign GPU resource, init will be invoked
+ ResourceMappings.AssignedResources assigned =
+ new ResourceMappings.AssignedResources();
+ assigned.updateAssignedResources(ImmutableList.of("0", "1"));
+ resourceMappings.addAssignedResources(ResourceInformation.GPU_URI,
+ assigned);
+
+ commandPlugin.setRequestsGpu(true);
+
+ // Since there's no HTTP server running, so we will see exception
+ boolean caughtException = false;
+ try {
+ commandPlugin.updateDockerRunCommand(runCommand, nmContainer);
+ } catch (ContainerExecutionException e) {
+ caughtException = true;
+ }
+ Assert.assertTrue(caughtException);
+
+ // Start HTTP server
+ MyHandler handler = new MyHandler();
+ HttpServer server = HttpServer.create(new InetSocketAddress(60111), 0);
+ server.createContext("/test", handler);
+ server.start();
+
+ String hostName = server.getAddress().getHostName();
+ int port = server.getAddress().getPort();
+ String httpUrl = "http://" + hostName + ":" + port + "/test";
+
+ conf.set(YarnConfiguration.NVIDIA_DOCKER_PLUGIN_ENDPOINT, httpUrl);
+
+ commandPlugin = new MyGpuDockerCommandPlugin(conf);
+
+ // Start use invalid options
+ handler.response = "INVALID_RESPONSE";
+ try {
+ commandPlugin.updateDockerRunCommand(runCommand, nmContainer);
+ } catch (ContainerExecutionException e) {
+ caughtException = true;
+ }
+ Assert.assertTrue(caughtException);
+
+ // Start use invalid options
+ handler.response = "INVALID_RESPONSE";
+ try {
+ commandPlugin.updateDockerRunCommand(runCommand, nmContainer);
+ } catch (ContainerExecutionException e) {
+ caughtException = true;
+ }
+ Assert.assertTrue(caughtException);
+
+ /* Test get docker run command */
+ handler.response = "--device=/dev/nvidiactl --device=/dev/nvidia-uvm "
+ + "--device=/dev/nvidia0 --device=/dev/nvidia1 "
+ + "--volume-driver=nvidia-docker "
+ + "--volume=nvidia_driver_352.68:/usr/local/nvidia:ro";
+
+ commandPlugin.setRequestsGpu(true);
+ commandPlugin.updateDockerRunCommand(runCommand, nmContainer);
+ Map> newCommandLine =
+ runCommand.getDockerCommandWithArguments();
+
+ // Command line will be updated
+ Assert.assertFalse(commandlinesEquals(originalCommandline, newCommandLine));
+ // Volume driver should not be included by final commandline
+ Assert.assertFalse(newCommandLine.containsKey("volume-driver"));
+ Assert.assertTrue(newCommandLine.containsKey("devices"));
+ Assert.assertTrue(newCommandLine.containsKey("ro-mounts"));
+
+ /* Test get docker volume command */
+ commandPlugin = new MyGpuDockerCommandPlugin(conf);
+
+ // When requests Gpu == false, returned docker volume command is null,
+ Assert.assertNull(commandPlugin.createDockerVolume(nmContainer));
+
+ // set requests Gpu to true
+ commandPlugin.setRequestsGpu(true);
+
+ DockerVolumeCommand dockerVolumeCommand = commandPlugin.createDockerVolume(
+ nmContainer);
+ Assert.assertEquals(
+ "volume docker-command=volume " + "driver=nvidia-docker "
+ + "sub-command=create " + "volume=nvidia_driver_352.68",
+ dockerVolumeCommand.toString());
+ }
+}
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/recovery/NMMemoryStateStoreService.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/recovery/NMMemoryStateStoreService.java
index 59a225ad188..c8f3c41e9ea 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/recovery/NMMemoryStateStoreService.java
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/recovery/NMMemoryStateStoreService.java
@@ -41,6 +41,7 @@
import org.apache.hadoop.yarn.proto.YarnServerNodemanagerRecoveryProtos.LogDeleterProto;
import org.apache.hadoop.yarn.server.api.records.MasterKey;
import org.apache.hadoop.yarn.server.api.records.impl.pb.MasterKeyPBImpl;
+import org.apache.hadoop.yarn.server.nodemanager.containermanager.container.Container;
import org.apache.hadoop.yarn.server.nodemanager.containermanager.container.ResourceMappings;
public class NMMemoryStateStoreService extends NMStateStoreService {
@@ -497,14 +498,17 @@ public synchronized void removeAMRMProxyAppContext(
}
@Override
- public void storeAssignedResources(ContainerId containerId,
+ public void storeAssignedResources(Container container,
String resourceType, List assignedResources)
throws IOException {
ResourceMappings.AssignedResources ar =
new ResourceMappings.AssignedResources();
ar.updateAssignedResources(assignedResources);
- containerStates.get(containerId).getResourceMappings()
+ containerStates.get(container.getContainerId()).getResourceMappings()
.addAssignedResources(resourceType, ar);
+
+ // update container resource mapping.
+ updateContainerResourceMapping(container, resourceType, assignedResources);
}
private static class TrackerState {
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/recovery/TestNMLeveldbStateStoreService.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/recovery/TestNMLeveldbStateStoreService.java
index 8c13356cb22..c471abfc332 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/recovery/TestNMLeveldbStateStoreService.java
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/recovery/TestNMLeveldbStateStoreService.java
@@ -29,6 +29,7 @@
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.timeout;
import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
import java.io.File;
import java.io.IOException;
@@ -69,6 +70,8 @@
import org.apache.hadoop.yarn.security.ContainerTokenIdentifier;
import org.apache.hadoop.yarn.server.api.records.MasterKey;
import org.apache.hadoop.yarn.server.nodemanager.amrmproxy.AMRMProxyTokenSecretManager;
+import org.apache.hadoop.yarn.server.nodemanager.containermanager.container.Container;
+import org.apache.hadoop.yarn.server.nodemanager.containermanager.container.ResourceMappings;
import org.apache.hadoop.yarn.server.nodemanager.recovery.NMStateStoreService.LocalResourceTrackerState;
import org.apache.hadoop.yarn.server.nodemanager.recovery.NMStateStoreService.RecoveredAMRMProxyState;
import org.apache.hadoop.yarn.server.nodemanager.recovery.NMStateStoreService.RecoveredApplicationsState;
@@ -1118,16 +1121,21 @@ public void testStateStoreForResourceMapping() throws IOException {
ContainerId containerId = ContainerId.newContainerId(appAttemptId, 5);
storeMockContainer(containerId);
+ Container container = mock(Container.class);
+ when(container.getContainerId()).thenReturn(containerId);
+ ResourceMappings resourceMappings = new ResourceMappings();
+ when(container.getResourceMappings()).thenReturn(resourceMappings);
+
// Store ResourceMapping
- stateStore.storeAssignedResources(containerId, "gpu",
+ stateStore.storeAssignedResources(container, "gpu",
Arrays.asList("1", "2", "3"));
// This will overwrite above
List gpuRes1 = Arrays.asList("1", "2", "4");
- stateStore.storeAssignedResources(containerId, "gpu", gpuRes1);
+ stateStore.storeAssignedResources(container, "gpu", gpuRes1);
List fpgaRes = Arrays.asList("3", "4", "5", "6");
- stateStore.storeAssignedResources(containerId, "fpga", fpgaRes);
+ stateStore.storeAssignedResources(container, "fpga", fpgaRes);
List numaRes = Arrays.asList("numa1");
- stateStore.storeAssignedResources(containerId, "numa", numaRes);
+ stateStore.storeAssignedResources(container, "numa", numaRes);
// add a invalid key
restartStateStore();
@@ -1137,12 +1145,18 @@ public void testStateStoreForResourceMapping() throws IOException {
List res = rcs.getResourceMappings()
.getAssignedResources("gpu");
Assert.assertTrue(res.equals(gpuRes1));
+ Assert.assertTrue(
+ resourceMappings.getAssignedResources("gpu").equals(gpuRes1));
res = rcs.getResourceMappings().getAssignedResources("fpga");
Assert.assertTrue(res.equals(fpgaRes));
+ Assert.assertTrue(
+ resourceMappings.getAssignedResources("fpga").equals(fpgaRes));
res = rcs.getResourceMappings().getAssignedResources("numa");
Assert.assertTrue(res.equals(numaRes));
+ Assert.assertTrue(
+ resourceMappings.getAssignedResources("numa").equals(numaRes));
}
private StartContainerRequest storeMockContainer(ContainerId containerId)