default SELF withFileFromClasspath(String path, String resourcePath) { final MountableFile mountableFile = MountableFile.forClasspathResource(resourcePath); return ((SELF) this).withFileFromPath(path, Paths.get(mountableFile.getResolvedPath())); } }
/** * {@inheritDoc} */ @Override public void addFileSystemBind(final String hostPath, final String containerPath, final BindMode mode, final SelinuxContext selinuxContext) { final MountableFile mountableFile = MountableFile.forHostPath(hostPath); binds.add(new Bind(mountableFile.getResolvedPath(), new Volume(containerPath), mode.accessMode, selinuxContext.selContext)); }
/** * Obtains a {@link MountableFile} corresponding to a resource on the classpath (including resources in JAR files) * * @param resourceName the classpath path to the resource * @param mode octal value of posix file mode (000..777) * @return a {@link MountableFile} that may be used to obtain a mountable path */ public static MountableFile forClasspathResource(@NotNull final String resourceName, Integer mode) { return new MountableFile(getClasspathResource(resourceName, new HashSet<>()).toString(), mode); }
/** * {@inheritDoc} */ @Override public void transferTo(final TarArchiveOutputStream outputStream, String destinationPathInTar) { recursiveTar(destinationPathInTar, this.getResolvedPath(), this.getResolvedPath(), outputStream); }
@Override public int getFileMode() { return getUnixFileMode(this.getResolvedPath()); }
private String getResourcePath() { if (path.contains(".jar!")) { resourcePath = extractClassPathResourceToTempLocation(this.path); } else { resourcePath = unencodeResourceURIToFilePath(path); } return resourcePath; }
/** * Obtains a {@link MountableFile} corresponding to a resource on the classpath (including resources in JAR files) * * @param resourceName the classpath path to the resource * @return a {@link MountableFile} that may be used to obtain a mountable path */ public static MountableFile forClasspathResource(@NotNull final String resourceName) { return forClasspathResource(resourceName, null); }
return forClasspathResource(resourceName, null); return new MountableFile(getClasspathResource(resourceName, new HashSet<>()).toString(), mode); return new MountableFile(new File(path).toURI().toString(), mode);
File tmpLocation = createTempDirectory(); String urldecodedJarPath = unencodeResourceURIToFilePath(hostPath); String internalPath = hostPath.replaceAll("[^!]*!/", ""); hostPath, tmpLocation); copyFromJarToLocation(jarFile, entry, internalPath, tmpLocation); deleteOnExit(tmpLocation.toPath());
/** * Obtains a {@link MountableFile} corresponding to a file on the docker host filesystem. * * @param path the path to the resource * @return a {@link MountableFile} that may be used to obtain a mountable path */ public static MountableFile forHostPath(final Path path) { return forHostPath(path, null); }
@Test public void forClasspathResourceWithPermission() throws Exception { final MountableFile mountableFile = MountableFile.forClasspathResource("mappable-resource/test-resource.txt", TEST_FILE_MODE); performChecks(mountableFile); assertEquals("Valid file mode.", BASE_FILE_MODE | TEST_FILE_MODE, mountableFile.getFileMode()); }
@Test public void noTrailingSlashesInTarEntryNames() throws Exception { final MountableFile mountableFile = MountableFile.forClasspathResource("mappable-resource/test-resource.txt"); @Cleanup final TarArchiveInputStream tais = intoTarArchive((taos) -> { mountableFile.transferTo(taos, "/some/path.txt"); mountableFile.transferTo(taos, "/path.txt"); mountableFile.transferTo(taos, "path.txt"); }); ArchiveEntry entry; while ((entry = tais.getNextEntry()) != null) { assertFalse("no entries should have a trailing slash", entry.getName().endsWith("/")); } }
public ContainerisedDockerCompose(List<File> composeFiles, String identifier) { super(TestcontainersConfiguration.getInstance().getDockerComposeContainerImage()); validateFileList(composeFiles); addEnv(ENV_PROJECT_NAME, 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).getFilesystemPath(); final List<String> absoluteDockerComposeFiles = composeFiles.stream() .map(File::getAbsolutePath) .map(MountableFile::forHostPath) .map(MountableFile::getFilesystemPath) .collect(toList()); 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); // Ensure that compose can access docker. Since the container is assumed to be running on the same machine // 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(getDockerSocketHostPath(), "/docker.sock", READ_WRITE); addEnv("DOCKER_HOST", "unix:///docker.sock"); setStartupCheckStrategy(new IndefiniteWaitOneShotStartupCheckStrategy()); setWorkingDirectory(containerPwd); String dockerConfigPath = determineDockerConfigPath(); if (dockerConfigPath != null && !dockerConfigPath.isEmpty()) { addFileSystemBind(dockerConfigPath, DOCKER_CONFIG_FILE, READ_ONLY); } }
@Override public String getDescription() { return this.getResolvedPath(); }
@Test public void forHostFilePathWithPermission() throws Exception { final Path file = createTempFile("somepath"); final MountableFile mountableFile = MountableFile.forHostPath(file.toString(), TEST_FILE_MODE); performChecks(mountableFile); assertEquals("Valid file mode.", BASE_FILE_MODE | TEST_FILE_MODE, mountableFile.getFileMode()); }
/** * Extract a file or directory tree from a JAR file to a temporary location. * This allows Docker to mount classpath resources as files. * * @param hostPath the path on the host, expected to be of the format 'file:/path/to/some.jar!/classpath/path/to/resource' * @return the path of the temporary file/directory */ private String extractClassPathResourceToTempLocation(final String hostPath) { File tmpLocation = createTempDirectory(); //noinspection ResultOfMethodCallIgnored tmpLocation.delete(); String urldecodedJarPath = unencodeResourceURIToFilePath(hostPath); String internalPath = hostPath.replaceAll("[^!]*!/", ""); try (JarFile jarFile = new JarFile(urldecodedJarPath)) { Enumeration<JarEntry> entries = jarFile.entries(); while (entries.hasMoreElements()) { JarEntry entry = entries.nextElement(); final String name = entry.getName(); if (name.startsWith(internalPath)) { log.debug("Copying classpath resource(s) from {} to {} to permit Docker to bind", hostPath, tmpLocation); copyFromJarToLocation(jarFile, entry, internalPath, tmpLocation); } } } catch (IOException e) { throw new IllegalStateException("Failed to process JAR file when extracting classpath resource: " + hostPath, e); } // Mark temporary files/dirs for deletion at JVM shutdown deleteOnExit(tmpLocation.toPath()); return tmpLocation.getAbsolutePath(); }
/** * Obtains a {@link MountableFile} corresponding to a file on the docker host filesystem. * * @param path the path to the resource * @param mode octal value of posix file mode (000..777) * @return a {@link MountableFile} that may be used to obtain a mountable path */ public static MountableFile forHostPath(final Path path, Integer mode) { return new MountableFile(path.toAbsolutePath().toString(), mode); }
private String getResourcePath() { if (path.contains(".jar!")) { resourcePath = extractClassPathResourceToTempLocation(this.path); } else { resourcePath = unencodeResourceURIToFilePath(path); } return resourcePath; }
private File createTempDirectory() { try { if (SystemUtils.IS_OS_MAC) { return Files.createTempDirectory(Paths.get(OS_MAC_TMP_DIR), TESTCONTAINERS_TMP_DIR_PREFIX).toFile(); } return Files.createTempDirectory(TESTCONTAINERS_TMP_DIR_PREFIX).toFile(); } catch (IOException e) { return new File(TESTCONTAINERS_TMP_DIR_PREFIX + Base58.randomString(5)); } }
@SuppressWarnings("ResultOfMethodCallIgnored") private void copyFromJarToLocation(final JarFile jarFile, final JarEntry entry, final String fromRoot, final File toRoot) throws IOException { String destinationName = entry.getName().replaceFirst(fromRoot, ""); File newFile = new File(toRoot, destinationName); log.debug("Copying resource {} from JAR file {}", fromRoot, jarFile.getName()); if (!entry.isDirectory()) { // Create parent directories Path parent = newFile.getAbsoluteFile().toPath().getParent(); parent.toFile().mkdirs(); newFile.deleteOnExit(); try (InputStream is = jarFile.getInputStream(entry)) { Files.copy(is, newFile.toPath()); } catch (IOException e) { log.error("Failed to extract classpath resource " + entry.getName() + " from JAR file " + jarFile.getName(), e); throw e; } } }