Add support for untrusted CNB builders
A `trustBuilder` configuration option has been added to the Maven and Gradle CNB integration image building goal and task. A known set of builders published by Paketo, Heroku, and Google are trusted by default, all other builders are untrusted by default. Closes gh-41352
This commit is contained in:
@@ -78,6 +78,23 @@ 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("Running detector");
|
||||
assertThat(result.getOutput()).contains("Running builder");
|
||||
assertThat(result.getOutput()).contains("---> Test Info buildpack building");
|
||||
assertThat(result.getOutput()).contains("Network status: HTTP/2 200");
|
||||
assertThat(result.getOutput()).contains("---> Test Info buildpack done");
|
||||
removeImages(projectName);
|
||||
}
|
||||
|
||||
@TestTemplate
|
||||
void buildsImageWithTrustBuilder() throws IOException {
|
||||
writeMainClass();
|
||||
writeLongNameResource();
|
||||
BuildResult result = this.gradleBuild.build("bootBuildImage");
|
||||
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("Running creator");
|
||||
assertThat(result.getOutput()).contains("---> Test Info buildpack building");
|
||||
assertThat(result.getOutput()).contains("Network status: HTTP/2 200");
|
||||
assertThat(result.getOutput()).contains("---> Test Info buildpack done");
|
||||
@@ -146,10 +163,11 @@ class BootBuildImageIntegrationTests {
|
||||
writeLongNameResource();
|
||||
BuildResult result = this.gradleBuild.build("bootBuildImage", "--pullPolicy=IF_NOT_PRESENT",
|
||||
"--imageName=example/test-image-cmd", "--builder=ghcr.io/spring-io/spring-boot-cnb-test-builder:0.0.1",
|
||||
"--runImage=paketobuildpacks/run-jammy-tiny", "--createdDate=2020-07-01T12:34:56Z",
|
||||
"--trustBuilder", "--runImage=paketobuildpacks/run-jammy-tiny", "--createdDate=2020-07-01T12:34:56Z",
|
||||
"--applicationDirectory=/application");
|
||||
assertThat(result.task(":bootBuildImage").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
|
||||
assertThat(result.getOutput()).contains("example/test-image-cmd");
|
||||
assertThat(result.getOutput()).contains("Running creator");
|
||||
assertThat(result.getOutput()).contains("---> Test Info buildpack building");
|
||||
assertThat(result.getOutput()).contains("---> Test Info buildpack done");
|
||||
Image image = new DockerApi().image().inspect(ImageReference.of("example/test-image-cmd"));
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
plugins {
|
||||
id 'java'
|
||||
id 'org.springframework.boot' version '{version}'
|
||||
}
|
||||
|
||||
if (project.hasProperty('applyWarPlugin')) {
|
||||
apply plugin: 'war'
|
||||
}
|
||||
|
||||
bootBuildImage {
|
||||
builder = "ghcr.io/spring-io/spring-boot-cnb-test-builder:0.0.1"
|
||||
trustBuilder = true
|
||||
pullPolicy = "IF_NOT_PRESENT"
|
||||
}
|
||||
@@ -118,9 +118,14 @@ The following table summarizes the available properties and their default values
|
||||
|
||||
| `builder`
|
||||
| `--builder`
|
||||
| Name of the Builder image to use.
|
||||
| Name of the builder image to use.
|
||||
| `paketobuildpacks/builder-jammy-tiny:latest`
|
||||
|
||||
| `trustBuilder`
|
||||
| `--trustBuilder`
|
||||
| Whether to treat the builder as https://buildpacks.io/docs/for-platform-operators/how-to/integrate-ci/pack/concepts/trusted_builders/#what-is-a-trusted-builder[trusted].
|
||||
| `true` if the builder is one of `paketobuildpacks/builder-jammy-tiny`, `paketobuildpacks/builder-jammy-base`, `paketobuildpacks/builder-jammy-full`, `paketobuildpacks/builder-jammy-buildpackless-tiny`, `paketobuildpacks/builder-jammy-buildpackless-base`, `paketobuildpacks/builder-jammy-buildpackless-full`, `gcr.io/buildpacks/builder`, `heroku/builder`; false otherwise.
|
||||
|
||||
| `runImage`
|
||||
| `--runImage`
|
||||
| Name of the run image to use.
|
||||
|
||||
@@ -91,6 +91,7 @@ public abstract class BootBuildImage extends DefaultTask {
|
||||
}
|
||||
return ImageReference.of(imageName, projectVersion.get()).toString();
|
||||
}));
|
||||
getTrustBuilder().convention((Boolean) null);
|
||||
getCleanCache().convention(false);
|
||||
getVerboseLogging().convention(false);
|
||||
getPublish().convention(false);
|
||||
@@ -131,6 +132,16 @@ public abstract class BootBuildImage extends DefaultTask {
|
||||
@Option(option = "builder", description = "The name of the builder image to use")
|
||||
public abstract Property<String> getBuilder();
|
||||
|
||||
/**
|
||||
* Whether to treat the builder as trusted.
|
||||
* @return whether to trust the builder
|
||||
* @since 3.4.0
|
||||
*/
|
||||
@Input
|
||||
@Optional
|
||||
@Option(option = "trustBuilder", description = "Consider the builder trusted")
|
||||
public abstract Property<Boolean> getTrustBuilder();
|
||||
|
||||
/**
|
||||
* Returns the run image that will be included in the built image. When {@code null},
|
||||
* the run image bundled with the builder will be used.
|
||||
@@ -348,13 +359,16 @@ public abstract class BootBuildImage extends DefaultTask {
|
||||
|
||||
private BuildRequest customize(BuildRequest request) {
|
||||
request = customizeBuilder(request);
|
||||
if (getTrustBuilder().isPresent()) {
|
||||
request = request.withTrustBuilder(getTrustBuilder().get());
|
||||
}
|
||||
request = customizeRunImage(request);
|
||||
request = customizeEnvironment(request);
|
||||
request = customizeCreator(request);
|
||||
request = request.withCleanCache(getCleanCache().get());
|
||||
request = request.withVerboseLogging(getVerboseLogging().get());
|
||||
request = customizePullPolicy(request);
|
||||
request = customizePublish(request);
|
||||
request = request.withPublish(getPublish().get());
|
||||
request = customizeBuildpacks(request);
|
||||
request = customizeBindings(request);
|
||||
request = customizeTags(request);
|
||||
@@ -406,11 +420,6 @@ public abstract class BootBuildImage extends DefaultTask {
|
||||
return request;
|
||||
}
|
||||
|
||||
private BuildRequest customizePublish(BuildRequest request) {
|
||||
request = request.withPublish(getPublish().get());
|
||||
return request;
|
||||
}
|
||||
|
||||
private BuildRequest customizeBuildpacks(BuildRequest request) {
|
||||
List<String> buildpacks = getBuildpacks().getOrNull();
|
||||
if (!CollectionUtils.isEmpty(buildpacks)) {
|
||||
|
||||
@@ -172,14 +172,24 @@ class BootBuildImageTests {
|
||||
|
||||
@Test
|
||||
void whenNoBuilderIsConfiguredThenRequestHasDefaultBuilder() {
|
||||
assertThat(this.buildImage.createRequest().getBuilder().getName())
|
||||
.isEqualTo("paketobuildpacks/builder-jammy-tiny");
|
||||
BuildRequest request = this.buildImage.createRequest();
|
||||
assertThat(request.getBuilder().getName()).isEqualTo("paketobuildpacks/builder-jammy-tiny");
|
||||
assertThat(request.isTrustBuilder()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenBuilderIsConfiguredThenRequestUsesSpecifiedBuilder() {
|
||||
this.buildImage.getBuilder().set("example.com/test/builder:1.2");
|
||||
assertThat(this.buildImage.createRequest().getBuilder().getName()).isEqualTo("test/builder");
|
||||
BuildRequest request = this.buildImage.createRequest();
|
||||
assertThat(request.getBuilder().getName()).isEqualTo("test/builder");
|
||||
assertThat(request.isTrustBuilder()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenTrustBuilderIsEnabledThenRequestHasTrustBuilderEnabled() {
|
||||
this.buildImage.getBuilder().set("example.com/test/builder:1.2");
|
||||
this.buildImage.getTrustBuilder().set(true);
|
||||
assertThat(this.buildImage.createRequest().isTrustBuilder()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Reference in New Issue
Block a user