Skip to content

Commit b637e28

Browse files
authored
Merge pull request docker-java#1043 from fengxx/bugfix/walk_dir
follow symbolic links when walking dir
2 parents 7a8ae34 + b1061c2 commit b637e28

File tree

3 files changed

+59
-11
lines changed

3 files changed

+59
-11
lines changed

src/main/java/com/github/dockerjava/core/util/CompressArchiveUtil.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.github.dockerjava.core.util;
22

33
import static com.github.dockerjava.core.util.FilePathUtil.relativize;
4+
import static java.nio.file.FileVisitOption.FOLLOW_LINKS;
45

56
import java.io.BufferedInputStream;
67
import java.io.BufferedOutputStream;
@@ -12,6 +13,7 @@
1213
import java.io.OutputStream;
1314
import java.nio.file.Files;
1415
import java.nio.file.Path;
16+
import java.util.EnumSet;
1517
import java.util.zip.GZIPOutputStream;
1618

1719
import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
@@ -78,7 +80,8 @@ public static void tar(Path inputPath, Path outputPath, boolean gZipped, boolean
7880
// In order to have the dossier as the root entry
7981
sourcePath = inputPath.getParent();
8082
}
81-
Files.walkFileTree(inputPath, new TarDirWalker(sourcePath, tarArchiveOutputStream));
83+
Files.walkFileTree(inputPath, EnumSet.of(FOLLOW_LINKS), Integer.MAX_VALUE,
84+
new TarDirWalker(sourcePath, tarArchiveOutputStream));
8285
}
8386
tarArchiveOutputStream.flush();
8487
}

src/main/java/com/github/dockerjava/core/util/TarDirWalker.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,12 @@ public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) th
3333

3434
@Override
3535
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
36+
if (attrs.isSymbolicLink()) { // symbolic link to folder
37+
return FileVisitResult.CONTINUE;
38+
}
3639
TarArchiveEntry tarEntry = new TarArchiveEntry(FilePathUtil.relativize(basePath, file));
3740
if (file.toFile().canExecute()) {
38-
tarEntry.setMode(tarEntry.getMode() | 0755);
41+
tarEntry.setMode(tarEntry.getMode() | 0755);
3942
}
4043
CompressArchiveUtil.putTarEntry(tarArchiveOutputStream, tarEntry, file);
4144
return FileVisitResult.CONTINUE;

src/test/java/com/github/dockerjava/core/CompressArchiveUtilTest.java

Lines changed: 51 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,11 @@
1212
import java.io.FileInputStream;
1313
import java.io.FileOutputStream;
1414
import java.io.IOException;
15+
import java.nio.file.Files;
16+
import java.nio.file.Path;
1517
import java.util.zip.GZIPInputStream;
1618

1719
import static java.util.Arrays.asList;
18-
import static org.hamcrest.CoreMatchers.equalTo;
1920
import static org.hamcrest.CoreMatchers.is;
2021
import static org.hamcrest.MatcherAssert.assertThat;
2122

@@ -26,9 +27,11 @@ public void testExecutableFlagIsPreserved() throws Exception {
2627
File executableFile = createExecutableFile();
2728
File archive = CompressArchiveUtil.archiveTARFiles(executableFile.getParentFile(), asList(executableFile),
2829
"archive");
29-
File expectedFile = extractFileByName(archive, "executableFile.sh.result");
30+
File expectedFile = extractFileByName(archive, "executableFile.sh", "executableFile.sh.result");
3031

3132
assertThat("should be executable", expectedFile.canExecute());
33+
expectedFile.delete();
34+
archive.delete();
3235
}
3336

3437
private File createExecutableFile() throws IOException {
@@ -40,25 +43,64 @@ private File createExecutableFile() throws IOException {
4043
return executableFile;
4144
}
4245

43-
private File extractFileByName(File archive, String filenameToExtract) throws IOException {
46+
private File extractFileByName(File archive, String filenameToExtract, String outputName) throws IOException {
4447
File baseDir = new File(FileUtils.getTempDirectoryPath());
45-
File expectedFile = new File(baseDir, filenameToExtract);
48+
File expectedFile = new File(baseDir, outputName);
4649
expectedFile.delete();
4750
assertThat(expectedFile.exists(), is(false));
4851

4952
TarArchiveInputStream tarArchiveInputStream = new TarArchiveInputStream(new GZIPInputStream(
5053
new BufferedInputStream(new FileInputStream(archive))));
5154
TarArchiveEntry entry;
55+
boolean found = false;
5256
while ((entry = tarArchiveInputStream.getNextTarEntry()) != null) {
5357
String individualFiles = entry.getName();
54-
// there should be only one file in this archive
55-
assertThat(individualFiles, equalTo("executableFile.sh"));
56-
IOUtils.copy(tarArchiveInputStream, new FileOutputStream(expectedFile));
57-
if ((entry.getMode() & 0755) == 0755) {
58-
expectedFile.setExecutable(true);
58+
if (individualFiles.equals(filenameToExtract) || individualFiles.endsWith("/" + filenameToExtract)) {
59+
found = true;
60+
IOUtils.copy(tarArchiveInputStream, new FileOutputStream(expectedFile));
61+
if ((entry.getMode() & 0755) == 0755) {
62+
expectedFile.setExecutable(true);
63+
}
64+
break;
5965
}
6066
}
67+
assertThat("should extracted the file", found);
6168
tarArchiveInputStream.close();
6269
return expectedFile;
6370
}
71+
72+
@Test
73+
public void testSymbolicLinkDir() throws IOException {
74+
Path uploadDir = Files.createTempDirectory("upload");
75+
Path linkTarget = Files.createTempDirectory("ink-target");
76+
Path tmpFile = Files.createTempFile(linkTarget, "link-dir", "rand");
77+
Files.createSymbolicLink(uploadDir.resolve("link-folder"), linkTarget);
78+
Path tarGzFile = Files.createTempFile("docker-java", ".tar.gz");
79+
//follow link only works for childrenOnly=false
80+
CompressArchiveUtil.tar(uploadDir, tarGzFile, true, false);
81+
File expectedFile = extractFileByName(tarGzFile.toFile(), tmpFile.toFile().getName(), "foo1");
82+
assertThat(expectedFile.canRead(), is(true));
83+
uploadDir.toFile().delete();
84+
linkTarget.toFile().delete();
85+
tarGzFile.toFile().delete();
86+
}
87+
88+
@Test
89+
public void testSymbolicLinkFile() throws IOException {
90+
Path uploadDir = Files.createTempDirectory("upload");
91+
Path tmpFile = Files.createTempFile("src", "");
92+
Files.createSymbolicLink(uploadDir.resolve("link-file"), tmpFile);
93+
Path tarGzFile = Files.createTempFile("docker-java", ".tar.gz");
94+
boolean childrenOnly = false;
95+
CompressArchiveUtil.tar(uploadDir, tarGzFile, true, childrenOnly);
96+
File expectedFile = extractFileByName(tarGzFile.toFile(), "link-file", "foo1");
97+
assertThat(expectedFile.canRead(), is(true));
98+
childrenOnly = true;
99+
CompressArchiveUtil.tar(uploadDir, tarGzFile, true, childrenOnly);
100+
extractFileByName(tarGzFile.toFile(), "link-file", "foo1");
101+
assertThat(expectedFile.canRead(), is(true));
102+
uploadDir.toFile().delete();
103+
tmpFile.toFile().delete();
104+
tarGzFile.toFile().delete();
105+
}
64106
}

0 commit comments

Comments
 (0)