diff --git a/jib-core/src/main/java/com/google/cloud/tools/jib/registry/RegistryAliasGroup.java b/jib-core/src/main/java/com/google/cloud/tools/jib/registry/RegistryAliasGroup.java new file mode 100644 index 0000000000..58c988414d --- /dev/null +++ b/jib-core/src/main/java/com/google/cloud/tools/jib/registry/RegistryAliasGroup.java @@ -0,0 +1,53 @@ +/* + * Copyright 2018 Google LLC. All rights reserved. + * + * Licensed 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 com.google.cloud.tools.jib.registry; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableSet; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +/** Provides known aliases for a given registry. */ +public class RegistryAliasGroup { + + private static final ImmutableList> REGISTRY_ALIAS_GROUPS = + ImmutableList.of( + // Docker Hub alias group + ImmutableSet.of("registry.hub.docker.com", "index.docker.io")); + + /** + * Returns the list of registry aliases for the given {@code registry}, including {@code registry} + * as the first element. + * + * @param registry the registry for which the alias group is requested + * @return non-empty list of registries where {@code registry} is the first element + */ + public static List getAliasesGroup(String registry) { + for (ImmutableSet aliasGroup : REGISTRY_ALIAS_GROUPS) { + if (aliasGroup.contains(registry)) { + // Found a group. Move the requested "registry" to the front before returning it. + Stream self = Stream.of(registry); + Stream withoutSelf = aliasGroup.stream().filter(alias -> !registry.equals(alias)); + return Stream.concat(self, withoutSelf).collect(Collectors.toList()); + } + } + + return Collections.singletonList(registry); + } +} diff --git a/jib-core/src/main/java/com/google/cloud/tools/jib/registry/credentials/DockerConfigCredentialRetriever.java b/jib-core/src/main/java/com/google/cloud/tools/jib/registry/credentials/DockerConfigCredentialRetriever.java index 4670214931..53be488636 100644 --- a/jib-core/src/main/java/com/google/cloud/tools/jib/registry/credentials/DockerConfigCredentialRetriever.java +++ b/jib-core/src/main/java/com/google/cloud/tools/jib/registry/credentials/DockerConfigCredentialRetriever.java @@ -19,6 +19,7 @@ import com.google.cloud.tools.jib.http.Authorization; import com.google.cloud.tools.jib.http.Authorizations; import com.google.cloud.tools.jib.json.JsonTemplateMapper; +import com.google.cloud.tools.jib.registry.RegistryAliasGroup; import com.google.cloud.tools.jib.registry.credentials.json.DockerConfigTemplate; import com.google.common.annotations.VisibleForTesting; import java.io.IOException; @@ -86,6 +87,17 @@ public Authorization retrieve() throws IOException { return null; } + for (String registry : RegistryAliasGroup.getAliasesGroup(registry)) { + Authorization authorization = retrieve(dockerConfigTemplate, registry); + if (authorization != null) { + return authorization; + } + } + return null; + } + + @Nullable + private Authorization retrieve(DockerConfigTemplate dockerConfigTemplate, String registry) { // First, tries to find defined auth. String auth = dockerConfigTemplate.getAuthFor(registry); if (auth != null) { diff --git a/jib-core/src/test/java/com/google/cloud/tools/jib/registry/RegistryAliasGroupTest.java b/jib-core/src/test/java/com/google/cloud/tools/jib/registry/RegistryAliasGroupTest.java new file mode 100644 index 0000000000..90dc98e2d8 --- /dev/null +++ b/jib-core/src/test/java/com/google/cloud/tools/jib/registry/RegistryAliasGroupTest.java @@ -0,0 +1,47 @@ +/* + * Copyright 2018 Google LLC. All rights reserved. + * + * Licensed 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 com.google.cloud.tools.jib.registry; + +import java.util.Arrays; +import java.util.List; +import org.junit.Assert; +import org.junit.Test; + +/** Tests for {@link RegistryAliasGroup}. */ +public class RegistryAliasGroupTest { + + @Test + public void testGetAliasesGroup_noKnownAliases() { + List singleton = RegistryAliasGroup.getAliasesGroup("something.gcr.io"); + Assert.assertEquals(1, singleton.size()); + Assert.assertEquals("something.gcr.io", singleton.get(0)); + } + + @Test + public void testGetAliasesGroup_registryHubDockerCom() { + Assert.assertEquals( + Arrays.asList("registry.hub.docker.com", "index.docker.io"), + RegistryAliasGroup.getAliasesGroup("registry.hub.docker.com")); + } + + @Test + public void testGetAliasesGroup_indexDockerIo() { + Assert.assertEquals( + Arrays.asList("index.docker.io", "registry.hub.docker.com"), + RegistryAliasGroup.getAliasesGroup("index.docker.io")); + } +} diff --git a/jib-core/src/test/java/com/google/cloud/tools/jib/registry/credentials/DockerConfigCredentialRetrieverTest.java b/jib-core/src/test/java/com/google/cloud/tools/jib/registry/credentials/DockerConfigCredentialRetrieverTest.java index 256e3384e0..b295157617 100644 --- a/jib-core/src/test/java/com/google/cloud/tools/jib/registry/credentials/DockerConfigCredentialRetrieverTest.java +++ b/jib-core/src/test/java/com/google/cloud/tools/jib/registry/credentials/DockerConfigCredentialRetrieverTest.java @@ -118,4 +118,21 @@ public void testRetrieve_none() throws IOException { Assert.assertNull(dockerConfigCredentialRetriever.retrieve()); } + + @Test + public void testRetrieve_credentialFromAlias() throws IOException { + Mockito.when(mockDockerCredentialHelperFactory.withCredentialHelperSuffix(Mockito.anyString())) + .thenReturn(Mockito.mock(DockerCredentialHelper.class)); + Mockito.when( + mockDockerCredentialHelperFactory.withCredentialHelperSuffix( + "index.docker.io credential helper")) + .thenReturn(mockDockerCredentialHelper); + + DockerConfigCredentialRetriever dockerConfigCredentialRetriever = + new DockerConfigCredentialRetriever( + "registry.hub.docker.com", dockerConfigFile, mockDockerCredentialHelperFactory); + + Authorization authorization = dockerConfigCredentialRetriever.retrieve(); + Assert.assertEquals(mockAuthorization, authorization); + } } diff --git a/jib-core/src/test/resources/json/dockerconfig.json b/jib-core/src/test/resources/json/dockerconfig.json index a4cbe7a126..cc8c1d9093 100644 --- a/jib-core/src/test/resources/json/dockerconfig.json +++ b/jib-core/src/test/resources/json/dockerconfig.json @@ -1 +1,15 @@ -{"auths":{"some other registry":{"auth":"some other auth"},"some registry":{"auth":"some auth","password":"ignored"},"https://registry":{"auth":"token"},"just registry":{},"https://with.protocol":{}},"credsStore":"some credential store","credHelpers":{"another registry":"another credential helper","some registry":"some credential helper"}} \ No newline at end of file +{ + "auths":{ + "some other registry":{"auth":"some other auth"}, + "some registry":{"auth":"some auth","password":"ignored"}, + "https://registry":{"auth":"token"}, + "just registry":{}, + "https://with.protocol":{} + }, + "credsStore":"some credential store", + "credHelpers":{ + "another registry":"another credential helper", + "some registry":"some credential helper", + "index.docker.io":"index.docker.io credential helper" + } +} \ No newline at end of file diff --git a/jib-gradle-plugin/CHANGELOG.md b/jib-gradle-plugin/CHANGELOG.md index a158c61885..9b24c56728 100644 --- a/jib-gradle-plugin/CHANGELOG.md +++ b/jib-gradle-plugin/CHANGELOG.md @@ -7,6 +7,7 @@ All notable changes to this project will be documented in this file. - Snapshot dependencies are added as their own layer ([#584](https://github.com/GoogleContainerTools/jib/pull/584)) - `jibBuildTar` task to build an image tarball at `build/jib-image.tar`, which can be loaded into docker using `docker load` ([#514](https://github.com/GoogleContainerTools/jib/issues/514)) +- For Docker Hub, also tries registry aliases when getting a credential from the Docker config ### Changed diff --git a/jib-maven-plugin/CHANGELOG.md b/jib-maven-plugin/CHANGELOG.md index 7d21c8224d..6db12229a2 100644 --- a/jib-maven-plugin/CHANGELOG.md +++ b/jib-maven-plugin/CHANGELOG.md @@ -7,6 +7,7 @@ All notable changes to this project will be documented in this file. - Snapshot dependencies are added as their own layer ([#584](https://github.com/GoogleContainerTools/jib/pull/584)) - `jib:buildTar` goal to build an image tarball at `target/jib-image.tar`, which can be loaded into docker using `docker load` ([#514](https://github.com/GoogleContainerTools/jib/issues/514)) +- For Docker Hub, also tries registry aliases when getting a credential from the Docker config ### Changed