Polish "Add pullPolicy option for image building"

See gh-22736
This commit is contained in:
Scott Frederick 2020-08-11 18:17:36 -05:00
parent c7449b57ce
commit 6b15822cb1
10 changed files with 82 additions and 32 deletions

View File

@ -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<TotalProgressEvent> 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<TotalProgressEvent> pullingRunImage(BuildRequest request, ImageReference imageReference) {
return pullingImage(imageReference, ImageType.RUNNER);
}
@Override
@Deprecated
public void pulledRunImage(BuildRequest request, Image image) {
pulledImage(image, ImageType.RUNNER);
}

View File

@ -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<TotalProgressEvent> 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<TotalProgressEvent> 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<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 imageType the image type that was pulled
*/

View File

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

View File

@ -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;
}

View File

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

View File

@ -57,12 +57,13 @@ class PrintStreamBuildLogTests {
given(runImage.getDigests()).willReturn(Collections.singletonList("00000002"));
given(request.getName()).willReturn(name);
log.start(request);
Consumer<TotalProgressEvent> pullBuildImageConsumer = log.pullingBuilder(request, builderImageReference);
Consumer<TotalProgressEvent> pullBuildImageConsumer = log.pullingImage(builderImageReference,
ImageType.BUILDER);
pullBuildImageConsumer.accept(new TotalProgressEvent(100));
log.pulledBuilder(request, builderImage);
Consumer<TotalProgressEvent> pullRunImageConsumer = log.pullingRunImage(request, runImageReference);
log.pulledImage(builderImage, ImageType.BUILDER);
Consumer<TotalProgressEvent> 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<LogUpdateEvent> phase1Consumer = log.runningPhase(request, "alphabet");
phase1Consumer.accept(mockLogEvent("one"));

View File

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

View File

@ -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();

View File

@ -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);
}

View File

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