Relocate DockerConfiguration and refactor buildpack platform code
Relate `DockerConfiguration` from `...platform.docker` to `...platform.build` since it contains build specific concepts. This commit also refactors a few other areas of the code to make it easier to support credential helpers in the future. Closes gh-45283
This commit is contained in:
@@ -26,7 +26,8 @@ import org.springframework.boot.buildpack.platform.docker.TotalProgressEvent;
|
||||
import org.springframework.boot.buildpack.platform.docker.TotalProgressPullListener;
|
||||
import org.springframework.boot.buildpack.platform.docker.TotalProgressPushListener;
|
||||
import org.springframework.boot.buildpack.platform.docker.UpdateListener;
|
||||
import org.springframework.boot.buildpack.platform.docker.configuration.DockerConfiguration;
|
||||
import org.springframework.boot.buildpack.platform.docker.configuration.DockerConnectionConfiguration;
|
||||
import org.springframework.boot.buildpack.platform.docker.configuration.DockerRegistryAuthentication;
|
||||
import org.springframework.boot.buildpack.platform.docker.configuration.ResolvedDockerHost;
|
||||
import org.springframework.boot.buildpack.platform.docker.transport.DockerEngineException;
|
||||
import org.springframework.boot.buildpack.platform.docker.type.Binding;
|
||||
@@ -54,7 +55,7 @@ public class Builder {
|
||||
|
||||
private final DockerApi docker;
|
||||
|
||||
private final DockerConfiguration dockerConfiguration;
|
||||
private final BuilderDockerConfiguration dockerConfiguration;
|
||||
|
||||
/**
|
||||
* Create a new builder instance.
|
||||
@@ -67,8 +68,22 @@ public class Builder {
|
||||
* Create a new builder instance.
|
||||
* @param dockerConfiguration the docker configuration
|
||||
* @since 2.4.0
|
||||
* @deprecated since 3.5.0 for removal in 4.0.0 in favor of
|
||||
* {@link #Builder(BuilderDockerConfiguration)}
|
||||
*/
|
||||
public Builder(DockerConfiguration dockerConfiguration) {
|
||||
@Deprecated(since = "3.5.0", forRemoval = true)
|
||||
@SuppressWarnings("removal")
|
||||
public Builder(
|
||||
org.springframework.boot.buildpack.platform.docker.configuration.DockerConfiguration dockerConfiguration) {
|
||||
this(BuildLog.toSystemOut(), dockerConfiguration);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new builder instance.
|
||||
* @param dockerConfiguration the docker configuration
|
||||
* @since 3.5.0
|
||||
*/
|
||||
public Builder(BuilderDockerConfiguration dockerConfiguration) {
|
||||
this(BuildLog.toSystemOut(), dockerConfiguration);
|
||||
}
|
||||
|
||||
@@ -85,17 +100,45 @@ public class Builder {
|
||||
* @param log a logger used to record output
|
||||
* @param dockerConfiguration the docker configuration
|
||||
* @since 2.4.0
|
||||
* @deprecated since 3.5.0 for removal in 4.0.0 in favor of
|
||||
* {@link #Builder(BuildLog, BuilderDockerConfiguration)}
|
||||
*/
|
||||
public Builder(BuildLog log, DockerConfiguration dockerConfiguration) {
|
||||
this(log, new DockerApi((dockerConfiguration != null) ? dockerConfiguration.getHost() : null,
|
||||
@Deprecated(since = "3.5.0", forRemoval = true)
|
||||
@SuppressWarnings("removal")
|
||||
public Builder(BuildLog log,
|
||||
org.springframework.boot.buildpack.platform.docker.configuration.DockerConfiguration dockerConfiguration) {
|
||||
this(log, adaptDeprecatedConfiguration(dockerConfiguration));
|
||||
}
|
||||
|
||||
@SuppressWarnings("removal")
|
||||
private static BuilderDockerConfiguration adaptDeprecatedConfiguration(
|
||||
org.springframework.boot.buildpack.platform.docker.configuration.DockerConfiguration configuration) {
|
||||
if (configuration == null) {
|
||||
return null;
|
||||
}
|
||||
DockerConnectionConfiguration connection = org.springframework.boot.buildpack.platform.docker.configuration.DockerConfiguration.DockerHostConfiguration
|
||||
.asConnectionConfiguration(configuration.getHost());
|
||||
return new BuilderDockerConfiguration(connection, configuration.isBindHostToBuilder(),
|
||||
configuration.getBuilderRegistryAuthentication(), configuration.getPublishRegistryAuthentication());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new builder instance.
|
||||
* @param log a logger used to record output
|
||||
* @param dockerConfiguration the docker configuration
|
||||
* @since 3.5.0
|
||||
*/
|
||||
public Builder(BuildLog log, BuilderDockerConfiguration dockerConfiguration) {
|
||||
this(log, new DockerApi((dockerConfiguration != null) ? dockerConfiguration.connection() : null,
|
||||
BuildLogAdapter.get(log)), dockerConfiguration);
|
||||
}
|
||||
|
||||
Builder(BuildLog log, DockerApi docker, DockerConfiguration dockerConfiguration) {
|
||||
Builder(BuildLog log, DockerApi docker, BuilderDockerConfiguration dockerConfiguration) {
|
||||
Assert.notNull(log, "'log' must not be null");
|
||||
this.log = log;
|
||||
this.docker = docker;
|
||||
this.dockerConfiguration = dockerConfiguration;
|
||||
this.dockerConfiguration = (dockerConfiguration != null) ? dockerConfiguration
|
||||
: new BuilderDockerConfiguration();
|
||||
}
|
||||
|
||||
public void build(BuildRequest request) throws DockerEngineException, IOException {
|
||||
@@ -104,8 +147,8 @@ public class Builder {
|
||||
validateBindings(request.getBindings());
|
||||
String domain = request.getBuilder().getDomain();
|
||||
PullPolicy pullPolicy = request.getPullPolicy();
|
||||
ImageFetcher imageFetcher = new ImageFetcher(domain, getBuilderAuthHeader(), pullPolicy,
|
||||
request.getImagePlatform());
|
||||
ImageFetcher imageFetcher = new ImageFetcher(domain, this.dockerConfiguration.builderRegistryAuthentication(),
|
||||
pullPolicy, request.getImagePlatform());
|
||||
Image builderImage = imageFetcher.fetchImage(ImageType.BUILDER, request.getBuilder());
|
||||
BuilderMetadata builderMetadata = BuilderMetadata.fromImage(builderImage);
|
||||
request = withRunImageIfNeeded(request, builderMetadata);
|
||||
@@ -182,8 +225,8 @@ public class Builder {
|
||||
}
|
||||
|
||||
private ResolvedDockerHost getDockerHost() {
|
||||
boolean bindHostToBuilder = this.dockerConfiguration != null && this.dockerConfiguration.isBindHostToBuilder();
|
||||
return (bindHostToBuilder) ? ResolvedDockerHost.from(this.dockerConfiguration.getHost()) : null;
|
||||
boolean bindToBuilder = this.dockerConfiguration.bindHostToBuilder();
|
||||
return (bindToBuilder) ? ResolvedDockerHost.from(this.dockerConfiguration.connection()) : null;
|
||||
}
|
||||
|
||||
private void tagImage(ImageReference sourceReference, List<ImageReference> tags) throws IOException {
|
||||
@@ -203,18 +246,13 @@ public class Builder {
|
||||
private void pushImage(ImageReference reference) throws IOException {
|
||||
Consumer<TotalProgressEvent> progressConsumer = this.log.pushingImage(reference);
|
||||
TotalProgressPushListener listener = new TotalProgressPushListener(progressConsumer);
|
||||
this.docker.image().push(reference, listener, getPublishAuthHeader());
|
||||
String authHeader = authHeader(this.dockerConfiguration.publishRegistryAuthentication());
|
||||
this.docker.image().push(reference, listener, authHeader);
|
||||
this.log.pushedImage(reference);
|
||||
}
|
||||
|
||||
private String getBuilderAuthHeader() {
|
||||
return (this.dockerConfiguration != null && this.dockerConfiguration.getBuilderRegistryAuthentication() != null)
|
||||
? this.dockerConfiguration.getBuilderRegistryAuthentication().getAuthHeader() : null;
|
||||
}
|
||||
|
||||
private String getPublishAuthHeader() {
|
||||
return (this.dockerConfiguration != null && this.dockerConfiguration.getPublishRegistryAuthentication() != null)
|
||||
? this.dockerConfiguration.getPublishRegistryAuthentication().getAuthHeader() : null;
|
||||
private static String authHeader(DockerRegistryAuthentication authentication) {
|
||||
return (authentication != null) ? authentication.getAuthHeader() : null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -224,15 +262,16 @@ public class Builder {
|
||||
|
||||
private final String domain;
|
||||
|
||||
private final String authHeader;
|
||||
private final DockerRegistryAuthentication registryAuthentication;
|
||||
|
||||
private final PullPolicy pullPolicy;
|
||||
|
||||
private ImagePlatform defaultPlatform;
|
||||
|
||||
ImageFetcher(String domain, String authHeader, PullPolicy pullPolicy, ImagePlatform platform) {
|
||||
ImageFetcher(String domain, DockerRegistryAuthentication registryAuthentication, PullPolicy pullPolicy,
|
||||
ImagePlatform platform) {
|
||||
this.domain = domain;
|
||||
this.authHeader = authHeader;
|
||||
this.registryAuthentication = registryAuthentication;
|
||||
this.pullPolicy = pullPolicy;
|
||||
this.defaultPlatform = platform;
|
||||
}
|
||||
@@ -240,7 +279,8 @@ public class Builder {
|
||||
Image fetchImage(ImageType type, ImageReference reference) throws IOException {
|
||||
Assert.notNull(type, "'type' must not be null");
|
||||
Assert.notNull(reference, "'reference' must not be null");
|
||||
Assert.state(this.authHeader == null || reference.getDomain().equals(this.domain),
|
||||
String authHeader = authHeader(this.registryAuthentication);
|
||||
Assert.state(authHeader == null || reference.getDomain().equals(this.domain),
|
||||
() -> String.format("%s '%s' must be pulled from the '%s' authenticated registry",
|
||||
StringUtils.capitalize(type.getDescription()), reference, this.domain));
|
||||
if (this.pullPolicy == PullPolicy.ALWAYS) {
|
||||
@@ -260,7 +300,8 @@ public class Builder {
|
||||
private Image pullImage(ImageReference reference, ImageType imageType) throws IOException {
|
||||
TotalProgressPullListener listener = new TotalProgressPullListener(
|
||||
Builder.this.log.pullingImage(reference, this.defaultPlatform, imageType));
|
||||
Image image = Builder.this.docker.image().pull(reference, this.defaultPlatform, listener, this.authHeader);
|
||||
String authHeader = authHeader(this.registryAuthentication);
|
||||
Image image = Builder.this.docker.image().pull(reference, this.defaultPlatform, listener, authHeader);
|
||||
Builder.this.log.pulledImage(image, imageType);
|
||||
if (this.defaultPlatform == null) {
|
||||
this.defaultPlatform = ImagePlatform.from(image);
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright 2012-2025 the original author or authors.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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.springframework.boot.buildpack.platform.build;
|
||||
|
||||
import org.springframework.boot.buildpack.platform.docker.configuration.DockerConnectionConfiguration;
|
||||
import org.springframework.boot.buildpack.platform.docker.configuration.DockerRegistryAuthentication;
|
||||
|
||||
/**
|
||||
* {@link Builder} configuration options for Docker.
|
||||
*
|
||||
* @param connection the Docker host configuration
|
||||
* @param bindHostToBuilder if the host resolved from the connection should be bound to
|
||||
* the builder
|
||||
* @param builderRegistryAuthentication the builder {@link DockerRegistryAuthentication}
|
||||
* @param publishRegistryAuthentication the publish {@link DockerRegistryAuthentication}
|
||||
* @author Phillip Webb
|
||||
* @author Wei Jiang
|
||||
* @author Scott Frederick
|
||||
* @since 3.5.0
|
||||
*/
|
||||
public record BuilderDockerConfiguration(DockerConnectionConfiguration connection, boolean bindHostToBuilder,
|
||||
DockerRegistryAuthentication builderRegistryAuthentication,
|
||||
DockerRegistryAuthentication publishRegistryAuthentication) {
|
||||
|
||||
public BuilderDockerConfiguration() {
|
||||
this(null, false, null, null);
|
||||
}
|
||||
|
||||
public BuilderDockerConfiguration withContext(String context) {
|
||||
return withConnection(new DockerConnectionConfiguration.Context(context));
|
||||
}
|
||||
|
||||
public BuilderDockerConfiguration withHost(String address, boolean secure, String certificatePath) {
|
||||
return withConnection(new DockerConnectionConfiguration.Host(address, secure, certificatePath));
|
||||
}
|
||||
|
||||
private BuilderDockerConfiguration withConnection(DockerConnectionConfiguration hostConfiguration) {
|
||||
return new BuilderDockerConfiguration(hostConfiguration, this.bindHostToBuilder,
|
||||
this.builderRegistryAuthentication, this.publishRegistryAuthentication);
|
||||
}
|
||||
|
||||
public BuilderDockerConfiguration withBindHostToBuilder(boolean bindHostToBuilder) {
|
||||
return new BuilderDockerConfiguration(this.connection, bindHostToBuilder, this.builderRegistryAuthentication,
|
||||
this.publishRegistryAuthentication);
|
||||
}
|
||||
|
||||
public BuilderDockerConfiguration withBuilderRegistryAuthentication(
|
||||
DockerRegistryAuthentication builderRegistryAuthentication) {
|
||||
return new BuilderDockerConfiguration(this.connection, this.bindHostToBuilder, builderRegistryAuthentication,
|
||||
this.publishRegistryAuthentication);
|
||||
|
||||
}
|
||||
|
||||
public BuilderDockerConfiguration withPublishRegistryAuthentication(
|
||||
DockerRegistryAuthentication publishRegistryAuthentication) {
|
||||
return new BuilderDockerConfiguration(this.connection, this.bindHostToBuilder,
|
||||
this.builderRegistryAuthentication, publishRegistryAuthentication);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -28,7 +28,7 @@ import java.util.Objects;
|
||||
import org.apache.hc.core5.http.Header;
|
||||
import org.apache.hc.core5.net.URIBuilder;
|
||||
|
||||
import org.springframework.boot.buildpack.platform.docker.configuration.DockerConfiguration.DockerHostConfiguration;
|
||||
import org.springframework.boot.buildpack.platform.docker.configuration.DockerConnectionConfiguration;
|
||||
import org.springframework.boot.buildpack.platform.docker.transport.HttpTransport;
|
||||
import org.springframework.boot.buildpack.platform.docker.transport.HttpTransport.Response;
|
||||
import org.springframework.boot.buildpack.platform.docker.type.ApiVersion;
|
||||
@@ -87,26 +87,32 @@ public class DockerApi {
|
||||
* Create a new {@link DockerApi} instance.
|
||||
*/
|
||||
public DockerApi() {
|
||||
this(null);
|
||||
this(HttpTransport.create((DockerConnectionConfiguration) null), DockerLog.toSystemOut());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new {@link DockerApi} instance.
|
||||
* @param dockerHost the Docker daemon host information
|
||||
* @since 2.4.0
|
||||
* @deprecated since 3.5.0 for removal in 4.0.0 in favor of
|
||||
* {@link #DockerApi(DockerConnectionConfiguration, DockerLog)}
|
||||
*/
|
||||
public DockerApi(DockerHostConfiguration dockerHost) {
|
||||
this(dockerHost, DockerLog.toSystemOut());
|
||||
@Deprecated(since = "3.5.0", forRemoval = true)
|
||||
@SuppressWarnings("removal")
|
||||
public DockerApi(
|
||||
org.springframework.boot.buildpack.platform.docker.configuration.DockerConfiguration.DockerHostConfiguration dockerHost) {
|
||||
this(org.springframework.boot.buildpack.platform.docker.configuration.DockerConfiguration.DockerHostConfiguration
|
||||
.asConnectionConfiguration(dockerHost), DockerLog.toSystemOut());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new {@link DockerApi} instance.
|
||||
* @param dockerHost the Docker daemon host information
|
||||
* @param connectionConfiguration the connection configuration to use
|
||||
* @param log a logger used to record output
|
||||
* @since 3.5.0
|
||||
*/
|
||||
public DockerApi(DockerHostConfiguration dockerHost, DockerLog log) {
|
||||
this(HttpTransport.create(dockerHost), log);
|
||||
public DockerApi(DockerConnectionConfiguration connectionConfiguration, DockerLog log) {
|
||||
this(HttpTransport.create(connectionConfiguration), log);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package org.springframework.boot.buildpack.platform.docker.configuration;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Docker configuration options.
|
||||
@@ -24,7 +25,11 @@ import org.springframework.util.Assert;
|
||||
* @author Wei Jiang
|
||||
* @author Scott Frederick
|
||||
* @since 2.4.0
|
||||
* @deprecated since 3.5.0 for removal in 4.0.0 in favor of
|
||||
* {@link org.springframework.boot.buildpack.platform.build.BuilderDockerConfiguration}.
|
||||
*/
|
||||
@Deprecated(since = "3.5.0", forRemoval = true)
|
||||
@SuppressWarnings("removal")
|
||||
public final class DockerConfiguration {
|
||||
|
||||
private final DockerHostConfiguration host;
|
||||
@@ -113,6 +118,13 @@ public final class DockerConfiguration {
|
||||
new DockerRegistryUserAuthentication("", "", "", ""), this.bindHostToBuilder);
|
||||
}
|
||||
|
||||
/**
|
||||
* Docker host configuration.
|
||||
*
|
||||
* @deprecated since 3.5.0 for removal in 4.0.0 in favor of
|
||||
* {@link DockerHostConfiguration}
|
||||
*/
|
||||
@Deprecated(since = "3.5.0", forRemoval = true)
|
||||
public static class DockerHostConfiguration {
|
||||
|
||||
private final String address;
|
||||
@@ -158,6 +170,24 @@ public final class DockerConfiguration {
|
||||
return new DockerHostConfiguration(null, context, false, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adapts a {@link DockerHostConfiguration} to a
|
||||
* {@link DockerConnectionConfiguration}.
|
||||
* @param configuration the configuration to adapt
|
||||
* @return the adapted configuration
|
||||
* @since 3.5.0
|
||||
*/
|
||||
public static DockerConnectionConfiguration asConnectionConfiguration(DockerHostConfiguration configuration) {
|
||||
if (configuration != null && StringUtils.hasLength(configuration.context)) {
|
||||
return new DockerConnectionConfiguration.Context(configuration.context);
|
||||
}
|
||||
if (configuration != null && StringUtils.hasLength(configuration.address)) {
|
||||
return new DockerConnectionConfiguration.Host(configuration.address, configuration.secure,
|
||||
configuration.certificatePath);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright 2012-2025 the original author or authors.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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.springframework.boot.buildpack.platform.docker.configuration;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Configuration for how to connect to Docker.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @since 3.5.0
|
||||
*/
|
||||
public sealed interface DockerConnectionConfiguration {
|
||||
|
||||
/**
|
||||
* Connect to specific host.
|
||||
*
|
||||
* @param address the host address
|
||||
* @param secure if connection is secure
|
||||
* @param certificatePath a path to the certificate used for secure connections
|
||||
*/
|
||||
record Host(String address, boolean secure, String certificatePath) implements DockerConnectionConfiguration {
|
||||
|
||||
public Host(String address) {
|
||||
this(address, false, null);
|
||||
}
|
||||
|
||||
public Host {
|
||||
Assert.hasLength(address, "'address' must not be empty");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect using a specific context reference.
|
||||
*
|
||||
* @param context a reference to the Docker context
|
||||
*/
|
||||
record Context(String context) implements DockerConnectionConfiguration {
|
||||
|
||||
public Context {
|
||||
Assert.hasLength(context, "'context' must not be empty");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
* Copyright 2012-2025 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -24,10 +24,43 @@ package org.springframework.boot.buildpack.platform.docker.configuration;
|
||||
*/
|
||||
public interface DockerRegistryAuthentication {
|
||||
|
||||
/**
|
||||
* An empty {@link #user(String, String, String, String)} authentication.
|
||||
* @since 3.5.0
|
||||
*/
|
||||
DockerRegistryAuthentication EMPTY_USER = DockerRegistryAuthentication.user("", "", "", "");
|
||||
|
||||
/**
|
||||
* Returns the auth header that should be used for docker authentication.
|
||||
* @return the auth header
|
||||
*/
|
||||
String getAuthHeader();
|
||||
|
||||
/**
|
||||
* Factory method to that returns a new {@link DockerRegistryAuthentication} instance
|
||||
* that uses a header generated by base64 encoding a JSON payload created from the
|
||||
* given parameters.
|
||||
* @param identityToken the identity token JSON field
|
||||
* @return a new {@link DockerRegistryAuthentication} instance
|
||||
* @since 3.5.0
|
||||
*/
|
||||
static DockerRegistryAuthentication token(String identityToken) {
|
||||
return new DockerRegistryTokenAuthentication(identityToken);
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method to that returns a new {@link DockerRegistryAuthentication} instance
|
||||
* that uses a header generated by base64 encoding a JSON payload created from the
|
||||
* given parameters.
|
||||
* @param username the username JSON field
|
||||
* @param password the password JSON field
|
||||
* @param serverAddress the server address JSON field
|
||||
* @param email the email JSON field
|
||||
* @return a new {@link DockerRegistryAuthentication} instance
|
||||
* @since 3.5.0
|
||||
*/
|
||||
static DockerRegistryAuthentication user(String username, String password, String serverAddress, String email) {
|
||||
return new DockerRegistryUserAuthentication(username, password, serverAddress, email);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2024 the original author or authors.
|
||||
* Copyright 2012-2025 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -21,7 +21,6 @@ import java.nio.file.Paths;
|
||||
|
||||
import com.sun.jna.Platform;
|
||||
|
||||
import org.springframework.boot.buildpack.platform.docker.configuration.DockerConfiguration.DockerHostConfiguration;
|
||||
import org.springframework.boot.buildpack.platform.docker.configuration.DockerConfigurationMetadata.DockerContext;
|
||||
import org.springframework.boot.buildpack.platform.system.Environment;
|
||||
|
||||
@@ -77,30 +76,49 @@ public class ResolvedDockerHost extends DockerHost {
|
||||
}
|
||||
}
|
||||
|
||||
public static ResolvedDockerHost from(DockerHostConfiguration dockerHost) {
|
||||
return from(Environment.SYSTEM, dockerHost);
|
||||
/**
|
||||
* Create a new {@link ResolvedDockerHost} from the given host configuration.
|
||||
* @param dockerHostConfiguration the host configuration or {@code null}
|
||||
* @return the resolved docker host
|
||||
* @deprecated since 3.5.0 for removal in 4.0.0 in favor of
|
||||
* {@link #from(DockerConnectionConfiguration)}
|
||||
*/
|
||||
@Deprecated(since = "3.5.0", forRemoval = true)
|
||||
@SuppressWarnings("removal")
|
||||
public static ResolvedDockerHost from(DockerConfiguration.DockerHostConfiguration dockerHostConfiguration) {
|
||||
return from(Environment.SYSTEM,
|
||||
DockerConfiguration.DockerHostConfiguration.asConnectionConfiguration(dockerHostConfiguration));
|
||||
}
|
||||
|
||||
static ResolvedDockerHost from(Environment environment, DockerHostConfiguration dockerHost) {
|
||||
DockerConfigurationMetadata config = DockerConfigurationMetadata.from(environment);
|
||||
/**
|
||||
* Create a new {@link ResolvedDockerHost} from the given host configuration.
|
||||
* @param connectionConfiguration the host configuration or {@code null}
|
||||
* @return the resolved docker host
|
||||
*/
|
||||
public static ResolvedDockerHost from(DockerConnectionConfiguration connectionConfiguration) {
|
||||
return from(Environment.SYSTEM, connectionConfiguration);
|
||||
}
|
||||
|
||||
static ResolvedDockerHost from(Environment environment, DockerConnectionConfiguration connectionConfiguration) {
|
||||
DockerConfigurationMetadata environmentConfiguration = DockerConfigurationMetadata.from(environment);
|
||||
if (environment.get(DOCKER_CONTEXT) != null) {
|
||||
DockerContext context = config.forContext(environment.get(DOCKER_CONTEXT));
|
||||
DockerContext context = environmentConfiguration.forContext(environment.get(DOCKER_CONTEXT));
|
||||
return new ResolvedDockerHost(context.getDockerHost(), context.isTlsVerify(), context.getTlsPath());
|
||||
}
|
||||
if (dockerHost != null && dockerHost.getContext() != null) {
|
||||
DockerContext context = config.forContext(dockerHost.getContext());
|
||||
if (connectionConfiguration instanceof DockerConnectionConfiguration.Context contextConfiguration) {
|
||||
DockerContext context = environmentConfiguration.forContext(contextConfiguration.context());
|
||||
return new ResolvedDockerHost(context.getDockerHost(), context.isTlsVerify(), context.getTlsPath());
|
||||
}
|
||||
if (environment.get(DOCKER_HOST) != null) {
|
||||
return new ResolvedDockerHost(environment.get(DOCKER_HOST), isTrue(environment.get(DOCKER_TLS_VERIFY)),
|
||||
environment.get(DOCKER_CERT_PATH));
|
||||
}
|
||||
if (dockerHost != null && dockerHost.getAddress() != null) {
|
||||
return new ResolvedDockerHost(dockerHost.getAddress(), dockerHost.isSecure(),
|
||||
dockerHost.getCertificatePath());
|
||||
if (connectionConfiguration instanceof DockerConnectionConfiguration.Host addressConfiguration) {
|
||||
return new ResolvedDockerHost(addressConfiguration.address(), addressConfiguration.secure(),
|
||||
addressConfiguration.certificatePath());
|
||||
}
|
||||
if (config.getContext().getDockerHost() != null) {
|
||||
DockerContext context = config.getContext();
|
||||
if (environmentConfiguration.getContext().getDockerHost() != null) {
|
||||
DockerContext context = environmentConfiguration.getContext();
|
||||
return new ResolvedDockerHost(context.getDockerHost(), context.isTlsVerify(), context.getTlsPath());
|
||||
}
|
||||
return new ResolvedDockerHost(getDefaultAddress());
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2024 the original author or authors.
|
||||
* Copyright 2012-2025 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -24,7 +24,8 @@ import java.net.URI;
|
||||
|
||||
import org.apache.hc.core5.http.Header;
|
||||
|
||||
import org.springframework.boot.buildpack.platform.docker.configuration.DockerConfiguration.DockerHostConfiguration;
|
||||
import org.springframework.boot.buildpack.platform.docker.configuration.DockerConfiguration;
|
||||
import org.springframework.boot.buildpack.platform.docker.configuration.DockerConnectionConfiguration;
|
||||
import org.springframework.boot.buildpack.platform.docker.configuration.DockerHost;
|
||||
import org.springframework.boot.buildpack.platform.docker.configuration.ResolvedDockerHost;
|
||||
import org.springframework.boot.buildpack.platform.io.IOConsumer;
|
||||
@@ -103,13 +104,28 @@ public interface HttpTransport {
|
||||
* Create the most suitable {@link HttpTransport} based on the {@link DockerHost}.
|
||||
* @param dockerHost the Docker host information
|
||||
* @return a {@link HttpTransport} instance
|
||||
* @deprecated since 3.5.0 for removal in 4.0.0 in favor of
|
||||
* {@link #create(DockerConnectionConfiguration)}
|
||||
*/
|
||||
static HttpTransport create(DockerHostConfiguration dockerHost) {
|
||||
@Deprecated(since = "3.5.0", forRemoval = true)
|
||||
@SuppressWarnings("removal")
|
||||
static HttpTransport create(DockerConfiguration.DockerHostConfiguration dockerHost) {
|
||||
ResolvedDockerHost host = ResolvedDockerHost.from(dockerHost);
|
||||
HttpTransport remote = RemoteHttpClientTransport.createIfPossible(host);
|
||||
return (remote != null) ? remote : LocalHttpClientTransport.create(host);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the most suitable {@link HttpTransport} based on the {@link DockerHost}.
|
||||
* @param connectionConfiguration the Docker host information
|
||||
* @return a {@link HttpTransport} instance
|
||||
*/
|
||||
static HttpTransport create(DockerConnectionConfiguration connectionConfiguration) {
|
||||
ResolvedDockerHost host = ResolvedDockerHost.from(connectionConfiguration);
|
||||
HttpTransport remote = RemoteHttpClientTransport.createIfPossible(host);
|
||||
return (remote != null) ? remote : LocalHttpClientTransport.create(host);
|
||||
}
|
||||
|
||||
/**
|
||||
* An HTTP operation response.
|
||||
*/
|
||||
|
||||
@@ -32,7 +32,7 @@ import org.springframework.boot.buildpack.platform.docker.DockerApi.ImageApi;
|
||||
import org.springframework.boot.buildpack.platform.docker.DockerApi.VolumeApi;
|
||||
import org.springframework.boot.buildpack.platform.docker.DockerLog;
|
||||
import org.springframework.boot.buildpack.platform.docker.TotalProgressPullListener;
|
||||
import org.springframework.boot.buildpack.platform.docker.configuration.DockerConfiguration;
|
||||
import org.springframework.boot.buildpack.platform.docker.configuration.DockerRegistryAuthentication;
|
||||
import org.springframework.boot.buildpack.platform.docker.transport.DockerEngineException;
|
||||
import org.springframework.boot.buildpack.platform.docker.type.Binding;
|
||||
import org.springframework.boot.buildpack.platform.docker.type.ContainerReference;
|
||||
@@ -49,6 +49,7 @@ import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
|
||||
import static org.assertj.core.api.Assertions.assertThatNoException;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.argThat;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.ArgumentMatchers.isNull;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
@@ -66,6 +67,15 @@ import static org.mockito.Mockito.times;
|
||||
*/
|
||||
class BuilderTests {
|
||||
|
||||
private static final ImageReference PAKETO_BUILDPACKS_BUILDER = ImageReference
|
||||
.of("gcr.io/paketo-buildpacks/builder");
|
||||
|
||||
private static final ImageReference LATEST_PAKETO_BUILDPACKS_BUILDER = PAKETO_BUILDPACKS_BUILDER.inTaggedForm();
|
||||
|
||||
private static final ImageReference DEFAULT_BUILDER = ImageReference.of(BuildRequest.DEFAULT_BUILDER_IMAGE_REF);
|
||||
|
||||
private static final ImageReference BASE_CNB = ImageReference.of("docker.io/cloudfoundry/run:base-cnb");
|
||||
|
||||
@Test
|
||||
void createWhenLogIsNullThrowsException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new Builder((BuildLog) null))
|
||||
@@ -108,12 +118,9 @@ class BuilderTests {
|
||||
DockerApi docker = mockDockerApi();
|
||||
Image builderImage = loadImage("image.json");
|
||||
Image runImage = loadImage("run-image.json");
|
||||
given(docker.image()
|
||||
.pull(eq(ImageReference.of(BuildRequest.DEFAULT_BUILDER_IMAGE_REF)), isNull(), any(), isNull()))
|
||||
given(docker.image().pull(eq(DEFAULT_BUILDER), isNull(), any(), isNull()))
|
||||
.willAnswer(withPulledImage(builderImage));
|
||||
given(docker.image()
|
||||
.pull(eq(ImageReference.of("docker.io/cloudfoundry/run:base-cnb")), eq(ImagePlatform.from(builderImage)),
|
||||
any(), isNull()))
|
||||
given(docker.image().pull(eq(BASE_CNB), eq(ImagePlatform.from(builderImage)), any(), isNull()))
|
||||
.willAnswer(withPulledImage(runImage));
|
||||
Builder builder = new Builder(BuildLog.to(out), docker, null);
|
||||
BuildRequest request = getTestRequest();
|
||||
@@ -121,11 +128,8 @@ class BuilderTests {
|
||||
assertThat(out.toString()).contains("Running creator");
|
||||
assertThat(out.toString()).contains("Successfully built image 'docker.io/library/my-application:latest'");
|
||||
ArgumentCaptor<ImageArchive> archive = ArgumentCaptor.forClass(ImageArchive.class);
|
||||
then(docker.image()).should()
|
||||
.pull(eq(ImageReference.of(BuildRequest.DEFAULT_BUILDER_IMAGE_REF)), isNull(), any(), isNull());
|
||||
then(docker.image()).should()
|
||||
.pull(eq(ImageReference.of("docker.io/cloudfoundry/run:base-cnb")), eq(ImagePlatform.from(builderImage)),
|
||||
any(), isNull());
|
||||
then(docker.image()).should().pull(eq(DEFAULT_BUILDER), isNull(), any(), isNull());
|
||||
then(docker.image()).should().pull(eq(BASE_CNB), eq(ImagePlatform.from(builderImage)), any(), isNull());
|
||||
then(docker.image()).should().load(archive.capture(), any());
|
||||
then(docker.image()).should().remove(archive.getValue().getTag(), true);
|
||||
then(docker.image()).shouldHaveNoMoreInteractions();
|
||||
@@ -137,16 +141,14 @@ class BuilderTests {
|
||||
DockerApi docker = mockDockerApi();
|
||||
Image builderImage = loadImage("image.json");
|
||||
Image runImage = loadImage("run-image.json");
|
||||
DockerConfiguration dockerConfiguration = new DockerConfiguration()
|
||||
.withBuilderRegistryTokenAuthentication("builder token")
|
||||
.withPublishRegistryTokenAuthentication("publish token");
|
||||
given(docker.image()
|
||||
.pull(eq(ImageReference.of(BuildRequest.DEFAULT_BUILDER_IMAGE_REF)), isNull(), any(),
|
||||
eq(dockerConfiguration.getBuilderRegistryAuthentication().getAuthHeader())))
|
||||
DockerRegistryAuthentication builderToken = DockerRegistryAuthentication.token("builder token");
|
||||
DockerRegistryAuthentication publishToken = DockerRegistryAuthentication.token("publish token");
|
||||
BuilderDockerConfiguration dockerConfiguration = new BuilderDockerConfiguration()
|
||||
.withBuilderRegistryAuthentication(builderToken)
|
||||
.withPublishRegistryAuthentication(publishToken);
|
||||
given(docker.image().pull(eq(DEFAULT_BUILDER), isNull(), any(), regAuthEq(builderToken)))
|
||||
.willAnswer(withPulledImage(builderImage));
|
||||
given(docker.image()
|
||||
.pull(eq(ImageReference.of("docker.io/cloudfoundry/run:base-cnb")), eq(ImagePlatform.from(builderImage)),
|
||||
any(), eq(dockerConfiguration.getBuilderRegistryAuthentication().getAuthHeader())))
|
||||
given(docker.image().pull(eq(BASE_CNB), eq(ImagePlatform.from(builderImage)), any(), regAuthEq(builderToken)))
|
||||
.willAnswer(withPulledImage(runImage));
|
||||
Builder builder = new Builder(BuildLog.to(out), docker, dockerConfiguration);
|
||||
BuildRequest request = getTestRequest().withPublish(true);
|
||||
@@ -154,15 +156,10 @@ class BuilderTests {
|
||||
assertThat(out.toString()).contains("Running creator");
|
||||
assertThat(out.toString()).contains("Successfully built image 'docker.io/library/my-application:latest'");
|
||||
ArgumentCaptor<ImageArchive> archive = ArgumentCaptor.forClass(ImageArchive.class);
|
||||
then(docker.image()).should().pull(eq(DEFAULT_BUILDER), isNull(), any(), regAuthEq(builderToken));
|
||||
then(docker.image()).should()
|
||||
.pull(eq(ImageReference.of(BuildRequest.DEFAULT_BUILDER_IMAGE_REF)), isNull(), any(),
|
||||
eq(dockerConfiguration.getBuilderRegistryAuthentication().getAuthHeader()));
|
||||
then(docker.image()).should()
|
||||
.pull(eq(ImageReference.of("docker.io/cloudfoundry/run:base-cnb")), eq(ImagePlatform.from(builderImage)),
|
||||
any(), eq(dockerConfiguration.getBuilderRegistryAuthentication().getAuthHeader()));
|
||||
then(docker.image()).should()
|
||||
.push(eq(request.getName()), any(),
|
||||
eq(dockerConfiguration.getPublishRegistryAuthentication().getAuthHeader()));
|
||||
.pull(eq(BASE_CNB), eq(ImagePlatform.from(builderImage)), any(), regAuthEq(builderToken));
|
||||
then(docker.image()).should().push(eq(request.getName()), any(), regAuthEq(publishToken));
|
||||
then(docker.image()).should().load(archive.capture(), any());
|
||||
then(docker.image()).should().remove(archive.getValue().getTag(), true);
|
||||
then(docker.image()).shouldHaveNoMoreInteractions();
|
||||
@@ -174,15 +171,14 @@ class BuilderTests {
|
||||
DockerApi docker = mockDockerApi();
|
||||
Image builderImage = loadImage("image-with-no-run-image-tag.json");
|
||||
Image runImage = loadImage("run-image.json");
|
||||
given(docker.image()
|
||||
.pull(eq(ImageReference.of("gcr.io/paketo-buildpacks/builder:latest")), isNull(), any(), isNull()))
|
||||
given(docker.image().pull(eq(LATEST_PAKETO_BUILDPACKS_BUILDER), isNull(), any(), isNull()))
|
||||
.willAnswer(withPulledImage(builderImage));
|
||||
given(docker.image()
|
||||
.pull(eq(ImageReference.of("docker.io/cloudfoundry/run:latest")), eq(ImagePlatform.from(builderImage)),
|
||||
any(), isNull()))
|
||||
.willAnswer(withPulledImage(runImage));
|
||||
Builder builder = new Builder(BuildLog.to(out), docker, null);
|
||||
BuildRequest request = getTestRequest().withBuilder(ImageReference.of("gcr.io/paketo-buildpacks/builder"));
|
||||
BuildRequest request = getTestRequest().withBuilder(PAKETO_BUILDPACKS_BUILDER);
|
||||
builder.build(request);
|
||||
assertThat(out.toString()).contains("Running creator");
|
||||
assertThat(out.toString()).contains("Successfully built image 'docker.io/library/my-application:latest'");
|
||||
@@ -197,8 +193,7 @@ class BuilderTests {
|
||||
DockerApi docker = mockDockerApi();
|
||||
Image builderImage = loadImage("image-with-run-image-digest.json");
|
||||
Image runImage = loadImage("run-image.json");
|
||||
given(docker.image()
|
||||
.pull(eq(ImageReference.of(BuildRequest.DEFAULT_BUILDER_IMAGE_REF)), isNull(), any(), isNull()))
|
||||
given(docker.image().pull(eq(DEFAULT_BUILDER), isNull(), any(), isNull()))
|
||||
.willAnswer(withPulledImage(builderImage));
|
||||
given(docker.image()
|
||||
.pull(eq(ImageReference
|
||||
@@ -221,15 +216,12 @@ class BuilderTests {
|
||||
DockerApi docker = mockDockerApi();
|
||||
Image builderImage = loadImage("image-with-empty-stack.json");
|
||||
Image runImage = loadImage("run-image.json");
|
||||
given(docker.image()
|
||||
.pull(eq(ImageReference.of("gcr.io/paketo-buildpacks/builder:latest")), isNull(), any(), isNull()))
|
||||
given(docker.image().pull(eq(LATEST_PAKETO_BUILDPACKS_BUILDER), isNull(), any(), isNull()))
|
||||
.willAnswer(withPulledImage(builderImage));
|
||||
given(docker.image()
|
||||
.pull(eq(ImageReference.of("docker.io/cloudfoundry/run:base-cnb")), eq(ImagePlatform.from(builderImage)),
|
||||
any(), isNull()))
|
||||
given(docker.image().pull(eq(BASE_CNB), eq(ImagePlatform.from(builderImage)), any(), isNull()))
|
||||
.willAnswer(withPulledImage(runImage));
|
||||
Builder builder = new Builder(BuildLog.to(out), docker, null);
|
||||
BuildRequest request = getTestRequest().withBuilder(ImageReference.of("gcr.io/paketo-buildpacks/builder"));
|
||||
BuildRequest request = getTestRequest().withBuilder(PAKETO_BUILDPACKS_BUILDER);
|
||||
builder.build(request);
|
||||
assertThat(out.toString()).contains("Running creator");
|
||||
assertThat(out.toString()).contains("Successfully built image 'docker.io/library/my-application:latest'");
|
||||
@@ -244,8 +236,7 @@ class BuilderTests {
|
||||
DockerApi docker = mockDockerApi();
|
||||
Image builderImage = loadImage("image.json");
|
||||
Image runImage = loadImage("run-image.json");
|
||||
given(docker.image()
|
||||
.pull(eq(ImageReference.of(BuildRequest.DEFAULT_BUILDER_IMAGE_REF)), isNull(), any(), isNull()))
|
||||
given(docker.image().pull(eq(DEFAULT_BUILDER), isNull(), any(), isNull()))
|
||||
.willAnswer(withPulledImage(builderImage));
|
||||
given(docker.image()
|
||||
.pull(eq(ImageReference.of("example.com/custom/run:latest")), eq(ImagePlatform.from(builderImage)), any(),
|
||||
@@ -267,17 +258,12 @@ class BuilderTests {
|
||||
DockerApi docker = mockDockerApi();
|
||||
Image builderImage = loadImage("image.json");
|
||||
Image runImage = loadImage("run-image.json");
|
||||
given(docker.image()
|
||||
.pull(eq(ImageReference.of(BuildRequest.DEFAULT_BUILDER_IMAGE_REF)), isNull(), any(), isNull()))
|
||||
given(docker.image().pull(eq(DEFAULT_BUILDER), isNull(), any(), isNull()))
|
||||
.willAnswer(withPulledImage(builderImage));
|
||||
given(docker.image()
|
||||
.pull(eq(ImageReference.of("docker.io/cloudfoundry/run:base-cnb")), eq(ImagePlatform.from(builderImage)),
|
||||
any(), isNull()))
|
||||
given(docker.image().pull(eq(BASE_CNB), eq(ImagePlatform.from(builderImage)), any(), isNull()))
|
||||
.willAnswer(withPulledImage(runImage));
|
||||
given(docker.image().inspect(eq(ImageReference.of(BuildRequest.DEFAULT_BUILDER_IMAGE_REF))))
|
||||
.willReturn(builderImage);
|
||||
given(docker.image().inspect(eq(ImageReference.of("docker.io/cloudfoundry/run:base-cnb"))))
|
||||
.willReturn(runImage);
|
||||
given(docker.image().inspect(eq(DEFAULT_BUILDER))).willReturn(builderImage);
|
||||
given(docker.image().inspect(eq(BASE_CNB))).willReturn(runImage);
|
||||
Builder builder = new Builder(BuildLog.to(out), docker, null);
|
||||
BuildRequest request = getTestRequest().withPullPolicy(PullPolicy.NEVER);
|
||||
builder.build(request);
|
||||
@@ -296,17 +282,12 @@ class BuilderTests {
|
||||
DockerApi docker = mockDockerApi();
|
||||
Image builderImage = loadImage("image.json");
|
||||
Image runImage = loadImage("run-image.json");
|
||||
given(docker.image()
|
||||
.pull(eq(ImageReference.of(BuildRequest.DEFAULT_BUILDER_IMAGE_REF)), isNull(), any(), isNull()))
|
||||
given(docker.image().pull(eq(DEFAULT_BUILDER), isNull(), any(), isNull()))
|
||||
.willAnswer(withPulledImage(builderImage));
|
||||
given(docker.image()
|
||||
.pull(eq(ImageReference.of("docker.io/cloudfoundry/run:base-cnb")), eq(ImagePlatform.from(builderImage)),
|
||||
any(), isNull()))
|
||||
given(docker.image().pull(eq(BASE_CNB), eq(ImagePlatform.from(builderImage)), any(), isNull()))
|
||||
.willAnswer(withPulledImage(runImage));
|
||||
given(docker.image().inspect(eq(ImageReference.of(BuildRequest.DEFAULT_BUILDER_IMAGE_REF))))
|
||||
.willReturn(builderImage);
|
||||
given(docker.image().inspect(eq(ImageReference.of("docker.io/cloudfoundry/run:base-cnb"))))
|
||||
.willReturn(runImage);
|
||||
given(docker.image().inspect(eq(DEFAULT_BUILDER))).willReturn(builderImage);
|
||||
given(docker.image().inspect(eq(BASE_CNB))).willReturn(runImage);
|
||||
Builder builder = new Builder(BuildLog.to(out), docker, null);
|
||||
BuildRequest request = getTestRequest().withPullPolicy(PullPolicy.ALWAYS);
|
||||
builder.build(request);
|
||||
@@ -325,18 +306,15 @@ class BuilderTests {
|
||||
DockerApi docker = mockDockerApi();
|
||||
Image builderImage = loadImage("image.json");
|
||||
Image runImage = loadImage("run-image.json");
|
||||
given(docker.image()
|
||||
.pull(eq(ImageReference.of(BuildRequest.DEFAULT_BUILDER_IMAGE_REF)), isNull(), any(), isNull()))
|
||||
given(docker.image().pull(eq(DEFAULT_BUILDER), isNull(), any(), isNull()))
|
||||
.willAnswer(withPulledImage(builderImage));
|
||||
given(docker.image()
|
||||
.pull(eq(ImageReference.of("docker.io/cloudfoundry/run:base-cnb")), eq(ImagePlatform.from(builderImage)),
|
||||
any(), isNull()))
|
||||
given(docker.image().pull(eq(BASE_CNB), eq(ImagePlatform.from(builderImage)), any(), isNull()))
|
||||
.willAnswer(withPulledImage(runImage));
|
||||
given(docker.image().inspect(eq(ImageReference.of(BuildRequest.DEFAULT_BUILDER_IMAGE_REF))))
|
||||
given(docker.image().inspect(eq(DEFAULT_BUILDER)))
|
||||
.willThrow(
|
||||
new DockerEngineException("docker://localhost/", new URI("example"), 404, "NOT FOUND", null, null))
|
||||
.willReturn(builderImage);
|
||||
given(docker.image().inspect(eq(ImageReference.of("docker.io/cloudfoundry/run:base-cnb"))))
|
||||
given(docker.image().inspect(eq(BASE_CNB)))
|
||||
.willThrow(
|
||||
new DockerEngineException("docker://localhost/", new URI("example"), 404, "NOT FOUND", null, null))
|
||||
.willReturn(runImage);
|
||||
@@ -358,12 +336,9 @@ class BuilderTests {
|
||||
DockerApi docker = mockDockerApi();
|
||||
Image builderImage = loadImage("image.json");
|
||||
Image runImage = loadImage("run-image.json");
|
||||
given(docker.image()
|
||||
.pull(eq(ImageReference.of(BuildRequest.DEFAULT_BUILDER_IMAGE_REF)), isNull(), any(), isNull()))
|
||||
given(docker.image().pull(eq(DEFAULT_BUILDER), isNull(), any(), isNull()))
|
||||
.willAnswer(withPulledImage(builderImage));
|
||||
given(docker.image()
|
||||
.pull(eq(ImageReference.of("docker.io/cloudfoundry/run:base-cnb")), eq(ImagePlatform.from(builderImage)),
|
||||
any(), isNull()))
|
||||
given(docker.image().pull(eq(BASE_CNB), eq(ImagePlatform.from(builderImage)), any(), isNull()))
|
||||
.willAnswer(withPulledImage(runImage));
|
||||
Builder builder = new Builder(BuildLog.to(out), docker, null);
|
||||
BuildRequest request = getTestRequest().withTags(ImageReference.of("my-application:1.2.3"));
|
||||
@@ -383,37 +358,31 @@ class BuilderTests {
|
||||
DockerApi docker = mockDockerApi();
|
||||
Image builderImage = loadImage("image.json");
|
||||
Image runImage = loadImage("run-image.json");
|
||||
DockerConfiguration dockerConfiguration = new DockerConfiguration()
|
||||
.withBuilderRegistryTokenAuthentication("builder token")
|
||||
.withPublishRegistryTokenAuthentication("publish token");
|
||||
given(docker.image()
|
||||
.pull(eq(ImageReference.of(BuildRequest.DEFAULT_BUILDER_IMAGE_REF)), isNull(), any(),
|
||||
eq(dockerConfiguration.getBuilderRegistryAuthentication().getAuthHeader())))
|
||||
DockerRegistryAuthentication builderToken = DockerRegistryAuthentication.token("builder token");
|
||||
DockerRegistryAuthentication publishToken = DockerRegistryAuthentication.token("publish token");
|
||||
BuilderDockerConfiguration dockerConfiguration = new BuilderDockerConfiguration()
|
||||
.withBuilderRegistryAuthentication(builderToken)
|
||||
.withPublishRegistryAuthentication(publishToken);
|
||||
ImageReference defaultBuilderImageReference = DEFAULT_BUILDER;
|
||||
given(docker.image().pull(eq(defaultBuilderImageReference), isNull(), any(), regAuthEq(builderToken)))
|
||||
.willAnswer(withPulledImage(builderImage));
|
||||
ImageReference baseImageReference = BASE_CNB;
|
||||
given(docker.image()
|
||||
.pull(eq(ImageReference.of("docker.io/cloudfoundry/run:base-cnb")), eq(ImagePlatform.from(builderImage)),
|
||||
any(), eq(dockerConfiguration.getBuilderRegistryAuthentication().getAuthHeader())))
|
||||
.pull(eq(baseImageReference), eq(ImagePlatform.from(builderImage)), any(), regAuthEq(builderToken)))
|
||||
.willAnswer(withPulledImage(runImage));
|
||||
Builder builder = new Builder(BuildLog.to(out), docker, dockerConfiguration);
|
||||
BuildRequest request = getTestRequest().withPublish(true).withTags(ImageReference.of("my-application:1.2.3"));
|
||||
ImageReference builtImageReference = ImageReference.of("my-application:1.2.3");
|
||||
BuildRequest request = getTestRequest().withPublish(true).withTags(builtImageReference);
|
||||
builder.build(request);
|
||||
assertThat(out.toString()).contains("Running creator");
|
||||
assertThat(out.toString()).contains("Successfully built image 'docker.io/library/my-application:latest'");
|
||||
assertThat(out.toString()).contains("Successfully created image tag 'docker.io/library/my-application:1.2.3'");
|
||||
|
||||
then(docker.image()).should().pull(eq(defaultBuilderImageReference), isNull(), any(), regAuthEq(builderToken));
|
||||
then(docker.image()).should()
|
||||
.pull(eq(ImageReference.of(BuildRequest.DEFAULT_BUILDER_IMAGE_REF)), isNull(), any(),
|
||||
eq(dockerConfiguration.getBuilderRegistryAuthentication().getAuthHeader()));
|
||||
then(docker.image()).should()
|
||||
.pull(eq(ImageReference.of("docker.io/cloudfoundry/run:base-cnb")), eq(ImagePlatform.from(builderImage)),
|
||||
any(), eq(dockerConfiguration.getBuilderRegistryAuthentication().getAuthHeader()));
|
||||
then(docker.image()).should()
|
||||
.push(eq(request.getName()), any(),
|
||||
eq(dockerConfiguration.getPublishRegistryAuthentication().getAuthHeader()));
|
||||
then(docker.image()).should().tag(eq(request.getName()), eq(ImageReference.of("my-application:1.2.3")));
|
||||
then(docker.image()).should()
|
||||
.push(eq(ImageReference.of("my-application:1.2.3")), any(),
|
||||
eq(dockerConfiguration.getPublishRegistryAuthentication().getAuthHeader()));
|
||||
.pull(eq(baseImageReference), eq(ImagePlatform.from(builderImage)), any(), regAuthEq(builderToken));
|
||||
then(docker.image()).should().push(eq(request.getName()), any(), regAuthEq(publishToken));
|
||||
then(docker.image()).should().tag(eq(request.getName()), eq(builtImageReference));
|
||||
then(docker.image()).should().push(eq(builtImageReference), any(), regAuthEq(publishToken));
|
||||
ArgumentCaptor<ImageArchive> archive = ArgumentCaptor.forClass(ImageArchive.class);
|
||||
then(docker.image()).should().load(archive.capture(), any());
|
||||
then(docker.image()).should().remove(archive.getValue().getTag(), true);
|
||||
@@ -427,22 +396,17 @@ class BuilderTests {
|
||||
DockerApi docker = mockDockerApi(platform);
|
||||
Image builderImage = loadImage("image-with-platform.json");
|
||||
Image runImage = loadImage("run-image-with-platform.json");
|
||||
given(docker.image()
|
||||
.pull(eq(ImageReference.of(BuildRequest.DEFAULT_BUILDER_IMAGE_REF)), eq(platform), any(), isNull()))
|
||||
given(docker.image().pull(eq(DEFAULT_BUILDER), eq(platform), any(), isNull()))
|
||||
.willAnswer(withPulledImage(builderImage));
|
||||
given(docker.image()
|
||||
.pull(eq(ImageReference.of("docker.io/cloudfoundry/run:base-cnb")), eq(platform), any(), isNull()))
|
||||
.willAnswer(withPulledImage(runImage));
|
||||
given(docker.image().pull(eq(BASE_CNB), eq(platform), any(), isNull())).willAnswer(withPulledImage(runImage));
|
||||
Builder builder = new Builder(BuildLog.to(out), docker, null);
|
||||
BuildRequest request = getTestRequest().withImagePlatform("linux/arm64/v1");
|
||||
builder.build(request);
|
||||
assertThat(out.toString()).contains("Running creator");
|
||||
assertThat(out.toString()).contains("Successfully built image 'docker.io/library/my-application:latest'");
|
||||
ArgumentCaptor<ImageArchive> archive = ArgumentCaptor.forClass(ImageArchive.class);
|
||||
then(docker.image()).should()
|
||||
.pull(eq(ImageReference.of(BuildRequest.DEFAULT_BUILDER_IMAGE_REF)), eq(platform), any(), isNull());
|
||||
then(docker.image()).should()
|
||||
.pull(eq(ImageReference.of("docker.io/cloudfoundry/run:base-cnb")), eq(platform), any(), isNull());
|
||||
then(docker.image()).should().pull(eq(DEFAULT_BUILDER), eq(platform), any(), isNull());
|
||||
then(docker.image()).should().pull(eq(BASE_CNB), eq(platform), any(), isNull());
|
||||
then(docker.image()).should().load(archive.capture(), any());
|
||||
then(docker.image()).should().remove(archive.getValue().getTag(), true);
|
||||
then(docker.image()).shouldHaveNoMoreInteractions();
|
||||
@@ -454,12 +418,9 @@ class BuilderTests {
|
||||
DockerApi docker = mockDockerApi();
|
||||
Image builderImage = loadImage("image.json");
|
||||
Image runImage = loadImage("run-image-with-bad-stack.json");
|
||||
given(docker.image()
|
||||
.pull(eq(ImageReference.of(BuildRequest.DEFAULT_BUILDER_IMAGE_REF)), isNull(), any(), isNull()))
|
||||
given(docker.image().pull(eq(DEFAULT_BUILDER), isNull(), any(), isNull()))
|
||||
.willAnswer(withPulledImage(builderImage));
|
||||
given(docker.image()
|
||||
.pull(eq(ImageReference.of("docker.io/cloudfoundry/run:base-cnb")), eq(ImagePlatform.from(builderImage)),
|
||||
any(), isNull()))
|
||||
given(docker.image().pull(eq(BASE_CNB), eq(ImagePlatform.from(builderImage)), any(), isNull()))
|
||||
.willAnswer(withPulledImage(runImage));
|
||||
Builder builder = new Builder(BuildLog.to(out), docker, null);
|
||||
BuildRequest request = getTestRequest();
|
||||
@@ -474,12 +435,9 @@ class BuilderTests {
|
||||
DockerApi docker = mockDockerApiLifecycleError();
|
||||
Image builderImage = loadImage("image.json");
|
||||
Image runImage = loadImage("run-image.json");
|
||||
given(docker.image()
|
||||
.pull(eq(ImageReference.of(BuildRequest.DEFAULT_BUILDER_IMAGE_REF)), isNull(), any(), isNull()))
|
||||
given(docker.image().pull(eq(DEFAULT_BUILDER), isNull(), any(), isNull()))
|
||||
.willAnswer(withPulledImage(builderImage));
|
||||
given(docker.image()
|
||||
.pull(eq(ImageReference.of("docker.io/cloudfoundry/run:base-cnb")), eq(ImagePlatform.from(builderImage)),
|
||||
any(), isNull()))
|
||||
given(docker.image().pull(eq(BASE_CNB), eq(ImagePlatform.from(builderImage)), any(), isNull()))
|
||||
.willAnswer(withPulledImage(runImage));
|
||||
Builder builder = new Builder(BuildLog.to(out), docker, null);
|
||||
BuildRequest request = getTestRequest();
|
||||
@@ -492,11 +450,11 @@ class BuilderTests {
|
||||
TestPrintStream out = new TestPrintStream();
|
||||
DockerApi docker = mockDockerApi();
|
||||
Image builderImage = loadImage("image-with-run-image-different-registry.json");
|
||||
DockerConfiguration dockerConfiguration = new DockerConfiguration()
|
||||
.withBuilderRegistryTokenAuthentication("builder token");
|
||||
given(docker.image()
|
||||
.pull(eq(ImageReference.of(BuildRequest.DEFAULT_BUILDER_IMAGE_REF)), any(), any(),
|
||||
eq(dockerConfiguration.getBuilderRegistryAuthentication().getAuthHeader())))
|
||||
DockerRegistryAuthentication builderToken = DockerRegistryAuthentication.token("builder token");
|
||||
BuilderDockerConfiguration dockerConfiguration = new BuilderDockerConfiguration()
|
||||
.withBuilderRegistryAuthentication(builderToken);
|
||||
ImageReference builderImageReference = DEFAULT_BUILDER;
|
||||
given(docker.image().pull(eq(builderImageReference), any(), any(), regAuthEq(builderToken)))
|
||||
.willAnswer(withPulledImage(builderImage));
|
||||
Builder builder = new Builder(BuildLog.to(out), docker, dockerConfiguration);
|
||||
BuildRequest request = getTestRequest();
|
||||
@@ -510,11 +468,10 @@ class BuilderTests {
|
||||
TestPrintStream out = new TestPrintStream();
|
||||
DockerApi docker = mockDockerApi();
|
||||
Image builderImage = loadImage("image.json");
|
||||
DockerConfiguration dockerConfiguration = new DockerConfiguration()
|
||||
.withBuilderRegistryTokenAuthentication("builder token");
|
||||
given(docker.image()
|
||||
.pull(eq(ImageReference.of(BuildRequest.DEFAULT_BUILDER_IMAGE_REF)), any(), any(),
|
||||
eq(dockerConfiguration.getBuilderRegistryAuthentication().getAuthHeader())))
|
||||
DockerRegistryAuthentication builderToken = DockerRegistryAuthentication.token("builder token");
|
||||
BuilderDockerConfiguration dockerConfiguration = new BuilderDockerConfiguration()
|
||||
.withBuilderRegistryAuthentication(builderToken);
|
||||
given(docker.image().pull(eq(DEFAULT_BUILDER), any(), any(), regAuthEq(builderToken)))
|
||||
.willAnswer(withPulledImage(builderImage));
|
||||
Builder builder = new Builder(BuildLog.to(out), docker, dockerConfiguration);
|
||||
BuildRequest request = getTestRequest().withRunImage(ImageReference.of("example.com/custom/run:latest"));
|
||||
@@ -529,11 +486,9 @@ class BuilderTests {
|
||||
DockerApi docker = mockDockerApiLifecycleError();
|
||||
Image builderImage = loadImage("image.json");
|
||||
Image runImage = loadImage("run-image.json");
|
||||
given(docker.image()
|
||||
.pull(eq(ImageReference.of(BuildRequest.DEFAULT_BUILDER_IMAGE_REF)), any(), any(), isNull()))
|
||||
given(docker.image().pull(eq(DEFAULT_BUILDER), any(), any(), isNull()))
|
||||
.willAnswer(withPulledImage(builderImage));
|
||||
given(docker.image().pull(eq(ImageReference.of("docker.io/cloudfoundry/run:base-cnb")), any(), any(), isNull()))
|
||||
.willAnswer(withPulledImage(runImage));
|
||||
given(docker.image().pull(eq(BASE_CNB), any(), any(), isNull())).willAnswer(withPulledImage(runImage));
|
||||
Builder builder = new Builder(BuildLog.to(out), docker, null);
|
||||
BuildpackReference reference = BuildpackReference.of("urn:cnb:builder:example/buildpack@1.2.3");
|
||||
BuildRequest request = getTestRequest().withBuildpacks(reference);
|
||||
@@ -548,12 +503,9 @@ class BuilderTests {
|
||||
DockerApi docker = mockDockerApi();
|
||||
Image builderImage = loadImage("image.json");
|
||||
Image runImage = loadImage("run-image.json");
|
||||
given(docker.image()
|
||||
.pull(eq(ImageReference.of(BuildRequest.DEFAULT_BUILDER_IMAGE_REF)), isNull(), any(), isNull()))
|
||||
given(docker.image().pull(eq(DEFAULT_BUILDER), isNull(), any(), isNull()))
|
||||
.willAnswer(withPulledImage(builderImage));
|
||||
given(docker.image()
|
||||
.pull(eq(ImageReference.of("docker.io/cloudfoundry/run:base-cnb")), eq(ImagePlatform.from(builderImage)),
|
||||
any(), isNull()))
|
||||
given(docker.image().pull(eq(BASE_CNB), eq(ImagePlatform.from(builderImage)), any(), isNull()))
|
||||
.willAnswer(withPulledImage(runImage));
|
||||
Builder builder = new Builder(BuildLog.to(out), docker, null);
|
||||
BuildRequest request = getTestRequest().withBindings(Binding.from("/host", "/cnb"));
|
||||
@@ -611,7 +563,10 @@ class BuilderTests {
|
||||
listener.onFinish();
|
||||
return image;
|
||||
};
|
||||
}
|
||||
|
||||
private static String regAuthEq(DockerRegistryAuthentication authentication) {
|
||||
return argThat(authentication.getAuthHeader()::equals);
|
||||
}
|
||||
|
||||
static class TestPrintStream extends PrintStream {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2024 the original author or authors.
|
||||
* Copyright 2012-2025 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -42,7 +42,7 @@ import org.springframework.boot.buildpack.platform.docker.DockerApi;
|
||||
import org.springframework.boot.buildpack.platform.docker.DockerApi.ContainerApi;
|
||||
import org.springframework.boot.buildpack.platform.docker.DockerApi.ImageApi;
|
||||
import org.springframework.boot.buildpack.platform.docker.DockerApi.VolumeApi;
|
||||
import org.springframework.boot.buildpack.platform.docker.configuration.DockerConfiguration.DockerHostConfiguration;
|
||||
import org.springframework.boot.buildpack.platform.docker.configuration.DockerConnectionConfiguration;
|
||||
import org.springframework.boot.buildpack.platform.docker.configuration.ResolvedDockerHost;
|
||||
import org.springframework.boot.buildpack.platform.docker.type.Binding;
|
||||
import org.springframework.boot.buildpack.platform.docker.type.ContainerConfig;
|
||||
@@ -362,7 +362,8 @@ class LifecycleTests {
|
||||
given(this.docker.container().create(any(), isNull(), any())).willAnswer(answerWithGeneratedContainerId());
|
||||
given(this.docker.container().wait(any())).willReturn(ContainerStatus.of(0, null));
|
||||
BuildRequest request = getTestRequest(trustBuilder);
|
||||
createLifecycle(request, ResolvedDockerHost.from(DockerHostConfiguration.forAddress("tcp://192.168.1.2:2376")))
|
||||
createLifecycle(request,
|
||||
ResolvedDockerHost.from(new DockerConnectionConfiguration.Host("tcp://192.168.1.2:2376")))
|
||||
.execute();
|
||||
if (trustBuilder) {
|
||||
assertPhaseWasRun("creator", withExpectedConfig("lifecycle-creator-inherit-remote.json"));
|
||||
@@ -384,7 +385,7 @@ class LifecycleTests {
|
||||
given(this.docker.container().create(any(), isNull(), any())).willAnswer(answerWithGeneratedContainerId());
|
||||
given(this.docker.container().wait(any())).willReturn(ContainerStatus.of(0, null));
|
||||
BuildRequest request = getTestRequest(trustBuilder);
|
||||
createLifecycle(request, ResolvedDockerHost.from(DockerHostConfiguration.forAddress("/var/alt.sock")))
|
||||
createLifecycle(request, ResolvedDockerHost.from(new DockerConnectionConfiguration.Host("/var/alt.sock")))
|
||||
.execute();
|
||||
if (trustBuilder) {
|
||||
assertPhaseWasRun("creator", withExpectedConfig("lifecycle-creator-inherit-local.json"));
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2021 the original author or authors.
|
||||
* Copyright 2012-2025 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -26,6 +26,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
* @author Wei Jiang
|
||||
* @author Scott Frederick
|
||||
*/
|
||||
@SuppressWarnings("removal")
|
||||
class DockerConfigurationTests {
|
||||
|
||||
@Test
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2024 the original author or authors.
|
||||
* Copyright 2012-2025 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -31,8 +31,6 @@ import org.junit.jupiter.api.condition.EnabledOnOs;
|
||||
import org.junit.jupiter.api.condition.OS;
|
||||
import org.junit.jupiter.api.io.TempDir;
|
||||
|
||||
import org.springframework.boot.buildpack.platform.docker.configuration.DockerConfiguration.DockerHostConfiguration;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
@@ -75,17 +73,6 @@ class ResolvedDockerHostTests {
|
||||
assertThat(dockerHost.getCertificatePath()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisabledOnOs(OS.WINDOWS)
|
||||
void resolveWhenDockerHostAddressIsNullReturnsLinuxDefault() throws Exception {
|
||||
this.environment.put("DOCKER_CONFIG", pathToResource("with-default-context/config.json"));
|
||||
ResolvedDockerHost dockerHost = ResolvedDockerHost.from(this.environment::get,
|
||||
DockerHostConfiguration.forAddress(null));
|
||||
assertThat(dockerHost.getAddress()).isEqualTo("/var/run/docker.sock");
|
||||
assertThat(dockerHost.isSecure()).isFalse();
|
||||
assertThat(dockerHost.getCertificatePath()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisabledOnOs(OS.WINDOWS)
|
||||
void resolveWhenUsingDefaultContextReturnsLinuxDefault() {
|
||||
@@ -100,7 +87,7 @@ class ResolvedDockerHostTests {
|
||||
void resolveWhenDockerHostAddressIsLocalReturnsAddress(@TempDir Path tempDir) throws IOException {
|
||||
String socketFilePath = Files.createTempFile(tempDir, "remote-transport", null).toAbsolutePath().toString();
|
||||
ResolvedDockerHost dockerHost = ResolvedDockerHost.from(this.environment::get,
|
||||
DockerHostConfiguration.forAddress(socketFilePath));
|
||||
new DockerConnectionConfiguration.Host(socketFilePath));
|
||||
assertThat(dockerHost.isLocalFileReference()).isTrue();
|
||||
assertThat(dockerHost.isRemote()).isFalse();
|
||||
assertThat(dockerHost.getAddress()).isEqualTo(socketFilePath);
|
||||
@@ -112,7 +99,7 @@ class ResolvedDockerHostTests {
|
||||
void resolveWhenDockerHostAddressIsLocalWithSchemeReturnsAddress(@TempDir Path tempDir) throws IOException {
|
||||
String socketFilePath = Files.createTempFile(tempDir, "remote-transport", null).toAbsolutePath().toString();
|
||||
ResolvedDockerHost dockerHost = ResolvedDockerHost.from(this.environment::get,
|
||||
DockerHostConfiguration.forAddress("unix://" + socketFilePath));
|
||||
new DockerConnectionConfiguration.Host("unix://" + socketFilePath));
|
||||
assertThat(dockerHost.isLocalFileReference()).isTrue();
|
||||
assertThat(dockerHost.isRemote()).isFalse();
|
||||
assertThat(dockerHost.getAddress()).isEqualTo(socketFilePath);
|
||||
@@ -123,7 +110,7 @@ class ResolvedDockerHostTests {
|
||||
@Test
|
||||
void resolveWhenDockerHostAddressIsHttpReturnsAddress() {
|
||||
ResolvedDockerHost dockerHost = ResolvedDockerHost.from(this.environment::get,
|
||||
DockerHostConfiguration.forAddress("http://docker.example.com"));
|
||||
new DockerConnectionConfiguration.Host("http://docker.example.com"));
|
||||
assertThat(dockerHost.isLocalFileReference()).isFalse();
|
||||
assertThat(dockerHost.isRemote()).isTrue();
|
||||
assertThat(dockerHost.getAddress()).isEqualTo("http://docker.example.com");
|
||||
@@ -134,7 +121,7 @@ class ResolvedDockerHostTests {
|
||||
@Test
|
||||
void resolveWhenDockerHostAddressIsHttpsReturnsAddress() {
|
||||
ResolvedDockerHost dockerHost = ResolvedDockerHost.from(this.environment::get,
|
||||
DockerHostConfiguration.forAddress("https://docker.example.com", true, "/cert-path"));
|
||||
new DockerConnectionConfiguration.Host("https://docker.example.com", true, "/cert-path"));
|
||||
assertThat(dockerHost.isLocalFileReference()).isFalse();
|
||||
assertThat(dockerHost.isRemote()).isTrue();
|
||||
assertThat(dockerHost.getAddress()).isEqualTo("https://docker.example.com");
|
||||
@@ -145,7 +132,7 @@ class ResolvedDockerHostTests {
|
||||
@Test
|
||||
void resolveWhenDockerHostAddressIsTcpReturnsAddress() {
|
||||
ResolvedDockerHost dockerHost = ResolvedDockerHost.from(this.environment::get,
|
||||
DockerHostConfiguration.forAddress("tcp://192.168.99.100:2376", true, "/cert-path"));
|
||||
new DockerConnectionConfiguration.Host("tcp://192.168.99.100:2376", true, "/cert-path"));
|
||||
assertThat(dockerHost.isLocalFileReference()).isFalse();
|
||||
assertThat(dockerHost.isRemote()).isTrue();
|
||||
assertThat(dockerHost.getAddress()).isEqualTo("tcp://192.168.99.100:2376");
|
||||
@@ -158,7 +145,7 @@ class ResolvedDockerHostTests {
|
||||
String socketFilePath = Files.createTempFile(tempDir, "remote-transport", null).toAbsolutePath().toString();
|
||||
this.environment.put("DOCKER_HOST", socketFilePath);
|
||||
ResolvedDockerHost dockerHost = ResolvedDockerHost.from(this.environment::get,
|
||||
DockerHostConfiguration.forAddress("/unused"));
|
||||
new DockerConnectionConfiguration.Host("/unused"));
|
||||
assertThat(dockerHost.isLocalFileReference()).isTrue();
|
||||
assertThat(dockerHost.isRemote()).isFalse();
|
||||
assertThat(dockerHost.getAddress()).isEqualTo(socketFilePath);
|
||||
@@ -171,7 +158,7 @@ class ResolvedDockerHostTests {
|
||||
String socketFilePath = Files.createTempFile(tempDir, "remote-transport", null).toAbsolutePath().toString();
|
||||
this.environment.put("DOCKER_HOST", "unix://" + socketFilePath);
|
||||
ResolvedDockerHost dockerHost = ResolvedDockerHost.from(this.environment::get,
|
||||
DockerHostConfiguration.forAddress("/unused"));
|
||||
new DockerConnectionConfiguration.Host("/unused"));
|
||||
assertThat(dockerHost.isLocalFileReference()).isTrue();
|
||||
assertThat(dockerHost.isRemote()).isFalse();
|
||||
assertThat(dockerHost.getAddress()).isEqualTo(socketFilePath);
|
||||
@@ -185,7 +172,7 @@ class ResolvedDockerHostTests {
|
||||
this.environment.put("DOCKER_TLS_VERIFY", "1");
|
||||
this.environment.put("DOCKER_CERT_PATH", "/cert-path");
|
||||
ResolvedDockerHost dockerHost = ResolvedDockerHost.from(this.environment::get,
|
||||
DockerHostConfiguration.forAddress("tcp://1.1.1.1"));
|
||||
new DockerConnectionConfiguration.Host("tcp://1.1.1.1"));
|
||||
assertThat(dockerHost.isLocalFileReference()).isFalse();
|
||||
assertThat(dockerHost.isRemote()).isTrue();
|
||||
assertThat(dockerHost.getAddress()).isEqualTo("tcp://192.168.99.100:2376");
|
||||
@@ -197,7 +184,7 @@ class ResolvedDockerHostTests {
|
||||
void resolveWithDockerHostContextReturnsAddress() throws Exception {
|
||||
this.environment.put("DOCKER_CONFIG", pathToResource("with-default-context/config.json"));
|
||||
ResolvedDockerHost dockerHost = ResolvedDockerHost.from(this.environment::get,
|
||||
DockerHostConfiguration.forContext("test-context"));
|
||||
new DockerConnectionConfiguration.Context("test-context"));
|
||||
assertThat(dockerHost.getAddress()).isEqualTo("/home/user/.docker/docker.sock");
|
||||
assertThat(dockerHost.isSecure()).isTrue();
|
||||
assertThat(dockerHost.getCertificatePath()).isNotNull();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
* Copyright 2012-2025 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -23,7 +23,7 @@ import java.nio.file.Path;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.io.TempDir;
|
||||
|
||||
import org.springframework.boot.buildpack.platform.docker.configuration.DockerConfiguration.DockerHostConfiguration;
|
||||
import org.springframework.boot.buildpack.platform.docker.configuration.DockerConnectionConfiguration;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@@ -37,21 +37,21 @@ class HttpTransportTests {
|
||||
|
||||
@Test
|
||||
void createWhenDockerHostVariableIsAddressReturnsRemote() {
|
||||
HttpTransport transport = HttpTransport.create(DockerHostConfiguration.forAddress("tcp://192.168.1.0"));
|
||||
HttpTransport transport = HttpTransport.create(new DockerConnectionConfiguration.Host("tcp://192.168.1.0"));
|
||||
assertThat(transport).isInstanceOf(RemoteHttpClientTransport.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void createWhenDockerHostVariableIsFileReturnsLocal(@TempDir Path tempDir) throws IOException {
|
||||
String dummySocketFilePath = Files.createTempFile(tempDir, "http-transport", null).toAbsolutePath().toString();
|
||||
HttpTransport transport = HttpTransport.create(DockerHostConfiguration.forAddress(dummySocketFilePath));
|
||||
HttpTransport transport = HttpTransport.create(new DockerConnectionConfiguration.Host(dummySocketFilePath));
|
||||
assertThat(transport).isInstanceOf(LocalHttpClientTransport.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void createWhenDockerHostVariableIsUnixSchemePrefixedFileReturnsLocal(@TempDir Path tempDir) throws IOException {
|
||||
String dummySocketFilePath = "unix://" + Files.createTempFile(tempDir, "http-transport", null).toAbsolutePath();
|
||||
HttpTransport transport = HttpTransport.create(DockerHostConfiguration.forAddress(dummySocketFilePath));
|
||||
HttpTransport transport = HttpTransport.create(new DockerConnectionConfiguration.Host(dummySocketFilePath));
|
||||
assertThat(transport).isInstanceOf(LocalHttpClientTransport.class);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
* Copyright 2012-2025 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -24,7 +24,7 @@ import java.nio.file.Paths;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.io.TempDir;
|
||||
|
||||
import org.springframework.boot.buildpack.platform.docker.configuration.DockerConfiguration.DockerHostConfiguration;
|
||||
import org.springframework.boot.buildpack.platform.docker.configuration.DockerConnectionConfiguration;
|
||||
import org.springframework.boot.buildpack.platform.docker.configuration.ResolvedDockerHost;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
@@ -39,7 +39,7 @@ class LocalHttpClientTransportTests {
|
||||
@Test
|
||||
void createWhenDockerHostIsFileReturnsTransport(@TempDir Path tempDir) throws IOException {
|
||||
String socketFilePath = Files.createTempFile(tempDir, "remote-transport", null).toAbsolutePath().toString();
|
||||
ResolvedDockerHost dockerHost = ResolvedDockerHost.from(DockerHostConfiguration.forAddress(socketFilePath));
|
||||
ResolvedDockerHost dockerHost = ResolvedDockerHost.from(new DockerConnectionConfiguration.Host(socketFilePath));
|
||||
LocalHttpClientTransport transport = LocalHttpClientTransport.create(dockerHost);
|
||||
assertThat(transport).isNotNull();
|
||||
assertThat(transport.getHost().toHostString()).isEqualTo(socketFilePath);
|
||||
@@ -48,7 +48,7 @@ class LocalHttpClientTransportTests {
|
||||
@Test
|
||||
void createWhenDockerHostIsFileThatDoesNotExistReturnsTransport(@TempDir Path tempDir) {
|
||||
String socketFilePath = Paths.get(tempDir.toString(), "dummy").toAbsolutePath().toString();
|
||||
ResolvedDockerHost dockerHost = ResolvedDockerHost.from(DockerHostConfiguration.forAddress(socketFilePath));
|
||||
ResolvedDockerHost dockerHost = ResolvedDockerHost.from(new DockerConnectionConfiguration.Host(socketFilePath));
|
||||
LocalHttpClientTransport transport = LocalHttpClientTransport.create(dockerHost);
|
||||
assertThat(transport).isNotNull();
|
||||
assertThat(transport.getHost().toHostString()).isEqualTo(socketFilePath);
|
||||
@@ -57,7 +57,7 @@ class LocalHttpClientTransportTests {
|
||||
@Test
|
||||
void createWhenDockerHostIsAddressReturnsTransport() {
|
||||
ResolvedDockerHost dockerHost = ResolvedDockerHost
|
||||
.from(DockerHostConfiguration.forAddress("tcp://192.168.1.2:2376"));
|
||||
.from(new DockerConnectionConfiguration.Host("tcp://192.168.1.2:2376"));
|
||||
LocalHttpClientTransport transport = LocalHttpClientTransport.create(dockerHost);
|
||||
assertThat(transport).isNotNull();
|
||||
assertThat(transport.getHost().toHostString()).isEqualTo("tcp://192.168.1.2:2376");
|
||||
|
||||
@@ -23,7 +23,7 @@ import javax.net.ssl.SSLContext;
|
||||
import org.apache.hc.core5.http.HttpHost;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.buildpack.platform.docker.configuration.DockerConfiguration.DockerHostConfiguration;
|
||||
import org.springframework.boot.buildpack.platform.docker.configuration.DockerConnectionConfiguration;
|
||||
import org.springframework.boot.buildpack.platform.docker.configuration.ResolvedDockerHost;
|
||||
import org.springframework.boot.buildpack.platform.docker.ssl.SslContextFactory;
|
||||
|
||||
@@ -42,14 +42,7 @@ class RemoteHttpClientTransportTests {
|
||||
|
||||
@Test
|
||||
void createIfPossibleWhenDockerHostIsNotSetReturnsNull() {
|
||||
ResolvedDockerHost dockerHost = ResolvedDockerHost.from(null);
|
||||
RemoteHttpClientTransport transport = RemoteHttpClientTransport.createIfPossible(dockerHost);
|
||||
assertThat(transport).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void createIfPossibleWhenDockerHostIsDefaultReturnsNull() {
|
||||
ResolvedDockerHost dockerHost = ResolvedDockerHost.from(DockerHostConfiguration.forAddress(null));
|
||||
ResolvedDockerHost dockerHost = ResolvedDockerHost.from((DockerConnectionConfiguration) null);
|
||||
RemoteHttpClientTransport transport = RemoteHttpClientTransport.createIfPossible(dockerHost);
|
||||
assertThat(transport).isNull();
|
||||
}
|
||||
@@ -57,7 +50,7 @@ class RemoteHttpClientTransportTests {
|
||||
@Test
|
||||
void createIfPossibleWhenDockerHostIsFileReturnsNull() {
|
||||
ResolvedDockerHost dockerHost = ResolvedDockerHost
|
||||
.from(DockerHostConfiguration.forAddress("unix:///var/run/socket.sock"));
|
||||
.from(new DockerConnectionConfiguration.Host("unix:///var/run/socket.sock"));
|
||||
RemoteHttpClientTransport transport = RemoteHttpClientTransport.createIfPossible(dockerHost);
|
||||
assertThat(transport).isNull();
|
||||
}
|
||||
@@ -65,7 +58,7 @@ class RemoteHttpClientTransportTests {
|
||||
@Test
|
||||
void createIfPossibleWhenDockerHostIsAddressReturnsTransport() {
|
||||
ResolvedDockerHost dockerHost = ResolvedDockerHost
|
||||
.from(DockerHostConfiguration.forAddress("tcp://192.168.1.2:2376"));
|
||||
.from(new DockerConnectionConfiguration.Host("tcp://192.168.1.2:2376"));
|
||||
RemoteHttpClientTransport transport = RemoteHttpClientTransport.createIfPossible(dockerHost);
|
||||
assertThat(transport).isNotNull();
|
||||
}
|
||||
@@ -73,7 +66,7 @@ class RemoteHttpClientTransportTests {
|
||||
@Test
|
||||
void createIfPossibleWhenNoTlsVerifyUsesHttp() {
|
||||
ResolvedDockerHost dockerHost = ResolvedDockerHost
|
||||
.from(DockerHostConfiguration.forAddress("tcp://192.168.1.2:2376"));
|
||||
.from(new DockerConnectionConfiguration.Host("tcp://192.168.1.2:2376"));
|
||||
RemoteHttpClientTransport transport = RemoteHttpClientTransport.createIfPossible(dockerHost);
|
||||
assertThat(transport.getHost()).satisfies(hostOf("http", "192.168.1.2", 2376));
|
||||
}
|
||||
@@ -83,7 +76,7 @@ class RemoteHttpClientTransportTests {
|
||||
SslContextFactory sslContextFactory = mock(SslContextFactory.class);
|
||||
given(sslContextFactory.forDirectory("/test-cert-path")).willReturn(SSLContext.getDefault());
|
||||
ResolvedDockerHost dockerHost = ResolvedDockerHost
|
||||
.from(DockerHostConfiguration.forAddress("tcp://192.168.1.2:2376", true, "/test-cert-path"));
|
||||
.from(new DockerConnectionConfiguration.Host("tcp://192.168.1.2:2376", true, "/test-cert-path"));
|
||||
RemoteHttpClientTransport transport = RemoteHttpClientTransport.createIfPossible(dockerHost, sslContextFactory);
|
||||
assertThat(transport.getHost()).satisfies(hostOf("https", "192.168.1.2", 2376));
|
||||
}
|
||||
@@ -91,7 +84,7 @@ class RemoteHttpClientTransportTests {
|
||||
@Test
|
||||
void createIfPossibleWhenTlsVerifyWithMissingCertPathThrowsException() {
|
||||
ResolvedDockerHost dockerHost = ResolvedDockerHost
|
||||
.from(DockerHostConfiguration.forAddress("tcp://192.168.1.2:2376", true, null));
|
||||
.from(new DockerConnectionConfiguration.Host("tcp://192.168.1.2:2376", true, null));
|
||||
assertThatIllegalStateException().isThrownBy(() -> RemoteHttpClientTransport.createIfPossible(dockerHost))
|
||||
.withMessageContaining("Docker host TLS verification requires trust material");
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
* Copyright 2012-2025 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -26,7 +26,8 @@ import org.gradle.api.tasks.Input;
|
||||
import org.gradle.api.tasks.Nested;
|
||||
import org.gradle.api.tasks.Optional;
|
||||
|
||||
import org.springframework.boot.buildpack.platform.docker.configuration.DockerConfiguration;
|
||||
import org.springframework.boot.buildpack.platform.build.BuilderDockerConfiguration;
|
||||
import org.springframework.boot.buildpack.platform.docker.configuration.DockerRegistryAuthentication;
|
||||
|
||||
/**
|
||||
* Encapsulates Docker configuration options.
|
||||
@@ -113,13 +114,13 @@ public abstract class DockerSpec {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns this configuration as a {@link DockerConfiguration} instance. This method
|
||||
* should only be called when the configuration is complete and will no longer be
|
||||
* changed.
|
||||
* Returns this configuration as a {@link BuilderDockerConfiguration} instance. This
|
||||
* method should only be called when the configuration is complete and will no longer
|
||||
* be changed.
|
||||
* @return the Docker configuration
|
||||
*/
|
||||
DockerConfiguration asDockerConfiguration() {
|
||||
DockerConfiguration dockerConfiguration = new DockerConfiguration();
|
||||
BuilderDockerConfiguration asDockerConfiguration() {
|
||||
BuilderDockerConfiguration dockerConfiguration = new BuilderDockerConfiguration();
|
||||
dockerConfiguration = customizeHost(dockerConfiguration);
|
||||
dockerConfiguration = dockerConfiguration.withBindHostToBuilder(getBindHostToBuilder().get());
|
||||
dockerConfiguration = customizeBuilderAuthentication(dockerConfiguration);
|
||||
@@ -127,7 +128,7 @@ public abstract class DockerSpec {
|
||||
return dockerConfiguration;
|
||||
}
|
||||
|
||||
private DockerConfiguration customizeHost(DockerConfiguration dockerConfiguration) {
|
||||
private BuilderDockerConfiguration customizeHost(BuilderDockerConfiguration dockerConfiguration) {
|
||||
String context = getContext().getOrNull();
|
||||
String host = getHost().getOrNull();
|
||||
if (context != null && host != null) {
|
||||
@@ -143,36 +144,30 @@ public abstract class DockerSpec {
|
||||
return dockerConfiguration;
|
||||
}
|
||||
|
||||
private DockerConfiguration customizeBuilderAuthentication(DockerConfiguration dockerConfiguration) {
|
||||
if (this.builderRegistry == null || this.builderRegistry.hasEmptyAuth()) {
|
||||
return dockerConfiguration;
|
||||
}
|
||||
if (this.builderRegistry.hasTokenAuth() && !this.builderRegistry.hasUserAuth()) {
|
||||
return dockerConfiguration.withBuilderRegistryTokenAuthentication(this.builderRegistry.getToken().get());
|
||||
}
|
||||
if (this.builderRegistry.hasUserAuth() && !this.builderRegistry.hasTokenAuth()) {
|
||||
return dockerConfiguration.withBuilderRegistryUserAuthentication(this.builderRegistry.getUsername().get(),
|
||||
this.builderRegistry.getPassword().get(), this.builderRegistry.getUrl().getOrNull(),
|
||||
this.builderRegistry.getEmail().getOrNull());
|
||||
}
|
||||
throw new GradleException(
|
||||
"Invalid Docker builder registry configuration, either token or username/password must be provided");
|
||||
private BuilderDockerConfiguration customizeBuilderAuthentication(BuilderDockerConfiguration dockerConfiguration) {
|
||||
return dockerConfiguration
|
||||
.withBuilderRegistryAuthentication(getRegistryAuthentication("builder", this.builderRegistry, null));
|
||||
}
|
||||
|
||||
private DockerConfiguration customizePublishAuthentication(DockerConfiguration dockerConfiguration) {
|
||||
if (this.publishRegistry == null || this.publishRegistry.hasEmptyAuth()) {
|
||||
return dockerConfiguration.withEmptyPublishRegistryAuthentication();
|
||||
private BuilderDockerConfiguration customizePublishAuthentication(BuilderDockerConfiguration dockerConfiguration) {
|
||||
return dockerConfiguration.withPublishRegistryAuthentication(
|
||||
getRegistryAuthentication("publish", this.publishRegistry, DockerRegistryAuthentication.EMPTY_USER));
|
||||
}
|
||||
|
||||
private DockerRegistryAuthentication getRegistryAuthentication(String type, DockerRegistrySpec registry,
|
||||
DockerRegistryAuthentication fallback) {
|
||||
if (registry == null || registry.hasEmptyAuth()) {
|
||||
return fallback;
|
||||
}
|
||||
if (this.publishRegistry.hasTokenAuth() && !this.publishRegistry.hasUserAuth()) {
|
||||
return dockerConfiguration.withPublishRegistryTokenAuthentication(this.publishRegistry.getToken().get());
|
||||
if (registry.hasTokenAuth() && !registry.hasUserAuth()) {
|
||||
return DockerRegistryAuthentication.token(registry.getToken().get());
|
||||
}
|
||||
if (this.publishRegistry.hasUserAuth() && !this.publishRegistry.hasTokenAuth()) {
|
||||
return dockerConfiguration.withPublishRegistryUserAuthentication(this.publishRegistry.getUsername().get(),
|
||||
this.publishRegistry.getPassword().get(), this.publishRegistry.getUrl().getOrNull(),
|
||||
this.publishRegistry.getEmail().getOrNull());
|
||||
if (registry.hasUserAuth() && !registry.hasTokenAuth()) {
|
||||
return DockerRegistryAuthentication.user(registry.getUsername().get(), registry.getPassword().get(),
|
||||
registry.getUrl().getOrNull(), registry.getEmail().getOrNull());
|
||||
}
|
||||
throw new GradleException(
|
||||
"Invalid Docker publish registry configuration, either token or username/password must be provided");
|
||||
throw new GradleException("Invalid Docker " + type
|
||||
+ " registry configuration, either token or username/password must be provided");
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
* Copyright 2012-2025 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -24,8 +24,8 @@ import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.io.TempDir;
|
||||
|
||||
import org.springframework.boot.buildpack.platform.docker.configuration.DockerConfiguration;
|
||||
import org.springframework.boot.buildpack.platform.docker.configuration.DockerConfiguration.DockerHostConfiguration;
|
||||
import org.springframework.boot.buildpack.platform.build.BuilderDockerConfiguration;
|
||||
import org.springframework.boot.buildpack.platform.docker.configuration.DockerConnectionConfiguration;
|
||||
import org.springframework.boot.gradle.junit.GradleProjectBuilder;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
@@ -52,10 +52,10 @@ class DockerSpecTests {
|
||||
|
||||
@Test
|
||||
void asDockerConfigurationWithDefaults() {
|
||||
DockerConfiguration dockerConfiguration = this.dockerSpec.asDockerConfiguration();
|
||||
assertThat(dockerConfiguration.getHost()).isNull();
|
||||
assertThat(dockerConfiguration.getBuilderRegistryAuthentication()).isNull();
|
||||
assertThat(decoded(dockerConfiguration.getPublishRegistryAuthentication().getAuthHeader()))
|
||||
BuilderDockerConfiguration dockerConfiguration = this.dockerSpec.asDockerConfiguration();
|
||||
assertThat(dockerConfiguration.connection()).isNull();
|
||||
assertThat(dockerConfiguration.builderRegistryAuthentication()).isNull();
|
||||
assertThat(decoded(dockerConfiguration.publishRegistryAuthentication().getAuthHeader()))
|
||||
.contains("\"username\" : \"\"")
|
||||
.contains("\"password\" : \"\"")
|
||||
.contains("\"email\" : \"\"")
|
||||
@@ -67,15 +67,14 @@ class DockerSpecTests {
|
||||
this.dockerSpec.getHost().set("docker.example.com");
|
||||
this.dockerSpec.getTlsVerify().set(true);
|
||||
this.dockerSpec.getCertPath().set("/tmp/ca-cert");
|
||||
DockerConfiguration dockerConfiguration = this.dockerSpec.asDockerConfiguration();
|
||||
DockerHostConfiguration host = dockerConfiguration.getHost();
|
||||
assertThat(host.getAddress()).isEqualTo("docker.example.com");
|
||||
assertThat(host.isSecure()).isTrue();
|
||||
assertThat(host.getCertificatePath()).isEqualTo("/tmp/ca-cert");
|
||||
assertThat(host.getContext()).isNull();
|
||||
assertThat(dockerConfiguration.isBindHostToBuilder()).isFalse();
|
||||
assertThat(this.dockerSpec.asDockerConfiguration().getBuilderRegistryAuthentication()).isNull();
|
||||
assertThat(decoded(dockerConfiguration.getPublishRegistryAuthentication().getAuthHeader()))
|
||||
BuilderDockerConfiguration dockerConfiguration = this.dockerSpec.asDockerConfiguration();
|
||||
DockerConnectionConfiguration.Host host = (DockerConnectionConfiguration.Host) dockerConfiguration.connection();
|
||||
assertThat(host.address()).isEqualTo("docker.example.com");
|
||||
assertThat(host.secure()).isTrue();
|
||||
assertThat(host.certificatePath()).isEqualTo("/tmp/ca-cert");
|
||||
assertThat(dockerConfiguration.bindHostToBuilder()).isFalse();
|
||||
assertThat(dockerConfiguration.builderRegistryAuthentication()).isNull();
|
||||
assertThat(decoded(dockerConfiguration.publishRegistryAuthentication().getAuthHeader()))
|
||||
.contains("\"username\" : \"\"")
|
||||
.contains("\"password\" : \"\"")
|
||||
.contains("\"email\" : \"\"")
|
||||
@@ -85,15 +84,14 @@ class DockerSpecTests {
|
||||
@Test
|
||||
void asDockerConfigurationWithHostConfigurationNoTlsVerify() {
|
||||
this.dockerSpec.getHost().set("docker.example.com");
|
||||
DockerConfiguration dockerConfiguration = this.dockerSpec.asDockerConfiguration();
|
||||
DockerHostConfiguration host = dockerConfiguration.getHost();
|
||||
assertThat(host.getAddress()).isEqualTo("docker.example.com");
|
||||
assertThat(host.isSecure()).isFalse();
|
||||
assertThat(host.getCertificatePath()).isNull();
|
||||
assertThat(host.getContext()).isNull();
|
||||
assertThat(dockerConfiguration.isBindHostToBuilder()).isFalse();
|
||||
assertThat(this.dockerSpec.asDockerConfiguration().getBuilderRegistryAuthentication()).isNull();
|
||||
assertThat(decoded(dockerConfiguration.getPublishRegistryAuthentication().getAuthHeader()))
|
||||
BuilderDockerConfiguration dockerConfiguration = this.dockerSpec.asDockerConfiguration();
|
||||
DockerConnectionConfiguration.Host host = (DockerConnectionConfiguration.Host) dockerConfiguration.connection();
|
||||
assertThat(host.address()).isEqualTo("docker.example.com");
|
||||
assertThat(host.secure()).isFalse();
|
||||
assertThat(host.certificatePath()).isNull();
|
||||
assertThat(dockerConfiguration.bindHostToBuilder()).isFalse();
|
||||
assertThat(dockerConfiguration.builderRegistryAuthentication()).isNull();
|
||||
assertThat(decoded(dockerConfiguration.publishRegistryAuthentication().getAuthHeader()))
|
||||
.contains("\"username\" : \"\"")
|
||||
.contains("\"password\" : \"\"")
|
||||
.contains("\"email\" : \"\"")
|
||||
@@ -103,15 +101,13 @@ class DockerSpecTests {
|
||||
@Test
|
||||
void asDockerConfigurationWithContextConfiguration() {
|
||||
this.dockerSpec.getContext().set("test-context");
|
||||
DockerConfiguration dockerConfiguration = this.dockerSpec.asDockerConfiguration();
|
||||
DockerHostConfiguration host = dockerConfiguration.getHost();
|
||||
assertThat(host.getContext()).isEqualTo("test-context");
|
||||
assertThat(host.getAddress()).isNull();
|
||||
assertThat(host.isSecure()).isFalse();
|
||||
assertThat(host.getCertificatePath()).isNull();
|
||||
assertThat(dockerConfiguration.isBindHostToBuilder()).isFalse();
|
||||
assertThat(this.dockerSpec.asDockerConfiguration().getBuilderRegistryAuthentication()).isNull();
|
||||
assertThat(decoded(dockerConfiguration.getPublishRegistryAuthentication().getAuthHeader()))
|
||||
BuilderDockerConfiguration dockerConfiguration = this.dockerSpec.asDockerConfiguration();
|
||||
DockerConnectionConfiguration.Context host = (DockerConnectionConfiguration.Context) dockerConfiguration
|
||||
.connection();
|
||||
assertThat(host.context()).isEqualTo("test-context");
|
||||
assertThat(dockerConfiguration.bindHostToBuilder()).isFalse();
|
||||
assertThat(dockerConfiguration.builderRegistryAuthentication()).isNull();
|
||||
assertThat(decoded(dockerConfiguration.publishRegistryAuthentication().getAuthHeader()))
|
||||
.contains("\"username\" : \"\"")
|
||||
.contains("\"password\" : \"\"")
|
||||
.contains("\"email\" : \"\"")
|
||||
@@ -130,14 +126,14 @@ class DockerSpecTests {
|
||||
void asDockerConfigurationWithBindHostToBuilder() {
|
||||
this.dockerSpec.getHost().set("docker.example.com");
|
||||
this.dockerSpec.getBindHostToBuilder().set(true);
|
||||
DockerConfiguration dockerConfiguration = this.dockerSpec.asDockerConfiguration();
|
||||
DockerHostConfiguration host = dockerConfiguration.getHost();
|
||||
assertThat(host.getAddress()).isEqualTo("docker.example.com");
|
||||
assertThat(host.isSecure()).isFalse();
|
||||
assertThat(host.getCertificatePath()).isNull();
|
||||
assertThat(dockerConfiguration.isBindHostToBuilder()).isTrue();
|
||||
assertThat(this.dockerSpec.asDockerConfiguration().getBuilderRegistryAuthentication()).isNull();
|
||||
assertThat(decoded(dockerConfiguration.getPublishRegistryAuthentication().getAuthHeader()))
|
||||
BuilderDockerConfiguration dockerConfiguration = this.dockerSpec.asDockerConfiguration();
|
||||
DockerConnectionConfiguration.Host host = (DockerConnectionConfiguration.Host) dockerConfiguration.connection();
|
||||
assertThat(host.address()).isEqualTo("docker.example.com");
|
||||
assertThat(host.secure()).isFalse();
|
||||
assertThat(host.certificatePath()).isNull();
|
||||
assertThat(dockerConfiguration.bindHostToBuilder()).isTrue();
|
||||
assertThat(dockerConfiguration.builderRegistryAuthentication()).isNull();
|
||||
assertThat(decoded(dockerConfiguration.publishRegistryAuthentication().getAuthHeader()))
|
||||
.contains("\"username\" : \"\"")
|
||||
.contains("\"password\" : \"\"")
|
||||
.contains("\"email\" : \"\"")
|
||||
@@ -158,18 +154,18 @@ class DockerSpecTests {
|
||||
registry.getUrl().set("https://docker2.example.com");
|
||||
registry.getEmail().set("docker2@example.com");
|
||||
});
|
||||
DockerConfiguration dockerConfiguration = this.dockerSpec.asDockerConfiguration();
|
||||
assertThat(decoded(dockerConfiguration.getBuilderRegistryAuthentication().getAuthHeader()))
|
||||
BuilderDockerConfiguration dockerConfiguration = this.dockerSpec.asDockerConfiguration();
|
||||
assertThat(decoded(dockerConfiguration.builderRegistryAuthentication().getAuthHeader()))
|
||||
.contains("\"username\" : \"user1\"")
|
||||
.contains("\"password\" : \"secret1\"")
|
||||
.contains("\"email\" : \"docker1@example.com\"")
|
||||
.contains("\"serveraddress\" : \"https://docker1.example.com\"");
|
||||
assertThat(decoded(dockerConfiguration.getPublishRegistryAuthentication().getAuthHeader()))
|
||||
assertThat(decoded(dockerConfiguration.publishRegistryAuthentication().getAuthHeader()))
|
||||
.contains("\"username\" : \"user2\"")
|
||||
.contains("\"password\" : \"secret2\"")
|
||||
.contains("\"email\" : \"docker2@example.com\"")
|
||||
.contains("\"serveraddress\" : \"https://docker2.example.com\"");
|
||||
assertThat(this.dockerSpec.asDockerConfiguration().getHost()).isNull();
|
||||
assertThat(dockerConfiguration.connection()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -198,10 +194,10 @@ class DockerSpecTests {
|
||||
void asDockerConfigurationWithTokenAuth() {
|
||||
this.dockerSpec.builderRegistry((registry) -> registry.getToken().set("token1"));
|
||||
this.dockerSpec.publishRegistry((registry) -> registry.getToken().set("token2"));
|
||||
DockerConfiguration dockerConfiguration = this.dockerSpec.asDockerConfiguration();
|
||||
assertThat(decoded(dockerConfiguration.getBuilderRegistryAuthentication().getAuthHeader()))
|
||||
BuilderDockerConfiguration dockerConfiguration = this.dockerSpec.asDockerConfiguration();
|
||||
assertThat(decoded(dockerConfiguration.builderRegistryAuthentication().getAuthHeader()))
|
||||
.contains("\"identitytoken\" : \"token1\"");
|
||||
assertThat(decoded(dockerConfiguration.getPublishRegistryAuthentication().getAuthHeader()))
|
||||
assertThat(decoded(dockerConfiguration.publishRegistryAuthentication().getAuthHeader()))
|
||||
.contains("\"identitytoken\" : \"token2\"");
|
||||
}
|
||||
|
||||
|
||||
@@ -38,10 +38,10 @@ import org.springframework.boot.buildpack.platform.build.AbstractBuildLog;
|
||||
import org.springframework.boot.buildpack.platform.build.BuildLog;
|
||||
import org.springframework.boot.buildpack.platform.build.BuildRequest;
|
||||
import org.springframework.boot.buildpack.platform.build.Builder;
|
||||
import org.springframework.boot.buildpack.platform.build.BuilderDockerConfiguration;
|
||||
import org.springframework.boot.buildpack.platform.build.Creator;
|
||||
import org.springframework.boot.buildpack.platform.build.PullPolicy;
|
||||
import org.springframework.boot.buildpack.platform.docker.TotalProgressEvent;
|
||||
import org.springframework.boot.buildpack.platform.docker.configuration.DockerConfiguration;
|
||||
import org.springframework.boot.buildpack.platform.io.Owner;
|
||||
import org.springframework.boot.buildpack.platform.io.TarArchive;
|
||||
import org.springframework.boot.loader.tools.EntryWriter;
|
||||
@@ -262,7 +262,7 @@ public abstract class BuildImageMojo extends AbstractPackagerMojo {
|
||||
Libraries libraries = getLibraries(Collections.emptySet());
|
||||
try {
|
||||
BuildRequest request = getBuildRequest(libraries);
|
||||
DockerConfiguration dockerConfiguration = (this.docker != null)
|
||||
BuilderDockerConfiguration dockerConfiguration = (this.docker != null)
|
||||
? this.docker.asDockerConfiguration(request.isPublish())
|
||||
: new Docker().asDockerConfiguration(request.isPublish());
|
||||
Builder builder = new Builder(new MojoBuildLog(this::getLog), dockerConfiguration);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2024 the original author or authors.
|
||||
* Copyright 2012-2025 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,7 +16,8 @@
|
||||
|
||||
package org.springframework.boot.maven;
|
||||
|
||||
import org.springframework.boot.buildpack.platform.docker.configuration.DockerConfiguration;
|
||||
import org.springframework.boot.buildpack.platform.build.BuilderDockerConfiguration;
|
||||
import org.springframework.boot.buildpack.platform.docker.configuration.DockerRegistryAuthentication;
|
||||
|
||||
/**
|
||||
* Docker configuration options.
|
||||
@@ -137,14 +138,14 @@ public class Docker {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns this configuration as a {@link DockerConfiguration} instance. This method
|
||||
* should only be called when the configuration is complete and will no longer be
|
||||
* changed.
|
||||
* Returns this configuration as a {@link BuilderDockerConfiguration} instance. This
|
||||
* method should only be called when the configuration is complete and will no longer
|
||||
* be changed.
|
||||
* @param publish whether the image should be published
|
||||
* @return the Docker configuration
|
||||
*/
|
||||
DockerConfiguration asDockerConfiguration(boolean publish) {
|
||||
DockerConfiguration dockerConfiguration = new DockerConfiguration();
|
||||
BuilderDockerConfiguration asDockerConfiguration(boolean publish) {
|
||||
BuilderDockerConfiguration dockerConfiguration = new BuilderDockerConfiguration();
|
||||
dockerConfiguration = customizeHost(dockerConfiguration);
|
||||
dockerConfiguration = dockerConfiguration.withBindHostToBuilder(this.bindHostToBuilder);
|
||||
dockerConfiguration = customizeBuilderAuthentication(dockerConfiguration);
|
||||
@@ -152,7 +153,7 @@ public class Docker {
|
||||
return dockerConfiguration;
|
||||
}
|
||||
|
||||
private DockerConfiguration customizeHost(DockerConfiguration dockerConfiguration) {
|
||||
private BuilderDockerConfiguration customizeHost(BuilderDockerConfiguration dockerConfiguration) {
|
||||
if (this.context != null && this.host != null) {
|
||||
throw new IllegalArgumentException(
|
||||
"Invalid Docker configuration, either context or host can be provided but not both");
|
||||
@@ -166,38 +167,34 @@ public class Docker {
|
||||
return dockerConfiguration;
|
||||
}
|
||||
|
||||
private DockerConfiguration customizeBuilderAuthentication(DockerConfiguration dockerConfiguration) {
|
||||
if (this.builderRegistry == null || this.builderRegistry.isEmpty()) {
|
||||
return dockerConfiguration;
|
||||
}
|
||||
if (this.builderRegistry.hasTokenAuth() && !this.builderRegistry.hasUserAuth()) {
|
||||
return dockerConfiguration.withBuilderRegistryTokenAuthentication(this.builderRegistry.getToken());
|
||||
}
|
||||
if (this.builderRegistry.hasUserAuth() && !this.builderRegistry.hasTokenAuth()) {
|
||||
return dockerConfiguration.withBuilderRegistryUserAuthentication(this.builderRegistry.getUsername(),
|
||||
this.builderRegistry.getPassword(), this.builderRegistry.getUrl(), this.builderRegistry.getEmail());
|
||||
}
|
||||
throw new IllegalArgumentException(
|
||||
"Invalid Docker builder registry configuration, either token or username/password must be provided");
|
||||
private BuilderDockerConfiguration customizeBuilderAuthentication(BuilderDockerConfiguration dockerConfiguration) {
|
||||
return dockerConfiguration
|
||||
.withBuilderRegistryAuthentication(getRegistryAuthentication("builder", this.builderRegistry, null));
|
||||
}
|
||||
|
||||
private DockerConfiguration customizePublishAuthentication(DockerConfiguration dockerConfiguration,
|
||||
private BuilderDockerConfiguration customizePublishAuthentication(BuilderDockerConfiguration dockerConfiguration,
|
||||
boolean publish) {
|
||||
if (!publish) {
|
||||
return dockerConfiguration;
|
||||
}
|
||||
if (this.publishRegistry == null || this.publishRegistry.isEmpty()) {
|
||||
return dockerConfiguration.withEmptyPublishRegistryAuthentication();
|
||||
return dockerConfiguration.withPublishRegistryAuthentication(
|
||||
getRegistryAuthentication("publish", this.publishRegistry, DockerRegistryAuthentication.EMPTY_USER));
|
||||
}
|
||||
|
||||
private DockerRegistryAuthentication getRegistryAuthentication(String type, DockerRegistry registry,
|
||||
DockerRegistryAuthentication fallback) {
|
||||
if (registry == null || registry.isEmpty()) {
|
||||
return fallback;
|
||||
}
|
||||
if (this.publishRegistry.hasTokenAuth() && !this.publishRegistry.hasUserAuth()) {
|
||||
return dockerConfiguration.withPublishRegistryTokenAuthentication(this.publishRegistry.getToken());
|
||||
if (registry.hasTokenAuth() && !registry.hasUserAuth()) {
|
||||
return DockerRegistryAuthentication.token(registry.getToken());
|
||||
}
|
||||
if (this.publishRegistry.hasUserAuth() && !this.publishRegistry.hasTokenAuth()) {
|
||||
return dockerConfiguration.withPublishRegistryUserAuthentication(this.publishRegistry.getUsername(),
|
||||
this.publishRegistry.getPassword(), this.publishRegistry.getUrl(), this.publishRegistry.getEmail());
|
||||
if (registry.hasUserAuth() && !registry.hasTokenAuth()) {
|
||||
return DockerRegistryAuthentication.user(registry.getUsername(), registry.getPassword(), registry.getUrl(),
|
||||
registry.getEmail());
|
||||
}
|
||||
throw new IllegalArgumentException(
|
||||
"Invalid Docker publish registry configuration, either token or username/password must be provided");
|
||||
throw new IllegalArgumentException("Invalid Docker " + type
|
||||
+ " registry configuration, either token or username/password must be provided");
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2024 the original author or authors.
|
||||
* Copyright 2012-2025 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -20,8 +20,8 @@ import java.util.Base64;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.buildpack.platform.docker.configuration.DockerConfiguration;
|
||||
import org.springframework.boot.buildpack.platform.docker.configuration.DockerConfiguration.DockerHostConfiguration;
|
||||
import org.springframework.boot.buildpack.platform.build.BuilderDockerConfiguration;
|
||||
import org.springframework.boot.buildpack.platform.docker.configuration.DockerConnectionConfiguration;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
||||
@@ -37,10 +37,10 @@ class DockerTests {
|
||||
@Test
|
||||
void asDockerConfigurationWithDefaults() {
|
||||
Docker docker = new Docker();
|
||||
DockerConfiguration dockerConfiguration = createDockerConfiguration(docker);
|
||||
assertThat(dockerConfiguration.getHost()).isNull();
|
||||
assertThat(dockerConfiguration.getBuilderRegistryAuthentication()).isNull();
|
||||
assertThat(decoded(dockerConfiguration.getPublishRegistryAuthentication().getAuthHeader()))
|
||||
BuilderDockerConfiguration dockerConfiguration = createDockerConfiguration(docker);
|
||||
assertThat(dockerConfiguration.connection()).isNull();
|
||||
assertThat(dockerConfiguration.builderRegistryAuthentication()).isNull();
|
||||
assertThat(decoded(dockerConfiguration.publishRegistryAuthentication().getAuthHeader()))
|
||||
.contains("\"username\" : \"\"")
|
||||
.contains("\"password\" : \"\"")
|
||||
.contains("\"email\" : \"\"")
|
||||
@@ -53,15 +53,14 @@ class DockerTests {
|
||||
docker.setHost("docker.example.com");
|
||||
docker.setTlsVerify(true);
|
||||
docker.setCertPath("/tmp/ca-cert");
|
||||
DockerConfiguration dockerConfiguration = createDockerConfiguration(docker);
|
||||
DockerHostConfiguration host = dockerConfiguration.getHost();
|
||||
assertThat(host.getAddress()).isEqualTo("docker.example.com");
|
||||
assertThat(host.isSecure()).isTrue();
|
||||
assertThat(host.getCertificatePath()).isEqualTo("/tmp/ca-cert");
|
||||
assertThat(host.getContext()).isNull();
|
||||
assertThat(dockerConfiguration.isBindHostToBuilder()).isFalse();
|
||||
assertThat(createDockerConfiguration(docker).getBuilderRegistryAuthentication()).isNull();
|
||||
assertThat(decoded(dockerConfiguration.getPublishRegistryAuthentication().getAuthHeader()))
|
||||
BuilderDockerConfiguration dockerConfiguration = createDockerConfiguration(docker);
|
||||
DockerConnectionConfiguration.Host host = (DockerConnectionConfiguration.Host) dockerConfiguration.connection();
|
||||
assertThat(host.address()).isEqualTo("docker.example.com");
|
||||
assertThat(host.secure()).isTrue();
|
||||
assertThat(host.certificatePath()).isEqualTo("/tmp/ca-cert");
|
||||
assertThat(dockerConfiguration.bindHostToBuilder()).isFalse();
|
||||
assertThat(createDockerConfiguration(docker).builderRegistryAuthentication()).isNull();
|
||||
assertThat(decoded(dockerConfiguration.publishRegistryAuthentication().getAuthHeader()))
|
||||
.contains("\"username\" : \"\"")
|
||||
.contains("\"password\" : \"\"")
|
||||
.contains("\"email\" : \"\"")
|
||||
@@ -72,15 +71,13 @@ class DockerTests {
|
||||
void asDockerConfigurationWithContextConfiguration() {
|
||||
Docker docker = new Docker();
|
||||
docker.setContext("test-context");
|
||||
DockerConfiguration dockerConfiguration = createDockerConfiguration(docker);
|
||||
DockerHostConfiguration host = dockerConfiguration.getHost();
|
||||
assertThat(host.getContext()).isEqualTo("test-context");
|
||||
assertThat(host.getAddress()).isNull();
|
||||
assertThat(host.isSecure()).isFalse();
|
||||
assertThat(host.getCertificatePath()).isNull();
|
||||
assertThat(dockerConfiguration.isBindHostToBuilder()).isFalse();
|
||||
assertThat(createDockerConfiguration(docker).getBuilderRegistryAuthentication()).isNull();
|
||||
assertThat(decoded(dockerConfiguration.getPublishRegistryAuthentication().getAuthHeader()))
|
||||
BuilderDockerConfiguration dockerConfiguration = createDockerConfiguration(docker);
|
||||
DockerConnectionConfiguration.Context context = (DockerConnectionConfiguration.Context) dockerConfiguration
|
||||
.connection();
|
||||
assertThat(context.context()).isEqualTo("test-context");
|
||||
assertThat(dockerConfiguration.bindHostToBuilder()).isFalse();
|
||||
assertThat(createDockerConfiguration(docker).builderRegistryAuthentication()).isNull();
|
||||
assertThat(decoded(dockerConfiguration.publishRegistryAuthentication().getAuthHeader()))
|
||||
.contains("\"username\" : \"\"")
|
||||
.contains("\"password\" : \"\"")
|
||||
.contains("\"email\" : \"\"")
|
||||
@@ -103,14 +100,14 @@ class DockerTests {
|
||||
docker.setTlsVerify(true);
|
||||
docker.setCertPath("/tmp/ca-cert");
|
||||
docker.setBindHostToBuilder(true);
|
||||
DockerConfiguration dockerConfiguration = createDockerConfiguration(docker);
|
||||
DockerHostConfiguration host = dockerConfiguration.getHost();
|
||||
assertThat(host.getAddress()).isEqualTo("docker.example.com");
|
||||
assertThat(host.isSecure()).isTrue();
|
||||
assertThat(host.getCertificatePath()).isEqualTo("/tmp/ca-cert");
|
||||
assertThat(dockerConfiguration.isBindHostToBuilder()).isTrue();
|
||||
assertThat(createDockerConfiguration(docker).getBuilderRegistryAuthentication()).isNull();
|
||||
assertThat(decoded(dockerConfiguration.getPublishRegistryAuthentication().getAuthHeader()))
|
||||
BuilderDockerConfiguration dockerConfiguration = createDockerConfiguration(docker);
|
||||
DockerConnectionConfiguration.Host host = (DockerConnectionConfiguration.Host) dockerConfiguration.connection();
|
||||
assertThat(host.address()).isEqualTo("docker.example.com");
|
||||
assertThat(host.secure()).isTrue();
|
||||
assertThat(host.certificatePath()).isEqualTo("/tmp/ca-cert");
|
||||
assertThat(dockerConfiguration.bindHostToBuilder()).isTrue();
|
||||
assertThat(createDockerConfiguration(docker).builderRegistryAuthentication()).isNull();
|
||||
assertThat(decoded(dockerConfiguration.publishRegistryAuthentication().getAuthHeader()))
|
||||
.contains("\"username\" : \"\"")
|
||||
.contains("\"password\" : \"\"")
|
||||
.contains("\"email\" : \"\"")
|
||||
@@ -124,13 +121,13 @@ class DockerTests {
|
||||
new Docker.DockerRegistry("user1", "secret1", "https://docker1.example.com", "docker1@example.com"));
|
||||
docker.setPublishRegistry(
|
||||
new Docker.DockerRegistry("user2", "secret2", "https://docker2.example.com", "docker2@example.com"));
|
||||
DockerConfiguration dockerConfiguration = createDockerConfiguration(docker);
|
||||
assertThat(decoded(dockerConfiguration.getBuilderRegistryAuthentication().getAuthHeader()))
|
||||
BuilderDockerConfiguration dockerConfiguration = createDockerConfiguration(docker);
|
||||
assertThat(decoded(dockerConfiguration.builderRegistryAuthentication().getAuthHeader()))
|
||||
.contains("\"username\" : \"user1\"")
|
||||
.contains("\"password\" : \"secret1\"")
|
||||
.contains("\"email\" : \"docker1@example.com\"")
|
||||
.contains("\"serveraddress\" : \"https://docker1.example.com\"");
|
||||
assertThat(decoded(dockerConfiguration.getPublishRegistryAuthentication().getAuthHeader()))
|
||||
assertThat(decoded(dockerConfiguration.publishRegistryAuthentication().getAuthHeader()))
|
||||
.contains("\"username\" : \"user2\"")
|
||||
.contains("\"password\" : \"secret2\"")
|
||||
.contains("\"email\" : \"docker2@example.com\"")
|
||||
@@ -160,8 +157,8 @@ class DockerTests {
|
||||
Docker docker = new Docker();
|
||||
docker.setPublishRegistry(
|
||||
new Docker.DockerRegistry("user", null, "https://docker.example.com", "docker@example.com"));
|
||||
DockerConfiguration dockerConfiguration = docker.asDockerConfiguration(false);
|
||||
assertThat(dockerConfiguration.getPublishRegistryAuthentication()).isNull();
|
||||
BuilderDockerConfiguration dockerConfiguration = docker.asDockerConfiguration(false);
|
||||
assertThat(dockerConfiguration.publishRegistryAuthentication()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -169,10 +166,10 @@ class DockerTests {
|
||||
Docker docker = new Docker();
|
||||
docker.setBuilderRegistry(new Docker.DockerRegistry("token1"));
|
||||
docker.setPublishRegistry(new Docker.DockerRegistry("token2"));
|
||||
DockerConfiguration dockerConfiguration = createDockerConfiguration(docker);
|
||||
assertThat(decoded(dockerConfiguration.getBuilderRegistryAuthentication().getAuthHeader()))
|
||||
BuilderDockerConfiguration dockerConfiguration = createDockerConfiguration(docker);
|
||||
assertThat(decoded(dockerConfiguration.builderRegistryAuthentication().getAuthHeader()))
|
||||
.contains("\"identitytoken\" : \"token1\"");
|
||||
assertThat(decoded(dockerConfiguration.getPublishRegistryAuthentication().getAuthHeader()))
|
||||
assertThat(decoded(dockerConfiguration.publishRegistryAuthentication().getAuthHeader()))
|
||||
.contains("\"identitytoken\" : \"token2\"");
|
||||
}
|
||||
|
||||
@@ -196,13 +193,12 @@ class DockerTests {
|
||||
dockerRegistry.setToken("token");
|
||||
Docker docker = new Docker();
|
||||
docker.setPublishRegistry(dockerRegistry);
|
||||
DockerConfiguration dockerConfiguration = docker.asDockerConfiguration(false);
|
||||
assertThat(dockerConfiguration.getPublishRegistryAuthentication()).isNull();
|
||||
BuilderDockerConfiguration dockerConfiguration = docker.asDockerConfiguration(false);
|
||||
assertThat(dockerConfiguration.publishRegistryAuthentication()).isNull();
|
||||
}
|
||||
|
||||
private DockerConfiguration createDockerConfiguration(Docker docker) {
|
||||
private BuilderDockerConfiguration createDockerConfiguration(Docker docker) {
|
||||
return docker.asDockerConfiguration(true);
|
||||
|
||||
}
|
||||
|
||||
String decoded(String value) {
|
||||
|
||||
Reference in New Issue
Block a user