package org.testcontainers.dockerclient; import com.github.dockerjava.core.DefaultDockerClientConfig; import com.github.dockerjava.core.DockerClientConfig; import org.jetbrains.annotations.NotNull; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; public class UnixSocketClientProviderStrategy extends DockerClientProviderStrategy { protected static final String DOCKER_SOCK_PATH = "/var/run/docker.sock"; private static final String SOCKET_LOCATION = "unix://" + DOCKER_SOCK_PATH; private static final int SOCKET_FILE_MODE_MASK = 0xc000; private static final String PING_TIMEOUT_DEFAULT = "10"; private static final String PING_TIMEOUT_PROPERTY_NAME = "testcontainers.unixsocketprovider.timeout"; @Override public void test() throws InvalidConfigurationException { if (!System.getProperty("os.name").toLowerCase().contains("linux")) { throw new InvalidConfigurationException("this strategy is only applicable to Linux"); } try { config = tryConfiguration(SOCKET_LOCATION); LOGGER.info("Accessing docker with local Unix socket"); } catch (Exception | UnsatisfiedLinkError e) { throw new InvalidConfigurationException("ping failed", e); } } @NotNull protected DockerClientConfig tryConfiguration(String dockerHost) { Path dockerSocketFile = Paths.get(DOCKER_SOCK_PATH); Integer mode; try { mode = (Integer) Files.getAttribute(dockerSocketFile, "unix:mode"); } catch (IOException e) { throw new InvalidConfigurationException("Could not find unix domain socket", e); } if ((mode & 0xc000) != SOCKET_FILE_MODE_MASK) { throw new InvalidConfigurationException("Found docker unix domain socket but file mode was not as expected (expected: srwxr-xr-x). This problem is possibly due to occurrence of this issue in the past: https://github.com/docker/docker/issues/13121"); } config = DefaultDockerClientConfig.createDefaultConfigBuilder() .withDockerHost(dockerHost) .withDockerTlsVerify(false) .build(); client = getClientForConfig(config); final int timeout = Integer.parseInt(System.getProperty(PING_TIMEOUT_PROPERTY_NAME, PING_TIMEOUT_DEFAULT)); ping(client, timeout); return config; } @Override public String getDescription() { return "local Unix socket (" + SOCKET_LOCATION + ")"; } }