diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000000..526c8a38d4a --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +*.sh text eol=lf \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 9a0d764da7b..d4a39b400b7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,8 @@ All notable changes to this project will be documented in this file. ## UNRELEASED ### Fixed +- Problems with using container based docker-compose on Windows ([\#514](https://github.com/testcontainers/testcontainers-java/pull/514)) +- Problems with copying files on Windows ([\#514](https://github.com/testcontainers/testcontainers-java/pull/514)) - Fixed regression in 1.4.3 when using Docker Compose on Windows ([\#439](https://github.com/testcontainers/testcontainers-java/issues/439)) - Fixed local Docker Compose executable name resolution on Windows (#416) - Fixed TAR composition on Windows (#444) diff --git a/core/src/main/java/org/testcontainers/containers/DockerComposeContainer.java b/core/src/main/java/org/testcontainers/containers/DockerComposeContainer.java index b5b30fd4a99..d4061d9e499 100644 --- a/core/src/main/java/org/testcontainers/containers/DockerComposeContainer.java +++ b/core/src/main/java/org/testcontainers/containers/DockerComposeContainer.java @@ -395,6 +395,10 @@ default void validateFileList(List composeFiles) { * Use Docker Compose container. */ class ContainerisedDockerCompose extends GenericContainer implements DockerCompose { + + private static final String DOCKER_SOCKET_PATH = "/var/run/docker.sock"; + public static final char UNIX_PATH_SEPERATOR = ':'; + public ContainerisedDockerCompose(List composeFiles, String identifier) { super(TestcontainersConfiguration.getInstance().getDockerComposeContainerImage()); @@ -405,14 +409,14 @@ public ContainerisedDockerCompose(List composeFiles, String identifier) { // Map the docker compose file into the container final File dockerComposeBaseFile = composeFiles.get(0); final String pwd = dockerComposeBaseFile.getAbsoluteFile().getParentFile().getAbsolutePath(); - final String containerPwd = MountableFile.forHostPath(pwd).getResolvedPath(); + final String containerPwd = MountableFile.forHostPath(pwd).getFilesystemPath(); final List absoluteDockerComposeFiles = composeFiles.stream() .map(File::getAbsolutePath) .map(MountableFile::forHostPath) - .map(MountableFile::getResolvedPath) + .map(MountableFile::getFilesystemPath) .collect(toList()); - final String composeFileEnvVariableValue = Joiner.on(File.pathSeparator).join(absoluteDockerComposeFiles); + final String composeFileEnvVariableValue = Joiner.on(UNIX_PATH_SEPERATOR).join(absoluteDockerComposeFiles); // we always need the UNIX path separator logger().debug("Set env COMPOSE_FILE={}", composeFileEnvVariableValue); addEnv(ENV_COMPOSE_FILE, composeFileEnvVariableValue); addFileSystemBind(pwd, containerPwd, READ_ONLY); @@ -421,12 +425,18 @@ public ContainerisedDockerCompose(List composeFiles, String identifier) { // as the docker daemon, just mapping the docker control socket is OK. // As there seems to be a problem with mapping to the /var/run directory in certain environments (e.g. CircleCI) // we map the socket file outside of /var/run, as just /docker.sock - addFileSystemBind("/var/run/docker.sock", "/docker.sock", READ_WRITE); + addFileSystemBind(getDockerSocketHostPath(), "/docker.sock", READ_WRITE); addEnv("DOCKER_HOST", "unix:///docker.sock"); setStartupCheckStrategy(new IndefiniteWaitOneShotStartupCheckStrategy()); setWorkingDirectory(containerPwd); } + private String getDockerSocketHostPath() { + return SystemUtils.IS_OS_WINDOWS + ? "/" + DOCKER_SOCKET_PATH + : DOCKER_SOCKET_PATH; + } + @Override public void invoke() { super.start(); diff --git a/core/src/main/java/org/testcontainers/images/builder/traits/ClasspathTrait.java b/core/src/main/java/org/testcontainers/images/builder/traits/ClasspathTrait.java index 8203f81d494..5617365f2cd 100644 --- a/core/src/main/java/org/testcontainers/images/builder/traits/ClasspathTrait.java +++ b/core/src/main/java/org/testcontainers/images/builder/traits/ClasspathTrait.java @@ -13,6 +13,6 @@ public interface ClasspathTrait & BuildContext default SELF withFileFromClasspath(String path, String resourcePath) { final MountableFile mountableFile = MountableFile.forClasspathResource(resourcePath); - return ((SELF) this).withFileFromPath(path, Paths.get(mountableFile.getFilesystemPath())); + return ((SELF) this).withFileFromPath(path, Paths.get(mountableFile.getResolvedPath())); } } diff --git a/core/src/main/java/org/testcontainers/utility/MountableFile.java b/core/src/main/java/org/testcontainers/utility/MountableFile.java index f92b8b4e887..9f99fe064af 100644 --- a/core/src/main/java/org/testcontainers/utility/MountableFile.java +++ b/core/src/main/java/org/testcontainers/utility/MountableFile.java @@ -1,9 +1,15 @@ package org.testcontainers.utility; -import static lombok.AccessLevel.PACKAGE; -import static org.testcontainers.utility.PathUtils.recursiveDeleteDir; - import com.google.common.base.Charsets; +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.compress.archivers.tar.TarArchiveEntry; +import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream; +import org.apache.commons.lang.SystemUtils; +import org.jetbrains.annotations.NotNull; +import org.testcontainers.images.builder.Transferable; + import java.io.File; import java.io.IOException; import java.io.InputStream; @@ -19,14 +25,9 @@ import java.util.Set; import java.util.jar.JarEntry; import java.util.jar.JarFile; -import lombok.Getter; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.apache.commons.compress.archivers.tar.TarArchiveEntry; -import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream; -import org.apache.commons.lang.SystemUtils; -import org.jetbrains.annotations.NotNull; -import org.testcontainers.images.builder.Transferable; + +import static lombok.AccessLevel.PACKAGE; +import static org.testcontainers.utility.PathUtils.recursiveDeleteDir; /** * An abstraction over files and classpath resources aimed at encapsulating all the complexity of generating @@ -165,8 +166,8 @@ private static String unencodeResourceURIToFilePath(@NotNull final String resour private String resolvePath() { String result = getResourcePath(); - if (SystemUtils.IS_OS_WINDOWS) { - result = PathUtils.createMinGWPath(result); + if (SystemUtils.IS_OS_WINDOWS && result.startsWith("/")) { + result = result.substring(1); } return result; @@ -177,13 +178,15 @@ private String resolvePath() { * into a container. If this is a classpath resource residing in a JAR, it will be extracted to * a temporary location so that the Docker daemon is able to access it. * + * TODO: rename method accordingly and check if really needed like this + * * @return */ private String resolveFilesystemPath() { String result = getResourcePath(); if (SystemUtils.IS_OS_WINDOWS && result.startsWith("/")) { - result = result.substring(1); + result = PathUtils.createMinGWPath(result).substring(1); } return result; @@ -285,7 +288,7 @@ private void deleteOnExit(final Path path) { */ @Override public void transferTo(final TarArchiveOutputStream outputStream, String destinationPathInTar) { - recursiveTar(destinationPathInTar, this.getFilesystemPath(), this.getFilesystemPath(), outputStream); + recursiveTar(destinationPathInTar, this.getResolvedPath(), this.getResolvedPath(), outputStream); } /* @@ -325,7 +328,7 @@ private void recursiveTar(String entryFilename, String rootPath, String itemPath @Override public long getSize() { - final File file = new File(this.getFilesystemPath()); + final File file = new File(this.getResolvedPath()); if (file.isFile()) { return file.length(); } else { @@ -340,7 +343,7 @@ public String getDescription() { @Override public int getFileMode() { - return getUnixFileMode(this.getFilesystemPath()); + return getUnixFileMode(this.getResolvedPath()); } private int getUnixFileMode(final String pathAsString) { diff --git a/core/src/test/java/org/testcontainers/utility/MountableFileTest.java b/core/src/test/java/org/testcontainers/utility/MountableFileTest.java index c278953c112..7bdaeeaeeeb 100644 --- a/core/src/test/java/org/testcontainers/utility/MountableFileTest.java +++ b/core/src/test/java/org/testcontainers/utility/MountableFileTest.java @@ -108,7 +108,7 @@ private Path createTempDir() throws IOException { } private void performChecks(final MountableFile mountableFile) { - final String mountablePath = mountableFile.getFilesystemPath(); + final String mountablePath = mountableFile.getResolvedPath(); assertTrue("The filesystem path '" + mountablePath + "' can be found", new File(mountablePath).exists()); assertFalse("The filesystem path '" + mountablePath + "' does not contain any URL escaping", mountablePath.contains("%20")); }