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

@@ -239,6 +239,14 @@ class BuildRequestTests {
assertThat(withCache.getBuildCache()).isEqualTo(Cache.volume("build-volume"));
}
@Test
void withBuildBindCacheAddsCache() throws IOException {
BuildRequest request = BuildRequest.forJarFile(writeTestJarFile("my-app-0.0.1.jar"));
BuildRequest withCache = request.withBuildCache(Cache.bind("/tmp/build-cache"));
assertThat(request.getBuildCache()).isNull();
assertThat(withCache.getBuildCache()).isEqualTo(Cache.bind("/tmp/build-cache"));
}
@Test
void withBuildVolumeCacheWhenCacheIsNullThrowsException() throws IOException {
BuildRequest request = BuildRequest.forJarFile(writeTestJarFile("my-app-0.0.1.jar"));
@@ -254,6 +262,14 @@ class BuildRequestTests {
assertThat(withCache.getLaunchCache()).isEqualTo(Cache.volume("launch-volume"));
}
@Test
void withLaunchBindCacheAddsCache() throws IOException {
BuildRequest request = BuildRequest.forJarFile(writeTestJarFile("my-app-0.0.1.jar"));
BuildRequest withCache = request.withLaunchCache(Cache.bind("/tmp/launch-cache"));
assertThat(request.getLaunchCache()).isNull();
assertThat(withCache.getLaunchCache()).isEqualTo(Cache.bind("/tmp/launch-cache"));
}
@Test
void withLaunchVolumeCacheWhenCacheIsNullThrowsException() throws IOException {
BuildRequest request = BuildRequest.forJarFile(writeTestJarFile("my-app-0.0.1.jar"));

View File

@@ -218,6 +218,18 @@ class LifecycleTests {
assertThat(this.out.toString()).contains("Successfully built image 'docker.io/library/my-application:latest'");
}
@Test
void executeWithCacheBindMountsExecutesPhases() 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));
BuildRequest request = getTestRequest().withBuildCache(Cache.bind("/tmp/build-cache"))
.withLaunchCache(Cache.bind("/tmp/launch-cache"));
createLifecycle(request).execute();
assertPhaseWasRun("creator", withExpectedConfig("lifecycle-creator-cache-bind-mounts.json"));
assertThat(this.out.toString()).contains("Successfully built image 'docker.io/library/my-application:latest'");
}
@Test
void executeWithCreatedDateExecutesPhases() throws Exception {
given(this.docker.container().create(any())).willAnswer(answerWithGeneratedContainerId());

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.
@@ -67,7 +67,7 @@ class PrintStreamBuildLogTests {
Consumer<TotalProgressEvent> pullRunImageConsumer = log.pullingImage(runImageReference, ImageType.RUNNER);
pullRunImageConsumer.accept(new TotalProgressEvent(100));
log.pulledImage(runImage, ImageType.RUNNER);
log.executingLifecycle(request, LifecycleVersion.parse("0.5"), VolumeName.of("pack-abc.cache"));
log.executingLifecycle(request, LifecycleVersion.parse("0.5"), Cache.volume(VolumeName.of("pack-abc.cache")));
Consumer<LogUpdateEvent> phase1Consumer = log.runningPhase(request, "alphabet");
phase1Consumer.accept(mockLogEvent("one"));
phase1Consumer.accept(mockLogEvent("two"));

View File

@@ -0,0 +1,39 @@
{
"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.8"
],
"Labels": {
"author": "spring-boot"
},
"HostConfig": {
"Binds": [
"/var/run/docker.sock:/var/run/docker.sock",
"pack-layers-aaaaaaaaaa:/layers",
"pack-app-aaaaaaaaaa:/workspace",
"/tmp/build-cache:/cache",
"/tmp/launch-cache:/launch-cache"
],
"SecurityOpt" : [
"label=disable"
]
}
}