Skip to content

Commit

Permalink
Match output of Compat Top API to Docker
Browse files Browse the repository at this point in the history
We were only splitting on tabs, not spaces, so we returned just a
single line most of the time, not an array of the fields in the
output of `ps`. Unfortunately, some of these fields are allowed
to contain spaces themselves, which makes things complicated, but
we got lucky in that Docker took the simplest possible solution
and just assumed that only one field would contain spaces and it
would always be the last one, which is easy enough to duplicate
on our end.

Fixes #23981

Signed-off-by: Matt Heon <[email protected]>
  • Loading branch information
mheon committed Sep 17, 2024
1 parent 47b85af commit e04668c
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 4 deletions.
19 changes: 15 additions & 4 deletions pkg/api/handlers/compat/containers_top.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,11 +88,22 @@ loop: // break out of for/select infinite` loop
}

for _, line := range output[1:] {
process := strings.Split(line, "\t")
for i := range process {
process[i] = strings.TrimSpace(process[i])
process := strings.FieldsFunc(line, func(r rune) bool {
return r == ' ' || r == '\t'
})
if len(process) > len(body.Titles) {
// Docker assumes the last entry is *always* command
// Which can include spaces.
// All other descriptors are assumed to NOT include extra spaces.
// So combine any extras.
cmd := strings.Join(process[len(body.Titles)-1:], " ")
var finalProc []string
finalProc = append(finalProc, process[:len(body.Titles)-1]...)
finalProc = append(finalProc, cmd)
body.Processes = append(body.Processes, finalProc)
} else {
body.Processes = append(body.Processes, process)
}
body.Processes = append(body.Processes, process)
}

if err := encoder.Encode(body); err != nil {
Expand Down
8 changes: 8 additions & 0 deletions test/apiv2/20-containers.at
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,14 @@ if root; then
podman rm -f $CTRNAME
fi

# Verify that compat top endpoint combines multi-entry COMMAND lines
CTRNAME=testtopproc
podman run --name $CTRNAME -d $IMAGE sleep 25
t GET containers/$CTRNAME/top?stream=false 200 \
.Processes.[0].[6]="00:00:00" \
.Processes.[0].[7]="sleep 25"
podman rm -f -t0 $CTRNAME

CTRNAME=test123
podman run --name $CTRNAME -d $IMAGE top
t GET libpod/containers/$CTRNAME/top?ps_args=--invalid 500 \
Expand Down

0 comments on commit e04668c

Please sign in to comment.