Skip to content

Commit

Permalink
fix (buildx) : Always pass --config option for latest versions of Doc…
Browse files Browse the repository at this point in the history
…ker CLI (#1701)

+ Always pass --config option in case of latest docker
+ Change default value of --node parameter to null

Signed-off-by: Rohan Kumar <[email protected]>
  • Loading branch information
rohanKanojia committed Aug 18, 2023
1 parent d730680 commit 390c2d1
Show file tree
Hide file tree
Showing 8 changed files with 212 additions and 48 deletions.
1 change: 1 addition & 0 deletions doc/changelog.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# ChangeLog
* **0.44-SNAPSHOT**:
- Always pass `--config` option for latest versions of Docker CLI ([1701](https://github.com/fabric8io/docker-maven-plugin/issues/1701))

* **0.43.3** (2023-08-13):
- Only add `--config` to buildx command string when authentication credentials are coming from outside sources
Expand Down
2 changes: 1 addition & 1 deletion src/main/asciidoc/inc/build/_buildx.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ The `<buildx>` element within `<build>` defines how to build multi-architecture
The builder manages the build cache.

| *nodeName*
| Specify the name of the node to be created or modified. If none is specified, it is the name of the builder it belongs to, with an index `0` number suffix.
| Specify the name of the node to be created or modified.

| *configFile*
| Configuration file for builder. Non-absolute files are relative to the maven project directory. If configFile starts with
Expand Down
67 changes: 61 additions & 6 deletions src/main/java/io/fabric8/maven/docker/service/BuildXService.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import io.fabric8.maven.docker.access.AuthConfigList;
import io.fabric8.maven.docker.access.DockerAccess;
import io.fabric8.maven.docker.access.util.ExternalCommand;
import io.fabric8.maven.docker.assembly.BuildDirs;
import io.fabric8.maven.docker.assembly.DockerAssemblyManager;
import io.fabric8.maven.docker.config.AttestationConfiguration;
Expand All @@ -12,6 +13,7 @@
import io.fabric8.maven.docker.util.ImageName;
import io.fabric8.maven.docker.util.Logger;
import io.fabric8.maven.docker.util.ProjectPaths;
import org.apache.commons.lang3.StringUtils;
import org.apache.maven.plugin.MojoExecutionException;

import java.io.BufferedReader;
Expand All @@ -36,6 +38,8 @@
import static io.fabric8.maven.docker.util.AuthConfigFactory.hasAuthForRegistryInDockerConfig;

public class BuildXService {
private static final int DOCKER_CLI_BUILDX_CONFIG_COMPATIBLE_MAJOR_VERSION = 23;
private static final String DOCKER = "docker";
private final DockerAccess dockerAccess;
private final DockerAssemblyManager dockerAssemblyManager;
private final Logger logger;
Expand Down Expand Up @@ -67,9 +71,8 @@ protected <C> void useBuilder(ProjectPaths projectPaths, ImageConfiguration imag

Path configPath = getDockerStateDir(imageConfig.getBuildConfiguration(), buildDirs);
List<String> buildX = new ArrayList<>();
buildX.add("docker");
if (authConfig != null && !authConfig.isEmpty() &&
!hasAuthForRegistryInDockerConfig(logger, configuredRegistry, authConfig)) {
buildX.add(DOCKER);
if (isDockerCLINotLegacy() || shouldAddConfigInLegacyDockerCLI(authConfig, configuredRegistry)) {
buildX.add("--config");
buildX.add(configPath.toString());
}
Expand All @@ -85,6 +88,31 @@ protected <C> void useBuilder(ProjectPaths projectPaths, ImageConfiguration imag
}
}

private boolean shouldAddConfigInLegacyDockerCLI(AuthConfigList authConfigList, String configuredRegistry) throws MojoExecutionException {
return authConfigList != null && !authConfigList.isEmpty() &&
!hasAuthForRegistryInDockerConfig(logger, configuredRegistry, authConfigList);
}

private boolean isDockerCLINotLegacy() {
DockerVersionExternalCommand dockerVersionExternalCommand = new DockerVersionExternalCommand(logger);
try {
dockerVersionExternalCommand.execute();
} catch (IOException e) {
logger.info("Failure in getting docker CLI version", e);
}
String version = dockerVersionExternalCommand.getVersion();
if (StringUtils.isNotBlank(version)) {
version = version.replaceAll("(^')|('$)", "");
String[] versionParts = version.split("\\.");
logger.info("Using Docker CLI " + version);
if (versionParts.length >= 3) {
int cliMajorVersion = Integer.parseInt(versionParts[0]);
return cliMajorVersion >= DOCKER_CLI_BUILDX_CONFIG_COMPATIBLE_MAJOR_VERSION;
}
}
return false;
}

protected void createConfigJson(Path configJson, AuthConfigList authConfig) throws MojoExecutionException {
try (BufferedWriter bufferedWriter = Files.newBufferedWriter(configJson, StandardCharsets.UTF_8,
StandardOpenOption.WRITE, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING)
Expand Down Expand Up @@ -203,7 +231,7 @@ protected Path getContextPath(File buildArchive) throws MojoExecutionException {

protected Path getDockerStateDir(BuildImageConfiguration buildConfiguration, BuildDirs buildDirs) {
String stateDir = buildConfiguration.getBuildX().getDockerStateDir();
Path dockerStatePath = buildDirs.getBuildPath(stateDir != null ? EnvUtil.resolveHomeReference(stateDir) : "docker");
Path dockerStatePath = buildDirs.getBuildPath(stateDir != null ? EnvUtil.resolveHomeReference(stateDir) : DOCKER);
createDirectory(dockerStatePath);
return dockerStatePath;
}
Expand All @@ -219,11 +247,14 @@ protected void createDirectory(Path cachePath) {
protected String createBuilder(Path configPath, List<String> buildX, ImageConfiguration imageConfig, BuildDirs buildDirs) throws MojoExecutionException {
BuildXConfiguration buildXConfiguration = imageConfig.getBuildConfiguration().getBuildX();
String builderName = Optional.ofNullable(buildXConfiguration.getBuilderName()).orElse("maven");
String nodeName = Optional.ofNullable(buildXConfiguration.getNodeName()).orElse(builderName + "0");
String nodeName = buildXConfiguration.getNodeName();
Path builderPath = configPath.resolve(Paths.get("buildx", "instances", builderName));
if(Files.notExists(builderPath)) {
List<String> cmds = new ArrayList<>(buildX);
append(cmds, "create", "--driver", "docker-container", "--name", builderName, "--node", nodeName);
append(cmds, "create", "--driver", "docker-container", "--name", builderName);
if (nodeName != null) {
append(cmds, "--node", nodeName);
}
String buildConfig = buildXConfiguration.getConfigFile();
if(buildConfig != null) {
append(cmds, "--config",
Expand Down Expand Up @@ -285,4 +316,28 @@ private void pumpStream(InputStream is) {
});
}
}

public static class DockerVersionExternalCommand extends ExternalCommand {
private final StringBuilder outputBuilder;
public DockerVersionExternalCommand(Logger logger) {
super(logger);
outputBuilder = new StringBuilder();
}

@Override
protected String[] getArgs() {
return new String[] {DOCKER, "version", "--format", "'{{.Client.Version}}'"};
}

@Override
protected void processLine(String line) {
if (StringUtils.isNotBlank(line)) {
outputBuilder.append(line);
}
}

public String getVersion() {
return outputBuilder.toString();
}
}
}
15 changes: 15 additions & 0 deletions src/test/java/io/fabric8/maven/docker/BuildMojoTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,16 @@
import io.fabric8.maven.docker.service.BuildXService;
import io.fabric8.maven.docker.service.ImagePullManager;
import org.apache.maven.plugin.MojoExecutionException;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.api.io.TempDir;
import org.mockito.ArgumentCaptor;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockedConstruction;
import org.mockito.Mockito;
import org.mockito.junit.jupiter.MockitoExtension;

Expand Down Expand Up @@ -51,11 +54,22 @@ class BuildMojoTest extends MojoTestBase {

@Mock
private BuildXService.Exec exec;
private MockedConstruction<BuildXService.DockerVersionExternalCommand> dockerVersionExternalCommandMockedConstruction;

private static String getOsDependentBuild(Path buildPath, String docker) {
return buildPath.resolve(docker).toString().replace('/', File.separatorChar);
}

@BeforeEach
void setUp() {
dockerVersionExternalCommandMockedConstruction = Mockito.mockConstruction(BuildXService.DockerVersionExternalCommand.class);
}

@AfterEach
void tearDown() {
dockerVersionExternalCommandMockedConstruction.close();
}

@Test
void skipWhenPom() throws IOException, MojoExecutionException {

Expand Down Expand Up @@ -336,6 +350,7 @@ private void whenMojoExecutes() throws IOException, MojoExecutionException {

private BuildXConfiguration.Builder getBuildXPlatforms(String... platforms) {
return new BuildXConfiguration.Builder()
.nodeName("maven0")
.platforms(Arrays.asList(platforms));
}

Expand Down
Loading

0 comments on commit 390c2d1

Please sign in to comment.