Return title fields as a list

Podman is attempting to split the headers returned by the ps
command into a list of headers. Problem is that some headers
are multi-word, and headers are not guaranteed to be split via
a tab. This PR splits the headers bases on white space, and for
the select group of CAPS headers which are multi-word, combines
them back together.

Fixes: https://github.com/containers/podman/issues/17524

Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>
This commit is contained in:
Daniel J Walsh
2023-04-10 13:50:10 -04:00
parent c8eb15114b
commit 1fa4e45a95
4 changed files with 33 additions and 3 deletions

View File

@ -63,7 +63,7 @@ loop: // break out of for/select infinite` loop
case <-r.Context().Done():
break loop
default:
output, err := c.Top([]string{query.PsArgs})
output, err := c.Top(strings.Split(query.PsArgs, ","))
if err != nil {
logrus.Infof("Error from %s %q : %v", r.Method, r.URL, err)
break loop
@ -71,7 +71,8 @@ loop: // break out of for/select infinite` loop
if len(output) > 0 {
body := handlers.ContainerTopOKBody{}
body.Titles = strings.Split(output[0], "\t")
body.Titles = utils.PSTitles(output[0])
for i := range body.Titles {
body.Titles[i] = strings.TrimSpace(body.Titles[i])
}

View File

@ -413,7 +413,7 @@ loop: // break out of for/select infinite` loop
if len(output) > 0 {
body := handlers.PodTopOKBody{}
body.Titles = strings.Split(output[0], "\t")
body.Titles = utils.PSTitles(output[0])
for i := range body.Titles {
body.Titles[i] = strings.TrimSpace(body.Titles[i])
}

View File

@ -6,6 +6,7 @@ import (
"fmt"
"net/http"
"strconv"
"strings"
"time"
"github.com/containers/podman/v4/libpod/events"
@ -238,3 +239,23 @@ func containerExists(ctx context.Context, name string) (bool, error) {
}
return ctrExistRep.Value, nil
}
// PSTitles merges CAPS headers from ps output. All PS headers are single words, except for
// CAPS. Function compines CAP Headers into single field separated by a space.
func PSTitles(output string) []string {
var titles []string
for _, title := range strings.Fields(output) {
switch title {
case "AMBIENT", "INHERITED", "PERMITTED", "EFFECTIVE", "BOUNDING":
{
titles = append(titles, title+" CAPS")
}
case "CAPS":
continue
default:
titles = append(titles, title)
}
}
return titles
}

View File

@ -121,6 +121,14 @@ if root; then
.memory_stats.limit=536870912 \
.id~[0-9a-f]\\{64\\}
t GET containers/$CTRNAME/top?stream=false 200 \
.Titles='[
"PID",
"USER",
"TIME",
"COMMAND"
]'
podman rm -f $CTRNAME
fi