diff --git a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/build/AbstractBuildLog.java b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/build/AbstractBuildLog.java index e668917a707..863f82e3080 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/build/AbstractBuildLog.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/build/AbstractBuildLog.java @@ -30,6 +30,7 @@ import org.springframework.boot.buildpack.platform.docker.type.VolumeName; * * @author Phillip Webb * @author Scott Frederick + * @author Andrey Shlykov * @since 2.3.0 */ public abstract class AbstractBuildLog implements BuildLog { @@ -41,21 +42,25 @@ public abstract class AbstractBuildLog implements BuildLog { } @Override + @Deprecated public Consumer pullingBuilder(BuildRequest request, ImageReference imageReference) { return pullingImage(imageReference, ImageType.BUILDER); } @Override + @Deprecated public void pulledBuilder(BuildRequest request, Image image) { pulledImage(image, ImageType.BUILDER); } @Override + @Deprecated public Consumer pullingRunImage(BuildRequest request, ImageReference imageReference) { return pullingImage(imageReference, ImageType.RUNNER); } @Override + @Deprecated public void pulledRunImage(BuildRequest request, Image image) { pulledImage(image, ImageType.RUNNER); } diff --git a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/build/BuildLog.java b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/build/BuildLog.java index da13f1eb22c..cee0eafc8fe 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/build/BuildLog.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/build/BuildLog.java @@ -30,6 +30,7 @@ import org.springframework.boot.buildpack.platform.docker.type.VolumeName; * * @author Phillip Webb * @author Scott Frederick + * @author Andrey Shlykov * @since 2.3.0 * @see #toSystemOut() */ @@ -46,14 +47,19 @@ public interface BuildLog { * @param request the build request * @param imageReference the builder image reference * @return a consumer for progress update events + * @deprecated since 2.4.0 in favor of + * {@link #pullingImage(ImageReference, ImageType)} */ + @Deprecated Consumer pullingBuilder(BuildRequest request, ImageReference imageReference); /** * Log that the builder image has been pulled. * @param request the build request * @param image the builder image that was pulled + * @deprecated since 2.4.0 in favor of {@link #pulledImage(Image, ImageType)} */ + @Deprecated void pulledBuilder(BuildRequest request, Image image); /** @@ -61,18 +67,23 @@ public interface BuildLog { * @param request the build request * @param imageReference the run image reference * @return a consumer for progress update events + * @deprecated since 2.4.0 in favor of + * {@link #pullingImage(ImageReference, ImageType)} */ + @Deprecated Consumer pullingRunImage(BuildRequest request, ImageReference imageReference); /** * Log that a run image has been pulled. * @param request the build request * @param image the run image that was pulled + * @deprecated since 2.4.0 in favor of {@link #pulledImage(Image, ImageType)} */ + @Deprecated void pulledRunImage(BuildRequest request, Image image); /** - * Log that the image is being pulled. + * Log that an image is being pulled. * @param imageReference the image reference * @param imageType the image type * @return a consumer for progress update events @@ -80,7 +91,7 @@ public interface BuildLog { Consumer pullingImage(ImageReference imageReference, ImageType imageType); /** - * Log that the image has been pulled. + * Log that an image has been pulled. * @param image the builder image that was pulled * @param imageType the image type that was pulled */ diff --git a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/build/Builder.java b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/build/Builder.java index 3737d2e885c..de06b365239 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/build/Builder.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/build/Builder.java @@ -96,25 +96,21 @@ public class Builder { private Image getImage(BuildRequest request, ImageType imageType) throws IOException { ImageReference imageReference = (imageType == ImageType.BUILDER) ? request.getBuilder() : request.getRunImage(); - Image image; - if (request.getPullPolicy() != PullPolicy.ALWAYS) { - try { - image = this.docker.image().inspect(imageReference); - } - catch (DockerEngineException exception) { - if (request.getPullPolicy() == PullPolicy.IF_NOT_PRESENT && exception.getStatusCode() == 404) { - image = pullImage(imageReference, imageType); - } - else { - throw exception; - } - } - } - else { - image = pullImage(imageReference, imageType); + if (request.getPullPolicy() == PullPolicy.ALWAYS) { + return pullImage(imageReference, imageType); } - return image; + try { + return this.docker.image().inspect(imageReference); + } + catch (DockerEngineException exception) { + if (request.getPullPolicy() == PullPolicy.IF_NOT_PRESENT && exception.getStatusCode() == 404) { + return pullImage(imageReference, imageType); + } + else { + throw exception; + } + } } private Image pullImage(ImageReference reference, ImageType imageType) throws IOException { diff --git a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/build/ImageType.java b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/build/ImageType.java index 68713962b85..28bd79dc70b 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/build/ImageType.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/build/ImageType.java @@ -20,9 +20,8 @@ package org.springframework.boot.buildpack.platform.build; * Image types. * * @author Andrey Shlykov - * @since 2.4.0 */ -public enum ImageType { +enum ImageType { /** * Builder image. @@ -40,7 +39,7 @@ public enum ImageType { this.description = description; } - public String getDescription() { + String getDescription() { return this.description; } diff --git a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/build/PullPolicy.java b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/build/PullPolicy.java index 6969687b4bf..4cbbac8694a 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/build/PullPolicy.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/build/PullPolicy.java @@ -25,17 +25,17 @@ package org.springframework.boot.buildpack.platform.build; public enum PullPolicy { /** - * Always pull the image. + * Always pull the image from the registry. */ ALWAYS, /** - * Never pull the image. + * Never pull the image from the registry. */ NEVER, /** - * Pull the image if it does not already exist in registry. + * Pull the image from the registry only if it does not exist locally. */ IF_NOT_PRESENT diff --git a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/build/PrintStreamBuildLogTests.java b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/build/PrintStreamBuildLogTests.java index 00bb5d01455..ec0ec4f3f75 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/build/PrintStreamBuildLogTests.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/build/PrintStreamBuildLogTests.java @@ -57,12 +57,13 @@ class PrintStreamBuildLogTests { given(runImage.getDigests()).willReturn(Collections.singletonList("00000002")); given(request.getName()).willReturn(name); log.start(request); - Consumer pullBuildImageConsumer = log.pullingBuilder(request, builderImageReference); + Consumer pullBuildImageConsumer = log.pullingImage(builderImageReference, + ImageType.BUILDER); pullBuildImageConsumer.accept(new TotalProgressEvent(100)); - log.pulledBuilder(request, builderImage); - Consumer pullRunImageConsumer = log.pullingRunImage(request, runImageReference); + log.pulledImage(builderImage, ImageType.BUILDER); + Consumer pullRunImageConsumer = log.pullingImage(runImageReference, ImageType.RUNNER); pullRunImageConsumer.accept(new TotalProgressEvent(100)); - log.pulledRunImage(request, runImage); + log.pulledImage(runImage, ImageType.RUNNER); log.executingLifecycle(request, LifecycleVersion.parse("0.5"), VolumeName.of("pack-abc.cache")); Consumer phase1Consumer = log.runningPhase(request, "alphabet"); phase1Consumer.accept(mockLogEvent("one")); diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/docs/asciidoc/packaging-oci-image.adoc b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/docs/asciidoc/packaging-oci-image.adoc index 7a5dfb60167..f55d3aab3c9 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/docs/asciidoc/packaging-oci-image.adoc +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/docs/asciidoc/packaging-oci-image.adoc @@ -61,6 +61,12 @@ The following table summarizes the available properties and their default values | {spring-boot-api}/buildpack/platform/docker/type/ImageReference.html#of-java.lang.String-[Image name] for the generated image. | `docker.io/library/${project.artifactId}:${project.version}` +| `pullPolicy` +| `--pullPolicy` +| {spring-boot-api}/buildpack/platform/build/PullPolicy.html[Policy] used to determine when to pull the builder and run images from the registry. +Acceptable values are `ALWAYS`, `NEVER`, and `IF_NOT_PRESENT`. +| `ALWAYS` + | `environment` | | Environment variables that should be passed to the builder. diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/bundling/BootBuildImageIntegrationTests.java b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/bundling/BootBuildImageIntegrationTests.java index b24beebaa44..8ea96714081 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/bundling/BootBuildImageIntegrationTests.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/bundling/BootBuildImageIntegrationTests.java @@ -126,6 +126,31 @@ class BootBuildImageIntegrationTests { } } + @TestTemplate + void buildsImageWithPullPolicy() throws IOException { + writeMainClass(); + writeLongNameResource(); + String projectName = this.gradleBuild.getProjectDir().getName(); + ImageReference imageReference = ImageReference.of(ImageName.of(projectName)); + + BuildResult result = this.gradleBuild.build("bootBuildImage", "--pullPolicy=ALWAYS"); + assertThat(result.task(":bootBuildImage").getOutcome()).isEqualTo(TaskOutcome.SUCCESS); + assertThat(result.getOutput()).contains("Pulled builder image").contains("Pulled run image"); + try (GenericContainer container = new GenericContainer<>(imageReference.toString())) { + container.waitingFor(Wait.forLogMessage("Launched\\n", 1)).start(); + } + + result = this.gradleBuild.build("bootBuildImage", "--pullPolicy=IF_NOT_PRESENT"); + assertThat(result.task(":bootBuildImage").getOutcome()).isEqualTo(TaskOutcome.SUCCESS); + assertThat(result.getOutput()).doesNotContain("Pulled builder image").doesNotContain("Pulled run image"); + try (GenericContainer container = new GenericContainer<>(imageReference.toString())) { + container.waitingFor(Wait.forLogMessage("Launched\\n", 1)).start(); + } + finally { + new DockerApi().image().remove(imageReference, false); + } + } + @TestTemplate void failsWithLaunchScript() { writeMainClass(); diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/bundling/BootBuildImageTests.java b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/bundling/BootBuildImageTests.java index 6ec40ca0b52..fad0ead78de 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/bundling/BootBuildImageTests.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/bundling/BootBuildImageTests.java @@ -36,6 +36,7 @@ import static org.assertj.core.api.Assertions.assertThat; * * @author Andy Wilkinson * @author Scott Frederick + * @author Andrey Shlykov */ class BootBuildImageTests { @@ -196,12 +197,12 @@ class BootBuildImageTests { } @Test - void whenUsingDefaultConfigurationThenRequestHasNoPullDisabled() { + void whenUsingDefaultConfigurationThenRequestHasAlwaysPullPolicy() { assertThat(this.buildImage.createRequest().getPullPolicy()).isEqualTo(PullPolicy.ALWAYS); } @Test - void whenNoPullIsEnabledThenRequestHasNoPullEnabled() { + void whenPullPolicyIsConfiguredThenRequestHasPullPolicy() { this.buildImage.setPullPolicy(PullPolicy.NEVER); assertThat(this.buildImage.createRequest().getPullPolicy()).isEqualTo(PullPolicy.NEVER); } diff --git a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/docs/asciidoc/packaging-oci-image.adoc b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/docs/asciidoc/packaging-oci-image.adoc index 744d6592efb..2d8d1e5354c 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/docs/asciidoc/packaging-oci-image.adoc +++ b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/docs/asciidoc/packaging-oci-image.adoc @@ -85,6 +85,12 @@ The following table summarizes the available parameters and their default values | `spring-boot.build-image.imageName` | `docker.io/library/${project.artifactId}:${project.version}` +| `pullPolicy` +| {spring-boot-api}/buildpack/platform/build/PullPolicy.html[Policy] used to determine when to pull the builder and run images from the registry. +Acceptable values are `ALWAYS`, `NEVER`, and `IF_NOT_PRESENT`. +| `spring-boot.build-image.pullPolicy` +| `ALWAYS` + | `env` | Environment variables that should be passed to the builder. | @@ -101,7 +107,7 @@ The following table summarizes the available parameters and their default values | `false` |=== -For more details, see <> and <>. +For more details, see <>. include::goals/build-image.adoc[leveloffset=+1]