From 881112d3aa8acefc1d9bb67ab80490debe2d3a09 Mon Sep 17 00:00:00 2001 From: Rohan Kumar Date: Thu, 29 Nov 2018 22:22:44 +0530 Subject: [PATCH] Fix #541: Allow @sha256 digest for tags in FROM --- .../maven/docker/access/UrlBuilder.java | 2 +- .../fabric8/maven/docker/util/ImageName.java | 81 ++++++++++++------- .../maven/docker/util/ImageNameTest.java | 2 + 3 files changed, 54 insertions(+), 31 deletions(-) diff --git a/src/main/java/io/fabric8/maven/docker/access/UrlBuilder.java b/src/main/java/io/fabric8/maven/docker/access/UrlBuilder.java index 71c13ae29..afe223d3f 100644 --- a/src/main/java/io/fabric8/maven/docker/access/UrlBuilder.java +++ b/src/main/java/io/fabric8/maven/docker/access/UrlBuilder.java @@ -98,7 +98,7 @@ public String loadImage() { public String pullImage(ImageName name, String registry) { return u("images/create") .p("fromImage", name.getNameWithoutTag(registry)) - .p("tag", name.getTag()) + .p("tag", name.getDigest() != null ? name.getDigest() : name.getTag()) .build(); } diff --git a/src/main/java/io/fabric8/maven/docker/util/ImageName.java b/src/main/java/io/fabric8/maven/docker/util/ImageName.java index 937181f28..39a64426e 100644 --- a/src/main/java/io/fabric8/maven/docker/util/ImageName.java +++ b/src/main/java/io/fabric8/maven/docker/util/ImageName.java @@ -37,6 +37,9 @@ public class ImageName { // Tag name private String tag; + // Digest + private String digest; + // User name private String user; @@ -60,38 +63,46 @@ public ImageName(String fullName, String givenTag) { if (fullName == null) { throw new NullPointerException("Image name must not be null"); } - Pattern tagPattern = Pattern.compile("^(.+?)(?::([^:/]+))?$"); - Matcher matcher = tagPattern.matcher(fullName); - if (!matcher.matches()) { - throw new IllegalArgumentException(fullName + " is not a proper image name ([registry/][repo][:port]"); - } - tag = givenTag != null ? givenTag : matcher.group(2); - String rest = matcher.group(1); - - String[] parts = rest.split("\\s*/\\s*"); - if (parts.length == 1) { - registry = null; - user = null; - repository = parts[0]; - } else if (parts.length >= 2) { - if (isRegistry(parts[0])) { - registry = parts[0]; - if (parts.length > 2) { - user = parts[1]; - repository = joinTail(parts); + + if(fullName.contains("@sha256")) { // Of it contains digest + String[] digestParts = fullName.split("@"); + digest = digestParts[1]; + repository = digestParts[0]; + } else { + digest = null; + Pattern tagPattern = Pattern.compile("^(.+?)(?::([^:/]+))?$"); + Matcher matcher = tagPattern.matcher(fullName); + if (!matcher.matches()) { + throw new IllegalArgumentException(fullName + " is not a proper image name ([registry/][repo][:port]"); + } + tag = givenTag != null ? givenTag : matcher.group(2); + String rest = matcher.group(1); + + String[] parts = rest.split("\\s*/\\s*"); + if (parts.length == 1) { + registry = null; + user = null; + repository = parts[0]; + } else if (parts.length >= 2) { + if (isRegistry(parts[0])) { + registry = parts[0]; + if (parts.length > 2) { + user = parts[1]; + repository = joinTail(parts); + } else { + user = null; + repository = parts[1]; + } } else { - user = null; - repository = parts[1]; + registry = null; + user = parts[0]; + repository = rest; } - } else { - registry = null; - user = parts[0]; - repository = rest; } - } - if (tag == null) { - tag = "latest"; + if (tag == null) { + tag = "latest"; + } } doValidate(); @@ -109,6 +120,10 @@ public String getTag() { return tag; } + public String getDigest() { + return digest; + } + public boolean hasRegistry() { return registry != null && registry.length() > 0; } @@ -177,6 +192,9 @@ public String getFullName() { * @return full name with original registry (if set) or optional registry (if not null). */ public String getFullName(String optionalRegistry) { + if(digest != null) { + return getNameWithoutTag(optionalRegistry) + "@" + digest; + } return getNameWithoutTag(optionalRegistry) + ":" + tag; } @@ -214,13 +232,14 @@ public static void validate(String image) { // Validate parts and throw an IllegalArgumentException if a part is not valid private void doValidate() { List errors = new ArrayList<>(); - // Stripp of user from repository name + // Strip off user from repository name String image = user != null ? repository.substring(user.length() + 1) : repository; Object[] checks = new Object[] { "registry", DOMAIN_REGEXP, registry, "image", IMAGE_NAME_REGEXP, image, "user", NAME_COMP_REGEXP, user, - "tag", TAG_REGEXP, tag + "tag", TAG_REGEXP, tag, + "digest", DIGEST_REGEXP, digest }; for (int i = 0; i < checks.length; i +=3) { String value = (String) checks[i + 2]; @@ -268,4 +287,6 @@ private void doValidate() { // https://github.com/docker/docker/blob/04da4041757370fb6f85510c8977c5a18ddae380/vendor/github.com/docker/distribution/reference/regexp.go#L37 private final Pattern TAG_REGEXP = Pattern.compile("^[\\w][\\w.-]{0,127}$"); + + private final Pattern DIGEST_REGEXP = Pattern.compile("^sha256:[a-z0-9]{32,}$"); } diff --git a/src/test/java/io/fabric8/maven/docker/util/ImageNameTest.java b/src/test/java/io/fabric8/maven/docker/util/ImageNameTest.java index 0a2afb249..2c142c8b4 100644 --- a/src/test/java/io/fabric8/maven/docker/util/ImageNameTest.java +++ b/src/test/java/io/fabric8/maven/docker/util/ImageNameTest.java @@ -125,6 +125,8 @@ public void testRegistryNamingExtended() throws Exception { new ImageName("docker.jolokia.org/org/jolokia/jolokia_demo").getFullName("another.registry.org")); assertEquals("docker.jolokia.org/org/jolokia/jolokia_demo:latest", new ImageName("docker.jolokia.org/org/jolokia/jolokia_demo").getFullName(null)); + assertEquals("docker.jolokia.org/org/jolokia/jolokia_demo@sha256:2781907cc3ae9bb732076f14392128d4b84ff3ebb66379d268e563b10fbfb9da", + new ImageName("docker.jolokia.org/org/jolokia/jolokia_demo@sha256:2781907cc3ae9bb732076f14392128d4b84ff3ebb66379d268e563b10fbfb9da").getFullName(null)); }