YARN-11364. Docker Container to accept docker Image name with sha256 digest (#5092)

Co-authored-by: Ashutosh Gupta <ashugpt@amazon.com>
Reviewed-by: slfan1989 <55643692+slfan1989@users.noreply.github.com>
Signed-off-by: Chris Nauroth <cnauroth@apache.org>
This commit is contained in:
Ashutosh Gupta 2022-11-01 21:44:35 +00:00 committed by GitHub
parent 69225ae5b9
commit 83acb55981
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 33 additions and 15 deletions

View File

@ -208,6 +208,8 @@ public class DockerLinuxContainerRuntime extends OCIContainerRuntime {
private static final Pattern dockerImagePattern = private static final Pattern dockerImagePattern =
Pattern.compile(DOCKER_IMAGE_PATTERN); Pattern.compile(DOCKER_IMAGE_PATTERN);
private static final Pattern DOCKER_DIGEST_PATTERN = Pattern.compile("^sha256:[a-z0-9]{12,64}$");
private static final String DEFAULT_PROCFS = "/proc"; private static final String DEFAULT_PROCFS = "/proc";
@InterfaceAudience.Private @InterfaceAudience.Private
@ -1201,9 +1203,17 @@ public static void validateImageName(String imageName)
throw new ContainerExecutionException( throw new ContainerExecutionException(
ENV_DOCKER_CONTAINER_IMAGE + " not set!"); ENV_DOCKER_CONTAINER_IMAGE + " not set!");
} }
if (!dockerImagePattern.matcher(imageName).matches()) { // check if digest is part of imageName, extract and validate it.
throw new ContainerExecutionException("Image name '" + imageName String digest = null;
+ "' doesn't match docker image name pattern"); if (imageName.contains("@sha256")) {
String[] digestParts = imageName.split("@");
digest = digestParts[1];
imageName = digestParts[0];
}
if (!dockerImagePattern.matcher(imageName).matches() || (digest != null
&& !DOCKER_DIGEST_PATTERN.matcher(digest).matches())) {
throw new ContainerExecutionException(
"Image name '" + imageName + "' doesn't match docker image name pattern");
} }
} }

View File

@ -2033,19 +2033,27 @@ public static Configuration enableMockContainerExecutor(Configuration conf) {
@Test @Test
public void testDockerImageNamePattern() throws Exception { public void testDockerImageNamePattern() throws Exception {
String[] validNames = String[] validNames = {"ubuntu", "fedora/httpd:version1.0", "fedora/httpd:version1.0.test",
{ "ubuntu", "fedora/httpd:version1.0", "fedora/httpd:version1.0.TEST", "myregistryhost:5000/ubuntu",
"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",
"myregistryhost:5000/fedora/httpd:version1.0.test", "myregistryhost:5000/fedora/httpd:version1.0.test",
"myregistryhost:5000/fedora/httpd:version1.0.TEST"}; "myregistryhost:5000/fedora/httpd:version1.0.TEST",
"123456789123.dkr.ecr.us-east-1.amazonaws.com/emr-docker-examples:pyspark-example"
+ "@sha256:f1d4ae3f7261a72e98c6ebefe9985cf10a0ea5bd762585a43e0700ed99863807"};
String[] invalidNames = { "Ubuntu", "ubuntu || fedora", "ubuntu#", String[] invalidNames = {"Ubuntu", "ubuntu || fedora", "ubuntu#", "myregistryhost:50AB0/ubuntu",
"myregistryhost:50AB0/ubuntu", "myregistry#host:50AB0/ubuntu", "myregistry#host:50AB0/ubuntu", ":8080/ubuntu",
":8080/ubuntu"
}; // Invalid: contains "@sha256" but doesn't really contain a digest.
"123456789123.dkr.ecr.us-east-1.amazonaws.com/emr-docker-examples:pyspark-example@sha256",
// Invalid: digest is too short.
"123456789123.dkr.ecr.us-east-1.amazonaws.com/emr-docker-examples:pyspark-example"
+ "@sha256:f1d4",
// Invalid: digest is too long
"123456789123.dkr.ecr.us-east-1.amazonaws.com/emr-docker-examples:pyspark-example"
+ "@sha256:f1d4ae3f7261a72e98c6ebefe9985cf10a0ea5bd762585a43e0700ed99863807f"};
for (String name : validNames) { for (String name : validNames) {
DockerLinuxContainerRuntime.validateImageName(name); DockerLinuxContainerRuntime.validateImageName(name);