-
Notifications
You must be signed in to change notification settings - Fork 85
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
docker cp archive/tar error with filenames greater than 100 characters #484
Comments
ping @kolyshkin |
I am running into this issue in |
The problem is, docker daemon writes tar in PAX format, but since the reading side has to guess the format, and it mis-guesses it as USTAR. This issue is probably caused in I have a fix in progress... |
As reported in docker/for-linux/issues/484, since Docker 18.06 docker cp with a destination file name fails with the following error: > archive/tar: cannot encode header: Format specifies USTAR; and USTAR cannot encode Name="a_very_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx_long_filename_that_is_101_characters" The problem is caused by changes in Go 1.10 archive/tar, which mis-guesses the tar stream format as USTAR (rather than PAX), which, in turn, leads to inability to specify file names longer than 100 characters. This tar stream is sent by TarWithOptions() (which, since we switched to Go 1.10, explicitly sets format=PAX for every file, see FileInfoHeader(), and before Go 1.10 it was PAX by default). Unfortunately, the receiving side, RebaseArchiveEntries(), which calls tar.Next(), mistakenly guesses header format as USTAR, which leads to the above error. The fix is easy: set the format to PAX in RebaseArchiveEntries() where we read the tar stream and change the file name. A unit test is added to prevent future regressions. NOTE this code is not used by dockerd, but rather but docker cli (also possibly other clients), so this needs to be re-vendored to cli in order to take effect. Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
Proposed fix: moby/moby#38634 (note it needs to be merged to moby/moby first and then vendored to docker/cli in order to take effect). |
As reported in docker/for-linux/issues/484, since Docker 18.06 docker cp with a destination file name fails with the following error: > archive/tar: cannot encode header: Format specifies USTAR; and USTAR cannot encode Name="a_very_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx_long_filename_that_is_101_characters" The problem is caused by changes in Go 1.10 archive/tar, which mis-guesses the tar stream format as USTAR (rather than PAX), which, in turn, leads to inability to specify file names longer than 100 characters. This tar stream is sent by TarWithOptions() (which, since we switched to Go 1.10, explicitly sets format=PAX for every file, see FileInfoHeader(), and before Go 1.10 it was PAX by default). Unfortunately, the receiving side, RebaseArchiveEntries(), which calls tar.Next(), mistakenly guesses header format as USTAR, which leads to the above error. The fix is easy: set the format to PAX in RebaseArchiveEntries() where we read the tar stream and change the file name. A unit test is added to prevent future regressions. NOTE this code is not used by dockerd, but rather but docker cli (also possibly other clients), so this needs to be re-vendored to cli in order to take effect. Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com> Upstream-commit: f55a4176febbd0dffd6e5eb65beb70bc32912d0b Component: engine
As reported in docker/for-linux/issues/484, since Docker 18.06 docker cp with a destination file name fails with the following error: > archive/tar: cannot encode header: Format specifies USTAR; and USTAR cannot encode Name="a_very_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx_long_filename_that_is_101_characters" The problem is caused by changes in Go 1.10 archive/tar, which mis-guesses the tar stream format as USTAR (rather than PAX), which, in turn, leads to inability to specify file names longer than 100 characters. This tar stream is sent by TarWithOptions() (which, since we switched to Go 1.10, explicitly sets format=PAX for every file, see FileInfoHeader(), and before Go 1.10 it was PAX by default). Unfortunately, the receiving side, RebaseArchiveEntries(), which calls tar.Next(), mistakenly guesses header format as USTAR, which leads to the above error. The fix is easy: set the format to PAX in RebaseArchiveEntries() where we read the tar stream and change the file name. A unit test is added to prevent future regressions. NOTE this code is not used by dockerd, but rather but docker cli (also possibly other clients), so this needs to be re-vendored to cli in order to take effect. Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com> (cherry picked from commit f55a417) Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
As reported in docker/for-linux/issues/484, since Docker 18.06 docker cp with a destination file name fails with the following error: > archive/tar: cannot encode header: Format specifies USTAR; and USTAR cannot encode Name="a_very_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx_long_filename_that_is_101_characters" The problem is caused by changes in Go 1.10 archive/tar, which mis-guesses the tar stream format as USTAR (rather than PAX), which, in turn, leads to inability to specify file names longer than 100 characters. This tar stream is sent by TarWithOptions() (which, since we switched to Go 1.10, explicitly sets format=PAX for every file, see FileInfoHeader(), and before Go 1.10 it was PAX by default). Unfortunately, the receiving side, RebaseArchiveEntries(), which calls tar.Next(), mistakenly guesses header format as USTAR, which leads to the above error. The fix is easy: set the format to PAX in RebaseArchiveEntries() where we read the tar stream and change the file name. A unit test is added to prevent future regressions. NOTE this code is not used by dockerd, but rather but docker cli (also possibly other clients), so this needs to be re-vendored to cli in order to take effect. Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com> (cherry picked from commit f55a4176febbd0dffd6e5eb65beb70bc32912d0b) Signed-off-by: Sebastiaan van Stijn <github@gone.nl> Upstream-commit: 989e7f5d3a3f40ebb936376245b770f766ea42e9 Component: engine
relevant changes; - moby/moby#38006 / docker-archive/engine#114 client: use io.LimitedReader for reading HTTP error - moby/moby#38634 / docker-archive/engine#167 pkg/archive:CopyTo(): fix for long dest filename - fixes docker/for-linux#484 for 18.09 - moby/moby#38944 / docker-archive/engine#183 gitutils: add validation for ref - moby/moby#37780 / docker-archive/engine#55 pkg/progress: work around closing closed channel panic - addresses moby/moby#/37735 pkg/progress: panic due to race on shutdown Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
relevant changes; - moby/moby#38006 / docker-archive/engine#114 client: use io.LimitedReader for reading HTTP error - moby/moby#38634 / docker-archive/engine#167 pkg/archive:CopyTo(): fix for long dest filename - fixes docker/for-linux#484 for 18.09 - moby/moby#38944 / docker-archive/engine#183 gitutils: add validation for ref - moby/moby#37780 / docker-archive/engine#55 pkg/progress: work around closing closed channel panic - addresses moby/moby#/37735 pkg/progress: panic due to race on shutdown Signed-off-by: Sebastiaan van Stijn <github@gone.nl> Upstream-commit: 010c234a0d5a03d450ebec60be37dd9f279feeca Component: cli
As reported in docker/for-linux/issues/484, since Docker 18.06 docker cp with a destination file name fails with the following error: > archive/tar: cannot encode header: Format specifies USTAR; and USTAR cannot encode Name="a_very_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx_long_filename_that_is_101_characters" The problem is caused by changes in Go 1.10 archive/tar, which mis-guesses the tar stream format as USTAR (rather than PAX), which, in turn, leads to inability to specify file names longer than 100 characters. This tar stream is sent by TarWithOptions() (which, since we switched to Go 1.10, explicitly sets format=PAX for every file, see FileInfoHeader(), and before Go 1.10 it was PAX by default). Unfortunately, the receiving side, RebaseArchiveEntries(), which calls tar.Next(), mistakenly guesses header format as USTAR, which leads to the above error. The fix is easy: set the format to PAX in RebaseArchiveEntries() where we read the tar stream and change the file name. A unit test is added to prevent future regressions. NOTE this code is not used by dockerd, but rather but docker cli (also possibly other clients), so this needs to be re-vendored to cli in order to take effect. Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
Assuming this issue is fixed in later docker version, could someone please share the version which solves this issue. |
Yes this is fixed; $ docker run -d -i --name docker_test alpine
$ docker cp docker_test:/etc/resolv.conf a_very_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx_long_filename_that_is_100_characters
$ docker cp docker_test:/etc/resolv.conf a_very_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx_long_filename_that_is_101_characters
$ ls a_very_*
a_very_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx_long_filename_that_is_100_characters
a_very_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx_long_filename_that_is_101_characters
It's included in Docker 18.09.4 and up; docker-archive/engine#167 / docker/cli#1778 |
Expected behavior
Using
docker cp
should copy files and directories from container to host with filenames greater than 100 characters for Docker version 18.06.1-ce and higher.Actual behavior
Using
docker cp container_name:/etc/resolv.conf a_very_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx_long_filename_that_is_101_characters
in 18.03.1-ce works but results in the error below on 18.06.1-ce and higher.Steps to reproduce the behavior
Output of
docker version
:Additional environment details (AWS, VirtualBox, physical, etc.)
I was able to reproduce the issue in Docker 18.06.1-ce and 18.09.0-ce but not in Docker 18.03.1-ce. The commands below can reproduce the issue. I reproduced the issue using CentOS 7.5 and Amazon Linux 2 hosts. I then used Vagrant to confirm the issue locally.
It appears a change to Golang v1.10 may have changed the default archive/tar format to USTAR which has a 100 character Linkname limit.
https://golang.org/doc/go1.10#archive/tar
https://golang.org/pkg/archive/tar/#Format
The text was updated successfully, but these errors were encountered: