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:
@@ -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