diff options
-rw-r--r-- | docs/source/markdown/podman-cp.1.md | 2 | ||||
-rw-r--r-- | libpod/container_copy_linux.go | 6 | ||||
-rw-r--r-- | test/e2e/cp_test.go | 1 |
3 files changed, 8 insertions, 1 deletions
diff --git a/docs/source/markdown/podman-cp.1.md b/docs/source/markdown/podman-cp.1.md index 56511c244..bafbbdf3b 100644 --- a/docs/source/markdown/podman-cp.1.md +++ b/docs/source/markdown/podman-cp.1.md @@ -57,6 +57,8 @@ If you use a : in a local machine path, you must be explicit with a relative or Using `-` as the *src_path* streams the contents of STDIN as a tar archive. The command extracts the content of the tar to the *DEST_PATH* in the container. In this case, *dest_path* must specify a directory. Using `-` as the *dest_path* streams the contents of the resource (can be a directory) as a tar archive to STDOUT. +Note that `podman cp` ignores permission errors when copying from a running rootless container. The TTY devices inside a rootless container are owned by the host's root user and hence cannot be read inside the container's user namespace. + ## OPTIONS ## ALTERNATIVES diff --git a/libpod/container_copy_linux.go b/libpod/container_copy_linux.go index 66ccd2f1f..9dd7e7e9c 100644 --- a/libpod/container_copy_linux.go +++ b/libpod/container_copy_linux.go @@ -14,6 +14,7 @@ import ( "github.com/containers/buildah/pkg/chrootuser" "github.com/containers/buildah/util" "github.com/containers/podman/v3/libpod/define" + "github.com/containers/podman/v3/pkg/rootless" "github.com/containers/storage" "github.com/containers/storage/pkg/idtools" "github.com/docker/docker/pkg/archive" @@ -139,6 +140,11 @@ func (c *Container) copyToArchive(ctx context.Context, path string, writer io.Wr ChownDirs: idPair, ChownFiles: idPair, Excludes: []string{"dev", "proc", "sys"}, + // Ignore EPERMs when copying from rootless containers + // since we cannot read TTY devices. Those are owned + // by the host's root and hence "nobody" inside the + // container's user namespace. + IgnoreUnreadable: rootless.IsRootless() && c.state.State == define.ContainerStateRunning, } return c.joinMountAndExec(ctx, func() error { diff --git a/test/e2e/cp_test.go b/test/e2e/cp_test.go index c0fb61544..c0fb3f887 100644 --- a/test/e2e/cp_test.go +++ b/test/e2e/cp_test.go @@ -212,7 +212,6 @@ var _ = Describe("Podman cp", func() { // Copy the root dir "/" of a container to the host. It("podman cp the root directory from the ctr to an existing directory on the host ", func() { - SkipIfRootless("cannot copy tty devices in rootless mode") container := "copyroottohost" session := podmanTest.RunTopContainer(container) session.WaitWithDefaultTimeout() |