Skip to content

Commit 23e6a89

Browse files
Merge pull request #27379 from Honny1/fix-copyuidguid
Fix copyUIDGID parameter inversion in Docker compat API
2 parents 2b646e7 + 2b848cc commit 23e6a89

File tree

3 files changed

+51
-4
lines changed

3 files changed

+51
-4
lines changed

pkg/api/handlers/compat/containers_archive.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,9 +124,17 @@ func handlePut(w http.ResponseWriter, r *http.Request, decoder *schema.Decoder,
124124
containerName := utils.GetName(r)
125125
containerEngine := abi.ContainerEngine{Libpod: runtime}
126126

127+
// Docker API semantics: copyUIDGID=true means "preserve UID/GID from archive"
128+
// Podman internal semantics: Chown=true means "chown to container user" (override archive)
129+
// For compat requests, we need to invert the value
130+
chown := query.Chown
131+
if !utils.IsLibpodRequest(r) {
132+
chown = !query.Chown
133+
}
134+
127135
copyFunc, err := containerEngine.ContainerCopyFromArchive(r.Context(), containerName, query.Path, r.Body,
128136
entities.CopyOptions{
129-
Chown: query.Chown,
137+
Chown: chown,
130138
NoOverwriteDirNonDir: query.NoOverwriteDirNonDir,
131139
Rename: rename,
132140
})

test/apiv2/23-containersArchive.at

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ t HEAD "containers/${CTR}/archive?path=%2Fnon%2Fexistent%2Fpath" 404
4040
t HEAD "containers/${CTR}/archive?path=%2Fetc%2Fpasswd" 200
4141

4242
# Send tarfile to container...
43-
t PUT "/containers/${CTR}/archive?path=%2Ftmp%2F" ${HELLO_TAR} 200 ''
43+
t PUT "/containers/${CTR}/archive?path=%2Ftmp%2F&copyUIDGID=true" ${HELLO_TAR} 200 ''
4444

4545
# ...and 'exec cat file' to confirm that it got extracted into place.
4646
cat >$TMPD/exec.json <<EOF
@@ -80,6 +80,44 @@ EOF
8080

8181
t POST containers/${CTR}/exec $TMPD/exec.json 201 .Id~[0-9a-f]\\{64\\}
8282
eid=$(jq -r '.Id' <<<"$output")
83-
t POST exec/$eid/start 200 $'\001\012'1042:1043
83+
t POST exec/$eid/start 200
84+
85+
output_uidgid=$(grep -o '[0-9]*:[0-9]*' <<<"$output")
86+
is "$output_uidgid" "1042:1043" "UID:GID preserved with copyUIDGID=true"
87+
88+
89+
FILE_NAME=test1
90+
TAR_PATH="${TMPD}/${FILE_NAME}.tar"
91+
echo "Hello2_$(random_string 8)" > ${TMPD}/${FILE_NAME}.txt
92+
tar --owner=2001 --group=2002 --format=posix -C $TMPD -cvf ${TAR_PATH} ${FILE_NAME}.txt &> /dev/null
93+
94+
t PUT "/containers/${CTR}/archive?path=%2Ftmp%2F" ${TAR_PATH} 200 ''
95+
96+
cat >$TMPD/exec.json <<EOF
97+
{ "AttachStdout":true,"Cmd":["stat","-c","%u:%g","/tmp/${FILE_NAME}.txt"]}
98+
EOF
99+
t POST containers/${CTR}/exec $TMPD/exec.json 201 .Id~[0-9a-f]\\{64\\}
100+
eid=$(jq -r '.Id' <<<"$output")
101+
t POST exec/$eid/start 200
102+
103+
output_uidgid=$(grep -o '[0-9]*:[0-9]*' <<<"$output")
104+
is "$output_uidgid" "0:0" "UID:GID chowned to container user without copyUIDGID"
105+
106+
# --- libpod
107+
FILE_NAME=test3
108+
TAR_PATH="${TMPD}/${FILE_NAME}.tar"
109+
echo "test3_$(random_string 8)" > ${TMPD}/${FILE_NAME}.txt
110+
tar --owner=4001 --group=4002 --format=posix -C $TMPD -cvf ${TAR_PATH} ${FILE_NAME}.txt &> /dev/null
111+
t PUT "libpod/containers/${CTR}/archive?path=%2Ftmp%2F" ${TAR_PATH} 200 ''
112+
113+
cat >$TMPD/exec.json <<EOF
114+
{ "AttachStdout":true,"Cmd":["stat","-c","%u:%g","/tmp/${FILE_NAME}.txt"]}
115+
EOF
116+
t POST containers/${CTR}/exec $TMPD/exec.json 201 .Id~[0-9a-f]\\{64\\}
117+
eid=$(jq -r '.Id' <<<"$output")
118+
t POST exec/$eid/start 200
119+
120+
output_uidgid=$(grep -o '[0-9]*:[0-9]*' <<<"$output")
121+
is "$output_uidgid" "0:0" "libpod API: UID:GID chowned to container user"
84122

85123
cleanUpArchiveTest

test/python/docker/compat/test_containers.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,8 @@ def test_copy_to_container(self):
191191
ret, out = ctr.exec_run(["stat", "-c", "%u:%g", "/tmp/a.txt"])
192192

193193
self.assertEqual(ret, 0)
194-
self.assertEqual(out.rstrip(), b"1042:1043", "UID/GID of copied file")
194+
# Docker-py implementation of put_archive dont do request with copyUIDGID=true
195+
self.assertEqual(out.rstrip(), b"0:0", "UID/GID of copied file")
195196

196197
ret, out = ctr.exec_run(["cat", "/tmp/a.txt"])
197198
self.assertEqual(ret, 0)

0 commit comments

Comments
 (0)