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