diff --git a/libpod/container_internal.go b/libpod/container_internal.go index ac96a43f1d..a5f8f39a1e 100644 --- a/libpod/container_internal.go +++ b/libpod/container_internal.go @@ -1922,6 +1922,11 @@ func (c *Container) mountNamedVolume(v *ContainerNamedVolume, mountpoint string) getOptions := copier.GetOptions{ KeepDirectoryNames: false, } + // If the volume is idmapped, we need to "undo" the idmapping + if slices.Contains(v.Options, "idmap") { + getOptions.UIDMap = c.config.IDMappings.UIDMap + getOptions.GIDMap = c.config.IDMappings.GIDMap + } errChan <- copier.Get(srcDir, "", getOptions, []string{"/."}, writer) }() @@ -1929,6 +1934,8 @@ func (c *Container) mountNamedVolume(v *ContainerNamedVolume, mountpoint string) // the volume. copyOpts := copier.PutOptions{} if err := copier.Put(volMount, "", copyOpts, reader); err != nil { + // consume the reader otherwise the goroutine will block + _, _ = io.Copy(io.Discard, reader) err2 := <-errChan if err2 != nil { logrus.Errorf("Streaming contents of container %s directory for volume copy-up: %v", c.ID(), err2) diff --git a/test/system/030-run.bats b/test/system/030-run.bats index 6f56857219..ec788642b9 100644 --- a/test/system/030-run.bats +++ b/test/system/030-run.bats @@ -1232,7 +1232,7 @@ EOF fi } -@test "podman run - rootfs with idmapped mounts" { +@test "podman run - idmapped mounts" { skip_if_rootless "idmapped mounts work only with root for now" skip_if_remote "userns=auto is set on the server" @@ -1280,6 +1280,12 @@ EOF is "$output" "0:0" run_podman volume rm $myvolume + # verify that copyup with an idmap volume maintains the original ownership + myvolume=my-volume-$(safename) + run_podman run --rm --uidmap=0:1000:10000 -v $myvolume:/etc:idmap $IMAGE stat -c %u:%g /etc/passwd + is "$output" "0:0" + run_podman volume rm $myvolume + rm -rf $romount }