Skip to content

Commit 390ec49

Browse files
authored
Merge pull request #1218 from hugares/fix-tar-with-symlink
Fix tar with symlink
2 parents b6f44c6 + 5f7349f commit 390ec49

File tree

3 files changed

+25
-42
lines changed

3 files changed

+25
-42
lines changed

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

Lines changed: 24 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
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;
54

65
import java.io.BufferedInputStream;
76
import java.io.BufferedOutputStream;
@@ -13,7 +12,6 @@
1312
import java.io.OutputStream;
1413
import java.nio.file.Files;
1514
import java.nio.file.Path;
16-
import java.util.EnumSet;
1715
import java.util.zip.GZIPOutputStream;
1816

1917
import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
@@ -28,14 +26,26 @@ private CompressArchiveUtil() {
2826
// utility class
2927
}
3028

31-
static void putTarEntry(TarArchiveOutputStream tarOutputStream, TarArchiveEntry tarEntry, Path file)
29+
static void addFileToTar(TarArchiveOutputStream tarArchiveOutputStream, Path file, String entryName)
3230
throws IOException {
33-
tarEntry.setSize(Files.size(file));
34-
tarOutputStream.putArchiveEntry(tarEntry);
35-
try (InputStream input = new BufferedInputStream(Files.newInputStream(file))) {
36-
ByteStreams.copy(input, tarOutputStream);
37-
tarOutputStream.closeArchiveEntry();
31+
if (Files.isSymbolicLink(file)) {
32+
TarArchiveEntry tarArchiveEntry = new TarArchiveEntry(entryName, TarArchiveEntry.LF_SYMLINK);
33+
tarArchiveEntry.setLinkName(Files.readSymbolicLink(file).toString());
34+
tarArchiveOutputStream.putArchiveEntry(tarArchiveEntry);
35+
} else {
36+
TarArchiveEntry tarArchiveEntry = (TarArchiveEntry) tarArchiveOutputStream.createArchiveEntry(file.toFile(),
37+
entryName);
38+
if (file.toFile().canExecute()) {
39+
tarArchiveEntry.setMode(tarArchiveEntry.getMode() | 0755);
40+
}
41+
tarArchiveOutputStream.putArchiveEntry(tarArchiveEntry);
42+
if (file.toFile().isFile()) {
43+
try (InputStream input = new BufferedInputStream(Files.newInputStream(file))) {
44+
ByteStreams.copy(input, tarArchiveOutputStream);
45+
}
46+
}
3847
}
48+
tarArchiveOutputStream.closeArchiveEntry();
3949
}
4050

4151
private static TarArchiveOutputStream buildTarStream(Path outputPath, boolean gZipped) throws IOException {
@@ -69,19 +79,14 @@ public static void tar(Path inputPath, Path outputPath, boolean gZipped, boolean
6979

7080
try (TarArchiveOutputStream tarArchiveOutputStream = buildTarStream(outputPath, gZipped)) {
7181
if (!Files.isDirectory(inputPath)) {
72-
TarArchiveEntry tarEntry = new TarArchiveEntry(inputPath.getFileName().toString());
73-
if (inputPath.toFile().canExecute()) {
74-
tarEntry.setMode(tarEntry.getMode() | 0755);
75-
}
76-
putTarEntry(tarArchiveOutputStream, tarEntry, inputPath);
82+
addFileToTar(tarArchiveOutputStream, inputPath, inputPath.getFileName().toString());
7783
} else {
7884
Path sourcePath = inputPath;
7985
if (!childrenOnly) {
8086
// In order to have the dossier as the root entry
8187
sourcePath = inputPath.getParent();
8288
}
83-
Files.walkFileTree(inputPath, EnumSet.of(FOLLOW_LINKS), Integer.MAX_VALUE,
84-
new TarDirWalker(sourcePath, tarArchiveOutputStream));
89+
Files.walkFileTree(inputPath, new TarDirWalker(sourcePath, tarArchiveOutputStream));
8590
}
8691
tarArchiveOutputStream.flush();
8792
}
@@ -95,19 +100,10 @@ public static File archiveTARFiles(File base, Iterable<File> files, String archi
95100
new FileOutputStream(tarFile))))) {
96101
tos.setLongFileMode(TarArchiveOutputStream.LONGFILE_GNU);
97102
for (File file : files) {
98-
TarArchiveEntry tarEntry = new TarArchiveEntry(file);
99-
tarEntry.setName(relativize(base, file));
100-
101-
if (!file.isDirectory() && file.canExecute()) {
102-
tarEntry.setMode(tarEntry.getMode() | 0755);
103-
}
104-
105-
tos.putArchiveEntry(tarEntry);
106-
107-
if (!file.isDirectory()) {
108-
FileUtils.copyFile(file, tos);
109-
}
110-
tos.closeArchiveEntry();
103+
// relativize with method using Path otherwise method with File resolves the symlinks
104+
// and this is not want we want. If the file is a symlink, the relativized path should
105+
// keep the symlink name and not the target it points to.
106+
addFileToTar(tos, file.toPath(), relativize(base.toPath(), file.toPath()));
111107
}
112108
}
113109

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

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -33,14 +33,7 @@ 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-
}
39-
TarArchiveEntry tarEntry = new TarArchiveEntry(FilePathUtil.relativize(basePath, file));
40-
if (file.toFile().canExecute()) {
41-
tarEntry.setMode(tarEntry.getMode() | 0755);
42-
}
43-
CompressArchiveUtil.putTarEntry(tarArchiveOutputStream, tarEntry, file);
36+
CompressArchiveUtil.addFileToTar(tarArchiveOutputStream, file, FilePathUtil.relativize(basePath, file));
4437
return FileVisitResult.CONTINUE;
4538
}
4639

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

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
44
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
5-
import org.junit.Ignore;
65
import org.junit.Rule;
76
import org.junit.Test;
87
import org.junit.rules.TemporaryFolder;
@@ -69,7 +68,6 @@ public void tarWithExecutableFileAsInput() throws Exception {
6968
}
7069

