JCLOUDS-1158 fix Docker find image Predicate for cases where repoTags field contains 'docker.io/' registry host prefix
Project: http://git-wip-us.apache.org/repos/asf/jclouds-labs/repo Commit: http://git-wip-us.apache.org/repos/asf/jclouds-labs/commit/44946467 Tree: http://git-wip-us.apache.org/repos/asf/jclouds-labs/tree/44946467 Diff: http://git-wip-us.apache.org/repos/asf/jclouds-labs/diff/44946467 Branch: refs/heads/master Commit: 44946467a1c79239dc3e1aa949de01617027b2bb Parents: 66c7617 Author: Josef Cacek <[email protected]> Authored: Mon Aug 22 15:21:09 2016 +0200 Committer: Ignasi Barrera <[email protected]> Committed: Mon Aug 29 22:31:44 2016 +0200 ---------------------------------------------------------------------- .../strategy/DockerComputeServiceAdapter.java | 43 +++++-- .../DockerComputeServiceAdapterLiveTest.java | 4 +- .../PredicateLocateImageByNameTest.java | 111 +++++++++++++++++++ 3 files changed, 146 insertions(+), 12 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/44946467/docker/src/main/java/org/jclouds/docker/compute/strategy/DockerComputeServiceAdapter.java ---------------------------------------------------------------------- diff --git a/docker/src/main/java/org/jclouds/docker/compute/strategy/DockerComputeServiceAdapter.java b/docker/src/main/java/org/jclouds/docker/compute/strategy/DockerComputeServiceAdapter.java index 8130838..690b50e 100644 --- a/docker/src/main/java/org/jclouds/docker/compute/strategy/DockerComputeServiceAdapter.java +++ b/docker/src/main/java/org/jclouds/docker/compute/strategy/DockerComputeServiceAdapter.java @@ -22,6 +22,7 @@ import static com.google.common.collect.Iterables.find; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.regex.Pattern; import javax.annotation.Resource; import javax.inject.Inject; @@ -67,6 +68,21 @@ import org.jclouds.logging.Logger; public class DockerComputeServiceAdapter implements ComputeServiceAdapter<Container, Hardware, Image, Location> { + + /** + * Some Docker versions returns host prefix even for images from Docker hub in repoTags field. We use this constant + * to correctly identify requested image name. + */ + public static final String PREFIX_DOCKER_HUB_HOST = "docker.io/"; + + /** + * (Optional) Suffix used, when image version is not used during searching images. + */ + public static final String SUFFIX_LATEST_VERSION = ":latest"; + + private static final String PATTERN_IMAGE_PREFIX = "^(" + Pattern.quote(PREFIX_DOCKER_HUB_HOST) + ")?"; + private static final String PATTERN_IMAGE_SUFFIX = "(" + Pattern.quote(SUFFIX_LATEST_VERSION) + ")?$"; + @Resource @Named(ComputeServiceConstants.COMPUTE_LOGGER) protected Logger logger = Logger.NULL; @@ -266,17 +282,7 @@ public class DockerComputeServiceAdapter implements api.getImageApi().createImage(CreateImageOptions.Builder.fromImage(imageIdOrName)); // as above this ensure repotags are returned - return find(listImages(), new Predicate<Image>() { - @Override - public boolean apply(Image input) { - for (String tag : input.repoTags()) { - if (tag.equals(imageIdOrName) || tag.equals(imageIdOrName + ":latest")) { - return true; - } - } - return false; - } - }, null); + return find(listImages(), createPredicateMatchingRepoTags(imageIdOrName), null); } @Override @@ -329,4 +335,19 @@ public class DockerComputeServiceAdapter implements api.getContainerApi().pause(id); } + protected static Predicate<Image> createPredicateMatchingRepoTags(final String imageIdOrName) { + final Pattern imgPattern = Pattern + .compile(PATTERN_IMAGE_PREFIX + Pattern.quote(imageIdOrName) + PATTERN_IMAGE_SUFFIX); + return new Predicate<Image>() { + @Override + public boolean apply(Image input) { + for (String tag : input.repoTags()) { + if (imgPattern.matcher(tag).matches()) { + return true; + } + } + return false; + } + }; + } } http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/44946467/docker/src/test/java/org/jclouds/docker/compute/DockerComputeServiceAdapterLiveTest.java ---------------------------------------------------------------------- diff --git a/docker/src/test/java/org/jclouds/docker/compute/DockerComputeServiceAdapterLiveTest.java b/docker/src/test/java/org/jclouds/docker/compute/DockerComputeServiceAdapterLiveTest.java index c37c474..72fc8d5 100644 --- a/docker/src/test/java/org/jclouds/docker/compute/DockerComputeServiceAdapterLiveTest.java +++ b/docker/src/test/java/org/jclouds/docker/compute/DockerComputeServiceAdapterLiveTest.java @@ -148,7 +148,9 @@ public class DockerComputeServiceAdapterLiveTest extends BaseDockerApiLiveTest { @Override public boolean apply(Image input) { for (String tag : input.repoTags()) { - if (tag.equals(image) || tag.equals(CHUANWEN_COWSAY + ":latest")) { + if (tag.equals(CHUANWEN_COWSAY + DockerComputeServiceAdapter.SUFFIX_LATEST_VERSION) + || tag.equals(DockerComputeServiceAdapter.PREFIX_DOCKER_HUB_HOST + CHUANWEN_COWSAY + + DockerComputeServiceAdapter.SUFFIX_LATEST_VERSION)) { return true; } } http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/44946467/docker/src/test/java/org/jclouds/docker/compute/strategy/PredicateLocateImageByNameTest.java ---------------------------------------------------------------------- diff --git a/docker/src/test/java/org/jclouds/docker/compute/strategy/PredicateLocateImageByNameTest.java b/docker/src/test/java/org/jclouds/docker/compute/strategy/PredicateLocateImageByNameTest.java new file mode 100644 index 0000000..dd8b654 --- /dev/null +++ b/docker/src/test/java/org/jclouds/docker/compute/strategy/PredicateLocateImageByNameTest.java @@ -0,0 +1,111 @@ +/* + * 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.jclouds.docker.compute.strategy; + +import static org.testng.Assert.assertFalse; +import static org.testng.Assert.assertTrue; + +import java.util.Date; + +import org.jclouds.docker.domain.Config; +import org.jclouds.docker.domain.Image; +import org.testng.annotations.Test; + +import com.google.common.base.Predicate; +import com.google.common.collect.ImmutableList; + +/** + * Unit tests for finding images logic used in + * {@link DockerComputeServiceAdapter#getImage(String)} method. It's mainly a + * regression test for issue + * <a href="https://issues.apache.org/jira/browse/JCLOUDS-1158">JCLOUDS-1158</a> + * . + */ +@Test(groups = "unit", testName = "PredicateLocateImageByNameTest") +public class PredicateLocateImageByNameTest { + + private static final Image IMAGE_REPO_TAGS_MULTI = Image.create("id", // id + "author", "comment", Config.builder().image("imageId").build(), Config.builder().image("imageId").build(), + "parent", // parent + new Date(), // created + "containerId", // container + "1.3.1", // dockerVersion + "x86_64", // architecture + "os", // os + 0l, // size + 0l, // virtualSize + ImmutableList.<String> of("kwart/alpine-ext:3.3-ssh", "kwart/alpine-ext:latest", "my-tag:latestdock") // repoTags + ); + + private static final Image IMAGE_REPO_TAGS_EMPTY = Image.create("id", // id + "author", "comment", Config.builder().image("imageId").build(), Config.builder().image("imageId").build(), + "parent", // parent + new Date(), // created + "containerId", // container + "1.3.1", // dockerVersion + "x86_64", // architecture + "os", // os + 0l, // size + 0l, // virtualSize + ImmutableList.<String> of() // repoTags + ); + + private static final Image IMAGE_REPO_TAGS_WITH_HOST = Image.create("id", // id + "author", "comment", Config.builder().image("imageId").build(), Config.builder().image("imageId").build(), + "parent", // parent + new Date(), // created + "containerId", // container + "1.3.1", // dockerVersion + "x86_64", // architecture + "os", // os + 0l, // size + 0l, // virtualSize + ImmutableList.<String> of("docker.io/kwart/alpine-ext:3.3-ssh", "docker.io/kwart/alpine-ext:latest") // repoTags + ); + + public void testRepoTagVersion() { + final Predicate<Image> predicate = DockerComputeServiceAdapter + .createPredicateMatchingRepoTags("kwart/alpine-ext:3.3-ssh"); + assertTrue(predicate.apply(IMAGE_REPO_TAGS_MULTI)); + assertFalse(predicate.apply(IMAGE_REPO_TAGS_EMPTY)); + assertTrue(predicate.apply(IMAGE_REPO_TAGS_WITH_HOST)); + } + + public void testRepoTagLatest() { + final Predicate<Image> predicate = DockerComputeServiceAdapter.createPredicateMatchingRepoTags("kwart/alpine-ext"); + assertTrue(predicate.apply(IMAGE_REPO_TAGS_MULTI)); + assertFalse(predicate.apply(IMAGE_REPO_TAGS_EMPTY)); + assertTrue(predicate.apply(IMAGE_REPO_TAGS_WITH_HOST)); + } + + public void testRepoTagVersionWithHost() { + final Predicate<Image> predicate = DockerComputeServiceAdapter + .createPredicateMatchingRepoTags("docker.io/kwart/alpine-ext:3.3-ssh"); + assertFalse(predicate.apply(IMAGE_REPO_TAGS_MULTI)); + assertFalse(predicate.apply(IMAGE_REPO_TAGS_EMPTY)); + assertTrue(predicate.apply(IMAGE_REPO_TAGS_WITH_HOST)); + } + + public void testRepoTagLatestWithHost() { + final Predicate<Image> predicate = DockerComputeServiceAdapter + .createPredicateMatchingRepoTags("docker.io/kwart/alpine-ext"); + assertFalse(predicate.apply(IMAGE_REPO_TAGS_MULTI)); + assertFalse(predicate.apply(IMAGE_REPO_TAGS_EMPTY)); + assertTrue(predicate.apply(IMAGE_REPO_TAGS_WITH_HOST)); + } + +}
