Skip to content

Commit

Permalink
Merge branch 'gh-28844' into 2.6.x
Browse files Browse the repository at this point in the history
Closes gh-31823
  • Loading branch information
scottfrederick committed Jul 20, 2022
2 parents ab2b04f + 9b0cdac commit a7dfeae
Show file tree
Hide file tree
Showing 14 changed files with 49 additions and 74 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2012-2020 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.
Expand Down Expand Up @@ -90,4 +90,9 @@ public DockerConfiguration withPublishRegistryUserAuthentication(String username
new DockerRegistryUserAuthentication(username, password, url, email));
}

public DockerConfiguration withEmptyPublishRegistryAuthentication() {
return new DockerConfiguration(this.host, this.builderAuthentication,
new DockerRegistryUserAuthentication("", "", "", ""));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -368,7 +368,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
Expand Down
Original file line number Diff line number Diff line change
@@ -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.
Expand All @@ -25,7 +25,6 @@
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;
Expand Down Expand Up @@ -605,11 +604,6 @@ private BuildRequest customizePullPolicy(BuildRequest request) {
}

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;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2012-2020 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.
Expand Down Expand Up @@ -179,7 +179,7 @@ private DockerConfiguration customizeBuilderAuthentication(DockerConfiguration d

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());
Expand Down
Original file line number Diff line number Diff line change
@@ -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.
Expand Down Expand Up @@ -313,15 +313,6 @@ void failsWithInvalidImageName() throws IOException {
.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();
Expand Down
Original file line number Diff line number Diff line change
@@ -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.
Expand All @@ -21,7 +21,6 @@
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;
Expand All @@ -36,7 +35,6 @@
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}.
Expand Down Expand Up @@ -189,13 +187,6 @@ void whenUsingDefaultConfigurationThenRequestHasPublishDisabled() {
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");
Expand Down
Original file line number Diff line number Diff line change
@@ -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.
Expand Down Expand Up @@ -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
Expand All @@ -54,7 +57,9 @@ void asDockerConfigurationWithHostConfiguration() {
assertThat(host.isSecure()).isEqualTo(true);
assertThat(host.getCertificatePath()).isEqualTo("/tmp/ca-cert");
assertThat(dockerSpec.asDockerConfiguration().getBuilderRegistryAuthentication()).isNull();
assertThat(dockerSpec.asDockerConfiguration().getPublishRegistryAuthentication()).isNull();
assertThat(decoded(dockerConfiguration.getPublishRegistryAuthentication().getAuthHeader()))
.contains("\"username\" : \"\"").contains("\"password\" : \"\"").contains("\"email\" : \"\"")
.contains("\"serveraddress\" : \"\"");
}

@Test
Expand All @@ -67,7 +72,9 @@ void asDockerConfigurationWithHostConfigurationNoTlsVerify() {
assertThat(host.isSecure()).isEqualTo(false);
assertThat(host.getCertificatePath()).isNull();
assertThat(dockerSpec.asDockerConfiguration().getBuilderRegistryAuthentication()).isNull();
assertThat(dockerSpec.asDockerConfiguration().getPublishRegistryAuthentication()).isNull();
assertThat(decoded(dockerConfiguration.getPublishRegistryAuthentication().getAuthHeader()))
.contains("\"username\" : \"\"").contains("\"password\" : \"\"").contains("\"email\" : \"\"")
.contains("\"serveraddress\" : \"\"");
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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"
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,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]
----
Expand Down
Original file line number Diff line number Diff line change
@@ -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.
Expand Down Expand Up @@ -330,12 +330,6 @@ void failsWhenBuildImageIsInvokedOnMultiModuleProjectWithBuildImageGoal(MavenBui
(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")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ private void buildImage() throws MojoExecutionException {
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);
Expand All @@ -234,7 +234,7 @@ private void buildImage() throws MojoExecutionException {
}
}

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();
Expand All @@ -259,17 +259,9 @@ private BuildRequest getBuildRequest(Libraries libraries) throws MojoExecutionEx
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);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2012-2020 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.
Expand Down Expand Up @@ -146,7 +146,7 @@ private DockerConfiguration customizeBuilderAuthentication(DockerConfiguration d

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());
Expand Down
Original file line number Diff line number Diff line change
@@ -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.
Expand Down Expand Up @@ -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
Expand All @@ -53,7 +56,9 @@ void asDockerConfigurationWithHostConfiguration() {
assertThat(host.isSecure()).isEqualTo(true);
assertThat(host.getCertificatePath()).isEqualTo("/tmp/ca-cert");
assertThat(docker.asDockerConfiguration().getBuilderRegistryAuthentication()).isNull();
assertThat(docker.asDockerConfiguration().getPublishRegistryAuthentication()).isNull();
assertThat(decoded(dockerConfiguration.getPublishRegistryAuthentication().getAuthHeader()))
.contains("\"username\" : \"\"").contains("\"password\" : \"\"").contains("\"email\" : \"\"")
.contains("\"serveraddress\" : \"\"");
}

@Test
Expand Down

0 comments on commit a7dfeae

Please sign in to comment.