Skip to content

Commit 26013ff

Browse files
authored
Merge pull request #31490 from Karm/issue-31307-q-main
Enable Podman and Docker Windows quarkus-container-image-docker testing
2 parents d1c9c14 + 6678ea5 commit 26013ff

File tree

11 files changed

+266
-141
lines changed

11 files changed

+266
-141
lines changed

core/deployment/src/main/java/io/quarkus/deployment/IsDockerWorking.java

Lines changed: 7 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11

22
package io.quarkus.deployment;
33

4-
import java.io.File;
4+
import static io.quarkus.runtime.util.ContainerRuntimeUtil.ContainerRuntime.UNAVAILABLE;
5+
56
import java.io.IOException;
67
import java.lang.reflect.InvocationTargetException;
78
import java.lang.reflect.Method;
@@ -11,23 +12,20 @@
1112
import java.net.URISyntaxException;
1213
import java.nio.file.Files;
1314
import java.nio.file.Path;
14-
import java.time.Duration;
1515
import java.util.List;
1616
import java.util.Optional;
1717
import java.util.function.BooleanSupplier;
1818
import java.util.function.Supplier;
1919

20-
import org.eclipse.microprofile.config.ConfigProvider;
2120
import org.jboss.logging.Logger;
2221

2322
import io.quarkus.deployment.console.StartupLogCompressor;
24-
import io.quarkus.deployment.util.ExecUtil;
23+
import io.quarkus.runtime.util.ContainerRuntimeUtil;
2524

