Add bindings option for image building

This commit adds configuration to the Maven and Gradle plugins to
allow a list of volume mount bindings to be provided to the image
building goal and task. This enables service bindings to be mounted
in the builder image that are recognized by buildpacks to support
custom certificates, build tool configuration, APM integration, and
other buildpack features.

Fixes gh-23518
This commit is contained in:
Scott Frederick
2021-02-22 13:10:54 -06:00
parent 8cb24a426d
commit 89555a8745
24 changed files with 546 additions and 66 deletions

View File

@@ -219,6 +219,17 @@ class BootBuildImageIntegrationTests {
}
}
@TestTemplate
void failsWithBindingContainingInvalidCertificate() throws IOException {
writeMainClass();
writeLongNameResource();
writeCertificateBindingFiles();
BuildResult result = this.gradleBuild.buildAndFail("bootBuildImage", "--pullPolicy=IF_NOT_PRESENT");
assertThat(result.task(":bootBuildImage").getOutcome()).isEqualTo(TaskOutcome.FAILED);
assertThat(result.getOutput()).contains("failed to decode certificate")
.contains("/platform/bindings/certificates/test.crt");
}
@TestTemplate
void failsWithLaunchScript() throws IOException {
writeMainClass();
@@ -380,4 +391,17 @@ class BootBuildImageIntegrationTests {
tar.closeArchiveEntry();
}
private void writeCertificateBindingFiles() throws IOException {
File bindingDir = new File(this.gradleBuild.getProjectDir(), "bindings/ca-certificates");
bindingDir.mkdirs();
File type = new File(bindingDir, "type");
try (PrintWriter writer = new PrintWriter(new FileWriter(type))) {
writer.print("ca-certificates");
}
File cert = new File(bindingDir, "test.crt");
try (PrintWriter writer = new PrintWriter(new FileWriter(cert))) {
writer.println("not a valid certificate");
}
}
}

View File

@@ -31,6 +31,7 @@ import org.junit.jupiter.api.io.TempDir;
import org.springframework.boot.buildpack.platform.build.BuildRequest;
import org.springframework.boot.buildpack.platform.build.BuildpackReference;
import org.springframework.boot.buildpack.platform.build.PullPolicy;
import org.springframework.boot.buildpack.platform.docker.type.Binding;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
@@ -250,4 +251,31 @@ class BootBuildImageTests {
BuildpackReference.of("example/buildpack1"), BuildpackReference.of("example/buildpack2"));
}
@Test
void whenNoBindingsAreConfiguredThenRequestHasNoBindings() {
assertThat(this.buildImage.createRequest().getBindings()).isEmpty();
}
@Test
void whenBindingsAreConfiguredThenRequestHasBindings() {
this.buildImage.setBindings(Arrays.asList("host-src:container-dest:ro", "volume-name:container-dest:rw"));
assertThat(this.buildImage.createRequest().getBindings())
.containsExactly(Binding.of("host-src:container-dest:ro"), Binding.of("volume-name:container-dest:rw"));
}
@Test
void whenEntriesAreAddedToBindingsThenRequestHasBindings() {
this.buildImage.bindings(Arrays.asList("host-src:container-dest:ro", "volume-name:container-dest:rw"));
assertThat(this.buildImage.createRequest().getBindings())
.containsExactly(Binding.of("host-src:container-dest:ro"), Binding.of("volume-name:container-dest:rw"));
}
@Test
void whenIndividualEntriesAreAddedToBindingsThenRequestHasBindings() {
this.buildImage.binding("host-src:container-dest:ro");
this.buildImage.binding("volume-name:container-dest:rw");
assertThat(this.buildImage.createRequest().getBindings())
.containsExactly(Binding.of("host-src:container-dest:ro"), Binding.of("volume-name:container-dest:rw"));
}
}