Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 61 additions & 0 deletions it/buildx-target/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>io.fabric8.dmp.itests</groupId>
<artifactId>dmp-it-parent</artifactId>
<version>0.49-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

<artifactId>dmp-it-buildx-target</artifactId>

<build>
<plugins>
<plugin>
<groupId>io.fabric8</groupId>
<artifactId>docker-maven-plugin</artifactId>
<configuration>
<images>
<image>
<name>dmp/buildx-target:${project.version}</name>
<build>
<dockerFile>${project.basedir}/src/main/docker/Dockerfile</dockerFile>
<target>base</target>
<buildx>
<platforms>
<platform>linux/amd64</platform>
<platform>linux/arm64</platform>
</platforms>
</buildx>
</build>
<run>
<wait>
<log>base</log>
<time>5000</time>
</wait>
</run>
</image>
</images>
</configuration>
<executions>
<execution>
<id>build</id>
<goals>
<goal>build</goal>
</goals>
<phase>package</phase>
</execution>
<execution>
<id>integration-test</id>
<goals>
<goal>start</goal>
<goal>stop</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
6 changes: 6 additions & 0 deletions it/buildx-target/src/main/docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
FROM alpine AS base
RUN echo "base" > /stage.txt
CMD ["sh", "-c", "cat /stage.txt && sleep infinity"]

FROM base AS final
RUN echo "final" > /stage.txt
55 changes: 55 additions & 0 deletions it/dockerfile-target/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>io.fabric8.dmp.itests</groupId>
<artifactId>dmp-it-parent</artifactId>
<version>0.49-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

<artifactId>dmp-it-dockerfile-target</artifactId>

<build>
<plugins>
<plugin>
<groupId>io.fabric8</groupId>
<artifactId>docker-maven-plugin</artifactId>
<configuration>
<images>
<image>
<name>dmp/dockerfile-target:${project.version}</name>
<build>
<dockerFile>${project.basedir}/src/main/docker/Dockerfile</dockerFile>
<target>base</target>
</build>
<run>
<wait>
<log>base</log>
<time>5000</time>
</wait>
</run>
</image>
</images>
</configuration>
<executions>
<execution>
<id>build</id>
<goals>
<goal>build</goal>
</goals>
<phase>package</phase>
</execution>
<execution>
<id>integration-test</id>
<goals>
<goal>start</goal>
<goal>stop</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
6 changes: 6 additions & 0 deletions it/dockerfile-target/src/main/docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
FROM alpine AS base
RUN echo "base" > /stage.txt
CMD ["sh", "-c", "cat /stage.txt && sleep infinity"]

