Merge branch '2.6.x' into 2.7.x

Closes gh-31824
This commit is contained in:
Scott Frederick 2022-07-20 15:10:43 -05:00
commit 09c7ce6dab
14 changed files with 43 additions and 68 deletions

View File

@ -102,4 +102,9 @@ public final class DockerConfiguration {
new DockerRegistryUserAuthentication(username, password, url, email), this.bindHostToBuilder);
}
public DockerConfiguration withEmptyPublishRegistryAuthentication() {
return new DockerConfiguration(this.host, this.builderAuthentication,
new DockerRegistryUserAuthentication("", "", "", ""));
}
}

View File

@ -369,7 +369,10 @@ An OCI image containing a https://buildpacks.io/docs/buildpack-author-guide/pack
[[build-image.examples.publish]]
=== Image Publishing
The generated image can be published to a Docker registry by enabling a `publish` option and configuring authentication for the registry using `docker.publishRegistry` properties.
The generated image can be published to a Docker registry by enabling a `publish` option.
If the Docker registry requires authentication, the credentials can be configured using `docker.publishRegistry` properties.
If the Docker registry does not require authentication, the `docker.publishRegistry` configuration can be omitted.
[source,groovy,indent=0,subs="verbatim,attributes",role="primary"]
.Groovy

View File

@ -25,7 +25,6 @@ import java.util.stream.Collectors;
import groovy.lang.Closure;
import org.gradle.api.Action;
import org.gradle.api.DefaultTask;
import org.gradle.api.GradleException;
import org.gradle.api.JavaVersion;
import org.gradle.api.Project;
import org.gradle.api.Task;
@ -594,11 +593,6 @@ public class BootBuildImage extends DefaultTask {
}
private BuildRequest customizePublish(BuildRequest request) {
boolean publishRegistryAuthNotConfigured = this.docker == null || this.docker.getPublishRegistry() == null
|| this.docker.getPublishRegistry().hasEmptyAuth();
if (this.publish && publishRegistryAuthNotConfigured) {
throw new GradleException("Publishing an image requires docker.publishRegistry to be configured");
}
request = request.withPublish(this.publish);
return request;
}

View File

