Skip to content

Commit

Permalink
feature: Add the possibility to give secret to buildx build (fabric8i…
Browse files Browse the repository at this point in the history
…o#1798)

Signed-off-by: Kevin Leturc <kevinleturc@users.noreply.github.com>
  • Loading branch information
kevinleturc committed Jul 16, 2024
1 parent e980189 commit bb3a237
Show file tree
Hide file tree
Showing 11 changed files with 219 additions and 20 deletions.
1 change: 1 addition & 0 deletions doc/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
- Automatically create parent directories of portPropertyFile path
- Added support for `platform` attribute of a container in the docker-compose configuration.
- `docker:push` failed with build `ARG` in `FROM` ([1778](https://github.com/fabric8io/docker-maven-plugin/issues/1778))
- Add the possibility to give secret to buildx build ([1798](https://github.com/fabric8io/docker-maven-plugin/issues/1798)

* **0.44.0** (2024-02-17):
- Add new option "useDefaultExclusion" for build configuration to handle exclusion of hidden files ([1708](https://github.com/fabric8io/docker-maven-plugin/issues/1708))
Expand Down
51 changes: 51 additions & 0 deletions it/buildx-dockerfile-secret/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?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.45-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

<artifactId>dmp-it-buildx-dockerfile-secret</artifactId>

<build>
<plugins>
<plugin>
<groupId>io.fabric8</groupId>
<artifactId>docker-maven-plugin</artifactId>
<configuration>
<images>
<image>
<name>dmp/alpine:${project.version}</name>
<build>
<dockerFile>${project.basedir}/src/main/docker/Dockerfile</dockerFile>
<buildx>
<secret>
<envs>
<myEnvVar>something</myEnvVar>
</envs>
<files>
<myFile>${project.basedir}/../README.md</myFile>
</files>
</secret>
</buildx>
</build>
</image>
</images>
</configuration>
<executions>
<execution>
<id>default</id>
<goals>
<goal>build</goal>
</goals>
<phase>package</phase>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
4 changes: 4 additions & 0 deletions it/buildx-dockerfile-secret/src/main/docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
FROM alpine

RUN --mount=type=secret,id=myEnvVar cat /run/secrets/myEnvVar
RUN --mount=type=secret,id=myFile cat /run/secrets/myFile
1 change: 1 addition & 0 deletions it/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
<module>buildx-contextdir</module>
<module>buildx-dependencyset</module>
<module>buildx-dockerfile</module>
<module>buildx-dockerfile-secret</module>
<module>buildx-dockerfile_and_contextdir</module>
<module>buildx-push</module>
<module>docker-compose</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 @@ -60,6 +60,8 @@ element defaults to `min` and the `<sbom>` element defaults to `false`.
| A value to be passed through to the `--cache-from` option of `docker buildx build`. See https://docs.docker.com/engine/reference/commandline/buildx_build/#cache-from[docker buildx reference docs].
| *cacheTo*
| A value to be passed through to the `--cache-to` option of `docker buildx build`. See https://docs.docker.com/engine/reference/commandline/buildx_build/#cache-to[docker buildx reference docs].
| *secret*
| Two Maps, under `envs` and `files` of `<ID>VALUE</id>` elements specifying the values of https://docs.docker.com/reference/cli/docker/buildx/build/#secret[Docker Buildx secret] to give to the build as `--secret id=ID[,[env\|src]=VALUE]`.
|===

.Examples
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,12 @@ public class BuildXConfiguration implements Serializable {
@Parameter
private Map<String, String> driverOpts;

/**
* Secret to expose to the build
*/
@Parameter
private SecretConfiguration secret;

public String getBuilderName() {
return builderName;
}
Expand All @@ -86,7 +92,7 @@ public String getCacheTo() {
}

public boolean isBuildX() {
return !getPlatforms().isEmpty();
return !getPlatforms().isEmpty() || hasSecret();
}

@Nonnull
Expand All @@ -102,6 +108,14 @@ public Map<String, String> getDriverOpts() {
return driverOpts;
}

public boolean hasSecret() {
return secret != null && (!secret.getEnvs().isEmpty() || !secret.getFiles().isEmpty());
}

public SecretConfiguration getSecret() {
return secret;
}

public static class Builder {

private final BuildXConfiguration config = new BuildXConfiguration();
Expand Down Expand Up @@ -159,7 +173,6 @@ public Builder attestations(AttestationConfiguration attestations) {
return this;
}


public Builder cacheFrom(String cacheFrom) {
config.cacheFrom = cacheFrom;
if (cacheFrom != null) {
Expand All @@ -183,5 +196,13 @@ public Builder cacheTo(String cacheTo) {
}
return this;
}

public Builder secret(SecretConfiguration secret) {
config.secret = secret;
if (secret != null) {
isEmpty = false;
}
return this;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package io.fabric8.maven.docker.config;

import org.apache.maven.plugins.annotations.Parameter;

import java.io.Serializable;
import java.util.Map;

/**
* @since 15/07/24
*/
public class SecretConfiguration implements Serializable {

@Parameter
private Map<String, String> envs;

@Parameter
private Map<String, String> files;

public Map<String, String> getEnvs() {
return envs;
}

public Map<String, String> getFiles() {
return files;
}

public static class Builder {

private final SecretConfiguration config = new SecretConfiguration();
private boolean isEmpty = true;

public SecretConfiguration build() {
return isEmpty ? null : config;
}

public SecretConfiguration.Builder envs(Map<String, String> envs) {
config.envs = envs;
if (envs != null) {
isEmpty = false;
}
return this;
}

public SecretConfiguration.Builder files(Map<String, String> files) {
config.files = files;
if (files != null) {
isEmpty = false;
}
return this;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ public enum ConfigKey {
BUILDX_ATTESTATION_SBOM("buildx.attestations.sbom"),
BUILDX_CACHE_FROM("buildx.cacheFrom"),
BUILDX_CACHE_TO("buildx.cacheTo"),
BUILDX_SECRET_ENVS("buildx.secret.envs", ValueCombinePolicy.Merge),
BUILDX_SECRET_FILES("buildx.secret.files", ValueCombinePolicy.Merge),
CAP_ADD,
CAP_DROP,
SYSCTLS,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import io.fabric8.maven.docker.config.RestartPolicy;
import io.fabric8.maven.docker.config.RunImageConfiguration;
import io.fabric8.maven.docker.config.RunVolumeConfiguration;
import io.fabric8.maven.docker.config.SecretConfiguration;
import io.fabric8.maven.docker.config.UlimitConfig;
import io.fabric8.maven.docker.config.WaitConfiguration;
import io.fabric8.maven.docker.config.WatchImageConfiguration;
Expand Down Expand Up @@ -342,6 +343,7 @@ private BuildXConfiguration extractBuildx(BuildXConfiguration config, ValueProvi
.attestations(extractAttestations(config.getAttestations(), valueProvider))
.cacheFrom(valueProvider.getString(BUILDX_CACHE_FROM, config.getCacheFrom()))
.cacheTo(valueProvider.getString(BUILDX_CACHE_TO, config.getCacheTo()))
.secret(extractSecret(config.getSecret(), valueProvider))
.build();
}

Expand All @@ -356,6 +358,17 @@ private AttestationConfiguration extractAttestations(AttestationConfiguration co
.build();
}

private SecretConfiguration extractSecret(SecretConfiguration config, ValueProvider valueProvider) {
if (config == null) {
config = new SecretConfiguration();
}

return new SecretConfiguration.Builder()
.envs(valueProvider.getMap(BUILDX_SECRET_ENVS, config.getEnvs()))
.files(valueProvider.getMap(BUILDX_SECRET_FILES, config.getFiles()))
.build();
}

// Extract only the values of the port mapping

private List<String> extractPortValues(List<String> config, ValueProvider valueProvider) {
Expand Down
31 changes: 29 additions & 2 deletions src/main/java/io/fabric8/maven/docker/service/BuildXService.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import io.fabric8.maven.docker.config.BuildXConfiguration;
import io.fabric8.maven.docker.config.ConfigHelper;
import io.fabric8.maven.docker.config.ImageConfiguration;
import io.fabric8.maven.docker.config.SecretConfiguration;
import io.fabric8.maven.docker.util.EnvUtil;
import io.fabric8.maven.docker.util.ImageName;
import io.fabric8.maven.docker.util.Logger;
Expand All @@ -35,6 +36,8 @@
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.function.BiConsumer;
import java.util.function.Consumer;

public class BuildXService {
private static final String DOCKER = "docker";
Expand Down Expand Up @@ -121,7 +124,7 @@ protected void buildAndLoadSinglePlatform(List<String> buildX, String builderNam
String nativePlatform = dockerAccess.getNativePlatform();
if (platforms.size() == 1) {
buildX(buildX, builderName, buildDirs, imageConfig, configuredRegistry, platforms, buildArchive, "--load");
} else if (platforms.contains(nativePlatform)) {
} else if (platforms.isEmpty() || platforms.contains(nativePlatform)) {
buildX(buildX, builderName, buildDirs, imageConfig, configuredRegistry, Collections.singletonList(nativePlatform), buildArchive, "--load");
} else {
logger.info("More than one platform specified not including native %s, no image built", nativePlatform);
Expand All @@ -130,7 +133,11 @@ protected void buildAndLoadSinglePlatform(List<String> buildX, String builderNam

protected void pushMultiPlatform(List<String> buildX, String builderName, BuildDirs buildDirs, ImageConfiguration imageConfig, String configuredRegistry, File buildArchive) throws MojoExecutionException {
// build and push all images. The native platform may be re-built, image should be cached and build should be quick
buildX(buildX, builderName, buildDirs, imageConfig, configuredRegistry, imageConfig.getBuildConfiguration().getBuildX().getPlatforms(), buildArchive, "--push");
List<String> platforms = new ArrayList<>(imageConfig.getBuildConfiguration().getBuildX().getPlatforms());
if (platforms.isEmpty()) {
platforms.add(dockerAccess.getNativePlatform());
}
buildX(buildX, builderName, buildDirs, imageConfig, configuredRegistry, platforms, buildArchive, "--push");
}

protected void buildX(List<String> buildX, String builderName, BuildDirs buildDirs, ImageConfiguration imageConfig, String configuredRegistry, List<String> platforms, File buildArchive, String extraParam)
Expand Down Expand Up @@ -190,6 +197,15 @@ protected void buildX(List<String> buildX, String builderName, BuildDirs buildDi
if (buildXConfiguration.getCacheTo() != null) {
cmdLine.add("--cache-to=" + buildXConfiguration.getCacheTo());
}
SecretConfiguration secret = buildXConfiguration.getSecret();
if (secret != null) {
if (secret.getEnvs() != null) {
secret.getEnvs().forEach(buildXSecretConsumerFor("env", cmdLine::add));
}
if (secret.getFiles() != null) {
secret.getFiles().forEach(buildXSecretConsumerFor("src", cmdLine::add));
}
}

if (buildConfiguration.squash()) {
cmdLine.add("--squash");
Expand All @@ -213,6 +229,17 @@ protected void buildX(List<String> buildX, String builderName, BuildDirs buildDi
}
}

protected BiConsumer<String, String> buildXSecretConsumerFor(String attribute, Consumer<String> cmdLineConsumer) {
return (arg0, arg1) -> {
cmdLineConsumer.accept("--secret");
String secretParameter = "id=" + arg0;
if (arg1 != null) {
secretParameter += "," + attribute + "=" + arg1;
}
cmdLineConsumer.accept(secretParameter);
};
}

protected Path getContextPath(File buildArchive) throws MojoExecutionException {
String archiveName = buildArchive.getName();
String fileName = archiveName.substring(0, archiveName.indexOf('.'));
Expand Down
Loading

0 comments on commit bb3a237

Please sign in to comment.