Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature: Add the possibility to give secret to buildx build (#1798) #1799

Merged
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
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();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is okay for now but we need to improve this in the future.

}

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

public boolean hasSecret() {
return secret != null;
}

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 && !envs.isEmpty()) {
isEmpty = false;
}
return this;
}

public SecretConfiguration.Builder files(Map<String, String> files) {
config.files = files;
if (files != null && !files.isEmpty()) {
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
Loading