@ -192,7 +192,7 @@ public class DockerSpec {
private DockerConfiguration customizePublishAuthentication(DockerConfiguration dockerConfiguration) {
if (this.publishRegistry == null || this.publishRegistry.hasEmptyAuth()) {
return dockerConfiguration;
return dockerConfiguration.withEmptyPublishRegistryAuthentication();
}
if (this.publishRegistry.hasTokenAuth() && !this.publishRegistry.hasUserAuth()) {
return dockerConfiguration.withPublishRegistryTokenAuthentication(this.publishRegistry.getToken());

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2021 the original author or authors.
* Copyright 2012-2022 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.
@ -313,15 +313,6 @@ class BootBuildImageIntegrationTests {
.containsPattern("example/Invalid-Image-Name");
}
@TestTemplate
void failsWithPublishMissingPublishRegistry() throws IOException {
writeMainClass();
writeLongNameResource();
BuildResult result = this.gradleBuild.buildAndFail("bootBuildImage", "--publishImage");
assertThat(result.task(":bootBuildImage").getOutcome()).isEqualTo(TaskOutcome.FAILED);
assertThat(result.getOutput()).contains("requires docker.publishRegistry");
}
@TestTemplate
void failsWithBuildpackNotInBuilder() throws IOException {
writeMainClass();

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2021 the original author or authors.
* Copyright 2012-2022 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.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import org.gradle.api.GradleException;
import org.gradle.api.JavaVersion;
import org.gradle.api.Project;
import org.junit.jupiter.api.BeforeEach;
@ -36,7 +35,6 @@ import org.springframework.boot.buildpack.platform.docker.type.ImageReference;
import org.springframework.boot.gradle.junit.GradleProjectBuilder;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
/**
* Tests for {@link BootBuildImage}.
@ -189,13 +187,6 @@ class BootBuildImageTests {
assertThat(this.buildImage.createRequest().isPublish()).isFalse();
}
@Test
void whenPublishIsEnabledWithoutPublishRegistryThenExceptionIsThrown() {
this.buildImage.setPublish(true);
assertThatExceptionOfType(GradleException.class).isThrownBy(this.buildImage::createRequest)
.withMessageContaining("Publishing an image requires docker.publishRegistry to be configured");
}
@Test
void whenNoBuilderIsConfiguredThenRequestHasDefaultBuilder() {
assertThat(this.buildImage.createRequest().getBuilder().getName()).isEqualTo("paketobuildpacks/builder");

View File

@ -37,9 +37,12 @@ class DockerSpecTests {
@Test
void asDockerConfigurationWithDefaults() {
DockerSpec dockerSpec = new DockerSpec();
assertThat(dockerSpec.asDockerConfiguration().getHost()).isNull();
assertThat(dockerSpec.asDockerConfiguration().getBuilderRegistryAuthentication()).isNull();
assertThat(dockerSpec.asDockerConfiguration().getPublishRegistryAuthentication()).isNull();
DockerConfiguration dockerConfiguration = dockerSpec.asDockerConfiguration();
assertThat(dockerConfiguration.getHost()).isNull();
assertThat(dockerConfiguration.getBuilderRegistryAuthentication()).isNull();
assertThat(decoded(dockerConfiguration.getPublishRegistryAuthentication().getAuthHeader()))
.contains("\"username\" : \"\"").contains("\"password\" : \"\"").contains("\"email\" : \"\"")
.contains("\"serveraddress\" : \"\"");
}
@Test
@ -55,7 +58,9 @@ class DockerSpecTests {
assertThat(host.getCertificatePath()).isEqualTo("/tmp/ca-cert");
assertThat(dockerConfiguration.isBindHostToBuilder()).isFalse();
assertThat(dockerSpec.asDockerConfiguration().getBuilderRegistryAuthentication()).isNull();
assertThat(dockerSpec.asDockerConfiguration().getPublishRegistryAuthentication()).isNull();
assertThat(decoded(dockerConfiguration.getPublishRegistryAuthentication().getAuthHeader()))
.contains("\"username\" : \"\"").contains("\"password\" : \"\"").contains("\"email\" : \"\"")
.contains("\"serveraddress\" : \"\"");
}
@Test
@ -84,7 +89,9 @@ class DockerSpecTests {
assertThat(host.getCertificatePath()).isNull();
assertThat(dockerConfiguration.isBindHostToBuilder()).isTrue();
assertThat(dockerSpec.asDockerConfiguration().getBuilderRegistryAuthentication()).isNull();
assertThat(dockerSpec.asDockerConfiguration().getPublishRegistryAuthentication()).isNull();
assertThat(decoded(dockerConfiguration.getPublishRegistryAuthentication().getAuthHeader()))
.contains("\"username\" : \"\"").contains("\"password\" : \"\"").contains("\"email\" : \"\"")
.contains("\"serveraddress\" : \"\"");
}
@Test

View File

@ -7,11 +7,6 @@ sourceCompatibility = '1.8'
targetCompatibility = '1.8'
bootBuildImage {
builder = "projects.registry.vmware.com/springboot/spring-boot-cnb-builder:0.0.1"
publish = true
docker {
publishRegistry {
username = "user"
password = "secret"
}
}
}

View File

@ -339,7 +339,10 @@ An OCI image containing a https://buildpacks.io/docs/buildpack-author-guide/pack
[[build-image.examples.publish]]
=== Image Publishing
The generated image can be published to a Docker registry by enabling a `publish` option and configuring authentication for the registry using `docker.publishRegistry` parameters.
The generated image can be published to a Docker registry by enabling a `publish` option.
If the Docker registry requires authentication, the credentials can be configured using `docker.publishRegistry` parameters.
If the Docker registry does not require authentication, the `docker.publishRegistry` configuration can be omitted.
[source,xml,indent=0,subs="verbatim,attributes",tabsize=4]
----

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2021 the original author or authors.
* Copyright 2012-2022 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.
@ -330,12 +330,6 @@ class BuildImageTests extends AbstractArchiveIntegrationTests {
(project) -> assertThat(buildLog(project)).contains("Error packaging archive for image"));
}
@TestTemplate
void failsWhenPublishWithoutPublishRegistryConfigured(MavenBuild mavenBuild) {
mavenBuild.project("build-image").goals("package").systemProperty("spring-boot.build-image.publish", "true")
.executeAndFail((project) -> assertThat(buildLog(project)).contains("requires docker.publishRegistry"));
}
@TestTemplate
void failsWhenBuilderFails(MavenBuild mavenBuild) {
mavenBuild.project("build-image-builder-error").goals("package")

View File

@ -23,14 +23,9 @@
</goals>
<configuration>
<image>
<builder>projects.registry.vmware.com/springboot/spring-boot-cnb-builder:0.0.1</builder>
<publish>true</publish>
</image>
<docker>
<publishRegistry>
<username>user</username>
<password>secret</password>
</publishRegistry>
</docker>
</configuration>
</execution>
</executions>

View File

@ -224,7 +224,7 @@ public class BuildImageMojo extends AbstractPackagerMojo {
Libraries libraries = getLibraries(Collections.emptySet());
try {
DockerConfiguration dockerConfiguration = (this.docker != null) ? this.docker.asDockerConfiguration()
: null;
: new Docker().asDockerConfiguration();
BuildRequest request = getBuildRequest(libraries);
Builder builder = new Builder(new MojoBuildLog(this::getLog), dockerConfiguration);
builder.build(request);
@ -234,7 +234,7 @@ public class BuildImageMojo extends AbstractPackagerMojo {
}
}
private BuildRequest getBuildRequest(Libraries libraries) throws MojoExecutionException {
private BuildRequest getBuildRequest(Libraries libraries) {
ImagePackager imagePackager = new ImagePackager(getArchiveFile(), getBackupFile());
Function<Owner, TarArchive> content = (owner) -> getApplicationContent(owner, libraries, imagePackager);
Image image = (this.image != null) ? this.image : new Image();
@ -259,17 +259,9 @@ public class BuildImageMojo extends AbstractPackagerMojo {
if (image.network == null && this.network != null) {
image.setNetwork(this.network);
}
if (image.publish != null && image.publish && publishRegistryNotConfigured()) {
throw new MojoExecutionException("Publishing an image requires docker.publishRegistry to be configured");
}
return customize(image.getBuildRequest(this.project.getArtifact(), content));
}
private boolean publishRegistryNotConfigured() {
return this.docker == null || this.docker.getPublishRegistry() == null
|| this.docker.getPublishRegistry().isEmpty();
}
private TarArchive getApplicationContent(Owner owner, Libraries libraries, ImagePackager imagePackager) {
ImagePackager packager = getConfiguredPackager(() -> imagePackager);
return new PackagedTarArchive(owner, libraries, packager);

View File

@ -161,7 +161,7 @@ public class Docker {
private DockerConfiguration customizePublishAuthentication(DockerConfiguration dockerConfiguration) {
if (this.publishRegistry == null || this.publishRegistry.isEmpty()) {
return dockerConfiguration;
return dockerConfiguration.withEmptyPublishRegistryAuthentication();
}
if (this.publishRegistry.hasTokenAuth() && !this.publishRegistry.hasUserAuth()) {
return dockerConfiguration.withPublishRegistryTokenAuthentication(this.publishRegistry.getToken());

View File

@ -36,9 +36,12 @@ class DockerTests {
@Test
void asDockerConfigurationWithDefaults() {
Docker docker = new Docker();
assertThat(docker.asDockerConfiguration().getHost()).isNull();
assertThat(docker.asDockerConfiguration().getBuilderRegistryAuthentication()).isNull();
assertThat(docker.asDockerConfiguration().getPublishRegistryAuthentication()).isNull();
DockerConfiguration dockerConfiguration = docker.asDockerConfiguration();
assertThat(dockerConfiguration.getHost()).isNull();
assertThat(dockerConfiguration.getBuilderRegistryAuthentication()).isNull();
assertThat(decoded(dockerConfiguration.getPublishRegistryAuthentication().getAuthHeader()))
.contains("\"username\" : \"\"").contains("\"password\" : \"\"").contains("\"email\" : \"\"")
.contains("\"serveraddress\" : \"\"");
}
@Test
@ -71,7 +74,9 @@ class DockerTests {
assertThat(host.getCertificatePath()).isEqualTo("/tmp/ca-cert");
assertThat(dockerConfiguration.isBindHostToBuilder()).isTrue();
assertThat(docker.asDockerConfiguration().getBuilderRegistryAuthentication()).isNull();
assertThat(docker.asDockerConfiguration().getPublishRegistryAuthentication()).isNull();
assertThat(decoded(dockerConfiguration.getPublishRegistryAuthentication().getAuthHeader()))
.contains("\"username\" : \"\"").contains("\"password\" : \"\"").contains("\"email\" : \"\"")
.contains("\"serveraddress\" : \"\"");
}
@Test