2625
public class IsDockerWorking implements BooleanSupplier {
2726

2827
private static final Logger LOGGER = Logger.getLogger(IsDockerWorking.class.getName());
2928
public static final int DOCKER_HOST_CHECK_TIMEOUT = 1000;
30-
public static final int DOCKER_CMD_CHECK_TIMEOUT = 3000;
3129

3230
private final List<Strategy> strategies;
3331

@@ -36,8 +34,7 @@ public IsDockerWorking() {
3634
}
3735

3836
public IsDockerWorking(boolean silent) {
39-
this.strategies = List.of(new TestContainersStrategy(silent), new DockerHostStrategy(),
40-
new DockerBinaryStrategy(silent));
37+
this.strategies = List.of(new TestContainersStrategy(silent), new DockerHostStrategy(), new DockerBinaryStrategy());
4138
}
4239

4340
@Override
@@ -170,41 +167,11 @@ public Result get() {
170167

171168
private static class DockerBinaryStrategy implements Strategy {
172169

173-
private final boolean silent;
174-
private final String binary;
175-
176-
private DockerBinaryStrategy(boolean silent) {
177-
this.silent = silent;
178-
this.binary = ConfigProvider.getConfig().getOptionalValue("quarkus.docker.executable-name", String.class)
179-
.orElse("docker");
180-
}
181-
182170
@Override
183171
public Result get() {
184-
try {
185-
if (!ExecUtil.execSilentWithTimeout(Duration.ofMillis(DOCKER_CMD_CHECK_TIMEOUT), binary, "-v")) {
186-
LOGGER.warnf("'%s -v' returned an error code. Make sure your Docker binary is correct", binary);
187-
return Result.UNKNOWN;
188-
}
189-
} catch (Exception e) {
190-
LOGGER.warnf("No %s binary found or general error: %s", binary, e);
191-
return Result.UNKNOWN;
192-
}
193-
194-
try {
195-
OutputFilter filter = new OutputFilter();
196-
if (ExecUtil.execWithTimeout(new File("."), filter, Duration.ofMillis(DOCKER_CMD_CHECK_TIMEOUT),
197-
"docker", "version", "--format", "'{{.Server.Version}}'")) {
198-
LOGGER.debugf("Docker daemon found. Version: %s", filter.getOutput());
199-
return Result.AVAILABLE;
200-
} else {
201-
if (!silent) {
202-
LOGGER.warn("Could not determine version of Docker daemon");
203-
}
204-
return Result.UNAVAILABLE;
205-
}
206-
} catch (Exception e) {
207-
LOGGER.warn("Unexpected error occurred while determining Docker daemon version", e);
172+
if (ContainerRuntimeUtil.detectContainerRuntime(false) != UNAVAILABLE) {
173+
return Result.AVAILABLE;
174+
} else {
208175
return Result.UNKNOWN;
209176
}
210177
}

core/deployment/src/main/java/io/quarkus/deployment/pkg/steps/AppCDSBuildStep.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package io.quarkus.deployment.pkg.steps;
22

33
import static io.quarkus.deployment.pkg.steps.LinuxIDUtil.getLinuxID;
4+
import static io.quarkus.runtime.util.ContainerRuntimeUtil.detectContainerRuntime;
45

56
import java.io.File;
67
import java.io.IOException;
@@ -28,6 +29,7 @@
2829
import io.quarkus.deployment.pkg.builditem.OutputTargetBuildItem;
2930
import io.quarkus.deployment.steps.MainClassBuildStep;
3031
import io.quarkus.runtime.LaunchMode;
32+
import io.quarkus.runtime.util.ContainerRuntimeUtil;
3133
import io.quarkus.utilities.JavaBinFinder;
3234

3335
public class AppCDSBuildStep {
@@ -37,6 +39,7 @@ public class AppCDSBuildStep {
3739
public static final String CLASSES_LIST_FILE_NAME = "classes.lst";
3840
private static final String CONTAINER_IMAGE_BASE_BUILD_DIR = "/tmp/quarkus";
3941
private static final String CONTAINER_IMAGE_APPCDS_DIR = CONTAINER_IMAGE_BASE_BUILD_DIR + "/appcds";
42+
public static final ContainerRuntimeUtil.ContainerRuntime CONTAINER_RUNTIME = detectContainerRuntime(false);
4043

4144
@BuildStep(onlyIf = AppCDSRequired.class)
4245
public void requested(OutputTargetBuildItem outputTarget, BuildProducer<AppCDSRequestedBuildItem> producer)
@@ -201,8 +204,12 @@ private Path createClassesList(JarBuildItem jarResult,
201204
// generate the classes file on the host
202205
private List<String> dockerRunCommands(OutputTargetBuildItem outputTarget, String containerImage,
203206
String containerWorkingDir) {
207+
if (CONTAINER_RUNTIME == ContainerRuntimeUtil.ContainerRuntime.UNAVAILABLE) {
208+
throw new IllegalStateException("No container runtime was found. "
209+
+ "Make sure you have either Docker or Podman installed in your environment.");
210+
}
204211
List<String> command = new ArrayList<>(10);
205-
command.add("docker");
212+
command.add(CONTAINER_RUNTIME.getExecutableName());
206213
command.add("run");
207214
command.add("-v");
208215
command.add(outputTarget.getOutputDirectory().toAbsolutePath().toString() + ":" + CONTAINER_IMAGE_BASE_BUILD_DIR

core/deployment/src/main/java/io/quarkus/deployment/pkg/steps/NativeImageBuildLocalContainerRunner.java

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package io.quarkus.deployment.pkg.steps;
22

33
import static io.quarkus.deployment.pkg.steps.LinuxIDUtil.getLinuxID;
4+
import static io.quarkus.runtime.util.ContainerRuntimeUtil.ContainerRuntime.DOCKER;
5+
import static io.quarkus.runtime.util.ContainerRuntimeUtil.ContainerRuntime.PODMAN;
46

57
import java.nio.file.Path;
68
import java.util.ArrayList;
@@ -9,30 +11,24 @@
911
import java.util.List;
1012

1113
import org.apache.commons.lang3.SystemUtils;
12-
import org.jboss.logging.Logger;
1314

1415
import io.quarkus.deployment.pkg.NativeConfig;
1516
import io.quarkus.deployment.util.FileUtil;
16-
import io.quarkus.runtime.util.ContainerRuntimeUtil;
1717

1818
public class NativeImageBuildLocalContainerRunner extends NativeImageBuildContainerRunner {
1919

20-
private static final Logger LOGGER = Logger.getLogger(NativeImageBuildLocalContainerRunner.class.getName());
21-
2220
public NativeImageBuildLocalContainerRunner(NativeConfig nativeConfig, Path outputDir) {
2321
super(nativeConfig, outputDir);
2422
if (SystemUtils.IS_OS_LINUX) {
25-
ArrayList<String> containerRuntimeArgs = new ArrayList<>(Arrays.asList(baseContainerRuntimeArgs));
26-
if (containerRuntime == ContainerRuntimeUtil.ContainerRuntime.DOCKER
27-
&& containerRuntime.isRootless()) {
23+
final ArrayList<String> containerRuntimeArgs = new ArrayList<>(Arrays.asList(baseContainerRuntimeArgs));
24+
if (containerRuntime == DOCKER && containerRuntime.isRootless()) {
2825
Collections.addAll(containerRuntimeArgs, "--user", String.valueOf(0));
2926
} else {
3027
String uid = getLinuxID("-ur");
3128
String gid = getLinuxID("-gr");
3229
if (uid != null && gid != null && !uid.isEmpty() && !gid.isEmpty()) {
3330
Collections.addAll(containerRuntimeArgs, "--user", uid + ":" + gid);
34-
if (containerRuntime == ContainerRuntimeUtil.ContainerRuntime.PODMAN
35-
&& containerRuntime.isRootless()) {
31+
if (containerRuntime == PODMAN && containerRuntime.isRootless()) {
3632
// Needed to avoid AccessDeniedExceptions
3733
containerRuntimeArgs.add("--userns=keep-id");
3834
}
@@ -44,16 +40,19 @@ public NativeImageBuildLocalContainerRunner(NativeConfig nativeConfig, Path outp
4440

4541
@Override
4642
protected List<String> getContainerRuntimeBuildArgs() {
47-
List<String> containerRuntimeArgs = super.getContainerRuntimeBuildArgs();
48-
String volumeOutputPath = outputPath;
43+
final List<String> containerRuntimeArgs = super.getContainerRuntimeBuildArgs();
44+
final String volumeOutputPath;
4945
if (SystemUtils.IS_OS_WINDOWS) {
50-
volumeOutputPath = FileUtil.translateToVolumePath(volumeOutputPath);
46+
volumeOutputPath = FileUtil.translateToVolumePath(outputPath);
47+
} else {
48+
volumeOutputPath = outputPath;
5149
}
5250

53-
String selinuxBindOption = ":z";
54-
if (SystemUtils.IS_OS_MAC
55-
&& ContainerRuntimeUtil.detectContainerRuntime() == ContainerRuntimeUtil.ContainerRuntime.PODMAN) {
51+
final String selinuxBindOption;
52+
if (SystemUtils.IS_OS_MAC && containerRuntime == PODMAN) {
5653
selinuxBindOption = "";
54+
} else {
55+
selinuxBindOption = ":z";
5756
}
5857

5958
Collections.addAll(containerRuntimeArgs, "-v",

core/deployment/src/test/java/io/quarkus/deployment/pkg/steps/NativeImageBuildContainerRunnerTest.java

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package io.quarkus.deployment.pkg.steps;
22

3+
import static io.quarkus.deployment.pkg.steps.AppCDSBuildStep.CONTAINER_RUNTIME;
34
import static org.assertj.core.api.Assertions.assertThat;
45

56
import java.nio.file.Path;
@@ -10,13 +11,18 @@
1011
import org.junit.jupiter.api.condition.DisabledIfSystemProperty;
1112

1213
import io.quarkus.deployment.pkg.NativeConfig;
14+
import io.quarkus.runtime.util.ContainerRuntimeUtil;
1315

1416
class NativeImageBuildContainerRunnerTest {
1517

1618
// This will default to false in the maven build and true in the IDE, so this will still run if invoked explicitly
1719
@DisabledIfSystemProperty(named = "avoid-containers", matches = "true")
1820
@Test
1921
void testBuilderImageBeingPickedUp() {
22+
if (CONTAINER_RUNTIME == ContainerRuntimeUtil.ContainerRuntime.UNAVAILABLE) {
23+
throw new IllegalStateException("No container runtime was found. "
24+
+ "Make sure you have either Docker or Podman installed in your environment.");
25+
}
2026
NativeConfig nativeConfig = new NativeConfig();
2127
nativeConfig.containerRuntime = Optional.empty();
2228
boolean found;
@@ -25,33 +31,39 @@ void testBuilderImageBeingPickedUp() {
2531

2632
nativeConfig.builderImage = "graalvm";
2733
localRunner = new NativeImageBuildLocalContainerRunner(nativeConfig, Path.of("/tmp"));
28-
command = localRunner.buildCommand("docker", Collections.emptyList(), Collections.emptyList());
34+
command = localRunner.buildCommand(CONTAINER_RUNTIME.getExecutableName(), Collections.emptyList(),
35+
Collections.emptyList());
2936
found = false;
3037
for (String part : command) {
3138
if (part.contains("ubi-quarkus-graalvmce-builder-image")) {
3239
found = true;
40+
break;
3341
}
3442
}
3543
assertThat(found).isTrue();
3644

3745
nativeConfig.builderImage = "mandrel";
3846
localRunner = new NativeImageBuildLocalContainerRunner(nativeConfig, Path.of("/tmp"));
39-
command = localRunner.buildCommand("docker", Collections.emptyList(), Collections.emptyList());
47+
command = localRunner.buildCommand(CONTAINER_RUNTIME.getExecutableName(), Collections.emptyList(),
48+
Collections.emptyList());
4049
found = false;
4150
for (String part : command) {
4251
if (part.contains("ubi-quarkus-mandrel-builder-image")) {
4352
found = true;
53+
break;
4454
}
4555
}
4656
assertThat(found).isTrue();
4757

4858
nativeConfig.builderImage = "RandomString";
4959
localRunner = new NativeImageBuildLocalContainerRunner(nativeConfig, Path.of("/tmp"));
50-
command = localRunner.buildCommand("docker", Collections.emptyList(), Collections.emptyList());
60+
command = localRunner.buildCommand(CONTAINER_RUNTIME.getExecutableName(), Collections.emptyList(),
61+
Collections.emptyList());
5162
found = false;
5263
for (String part : command) {
5364
if (part.equals("RandomString")) {
5465
found = true;
66+
break;
5567
}
5668
}
5769
assertThat(found).isTrue();

0 commit comments

Comments
 (0)