From 38984985d4be4770bf8b25c249e261a5d98240ba Mon Sep 17 00:00:00 2001 From: Scott Frederick Date: Mon, 19 Oct 2020 17:33:40 -0500 Subject: [PATCH] Add support for CNB platform API 0.4 This commit adds support for platform API 0.4 when invoking a CNB builder in the Maven and Gradle plugins. If the builder advertises that it supports platform API 0.4 then that version will be requested when invoking lifecycle phases. Otherwise the plugins will fall back to requesting platform API 0.3. Requesting platform API 0.4 when invoking builder lifecycle phases has the primary benefit of making it easier to pass command-line arguments to the default process in the generated image. Fixes gh-23692 --- .../buildpack/platform/build/ApiVersions.java | 2 +- .../buildpack/platform/build/Lifecycle.java | 7 + .../platform/build/BuilderMetadataTests.java | 2 +- .../platform/build/LifecycleTests.java | 16 +- .../builder-metadata-platform-api-0.3.json | 142 ++++++++++++++++++ .../builder-metadata-unsupported-apis.json | 4 +- .../platform/build/builder-metadata.json | 2 +- .../build/lifecycle-creator-clean-cache.json | 4 +- .../lifecycle-creator-platform-api-0.3.json | 12 ++ .../platform/build/lifecycle-creator.json | 4 +- 10 files changed, 183 insertions(+), 12 deletions(-) create mode 100644 spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/resources/org/springframework/boot/buildpack/platform/build/builder-metadata-platform-api-0.3.json create mode 100644 spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/resources/org/springframework/boot/buildpack/platform/build/lifecycle-creator-platform-api-0.3.json diff --git a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/build/ApiVersions.java b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/build/ApiVersions.java index 81cd623b9e7..9257bfed726 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/build/ApiVersions.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/build/ApiVersions.java @@ -32,7 +32,7 @@ final class ApiVersions { /** * The platform API versions supported by this release. */ - static final ApiVersions SUPPORTED_PLATFORMS = new ApiVersions(ApiVersion.of(0, 3)); + static final ApiVersions SUPPORTED_PLATFORMS = new ApiVersions(ApiVersion.of(0, 3), ApiVersion.of(0, 4)); private final ApiVersion[] apiVersions; diff --git a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/build/Lifecycle.java b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/build/Lifecycle.java index dac0298fcaf..0ab904b9fdc 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/build/Lifecycle.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/build/Lifecycle.java @@ -134,6 +134,9 @@ class Lifecycle implements Closeable { if (this.request.isCleanCache()) { phase.withArgs("-skip-restore"); } + if (requiresProcessTypeDefault()) { + phase.withArgs("-process-type=web"); + } phase.withArgs(this.request.getName()); phase.withBinds(this.layersVolume, Directory.LAYERS); phase.withBinds(this.applicationVolume, Directory.APPLICATION); @@ -147,6 +150,10 @@ class Lifecycle implements Closeable { return this.request.isVerboseLogging() && this.lifecycleVersion.isEqualOrGreaterThan(LOGGING_MINIMUM_VERSION); } + private boolean requiresProcessTypeDefault() { + return this.platformVersion.supports(ApiVersion.of(0, 4)); + } + private void run(Phase phase) throws IOException { Consumer logConsumer = this.log.runningPhase(this.request, phase.getName()); ContainerConfig containerConfig = ContainerConfig.of(this.builder.getName(), phase::apply); diff --git a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/build/BuilderMetadataTests.java b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/build/BuilderMetadataTests.java index 645e956047a..87385106f1b 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/build/BuilderMetadataTests.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/build/BuilderMetadataTests.java @@ -87,7 +87,7 @@ class BuilderMetadataTests extends AbstractJsonTests { assertThat(metadata.getStack().getRunImage().getMirrors()).isEmpty(); assertThat(metadata.getLifecycle().getVersion()).isEqualTo("0.7.2"); assertThat(metadata.getLifecycle().getApi().getBuildpack()).isEqualTo("0.2"); - assertThat(metadata.getLifecycle().getApi().getPlatform()).isEqualTo("0.3"); + assertThat(metadata.getLifecycle().getApi().getPlatform()).isEqualTo("0.4"); assertThat(metadata.getLifecycle().getApis().getBuildpack()).isNull(); assertThat(metadata.getLifecycle().getApis().getPlatform()).isNull(); } diff --git a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/build/LifecycleTests.java b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/build/LifecycleTests.java index b374de3d1aa..779217b02ab 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/build/LifecycleTests.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/build/LifecycleTests.java @@ -88,6 +88,16 @@ class LifecycleTests { assertThat(this.out.toString()).contains("Successfully built image 'docker.io/library/my-application:latest'"); } + @Test + void executeExecutesPhasesWithPlatformApi03() throws Exception { + given(this.docker.container().create(any())).willAnswer(answerWithGeneratedContainerId()); + given(this.docker.container().create(any(), any())).willAnswer(answerWithGeneratedContainerId()); + given(this.docker.container().wait(any())).willReturn(ContainerStatus.of(0, null)); + createLifecycle("builder-metadata-platform-api-0.3.json").execute(); + assertPhaseWasRun("creator", withExpectedConfig("lifecycle-creator-platform-api-0.3.json")); + assertThat(this.out.toString()).contains("Successfully built image 'docker.io/library/my-application:latest'"); + } + @Test void executeOnlyUploadsContentOnce() throws Exception { given(this.docker.container().create(any())).willAnswer(answerWithGeneratedContainerId()); @@ -136,7 +146,7 @@ class LifecycleTests { given(this.docker.container().wait(any())).willReturn(ContainerStatus.of(0, null)); assertThatIllegalStateException() .isThrownBy(() -> createLifecycle("builder-metadata-unsupported-api.json").execute()) - .withMessage("Detected platform API versions '0.2' are not included in supported versions '0.3'"); + .withMessage("Detected platform API versions '0.2' are not included in supported versions '0.3,0.4'"); } @Test @@ -145,8 +155,8 @@ class LifecycleTests { given(this.docker.container().create(any(), any())).willAnswer(answerWithGeneratedContainerId()); given(this.docker.container().wait(any())).willReturn(ContainerStatus.of(0, null)); assertThatIllegalStateException() - .isThrownBy(() -> createLifecycle("builder-metadata-unsupported-apis.json").execute()) - .withMessage("Detected platform API versions '0.4,0.5' are not included in supported versions '0.3'"); + .isThrownBy(() -> createLifecycle("builder-metadata-unsupported-apis.json").execute()).withMessage( + "Detected platform API versions '0.5,0.6' are not included in supported versions '0.3,0.4'"); } @Test diff --git a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/resources/org/springframework/boot/buildpack/platform/build/builder-metadata-platform-api-0.3.json b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/resources/org/springframework/boot/buildpack/platform/build/builder-metadata-platform-api-0.3.json new file mode 100644 index 00000000000..b6c755e911c --- /dev/null +++ b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/resources/org/springframework/boot/buildpack/platform/build/builder-metadata-platform-api-0.3.json @@ -0,0 +1,142 @@ +{ + "description": "Ubuntu bionic base image with buildpacks for Java, NodeJS and Golang", + "buildpacks": [ + { + "id": "org.cloudfoundry.googlestackdriver", + "version": "v1.1.11" + }, + { + "id": "org.cloudfoundry.springboot", + "version": "v1.2.13" + }, + { + "id": "org.cloudfoundry.debug", + "version": "v1.2.11" + }, + { + "id": "org.cloudfoundry.tomcat", + "version": "v1.3.18" + }, + { + "id": "org.cloudfoundry.go", + "version": "v0.0.4" + }, + { + "id": "org.cloudfoundry.openjdk", + "version": "v1.2.14" + }, + { + "id": "org.cloudfoundry.buildsystem", + "version": "v1.2.15" + }, + { + "id": "org.cloudfoundry.jvmapplication", + "version": "v1.1.12" + }, + { + "id": "org.cloudfoundry.springautoreconfiguration", + "version": "v1.1.11" + }, + { + "id": "org.cloudfoundry.archiveexpanding", + "version": "v1.0.102" + }, + { + "id": "org.cloudfoundry.jmx", + "version": "v1.1.12" + }, + { + "id": "org.cloudfoundry.nodejs", + "version": "v2.0.8" + }, + { + "id": "org.cloudfoundry.jdbc", + "version": "v1.1.14" + }, + { + "id": "org.cloudfoundry.procfile", + "version": "v1.1.12" + }, + { + "id": "org.cloudfoundry.dotnet-core", + "version": "v0.0.6" + }, + { + "id": "org.cloudfoundry.azureapplicationinsights", + "version": "v1.1.12" + }, + { + "id": "org.cloudfoundry.distzip", + "version": "v1.1.12" + }, + { + "id": "org.cloudfoundry.dep", + "version": "0.0.101" + }, + { + "id": "org.cloudfoundry.go-compiler", + "version": "0.0.105" + }, + { + "id": "org.cloudfoundry.go-mod", + "version": "0.0.89" + }, + { + "id": "org.cloudfoundry.node-engine", + "version": "0.0.163" + }, + { + "id": "org.cloudfoundry.npm", + "version": "0.1.3" + }, + { + "id": "org.cloudfoundry.yarn-install", + "version": "0.1.10" + }, + { + "id": "org.cloudfoundry.dotnet-core-aspnet", + "version": "0.0.118" + }, + { + "id": "org.cloudfoundry.dotnet-core-build", + "version": "0.0.68" + }, + { + "id": "org.cloudfoundry.dotnet-core-conf", + "version": "0.0.115" + }, + { + "id": "org.cloudfoundry.dotnet-core-runtime", + "version": "0.0.127" + }, + { + "id": "org.cloudfoundry.dotnet-core-sdk", + "version": "0.0.122" + }, + { + "id": "org.cloudfoundry.icu", + "version": "0.0.43" + }, + { + "id": "org.cloudfoundry.node-engine", + "version": "0.0.158" + } + ], + "stack": { + "runImage": { + "image": "cloudfoundry/run:base-cnb", + "mirrors": null + } + }, + "lifecycle": { + "version": "0.7.2", + "api": { + "buildpack": "0.2", + "platform": "0.3" + } + }, + "createdBy": { + "name": "Pack CLI", + "version": "v0.9.0 (git sha: d42c384a39f367588f2653f2a99702db910e5ad7)" + } +} \ No newline at end of file diff --git a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/resources/org/springframework/boot/buildpack/platform/build/builder-metadata-unsupported-apis.json b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/resources/org/springframework/boot/buildpack/platform/build/builder-metadata-unsupported-apis.json index d4978b23355..74f94029cee 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/resources/org/springframework/boot/buildpack/platform/build/builder-metadata-unsupported-apis.json +++ b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/resources/org/springframework/boot/buildpack/platform/build/builder-metadata-unsupported-apis.json @@ -30,8 +30,8 @@ "platform": { "deprecated": [], "supported": [ - "0.4", - "0.5" + "0.5", + "0.6" ] } } diff --git a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/resources/org/springframework/boot/buildpack/platform/build/builder-metadata.json b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/resources/org/springframework/boot/buildpack/platform/build/builder-metadata.json index b6c755e911c..1343dc29425 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/resources/org/springframework/boot/buildpack/platform/build/builder-metadata.json +++ b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/resources/org/springframework/boot/buildpack/platform/build/builder-metadata.json @@ -132,7 +132,7 @@ "version": "0.7.2", "api": { "buildpack": "0.2", - "platform": "0.3" + "platform": "0.4" } }, "createdBy": { diff --git a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/resources/org/springframework/boot/buildpack/platform/build/lifecycle-creator-clean-cache.json b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/resources/org/springframework/boot/buildpack/platform/build/lifecycle-creator-clean-cache.json index 62795c7409a..481f406c768 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/resources/org/springframework/boot/buildpack/platform/build/lifecycle-creator-clean-cache.json +++ b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/resources/org/springframework/boot/buildpack/platform/build/lifecycle-creator-clean-cache.json @@ -1,8 +1,8 @@ { "User" : "root", "Image" : "pack.local/ephemeral-builder", - "Cmd" : [ "/cnb/lifecycle/creator", "-app", "/workspace", "-platform", "/platform", "-run-image", "docker.io/cloudfoundry/run:latest", "-layers", "/layers", "-cache-dir", "/cache", "-launch-cache", "/launch-cache", "-daemon", "-skip-restore", "docker.io/library/my-application:latest" ], - "Env" : [ "CNB_PLATFORM_API=0.3" ], + "Cmd" : [ "/cnb/lifecycle/creator", "-app", "/workspace", "-platform", "/platform", "-run-image", "docker.io/cloudfoundry/run:latest", "-layers", "/layers", "-cache-dir", "/cache", "-launch-cache", "/launch-cache", "-daemon", "-skip-restore", "-process-type=web", "docker.io/library/my-application:latest" ], + "Env" : [ "CNB_PLATFORM_API=0.4" ], "Labels" : { "author" : "spring-boot" }, diff --git a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/resources/org/springframework/boot/buildpack/platform/build/lifecycle-creator-platform-api-0.3.json b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/resources/org/springframework/boot/buildpack/platform/build/lifecycle-creator-platform-api-0.3.json new file mode 100644 index 00000000000..d04ec56db36 --- /dev/null +++ b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/resources/org/springframework/boot/buildpack/platform/build/lifecycle-creator-platform-api-0.3.json @@ -0,0 +1,12 @@ +{ + "User" : "root", + "Image" : "pack.local/ephemeral-builder", + "Cmd" : [ "/cnb/lifecycle/creator", "-app", "/workspace", "-platform", "/platform", "-run-image", "docker.io/cloudfoundry/run:latest", "-layers", "/layers", "-cache-dir", "/cache", "-launch-cache", "/launch-cache", "-daemon", "docker.io/library/my-application:latest" ], + "Env" : [ "CNB_PLATFORM_API=0.3" ], + "Labels" : { + "author" : "spring-boot" + }, + "HostConfig" : { + "Binds" : [ "/var/run/docker.sock:/var/run/docker.sock", "pack-layers-aaaaaaaaaa:/layers", "pack-app-aaaaaaaaaa:/workspace", "pack-cache-b35197ac41ea.build:/cache", "pack-cache-b35197ac41ea.launch:/launch-cache" ] + } +} \ No newline at end of file diff --git a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/resources/org/springframework/boot/buildpack/platform/build/lifecycle-creator.json b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/resources/org/springframework/boot/buildpack/platform/build/lifecycle-creator.json index d04ec56db36..916fa52f8fa 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/resources/org/springframework/boot/buildpack/platform/build/lifecycle-creator.json +++ b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/resources/org/springframework/boot/buildpack/platform/build/lifecycle-creator.json @@ -1,8 +1,8 @@ { "User" : "root", "Image" : "pack.local/ephemeral-builder", - "Cmd" : [ "/cnb/lifecycle/creator", "-app", "/workspace", "-platform", "/platform", "-run-image", "docker.io/cloudfoundry/run:latest", "-layers", "/layers", "-cache-dir", "/cache", "-launch-cache", "/launch-cache", "-daemon", "docker.io/library/my-application:latest" ], - "Env" : [ "CNB_PLATFORM_API=0.3" ], + "Cmd" : [ "/cnb/lifecycle/creator", "-app", "/workspace", "-platform", "/platform", "-run-image", "docker.io/cloudfoundry/run:latest", "-layers", "/layers", "-cache-dir", "/cache", "-launch-cache", "/launch-cache", "-daemon", "-process-type=web", "docker.io/library/my-application:latest" ], + "Env" : [ "CNB_PLATFORM_API=0.4" ], "Labels" : { "author" : "spring-boot" },