Validate docker image name before launching container.

This commit is contained in:
Varun Vasudev 2017-05-18 11:53:16 +05:30
parent 9791ecc9d8
commit 51e65cc710
2 changed files with 49 additions and 4 deletions

View File

@ -51,6 +51,7 @@ import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.regex.Pattern;
import static org.apache.hadoop.yarn.server.nodemanager.containermanager.linux.runtime.LinuxContainerRuntimeConstants.*; import static org.apache.hadoop.yarn.server.nodemanager.containermanager.linux.runtime.LinuxContainerRuntimeConstants.*;
@ -60,6 +61,12 @@ public class DockerLinuxContainerRuntime implements LinuxContainerRuntime {
private static final Log LOG = LogFactory.getLog( private static final Log LOG = LogFactory.getLog(
DockerLinuxContainerRuntime.class); DockerLinuxContainerRuntime.class);
// This validates that the image is a proper docker image
public static final String DOCKER_IMAGE_PATTERN =
"^(([a-zA-Z0-9.-]+)(:\\d+)?/)?([a-z0-9_./-]+)(:[\\w.-]+)?$";
private static final Pattern dockerImagePattern =
Pattern.compile(DOCKER_IMAGE_PATTERN);
@InterfaceAudience.Private @InterfaceAudience.Private
public static final String ENV_DOCKER_CONTAINER_IMAGE = public static final String ENV_DOCKER_CONTAINER_IMAGE =
"YARN_CONTAINER_RUNTIME_DOCKER_IMAGE"; "YARN_CONTAINER_RUNTIME_DOCKER_IMAGE";
@ -216,10 +223,7 @@ public class DockerLinuxContainerRuntime implements LinuxContainerRuntime {
.getEnvironment(); .getEnvironment();
String imageName = environment.get(ENV_DOCKER_CONTAINER_IMAGE); String imageName = environment.get(ENV_DOCKER_CONTAINER_IMAGE);
if (imageName == null) { validateImageName(imageName);
throw new ContainerExecutionException(ENV_DOCKER_CONTAINER_IMAGE
+ " not set!");
}
String containerIdStr = container.getContainerId().toString(); String containerIdStr = container.getContainerId().toString();
String runAsUser = ctx.getExecutionAttribute(RUN_AS_USER); String runAsUser = ctx.getExecutionAttribute(RUN_AS_USER);
@ -354,4 +358,16 @@ public class DockerLinuxContainerRuntime implements LinuxContainerRuntime {
throws ContainerExecutionException { throws ContainerExecutionException {
} }
public static void validateImageName(String imageName)
throws ContainerExecutionException {
if (imageName == null || imageName.isEmpty()) {
throw new ContainerExecutionException(
ENV_DOCKER_CONTAINER_IMAGE + " not set!");
}
if (!dockerImagePattern.matcher(imageName).matches()) {
throw new ContainerExecutionException("Image name '" + imageName
+ "' doesn't match docker image name pattern");
}
}
} }

View File

@ -388,4 +388,33 @@ public class TestDockerContainerRuntime {
+ ": " + command, command.contains("--privileged")); + ": " + command, command.contains("--privileged"));
} }
@Test
public void testDockerImageNamePattern() throws Exception {
String[] validNames =
{ "ubuntu", "fedora/httpd:version1.0",
"fedora/httpd:version1.0.test",
"fedora/httpd:version1.0.TEST",
"myregistryhost:5000/ubuntu",
"myregistryhost:5000/fedora/httpd:version1.0",
"myregistryhost:5000/fedora/httpd:version1.0.test",
"myregistryhost:5000/fedora/httpd:version1.0.TEST"};
String[] invalidNames = { "Ubuntu", "ubuntu || fedora", "ubuntu#",
"myregistryhost:50AB0/ubuntu", "myregistry#host:50AB0/ubuntu",
":8080/ubuntu"
};
for (String name : validNames) {
DockerLinuxContainerRuntime.validateImageName(name);
}
for (String name : invalidNames) {
try {
DockerLinuxContainerRuntime.validateImageName(name);
Assert.fail(name + " is an invalid name and should fail the regex");
} catch (ContainerExecutionException ce) {
continue;
}
}
}
} }