123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219 |
- // DEPRECATION NOTICE. PLEASE DO NOT ADD ANYTHING TO THIS FILE.
- //
- // For additional commments see server/server.go
- //
- package server
- import (
- "errors"
- "fmt"
- "os/exec"
- "strconv"
- "strings"
- "github.com/docker/docker/daemon"
- "github.com/docker/docker/engine"
- "github.com/docker/docker/pkg/graphdb"
- )
- func (srv *Server) ContainerTop(job *engine.Job) engine.Status {
- if len(job.Args) != 1 && len(job.Args) != 2 {
- return job.Errorf("Not enough arguments. Usage: %s CONTAINER [PS_ARGS]\n", job.Name)
- }
- var (
- name = job.Args[0]
- psArgs = "-ef"
- )
- if len(job.Args) == 2 && job.Args[1] != "" {
- psArgs = job.Args[1]
- }
- if container := srv.daemon.Get(name); container != nil {
- if !container.State.IsRunning() {
- return job.Errorf("Container %s is not running", name)
- }
- pids, err := srv.daemon.ExecutionDriver().GetPidsForContainer(container.ID)
- if err != nil {
- return job.Error(err)
- }
- output, err := exec.Command("ps", psArgs).Output()
- if err != nil {
- return job.Errorf("Error running ps: %s", err)
- }
- lines := strings.Split(string(output), "\n")
- header := strings.Fields(lines[0])
- out := &engine.Env{}
- out.SetList("Titles", header)
- pidIndex := -1
- for i, name := range header {
- if name == "PID" {
- pidIndex = i
- }
- }
- if pidIndex == -1 {
- return job.Errorf("Couldn't find PID field in ps output")
- }
- processes := [][]string{}
- for _, line := range lines[1:] {
- if len(line) == 0 {
- continue
- }
- fields := strings.Fields(line)
- p, err := strconv.Atoi(fields[pidIndex])
- if err != nil {
- return job.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(header)-1]
- process = append(process, strings.Join(fields[len(header)-1:], " "))
- processes = append(processes, process)
- }
- }
- }
- out.SetJson("Processes", processes)
- out.WriteTo(job.Stdout)
- return engine.StatusOK
- }
- return job.Errorf("No such container: %s", name)
- }
- func (srv *Server) ContainerChanges(job *engine.Job) engine.Status {
- if n := len(job.Args); n != 1 {
- return job.Errorf("Usage: %s CONTAINER", job.Name)
- }
- name := job.Args[0]
- if container := srv.daemon.Get(name); container != nil {
- outs := engine.NewTable("", 0)
- changes, err := container.Changes()
- if err != nil {
- return job.Error(err)
- }
- for _, change := range changes {
- out := &engine.Env{}
- if err := out.Import(change); err != nil {
- return job.Error(err)
- }
- outs.Add(out)
- }
- if _, err := outs.WriteListTo(job.Stdout); err != nil {
- return job.Error(err)
- }
- } else {
- return job.Errorf("No such container: %s", name)
- }
- return engine.StatusOK
- }
- func (srv *Server) Containers(job *engine.Job) engine.Status {
- var (
- foundBefore bool
- displayed int
- all = job.GetenvBool("all")
- since = job.Getenv("since")
- before = job.Getenv("before")
- n = job.GetenvInt("limit")
- size = job.GetenvBool("size")
- )
- outs := engine.NewTable("Created", 0)
- names := map[string][]string{}
- srv.daemon.ContainerGraph().Walk("/", func(p string, e *graphdb.Entity) error {
- names[e.ID()] = append(names[e.ID()], p)
- return nil
- }, -1)
- var beforeCont, sinceCont *daemon.Container
- if before != "" {
- beforeCont = srv.daemon.Get(before)
- if beforeCont == nil {
- return job.Error(fmt.Errorf("Could not find container with name or id %s", before))
- }
- }
- if since != "" {
- sinceCont = srv.daemon.Get(since)
- if sinceCont == nil {
- return job.Error(fmt.Errorf("Could not find container with name or id %s", since))
- }
- }
- errLast := errors.New("last container")
- writeCont := func(container *daemon.Container) error {
- container.Lock()
- defer container.Unlock()
- if !container.State.IsRunning() && !all && n <= 0 && since == "" && before == "" {
- return nil
- }
- if before != "" && !foundBefore {
- if container.ID == beforeCont.ID {
- foundBefore = true
- }
- return nil
- }
- if n > 0 && displayed == n {
- return errLast
- }
- if since != "" {
- if container.ID == sinceCont.ID {
- return errLast
- }
- }
- displayed++
- out := &engine.Env{}
- out.Set("Id", container.ID)
- out.SetList("Names", names[container.ID])
- out.Set("Image", srv.daemon.Repositories().ImageName(container.Image))
- if len(container.Args) > 0 {
- args := []string{}
- for _, arg := range container.Args {
- if strings.Contains(arg, " ") {
- args = append(args, fmt.Sprintf("'%s'", arg))
- } else {
- args = append(args, arg)
- }
- }
- argsAsString := strings.Join(args, " ")
- out.Set("Command", fmt.Sprintf("\"%s %s\"", container.Path, argsAsString))
- } else {
- out.Set("Command", fmt.Sprintf("\"%s\"", container.Path))
- }
- out.SetInt64("Created", container.Created.Unix())
- out.Set("Status", container.State.String())
- str, err := container.NetworkSettings.PortMappingAPI().ToListString()
- if err != nil {
- return err
- }
- out.Set("Ports", str)
- if size {
- sizeRw, sizeRootFs := container.GetSize()
- out.SetInt64("SizeRw", sizeRw)
- out.SetInt64("SizeRootFs", sizeRootFs)
- }
- outs.Add(out)
- return nil
- }
- for _, container := range srv.daemon.List() {
- if err := writeCont(container); err != nil {
- if err != errLast {
- return job.Error(err)
- }
- break
- }
- }
- outs.ReverseSort()
- if _, err := outs.WriteListTo(job.Stdout); err != nil {
- return job.Error(err)
- }
- return engine.StatusOK
- }
|