Commit 6b15822c authored by Scott Frederick's avatar Scott Frederick

Polish "Add pullPolicy option for image building"

See gh-22736
parent c7449b57
...@@ -30,6 +30,7 @@ import org.springframework.boot.buildpack.platform.docker.type.VolumeName; ...@@ -30,6 +30,7 @@ import org.springframework.boot.buildpack.platform.docker.type.VolumeName;
* *
* @author Phillip Webb * @author Phillip Webb
* @author Scott Frederick * @author Scott Frederick
* @author Andrey Shlykov
* @since 2.3.0 * @since 2.3.0
*/ */
public abstract class AbstractBuildLog implements BuildLog { public abstract class AbstractBuildLog implements BuildLog {
...@@ -41,21 +42,25 @@ public abstract class AbstractBuildLog implements BuildLog { ...@@ -41,21 +42,25 @@ public abstract class AbstractBuildLog implements BuildLog {
} }
@Override @Override
@Deprecated
public Consumer<TotalProgressEvent> pullingBuilder(BuildRequest request, ImageReference imageReference) { public Consumer<TotalProgressEvent> pullingBuilder(BuildRequest request, ImageReference imageReference) {
return pullingImage(imageReference, ImageType.BUILDER); return pullingImage(imageReference, ImageType.BUILDER);
} }
@Override @Override
@Deprecated
public void pulledBuilder(BuildRequest request, Image image) { public void pulledBuilder(BuildRequest request, Image image) {
pulledImage(image, ImageType.BUILDER); pulledImage(image, ImageType.BUILDER);
} }
@Override @Override
@Deprecated
public Consumer<TotalProgressEvent> pullingRunImage(BuildRequest request, ImageReference imageReference) { public Consumer<TotalProgressEvent> pullingRunImage(BuildRequest request, ImageReference imageReference) {
return pullingImage(imageReference, ImageType.RUNNER); return pullingImage(imageReference, ImageType.RUNNER);
} }
@Override @Override
@Deprecated
public void pulledRunImage(BuildRequest request, Image image) { public void pulledRunImage(BuildRequest request, Image image) {
pulledImage(image, ImageType.RUNNER); pulledImage(image, ImageType.RUNNER);
} }
......
...@@ -30,6 +30,7 @@ import org.springframework.boot.buildpack.platform.docker.type.VolumeName; ...@@ -30,6 +30,7 @@ import org.springframework.boot.buildpack.platform.docker.type.VolumeName;
* *
* @author Phillip Webb * @author Phillip Webb
* @author Scott Frederick * @author Scott Frederick
* @author Andrey Shlykov
* @since 2.3.0 * @since 2.3.0
* @see #toSystemOut() * @see #toSystemOut()
*/ */
...@@ -46,14 +47,19 @@ public interface BuildLog { ...@@ -46,14 +47,19 @@ public interface BuildLog {
* @param request the build request * @param request the build request
* @param imageReference the builder image reference * @param imageReference the builder image reference
* @return a consumer for progress update events * @return a consumer for progress update events
* @deprecated since 2.4.0 in favor of
* {@link #pullingImage(ImageReference, ImageType)}
*/ */
@Deprecated
Consumer<TotalProgressEvent> pullingBuilder(BuildRequest request, ImageReference imageReference); Consumer<TotalProgressEvent> pullingBuilder(BuildRequest request, ImageReference imageReference);
/** /**
* Log that the builder image has been pulled. * Log that the builder image has been pulled.
* @param request the build request * @param request the build request
* @param image the builder image that was pulled * @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); void pulledBuilder(BuildRequest request, Image image);
/** /**
...@@ -61,18 +67,23 @@ public interface BuildLog { ...@@ -61,18 +67,23 @@ public interface BuildLog {
* @param request the build request * @param request the build request
* @param imageReference the run image reference * @param imageReference the run image reference
* @return a consumer for progress update events * @return a consumer for progress update events
* @deprecated since 2.4.0 in favor of
* {@link #pullingImage(ImageReference, ImageType)}
*/ */
@Deprecated
Consumer<TotalProgressEvent> pullingRunImage(BuildRequest request, ImageReference imageReference); Consumer<TotalProgressEvent> pullingRunImage(BuildRequest request, ImageReference imageReference);
/** /**
* Log that a run image has been pulled. * Log that a run image has been pulled.
* @param request the build request * @param request the build request
* @param image the run image that was pulled * @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); 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 imageReference the image reference
* @param imageType the image type * @param imageType the image type
* @return a consumer for progress update events * @return a consumer for progress update events
...@@ -80,7 +91,7 @@ public interface BuildLog { ...@@ -80,7 +91,7 @@ public interface BuildLog {
Consumer<TotalProgressEvent> pullingImage(ImageReference imageReference, ImageType imageType); Consumer<TotalProgressEvent> 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 image the builder image that was pulled
* @param imageType the image type that was pulled * @param imageType the image type that was pulled
*/ */
......
...@@ -96,25 +96,21 @@ public class Builder { ...@@ -96,25 +96,21 @@ public class Builder {
private Image getImage(BuildRequest request, ImageType imageType) throws IOException { private Image getImage(BuildRequest request, ImageType imageType) throws IOException {
ImageReference imageReference = (imageType == ImageType.BUILDER) ? request.getBuilder() : request.getRunImage(); ImageReference imageReference = (imageType == ImageType.BUILDER) ? request.getBuilder() : request.getRunImage();
Image image; if (request.getPullPolicy() == PullPolicy.ALWAYS) {
if (request.getPullPolicy() != PullPolicy.ALWAYS) { return pullImage(imageReference, imageType);
try { }
image = this.docker.image().inspect(imageReference);
try {
return this.docker.image().inspect(imageReference);
}
catch (DockerEngineException exception) {
if (request.getPullPolicy() == PullPolicy.IF_NOT_PRESENT && exception.getStatusCode() == 404) {
return pullImage(imageReference, imageType);
} }
catch (DockerEngineException exception) { else {
if (request.getPullPolicy() == PullPolicy.IF_NOT_PRESENT && exception.getStatusCode() == 404) { throw exception;
image = pullImage(imageReference, imageType);
}
else {
throw exception;
}
} }
} }
else {
image = pullImage(imageReference, imageType);
}
return image;
} }
private Image pullImage(ImageReference reference, ImageType imageType) throws IOException { private Image pullImage(ImageReference reference, ImageType imageType) throws IOException {
......
...@@ -20,9 +20,8 @@ package org.springframework.boot.buildpack.platform.build; ...@@ -20,9 +20,8 @@ package org.springframework.boot.buildpack.platform.build;
* Image types. * Image types.
* *
* @author Andrey Shlykov * @author Andrey Shlykov
* @since 2.4.0
*/ */
public enum ImageType { enum ImageType {
/** /**
* Builder image. * Builder image.
...@@ -40,7 +39,7 @@ public enum ImageType { ...@@ -40,7 +39,7 @@ public enum ImageType {
this.description = description; this.description = description;
} }
public String getDescription() { String getDescription() {
return this.description; return this.description;
} }
......
...@@ -25,17 +25,17 @@ package org.springframework.boot.buildpack.platform.build; ...@@ -25,17 +25,17 @@ package org.springframework.boot.buildpack.platform.build;
public enum PullPolicy { public enum PullPolicy {
/** /**
* Always pull the image. * Always pull the image from the registry.
*/ */
ALWAYS, ALWAYS,
/** /**
* Never pull the image. * Never pull the image from the registry.
*/ */
NEVER, 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 IF_NOT_PRESENT
......
...@@ -57,12 +57,13 @@ class PrintStreamBuildLogTests { ...@@ -57,12 +57,13 @@ class PrintStreamBuildLogTests {
given(runImage.getDigests()).willReturn(Collections.singletonList("00000002")); given(runImage.getDigests()).willReturn(Collections.singletonList("00000002"));
given(request.getName()).willReturn(name); given(request.getName()).willReturn(name);
log.start(request); log.start(request);
Consumer<TotalProgressEvent> pullBuildImageConsumer = log.pullingBuilder(request, builderImageReference); Consumer<TotalProgressEvent> pullBuildImageConsumer = log.pullingImage(builderImageReference,
ImageType.BUILDER);
pullBuildImageConsumer.accept(new TotalProgressEvent(100)); pullBuildImageConsumer.accept(new TotalProgressEvent(100));
log.pulledBuilder(request, builderImage); log.pulledImage(builderImage, ImageType.BUILDER);
Consumer<TotalProgressEvent> pullRunImageConsumer = log.pullingRunImage(request, runImageReference); Consumer<TotalProgressEvent> pullRunImageConsumer = log.pullingImage(runImageReference, ImageType.RUNNER);
pullRunImageConsumer.accept(new TotalProgressEvent(100)); 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")); log.executingLifecycle(request, LifecycleVersion.parse("0.5"), VolumeName.of("pack-abc.cache"));
Consumer<LogUpdateEvent> phase1Consumer = log.runningPhase(request, "alphabet"); Consumer<LogUpdateEvent> phase1Consumer = log.runningPhase(request, "alphabet");
phase1Consumer.accept(mockLogEvent("one")); phase1Consumer.accept(mockLogEvent("one"));
......
...@@ -61,6 +61,12 @@ The following table summarizes the available properties and their default values ...@@ -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. | {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}` | `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`
| |
| Environment variables that should be passed to the builder. | Environment variables that should be passed to the builder.
......
...@@ -126,6 +126,31 @@ class BootBuildImageIntegrationTests { ...@@ -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 @TestTemplate
void failsWithLaunchScript() { void failsWithLaunchScript() {
writeMainClass(); writeMainClass();
......
...@@ -36,6 +36,7 @@ import static org.assertj.core.api.Assertions.assertThat; ...@@ -36,6 +36,7 @@ import static org.assertj.core.api.Assertions.assertThat;
* *
* @author Andy Wilkinson * @author Andy Wilkinson
* @author Scott Frederick * @author Scott Frederick
* @author Andrey Shlykov
*/ */
class BootBuildImageTests { class BootBuildImageTests {
...@@ -196,12 +197,12 @@ class BootBuildImageTests { ...@@ -196,12 +197,12 @@ class BootBuildImageTests {
} }
@Test @Test
void whenUsingDefaultConfigurationThenRequestHasNoPullDisabled() { void whenUsingDefaultConfigurationThenRequestHasAlwaysPullPolicy() {
assertThat(this.buildImage.createRequest().getPullPolicy()).isEqualTo(PullPolicy.ALWAYS); assertThat(this.buildImage.createRequest().getPullPolicy()).isEqualTo(PullPolicy.ALWAYS);
} }
@Test @Test
void whenNoPullIsEnabledThenRequestHasNoPullEnabled() { void whenPullPolicyIsConfiguredThenRequestHasPullPolicy() {
this.buildImage.setPullPolicy(PullPolicy.NEVER); this.buildImage.setPullPolicy(PullPolicy.NEVER);
assertThat(this.buildImage.createRequest().getPullPolicy()).isEqualTo(PullPolicy.NEVER); assertThat(this.buildImage.createRequest().getPullPolicy()).isEqualTo(PullPolicy.NEVER);
} }
......
...@@ -85,6 +85,12 @@ The following table summarizes the available parameters and their default values ...@@ -85,6 +85,12 @@ The following table summarizes the available parameters and their default values
| `spring-boot.build-image.imageName` | `spring-boot.build-image.imageName`
| `docker.io/library/${project.artifactId}:${project.version}` | `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` | `env`
| Environment variables that should be passed to the builder. | Environment variables that should be passed to the builder.
| |
...@@ -101,7 +107,7 @@ The following table summarizes the available parameters and their default values ...@@ -101,7 +107,7 @@ The following table summarizes the available parameters and their default values
| `false` | `false`
|=== |===
For more details, see <<build-image-example-custom-image-builder,custom image builder>> and <<build-image-example-custom-image-name,custom image name>>. For more details, see <<build-image-examples,examples>>.
include::goals/build-image.adoc[leveloffset=+1] include::goals/build-image.adoc[leveloffset=+1]
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment