Use platform API builder image tags

CNB builder images are now being tagged in a manner that indicates
the version of the platform API implemented. This allows Spring Boot
to default to a builder tag that guarantees API compatibility while
allowing for updates to bundled buildpacks.

Fixes gh-20171
pull/20799/head
Scott Frederick 5 years ago
parent 4dad56a491
commit bb9e37e119

@ -36,7 +36,9 @@ import org.springframework.util.Assert;
*/
public class BuildRequest {
private static final ImageReference DEFAULT_BUILDER = ImageReference.of("cloudfoundry/cnb:0.0.53-bionic");
static final String DEFAULT_BUILDER_IMAGE_NAME = "cloudfoundry/cnb:bionic-platform-api-0.2";
private static final ImageReference DEFAULT_BUILDER = ImageReference.of(DEFAULT_BUILDER_IMAGE_NAME);
private final ImageReference name;

@ -55,7 +55,7 @@ public class BuildRequestTests {
writeTestJarFile(jarFile);
BuildRequest request = BuildRequest.forJarFile(jarFile);
assertThat(request.getName().toString()).isEqualTo("docker.io/library/my-app:0.0.1");
assertThat(request.getBuilder().toString()).isEqualTo("docker.io/cloudfoundry/cnb:0.0.53-bionic");
assertThat(request.getBuilder().toString()).isEqualTo("docker.io/" + BuildRequest.DEFAULT_BUILDER_IMAGE_NAME);
assertThat(request.getApplicationContent(Owner.ROOT)).satisfies(this::hasExpectedJarContent);
assertThat(request.getEnv()).isEmpty();
}
@ -66,7 +66,7 @@ public class BuildRequestTests {
writeTestJarFile(jarFile);
BuildRequest request = BuildRequest.forJarFile(ImageReference.of("test-app"), jarFile);
assertThat(request.getName().toString()).isEqualTo("docker.io/library/test-app:latest");
assertThat(request.getBuilder().toString()).isEqualTo("docker.io/cloudfoundry/cnb:0.0.53-bionic");
assertThat(request.getBuilder().toString()).isEqualTo("docker.io/" + BuildRequest.DEFAULT_BUILDER_IMAGE_NAME);
assertThat(request.getApplicationContent(Owner.ROOT)).satisfies(this::hasExpectedJarContent);
assertThat(request.getEnv()).isEmpty();
}

@ -72,7 +72,7 @@ class BuilderTests {
DockerApi docker = mockDockerApi();
Image builderImage = loadImage("image.json");
Image runImage = loadImage("run-image.json");
given(docker.image().pull(eq(ImageReference.of("docker.io/cloudfoundry/cnb:0.0.53-bionic")), any()))
given(docker.image().pull(eq(ImageReference.of("docker.io/" + BuildRequest.DEFAULT_BUILDER_IMAGE_NAME)), any()))
.willAnswer(withPulledImage(builderImage));
given(docker.image().pull(eq(ImageReference.of("docker.io/cloudfoundry/run:full-cnb")), any()))
.willAnswer(withPulledImage(runImage));
@ -97,7 +97,7 @@ class BuilderTests {
DockerApi docker = mockDockerApi();
Image builderImage = loadImage("image.json");
Image runImage = loadImage("run-image-with-bad-stack.json");
given(docker.image().pull(eq(ImageReference.of("docker.io/cloudfoundry/cnb:0.0.53-bionic")), any()))
given(docker.image().pull(eq(ImageReference.of("docker.io/" + BuildRequest.DEFAULT_BUILDER_IMAGE_NAME)), any()))
.willAnswer(withPulledImage(builderImage));
given(docker.image().pull(eq(ImageReference.of("docker.io/cloudfoundry/run:full-cnb")), any()))
.willAnswer(withPulledImage(runImage));
@ -113,7 +113,7 @@ class BuilderTests {
DockerApi docker = mockDockerApiLifecycleError();
Image builderImage = loadImage("image.json");
Image runImage = loadImage("run-image.json");
given(docker.image().pull(eq(ImageReference.of("docker.io/cloudfoundry/cnb:0.0.53-bionic")), any()))
given(docker.image().pull(eq(ImageReference.of("docker.io/" + BuildRequest.DEFAULT_BUILDER_IMAGE_NAME)), any()))
.willAnswer(withPulledImage(builderImage));
given(docker.image().pull(eq(ImageReference.of("docker.io/cloudfoundry/run:full-cnb")), any()))
.willAnswer(withPulledImage(runImage));

@ -48,7 +48,7 @@ The following table summarizes the available properties and their default values
| `builder`
| `--builder`
| Name of the Builder image to use.
| `cloudfoundry/cnb:0.0.53-bionic`
| `cloudfoundry/cnb:bionic-platform-api-0.2`
| `imageName`
| `--imageName`

@ -61,7 +61,7 @@ class BootBuildImageIntegrationTests {
String projectName = this.gradleBuild.getProjectDir().getName();
assertThat(result.task(":bootBuildImage").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
assertThat(result.getOutput()).contains("docker.io/library/" + projectName);
assertThat(result.getOutput()).contains("cloudfoundry/cnb:0.0.53-bionic");
assertThat(result.getOutput()).contains("cloudfoundry/cnb:bionic-platform-api");
ImageReference imageReference = ImageReference.of(ImageName.of(projectName));
try (GenericContainer<?> container = new GenericContainer<>(imageReference.toString())) {
container.waitingFor(Wait.forLogMessage("Launched\\n", 1)).start();
@ -78,7 +78,7 @@ class BootBuildImageIntegrationTests {
BuildResult result = this.gradleBuild.build("bootBuildImage");
assertThat(result.task(":bootBuildImage").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
assertThat(result.getOutput()).contains("example.com/test-image-name");
assertThat(result.getOutput()).contains("cloudfoundry/cnb:0.0.53-bionic");
assertThat(result.getOutput()).contains("cloudfoundry/cnb:bionic-platform-api");
ImageReference imageReference = ImageReference.of(ImageName.of("example.com/test-image-name"));
try (GenericContainer<?> container = new GenericContainer<>(imageReference.toString())) {
container.waitingFor(Wait.forLogMessage("Launched\\n", 1)).start();
@ -96,7 +96,7 @@ class BootBuildImageIntegrationTests {
String projectName = this.gradleBuild.getProjectDir().getName();
assertThat(result.task(":bootBuildImage").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
assertThat(result.getOutput()).contains("docker.io/library/" + projectName);
assertThat(result.getOutput()).contains("cloudfoundry/cnb:0.0.43-bionic");
assertThat(result.getOutput()).contains("cloudfoundry/cnb:bionic-platform-api-0.1");
ImageReference imageReference = ImageReference.of(ImageName.of(projectName));
try (GenericContainer<?> container = new GenericContainer<>(imageReference.toString())) {
container.waitingFor(Wait.forLogMessage("Launched\\n", 1)).start();

@ -7,5 +7,5 @@ sourceCompatibility = '1.8'
targetCompatibility = '1.8'
bootBuildImage {
builder = "cloudfoundry/cnb:0.0.43-bionic"
builder = "cloudfoundry/cnb:bionic-platform-api-0.1"
}

@ -73,7 +73,7 @@ The following table summarizes the available parameters and their default values
| `builder`
| Name of the Builder image to use.
| `spring-boot.build-image.builder`
| `cloudfoundry/cnb:0.0.53-bionic`
| `cloudfoundry/cnb:bionic-platform-api-0.2`
| `name`
| {spring-boot-api}/buildpack/platform/docker/type/ImageReference.html#of-java.lang.String-[Image name] for the generated image.

@ -52,7 +52,7 @@ public class BuildImageTests extends AbstractArchiveIntegrationTests {
assertThat(jar).isFile();
File original = new File(project, "target/build-image-0.0.1.BUILD-SNAPSHOT.jar.original");
assertThat(original).doesNotExist();
assertThat(buildLog(project)).contains("Building image").contains("cloudfoundry/cnb:0.0.53-bionic")
assertThat(buildLog(project)).contains("Building image").contains("cloudfoundry/cnb:bionic-platform-api")
.contains("docker.io/library/build-image:0.0.1.BUILD-SNAPSHOT")
.contains("Successfully built image");
ImageReference imageReference = ImageReference.of(ImageName.of("build-image"), "0.0.1.BUILD-SNAPSHOT");
@ -93,11 +93,11 @@ public class BuildImageTests extends AbstractArchiveIntegrationTests {
void whenBuildImageIsInvokedWithCommandLineParameters(MavenBuild mavenBuild) {
mavenBuild.project("build-image").goals("package")
.systemProperty("spring-boot.build-image.imageName", "example.com/test/cmd-property-name:v1")
.systemProperty("spring-boot.build-image.builder", "cloudfoundry/cnb:0.0.43-bionic")
.systemProperty("spring-boot.build-image.builder", "cloudfoundry/cnb:bionic-platform-api-0.1")
.execute((project) -> {
assertThat(buildLog(project)).contains("Building image")
.contains("example.com/test/cmd-property-name:v1")
.contains("cloudfoundry/cnb:0.0.43-bionic").contains("Successfully built image");
.contains("cloudfoundry/cnb:bionic-platform-api-0.1").contains("Successfully built image");
ImageReference imageReference = ImageReference.of("example.com/test/cmd-property-name:v1");
try (GenericContainer<?> container = new GenericContainer<>(imageReference.toString())) {
container.waitingFor(Wait.forLogMessage("Launched\\n", 1)).start();
@ -111,7 +111,8 @@ public class BuildImageTests extends AbstractArchiveIntegrationTests {
@TestTemplate
void whenBuildImageIsInvokedWithV1BuilderImage(MavenBuild mavenBuild) {
mavenBuild.project("build-image-v1-builder").goals("package").execute((project) -> {
assertThat(buildLog(project)).contains("Building image").contains("cloudfoundry/cnb:0.0.43-bionic")
assertThat(buildLog(project)).contains("Building image")
.contains("cloudfoundry/cnb:bionic-platform-api-0.1")
.contains("docker.io/library/build-image-v1-builder:0.0.1.BUILD-SNAPSHOT")
.contains("Successfully built image");
ImageReference imageReference = ImageReference

@ -23,7 +23,7 @@
</goals>
<configuration>
<image>
<builder>cloudfoundry/cnb:0.0.43-bionic</builder>
<builder>cloudfoundry/cnb:bionic-platform-api-0.1</builder>
</image>
</configuration>
</execution>

@ -57,7 +57,7 @@ class ImageTests {
void getBuildRequestWhenNoCustomizationsUsesDefaults() {
BuildRequest request = new Image().getBuildRequest(createArtifact(), mockAplicationContent());
assertThat(request.getName().toString()).isEqualTo("docker.io/library/my-app:0.0.1-SNAPSHOT");
assertThat(request.getBuilder().toString()).isEqualTo("docker.io/cloudfoundry/cnb:0.0.53-bionic");
assertThat(request.getBuilder().toString()).contains("docker.io/cloudfoundry/cnb:bionic-platform-api");
assertThat(request.getEnv()).isEmpty();
assertThat(request.isCleanCache()).isFalse();
assertThat(request.isVerboseLogging()).isFalse();

Loading…
Cancel
Save