mirror of
https://github.com/containers/podman.git
synced 2025-11-28 09:09:44 +08:00
Fix copyUIDGID parameter inversion in Docker compat API
Docker API's copyUIDGID=true means "preserve UID/GID from archive" but Podman's internal Chown=true means "chown to container user". This caused Docker SDK clients to have files incorrectly chowned to root:root instead of preserving the archive's UID/GID. Fixes: https://github.com/containers/podman/issues/27332 Fixes: https://issues.redhat.com/browse/RUN-3643 Signed-off-by: Jan Rodák <hony.com@seznam.cz>
This commit is contained in:
@@ -124,9 +124,17 @@ func handlePut(w http.ResponseWriter, r *http.Request, decoder *schema.Decoder,
|
||||
containerName := utils.GetName(r)
|
||||
containerEngine := abi.ContainerEngine{Libpod: runtime}
|
||||
|
||||
// Docker API semantics: copyUIDGID=true means "preserve UID/GID from archive"
|
||||
// Podman internal semantics: Chown=true means "chown to container user" (override archive)
|
||||
// For compat requests, we need to invert the value
|
||||
chown := query.Chown
|
||||
if !utils.IsLibpodRequest(r) {
|
||||
chown = !query.Chown
|
||||
}
|
||||
|
||||
copyFunc, err := containerEngine.ContainerCopyFromArchive(r.Context(), containerName, query.Path, r.Body,
|
||||
entities.CopyOptions{
|
||||
Chown: query.Chown,
|
||||
Chown: chown,
|
||||
NoOverwriteDirNonDir: query.NoOverwriteDirNonDir,
|
||||
Rename: rename,
|
||||
})
|
||||
|
||||
@@ -40,7 +40,7 @@ t HEAD "containers/${CTR}/archive?path=%2Fnon%2Fexistent%2Fpath" 404
|
||||
t HEAD "containers/${CTR}/archive?path=%2Fetc%2Fpasswd" 200
|
||||
|
||||
# Send tarfile to container...
|
||||
t PUT "/containers/${CTR}/archive?path=%2Ftmp%2F" ${HELLO_TAR} 200 ''
|
||||
t PUT "/containers/${CTR}/archive?path=%2Ftmp%2F©UIDGID=true" ${HELLO_TAR} 200 ''
|
||||
|
||||
# ...and 'exec cat file' to confirm that it got extracted into place.
|
||||
cat >$TMPD/exec.json <<EOF
|
||||
@@ -80,6 +80,44 @@ EOF
|
||||
|
||||
t POST containers/${CTR}/exec $TMPD/exec.json 201 .Id~[0-9a-f]\\{64\\}
|
||||
eid=$(jq -r '.Id' <<<"$output")
|
||||
t POST exec/$eid/start 200 $'\001\012'1042:1043
|
||||
t POST exec/$eid/start 200
|
||||
|
||||
output_uidgid=$(grep -o '[0-9]*:[0-9]*' <<<"$output")
|
||||
is "$output_uidgid" "1042:1043" "UID:GID preserved with copyUIDGID=true"
|
||||
|
||||
|
||||
FILE_NAME=test1
|
||||
TAR_PATH="${TMPD}/${FILE_NAME}.tar"
|
||||
echo "Hello2_$(random_string 8)" > ${TMPD}/${FILE_NAME}.txt
|
||||
tar --owner=2001 --group=2002 --format=posix -C $TMPD -cvf ${TAR_PATH} ${FILE_NAME}.txt &> /dev/null
|
||||
|
||||
t PUT "/containers/${CTR}/archive?path=%2Ftmp%2F" ${TAR_PATH} 200 ''
|
||||
|
||||
cat >$TMPD/exec.json <<EOF
|
||||
{ "AttachStdout":true,"Cmd":["stat","-c","%u:%g","/tmp/${FILE_NAME}.txt"]}
|
||||
EOF
|
||||
t POST containers/${CTR}/exec $TMPD/exec.json 201 .Id~[0-9a-f]\\{64\\}
|
||||
eid=$(jq -r '.Id' <<<"$output")
|
||||
t POST exec/$eid/start 200
|
||||
|
||||
output_uidgid=$(grep -o '[0-9]*:[0-9]*' <<<"$output")
|
||||
is "$output_uidgid" "0:0" "UID:GID chowned to container user without copyUIDGID"
|
||||
|
||||
# --- libpod
|
||||
FILE_NAME=test3
|
||||
TAR_PATH="${TMPD}/${FILE_NAME}.tar"
|
||||
echo "test3_$(random_string 8)" > ${TMPD}/${FILE_NAME}.txt
|
||||
tar --owner=4001 --group=4002 --format=posix -C $TMPD -cvf ${TAR_PATH} ${FILE_NAME}.txt &> /dev/null
|
||||
t PUT "libpod/containers/${CTR}/archive?path=%2Ftmp%2F" ${TAR_PATH} 200 ''
|
||||
|
||||
cat >$TMPD/exec.json <<EOF
|
||||
{ "AttachStdout":true,"Cmd":["stat","-c","%u:%g","/tmp/${FILE_NAME}.txt"]}
|
||||
EOF
|
||||
t POST containers/${CTR}/exec $TMPD/exec.json 201 .Id~[0-9a-f]\\{64\\}
|
||||
eid=$(jq -r '.Id' <<<"$output")
|
||||
t POST exec/$eid/start 200
|
||||
|
||||
output_uidgid=$(grep -o '[0-9]*:[0-9]*' <<<"$output")
|
||||
is "$output_uidgid" "0:0" "libpod API: UID:GID chowned to container user"
|
||||
|
||||
cleanUpArchiveTest
|
||||
|
||||
@@ -191,7 +191,8 @@ class TestContainers(common.DockerTestCase):
|
||||
ret, out = ctr.exec_run(["stat", "-c", "%u:%g", "/tmp/a.txt"])
|
||||
|
||||
self.assertEqual(ret, 0)
|
||||
self.assertEqual(out.rstrip(), b"1042:1043", "UID/GID of copied file")
|
||||
# Docker-py implementation of put_archive dont do request with copyUIDGID=true
|
||||
self.assertEqual(out.rstrip(), b"0:0", "UID/GID of copied file")
|
||||
|
||||
ret, out = ctr.exec_run(["cat", "/tmp/a.txt"])
|
||||
self.assertEqual(ret, 0)
|
||||
|
||||
Reference in New Issue
Block a user