FROM base AS final
RUN echo "final" > /stage.txt
2 changes: 2 additions & 0 deletions it/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
<module>builder</module>
<module>buildx</module>
<module>buildx-contextdir</module>
<module>buildx-target</module>
<module>buildx-dependencyset</module>
<module>buildx-dockerfile</module>
<module>buildx-dockerfile-secret</module>
Expand All @@ -31,6 +32,7 @@
<module>docker-compose</module>
<module>docker-compose-dependon</module>
<module>dockerfile</module>
<module>dockerfile-target</module>
<module>dockerfile-base-as-arg</module>
<module>dockerfile-base-as-arg-buildconfig</module>
<module>dockerfile-push-build-arg-from</module>
Expand Down
2 changes: 2 additions & 0 deletions src/main/asciidoc/inc/build/_buildx.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ element defaults to `min` and the `<sbom>` element defaults to `false`.
For environment variables add a `<env>` element with a list of variables in the form `<secret name>env variable name</secret name>` (whereas the `secret name` can then be referenced in your Dockerfile.
For files, add a `<files>` component with a list of paths to the files in the form `<secret name>path to file</secret name>`.
Examples can be found in the https://github.com/kevinleturc/docker-maven-plugin/blob/bd805724111f7744a38d0b67f80f3e2d2a3e46d2/it/buildx-dockerfile-secret/pom.xml#L26[integration tests].
NOTE: The `--target` option for multi-stage Dockerfiles is configured via the `<target>` element in the parent `<build>` section, not inside `<buildx>`. It applies to both the regular build path and buildx.

|===

.Examples
Expand Down
3 changes: 3 additions & 0 deletions src/main/asciidoc/inc/build/_configuration.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,9 @@ a| Scan the archive specified in `dockerArchive` and find the actual repository
| *skipTag*
| If set to `true` this plugin won't add any tags to images. Property: `docker.skip.tag`

| *target*
| Target build stage to build in a multi-stage Dockerfile. Passed as `--target` to `docker build` and `docker buildx build`. Can be overridden with the property `docker.buildTarget`.

| *tags*
| List of additional `tag` elements with which an image is to be tagged after the build. Whitespace is trimmed from each element and empty elements are ignored.

Expand Down
3 changes: 3 additions & 0 deletions src/main/asciidoc/inc/external/_property_configuration.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,9 @@ when a `docker.from` or a `docker.fromExt` is set.
| *docker.build.network*
| Set the networking mode for the RUN instructions during build

| *docker.buildTarget*
| Target build stage in a multi-stage Dockerfile. Passed as `--target` to `docker build` and `docker buildx build`.

| *docker.buildArg.VARIABLE*
| Set a ARG to be available during build of image. *Note*: this is handled separately from external configuration, and is always available. See <<property-buildargs,Build Args>> for more details.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,13 @@ public BuildOptions network(String network) {
return this;
}

public BuildOptions target(String target) {
if (target != null && !target.isEmpty()) {
options.put("target", target);
}
return this;
}

public Map<String, String> getOptions() {
return options;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,13 @@ public class BuildImageConfiguration implements Serializable {
@Parameter
private Map<String,String> buildOptions;

/**
* Target build stage in a multi-stage Dockerfile.
* Passed as {@code --target} to {@code docker build} and {@code docker buildx build}.
*/
@Parameter
private String target;

//Default file exclusions
@Parameter
private Boolean useDefaultExcludes;
Expand Down Expand Up @@ -456,6 +463,10 @@ public Map<String, String> getBuildOptions() {
return buildOptions;
}

public String getTarget() {
return target;
}

public Map<String, String> getCreateImageOptions() {
return createImageOptions;
}
Expand Down Expand Up @@ -750,6 +761,11 @@ public Builder buildOptions(Map<String,String> buildOptions) {
return this;
}

public Builder target(String target) {
config.target = target;
return this;
}

public Builder createImageOptions(Map<String, String> createImageOptions) {
config.createImageOptions = createImageOptions;
return this;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ public enum ConfigKey {
AUTO_REMOVE,
BIND,
BUILD_OPTIONS,
BUILD_TARGET,
BUILDX_PLATFORMS("buildx.platforms", ValueCombinePolicy.Merge),
BUILDX_BUILDERNAME("buildx.builderName"),
BUILDX_NODENAME("buildx.nodeName"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ private BuildImageConfiguration extractBuildConfiguration(ImageConfiguration fro
.tags(valueProvider.getList(TAGS, config.getTags()))
.maintainer(valueProvider.getString(MAINTAINER, config.getMaintainer()))
.network(valueProvider.getString(BUILD_NETWORK, config.getNetwork()))
.target(valueProvider.getString(BUILD_TARGET, config.getTarget()))
.workdir(valueProvider.getString(WORKDIR, config.getWorkdir()))
.skip(valueProvider.getBoolean(SKIP_BUILD, config.getSkip()))
.skipPush(valueProvider.getBoolean(SKIP_PUSH, config.getSkipPush()))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@ protected void buildImage(ImageConfiguration imageConfig, MojoParameters params,
.squash(squash)
.cacheFrom(buildConfig.getCacheFrom())
.network(buildConfig.getNetwork())
.target(buildConfig.getTarget())
.buildArgs(mergedBuildMap);
String newImageId = doBuildImage(imageName, dockerArchive, opts);
log.info("%s: Built image %s", imageConfig.getDescription(), newImageId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,11 @@ protected void buildX(List<String> buildX, String builderName, BuildDirs buildDi
if (buildXConfiguration.getCacheTo() != null) {
cmdLine.add("--cache-to=" + buildXConfiguration.getCacheTo());
}

if (buildConfiguration.getTarget() != null) {
cmdLine.add("--target=" + buildConfiguration.getTarget());
}

SecretConfiguration secret = buildXConfiguration.getSecret();
if (secret != null) {
if (secret.getEnvs() != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,54 @@ void testBuildArgsFromDifferentSources() throws MojoExecutionException, DockerAc
}
}

@Test
void testTargetIsPropagatedToBuildOptions() throws DockerAccessException, MojoExecutionException {
// Given
BuildImageConfiguration buildConfig = new BuildImageConfiguration.Builder()
.target("my-stage")
.build();

imageConfig = new ImageConfiguration.Builder()
.name("build-image")
.buildConfig(buildConfig)
.build();

BuildService.BuildContext buildContext = new BuildService.BuildContext.Builder()
.mojoParameters(mojoParameters)
.build();
File buildArchive = buildService.buildArchive(imageConfig, buildContext, "");

// When
buildService.buildImage(imageConfig, null, false, false, Collections.emptyMap(), buildArchive);

// Then
Mockito.verify(docker).buildImage(Mockito.any(), Mockito.any(),
Mockito.argThat((BuildOptions options) -> "my-stage".equals(options.getOptions().get("target"))));
}

@Test
void testTargetAbsentFromBuildOptionsWhenNotConfigured() throws DockerAccessException, MojoExecutionException {
// Given
BuildImageConfiguration buildConfig = new BuildImageConfiguration.Builder().build();

imageConfig = new ImageConfiguration.Builder()
.name("build-image")
.buildConfig(buildConfig)
.build();

BuildService.BuildContext buildContext = new BuildService.BuildContext.Builder()
.mojoParameters(mojoParameters)
.build();
File buildArchive = buildService.buildArchive(imageConfig, buildContext, "");

// When
buildService.buildImage(imageConfig, null, false, false, Collections.emptyMap(), buildArchive);

// Then
Mockito.verify(docker).buildImage(Mockito.any(), Mockito.any(),
Mockito.argThat((BuildOptions options) -> !options.getOptions().containsKey("target")));
}

private void givenAnImageConfiguration(String cleanup) {
BuildImageConfiguration buildConfig = new BuildImageConfiguration.Builder()
.cleanup(cleanup)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,32 @@ void testBuildXCacheToIsPresentIfProvided() throws Exception {
verifyBuildXArgumentPresentInExec("--cache-to=cacheToSpec");
}

@Test
void testBuildXTargetIsNotPresentIfNotProvided() throws Exception {

//Given
buildConfigUsingBuildx(temporaryFolder, (buildX, buildImage) -> {});

// When
buildx.build(projectPaths, imageConfig, configuredRegistry, authConfigList, buildArchive);

//Then
verifyBuildXArgumentNotPresentInExec("--target");
}

@Test
void testBuildXTargetIsPresentIfProvided() throws Exception {

//Given
buildConfigUsingBuildx(temporaryFolder, (buildX, buildImage) -> buildImage.target("my-stage"));

// When
buildx.build(projectPaths, imageConfig, configuredRegistry, authConfigList, buildArchive);

//Then
verifyBuildXArgumentPresentInExec("--target=my-stage");
}

private void buildConfigUsingBuildx(File temporaryFolder, BiConsumer<BuildXConfiguration.Builder, BuildImageConfiguration.Builder> spec) {
final BuildXConfiguration.Builder buildXConfigurationBuilder = new BuildXConfiguration.Builder()
.dockerStateDir(temporaryFolder.getAbsolutePath())
Expand Down
Loading