Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error building with docker #88

Closed
t089 opened this issue Mar 16, 2024 · 1 comment · Fixed by #90
Closed

Error building with docker #88

t089 opened this issue Mar 16, 2024 · 1 comment · Fixed by #90
Assignees

Comments

@t089
Copy link

t089 commented Mar 16, 2024

I am trying to build a SDK that includes libvips:

I created an image:

$ cat Dockerfile
FROM swift:5.10-jammy                                                                                                                                 
RUN apt update && apt -y install libvips libvips-dev && apt -y clean

$ docker build -t swift-5.10-vips --platform linux/amd64 -f Dockerfile .

Then, using the SDK generator:

$ swift run swift-sdk-generator make-linux-sdk \
       --target x86_64-unknown-linux-gnu \
       --swift-version 5.10-RELEASE \
       --with-docker \
       --from-container-image swift-5.10-vips:latest \
       --sdk-name 5.10-RELEASE_ubuntu_jammy_x86_64_vips -v

Fails with:

Launching a Docker container to copy Swift SDK for the target triple from it...
docker run --rm --platform=linux/amd64 -d swift-5.10-vips:latest tail -f /dev/null
docker cp 1c481dc1bea5304a25eebc0f923c625610732380570ae0b6668d320e7966dcb6:/usr/include /Users/tobias/Developing/swift-sdk-generator/Bundles/5.10-RELEASE_ubuntu_jammy_x86_64_vips.artifactbundle/5.10-RELEASE_ubuntu_jammy_x86_64_vips/x86_64-unknown-linux-gnu/ubuntu-jammy.sdk/usr/include
docker exec 1c481dc1bea5304a25eebc0f923c625610732380570ae0b6668d320e7966dcb6 sh -c 'test -e "/usr/lib64" && echo "y" || echo "n"'
docker cp 1c481dc1bea5304a25eebc0f923c625610732380570ae0b6668d320e7966dcb6:/usr/lib64 /Users/tobias/Developing/swift-sdk-generator/Bundles/5.10-RELEASE_ubuntu_jammy_x86_64_vips.artifactbundle/5.10-RELEASE_ubuntu_jammy_x86_64_vips/x86_64-unknown-linux-gnu/ubuntu-jammy.sdk/usr/lib64
docker cp 1c481dc1bea5304a25eebc0f923c625610732380570ae0b6668d320e7966dcb6:/usr/lib/clang /Users/tobias/Developing/swift-sdk-generator/Bundles/5.10-RELEASE_ubuntu_jammy_x86_64_vips.artifactbundle/5.10-RELEASE_ubuntu_jammy_x86_64_vips/x86_64-unknown-linux-gnu/ubuntu-jammy.sdk/usr/lib/clang
docker cp 1c481dc1bea5304a25eebc0f923c625610732380570ae0b6668d320e7966dcb6:/usr/lib/gcc /Users/tobias/Developing/swift-sdk-generator/Bundles/5.10-RELEASE_ubuntu_jammy_x86_64_vips.artifactbundle/5.10-RELEASE_ubuntu_jammy_x86_64_vips/x86_64-unknown-linux-gnu/ubuntu-jammy.sdk/usr/lib/gcc
docker cp 1c481dc1bea5304a25eebc0f923c625610732380570ae0b6668d320e7966dcb6:/usr/lib/swift /Users/tobias/Developing/swift-sdk-generator/Bundles/5.10-RELEASE_ubuntu_jammy_x86_64_vips.artifactbundle/5.10-RELEASE_ubuntu_jammy_x86_64_vips/x86_64-unknown-linux-gnu/ubuntu-jammy.sdk/usr/lib/swift
docker cp 1c481dc1bea5304a25eebc0f923c625610732380570ae0b6668d320e7966dcb6:/usr/lib/swift_static /Users/tobias/Developing/swift-sdk-generator/Bundles/5.10-RELEASE_ubuntu_jammy_x86_64_vips.artifactbundle/5.10-RELEASE_ubuntu_jammy_x86_64_vips/x86_64-unknown-linux-gnu/ubuntu-jammy.sdk/usr/lib/swift_static
docker exec 1c481dc1bea5304a25eebc0f923c625610732380570ae0b6668d320e7966dcb6 sh -c 'test -e "/usr/lib/x86_64-linux-gnu" && echo "y" || echo "n"'
docker cp 1c481dc1bea5304a25eebc0f923c625610732380570ae0b6668d320e7966dcb6:/usr/lib/x86_64-linux-gnu /Users/tobias/Developing/swift-sdk-generator/Bundles/5.10-RELEASE_ubuntu_jammy_x86_64_vips.artifactbundle/5.10-RELEASE_ubuntu_jammy_x86_64_vips/x86_64-unknown-linux-gnu/ubuntu-jammy.sdk/usr/lib/x86_64-linux-gnu
invalid symlink "/Users/tobias/Developing/swift-sdk-generator/Bundles/5.10-RELEASE_ubuntu_jammy_x86_64_vips.artifactbundle/5.10-RELEASE_ubuntu_jammy_x86_64_vips/x86_64-unknown-linux-gnu/ubuntu-jammy.sdk/usr/lib/x86_64-linux-gnu/hdf5/serial/include" -> "../../../../include/hdf5/serial"
docker stop 1c481dc1bea5304a25eebc0f923c625610732380570ae0b6668d320e7966dcb6
Error: Process launched with CommandInfo(command: "docker cp 1c481dc1bea5304a25eebc0f923c625610732380570ae0b6668d320e7966dcb6:/usr/lib/x86_64-linux-gnu /Users/tobias/Developing/swift-sdk-generator/Bundles/5.10-RELEASE_ubuntu_jammy_x86_64_vips.artifactbundle/5.10-RELEASE_ubuntu_jammy_x86_64_vips/x86_64-unknown-linux-gnu/ubuntu-jammy.sdk/usr/lib/x86_64-linux-gnu", file: "/Users/tobias/Developing/swift-sdk-generator/Sources/SwiftSDKGenerator/Generator/SwiftSDKGenerator.swift", line: 124) failed with exit code 1
@t089
Copy link
Author

t089 commented Mar 17, 2024

Found a workaround. Seems like docker cp does not like symlinks in the SOURCE_DIR. But there exists a workaround: piping the copy to tar:

docker cp CONTAINER:/path/in/container - | tar xC $(dirname /path/in/host)

Changing copyFromDockerContainer, the command succeeds.

 func copyFromDockerContainer(
    id: String,
    from containerPath: FilePath,
    to localPath: FilePath,
    failIfNotExists: Bool = true
  ) async throws {
    if !failIfNotExists {
      guard try await doesPathExist(containerPath, inContainer: id)
      else { return }
    }
    try await Shell.run(
      "\(Self.dockerCommand) cp \(id):\(containerPath) - | tar xC $(dirname \(localPath))",
      shouldLogCommands: self.isVerbose
    )
  }

@euanh euanh self-assigned this Mar 18, 2024
euanh added a commit to euanh/swift-sdk-generator that referenced this issue Mar 19, 2024
`docker cp` tries to avoid creating simlinks which would break out
of the directory it is creating.   In apple#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 apple#88
@euanh euanh closed this as completed in #90 Mar 19, 2024
euanh added a commit that referenced this issue Mar 19, 2024
`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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants