moby
moby copied to clipboard
`docker cp -a` doesn't preserve ownership information
Description
According to the documentation, docker cp -a
is supposed to copy files into or out of a container while preserving file & directory ownership information. It doesn't.
Steps to reproduce the issue:
- Container 'foobar-dev' has user 'scanner' with UID 1000
- Host machine has user 'scanner' with UID 1002 & user 'ec2-user' with UID 1000
Describe the results you received:
[foo@bar ~]$ sudo rm -rf save/mounted_keys/
[foo@bar ~]$ docker exec 'foobar-dev' ls -l '/etc/ssh/mounted_keys/'
total 24
-rw------- 1 scanner scanner 411 Jul 15 02:49 id_ed25519
-rw-r--r-- 1 scanner scanner 99 Jul 15 02:49 id_ed25519.pub
-rw------- 1 root root 411 Aug 4 22:36 id_ed25519_login
-rw-r--r-- 1 root root 99 Aug 4 22:36 id_ed25519_login.pub
-rw------- 1 root root 2602 Nov 13 2019 ssh_host_rsa_key
-rw-r--r-- 1 root root 571 Nov 13 2019 ssh_host_rsa_key.pub
[foo@bar ~]$ docker cp --archive 'foobar-dev:/etc/ssh/mounted_keys/' './save/'
[foo@bar ~]$ ls -la save/mounted_keys/
total 24
drwxr-xr-x 2 foo foo 150 Aug 4 18:53 .
drwxrwxr-x 8 foo foo 152 Nov 28 22:10 ..
-rw------- 1 foo foo 411 Jul 14 21:49 id_ed25519
-rw------- 1 foo foo 411 Aug 4 17:36 id_ed25519_login
-rw-r--r-- 1 foo foo 99 Aug 4 17:36 id_ed25519_login.pub
-rw-r--r-- 1 foo foo 99 Jul 14 21:49 id_ed25519.pub
-rw------- 1 foo foo 2602 Nov 13 2019 ssh_host_rsa_key
-rw-r--r-- 1 foo foo 571 Nov 13 2019 ssh_host_rsa_key.pub
[foo@bar ~]$ sudo chown scanner:scanner save/mounted_keys/id_ed25519
[foo@bar ~]$ sudo chown 1000:1000 save/mounted_keys/id_ed25519.pub
[foo@bar ~]$ ls -la save/mounted_keys/
total 24
drwxr-xr-x 2 foo foo 150 Aug 4 18:53 .
drwxrwxr-x 8 foo foo 152 Nov 28 22:10 ..
-rw------- 1 scanner scanner 411 Jul 14 21:49 id_ed25519
-rw------- 1 foo foo 411 Aug 4 17:36 id_ed25519_login
-rw-r--r-- 1 foo foo 99 Aug 4 17:36 id_ed25519_login.pub
-rw-r--r-- 1 ec2-user ec2-user 99 Jul 14 21:49 id_ed25519.pub
-rw------- 1 foo foo 2602 Nov 13 2019 ssh_host_rsa_key
-rw-r--r-- 1 foo foo 571 Nov 13 2019 ssh_host_rsa_key.pub
[foo@bar ~]$ sudo rm -rf save/mounted_keys/
[foo@bar ~]$ sudo docker cp --archive 'foobar-dev:/etc/ssh/mounted_keys/' './save/'
[foo@bar ~]$ ls -la save/mounted_keys/
total 24
drwxr-xr-x 2 root root 150 Aug 4 18:53 .
drwxrwxr-x 8 foo foo 152 Nov 28 22:13 ..
-rw------- 1 root root 411 Jul 14 21:49 id_ed25519
-rw------- 1 root root 411 Aug 4 17:36 id_ed25519_login
-rw-r--r-- 1 root root 99 Aug 4 17:36 id_ed25519_login.pub
-rw-r--r-- 1 root root 99 Jul 14 21:49 id_ed25519.pub
-rw------- 1 root root 2602 Nov 13 2019 ssh_host_rsa_key
-rw-r--r-- 1 root root 571 Nov 13 2019 ssh_host_rsa_key.pub
Describe the results you expected:
- Files
id_ed25519
andid_ed25519.pub
are created on the host owned by either user 'scanner' or user 'ec2-user', not owned by root. - If files cannot be created with the correct ownership (e.g. because the calling user doesn't have permission to perform the necessary
chown
) then a warning message will be emitted rather than failing silently
Output of docker version
:
Client:
Version: 18.06.1-ce
API version: 1.38
Go version: go1.10.3
Git commit: e68fc7a215d7133c34aa18e3b72b4a21fd0c6136
Built: Mon Jul 1 18:51:44 2019
OS/Arch: linux/amd64
Experimental: false
Server:
Engine:
Version: 18.06.1-ce
API version: 1.38 (minimum version 1.12)
Go version: go1.10.3
Git commit: e68fc7a/18.06.1-ce
Built: Mon Jul 1 18:53:20 2019
OS/Arch: linux/amd64
Experimental: false
Output of docker info
:
Containers: 13
Running: 12
Paused: 0
Stopped: 1
Images: 301
Server Version: 18.06.1-ce
Storage Driver: overlay2
Backing Filesystem: xfs
Supports d_type: true
Native Overlay Diff: true
Logging Driver: json-file
Cgroup Driver: cgroupfs
Plugins:
Volume: local
Network: bridge host macvlan null overlay
Log: awslogs fluentd gcplogs gelf journald json-file logentries splunk syslog
Swarm: inactive
Runtimes: runc
Default Runtime: runc
Init Binary: docker-init
containerd version: 468a545b9edcd5932818eb9de8e72413e616e86e
runc version: 69663f0bd4b60df09991c08812a60108003fa340
init version: fec3683
Security Options:
seccomp
Profile: default
Kernel Version: 4.14.88-88.76.amzn2.x86_64
Operating System: Amazon Linux 2
OSType: linux
Architecture: x86_64
CPUs: 1
Total Memory: 985.7MiB
Name: ssaas-dev-bastion-02
ID: DIIR:CQL2:BPRH:6SHK:EABX:UTTN:SGB7:SZ6B:PRDP:PMSU:PXWO:DHEQ
Docker Root Dir: /var/lib/docker
Debug Mode (client): false
Debug Mode (server): false
Registry: https://index.docker.io/v1/
Labels:
Experimental: false
Insecure Registries:
127.0.0.0/8
Live Restore Enabled: false
Hi @macdjord, I will like to help on this issue.
But can you state your reproducing steps clearer?
For example, docker cp --archive 'foobar-dev:/etc/ssh/mounted_keys/'
seems weird because it has no destination path.
From my testing, it seems that copying a file from container to the local machine will not preserve the ownership, but the opposite will (not shown below).
$ docker run -it —rm ubuntu:20.04 bash
root@3a7012ccb7a9:/# adduser haha
root@3a7012ccb7a9:/# touch test
root@3a7012ccb7a9:/# chown haha:haha test
root@3a7012ccb7a9:/# ls -al test
-rw-r--r-- 1 haha haha 0 Jan 10 14:41 test
$ docker cp 3a7012ccb7a9:/test ./
$ ls -al test
-rw-r--r-- 1 user user 0 一 10 22:41 test
Hi @macdjord, I will like to help on this issue. But can you state your reproducing steps clearer? For example,
docker cp --archive 'foobar-dev:/etc/ssh/mounted_keys/'
seems weird because it has no destination path.
You didn't copy the whole line:
[foo@bar ~]$ docker cp --archive 'foobar-dev:/etc/ssh/mounted_keys/' './save/'
From my testing, it seems that copying a file from container to the local machine will not preserve the ownership, but the opposite will (not shown below).
Well, that's a problem. -a
is supposed to "copy all uid/gid information", not just in one direction.
Also ran into this today. If you're going to not implement this, at the very minimum modify the docs.
As a workaround, you can use the tar stream output to fully preserve attributes, e.g.:
# docker cp container:src - | tar xf /dev/stdin -C dest
Same issue for me. Would expect files copied from container to preserve uid/gid, but they are all created under root instead.
any updates on this?
I ran into this problem too and looked at the source code. It seems to me the UID/GID are being overwritten here?
https://github.com/moby/moby/blob/b1c112d35e4f1921ca82c9f76d86e5c92c2a9280/pkg/archive/archive.go#L619-L623
When the --archive
option is used, containerExtractToDir
sets the tar
options: https://github.com/moby/moby/blob/3e4c9d90cf6a796334519f0de12ff09608d7abbe/daemon/archive_unix.go#L142-L150
tarCopyOptions
always sets ChownOpts
in UNIX: https://github.com/moby/moby/blob/3e4c9d90cf6a796334519f0de12ff09608d7abbe/daemon/archive_tarcopyoptions_unix.go#L21-L26
I think this was working in 2016 with 8a7ff5ff746a77e0be601c11540562341b2228c1, but possibly broken in 2017 with 8a34c67a7ec. https://github.com/moby/moby/pull/34590 has more context why this commit was introduced.
@thaJeztah I think you might have brought up a concern in https://github.com/moby/moby/issues/32816#issuecomment-298457178 related to this, but I'm still confused how all this is supposed to work. 😄