Revert "Fix copyUIDGID parameter inversion in Docker compat API"

This reverts commit 2b848cca36.

The official Docker API documentation was misleading here.
Testing shown that old podman behaviour was correct.
In docker copyUIDGID=true means that primary container uid/gid is used,
not the uid/gid from the tar stream.

Signed-off-by: Matej Vašek <matejvasek@gmail.com>
This commit is contained in:
Matej Vašek
2025-11-13 22:45:17 +01:00
parent d3c5c5d219
commit 65411d53c9
3 changed files with 4 additions and 51 deletions

View File

@@ -123,17 +123,9 @@ func handlePut(w http.ResponseWriter, r *http.Request, decoder *schema.Decoder,
containerName := utils.GetName(r) containerName := utils.GetName(r)
containerEngine := abi.ContainerEngine{Libpod: runtime} 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, copyFunc, err := containerEngine.ContainerCopyFromArchive(r.Context(), containerName, query.Path, r.Body,
entities.CopyOptions{ entities.CopyOptions{
Chown: chown, Chown: query.Chown,
NoOverwriteDirNonDir: query.NoOverwriteDirNonDir, NoOverwriteDirNonDir: query.NoOverwriteDirNonDir,
Rename: rename, Rename: rename,
}) })

View File

@@ -40,7 +40,7 @@ t HEAD "containers/${CTR}/archive?path=%2Fnon%2Fexistent%2Fpath" 404
t HEAD "containers/${CTR}/archive?path=%2Fetc%2Fpasswd" 200 t HEAD "containers/${CTR}/archive?path=%2Fetc%2Fpasswd" 200
# Send tarfile to container... # Send tarfile to container...
t PUT "/containers/${CTR}/archive?path=%2Ftmp%2F&copyUIDGID=true" ${HELLO_TAR} 200 '' t PUT "/containers/${CTR}/archive?path=%2Ftmp%2F" ${HELLO_TAR} 200 ''
# ...and 'exec cat file' to confirm that it got extracted into place. # ...and 'exec cat file' to confirm that it got extracted into place.
cat >$TMPD/exec.json <<EOF cat >$TMPD/exec.json <<EOF
@@ -80,44 +80,6 @@ EOF
t POST containers/${CTR}/exec $TMPD/exec.json 201 .Id~[0-9a-f]\\{64\\} t POST containers/${CTR}/exec $TMPD/exec.json 201 .Id~[0-9a-f]\\{64\\}
eid=$(jq -r '.Id' <<<"$output") eid=$(jq -r '.Id' <<<"$output")
t POST exec/$eid/start 200 t POST exec/$eid/start 200 $'\001\012'1042:1043
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 cleanUpArchiveTest

View File

@@ -191,8 +191,7 @@ class TestContainers(common.DockerTestCase):
ret, out = ctr.exec_run(["stat", "-c", "%u:%g", "/tmp/a.txt"]) ret, out = ctr.exec_run(["stat", "-c", "%u:%g", "/tmp/a.txt"])
self.assertEqual(ret, 0) self.assertEqual(ret, 0)
# Docker-py implementation of put_archive dont do request with copyUIDGID=true self.assertEqual(out.rstrip(), b"1042:1043", "UID/GID of copied file")
self.assertEqual(out.rstrip(), b"0:0", "UID/GID of copied file")
ret, out = ctr.exec_run(["cat", "/tmp/a.txt"]) ret, out = ctr.exec_run(["cat", "/tmp/a.txt"])
self.assertEqual(ret, 0) self.assertEqual(ret, 0)