Skip to content

Commit 384a07c

Browse files
Merge pull request #28292 from jeliebig
* pr/28292: Polish "Add option to customize cache volume names when building an image" Add option to customize cache volume names when building an image Closes gh-28292
2 parents 9d6a0cf + 8714689 commit 384a07c

File tree

25 files changed

+972
-38
lines changed

25 files changed

+972
-38
lines changed

spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/build/BuildRequest.java

Lines changed: 64 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
* @author Andrey Shlykov
3939
* @author Jeroen Meijer
4040
* @author Rafael Ceccone
41+
* @author Julian Liebig
4142
* @since 2.3.0
4243
*/
4344
public class BuildRequest {
@@ -74,6 +75,10 @@ public class BuildRequest {
7475

7576
private final List<ImageReference> tags;
7677

78+
private final Cache buildCache;
79+
80+
private final Cache launchCache;
81+
7782
BuildRequest(ImageReference name, Function<Owner, TarArchive> applicationContent) {
7883
Assert.notNull(name, "Name must not be null");
7984
Assert.notNull(applicationContent, "ApplicationContent must not be null");
@@ -91,12 +96,14 @@ public class BuildRequest {
9196
this.bindings = Collections.emptyList();
9297
this.network = null;
9398
this.tags = Collections.emptyList();
99+
this.buildCache = null;
100+
this.launchCache = null;
94101
}
95102

96103
BuildRequest(ImageReference name, Function<Owner, TarArchive> applicationContent, ImageReference builder,
97104
ImageReference runImage, Creator creator, Map<String, String> env, boolean cleanCache,
98105
boolean verboseLogging, PullPolicy pullPolicy, boolean publish, List<BuildpackReference> buildpacks,
99-
List<Binding> bindings, String network, List<ImageReference> tags) {
106+
List<Binding> bindings, String network, List<ImageReference> tags, Cache buildCache, Cache launchCache) {
100107
this.name = name;
101108
this.applicationContent = applicationContent;
102109
this.builder = builder;
@@ -111,6 +118,8 @@ public class BuildRequest {
111118
this.bindings = bindings;
112119
this.network = network;
113120
this.tags = tags;
121+
this.buildCache = buildCache;
122+
this.launchCache = launchCache;
114123
}
115124

116125
/**
@@ -122,7 +131,7 @@ public BuildRequest withBuilder(ImageReference builder) {
122131
Assert.notNull(builder, "Builder must not be null");
123132
return new BuildRequest(this.name, this.applicationContent, builder.inTaggedOrDigestForm(), this.runImage,
124133
this.creator, this.env, this.cleanCache, this.verboseLogging, this.pullPolicy, this.publish,
125-
this.buildpacks, this.bindings, this.network, this.tags);
134+
this.buildpacks, this.bindings, this.network, this.tags, this.buildCache, this.launchCache);
126135
}
127136

128137
/**
@@ -133,7 +142,7 @@ public BuildRequest withBuilder(ImageReference builder) {
133142
public BuildRequest withRunImage(ImageReference runImageName) {
134143
return new BuildRequest(this.name, this.applicationContent, this.builder, runImageName.inTaggedOrDigestForm(),
135144
this.creator, this.env, this.cleanCache, this.verboseLogging, this.pullPolicy, this.publish,
136-
this.buildpacks, this.bindings, this.network, this.tags);
145+
this.buildpacks, this.bindings, this.network, this.tags, this.buildCache, this.launchCache);
137146
}
138147

139148
/**
@@ -145,7 +154,7 @@ public BuildRequest withCreator(Creator creator) {
145154
Assert.notNull(creator, "Creator must not be null");
146155
return new BuildRequest(this.name, this.applicationContent, this.builder, this.runImage, creator, this.env,
147156
this.cleanCache, this.verboseLogging, this.pullPolicy, this.publish, this.buildpacks, this.bindings,
148-
this.network, this.tags);
157+
this.network, this.tags, this.buildCache, this.launchCache);
149158
}
150159

151160
/**
@@ -161,7 +170,7 @@ public BuildRequest withEnv(String name, String value) {
161170
env.put(name, value);
162171
return new BuildRequest(this.name, this.applicationContent, this.builder, this.runImage, this.creator,
163172
Collections.unmodifiableMap(env), this.cleanCache, this.verboseLogging, this.pullPolicy, this.publish,
164-
this.buildpacks, this.bindings, this.network, this.tags);
173+
this.buildpacks, this.bindings, this.network, this.tags, this.buildCache, this.launchCache);
165174
}
166175

167176
/**
@@ -175,7 +184,8 @@ public BuildRequest withEnv(Map<String, String> env) {
175184
updatedEnv.putAll(env);
176185
return new BuildRequest(this.name, this.applicationContent, this.builder, this.runImage, this.creator,
177186
Collections.unmodifiableMap(updatedEnv), this.cleanCache, this.verboseLogging, this.pullPolicy,
178-
this.publish, this.buildpacks, this.bindings, this.network, this.tags);
187+
this.publish, this.buildpacks, this.bindings, this.network, this.tags, this.buildCache,
188+
this.launchCache);
179189
}
180190

181191
/**
@@ -186,7 +196,7 @@ public BuildRequest withEnv(Map<String, String> env) {
186196
public BuildRequest withCleanCache(boolean cleanCache) {
187197
return new BuildRequest(this.name, this.applicationContent, this.builder, this.runImage, this.creator, this.env,
188198
cleanCache, this.verboseLogging, this.pullPolicy, this.publish, this.buildpacks, this.bindings,
189-
this.network, this.tags);
199+
this.network, this.tags, this.buildCache, this.launchCache);
190200
}
191201

192202
/**
@@ -197,7 +207,7 @@ public BuildRequest withCleanCache(boolean cleanCache) {
197207
public BuildRequest withVerboseLogging(boolean verboseLogging) {
198208
return new BuildRequest(this.name, this.applicationContent, this.builder, this.runImage, this.creator, this.env,
199209
this.cleanCache, verboseLogging, this.pullPolicy, this.publish, this.buildpacks, this.bindings,
200-
this.network, this.tags);
210+
this.network, this.tags, this.buildCache, this.launchCache);
201211
}
202212

203213
/**
@@ -208,7 +218,7 @@ public BuildRequest withVerboseLogging(boolean verboseLogging) {
208218
public BuildRequest withPullPolicy(PullPolicy pullPolicy) {
209219
return new BuildRequest(this.name, this.applicationContent, this.builder, this.runImage, this.creator, this.env,
210220
this.cleanCache, this.verboseLogging, pullPolicy, this.publish, this.buildpacks, this.bindings,
211-
this.network, this.tags);
221+
this.network, this.tags, this.buildCache, this.launchCache);
212222
}
213223

214224
/**
@@ -219,7 +229,7 @@ public BuildRequest withPullPolicy(PullPolicy pullPolicy) {
219229
public BuildRequest withPublish(boolean publish) {
220230
return new BuildRequest(this.name, this.applicationContent, this.builder, this.runImage, this.creator, this.env,
221231
this.cleanCache, this.verboseLogging, this.pullPolicy, publish, this.buildpacks, this.bindings,
222-
this.network, this.tags);
232+
this.network, this.tags, this.buildCache, this.launchCache);
223233
}
224234

225235
/**
@@ -243,7 +253,7 @@ public BuildRequest withBuildpacks(List<BuildpackReference> buildpacks) {
243253
Assert.notNull(buildpacks, "Buildpacks must not be null");
244254
return new BuildRequest(this.name, this.applicationContent, this.builder, this.runImage, this.creator, this.env,
245255
this.cleanCache, this.verboseLogging, this.pullPolicy, this.publish, buildpacks, this.bindings,
246-
this.network, this.tags);
256+
this.network, this.tags, this.buildCache, this.launchCache);
247257
}
248258

249259
/**
@@ -267,7 +277,7 @@ public BuildRequest withBindings(List<Binding> bindings) {
267277
Assert.notNull(bindings, "Bindings must not be null");
268278
return new BuildRequest(this.name, this.applicationContent, this.builder, this.runImage, this.creator, this.env,
269279
this.cleanCache, this.verboseLogging, this.pullPolicy, this.publish, this.buildpacks, bindings,
270-
this.network, this.tags);
280+
this.network, this.tags, this.buildCache, this.launchCache);
271281
}
272282

273283
/**
@@ -279,7 +289,7 @@ public BuildRequest withBindings(List<Binding> bindings) {
279289
public BuildRequest withNetwork(String network) {
280290
return new BuildRequest(this.name, this.applicationContent, this.builder, this.runImage, this.creator, this.env,
281291
this.cleanCache, this.verboseLogging, this.pullPolicy, this.publish, this.buildpacks, this.bindings,
282-
network, this.tags);
292+
network, this.tags, this.buildCache, this.launchCache);
283293
}
284294

285295
/**
@@ -301,7 +311,31 @@ public BuildRequest withTags(List<ImageReference> tags) {
301311
Assert.notNull(tags, "Tags must not be null");
302312
return new BuildRequest(this.name, this.applicationContent, this.builder, this.runImage, this.creator, this.env,
303313
this.cleanCache, this.verboseLogging, this.pullPolicy, this.publish, this.buildpacks, this.bindings,
304-
this.network, tags);
314+
this.network, tags, this.buildCache, this.launchCache);
315+
}
316+
317+
/**
318+
* Return a new {@link BuildRequest} with an updated build cache.
319+
* @param buildCache the build cache
320+
* @return an updated build request
321+
*/
322+
public BuildRequest withBuildCache(Cache buildCache) {
323+
Assert.notNull(buildCache, "BuildCache must not be null");
324+
return new BuildRequest(this.name, this.applicationContent, this.builder, this.runImage, this.creator, this.env,
325+
this.cleanCache, this.verboseLogging, this.pullPolicy, this.publish, this.buildpacks, this.bindings,
326+
this.network, this.tags, buildCache, this.launchCache);
327+
}
328+
329+
/**
330+
* Return a new {@link BuildRequest} with an updated launch cache.
331+
* @param launchCache the cache
332+
* @return an updated build request
333+
*/
334+
public BuildRequest withLaunchCache(Cache launchCache) {
335+
Assert.notNull(launchCache, "LaunchCache must not be null");
336+
return new BuildRequest(this.name, this.applicationContent, this.builder, this.runImage, this.creator, this.env,
337+
this.cleanCache, this.verboseLogging, this.pullPolicy, this.publish, this.buildpacks, this.bindings,
338+
this.network, this.tags, this.buildCache, launchCache);
305339
}
306340

307341
/**
@@ -421,6 +455,22 @@ public List<ImageReference> getTags() {
421455
return this.tags;
422456
}
423457

458+
/**
459+
* Return the custom build cache that should be used by the lifecycle.
460+
* @return the build cache
461+
*/
462+
public Cache getBuildCache() {
463+
return this.buildCache;
464+
}
465+
466+
/**
467+
* Return the custom launch cache that should be used by the lifecycle.
468+
* @return the launch cache
469+
*/
470+
public Cache getLaunchCache() {
471+
return this.launchCache;
472+
}
473+
424474
/**
425475
* Factory method to create a new {@link BuildRequest} from a JAR file.
426476
* @param jarFile the source jar file
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
/*
2+
* Copyright 2012-2021 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.boot.buildpack.platform.build;
18+
19+
import java.util.Objects;
20+
21+
import org.springframework.util.Assert;
22+
import org.springframework.util.ObjectUtils;
23+
24+
/**
25+
* Details of a cache for use by the CNB builder.
26+
*
27+
* @author Scott Frederick
28+
* @since 2.6.0
29+
*/
30+
public class Cache {
31+
32+
/**
33+
* The format of the cache.
34+
*/
35+
public enum Format {
36+
37+
/**
38+
* A cache stored as a volume in the Docker daemon.
39+
*/
40+
VOLUME;
41+
42+
}
43+
44+
protected final Format format;
45+
46+
Cache(Format format) {
47+
this.format = format;
48+
}
49+
50+
/**
51+
* Return the details of the cache if it is a volume cache.
52+
* @return the cache, or {@code null} if it is not a volume cache
53+
*/
54+
public Volume getVolume() {
55+
return (this.format.equals(Format.VOLUME)) ? (Volume) this : null;
56+
}
57+
58+
/**
59+
* Create a new {@code Cache} that uses a volume with the provided name.
60+
* @param name the cache volume name
61+
* @return a new cache instance
62+
*/
63+
public static Cache volume(String name) {
64+
Assert.notNull(name, "Name must not be null");
65+
return new Volume(name);
66+
}
67+
68+
@Override
69+
public boolean equals(Object obj) {
70+
if (this == obj) {
71+
return true;
72+
}
73+
if (obj == null || getClass() != obj.getClass()) {
74+
return false;
75+
}
76+
Cache other = (Cache) obj;
77+
return Objects.equals(this.format, other.format);
78+
}
79+
80+
@Override
81+
public int hashCode() {
82+
return ObjectUtils.nullSafeHashCode(this.format);
83+
}
84+
85+
/**
86+
* Details of a cache stored in a Docker volume.
87+
*/
88+
public static class Volume extends Cache {
89+
90+
private final String name;
91+
92+
Volume(String name) {
93+
super(Format.VOLUME);
94+
this.name = name;
95+
}
96+
97+
public String getName() {
98+
return this.name;
99+
}
100+
101+
@Override
102+
public boolean equals(Object obj) {
103+
if (this == obj) {
104+
return true;
105+
}
106+
if (obj == null || getClass() != obj.getClass()) {
107+
return false;
108+
}
109+
if (!super.equals(obj)) {
110+
return false;
111+
}
112+
Volume other = (Volume) obj;
113+
return Objects.equals(this.name, other.name);
114+
}
115+
116+
@Override
117+
public int hashCode() {
118+
int result = super.hashCode();
119+
result = 31 * result + ObjectUtils.nullSafeHashCode(this.name);
120+
return result;
121+
}
122+
123+
}
124+
125+
}

spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/build/Lifecycle.java

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
* @author Phillip Webb
4040
* @author Scott Frederick
4141
* @author Jeroen Meijer
42+
* @author Julian Liebig
4243
*/
4344
class Lifecycle implements Closeable {
4445

@@ -86,16 +87,37 @@ class Lifecycle implements Closeable {
8687
this.platformVersion = getPlatformVersion(builder.getBuilderMetadata().getLifecycle());
8788
this.layersVolume = createRandomVolumeName("pack-layers-");
8889
this.applicationVolume = createRandomVolumeName("pack-app-");
89-
this.buildCacheVolume = createCacheVolumeName(request, ".build");
90-
this.launchCacheVolume = createCacheVolumeName(request, ".launch");
90+
this.buildCacheVolume = getBuildCacheVolumeName(request);
91+
this.launchCacheVolume = getLaunchCacheVolumeName(request);
9192
}
9293

9394
protected VolumeName createRandomVolumeName(String prefix) {
9495
return VolumeName.random(prefix);
9596
}
9697

98+
private VolumeName getBuildCacheVolumeName(BuildRequest request) {
99+
if (request.getBuildCache() != null) {
100+
return getVolumeName(request.getBuildCache());
101+
}
102+
return createCacheVolumeName(request, "build");
103+
}
104+
105+
private VolumeName getLaunchCacheVolumeName(BuildRequest request) {
106+
if (request.getLaunchCache() != null) {
107+
return getVolumeName(request.getLaunchCache());
108+
}
109+
return createCacheVolumeName(request, "launch");
110+
}
111+
112+
private VolumeName getVolumeName(Cache cache) {
113+
if (cache.getVolume() != null) {
114+
return VolumeName.of(cache.getVolume().getName());
115+
}
116+
return null;
117+
}
118+
97119
private VolumeName createCacheVolumeName(BuildRequest request, String suffix) {
98-
return VolumeName.basedOn(request.getName(), ImageReference::toLegacyString, "pack-cache-", suffix, 6);
120+
return VolumeName.basedOn(request.getName(), ImageReference::toLegacyString, "pack-cache-", "." + suffix, 6);
99121
}
100122

101123
private ApiVersion getPlatformVersion(BuilderMetadata.Lifecycle lifecycle) {

0 commit comments

Comments
 (0)