Fixing issue of docker top command failure when dealing with -m option

Changed per requested review to refactor to make it more logic clear.

Current output for "docker top <contianer-id> m" option,eg:
root@b2c7ec58399d:/go/src/github.com/docker/docker# docker top 755d5871ec45 am
PID                 TTY                 STAT                TIME                COMMAND
148                 pts/0               -                   0:00                bash
-                   -                   Ss+                 0:00                -

fixing issue:#30580

Signed-off-by: catinthesky <yaozaiyong@hotmail.com>
This commit is contained in:
catinthesky 2017-02-02 09:02:53 +00:00 committed by Yao Zaiyong
parent 3c32e1775a
commit a7497c39cd
2 changed files with 41 additions and 9 deletions

View File

@ -41,6 +41,23 @@ func fieldsASCII(s string) []string {
return strings.FieldsFunc(s, fn)
}
func appendProcess2ProcList(procList *container.ContainerTopOKBody, fields []string) {
// Make sure number of fields equals number of header titles
// merging "overhanging" fields
process := fields[:len(procList.Titles)-1]
process = append(process, strings.Join(fields[len(procList.Titles)-1:], " "))
procList.Processes = append(procList.Processes, process)
}
func hasPid(pids []int, pid int) bool {
for _, i := range pids {
if i == pid {
return true
}
}
return false
}
func parsePSOutput(output []byte, pids []int) (*container.ContainerTopOKBody, error) {
procList := &container.ContainerTopOKBody{}
@ -58,25 +75,37 @@ func parsePSOutput(output []byte, pids []int) (*container.ContainerTopOKBody, er
}
// loop through the output and extract the PID from each line
// fixing #30580, be able to display thread line also when "m" option used
// in "docker top" client command
preContainedPidFlag := false
for _, line := range lines[1:] {
if len(line) == 0 {
continue
}
fields := fieldsASCII(line)
p, err := strconv.Atoi(fields[pidIndex])
var (
p int
err error
)
if fields[pidIndex] == "-" {
if preContainedPidFlag {
appendProcess2ProcList(procList, fields)
}
continue
}
p, err = strconv.Atoi(fields[pidIndex])
if err != nil {
return nil, fmt.Errorf("Unexpected pid '%s': %s", fields[pidIndex], err)
}
for _, pid := range pids {
if pid == p {
// Make sure number of fields equals number of header titles
// merging "overhanging" fields
process := fields[:len(procList.Titles)-1]
process = append(process, strings.Join(fields[len(procList.Titles)-1:], " "))
procList.Processes = append(procList.Processes, process)
}
if hasPid(pids, p) {
preContainedPidFlag = true
appendProcess2ProcList(procList, fields)
continue
}
preContainedPidFlag = false
}
return procList, nil
}

View File

@ -42,17 +42,20 @@ func TestContainerTopParsePSOutput(t *testing.T) {
{[]byte(` PID COMMAND
42 foo
43 bar
- -
100 baz
`), []int{42, 43}, false},
{[]byte(` UID COMMAND
42 foo
43 bar
- -
100 baz
`), []int{42, 43}, true},
// unicode space (U+2003, 0xe2 0x80 0x83)
{[]byte(`PIDCOMMAND
42 foo
43 bar
- -
100 baz
`), []int{42, 43}, true},
// the first space is U+2003, the second one is ascii.