7170
@Test
72-
@Ignore("Symlink creation is broken so test do not pass")
7371
public void tarWithSymbolicLinkFileAsInput() throws IOException {
7472
Path archiveSourceFile = tempFolder.getRoot().toPath().resolve("symlinkFile");
7573
Path linkTargetFile = tempFolder.newFile("link-target").toPath();
@@ -140,7 +138,6 @@ public void tarWithfolderAsInputAndNestedExecutableFile() throws Exception {
140138
}
141139

142140
@Test
143-
@Ignore("Symlink creation is broken so test do not pass")
144141
public void tarWithfolderAsInputAndNestedSymbolicLinkFile() throws Exception {
145142
Path archiveSourceDir = tempFolder.newFolder("archive-source").toPath();
146143
Path linkTargetFile = tempFolder.newFile("link-target").toPath();
@@ -162,7 +159,6 @@ public void tarWithfolderAsInputAndNestedSymbolicLinkFile() throws Exception {
162159
}
163160

164161
@Test
165-
@Ignore("Symlink creation is broken so test do not pass")
166162
public void tarWithfolderAsInputAndNestedSymbolicLinkDir() throws Exception {
167163
Path archiveSourceDir = tempFolder.newFolder("archive-source").toPath();
168164
Path linkTargetDir = tempFolder.newFolder("link-target").toPath();
@@ -207,7 +203,6 @@ public void archiveTARFilesWithExecutableFile() throws Exception {
207203
}
208204

209205
@Test
210-
@Ignore("Symlink creation is broken so test do not pass")
211206
public void archiveTARFilesWithSymbolicLinkFile() throws Exception {
212207
Path linkTargetFile = tempFolder.newFile("link-target").toPath();
213208
Path symlinkFile = tempFolder.getRoot().toPath().resolve("symlinkFile");
@@ -219,7 +214,6 @@ public void archiveTARFilesWithSymbolicLinkFile() throws Exception {
219214
}
220215

221216
@Test
222-
@Ignore("Symlink creation is broken so test do not pass")
223217
public void archiveTARFilesWithSymbolicLinkDir() throws Exception {
224218
Path linkTargetDir = tempFolder.newFolder("link-target").toPath();
225219
Path symlinkFile = tempFolder.getRoot().toPath().resolve("symlinkFile");

0 commit comments

Comments
 (0)