From 4c1cfc3e3f8a23519533c004cdef7dbfc8a82d90 Mon Sep 17 00:00:00 2001 From: Qingyang Chen Date: Mon, 18 Jun 2018 16:52:57 -0400 Subject: [PATCH 1/5] Don't try to authenticate pull unless the image requires authentication. --- .../cloud/tools/jib/builder/BuildSteps.java | 4 - .../builder/steps/AuthenticatePullStep.java | 86 ----------- .../steps/PullAndCacheBaseImageLayerStep.java | 20 ++- .../PullAndCacheBaseImageLayersStep.java | 8 +- .../jib/builder/steps/PullBaseImageStep.java | 136 +++++++++++------- .../tools/jib/builder/steps/StepsRunner.java | 24 +--- .../AuthenticationMethodRetriever.java | 15 +- .../jib/registry/RegistryAuthenticators.java | 14 +- .../tools/jib/registry/RegistryClient.java | 5 + 9 files changed, 126 insertions(+), 186 deletions(-) delete mode 100644 jib-core/src/main/java/com/google/cloud/tools/jib/builder/steps/AuthenticatePullStep.java diff --git a/jib-core/src/main/java/com/google/cloud/tools/jib/builder/BuildSteps.java b/jib-core/src/main/java/com/google/cloud/tools/jib/builder/BuildSteps.java index 27f002a01e..0360894f6d 100644 --- a/jib-core/src/main/java/com/google/cloud/tools/jib/builder/BuildSteps.java +++ b/jib-core/src/main/java/com/google/cloud/tools/jib/builder/BuildSteps.java @@ -76,9 +76,7 @@ public static BuildSteps forBuildToDockerRegistry( stepsRunner -> stepsRunner .runRetrieveTargetRegistryCredentialsStep() - .runRetrieveBaseRegistryCredentialsStep() .runAuthenticatePushStep() - .runAuthenticatePullStep() .runPullBaseImageStep() .runPullAndCacheBaseImageLayersStep() .runPushBaseImageLayersStep() @@ -114,8 +112,6 @@ public static BuildSteps forBuildToDockerDaemon( SUCCESS_MESSAGE_FORMAT_FOR_DOCKER_DAEMON, buildConfiguration.getTargetImageReference()), stepsRunner -> stepsRunner - .runRetrieveBaseRegistryCredentialsStep() - .runAuthenticatePullStep() .runPullBaseImageStep() .runPullAndCacheBaseImageLayersStep() .runBuildAndCacheApplicationLayerSteps() diff --git a/jib-core/src/main/java/com/google/cloud/tools/jib/builder/steps/AuthenticatePullStep.java b/jib-core/src/main/java/com/google/cloud/tools/jib/builder/steps/AuthenticatePullStep.java deleted file mode 100644 index f30e6458f1..0000000000 --- a/jib-core/src/main/java/com/google/cloud/tools/jib/builder/steps/AuthenticatePullStep.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * 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.builder.steps; - -import com.google.cloud.tools.jib.Timer; -import com.google.cloud.tools.jib.async.AsyncStep; -import com.google.cloud.tools.jib.async.NonBlockingSteps; -import com.google.cloud.tools.jib.builder.BuildConfiguration; -import com.google.cloud.tools.jib.http.Authorization; -import com.google.cloud.tools.jib.registry.RegistryAuthenticationFailedException; -import com.google.cloud.tools.jib.registry.RegistryAuthenticator; -import com.google.cloud.tools.jib.registry.RegistryAuthenticators; -import com.google.cloud.tools.jib.registry.RegistryException; -import com.google.common.util.concurrent.Futures; -import com.google.common.util.concurrent.ListenableFuture; -import com.google.common.util.concurrent.ListeningExecutorService; -import java.io.IOException; -import java.util.concurrent.Callable; -import java.util.concurrent.ExecutionException; - -/** - * Authenticates pull from the base image registry using Docker Token Authentication. - * - * @see https://docs.docker.com/registry/spec/auth/token/ - */ -class AuthenticatePullStep implements AsyncStep, Callable { - - private static final String DESCRIPTION = "Authenticating pull from %s"; - - private final BuildConfiguration buildConfiguration; - private final RetrieveRegistryCredentialsStep retrieveBaseRegistryCredentialsStep; - - private final ListenableFuture listenableFuture; - - AuthenticatePullStep( - ListeningExecutorService listeningExecutorService, - BuildConfiguration buildConfiguration, - RetrieveRegistryCredentialsStep retrieveBaseRegistryCredentialsStep) { - this.buildConfiguration = buildConfiguration; - this.retrieveBaseRegistryCredentialsStep = retrieveBaseRegistryCredentialsStep; - - listenableFuture = - Futures.whenAllSucceed(retrieveBaseRegistryCredentialsStep.getFuture()) - .call(this, listeningExecutorService); - } - - @Override - public ListenableFuture getFuture() { - return listenableFuture; - } - - @Override - public Authorization call() - throws RegistryAuthenticationFailedException, IOException, RegistryException, - ExecutionException { - try (Timer ignored = - new Timer( - buildConfiguration.getBuildLogger(), - String.format(DESCRIPTION, buildConfiguration.getBaseImageRegistry()))) { - Authorization registryCredentials = NonBlockingSteps.get(retrieveBaseRegistryCredentialsStep); - RegistryAuthenticator registryAuthenticator = - RegistryAuthenticators.forOther( - buildConfiguration.getBaseImageRegistry(), - buildConfiguration.getBaseImageRepository()); - if (registryAuthenticator == null) { - return registryCredentials; - } - return registryAuthenticator.setAuthorization(registryCredentials).authenticatePull(); - } - } -} diff --git a/jib-core/src/main/java/com/google/cloud/tools/jib/builder/steps/PullAndCacheBaseImageLayerStep.java b/jib-core/src/main/java/com/google/cloud/tools/jib/builder/steps/PullAndCacheBaseImageLayerStep.java index f228cc2318..449d771aca 100644 --- a/jib-core/src/main/java/com/google/cloud/tools/jib/builder/steps/PullAndCacheBaseImageLayerStep.java +++ b/jib-core/src/main/java/com/google/cloud/tools/jib/builder/steps/PullAndCacheBaseImageLayerStep.java @@ -18,23 +18,22 @@ import com.google.cloud.tools.jib.Timer; import com.google.cloud.tools.jib.async.AsyncStep; -import com.google.cloud.tools.jib.async.NonBlockingSteps; import com.google.cloud.tools.jib.builder.BuildConfiguration; import com.google.cloud.tools.jib.cache.Cache; import com.google.cloud.tools.jib.cache.CacheReader; import com.google.cloud.tools.jib.cache.CacheWriter; import com.google.cloud.tools.jib.cache.CachedLayer; +import com.google.cloud.tools.jib.http.Authorization; import com.google.cloud.tools.jib.image.DescriptorDigest; import com.google.cloud.tools.jib.image.LayerPropertyNotFoundException; import com.google.cloud.tools.jib.registry.RegistryClient; import com.google.cloud.tools.jib.registry.RegistryException; import com.google.common.io.CountingOutputStream; -import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListeningExecutorService; import java.io.IOException; import java.util.concurrent.Callable; -import java.util.concurrent.ExecutionException; +import javax.annotation.Nullable; /** Pulls and caches a single base image layer. */ class PullAndCacheBaseImageLayerStep implements AsyncStep, Callable { @@ -44,7 +43,7 @@ class PullAndCacheBaseImageLayerStep implements AsyncStep, Callable private final BuildConfiguration buildConfiguration; private final Cache cache; private final DescriptorDigest layerDigest; - private final AuthenticatePullStep authenticatePullStep; + private final @Nullable Authorization pullAuthorization; private final ListenableFuture listenableFuture; @@ -53,15 +52,13 @@ class PullAndCacheBaseImageLayerStep implements AsyncStep, Callable BuildConfiguration buildConfiguration, Cache cache, DescriptorDigest layerDigest, - AuthenticatePullStep authenticatePullStep) { + @Nullable Authorization pullAuthorization) { this.buildConfiguration = buildConfiguration; this.cache = cache; this.layerDigest = layerDigest; - this.authenticatePullStep = authenticatePullStep; + this.pullAuthorization = pullAuthorization; - listenableFuture = - Futures.whenAllSucceed(authenticatePullStep.getFuture()) - .call(this, listeningExecutorService); + listenableFuture = listeningExecutorService.submit(this); } @Override @@ -70,13 +67,12 @@ public ListenableFuture getFuture() { } @Override - public CachedLayer call() - throws IOException, RegistryException, LayerPropertyNotFoundException, ExecutionException { + public CachedLayer call() throws IOException, RegistryException, LayerPropertyNotFoundException { try (Timer ignored = new Timer(buildConfiguration.getBuildLogger(), String.format(DESCRIPTION, layerDigest))) { RegistryClient registryClient = new RegistryClient( - NonBlockingSteps.get(authenticatePullStep), + pullAuthorization, buildConfiguration.getBaseImageRegistry(), buildConfiguration.getBaseImageRepository()); diff --git a/jib-core/src/main/java/com/google/cloud/tools/jib/builder/steps/PullAndCacheBaseImageLayersStep.java b/jib-core/src/main/java/com/google/cloud/tools/jib/builder/steps/PullAndCacheBaseImageLayersStep.java index d03487699f..7fb23e3549 100644 --- a/jib-core/src/main/java/com/google/cloud/tools/jib/builder/steps/PullAndCacheBaseImageLayersStep.java +++ b/jib-core/src/main/java/com/google/cloud/tools/jib/builder/steps/PullAndCacheBaseImageLayersStep.java @@ -39,7 +39,6 @@ class PullAndCacheBaseImageLayersStep private final BuildConfiguration buildConfiguration; private final Cache cache; - private final AuthenticatePullStep authenticatePullStep; private final PullBaseImageStep pullBaseImageStep; private final ListeningExecutorService listeningExecutorService; @@ -49,12 +48,10 @@ class PullAndCacheBaseImageLayersStep ListeningExecutorService listeningExecutorService, BuildConfiguration buildConfiguration, Cache cache, - AuthenticatePullStep authenticatePullStep, PullBaseImageStep pullBaseImageStep) { this.listeningExecutorService = listeningExecutorService; this.buildConfiguration = buildConfiguration; this.cache = cache; - this.authenticatePullStep = authenticatePullStep; this.pullBaseImageStep = pullBaseImageStep; listenableFuture = @@ -70,7 +67,8 @@ public ListenableFuture> getFuture public ImmutableList call() throws ExecutionException, LayerPropertyNotFoundException { try (Timer ignored = new Timer(buildConfiguration.getBuildLogger(), DESCRIPTION)) { - ImmutableList baseImageLayers = NonBlockingSteps.get(pullBaseImageStep).getLayers(); + PullBaseImageStep.Result pullBaseImageStepResult = NonBlockingSteps.get(pullBaseImageStep); + ImmutableList baseImageLayers = pullBaseImageStepResult.getBaseImage().getLayers(); ImmutableList.Builder pullAndCacheBaseImageLayerStepsBuilder = ImmutableList.builderWithExpectedSize(baseImageLayers.size()); @@ -81,7 +79,7 @@ public ImmutableList call() buildConfiguration, cache, layer.getBlobDescriptor().getDigest(), - authenticatePullStep)); + pullBaseImageStepResult.getBaseImageAuthorization())); } return pullAndCacheBaseImageLayerStepsBuilder.build(); diff --git a/jib-core/src/main/java/com/google/cloud/tools/jib/builder/steps/PullBaseImageStep.java b/jib-core/src/main/java/com/google/cloud/tools/jib/builder/steps/PullBaseImageStep.java index 37f9c3c01e..2c243cd178 100644 --- a/jib-core/src/main/java/com/google/cloud/tools/jib/builder/steps/PullBaseImageStep.java +++ b/jib-core/src/main/java/com/google/cloud/tools/jib/builder/steps/PullBaseImageStep.java @@ -21,6 +21,8 @@ import com.google.cloud.tools.jib.async.NonBlockingSteps; import com.google.cloud.tools.jib.blob.Blobs; import com.google.cloud.tools.jib.builder.BuildConfiguration; +import com.google.cloud.tools.jib.builder.steps.PullBaseImageStep.Result; +import com.google.cloud.tools.jib.http.Authorization; import com.google.cloud.tools.jib.image.Image; import com.google.cloud.tools.jib.image.Layer; import com.google.cloud.tools.jib.image.LayerCountMismatchException; @@ -34,44 +36,61 @@ import com.google.cloud.tools.jib.json.JsonTemplateMapper; import com.google.cloud.tools.jib.registry.RegistryClient; import com.google.cloud.tools.jib.registry.RegistryException; -import com.google.common.util.concurrent.Futures; +import com.google.cloud.tools.jib.registry.RegistryUnauthorizedException; import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListeningExecutorService; +import com.google.common.util.concurrent.MoreExecutors; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; +import javax.annotation.Nullable; /** Pulls the base image manifest. */ -class PullBaseImageStep implements AsyncStep>, Callable> { +class PullBaseImageStep implements AsyncStep, Callable { private static final String DESCRIPTION = "Pulling base image manifest"; + /** Structure for the result returned by this step. */ + static class Result { + + private final Image baseImage; + private final @Nullable Authorization baseImageAuthorization; + + private Result(Image baseImage, @Nullable Authorization baseImageAuthorization) { + this.baseImage = baseImage; + this.baseImageAuthorization = baseImageAuthorization; + } + + Image getBaseImage() { + return baseImage; + } + + @Nullable + Authorization getBaseImageAuthorization() { + return baseImageAuthorization; + } + } + private final BuildConfiguration buildConfiguration; - private final AuthenticatePullStep authenticatePullStep; - private final ListenableFuture> listenableFuture; + private final ListenableFuture listenableFuture; PullBaseImageStep( - ListeningExecutorService listeningExecutorService, - BuildConfiguration buildConfiguration, - AuthenticatePullStep authenticatePullStep) { + ListeningExecutorService listeningExecutorService, BuildConfiguration buildConfiguration) { this.buildConfiguration = buildConfiguration; - this.authenticatePullStep = authenticatePullStep; - listenableFuture = - Futures.whenAllSucceed(authenticatePullStep.getFuture()) - .call(this, listeningExecutorService); + listenableFuture = listeningExecutorService.submit(this); } @Override - public ListenableFuture> getFuture() { + public ListenableFuture getFuture() { return listenableFuture; } @Override - public Image call() + public Result call() throws IOException, RegistryException, LayerPropertyNotFoundException, LayerCountMismatchException, ExecutionException { buildConfiguration @@ -79,44 +98,63 @@ public Image call() .lifecycle("Getting base image " + buildConfiguration.getBaseImageReference() + "..."); try (Timer ignored = new Timer(buildConfiguration.getBuildLogger(), DESCRIPTION)) { - RegistryClient registryClient = - new RegistryClient( - NonBlockingSteps.get(authenticatePullStep), - buildConfiguration.getBaseImageRegistry(), - buildConfiguration.getBaseImageRepository()); - - ManifestTemplate manifestTemplate = - registryClient.pullManifest(buildConfiguration.getBaseImageTag()); - - // TODO: Make schema version be enum. - switch (manifestTemplate.getSchemaVersion()) { - case 1: - V21ManifestTemplate v21ManifestTemplate = (V21ManifestTemplate) manifestTemplate; - return JsonToImageTranslator.toImage(v21ManifestTemplate); - - case 2: - V22ManifestTemplate v22ManifestTemplate = (V22ManifestTemplate) manifestTemplate; - if (v22ManifestTemplate.getContainerConfiguration() == null - || v22ManifestTemplate.getContainerConfiguration().getDigest() == null) { - throw new UnknownManifestFormatException( - "Invalid container configuration in Docker V2.2 manifest: \n" - + Blobs.writeToString(JsonTemplateMapper.toBlob(v22ManifestTemplate))); - } - - ByteArrayOutputStream containerConfigurationOutputStream = new ByteArrayOutputStream(); - registryClient.pullBlob( - v22ManifestTemplate.getContainerConfiguration().getDigest(), - containerConfigurationOutputStream); - String containerConfigurationString = - new String(containerConfigurationOutputStream.toByteArray(), StandardCharsets.UTF_8); - - ContainerConfigurationTemplate containerConfigurationTemplate = - JsonTemplateMapper.readJson( - containerConfigurationString, ContainerConfigurationTemplate.class); - return JsonToImageTranslator.toImage(v22ManifestTemplate, containerConfigurationTemplate); + // First, try with no credentials. + try { + return new Result(pullBaseImage(null), null); + + } catch (RegistryUnauthorizedException ex) { + // If failed, then, retrieve base registry credentials and try with retrieved credentials. + ListeningExecutorService directExecutorService = MoreExecutors.newDirectExecutorService(); + RetrieveRegistryCredentialsStep retrieveBaseRegistryCredentialsStep = + RetrieveRegistryCredentialsStep.forBaseImage(directExecutorService, buildConfiguration); + + Authorization registryCredentials = + NonBlockingSteps.get(retrieveBaseRegistryCredentialsStep); + return new Result(pullBaseImage(registryCredentials), registryCredentials); } + } + } - throw new IllegalStateException("Unknown manifest schema version"); + private Image pullBaseImage(@Nullable Authorization registryCredentials) + throws IOException, RegistryException, LayerPropertyNotFoundException, + LayerCountMismatchException { + RegistryClient registryClient = + new RegistryClient( + registryCredentials, + buildConfiguration.getBaseImageRegistry(), + buildConfiguration.getBaseImageRepository()); + + ManifestTemplate manifestTemplate = + registryClient.pullManifest(buildConfiguration.getBaseImageTag()); + + // TODO: Make schema version be enum. + switch (manifestTemplate.getSchemaVersion()) { + case 1: + V21ManifestTemplate v21ManifestTemplate = (V21ManifestTemplate) manifestTemplate; + return JsonToImageTranslator.toImage(v21ManifestTemplate); + + case 2: + V22ManifestTemplate v22ManifestTemplate = (V22ManifestTemplate) manifestTemplate; + if (v22ManifestTemplate.getContainerConfiguration() == null + || v22ManifestTemplate.getContainerConfiguration().getDigest() == null) { + throw new UnknownManifestFormatException( + "Invalid container configuration in Docker V2.2 manifest: \n" + + Blobs.writeToString(JsonTemplateMapper.toBlob(v22ManifestTemplate))); + } + + ByteArrayOutputStream containerConfigurationOutputStream = new ByteArrayOutputStream(); + registryClient.pullBlob( + v22ManifestTemplate.getContainerConfiguration().getDigest(), + containerConfigurationOutputStream); + String containerConfigurationString = + new String(containerConfigurationOutputStream.toByteArray(), StandardCharsets.UTF_8); + + ContainerConfigurationTemplate containerConfigurationTemplate = + JsonTemplateMapper.readJson( + containerConfigurationString, ContainerConfigurationTemplate.class); + return JsonToImageTranslator.toImage(v22ManifestTemplate, containerConfigurationTemplate); } + + throw new IllegalStateException("Unknown manifest schema version"); } } diff --git a/jib-core/src/main/java/com/google/cloud/tools/jib/builder/steps/StepsRunner.java b/jib-core/src/main/java/com/google/cloud/tools/jib/builder/steps/StepsRunner.java index 5cbf107323..e749bb7180 100644 --- a/jib-core/src/main/java/com/google/cloud/tools/jib/builder/steps/StepsRunner.java +++ b/jib-core/src/main/java/com/google/cloud/tools/jib/builder/steps/StepsRunner.java @@ -45,9 +45,7 @@ public class StepsRunner { private final Cache baseLayersCache; private final Cache applicationLayersCache; - @Nullable private RetrieveRegistryCredentialsStep retrieveBaseRegistryCredentialsStep; @Nullable private RetrieveRegistryCredentialsStep retrieveTargetRegistryCredentialsStep; - @Nullable private AuthenticatePullStep authenticatePullStep; @Nullable private AuthenticatePushStep authenticatePushStep; @Nullable private PullBaseImageStep pullBaseImageStep; @Nullable private PullAndCacheBaseImageLayersStep pullAndCacheBaseImageLayersStep; @@ -73,12 +71,6 @@ public StepsRunner( this.applicationLayersCache = applicationLayersCache; } - public StepsRunner runRetrieveBaseRegistryCredentialsStep() { - retrieveBaseRegistryCredentialsStep = - RetrieveRegistryCredentialsStep.forBaseImage(listeningExecutorService, buildConfiguration); - return this; - } - public StepsRunner runRetrieveTargetRegistryCredentialsStep() { retrieveTargetRegistryCredentialsStep = RetrieveRegistryCredentialsStep.forTargetImage( @@ -95,21 +87,8 @@ public StepsRunner runAuthenticatePushStep() { return this; } - public StepsRunner runAuthenticatePullStep() { - authenticatePullStep = - new AuthenticatePullStep( - listeningExecutorService, - buildConfiguration, - Preconditions.checkNotNull(retrieveBaseRegistryCredentialsStep)); - return this; - } - public StepsRunner runPullBaseImageStep() { - pullBaseImageStep = - new PullBaseImageStep( - listeningExecutorService, - buildConfiguration, - Preconditions.checkNotNull(authenticatePullStep)); + pullBaseImageStep = new PullBaseImageStep(listeningExecutorService, buildConfiguration); return this; } @@ -119,7 +98,6 @@ public StepsRunner runPullAndCacheBaseImageLayersStep() { listeningExecutorService, buildConfiguration, baseLayersCache, - Preconditions.checkNotNull(authenticatePullStep), Preconditions.checkNotNull(pullBaseImageStep)); return this; } diff --git a/jib-core/src/main/java/com/google/cloud/tools/jib/registry/AuthenticationMethodRetriever.java b/jib-core/src/main/java/com/google/cloud/tools/jib/registry/AuthenticationMethodRetriever.java index 07f1db09c2..c7a0883bf9 100644 --- a/jib-core/src/main/java/com/google/cloud/tools/jib/registry/AuthenticationMethodRetriever.java +++ b/jib-core/src/main/java/com/google/cloud/tools/jib/registry/AuthenticationMethodRetriever.java @@ -32,6 +32,10 @@ class AuthenticationMethodRetriever implements RegistryEndpointProvider getAccept() { return Collections.emptyList(); } + /** + * The request did not error, meaning that the registry does not require authentication. + * + * @param response ignored + * @return {@code null} + */ @Override @Nullable public RegistryAuthenticator handleResponse(Response response) { - // The registry does not require authentication. return null; } @@ -94,8 +103,4 @@ public RegistryAuthenticator handleHttpResponseException( .build(); } } - - AuthenticationMethodRetriever(RegistryEndpointProperties registryEndpointProperties) { - this.registryEndpointProperties = registryEndpointProperties; - } } diff --git a/jib-core/src/main/java/com/google/cloud/tools/jib/registry/RegistryAuthenticators.java b/jib-core/src/main/java/com/google/cloud/tools/jib/registry/RegistryAuthenticators.java index 2bbedf43e7..fca6c66ef2 100644 --- a/jib-core/src/main/java/com/google/cloud/tools/jib/registry/RegistryAuthenticators.java +++ b/jib-core/src/main/java/com/google/cloud/tools/jib/registry/RegistryAuthenticators.java @@ -28,12 +28,22 @@ public static RegistryAuthenticator forDockerHub(String repository) { "https://auth.docker.io/token", "registry.docker.io", repository); } + /** + * Gets a {@link RegistryAuthenticator} for a custom registry server and repository. + * + * @param serverUrl the server URL for the registry (for example, {@code gcr.io}) + * @param repository the image/repository name (also known as, namespace) + * @return the {@link RegistryAuthenticator} to authenticate pulls/pushes with the registry, or + * {@code null} if no token authentication is necessary + * @throws RegistryAuthenticationFailedException if failed to create the registry authenticator + * @throws IOException if communicating with the endpoint fails + * @throws RegistryException if communicating with the endpoint fails + */ @Nullable public static RegistryAuthenticator forOther(String serverUrl, String repository) throws RegistryAuthenticationFailedException, IOException, RegistryException { try { - RegistryClient registryClient = new RegistryClient(null, serverUrl, repository); - return registryClient.getRegistryAuthenticator(); + return new RegistryClient(null, serverUrl, repository).getRegistryAuthenticator(); } catch (MalformedURLException ex) { throw new RegistryAuthenticationFailedException(ex); diff --git a/jib-core/src/main/java/com/google/cloud/tools/jib/registry/RegistryClient.java b/jib-core/src/main/java/com/google/cloud/tools/jib/registry/RegistryClient.java index e90b65bfd8..444a3741ad 100644 --- a/jib-core/src/main/java/com/google/cloud/tools/jib/registry/RegistryClient.java +++ b/jib-core/src/main/java/com/google/cloud/tools/jib/registry/RegistryClient.java @@ -91,6 +91,11 @@ static String getUserAgent() { @Nullable private final Authorization authorization; private final RegistryEndpointProperties registryEndpointProperties; + /** + * @param authorization the {@link Authorization} to access the registry/repository + * @param serverUrl the server URL for the registry (for example, {@code gcr.io}) + * @param imageName the image/repository name (also known as, namespace) + */ public RegistryClient(@Nullable Authorization authorization, String serverUrl, String imageName) { this.authorization = authorization; this.registryEndpointProperties = new RegistryEndpointProperties(serverUrl, imageName); From 4f4d07b707e0c3e48c37e424b7cfb3cb3c80b1cf Mon Sep 17 00:00:00 2001 From: Qingyang Chen Date: Mon, 18 Jun 2018 17:12:55 -0400 Subject: [PATCH 2/5] Adds TODO. --- .../google/cloud/tools/jib/builder/steps/PullBaseImageStep.java | 1 + 1 file changed, 1 insertion(+) diff --git a/jib-core/src/main/java/com/google/cloud/tools/jib/builder/steps/PullBaseImageStep.java b/jib-core/src/main/java/com/google/cloud/tools/jib/builder/steps/PullBaseImageStep.java index 2c243cd178..afa0f2f520 100644 --- a/jib-core/src/main/java/com/google/cloud/tools/jib/builder/steps/PullBaseImageStep.java +++ b/jib-core/src/main/java/com/google/cloud/tools/jib/builder/steps/PullBaseImageStep.java @@ -104,6 +104,7 @@ public Result call() } catch (RegistryUnauthorizedException ex) { // If failed, then, retrieve base registry credentials and try with retrieved credentials. + // TODO: Refactor the logic in RetrieveRegistryCredentialsStep out to registry.credentials.RegistryCredentialsRetriever to avoid this direct executor hack. ListeningExecutorService directExecutorService = MoreExecutors.newDirectExecutorService(); RetrieveRegistryCredentialsStep retrieveBaseRegistryCredentialsStep = RetrieveRegistryCredentialsStep.forBaseImage(directExecutorService, buildConfiguration); From e3ac94c77205c5f1435dcf447c13603945e3b5e6 Mon Sep 17 00:00:00 2001 From: Qingyang Chen Date: Mon, 18 Jun 2018 17:25:02 -0400 Subject: [PATCH 3/5] Fixes format. --- .../cloud/tools/jib/builder/steps/PullBaseImageStep.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/jib-core/src/main/java/com/google/cloud/tools/jib/builder/steps/PullBaseImageStep.java b/jib-core/src/main/java/com/google/cloud/tools/jib/builder/steps/PullBaseImageStep.java index afa0f2f520..16f2ca658a 100644 --- a/jib-core/src/main/java/com/google/cloud/tools/jib/builder/steps/PullBaseImageStep.java +++ b/jib-core/src/main/java/com/google/cloud/tools/jib/builder/steps/PullBaseImageStep.java @@ -104,7 +104,8 @@ public Result call() } catch (RegistryUnauthorizedException ex) { // If failed, then, retrieve base registry credentials and try with retrieved credentials. - // TODO: Refactor the logic in RetrieveRegistryCredentialsStep out to registry.credentials.RegistryCredentialsRetriever to avoid this direct executor hack. + // TODO: Refactor the logic in RetrieveRegistryCredentialsStep out to + // registry.credentials.RegistryCredentialsRetriever to avoid this direct executor hack. ListeningExecutorService directExecutorService = MoreExecutors.newDirectExecutorService(); RetrieveRegistryCredentialsStep retrieveBaseRegistryCredentialsStep = RetrieveRegistryCredentialsStep.forBaseImage(directExecutorService, buildConfiguration); From 0cb792652974ce9791b213008c149ea52d1e95ee Mon Sep 17 00:00:00 2001 From: Qingyang Chen Date: Tue, 19 Jun 2018 11:23:41 -0400 Subject: [PATCH 4/5] Adds javadoc. --- .../tools/jib/builder/steps/PullBaseImageStep.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/jib-core/src/main/java/com/google/cloud/tools/jib/builder/steps/PullBaseImageStep.java b/jib-core/src/main/java/com/google/cloud/tools/jib/builder/steps/PullBaseImageStep.java index 16f2ca658a..89f7863018 100644 --- a/jib-core/src/main/java/com/google/cloud/tools/jib/builder/steps/PullBaseImageStep.java +++ b/jib-core/src/main/java/com/google/cloud/tools/jib/builder/steps/PullBaseImageStep.java @@ -117,6 +117,17 @@ public Result call() } } + /** + * Pulls the base image. + * + * @param registryCredentials authentication credentials to possibly use + * @return the pulled image + * @throws IOException when an I/O exception occurs during the pulling + * @throws RegistryException if communicating with the registry caused a known error + * @throws LayerCountMismatchException if the manifest and configuration contain conflicting layer + * information + * @throws LayerPropertyNotFoundException if adding image layers fails + */ private Image pullBaseImage(@Nullable Authorization registryCredentials) throws IOException, RegistryException, LayerPropertyNotFoundException, LayerCountMismatchException { From d3ce0bfd35b305d6ea71f15567725d0e6c328132 Mon Sep 17 00:00:00 2001 From: Qingyang Chen Date: Tue, 19 Jun 2018 14:06:54 -0400 Subject: [PATCH 5/5] Renames Result to BaseImageWithAuthorization. --- .../PullAndCacheBaseImageLayersStep.java | 3 ++- .../jib/builder/steps/PullBaseImageStep.java | 21 +++++++++++-------- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/jib-core/src/main/java/com/google/cloud/tools/jib/builder/steps/PullAndCacheBaseImageLayersStep.java b/jib-core/src/main/java/com/google/cloud/tools/jib/builder/steps/PullAndCacheBaseImageLayersStep.java index 7fb23e3549..26eef859b2 100644 --- a/jib-core/src/main/java/com/google/cloud/tools/jib/builder/steps/PullAndCacheBaseImageLayersStep.java +++ b/jib-core/src/main/java/com/google/cloud/tools/jib/builder/steps/PullAndCacheBaseImageLayersStep.java @@ -20,6 +20,7 @@ import com.google.cloud.tools.jib.async.AsyncStep; import com.google.cloud.tools.jib.async.NonBlockingSteps; import com.google.cloud.tools.jib.builder.BuildConfiguration; +import com.google.cloud.tools.jib.builder.steps.PullBaseImageStep.BaseImageWithAuthorization; import com.google.cloud.tools.jib.cache.Cache; import com.google.cloud.tools.jib.image.Layer; import com.google.cloud.tools.jib.image.LayerPropertyNotFoundException; @@ -67,7 +68,7 @@ public ListenableFuture> getFuture public ImmutableList call() throws ExecutionException, LayerPropertyNotFoundException { try (Timer ignored = new Timer(buildConfiguration.getBuildLogger(), DESCRIPTION)) { - PullBaseImageStep.Result pullBaseImageStepResult = NonBlockingSteps.get(pullBaseImageStep); + BaseImageWithAuthorization pullBaseImageStepResult = NonBlockingSteps.get(pullBaseImageStep); ImmutableList baseImageLayers = pullBaseImageStepResult.getBaseImage().getLayers(); ImmutableList.Builder pullAndCacheBaseImageLayerStepsBuilder = diff --git a/jib-core/src/main/java/com/google/cloud/tools/jib/builder/steps/PullBaseImageStep.java b/jib-core/src/main/java/com/google/cloud/tools/jib/builder/steps/PullBaseImageStep.java index 89f7863018..2525ad348d 100644 --- a/jib-core/src/main/java/com/google/cloud/tools/jib/builder/steps/PullBaseImageStep.java +++ b/jib-core/src/main/java/com/google/cloud/tools/jib/builder/steps/PullBaseImageStep.java @@ -21,7 +21,7 @@ import com.google.cloud.tools.jib.async.NonBlockingSteps; import com.google.cloud.tools.jib.blob.Blobs; import com.google.cloud.tools.jib.builder.BuildConfiguration; -import com.google.cloud.tools.jib.builder.steps.PullBaseImageStep.Result; +import com.google.cloud.tools.jib.builder.steps.PullBaseImageStep.BaseImageWithAuthorization; import com.google.cloud.tools.jib.http.Authorization; import com.google.cloud.tools.jib.image.Image; import com.google.cloud.tools.jib.image.Layer; @@ -48,17 +48,19 @@ import javax.annotation.Nullable; /** Pulls the base image manifest. */ -class PullBaseImageStep implements AsyncStep, Callable { +class PullBaseImageStep + implements AsyncStep, Callable { private static final String DESCRIPTION = "Pulling base image manifest"; /** Structure for the result returned by this step. */ - static class Result { + static class BaseImageWithAuthorization { private final Image baseImage; private final @Nullable Authorization baseImageAuthorization; - private Result(Image baseImage, @Nullable Authorization baseImageAuthorization) { + private BaseImageWithAuthorization( + Image baseImage, @Nullable Authorization baseImageAuthorization) { this.baseImage = baseImage; this.baseImageAuthorization = baseImageAuthorization; } @@ -75,7 +77,7 @@ Authorization getBaseImageAuthorization() { private final BuildConfiguration buildConfiguration; - private final ListenableFuture listenableFuture; + private final ListenableFuture listenableFuture; PullBaseImageStep( ListeningExecutorService listeningExecutorService, BuildConfiguration buildConfiguration) { @@ -85,12 +87,12 @@ Authorization getBaseImageAuthorization() { } @Override - public ListenableFuture getFuture() { + public ListenableFuture getFuture() { return listenableFuture; } @Override - public Result call() + public BaseImageWithAuthorization call() throws IOException, RegistryException, LayerPropertyNotFoundException, LayerCountMismatchException, ExecutionException { buildConfiguration @@ -100,7 +102,7 @@ public Result call() try (Timer ignored = new Timer(buildConfiguration.getBuildLogger(), DESCRIPTION)) { // First, try with no credentials. try { - return new Result(pullBaseImage(null), null); + return new BaseImageWithAuthorization(pullBaseImage(null), null); } catch (RegistryUnauthorizedException ex) { // If failed, then, retrieve base registry credentials and try with retrieved credentials. @@ -112,7 +114,8 @@ public Result call() Authorization registryCredentials = NonBlockingSteps.get(retrieveBaseRegistryCredentialsStep); - return new Result(pullBaseImage(registryCredentials), registryCredentials); + return new BaseImageWithAuthorization( + pullBaseImage(registryCredentials), registryCredentials); } } }