Commit a01c8452 authored by Scott Frederick's avatar Scott Frederick

Support CNB builder platform API 0.3

This commit adds support for Cloud Native Buildpacks builder platform
API 0.3, which is the latest platform API available currently. Support
for platform API 0.1 has been removed, adopting the policy of the pack
CLI to support the current platform API version and one version prior.

Fixes gh-20757
parent bb9e37e1
...@@ -29,8 +29,6 @@ import org.springframework.util.Assert; ...@@ -29,8 +29,6 @@ import org.springframework.util.Assert;
*/ */
final class ApiVersion { final class ApiVersion {
private static final ApiVersion PLATFORM_0_1 = new ApiVersion(0, 1);
private static final Pattern PATTERN = Pattern.compile("^v?(\\d+)\\.(\\d*)$"); private static final Pattern PATTERN = Pattern.compile("^v?(\\d+)\\.(\\d*)$");
private final int major; private final int major;
...@@ -88,25 +86,6 @@ final class ApiVersion { ...@@ -88,25 +86,6 @@ final class ApiVersion {
return this.minor >= other.minor; return this.minor >= other.minor;
} }
/**
* Returns a value indicating whether the API version has a separate cache phase, or
* caching is distributed across other stages.
* @return {@code true} if the API has a separate cache phase, {@code false} otherwise
*/
boolean hasCachePhase() {
return supports(PLATFORM_0_1);
}
/**
* Returns a value indicating whether the API version requires that the analyze phase
* must follow the restore phase, or if the reverse order is required.
* @return {@code true} if the analyze phase follows restore, {@code false} if restore
* follows analyze
*/
boolean analyzeFollowsRestore() {
return supports(PLATFORM_0_1);
}
@Override @Override
public boolean equals(Object obj) { public boolean equals(Object obj) {
if (this == obj) { if (this == obj) {
......
...@@ -32,7 +32,7 @@ final class ApiVersions { ...@@ -32,7 +32,7 @@ final class ApiVersions {
/** /**
* The platform API versions supported by this release. * The platform API versions supported by this release.
*/ */
static final ApiVersions SUPPORTED_PLATFORMS = new ApiVersions(ApiVersion.of(0, 1), ApiVersion.of(0, 2)); static final ApiVersions SUPPORTED_PLATFORMS = new ApiVersions(ApiVersion.of(0, 2), ApiVersion.of(0, 3));
private final ApiVersion[] apiVersions; private final ApiVersion[] apiVersions;
......
...@@ -115,19 +115,10 @@ class Lifecycle implements Closeable { ...@@ -115,19 +115,10 @@ class Lifecycle implements Closeable {
deleteVolume(this.buildCacheVolume); deleteVolume(this.buildCacheVolume);
} }
run(detectPhase()); run(detectPhase());
if (this.platformVersion.analyzeFollowsRestore()) { run(analyzePhase());
run(restorePhase()); run(restorePhase());
run(analyzePhase());
}
else {
run(analyzePhase());
run(restorePhase());
}
run(buildPhase()); run(buildPhase());
run(exportPhase()); run(exportPhase());
if (this.platformVersion.hasCachePhase()) {
run(cachePhase());
}
this.log.executedLifecycle(this.request); this.log.executedLifecycle(this.request);
} }
...@@ -140,10 +131,9 @@ class Lifecycle implements Closeable { ...@@ -140,10 +131,9 @@ class Lifecycle implements Closeable {
} }
private Phase restorePhase() { private Phase restorePhase() {
String cacheDirArg = this.platformVersion.hasCachePhase() ? "-path" : "-cache-dir";
Phase phase = createPhase("restorer"); Phase phase = createPhase("restorer");
phase.withDaemonAccess(); phase.withDaemonAccess();
phase.withArgs(cacheDirArg, Folder.CACHE); phase.withArgs("-cache-dir", Folder.CACHE);
phase.withArgs("-layers", Folder.LAYERS); phase.withArgs("-layers", Folder.LAYERS);
phase.withLogLevelArg(); phase.withLogLevelArg();
phase.withBinds(this.buildCacheVolume, Folder.CACHE); phase.withBinds(this.buildCacheVolume, Folder.CACHE);
...@@ -159,13 +149,9 @@ class Lifecycle implements Closeable { ...@@ -159,13 +149,9 @@ class Lifecycle implements Closeable {
} }
phase.withArgs("-daemon"); phase.withArgs("-daemon");
phase.withArgs("-layers", Folder.LAYERS); phase.withArgs("-layers", Folder.LAYERS);
if (!this.platformVersion.hasCachePhase()) { phase.withArgs("-cache-dir", Folder.CACHE);
phase.withArgs("-cache-dir", Folder.CACHE);
}
phase.withArgs(this.request.getName()); phase.withArgs(this.request.getName());
if (!this.platformVersion.hasCachePhase()) { phase.withBinds(this.buildCacheVolume, Folder.CACHE);
phase.withBinds(this.buildCacheVolume, Folder.CACHE);
}
return phase; return phase;
} }
...@@ -186,23 +172,9 @@ class Lifecycle implements Closeable { ...@@ -186,23 +172,9 @@ class Lifecycle implements Closeable {
phase.withArgs("-app", Folder.APPLICATION); phase.withArgs("-app", Folder.APPLICATION);
phase.withArgs("-daemon"); phase.withArgs("-daemon");
phase.withArgs("-launch-cache", Folder.LAUNCH_CACHE); phase.withArgs("-launch-cache", Folder.LAUNCH_CACHE);
if (!this.platformVersion.hasCachePhase()) { phase.withArgs("-cache-dir", Folder.CACHE);
phase.withArgs("-cache-dir", Folder.CACHE);
}
phase.withArgs(this.request.getName()); phase.withArgs(this.request.getName());
phase.withBinds(this.launchCacheVolume, Folder.LAUNCH_CACHE); phase.withBinds(this.launchCacheVolume, Folder.LAUNCH_CACHE);
if (!this.platformVersion.hasCachePhase()) {
phase.withBinds(this.buildCacheVolume, Folder.CACHE);
}
return phase;
}
private Phase cachePhase() {
Phase phase = createPhase("cacher");
phase.withDaemonAccess();
phase.withArgs("-path", Folder.CACHE);
phase.withArgs("-layers", Folder.LAYERS);
phase.withLogLevelArg();
phase.withBinds(this.buildCacheVolume, Folder.CACHE); phase.withBinds(this.buildCacheVolume, Folder.CACHE);
return phase; return phase;
} }
......
...@@ -33,6 +33,7 @@ import static org.mockito.Mockito.mock; ...@@ -33,6 +33,7 @@ import static org.mockito.Mockito.mock;
* Tests for {@link BuilderMetadata}. * Tests for {@link BuilderMetadata}.
* *
* @author Phillip Webb * @author Phillip Webb
* @author Scott Frederick
*/ */
class BuilderMetadataTests extends AbstractJsonTests { class BuilderMetadataTests extends AbstractJsonTests {
...@@ -40,14 +41,14 @@ class BuilderMetadataTests extends AbstractJsonTests { ...@@ -40,14 +41,14 @@ class BuilderMetadataTests extends AbstractJsonTests {
void fromImageLoadsMetadata() throws IOException { void fromImageLoadsMetadata() throws IOException {
Image image = Image.of(getContent("image.json")); Image image = Image.of(getContent("image.json"));
BuilderMetadata metadata = BuilderMetadata.fromImage(image); BuilderMetadata metadata = BuilderMetadata.fromImage(image);
assertThat(metadata.getStack().getRunImage().getImage()).isEqualTo("cloudfoundry/run:full-cnb"); assertThat(metadata.getStack().getRunImage().getImage()).isEqualTo("cloudfoundry/run:base-cnb");
assertThat(metadata.getStack().getRunImage().getMirrors()).isEmpty(); assertThat(metadata.getStack().getRunImage().getMirrors()).isEmpty();
assertThat(metadata.getLifecycle().getVersion()).isEqualTo("0.5.0"); assertThat(metadata.getLifecycle().getVersion()).isEqualTo("0.7.2");
assertThat(metadata.getLifecycle().getApi().getBuildpack()).isEqualTo("0.2"); assertThat(metadata.getLifecycle().getApi().getBuildpack()).isEqualTo("0.2");
assertThat(metadata.getLifecycle().getApi().getPlatform()).isEqualTo("0.1"); assertThat(metadata.getLifecycle().getApi().getPlatform()).isEqualTo("0.3");
assertThat(metadata.getCreatedBy().getName()).isEqualTo("Pack CLI"); assertThat(metadata.getCreatedBy().getName()).isEqualTo("Pack CLI");
assertThat(metadata.getCreatedBy().getVersion()) assertThat(metadata.getCreatedBy().getVersion())
.isEqualTo("v0.5.0 (git sha: c9cfac75b49609524e1ea33f809c12071406547c)"); .isEqualTo("v0.9.0 (git sha: d42c384a39f367588f2653f2a99702db910e5ad7)");
} }
@Test @Test
......
...@@ -74,7 +74,7 @@ class BuilderTests { ...@@ -74,7 +74,7 @@ class BuilderTests {
Image runImage = loadImage("run-image.json"); Image runImage = loadImage("run-image.json");
given(docker.image().pull(eq(ImageReference.of("docker.io/" + BuildRequest.DEFAULT_BUILDER_IMAGE_NAME)), any())) given(docker.image().pull(eq(ImageReference.of("docker.io/" + BuildRequest.DEFAULT_BUILDER_IMAGE_NAME)), any()))
.willAnswer(withPulledImage(builderImage)); .willAnswer(withPulledImage(builderImage));
given(docker.image().pull(eq(ImageReference.of("docker.io/cloudfoundry/run:full-cnb")), any())) given(docker.image().pull(eq(ImageReference.of("docker.io/cloudfoundry/run:base-cnb")), any()))
.willAnswer(withPulledImage(runImage)); .willAnswer(withPulledImage(runImage));
Builder builder = new Builder(BuildLog.to(out), docker); Builder builder = new Builder(BuildLog.to(out), docker);
BuildRequest request = getTestRequest(); BuildRequest request = getTestRequest();
...@@ -84,7 +84,6 @@ class BuilderTests { ...@@ -84,7 +84,6 @@ class BuilderTests {
assertThat(out.toString()).contains("Running analyzer"); assertThat(out.toString()).contains("Running analyzer");
assertThat(out.toString()).contains("Running builder"); assertThat(out.toString()).contains("Running builder");
assertThat(out.toString()).contains("Running exporter"); assertThat(out.toString()).contains("Running exporter");
assertThat(out.toString()).contains("Running cacher");
assertThat(out.toString()).contains("Successfully built image 'docker.io/library/my-application:latest'"); assertThat(out.toString()).contains("Successfully built image 'docker.io/library/my-application:latest'");
ArgumentCaptor<ImageArchive> archive = ArgumentCaptor.forClass(ImageArchive.class); ArgumentCaptor<ImageArchive> archive = ArgumentCaptor.forClass(ImageArchive.class);
verify(docker.image()).load(archive.capture(), any()); verify(docker.image()).load(archive.capture(), any());
...@@ -99,12 +98,12 @@ class BuilderTests { ...@@ -99,12 +98,12 @@ class BuilderTests {
Image runImage = loadImage("run-image-with-bad-stack.json"); Image runImage = loadImage("run-image-with-bad-stack.json");
given(docker.image().pull(eq(ImageReference.of("docker.io/" + BuildRequest.DEFAULT_BUILDER_IMAGE_NAME)), any())) given(docker.image().pull(eq(ImageReference.of("docker.io/" + BuildRequest.DEFAULT_BUILDER_IMAGE_NAME)), any()))
.willAnswer(withPulledImage(builderImage)); .willAnswer(withPulledImage(builderImage));
given(docker.image().pull(eq(ImageReference.of("docker.io/cloudfoundry/run:full-cnb")), any())) given(docker.image().pull(eq(ImageReference.of("docker.io/cloudfoundry/run:base-cnb")), any()))
.willAnswer(withPulledImage(runImage)); .willAnswer(withPulledImage(runImage));
Builder builder = new Builder(BuildLog.to(out), docker); Builder builder = new Builder(BuildLog.to(out), docker);
BuildRequest request = getTestRequest(); BuildRequest request = getTestRequest();
assertThatIllegalStateException().isThrownBy(() -> builder.build(request)).withMessage( assertThatIllegalStateException().isThrownBy(() -> builder.build(request)).withMessage(
"Run image stack 'org.cloudfoundry.stacks.cfwindowsfs3' does not match builder stack 'org.cloudfoundry.stacks.cflinuxfs3'"); "Run image stack 'org.cloudfoundry.stacks.cfwindowsfs3' does not match builder stack 'io.buildpacks.stacks.bionic'");
} }
@Test @Test
...@@ -115,7 +114,7 @@ class BuilderTests { ...@@ -115,7 +114,7 @@ class BuilderTests {
Image runImage = loadImage("run-image.json"); Image runImage = loadImage("run-image.json");
given(docker.image().pull(eq(ImageReference.of("docker.io/" + BuildRequest.DEFAULT_BUILDER_IMAGE_NAME)), any())) given(docker.image().pull(eq(ImageReference.of("docker.io/" + BuildRequest.DEFAULT_BUILDER_IMAGE_NAME)), any()))
.willAnswer(withPulledImage(builderImage)); .willAnswer(withPulledImage(builderImage));
given(docker.image().pull(eq(ImageReference.of("docker.io/cloudfoundry/run:full-cnb")), any())) given(docker.image().pull(eq(ImageReference.of("docker.io/cloudfoundry/run:base-cnb")), any()))
.willAnswer(withPulledImage(runImage)); .willAnswer(withPulledImage(runImage));
Builder builder = new Builder(BuildLog.to(out), docker); Builder builder = new Builder(BuildLog.to(out), docker);
BuildRequest request = getTestRequest(); BuildRequest request = getTestRequest();
......
...@@ -79,32 +79,16 @@ class LifecycleTests { ...@@ -79,32 +79,16 @@ class LifecycleTests {
} }
@Test @Test
void executeExecutesPhasesWithCacherPhase() throws Exception { void executeExecutesPhases() throws Exception {
given(this.docker.container().create(any())).willAnswer(answerWithGeneratedContainerId()); given(this.docker.container().create(any())).willAnswer(answerWithGeneratedContainerId());
given(this.docker.container().create(any(), any())).willAnswer(answerWithGeneratedContainerId()); given(this.docker.container().create(any(), any())).willAnswer(answerWithGeneratedContainerId());
given(this.docker.container().wait(any())).willReturn(ContainerStatus.of(0, null)); given(this.docker.container().wait(any())).willReturn(ContainerStatus.of(0, null));
createLifecycle("0.5").execute(); createLifecycle().execute();
assertPhaseWasRun("detector", withExpectedConfig("lifecycle-detector.json"));
assertPhaseWasRun("restorer", withExpectedConfig("lifecycle-restorer-0.1.json"));
assertPhaseWasRun("analyzer", withExpectedConfig("lifecycle-analyzer-0.1.json"));
assertPhaseWasRun("builder", withExpectedConfig("lifecycle-builder.json"));
assertPhaseWasRun("exporter", withExpectedConfig("lifecycle-exporter-0.1.json"));
assertPhaseWasRun("cacher", withExpectedConfig("lifecycle-cacher.json"));
assertThat(this.out.toString()).contains("Successfully built image 'docker.io/library/my-application:latest'");
}
@Test
void executeExecutesPhasesWithEmbeddedCaching() 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("0.6").execute();
assertPhaseWasRun("detector", withExpectedConfig("lifecycle-detector.json")); assertPhaseWasRun("detector", withExpectedConfig("lifecycle-detector.json"));
assertPhaseWasRun("analyzer", withExpectedConfig("lifecycle-analyzer-0.2.json")); assertPhaseWasRun("analyzer", withExpectedConfig("lifecycle-analyzer.json"));
assertPhaseWasRun("restorer", withExpectedConfig("lifecycle-restorer-0.2.json")); assertPhaseWasRun("restorer", withExpectedConfig("lifecycle-restorer.json"));
assertPhaseWasRun("builder", withExpectedConfig("lifecycle-builder.json")); assertPhaseWasRun("builder", withExpectedConfig("lifecycle-builder.json"));
assertPhaseWasRun("exporter", withExpectedConfig("lifecycle-exporter-0.2.json")); assertPhaseWasRun("exporter", withExpectedConfig("lifecycle-exporter.json"));
assertPhaseWasNotRun("cacher");
assertThat(this.out.toString()).contains("Successfully built image 'docker.io/library/my-application:latest'"); assertThat(this.out.toString()).contains("Successfully built image 'docker.io/library/my-application:latest'");
} }
...@@ -173,27 +157,18 @@ class LifecycleTests { ...@@ -173,27 +157,18 @@ class LifecycleTests {
} }
private Lifecycle createLifecycle() throws IOException { private Lifecycle createLifecycle() throws IOException {
return createLifecycle("0.6"); return createLifecycle(getTestRequest());
}
private Lifecycle createLifecycle(String version) throws IOException {
return createLifecycle(getTestRequest(), version);
} }
private Lifecycle createLifecycle(BuildRequest request) throws IOException { private Lifecycle createLifecycle(BuildRequest request) throws IOException {
return createLifecycle(request, "0.6"); EphemeralBuilder builder = mockEphemeralBuilder();
}
private Lifecycle createLifecycle(BuildRequest request, String version) throws IOException {
EphemeralBuilder builder = mockEphemeralBuilder((version != null) ? version : "0.5");
return new TestLifecycle(BuildLog.to(this.out), this.docker, request, ImageReference.of("cloudfoundry/run"), return new TestLifecycle(BuildLog.to(this.out), this.docker, request, ImageReference.of("cloudfoundry/run"),
builder); builder);
} }
private EphemeralBuilder mockEphemeralBuilder(String version) throws IOException { private EphemeralBuilder mockEphemeralBuilder() throws IOException {
EphemeralBuilder builder = mock(EphemeralBuilder.class); EphemeralBuilder builder = mock(EphemeralBuilder.class);
byte[] metadataContent = FileCopyUtils byte[] metadataContent = FileCopyUtils.copyToByteArray(getClass().getResourceAsStream("builder-metadata.json"));
.copyToByteArray(getClass().getResourceAsStream("builder-metadata-version-" + version + ".json"));
BuilderMetadata metadata = BuilderMetadata.fromJson(new String(metadataContent, StandardCharsets.UTF_8)); BuilderMetadata metadata = BuilderMetadata.fromJson(new String(metadataContent, StandardCharsets.UTF_8));
given(builder.getName()).willReturn(ImageReference.of("pack.local/ephemeral-builder")); given(builder.getName()).willReturn(ImageReference.of("pack.local/ephemeral-builder"));
given(builder.getBuilderMetadata()).willReturn(metadata); given(builder.getBuilderMetadata()).willReturn(metadata);
...@@ -226,11 +201,6 @@ class LifecycleTests { ...@@ -226,11 +201,6 @@ class LifecycleTests {
configConsumer.accept(this.configs.get(containerReference.toString())); configConsumer.accept(this.configs.get(containerReference.toString()));
} }
private void assertPhaseWasNotRun(String name) {
ContainerReference containerReference = ContainerReference.of("lifecycle-" + name);
assertThat(this.configs.get(containerReference.toString())).isNull();
}
private IOConsumer<ContainerConfig> withExpectedConfig(String name) { private IOConsumer<ContainerConfig> withExpectedConfig(String name) {
return (config) -> { return (config) -> {
InputStream in = getClass().getResourceAsStream(name); InputStream in = getClass().getResourceAsStream(name);
......
{
"description": "Ubuntu bionic base image with buildpacks for Java, NodeJS and Golang",
"buildpacks": [
{
"id": "org.cloudfoundry.debug",
"version": "v1.0.106",
"latest": true
},
{
"id": "org.cloudfoundry.go",
"version": "v0.0.2",
"latest": true
},
{
"id": "org.cloudfoundry.springautoreconfiguration",
"version": "v1.0.113",
"latest": true
},
{
"id": "org.cloudfoundry.buildsystem",
"version": "v1.0.133",
"latest": true
},
{
"id": "org.cloudfoundry.procfile",
"version": "v1.0.41",
"latest": true
},
{
"id": "org.cloudfoundry.nodejs",
"version": "v0.0.5",
"latest": true
},
{
"id": "org.cloudfoundry.distzip",
"version": "v1.0.101",
"latest": true
},
{
"id": "org.cloudfoundry.jdbc",
"version": "v1.0.107",
"latest": true
},
{
"id": "org.cloudfoundry.azureapplicationinsights",
"version": "v1.0.105",
"latest": true
},
{
"id": "org.cloudfoundry.springboot",
"version": "v1.0.112",
"latest": true
},
{
"id": "org.cloudfoundry.openjdk",
"version": "v1.0.58",
"latest": true
},
{
"id": "org.cloudfoundry.tomcat",
"version": "v1.1.24",
"latest": true
},
{
"id": "org.cloudfoundry.googlestackdriver",
"version": "v1.0.54",
"latest": true
},
{
"id": "org.cloudfoundry.jmx",
"version": "v1.0.107",
"latest": true
},
{
"id": "org.cloudfoundry.archiveexpanding",
"version": "v1.0.99",
"latest": true
},
{
"id": "org.cloudfoundry.jvmapplication",
"version": "v1.0.82",
"latest": true
},
{
"id": "org.cloudfoundry.dep",
"version": "0.0.64",
"latest": true
},
{
"id": "org.cloudfoundry.go-compiler",
"version": "0.0.55",
"latest": true
},
{
"id": "org.cloudfoundry.go-mod",
"version": "0.0.58",
"latest": true
},
{
"id": "org.cloudfoundry.node-engine",
"version": "0.0.102",
"latest": true
},
{
"id": "org.cloudfoundry.npm",
"version": "0.0.63",
"latest": true
},
{
"id": "org.cloudfoundry.yarn",
"version": "0.0.69",
"latest": true
}
],
"groups": [
{
"buildpacks": [
{
"id": "org.cloudfoundry.archiveexpanding",
"version": "v1.0.99",
"optional": true
},
{
"id": "org.cloudfoundry.openjdk",
"version": "v1.0.58"
},
{
"id": "org.cloudfoundry.buildsystem",
"version": "v1.0.133",
"optional": true
},
{
"id": "org.cloudfoundry.jvmapplication",
"version": "v1.0.82"
},
{
"id": "org.cloudfoundry.tomcat",
"version": "v1.1.24",
"optional": true
},
{
"id": "org.cloudfoundry.springboot",
"version": "v1.0.112",
"optional": true
},
{
"id": "org.cloudfoundry.distzip",
"version": "v1.0.101",
"optional": true
},
{
"id": "org.cloudfoundry.procfile",
"version": "v1.0.41",
"optional": true
},
{
"id": "org.cloudfoundry.azureapplicationinsights",
"version": "v1.0.105",
"optional": true
},
{
"id": "org.cloudfoundry.debug",
"version": "v1.0.106",
"optional": true
},
{
"id": "org.cloudfoundry.googlestackdriver",
"version": "v1.0.54",
"optional": true
},
{
"id": "org.cloudfoundry.jdbc",
"version": "v1.0.107",
"optional": true
},
{
"id": "org.cloudfoundry.jmx",
"version": "v1.0.107",
"optional": true
},
{
"id": "org.cloudfoundry.springautoreconfiguration",
"version": "v1.0.113",
"optional": true
}
]
},
{
"buildpacks": [
{
"id": "org.cloudfoundry.nodejs",
"version": "v0.0.5"
}
]
},
{
"buildpacks": [
{
"id": "org.cloudfoundry.go",
"version": "v0.0.2"
}
]
}
],
"stack": {
"runImage": {
"image": "cloudfoundry/run:base-cnb",
"mirrors": null
}
},
"lifecycle": {
"version": "0.6.0",
"api": {
"buildpack": "0.2",
"platform": "0.2"
}
},
"createdBy": {
"name": "Pack CLI",
"version": "dev-2019-11-19-22:34:59"
}
}
...@@ -2,204 +2,124 @@ ...@@ -2,204 +2,124 @@
"description": "Ubuntu bionic base image with buildpacks for Java, NodeJS and Golang", "description": "Ubuntu bionic base image with buildpacks for Java, NodeJS and Golang",
"buildpacks": [ "buildpacks": [
{ {
"id": "org.cloudfoundry.debug", "id": "org.cloudfoundry.googlestackdriver",
"version": "v1.0.106", "version": "v1.1.11"
"latest": true
}, },
{ {
"id": "org.cloudfoundry.go", "id": "org.cloudfoundry.springboot",
"version": "v0.0.2", "version": "v1.2.13"
"latest": true
}, },
{ {
"id": "org.cloudfoundry.springautoreconfiguration", "id": "org.cloudfoundry.debug",
"version": "v1.0.113", "version": "v1.2.11"
"latest": true
}, },
{ {
"id": "org.cloudfoundry.buildsystem", "id": "org.cloudfoundry.tomcat",
"version": "v1.0.133", "version": "v1.3.18"
"latest": true
}, },
{ {
"id": "org.cloudfoundry.procfile", "id": "org.cloudfoundry.go",
"version": "v1.0.41", "version": "v0.0.4"
"latest": true
}, },
{ {
"id": "org.cloudfoundry.nodejs", "id": "org.cloudfoundry.openjdk",
"version": "v0.0.5", "version": "v1.2.14"
"latest": true
}, },
{ {
"id": "org.cloudfoundry.distzip", "id": "org.cloudfoundry.buildsystem",
"version": "v1.0.101", "version": "v1.2.15"
"latest": true
}, },
{ {
"id": "org.cloudfoundry.jdbc", "id": "org.cloudfoundry.jvmapplication",
"version": "v1.0.107", "version": "v1.1.12"
"latest": true
}, },
{ {
"id": "org.cloudfoundry.azureapplicationinsights", "id": "org.cloudfoundry.springautoreconfiguration",
"version": "v1.0.105", "version": "v1.1.11"
"latest": true
}, },
{ {
"id": "org.cloudfoundry.springboot", "id": "org.cloudfoundry.archiveexpanding",
"version": "v1.0.112", "version": "v1.0.102"
"latest": true
}, },
{ {
"id": "org.cloudfoundry.openjdk", "id": "org.cloudfoundry.jmx",
"version": "v1.0.58", "version": "v1.1.12"
"latest": true
}, },
{ {
"id": "org.cloudfoundry.tomcat", "id": "org.cloudfoundry.nodejs",
"version": "v1.1.24", "version": "v2.0.8"
"latest": true
}, },
{ {
"id": "org.cloudfoundry.googlestackdriver", "id": "org.cloudfoundry.jdbc",
"version": "v1.0.54", "version": "v1.1.14"
"latest": true
}, },
{ {
"id": "org.cloudfoundry.jmx", "id": "org.cloudfoundry.procfile",
"version": "v1.0.107", "version": "v1.1.12"
"latest": true
}, },
{ {
"id": "org.cloudfoundry.archiveexpanding", "id": "org.cloudfoundry.dotnet-core",
"version": "v1.0.99", "version": "v0.0.6"
"latest": true
}, },
{ {
"id": "org.cloudfoundry.jvmapplication", "id": "org.cloudfoundry.azureapplicationinsights",
"version": "v1.0.82", "version": "v1.1.12"
"latest": true },
{
"id": "org.cloudfoundry.distzip",
"version": "v1.1.12"
}, },
{ {
"id": "org.cloudfoundry.dep", "id": "org.cloudfoundry.dep",
"version": "0.0.64", "version": "0.0.101"
"latest": true
}, },
{ {
"id": "org.cloudfoundry.go-compiler", "id": "org.cloudfoundry.go-compiler",
"version": "0.0.55", "version": "0.0.105"
"latest": true
}, },
{ {
"id": "org.cloudfoundry.go-mod", "id": "org.cloudfoundry.go-mod",
"version": "0.0.58", "version": "0.0.89"
"latest": true
}, },
{ {
"id": "org.cloudfoundry.node-engine", "id": "org.cloudfoundry.node-engine",
"version": "0.0.102", "version": "0.0.163"
"latest": true
}, },
{ {
"id": "org.cloudfoundry.npm", "id": "org.cloudfoundry.npm",
"version": "0.0.63", "version": "0.1.3"
"latest": true
}, },
{ {
"id": "org.cloudfoundry.yarn", "id": "org.cloudfoundry.yarn-install",
"version": "0.0.69", "version": "0.1.10"
"latest": true },
} {
], "id": "org.cloudfoundry.dotnet-core-aspnet",
"groups": [ "version": "0.0.118"
{ },
"buildpacks": [ {
{ "id": "org.cloudfoundry.dotnet-core-build",
"id": "org.cloudfoundry.archiveexpanding", "version": "0.0.68"
"version": "v1.0.99", },
"optional": true {
}, "id": "org.cloudfoundry.dotnet-core-conf",
{ "version": "0.0.115"
"id": "org.cloudfoundry.openjdk", },
"version": "v1.0.58" {
}, "id": "org.cloudfoundry.dotnet-core-runtime",
{ "version": "0.0.127"
"id": "org.cloudfoundry.buildsystem", },
"version": "v1.0.133", {
"optional": true "id": "org.cloudfoundry.dotnet-core-sdk",
}, "version": "0.0.122"
{ },
"id": "org.cloudfoundry.jvmapplication", {
"version": "v1.0.82" "id": "org.cloudfoundry.icu",
}, "version": "0.0.43"
{ },
"id": "org.cloudfoundry.tomcat", {
"version": "v1.1.24", "id": "org.cloudfoundry.node-engine",
"optional": true "version": "0.0.158"
},
{
"id": "org.cloudfoundry.springboot",
"version": "v1.0.112",
"optional": true
},
{
"id": "org.cloudfoundry.distzip",
"version": "v1.0.101",
"optional": true
},
{
"id": "org.cloudfoundry.procfile",
"version": "v1.0.41",
"optional": true
},
{
"id": "org.cloudfoundry.azureapplicationinsights",
"version": "v1.0.105",
"optional": true
},
{
"id": "org.cloudfoundry.debug",
"version": "v1.0.106",
"optional": true
},
{
"id": "org.cloudfoundry.googlestackdriver",
"version": "v1.0.54",
"optional": true
},
{
"id": "org.cloudfoundry.jdbc",
"version": "v1.0.107",
"optional": true
},
{
"id": "org.cloudfoundry.jmx",
"version": "v1.0.107",
"optional": true
},
{
"id": "org.cloudfoundry.springautoreconfiguration",
"version": "v1.0.113",
"optional": true
}
]
},
{
"buildpacks": [
{
"id": "org.cloudfoundry.nodejs",
"version": "v0.0.5"
}
]
},
{
"buildpacks": [
{
"id": "org.cloudfoundry.go",
"version": "v0.0.2"
}
]
} }
], ],
"stack": { "stack": {
...@@ -209,14 +129,14 @@ ...@@ -209,14 +129,14 @@
} }
}, },
"lifecycle": { "lifecycle": {
"version": "0.5.0", "version": "0.7.2",
"api": { "api": {
"buildpack": "0.2", "buildpack": "0.2",
"platform": "0.1" "platform": "0.3"
} }
}, },
"createdBy": { "createdBy": {
"name": "Pack CLI", "name": "Pack CLI",
"version": "dev-2019-11-19-22:34:59" "version": "v0.9.0 (git sha: d42c384a39f367588f2653f2a99702db910e5ad7)"
} }
} }
\ No newline at end of file
{
"User" : "root",
"Image" : "pack.local/ephemeral-builder",
"Cmd" : [ "/lifecycle/analyzer", "-daemon", "-layers", "/layers", "docker.io/library/my-application:latest" ],
"Labels" : {
"author" : "spring-boot"
},
"HostConfig" : {
"Binds" : [ "/var/run/docker.sock:/var/run/docker.sock", "pack-layers-aaaaaaaaaa:/layers", "pack-app-aaaaaaaaaa:/workspace" ]
}
}
\ No newline at end of file
{
"User" : "root",
"Image" : "pack.local/ephemeral-builder",
"Cmd" : [ "/lifecycle/exporter", "-image", "docker.io/cloudfoundry/run", "-layers", "/layers", "-app", "/workspace", "-daemon", "-launch-cache", "/launch-cache", "docker.io/library/my-application:latest" ],
"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.launch:/launch-cache" ]
}
}
\ No newline at end of file
{
"User" : "root",
"Image" : "pack.local/ephemeral-builder",
"Cmd" : [ "/lifecycle/restorer", "-path", "/cache", "-layers", "/layers" ],
"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" ]
}
}
\ No newline at end of file
...@@ -89,14 +89,14 @@ class BootBuildImageIntegrationTests { ...@@ -89,14 +89,14 @@ class BootBuildImageIntegrationTests {
} }
@TestTemplate @TestTemplate
void buildsImageWithV1Builder() throws IOException { void buildsImageWithV2Builder() throws IOException {
writeMainClass(); writeMainClass();
writeLongNameResource(); writeLongNameResource();
BuildResult result = this.gradleBuild.build("bootBuildImage"); BuildResult result = this.gradleBuild.build("bootBuildImage");
String projectName = this.gradleBuild.getProjectDir().getName(); String projectName = this.gradleBuild.getProjectDir().getName();
assertThat(result.task(":bootBuildImage").getOutcome()).isEqualTo(TaskOutcome.SUCCESS); assertThat(result.task(":bootBuildImage").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
assertThat(result.getOutput()).contains("docker.io/library/" + projectName); assertThat(result.getOutput()).contains("docker.io/library/" + projectName);
assertThat(result.getOutput()).contains("cloudfoundry/cnb:bionic-platform-api-0.1"); assertThat(result.getOutput()).contains("cloudfoundry/cnb:bionic-platform-api-0.2");
ImageReference imageReference = ImageReference.of(ImageName.of(projectName)); ImageReference imageReference = ImageReference.of(ImageName.of(projectName));
try (GenericContainer<?> container = new GenericContainer<>(imageReference.toString())) { try (GenericContainer<?> container = new GenericContainer<>(imageReference.toString())) {
container.waitingFor(Wait.forLogMessage("Launched\\n", 1)).start(); container.waitingFor(Wait.forLogMessage("Launched\\n", 1)).start();
...@@ -111,10 +111,10 @@ class BootBuildImageIntegrationTests { ...@@ -111,10 +111,10 @@ class BootBuildImageIntegrationTests {
writeMainClass(); writeMainClass();
writeLongNameResource(); writeLongNameResource();
BuildResult result = this.gradleBuild.build("bootBuildImage", "--imageName=example.com/test-image-name", BuildResult result = this.gradleBuild.build("bootBuildImage", "--imageName=example.com/test-image-name",
"--builder=cloudfoundry/cnb:0.0.43-bionic"); "--builder=cloudfoundry/cnb:bionic-platform-api-0.2");
assertThat(result.task(":bootBuildImage").getOutcome()).isEqualTo(TaskOutcome.SUCCESS); assertThat(result.task(":bootBuildImage").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
assertThat(result.getOutput()).contains("example.com/test-image-name"); assertThat(result.getOutput()).contains("example.com/test-image-name");
assertThat(result.getOutput()).contains("cloudfoundry/cnb:0.0.43-bionic"); assertThat(result.getOutput()).contains("cloudfoundry/cnb:bionic-platform-api-0.2");
ImageReference imageReference = ImageReference.of(ImageName.of("example.com/test-image-name")); ImageReference imageReference = ImageReference.of(ImageName.of("example.com/test-image-name"));
try (GenericContainer<?> container = new GenericContainer<>(imageReference.toString())) { try (GenericContainer<?> container = new GenericContainer<>(imageReference.toString())) {
container.waitingFor(Wait.forLogMessage("Launched\\n", 1)).start(); container.waitingFor(Wait.forLogMessage("Launched\\n", 1)).start();
......
...@@ -7,5 +7,5 @@ sourceCompatibility = '1.8' ...@@ -7,5 +7,5 @@ sourceCompatibility = '1.8'
targetCompatibility = '1.8' targetCompatibility = '1.8'
bootBuildImage { bootBuildImage {
builder = "cloudfoundry/cnb:bionic-platform-api-0.1" builder = "cloudfoundry/cnb:bionic-platform-api-0.2"
} }
...@@ -93,11 +93,11 @@ public class BuildImageTests extends AbstractArchiveIntegrationTests { ...@@ -93,11 +93,11 @@ public class BuildImageTests extends AbstractArchiveIntegrationTests {
void whenBuildImageIsInvokedWithCommandLineParameters(MavenBuild mavenBuild) { void whenBuildImageIsInvokedWithCommandLineParameters(MavenBuild mavenBuild) {
mavenBuild.project("build-image").goals("package") mavenBuild.project("build-image").goals("package")
.systemProperty("spring-boot.build-image.imageName", "example.com/test/cmd-property-name:v1") .systemProperty("spring-boot.build-image.imageName", "example.com/test/cmd-property-name:v1")
.systemProperty("spring-boot.build-image.builder", "cloudfoundry/cnb:bionic-platform-api-0.1") .systemProperty("spring-boot.build-image.builder", "cloudfoundry/cnb:bionic-platform-api-0.2")
.execute((project) -> { .execute((project) -> {
assertThat(buildLog(project)).contains("Building image") assertThat(buildLog(project)).contains("Building image")
.contains("example.com/test/cmd-property-name:v1") .contains("example.com/test/cmd-property-name:v1")
.contains("cloudfoundry/cnb:bionic-platform-api-0.1").contains("Successfully built image"); .contains("cloudfoundry/cnb:bionic-platform-api-0.2").contains("Successfully built image");
ImageReference imageReference = ImageReference.of("example.com/test/cmd-property-name:v1"); ImageReference imageReference = ImageReference.of("example.com/test/cmd-property-name:v1");
try (GenericContainer<?> container = new GenericContainer<>(imageReference.toString())) { try (GenericContainer<?> container = new GenericContainer<>(imageReference.toString())) {
container.waitingFor(Wait.forLogMessage("Launched\\n", 1)).start(); container.waitingFor(Wait.forLogMessage("Launched\\n", 1)).start();
...@@ -109,14 +109,14 @@ public class BuildImageTests extends AbstractArchiveIntegrationTests { ...@@ -109,14 +109,14 @@ public class BuildImageTests extends AbstractArchiveIntegrationTests {
} }
@TestTemplate @TestTemplate
void whenBuildImageIsInvokedWithV1BuilderImage(MavenBuild mavenBuild) { void whenBuildImageIsInvokedWithV2BuilderImage(MavenBuild mavenBuild) {
mavenBuild.project("build-image-v1-builder").goals("package").execute((project) -> { mavenBuild.project("build-image-v2-builder").goals("package").execute((project) -> {
assertThat(buildLog(project)).contains("Building image") assertThat(buildLog(project)).contains("Building image")
.contains("cloudfoundry/cnb:bionic-platform-api-0.1") .contains("cloudfoundry/cnb:bionic-platform-api-0.2")
.contains("docker.io/library/build-image-v1-builder:0.0.1.BUILD-SNAPSHOT") .contains("docker.io/library/build-image-v2-builder:0.0.1.BUILD-SNAPSHOT")
.contains("Successfully built image"); .contains("Successfully built image");
ImageReference imageReference = ImageReference ImageReference imageReference = ImageReference
.of("docker.io/library/build-image-v1-builder:0.0.1.BUILD-SNAPSHOT"); .of("docker.io/library/build-image-v2-builder:0.0.1.BUILD-SNAPSHOT");
try (GenericContainer<?> container = new GenericContainer<>(imageReference.toString())) { try (GenericContainer<?> container = new GenericContainer<>(imageReference.toString())) {
container.waitingFor(Wait.forLogMessage("Launched\\n", 1)).start(); container.waitingFor(Wait.forLogMessage("Launched\\n", 1)).start();
} }
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>org.springframework.boot.maven.it</groupId> <groupId>org.springframework.boot.maven.it</groupId>
<artifactId>build-image-v1-builder</artifactId> <artifactId>build-image-v2-builder</artifactId>
<version>0.0.1.BUILD-SNAPSHOT</version> <version>0.0.1.BUILD-SNAPSHOT</version>
<properties> <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
</goals> </goals>
<configuration> <configuration>
<image> <image>
<builder>cloudfoundry/cnb:bionic-platform-api-0.1</builder> <builder>cloudfoundry/cnb:bionic-platform-api-0.2</builder>
</image> </image>
</configuration> </configuration>
</execution> </execution>
......
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