Polish "Add network option for image building"
See gh-27486
This commit is contained in:
parent
8e6d03b221
commit
2178c281e9
|
@ -265,6 +265,12 @@ public class BuildRequest {
|
||||||
this.network);
|
this.network);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a new {@link BuildRequest} with an updated network setting.
|
||||||
|
* @param network the network the build container will connect to
|
||||||
|
* @return an updated build request
|
||||||
|
* @since 2.6.0
|
||||||
|
*/
|
||||||
public BuildRequest withNetwork(String network) {
|
public BuildRequest withNetwork(String network) {
|
||||||
return new BuildRequest(this.name, this.applicationContent, this.builder, this.runImage, this.creator, this.env,
|
return new BuildRequest(this.name, this.applicationContent, this.builder, this.runImage, this.creator, this.env,
|
||||||
this.cleanCache, this.verboseLogging, this.pullPolicy, this.publish, this.buildpacks, this.bindings,
|
this.cleanCache, this.verboseLogging, this.pullPolicy, this.publish, this.buildpacks, this.bindings,
|
||||||
|
@ -371,6 +377,11 @@ public class BuildRequest {
|
||||||
return this.bindings;
|
return this.bindings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the network the build container will connect to.
|
||||||
|
* @return the network
|
||||||
|
* @since 2.6.0
|
||||||
|
*/
|
||||||
public String getNetwork() {
|
public String getNetwork() {
|
||||||
return this.network;
|
return this.network;
|
||||||
}
|
}
|
||||||
|
|
|
@ -148,7 +148,9 @@ class Lifecycle implements Closeable {
|
||||||
this.request.getBindings().forEach(phase::withBinding);
|
this.request.getBindings().forEach(phase::withBinding);
|
||||||
}
|
}
|
||||||
phase.withEnv(PLATFORM_API_VERSION_KEY, this.platformVersion.toString());
|
phase.withEnv(PLATFORM_API_VERSION_KEY, this.platformVersion.toString());
|
||||||
|
if (this.request.getNetwork() != null) {
|
||||||
phase.withNetworkMode(this.request.getNetwork());
|
phase.withNetworkMode(this.request.getNetwork());
|
||||||
|
}
|
||||||
return phase;
|
return phase;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -104,6 +104,10 @@ class Phase {
|
||||||
this.env.put(name, value);
|
this.env.put(name, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update this phase with the network the build container will connect to.
|
||||||
|
* @param networkMode the network
|
||||||
|
*/
|
||||||
void withNetworkMode(String networkMode) {
|
void withNetworkMode(String networkMode) {
|
||||||
this.networkMode = networkMode;
|
this.networkMode = networkMode;
|
||||||
}
|
}
|
||||||
|
@ -134,7 +138,9 @@ class Phase {
|
||||||
update.withLabel("author", "spring-boot");
|
update.withLabel("author", "spring-boot");
|
||||||
this.bindings.forEach(update::withBinding);
|
this.bindings.forEach(update::withBinding);
|
||||||
this.env.forEach(update::withEnv);
|
this.env.forEach(update::withEnv);
|
||||||
|
if (this.networkMode != null) {
|
||||||
update.withNetworkMode(this.networkMode);
|
update.withNetworkMode(this.networkMode);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -188,6 +188,11 @@ public class ContainerConfig {
|
||||||
this.env.put(name, value);
|
this.env.put(name, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the container config with the network that the build container will
|
||||||
|
* connect to.
|
||||||
|
* @param networkMode the network
|
||||||
|
*/
|
||||||
public void withNetworkMode(String networkMode) {
|
public void withNetworkMode(String networkMode) {
|
||||||
this.networkMode = networkMode;
|
this.networkMode = networkMode;
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,7 +57,6 @@ class PhaseTests {
|
||||||
phase.apply(update);
|
phase.apply(update);
|
||||||
verify(update).withCommand("/cnb/lifecycle/test", NO_ARGS);
|
verify(update).withCommand("/cnb/lifecycle/test", NO_ARGS);
|
||||||
verify(update).withLabel("author", "spring-boot");
|
verify(update).withLabel("author", "spring-boot");
|
||||||
verify(update).withNetworkMode(null);
|
|
||||||
verifyNoMoreInteractions(update);
|
verifyNoMoreInteractions(update);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,7 +70,6 @@ class PhaseTests {
|
||||||
verify(update).withBinding(Binding.from("/var/run/docker.sock", "/var/run/docker.sock"));
|
verify(update).withBinding(Binding.from("/var/run/docker.sock", "/var/run/docker.sock"));
|
||||||
verify(update).withCommand("/cnb/lifecycle/test", NO_ARGS);
|
verify(update).withCommand("/cnb/lifecycle/test", NO_ARGS);
|
||||||
verify(update).withLabel("author", "spring-boot");
|
verify(update).withLabel("author", "spring-boot");
|
||||||
verify(update).withNetworkMode(null);
|
|
||||||
verifyNoMoreInteractions(update);
|
verifyNoMoreInteractions(update);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,7 +81,6 @@ class PhaseTests {
|
||||||
phase.apply(update);
|
phase.apply(update);
|
||||||
verify(update).withCommand("/cnb/lifecycle/test", "-log-level", "debug");
|
verify(update).withCommand("/cnb/lifecycle/test", "-log-level", "debug");
|
||||||
verify(update).withLabel("author", "spring-boot");
|
verify(update).withLabel("author", "spring-boot");
|
||||||
verify(update).withNetworkMode(null);
|
|
||||||
verifyNoMoreInteractions(update);
|
verifyNoMoreInteractions(update);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,7 +92,6 @@ class PhaseTests {
|
||||||
phase.apply(update);
|
phase.apply(update);
|
||||||
verify(update).withCommand("/cnb/lifecycle/test");
|
verify(update).withCommand("/cnb/lifecycle/test");
|
||||||
verify(update).withLabel("author", "spring-boot");
|
verify(update).withLabel("author", "spring-boot");
|
||||||
verify(update).withNetworkMode(null);
|
|
||||||
verifyNoMoreInteractions(update);
|
verifyNoMoreInteractions(update);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,7 +103,6 @@ class PhaseTests {
|
||||||
phase.apply(update);
|
phase.apply(update);
|
||||||
verify(update).withCommand("/cnb/lifecycle/test", "a", "b", "c");
|
verify(update).withCommand("/cnb/lifecycle/test", "a", "b", "c");
|
||||||
verify(update).withLabel("author", "spring-boot");
|
verify(update).withLabel("author", "spring-boot");
|
||||||
verify(update).withNetworkMode(null);
|
|
||||||
verifyNoMoreInteractions(update);
|
verifyNoMoreInteractions(update);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,7 +116,6 @@ class PhaseTests {
|
||||||
verify(update).withCommand("/cnb/lifecycle/test");
|
verify(update).withCommand("/cnb/lifecycle/test");
|
||||||
verify(update).withLabel("author", "spring-boot");
|
verify(update).withLabel("author", "spring-boot");
|
||||||
verify(update).withBinding(Binding.from(volumeName, "/test"));
|
verify(update).withBinding(Binding.from(volumeName, "/test"));
|
||||||
verify(update).withNetworkMode(null);
|
|
||||||
verifyNoMoreInteractions(update);
|
verifyNoMoreInteractions(update);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -136,7 +130,6 @@ class PhaseTests {
|
||||||
verify(update).withLabel("author", "spring-boot");
|
verify(update).withLabel("author", "spring-boot");
|
||||||
verify(update).withEnv("name1", "value1");
|
verify(update).withEnv("name1", "value1");
|
||||||
verify(update).withEnv("name2", "value2");
|
verify(update).withEnv("name2", "value2");
|
||||||
verify(update).withNetworkMode(null);
|
|
||||||
verifyNoMoreInteractions(update);
|
verifyNoMoreInteractions(update);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -155,6 +155,12 @@ Where `<options>` can contain:
|
||||||
* `volume-opt=key=value` to specify key-value pairs consisting of an option name and its value
|
* `volume-opt=key=value` to specify key-value pairs consisting of an option name and its value
|
||||||
|
|
|
|
||||||
|
|
||||||
|
| `network`
|
||||||
|
| `--network`
|
||||||
|
| The https://docs.docker.com/network/#network-drivers[network driver] the builder container will be configured to use.
|
||||||
|
The value supplied will be passed unvalidated to Docker when creating the builder container.
|
||||||
|
|
|
||||||
|
|
||||||
| `cleanCache`
|
| `cleanCache`
|
||||||
| `--cleanCache`
|
| `--cleanCache`
|
||||||
| Whether to clean the cache before building.
|
| Whether to clean the cache before building.
|
||||||
|
@ -170,13 +176,6 @@ Where `<options>` can contain:
|
||||||
| Whether to publish the generated image to a Docker registry.
|
| Whether to publish the generated image to a Docker registry.
|
||||||
| `false`
|
| `false`
|
||||||
|
|
||||||
| `network`
|
|
||||||
| `--network`
|
|
||||||
| The network the build container will connect to. The value supplied for this option will be passed
|
|
||||||
unvalidated as `HostConfig.NetworkMode` to the configuration which creates the build container,
|
|
||||||
see https://docs.docker.com/engine/api/v1.41/#operation/ContainerCreate[Docker's engine API].
|
|
||||||
Using this option is similar to running `docker build --network ...`.
|
|
||||||
|
|
|
||||||
|===
|
|===
|
||||||
|
|
||||||
NOTE: The plugin detects the target Java compatibility of the project using the JavaPlugin's `targetCompatibility` property.
|
NOTE: The plugin detects the target Java compatibility of the project using the JavaPlugin's `targetCompatibility` property.
|
||||||
|
|
|
@ -71,6 +71,7 @@ class BootBuildImageIntegrationTests {
|
||||||
assertThat(result.getOutput()).contains("docker.io/library/" + projectName);
|
assertThat(result.getOutput()).contains("docker.io/library/" + projectName);
|
||||||
assertThat(result.getOutput()).contains("---> Test Info buildpack building");
|
assertThat(result.getOutput()).contains("---> Test Info buildpack building");
|
||||||
assertThat(result.getOutput()).contains("env: BP_JVM_VERSION=8.*");
|
assertThat(result.getOutput()).contains("env: BP_JVM_VERSION=8.*");
|
||||||
|
assertThat(result.getOutput()).contains("Network status: HTTP/2 200");
|
||||||
assertThat(result.getOutput()).contains("---> Test Info buildpack done");
|
assertThat(result.getOutput()).contains("---> Test Info buildpack done");
|
||||||
removeImage(projectName);
|
removeImage(projectName);
|
||||||
}
|
}
|
||||||
|
@ -247,6 +248,20 @@ class BootBuildImageIntegrationTests {
|
||||||
removeImage(projectName);
|
removeImage(projectName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestTemplate
|
||||||
|
void buildsImageWithNetworkModeNone() throws IOException {
|
||||||
|
writeMainClass();
|
||||||
|
writeLongNameResource();
|
||||||
|
BuildResult result = this.gradleBuild.build("bootBuildImage", "--pullPolicy=IF_NOT_PRESENT");
|
||||||
|
String projectName = this.gradleBuild.getProjectDir().getName();
|
||||||
|
assertThat(result.task(":bootBuildImage").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
|
||||||
|
assertThat(result.getOutput()).contains("docker.io/library/" + projectName);
|
||||||
|
assertThat(result.getOutput()).contains("---> Test Info buildpack building");
|
||||||
|
assertThat(result.getOutput()).contains("Network status: curl failed");
|
||||||
|
assertThat(result.getOutput()).contains("---> Test Info buildpack done");
|
||||||
|
removeImage(projectName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestTemplate
|
@TestTemplate
|
||||||
void failsWithBuilderError() throws IOException {
|
void failsWithBuilderError() throws IOException {
|
||||||
writeMainClass();
|
writeMainClass();
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
plugins {
|
||||||
|
id 'java'
|
||||||
|
id 'org.springframework.boot' version '{version}'
|
||||||
|
}
|
||||||
|
|
||||||
|
if (project.hasProperty('applyWarPlugin')) {
|
||||||
|
apply plugin: 'war'
|
||||||
|
}
|
||||||
|
|
||||||
|
sourceCompatibility = '1.8'
|
||||||
|
targetCompatibility = '1.8'
|
||||||
|
|
||||||
|
bootBuildImage {
|
||||||
|
builder = "projects.registry.vmware.com/springboot/spring-boot-cnb-builder:0.0.1"
|
||||||
|
network = "none"
|
||||||
|
}
|
|
@ -163,6 +163,12 @@ Where `<options>` can contain:
|
||||||
* `volume-opt=key=value` to specify key-value pairs consisting of an option name and its value
|
* `volume-opt=key=value` to specify key-value pairs consisting of an option name and its value
|
||||||
|
|
|
|
||||||
|
|
||||||
|
| `network` +
|
||||||
|
(`spring-boot.build-image.network`)
|
||||||
|
| The https://docs.docker.com/network/#network-drivers[network driver] the builder container will be configured to use.
|
||||||
|
The value supplied will be passed unvalidated to Docker when creating the builder container.
|
||||||
|
|
|
||||||
|
|
||||||
| `cleanCache` +
|
| `cleanCache` +
|
||||||
(`spring-boot.build-image.cleanCache`)
|
(`spring-boot.build-image.cleanCache`)
|
||||||
| Whether to clean the cache before building.
|
| Whether to clean the cache before building.
|
||||||
|
@ -177,13 +183,6 @@ Where `<options>` can contain:
|
||||||
| Whether to publish the generated image to a Docker registry.
|
| Whether to publish the generated image to a Docker registry.
|
||||||
| `false`
|
| `false`
|
||||||
|
|
||||||
| `network` +
|
|
||||||
(`spring-boot.build-image.network`)
|
|
||||||
| The network the build container will connect to. The value supplied for this option will be passed
|
|
||||||
unvalidated as `HostConfig.NetworkMode` to the configuration which creates the build container,
|
|
||||||
see https://docs.docker.com/engine/api/v1.41/#operation/ContainerCreate[Docker's engine API].
|
|
||||||
Using this option is similar to running `docker build --network ...`.
|
|
||||||
|
|
|
||||||
|===
|
|===
|
||||||
|
|
||||||
NOTE: The plugin detects the target Java compatibility of the project using the compiler's plugin configuration or the `maven.compiler.target` property.
|
NOTE: The plugin detects the target Java compatibility of the project using the compiler's plugin configuration or the `maven.compiler.target` property.
|
||||||
|
|
|
@ -270,6 +270,17 @@ public class BuildImageTests extends AbstractArchiveIntegrationTests {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestTemplate
|
||||||
|
void whenBuildImageIsInvokedWithNetworkModeNone(MavenBuild mavenBuild) {
|
||||||
|
mavenBuild.project("build-image-network").goals("package")
|
||||||
|
.systemProperty("spring-boot.build-image.pullPolicy", "IF_NOT_PRESENT").execute((project) -> {
|
||||||
|
assertThat(buildLog(project)).contains("Building image")
|
||||||
|
.contains("docker.io/library/build-image-network:0.0.1.BUILD-SNAPSHOT")
|
||||||
|
.contains("Network status: curl failed").contains("Successfully built image");
|
||||||
|
removeImage("build-image-network", "0.0.1.BUILD-SNAPSHOT");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@TestTemplate
|
@TestTemplate
|
||||||
void whenBuildImageIsInvokedOnMultiModuleProjectWithPackageGoal(MavenBuild mavenBuild) {
|
void whenBuildImageIsInvokedOnMultiModuleProjectWithPackageGoal(MavenBuild mavenBuild) {
|
||||||
mavenBuild.project("build-image-multi-module").goals("package")
|
mavenBuild.project("build-image-multi-module").goals("package")
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
<?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-network</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</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<image>
|
||||||
|
<builder>projects.registry.vmware.com/springboot/spring-boot-cnb-builder:0.0.1</builder>
|
||||||
|
<network>none</network>
|
||||||
|
</image>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</project>
|
|
@ -0,0 +1,28 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2012-2020 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"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -32,4 +32,6 @@ if [[ -f META-INF/MANIFEST.MF ]]; then
|
||||||
cat META-INF/MANIFEST.MF
|
cat META-INF/MANIFEST.MF
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
echo "Network status: $(curl --silent --head https://spring.io | grep -E '^HTTP' || echo "curl failed")"
|
||||||
|
|
||||||
echo "---> Test Info buildpack done"
|
echo "---> Test Info buildpack done"
|
||||||
|
|
Loading…
Reference in New Issue