github.com/willmtemple/docker@v1.7.0-rc2/daemon/top.go (about) 1 package daemon 2 3 import ( 4 "fmt" 5 "os/exec" 6 "strconv" 7 "strings" 8 9 "github.com/docker/docker/api/types" 10 ) 11 12 func (daemon *Daemon) ContainerTop(name string, psArgs string) (*types.ContainerProcessList, error) { 13 if psArgs == "" { 14 psArgs = "-ef" 15 } 16 17 container, err := daemon.Get(name) 18 if err != nil { 19 return nil, err 20 } 21 22 if !container.IsRunning() { 23 return nil, fmt.Errorf("Container %s is not running", name) 24 } 25 26 pids, err := daemon.ExecutionDriver().GetPidsForContainer(container.ID) 27 if err != nil { 28 return nil, err 29 } 30 31 output, err := exec.Command("ps", strings.Split(psArgs, " ")...).Output() 32 if err != nil { 33 return nil, fmt.Errorf("Error running ps: %s", err) 34 } 35 36 procList := &types.ContainerProcessList{} 37 38 lines := strings.Split(string(output), "\n") 39 procList.Titles = strings.Fields(lines[0]) 40 41 pidIndex := -1 42 for i, name := range procList.Titles { 43 if name == "PID" { 44 pidIndex = i 45 } 46 } 47 if pidIndex == -1 { 48 return nil, fmt.Errorf("Couldn't find PID field in ps output") 49 } 50 51 for _, line := range lines[1:] { 52 if len(line) == 0 { 53 continue 54 } 55 fields := strings.Fields(line) 56 p, err := strconv.Atoi(fields[pidIndex]) 57 if err != nil { 58 return nil, fmt.Errorf("Unexpected pid '%s': %s", fields[pidIndex], err) 59 } 60 61 for _, pid := range pids { 62 if pid == p { 63 // Make sure number of fields equals number of header titles 64 // merging "overhanging" fields 65 process := fields[:len(procList.Titles)-1] 66 process = append(process, strings.Join(fields[len(procList.Titles)-1:], " ")) 67 procList.Processes = append(procList.Processes, process) 68 } 69 } 70 } 71 return procList, nil 72 }