Skip to content

Commit 21b2dd2

Browse files
Allow empty env entries when building an image
Prior to this commit, an entry in the environment map provided to the build plugin image building goal or task that had a null value would result in a failure with a message that was difficult to diagnose. This commit treats env map entries with a null value as an empty entry to prevent the failure and also make it easier to provide an explicit empty entry in the Maven XML. Fixes gh-22703
1 parent 1233288 commit 21b2dd2

File tree

5 files changed

+88
-3
lines changed

5 files changed

+88
-3
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ private Layer getEnvLayer(Map<String, String> env) throws IOException {
7474
return Layer.of((layout) -> {
7575
for (Map.Entry<String, String> entry : env.entrySet()) {
7676
String name = "/platform/env/" + entry.getKey();
77-
Content content = Content.of(entry.getValue());
77+
Content content = Content.of((entry.getValue() != null) ? entry.getValue() : "");
7878
layout.file(name, Owner.ROOT, content);
7979
}
8080
});

spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/build/EphemeralBuilderTests.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
import java.time.Instant;
2626
import java.time.OffsetDateTime;
2727
import java.time.ZoneId;
28-
import java.util.Collections;
28+
import java.util.HashMap;
2929
import java.util.Map;
3030

3131
import org.apache.commons.compress.archivers.ArchiveEntry;
@@ -68,7 +68,9 @@ class EphemeralBuilderTests extends AbstractJsonTests {
6868
void setup() throws Exception {
6969
this.image = Image.of(getContent("image.json"));
7070
this.metadata = BuilderMetadata.fromImage(this.image);
71-
this.env = Collections.singletonMap("spring", "boot");
71+
this.env = new HashMap<>();
72+
this.env.put("spring", "boot");
73+
this.env.put("empty", null);
7274
}
7375

7476
@Test
@@ -113,6 +115,7 @@ void getArchiveContainsEnvLayer() throws Exception {
113115
EphemeralBuilder builder = new EphemeralBuilder(this.owner, this.image, this.metadata, this.creator, this.env);
114116
File directory = unpack(getLayer(builder.getArchive(), 0), "env");
115117
assertThat(new File(directory, "platform/env/spring")).usingCharset(StandardCharsets.UTF_8).hasContent("boot");
118+
assertThat(new File(directory, "platform/env/empty")).usingCharset(StandardCharsets.UTF_8).hasContent("");
116119
}
117120

118121
private TarArchiveInputStream getLayer(ImageArchive archive, int index) throws Exception {

spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/java/org/springframework/boot/maven/BuildImageTests.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,24 @@ void whenBuildImageIsInvokedWithCustomBuilderImageAndRunImage(MavenBuild mavenBu
130130
});
131131
}
132132

133+
@TestTemplate
134+
void whenBuildImageIsInvokedWithEmptyEnvEntry(MavenBuild mavenBuild) {
135+
mavenBuild.project("build-image-empty-env-entry").goals("package").prepare(this::writeLongNameResource)
136+
.execute((project) -> {
137+
assertThat(buildLog(project)).contains("Building image").contains("paketo-buildpacks/builder")
138+
.contains("docker.io/library/build-image-empty-env-entry:0.0.1.BUILD-SNAPSHOT")
139+
.contains("Successfully built image");
140+
ImageReference imageReference = ImageReference.of(ImageName.of("build-image-empty-env-entry"),
141+
"0.0.1.BUILD-SNAPSHOT");
142+
try (GenericContainer<?> container = new GenericContainer<>(imageReference.toString())) {
143+
container.waitingFor(Wait.forLogMessage("Launched\\n", 1)).start();
144+
}
145+
finally {
146+
removeImage(imageReference);
147+
}
148+
});
149+
}
150+
133151
@TestTemplate
134152
void failsWhenBuilderFails(MavenBuild mavenBuild) {
135153
mavenBuild.project("build-image-builder-error").goals("package")
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
4+
<modelVersion>4.0.0</modelVersion>
5+
<groupId>org.springframework.boot.maven.it</groupId>
6+
<artifactId>build-image-empty-env-entry</artifactId>
7+
<version>0.0.1.BUILD-SNAPSHOT</version>
8+
<properties>
9+
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
10+
<maven.compiler.source>@java.version@</maven.compiler.source>
11+
<maven.compiler.target>@java.version@</maven.compiler.target>
12+
</properties>
13+
<build>
14+
<plugins>
15+
<plugin>
16+
<groupId>@project.groupId@</groupId>
17+
<artifactId>@project.artifactId@</artifactId>
18+
<version>@project.version@</version>
19+
<executions>
20+
<execution>
21+
<goals>
22+
<goal>build-image</goal>
23+
</goals>
24+
<configuration>
25+
<image>
26+
<env>
27+
<EMPTY_KEY></EMPTY_KEY>
28+
</env>
29+
</image>
30+
</configuration>
31+
</execution>
32+
</executions>
33+
</plugin>
34+
</plugins>
35+
</build>
36+
</project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*
2+
* Copyright 2012-2020 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.test;
18+
19+
public class SampleApplication {
20+
21+
public static void main(String[] args) throws Exception {
22+
System.out.println("Launched");
23+
synchronized(args) {
24+
args.wait(); // Prevent exit"
25+
}
26+
}
27+
28+
}

0 commit comments

Comments
 (0)