Skip to content

Commit aa28983

Browse files
authored
generator: Handle symlinks when copying from a container (#90)
`docker cp` tries to avoid creating simlinks which would break out of the directory it is creating. In #88, when copying `/usr/lib/x86_64-linux-gnu` from a running container, a symlink pointing back 4 layers is rejected: invalid symlink: <dest>/usr/lib/x86_64-linux-gnu/hdf5/serial/include" -> "../../../../include/hdf5/serial" The intended target of the symlink is in `<dest>/usr/include` which is outside the path being copied. The error message is generated here: https://github.com/moby/moby/blob/dd146571ea458082c499c647ba36580bb7277131/pkg/archive/archive.go#L753 Symlinks which point inside the directory tree being copied do not cause errors: <dest>/usr/lib/x86_64-linux-gnu/libxcb-render.so.0 -> libxcb-render.so.0.0.0 The "hdf5 include" error does not occur if we copy the whole of the `/usr` directory from the container, making the symlink no longer break out of the copied directory: % docker cp <container>:/usr <dest> Successfully copied 3.24GB to <dest> This commit avoids the error by asking `docker cp' to print a 'tar' stream to standard output and piping it to a local `tar` process. The local `tar` does not complain about creating potential dangling symlinks. The performance of piping to 'tar' should be similar to using "normal" `docker cp` because `dockerd` always sends a `tar` stream to the `docker` CLI. In the normal case, `docker cp` unarchives the `tar` stream, using the library which checks for symlinks which break out of the tree. In the "tar stream" case, `docker cp` just prints the stream to standard output. Co-authored-by: @t089 Fixes #88
1 parent e40e1fb commit aa28983

File tree

2 files changed

+2
-2
lines changed

2 files changed

+2
-2
lines changed

Sources/SwiftSDKGenerator/Generator/SwiftSDKGenerator+Copy.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ extension SwiftSDKGenerator {
1818
try await withDockerContainer(fromImage: baseDockerImage) { containerID in
1919
try await inTemporaryDirectory { generator, _ in
2020
let sdkUsrPath = sdkDirPath.appending("usr")
21-
let sdkUsrLibPath = sdkUsrPath.appending("lib")
2221
try await generator.createDirectoryIfNeeded(at: sdkUsrPath)
2322
try await generator.copyFromDockerContainer(
2423
id: containerID,
@@ -57,6 +56,7 @@ extension SwiftSDKGenerator {
5756
try await createSymlink(at: sdkDirPath.appending("lib64"), pointingTo: "./usr/lib64")
5857
}
5958

59+
let sdkUsrLibPath = sdkUsrPath.appending("lib")
6060
try await generator.createDirectoryIfNeeded(at: sdkUsrLibPath)
6161
var subpaths: [(subpath: String, failIfNotExists: Bool)] = [
6262
("clang", true), ("gcc", true), ("swift", true), ("swift_static", true)

Sources/SwiftSDKGenerator/Generator/SwiftSDKGenerator.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ public actor SwiftSDKGenerator {
122122
else { return }
123123
}
124124
try await Shell.run(
125-
"\(Self.dockerCommand) cp \(id):\(containerPath) \(localPath)",
125+
"\(Self.dockerCommand) cp \(id):\(containerPath) - | tar x -C \(localPath.removingLastComponent())",
126126
shouldLogCommands: self.isVerbose
127127
)
128128
}

0 commit comments

Comments
 (0)