| package client |
| |
| import ( |
| "encoding/json" |
| "fmt" |
| "net/url" |
| "strconv" |
| "strings" |
| "text/tabwriter" |
| "time" |
| |
| "github.com/docker/docker/api" |
| "github.com/docker/docker/api/types" |
| "github.com/docker/docker/opts" |
| flag "github.com/docker/docker/pkg/mflag" |
| "github.com/docker/docker/pkg/parsers/filters" |
| "github.com/docker/docker/pkg/stringid" |
| "github.com/docker/docker/pkg/stringutils" |
| "github.com/docker/docker/pkg/units" |
| ) |
| |
| // CmdPs outputs a list of Docker containers. |
| // |
| // Usage: docker ps [OPTIONS] |
| func (cli *DockerCli) CmdPs(args ...string) error { |
| var ( |
| err error |
| |
| psFilterArgs = filters.Args{} |
| v = url.Values{} |
| |
| cmd = cli.Subcmd("ps", "", "List containers", true) |
| quiet = cmd.Bool([]string{"q", "-quiet"}, false, "Only display numeric IDs") |
| size = cmd.Bool([]string{"s", "-size"}, false, "Display total file sizes") |
| all = cmd.Bool([]string{"a", "-all"}, false, "Show all containers (default shows just running)") |
| noTrunc = cmd.Bool([]string{"#notrunc", "-no-trunc"}, false, "Don't truncate output") |
| nLatest = cmd.Bool([]string{"l", "-latest"}, false, "Show the latest created container, include non-running") |
| since = cmd.String([]string{"#sinceId", "#-since-id", "-since"}, "", "Show created since Id or Name, include non-running") |
| before = cmd.String([]string{"#beforeId", "#-before-id", "-before"}, "", "Show only container created before Id or Name") |
| last = cmd.Int([]string{"n"}, -1, "Show n last created containers, include non-running") |
| flFilter = opts.NewListOpts(nil) |
| ) |
| cmd.Require(flag.Exact, 0) |
| |
| cmd.Var(&flFilter, []string{"f", "-filter"}, "Filter output based on conditions provided") |
| |
| cmd.ParseFlags(args, true) |
| if *last == -1 && *nLatest { |
| *last = 1 |
| } |
| |
| if *all { |
| v.Set("all", "1") |
| } |
| |
| if *last != -1 { |
| v.Set("limit", strconv.Itoa(*last)) |
| } |
| |
| if *since != "" { |
| v.Set("since", *since) |
| } |
| |
| if *before != "" { |
| v.Set("before", *before) |
| } |
| |
| if *size { |
| v.Set("size", "1") |
| } |
| |
| // Consolidate all filter flags, and sanity check them. |
| // They'll get processed in the daemon/server. |
| for _, f := range flFilter.GetAll() { |
| if psFilterArgs, err = filters.ParseFlag(f, psFilterArgs); err != nil { |
| return err |
| } |
| } |
| |
| if len(psFilterArgs) > 0 { |
| filterJSON, err := filters.ToParam(psFilterArgs) |
| if err != nil { |
| return err |
| } |
| |
| v.Set("filters", filterJSON) |
| } |
| |
| rdr, _, err := cli.call("GET", "/containers/json?"+v.Encode(), nil, nil) |
| if err != nil { |
| return err |
| } |
| |
| containers := []types.Container{} |
| if err := json.NewDecoder(rdr).Decode(&containers); err != nil { |
| return err |
| } |
| |
| w := tabwriter.NewWriter(cli.out, 20, 1, 3, ' ', 0) |
| if !*quiet { |
| fmt.Fprint(w, "CONTAINER ID\tIMAGE\tCOMMAND\tCREATED\tSTATUS\tPORTS\tNAMES") |
| |
| if *size { |
| fmt.Fprintln(w, "\tSIZE") |
| } else { |
| fmt.Fprint(w, "\n") |
| } |
| } |
| |
| stripNamePrefix := func(ss []string) []string { |
| for i, s := range ss { |
| ss[i] = s[1:] |
| } |
| |
| return ss |
| } |
| |
| for _, container := range containers { |
| ID := container.ID |
| |
| if !*noTrunc { |
| ID = stringid.TruncateID(ID) |
| } |
| |
| if *quiet { |
| fmt.Fprintln(w, ID) |
| |
| continue |
| } |
| |
| var ( |
| names = stripNamePrefix(container.Names) |
| command = strconv.Quote(container.Command) |
| ) |
| |
| if !*noTrunc { |
| command = stringutils.Truncate(command, 20) |
| |
| // only display the default name for the container with notrunc is passed |
| for _, name := range names { |
| if len(strings.Split(name, "/")) == 1 { |
| names = []string{name} |
| break |
| } |
| } |
| } |
| |
| image := container.Image |
| if image == "" { |
| image = "<no image>" |
| } |
| |
| fmt.Fprintf(w, "%s\t%s\t%s\t%s ago\t%s\t%s\t%s\t", ID, image, command, |
| units.HumanDuration(time.Now().UTC().Sub(time.Unix(int64(container.Created), 0))), |
| container.Status, api.DisplayablePorts(container.Ports), strings.Join(names, ",")) |
| |
| if *size { |
| if container.SizeRootFs > 0 { |
| fmt.Fprintf(w, "%s (virtual %s)\n", units.HumanSize(float64(container.SizeRw)), units.HumanSize(float64(container.SizeRootFs))) |
| } else { |
| fmt.Fprintf(w, "%s\n", units.HumanSize(float64(container.SizeRw))) |
| } |
| |
| continue |
| } |
| |
| fmt.Fprint(w, "\n") |
| } |
| |
| if !*quiet { |
| w.Flush() |
| } |
| |
| return nil |
| } |