From 706a6697408ef3c9ca98e5d7ab559e4ccfdf8cff Mon Sep 17 00:00:00 2001 From: Sergei Egorov Date: Mon, 27 Jul 2020 18:30:22 +0200 Subject: [PATCH] Fix the Rootless Docker CI job (#3050) --- .github/workflows/ci-rootless.yml | 23 ++++++-- .../RootlessDockerClientProviderStrategy.java | 54 +++++++++++++++++-- 2 files changed, 67 insertions(+), 10 deletions(-) diff --git a/.github/workflows/ci-rootless.yml b/.github/workflows/ci-rootless.yml index e752747b804..7dacc2767a5 100644 --- a/.github/workflows/ci-rootless.yml +++ b/.github/workflows/ci-rootless.yml @@ -7,6 +7,14 @@ on: jobs: test: runs-on: ubuntu-18.04 + strategy: + fail-fast: false + matrix: + include: + - { XDG_RUNTIME_DIR: "" } + - { XDG_RUNTIME_DIR: "/tmp/docker-testcontainers/" } + env: + XDG_RUNTIME_DIR: ${{ matrix.XDG_RUNTIME_DIR }} steps: - uses: actions/checkout@v2 - name: debug @@ -14,17 +22,22 @@ jobs: - name: uninstall rootful Docker run: sudo apt-get -q -y --purge remove moby-engine moby-buildx && sudo rm -rf /var/run/docker.sock - name: install rootless Docker - run: curl -fsSL https://get.docker.com/rootless | sh - - name: start rootless Docker - run: PATH=$HOME/bin:$PATH XDG_RUNTIME_DIR=/tmp/docker-$(id -u) dockerd-rootless.sh --experimental --storage-driver vfs & + run: | + mkdir -p $XDG_RUNTIME_DIR || true + curl -fsSL https://get.docker.com/rootless | sh > init.sh + cat init.sh + source <(grep '^export' init.sh) + PATH=$HOME/bin:$PATH dockerd-rootless.sh --experimental --storage-driver vfs & + sleep 1 + DOCKER_HOST=unix://$XDG_RUNTIME_DIR/docker.sock docker info || ls -la $XDG_RUNTIME_DIR - name: Build with Gradle - run: XDG_RUNTIME_DIR=/tmp/docker-$(id -u) ./gradlew --no-daemon --scan testcontainers:test + run: ./gradlew --no-daemon --scan testcontainers:test - name: aggregate test reports with ciMate if: always() continue-on-error: true env: CIMATE_PROJECT_ID: 2348n4vl - CIMATE_CI_KEY: "CI / rootless Docker" + CIMATE_CI_KEY: "CI / rootless Docker (${{ matrix.XDG_RUNTIME_DIR }})" run: | wget -q https://get.cimate.io/release/linux/cimate chmod +x cimate diff --git a/core/src/main/java/org/testcontainers/dockerclient/RootlessDockerClientProviderStrategy.java b/core/src/main/java/org/testcontainers/dockerclient/RootlessDockerClientProviderStrategy.java index cc6b23e506d..3ee58f4910a 100644 --- a/core/src/main/java/org/testcontainers/dockerclient/RootlessDockerClientProviderStrategy.java +++ b/core/src/main/java/org/testcontainers/dockerclient/RootlessDockerClientProviderStrategy.java @@ -2,28 +2,72 @@ import com.sun.jna.Library; import com.sun.jna.Native; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.SystemUtils; +import org.jetbrains.annotations.Nullable; import java.net.URI; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.Optional; /** * * @deprecated this class is used by the SPI and should not be used directly */ @Deprecated +@Slf4j public final class RootlessDockerClientProviderStrategy extends DockerClientProviderStrategy { public static final int PRIORITY = UnixSocketClientProviderStrategy.PRIORITY + 1; - private Path getSocketPath() { + @Getter(lazy = true) + @Nullable + private final Path socketPath = resolveSocketPath(); + + private Path resolveSocketPath() { + return tryEnv().orElseGet(() -> { + Path homePath = Paths.get(System.getProperty("user.home")).resolve(".docker").resolve("run"); + return tryFolder(homePath).orElseGet(() -> { + Path implicitPath = Paths.get("/run/user/" + LibC.INSTANCE.getuid()); + return tryFolder(implicitPath).orElse(null); + }); + }); + } + + private Optional tryEnv() { String xdgRuntimeDir = System.getenv("XDG_RUNTIME_DIR"); - if (xdgRuntimeDir == null) { - xdgRuntimeDir = "/run/user/" + LibC.INSTANCE.getuid(); + if (StringUtils.isBlank(xdgRuntimeDir)) { + log.debug("$XDG_RUNTIME_DIR is not set."); + return Optional.empty(); + } + Path path = Paths.get(xdgRuntimeDir); + if (!Files.exists(path)) { + log.debug("$XDG_RUNTIME_DIR is set to '{}' but the folder does not exist.", path); + return Optional.empty(); + } + Path socketPath = path.resolve("docker.sock"); + if (!Files.exists(socketPath)) { + log.debug("$XDG_RUNTIME_DIR is set but '{}' does not exist.", socketPath); + return Optional.empty(); + } + return Optional.of(socketPath); + } + + private Optional tryFolder(Path path) { + if (!Files.exists(path)) { + log.debug("'{}' does not exist.", path); + return Optional.empty(); + } + Path socketPath = path.resolve("docker.sock"); + if (!Files.exists(socketPath)) { + log.debug("'{}' does not exist.", socketPath); + return Optional.empty(); } - return Paths.get(xdgRuntimeDir).resolve("docker.sock"); + return Optional.of(socketPath); } @Override @@ -35,7 +79,7 @@ public TransportConfig getTransportConfig() throws InvalidConfigurationException @Override protected boolean isApplicable() { - return SystemUtils.IS_OS_LINUX && Files.exists(getSocketPath()); + return SystemUtils.IS_OS_LINUX && getSocketPath() != null && Files.exists(getSocketPath()); } @Override