ps.go 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. package client
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "net/url"
  6. "strconv"
  7. "strings"
  8. "text/tabwriter"
  9. "time"
  10. "github.com/docker/docker/api"
  11. "github.com/docker/docker/api/types"
  12. "github.com/docker/docker/opts"
  13. flag "github.com/docker/docker/pkg/mflag"
  14. "github.com/docker/docker/pkg/parsers/filters"
  15. "github.com/docker/docker/pkg/stringid"
  16. "github.com/docker/docker/pkg/stringutils"
  17. "github.com/docker/docker/pkg/units"
  18. )
  19. // CmdPs outputs a list of Docker containers.
  20. //
  21. // Usage: docker ps [OPTIONS]
  22. func (cli *DockerCli) CmdPs(args ...string) error {
  23. var (
  24. err error
  25. psFilterArgs = filters.Args{}
  26. v = url.Values{}
  27. cmd = cli.Subcmd("ps", nil, "List containers", true)
  28. quiet = cmd.Bool([]string{"q", "-quiet"}, false, "Only display numeric IDs")
  29. size = cmd.Bool([]string{"s", "-size"}, false, "Display total file sizes")
  30. all = cmd.Bool([]string{"a", "-all"}, false, "Show all containers (default shows just running)")
  31. noTrunc = cmd.Bool([]string{"#notrunc", "-no-trunc"}, false, "Don't truncate output")
  32. nLatest = cmd.Bool([]string{"l", "-latest"}, false, "Show the latest created container, include non-running")
  33. since = cmd.String([]string{"#sinceId", "#-since-id", "-since"}, "", "Show created since Id or Name, include non-running")
  34. before = cmd.String([]string{"#beforeId", "#-before-id", "-before"}, "", "Show only container created before Id or Name")
  35. last = cmd.Int([]string{"n"}, -1, "Show n last created containers, include non-running")
  36. flFilter = opts.NewListOpts(nil)
  37. )
  38. cmd.Require(flag.Exact, 0)
  39. cmd.Var(&flFilter, []string{"f", "-filter"}, "Filter output based on conditions provided")
  40. cmd.ParseFlags(args, true)
  41. if *last == -1 && *nLatest {
  42. *last = 1
  43. }
  44. if *all {
  45. v.Set("all", "1")
  46. }
  47. if *last != -1 {
  48. v.Set("limit", strconv.Itoa(*last))
  49. }
  50. if *since != "" {
  51. v.Set("since", *since)
  52. }
  53. if *before != "" {
  54. v.Set("before", *before)
  55. }
  56. if *size {
  57. v.Set("size", "1")
  58. }
  59. // Consolidate all filter flags, and sanity check them.
  60. // They'll get processed in the daemon/server.
  61. for _, f := range flFilter.GetAll() {
  62. if psFilterArgs, err = filters.ParseFlag(f, psFilterArgs); err != nil {
  63. return err
  64. }
  65. }
  66. if len(psFilterArgs) > 0 {
  67. filterJSON, err := filters.ToParam(psFilterArgs)
  68. if err != nil {
  69. return err
  70. }
  71. v.Set("filters", filterJSON)
  72. }
  73. rdr, _, _, err := cli.call("GET", "/containers/json?"+v.Encode(), nil, nil)
  74. if err != nil {
  75. return err
  76. }
  77. containers := []types.Container{}
  78. if err := json.NewDecoder(rdr).Decode(&containers); err != nil {
  79. return err
  80. }
  81. w := tabwriter.NewWriter(cli.out, 20, 1, 3, ' ', 0)
  82. if !*quiet {
  83. fmt.Fprint(w, "CONTAINER ID\tIMAGE\tCOMMAND\tCREATED\tSTATUS\tPORTS\tNAMES")
  84. if *size {
  85. fmt.Fprintln(w, "\tSIZE")
  86. } else {
  87. fmt.Fprint(w, "\n")
  88. }
  89. }
  90. stripNamePrefix := func(ss []string) []string {
  91. for i, s := range ss {
  92. ss[i] = s[1:]
  93. }
  94. return ss
  95. }
  96. for _, container := range containers {
  97. ID := container.ID
  98. if !*noTrunc {
  99. ID = stringid.TruncateID(ID)
  100. }
  101. if *quiet {
  102. fmt.Fprintln(w, ID)
  103. continue
  104. }
  105. var (
  106. names = stripNamePrefix(container.Names)
  107. command = strconv.Quote(container.Command)
  108. displayPort string
  109. )
  110. if !*noTrunc {
  111. command = stringutils.Truncate(command, 20)
  112. // only display the default name for the container with notrunc is passed
  113. for _, name := range names {
  114. if len(strings.Split(name, "/")) == 1 {
  115. names = []string{name}
  116. break
  117. }
  118. }
  119. }
  120. image := container.Image
  121. if image == "" {
  122. image = "<no image>"
  123. }
  124. if container.HostConfig.NetworkMode == "host" {
  125. displayPort = "*/tcp, */udp"
  126. } else {
  127. displayPort = api.DisplayablePorts(container.Ports)
  128. }
  129. fmt.Fprintf(w, "%s\t%s\t%s\t%s ago\t%s\t%s\t%s\t", ID, image, command,
  130. units.HumanDuration(time.Now().UTC().Sub(time.Unix(int64(container.Created), 0))),
  131. container.Status, displayPort, strings.Join(names, ","))
  132. if *size {
  133. if container.SizeRootFs > 0 {
  134. fmt.Fprintf(w, "%s (virtual %s)\n", units.HumanSize(float64(container.SizeRw)), units.HumanSize(float64(container.SizeRootFs)))
  135. } else {
  136. fmt.Fprintf(w, "%s\n", units.HumanSize(float64(container.SizeRw)))
  137. }
  138. continue
  139. }
  140. fmt.Fprint(w, "\n")
  141. }
  142. if !*quiet {
  143. w.Flush()
  144. }
  145. return nil
  146. }