Add support for caching to bind mounts when building images

When building an image using the Maven `spring-boot:build-image` goal or
the Gradle `bootBuildImage` task, the build and launch caches can be
configured to use a bind mount as an alternative to using a named
volume.

Closes gh-28387
This commit is contained in:
Scott Frederick
2023-08-21 15:03:39 -05:00
parent d46a58f0f6
commit c17ecf0f0b
25 changed files with 575 additions and 47 deletions

View File

@@ -37,6 +37,7 @@ import org.springframework.boot.buildpack.platform.docker.type.ImageReference;
import org.springframework.boot.buildpack.platform.docker.type.VolumeName;
import org.springframework.boot.testsupport.junit.DisabledOnOs;
import org.springframework.boot.testsupport.testcontainers.DisabledIfDockerUnavailable;
import org.springframework.util.FileSystemUtils;
import static org.assertj.core.api.Assertions.assertThat;
@@ -385,19 +386,41 @@ class BuildImageTests extends AbstractArchiveIntegrationTests {
@TestTemplate
void whenBuildImageIsInvokedWithVolumeCaches(MavenBuild mavenBuild) {
String testBuildId = randomString();
mavenBuild.project("build-image-caches")
mavenBuild.project("build-image-volume-caches")
.goals("package")
.systemProperty("spring-boot.build-image.pullPolicy", "IF_NOT_PRESENT")
.systemProperty("test-build-id", testBuildId)
.execute((project) -> {
assertThat(buildLog(project)).contains("Building image")
.contains("docker.io/library/build-image-caches:0.0.1.BUILD-SNAPSHOT")
.contains("docker.io/library/build-image-volume-caches:0.0.1.BUILD-SNAPSHOT")
.contains("Successfully built image");
removeImage("build-image-caches", "0.0.1.BUILD-SNAPSHOT");
removeImage("build-image-volume-caches", "0.0.1.BUILD-SNAPSHOT");
deleteVolumes("cache-" + testBuildId + ".build", "cache-" + testBuildId + ".launch");
});
}
@TestTemplate
void whenBuildImageIsInvokedWithBindCaches(MavenBuild mavenBuild) {
String testBuildId = randomString();
mavenBuild.project("build-image-bind-caches")
.goals("package")
.systemProperty("spring-boot.build-image.pullPolicy", "IF_NOT_PRESENT")
.systemProperty("test-build-id", testBuildId)
.execute((project) -> {
assertThat(buildLog(project)).contains("Building image")
.contains("docker.io/library/build-image-bind-caches:0.0.1.BUILD-SNAPSHOT")
.contains("Successfully built image");
removeImage("build-image-bind-caches", "0.0.1.BUILD-SNAPSHOT");
String tempDir = System.getProperty("java.io.tmpdir");
Path buildCachePath = Paths.get(tempDir, "junit-image-cache-" + testBuildId + "-build");
Path launchCachePath = Paths.get(tempDir, "junit-image-cache-" + testBuildId + "-launch");
assertThat(buildCachePath).exists().isDirectory();
assertThat(launchCachePath).exists().isDirectory();
FileSystemUtils.deleteRecursively(buildCachePath);
FileSystemUtils.deleteRecursively(launchCachePath);
});
}
@TestTemplate
void whenBuildImageIsInvokedWithCreatedDate(MavenBuild mavenBuild) {
String testBuildId = randomString();

View File

@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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>
<groupId>org.springframework.boot.maven.it</groupId>
<artifactId>build-image-bind-caches</artifactId>
<version>0.0.1.BUILD-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>@java.version@</maven.compiler.source>
<maven.compiler.target>@java.version@</maven.compiler.target>
</properties>
<build>
<plugins>
<plugin>
<groupId>@project.groupId@</groupId>
<artifactId>@project.artifactId@</artifactId>
<version>@project.version@</version>
<executions>
<execution>
<goals>
<goal>build-image-no-fork</goal>
</goals>
<configuration>
<image>
<builder>projects.registry.vmware.com/springboot/spring-boot-cnb-builder:0.0.2</builder>
<buildCache>
<bind>
<source>${java.io.tmpdir}/junit-image-cache-${test-build-id}-build</source>
</bind>
</buildCache>
<launchCache>
<bind>
<source>${java.io.tmpdir}/junit-image-cache-${test-build-id}-launch</source>
</bind>
</launchCache>
</image>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2021 the original author or authors.
* Copyright 2012-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -3,7 +3,7 @@
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>
<groupId>org.springframework.boot.maven.it</groupId>
<artifactId>build-image-caches</artifactId>
<artifactId>build-image-volume-caches</artifactId>
<version>0.0.1.BUILD-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

View File

@@ -0,0 +1,28 @@
/*
* Copyright 2012-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.test;
public class SampleApplication {
public static void main(String[] args) throws Exception {
System.out.println("Launched");
synchronized(args) {
args.wait(); // Prevent exit
}
}
}