github.com/erriapo/docker@v1.6.0-rc2/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  	container, err := daemon.Get(name)
    25  	if err != nil {
    26  		return job.Error(err)
    27  	}
    28  	if !container.IsRunning() {
    29  		return job.Errorf("Container %s is not running", name)
    30  	}
    31  	pids, err := daemon.ExecutionDriver().GetPidsForContainer(container.ID)
    32  	if err != nil {
    33  		return job.Error(err)
    34  	}
    35  	output, err := exec.Command("ps", strings.Split(psArgs, " ")...).Output()
    36  	if err != nil {
    37  		return job.Errorf("Error running ps: %s", err)
    38  	}
    39  
    40  	lines := strings.Split(string(output), "\n")
    41  	header := strings.Fields(lines[0])
    42  	out := &engine.Env{}
    43  	out.SetList("Titles", header)
    44  
    45  	pidIndex := -1
    46  	for i, name := range header {
    47  		if name == "PID" {
    48  			pidIndex = i
    49  		}
    50  	}
    51  	if pidIndex == -1 {
    52  		return job.Errorf("Couldn't find PID field in ps output")
    53  	}
    54  
    55  	processes := [][]string{}
    56  	for _, line := range lines[1:] {
    57  		if len(line) == 0 {
    58  			continue
    59  		}
    60  		fields := strings.Fields(line)
    61  		p, err := strconv.Atoi(fields[pidIndex])
    62  		if err != nil {
    63  			return job.Errorf("Unexpected pid '%s': %s", fields[pidIndex], err)
    64  		}
    65  
    66  		for _, pid := range pids {
    67  			if pid == p {
    68  				// Make sure number of fields equals number of header titles
    69  				// merging "overhanging" fields
    70  				process := fields[:len(header)-1]
    71  				process = append(process, strings.Join(fields[len(header)-1:], " "))
    72  				processes = append(processes, process)
    73  			}
    74  		}
    75  	}
    76  	out.SetJson("Processes", processes)
    77  	out.WriteTo(job.Stdout)
    78  	return engine.StatusOK
    79  }