Signed-off-by: Doug Davis <dug@us.ibm.com>
| ... | ... |
@@ -1,12 +1,13 @@ |
| 1 | 1 |
package client |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 |
+ "encoding/json" |
|
| 4 | 5 |
"fmt" |
| 5 | 6 |
"net/url" |
| 6 | 7 |
"strings" |
| 7 | 8 |
"text/tabwriter" |
| 8 | 9 |
|
| 9 |
- "github.com/docker/docker/engine" |
|
| 10 |
+ "github.com/docker/docker/api/types" |
|
| 10 | 11 |
flag "github.com/docker/docker/pkg/mflag" |
| 11 | 12 |
) |
| 12 | 13 |
|
| ... | ... |
@@ -28,17 +29,17 @@ func (cli *DockerCli) CmdTop(args ...string) error {
|
| 28 | 28 |
if err != nil {
|
| 29 | 29 |
return err |
| 30 | 30 |
} |
| 31 |
- var procs engine.Env |
|
| 32 |
- if err := procs.Decode(stream); err != nil {
|
|
| 31 |
+ |
|
| 32 |
+ procList := types.ContainerProcessList{}
|
|
| 33 |
+ err = json.NewDecoder(stream).Decode(&procList) |
|
| 34 |
+ if err != nil {
|
|
| 33 | 35 |
return err |
| 34 | 36 |
} |
| 37 |
+ |
|
| 35 | 38 |
w := tabwriter.NewWriter(cli.out, 20, 1, 3, ' ', 0) |
| 36 |
- fmt.Fprintln(w, strings.Join(procs.GetList("Titles"), "\t"))
|
|
| 37 |
- processes := [][]string{}
|
|
| 38 |
- if err := procs.GetJson("Processes", &processes); err != nil {
|
|
| 39 |
- return err |
|
| 40 |
- } |
|
| 41 |
- for _, proc := range processes {
|
|
| 39 |
+ fmt.Fprintln(w, strings.Join(procList.Titles, "\t")) |
|
| 40 |
+ |
|
| 41 |
+ for _, proc := range procList.Processes {
|
|
| 42 | 42 |
fmt.Fprintln(w, strings.Join(proc, "\t")) |
| 43 | 43 |
} |
| 44 | 44 |
w.Flush() |
| ... | ... |
@@ -471,16 +471,21 @@ func getContainersTop(eng *engine.Engine, version version.Version, w http.Respon |
| 471 | 471 |
if version.LessThan("1.4") {
|
| 472 | 472 |
return fmt.Errorf("top was improved a lot since 1.3, Please upgrade your docker client.")
|
| 473 | 473 |
} |
| 474 |
+ |
|
| 474 | 475 |
if vars == nil {
|
| 475 | 476 |
return fmt.Errorf("Missing parameter")
|
| 476 | 477 |
} |
| 478 |
+ |
|
| 477 | 479 |
if err := parseForm(r); err != nil {
|
| 478 | 480 |
return err |
| 479 | 481 |
} |
| 480 | 482 |
|
| 481 |
- job := eng.Job("top", vars["name"], r.Form.Get("ps_args"))
|
|
| 482 |
- streamJSON(job, w, false) |
|
| 483 |
- return job.Run() |
|
| 483 |
+ procList, err := getDaemon(eng).ContainerTop(vars["name"], r.Form.Get("ps_args"))
|
|
| 484 |
+ if err != nil {
|
|
| 485 |
+ return err |
|
| 486 |
+ } |
|
| 487 |
+ |
|
| 488 |
+ return writeJSON(w, http.StatusOK, procList) |
|
| 484 | 489 |
} |
| 485 | 490 |
|
| 486 | 491 |
func getContainersJSON(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
| ... | ... |
@@ -128,7 +128,6 @@ func (daemon *Daemon) Install(eng *engine.Engine) error {
|
| 128 | 128 |
"restart": daemon.ContainerRestart, |
| 129 | 129 |
"start": daemon.ContainerStart, |
| 130 | 130 |
"stop": daemon.ContainerStop, |
| 131 |
- "top": daemon.ContainerTop, |
|
| 132 | 131 |
"wait": daemon.ContainerWait, |
| 133 | 132 |
"execCreate": daemon.ContainerExecCreate, |
| 134 | 133 |
"execStart": daemon.ContainerExecStart, |
| ... | ... |
@@ -6,54 +6,48 @@ import ( |
| 6 | 6 |
"strconv" |
| 7 | 7 |
"strings" |
| 8 | 8 |
|
| 9 |
- "github.com/docker/docker/engine" |
|
| 9 |
+ "github.com/docker/docker/api/types" |
|
| 10 | 10 |
) |
| 11 | 11 |
|
| 12 |
-func (daemon *Daemon) ContainerTop(job *engine.Job) error {
|
|
| 13 |
- if len(job.Args) != 1 && len(job.Args) != 2 {
|
|
| 14 |
- return fmt.Errorf("Not enough arguments. Usage: %s CONTAINER [PS_ARGS]\n", job.Name)
|
|
| 15 |
- } |
|
| 16 |
- var ( |
|
| 17 |
- name = job.Args[0] |
|
| 12 |
+func (daemon *Daemon) ContainerTop(name string, psArgs string) (*types.ContainerProcessList, error) {
|
|
| 13 |
+ if psArgs == "" {
|
|
| 18 | 14 |
psArgs = "-ef" |
| 19 |
- ) |
|
| 20 |
- |
|
| 21 |
- if len(job.Args) == 2 && job.Args[1] != "" {
|
|
| 22 |
- psArgs = job.Args[1] |
|
| 23 | 15 |
} |
| 24 | 16 |
|
| 25 | 17 |
container, err := daemon.Get(name) |
| 26 | 18 |
if err != nil {
|
| 27 |
- return err |
|
| 19 |
+ return nil, err |
|
| 28 | 20 |
} |
| 21 |
+ |
|
| 29 | 22 |
if !container.IsRunning() {
|
| 30 |
- return fmt.Errorf("Container %s is not running", name)
|
|
| 23 |
+ return nil, fmt.Errorf("Container %s is not running", name)
|
|
| 31 | 24 |
} |
| 25 |
+ |
|
| 32 | 26 |
pids, err := daemon.ExecutionDriver().GetPidsForContainer(container.ID) |
| 33 | 27 |
if err != nil {
|
| 34 |
- return err |
|
| 28 |
+ return nil, err |
|
| 35 | 29 |
} |
| 30 |
+ |
|
| 36 | 31 |
output, err := exec.Command("ps", strings.Split(psArgs, " ")...).Output()
|
| 37 | 32 |
if err != nil {
|
| 38 |
- return fmt.Errorf("Error running ps: %s", err)
|
|
| 33 |
+ return nil, fmt.Errorf("Error running ps: %s", err)
|
|
| 39 | 34 |
} |
| 40 | 35 |
|
| 36 |
+ procList := &types.ContainerProcessList{}
|
|
| 37 |
+ |
|
| 41 | 38 |
lines := strings.Split(string(output), "\n") |
| 42 |
- header := strings.Fields(lines[0]) |
|
| 43 |
- out := &engine.Env{}
|
|
| 44 |
- out.SetList("Titles", header)
|
|
| 39 |
+ procList.Titles = strings.Fields(lines[0]) |
|
| 45 | 40 |
|
| 46 | 41 |
pidIndex := -1 |
| 47 |
- for i, name := range header {
|
|
| 42 |
+ for i, name := range procList.Titles {
|
|
| 48 | 43 |
if name == "PID" {
|
| 49 | 44 |
pidIndex = i |
| 50 | 45 |
} |
| 51 | 46 |
} |
| 52 | 47 |
if pidIndex == -1 {
|
| 53 |
- return fmt.Errorf("Couldn't find PID field in ps output")
|
|
| 48 |
+ return nil, fmt.Errorf("Couldn't find PID field in ps output")
|
|
| 54 | 49 |
} |
| 55 | 50 |
|
| 56 |
- processes := [][]string{}
|
|
| 57 | 51 |
for _, line := range lines[1:] {
|
| 58 | 52 |
if len(line) == 0 {
|
| 59 | 53 |
continue |
| ... | ... |
@@ -61,20 +55,18 @@ func (daemon *Daemon) ContainerTop(job *engine.Job) error {
|
| 61 | 61 |
fields := strings.Fields(line) |
| 62 | 62 |
p, err := strconv.Atoi(fields[pidIndex]) |
| 63 | 63 |
if err != nil {
|
| 64 |
- return fmt.Errorf("Unexpected pid '%s': %s", fields[pidIndex], err)
|
|
| 64 |
+ return nil, fmt.Errorf("Unexpected pid '%s': %s", fields[pidIndex], err)
|
|
| 65 | 65 |
} |
| 66 | 66 |
|
| 67 | 67 |
for _, pid := range pids {
|
| 68 | 68 |
if pid == p {
|
| 69 | 69 |
// Make sure number of fields equals number of header titles |
| 70 | 70 |
// merging "overhanging" fields |
| 71 |
- process := fields[:len(header)-1] |
|
| 72 |
- process = append(process, strings.Join(fields[len(header)-1:], " ")) |
|
| 73 |
- processes = append(processes, process) |
|
| 71 |
+ process := fields[:len(procList.Titles)-1] |
|
| 72 |
+ process = append(process, strings.Join(fields[len(procList.Titles)-1:], " ")) |
|
| 73 |
+ procList.Processes = append(procList.Processes, process) |
|
| 74 | 74 |
} |
| 75 | 75 |
} |
| 76 | 76 |
} |
| 77 |
- out.SetJson("Processes", processes)
|
|
| 78 |
- out.WriteTo(job.Stdout) |
|
| 79 |
- return nil |
|
| 77 |
+ return procList, nil |
|
| 80 | 78 |
} |