Signed-off-by: Tianyi Wang <capkurmagati@gmail.com>
| 14 | 13 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,125 @@ |
| 0 |
+package container |
|
| 1 |
+ |
|
| 2 |
+import ( |
|
| 3 |
+ "golang.org/x/net/context" |
|
| 4 |
+ |
|
| 5 |
+ "github.com/docker/docker/api/client" |
|
| 6 |
+ "github.com/docker/docker/api/client/formatter" |
|
| 7 |
+ "github.com/docker/docker/cli" |
|
| 8 |
+ "github.com/docker/engine-api/types" |
|
| 9 |
+ "github.com/docker/engine-api/types/filters" |
|
| 10 |
+ |
|
| 11 |
+ "github.com/docker/docker/utils/templates" |
|
| 12 |
+ "github.com/spf13/cobra" |
|
| 13 |
+ "io/ioutil" |
|
| 14 |
+) |
|
| 15 |
+ |
|
| 16 |
+type psOptions struct {
|
|
| 17 |
+ quiet bool |
|
| 18 |
+ size bool |
|
| 19 |
+ all bool |
|
| 20 |
+ noTrunc bool |
|
| 21 |
+ nLatest bool |
|
| 22 |
+ last int |
|
| 23 |
+ format string |
|
| 24 |
+ filter []string |
|
| 25 |
+} |
|
| 26 |
+ |
|
| 27 |
+type preProcessor struct {
|
|
| 28 |
+ opts *types.ContainerListOptions |
|
| 29 |
+} |
|
| 30 |
+ |
|
| 31 |
+// Size sets the size option when called by a template execution. |
|
| 32 |
+func (p *preProcessor) Size() bool {
|
|
| 33 |
+ p.opts.Size = true |
|
| 34 |
+ return true |
|
| 35 |
+} |
|
| 36 |
+ |
|
| 37 |
+// NewPsCommand creates a new cobra.Command for `docker ps` |
|
| 38 |
+func NewPsCommand(dockerCli *client.DockerCli) *cobra.Command {
|
|
| 39 |
+ var opts psOptions |
|
| 40 |
+ |
|
| 41 |
+ cmd := &cobra.Command{
|
|
| 42 |
+ Use: "ps [OPTIONS]", |
|
| 43 |
+ Short: "List containers", |
|
| 44 |
+ Args: cli.ExactArgs(0), |
|
| 45 |
+ RunE: func(cmd *cobra.Command, args []string) error {
|
|
| 46 |
+ return runPs(dockerCli, &opts) |
|
| 47 |
+ }, |
|
| 48 |
+ } |
|
| 49 |
+ |
|
| 50 |
+ flags := cmd.Flags() |
|
| 51 |
+ |
|
| 52 |
+ flags.BoolVarP(&opts.quiet, "quiet", "q", false, "Only display numeric IDs") |
|
| 53 |
+ flags.BoolVarP(&opts.size, "size", "s", false, "Display total file sizes") |
|
| 54 |
+ flags.BoolVarP(&opts.all, "all", "a", false, "Show all containers (default shows just running)") |
|
| 55 |
+ flags.BoolVar(&opts.noTrunc, "no-trunc", false, "Don't truncate output") |
|
| 56 |
+ flags.BoolVarP(&opts.nLatest, "latest", "l", false, "Show the latest created container (includes all states)") |
|
| 57 |
+ flags.IntVarP(&opts.last, "", "n", -1, "Show n last created containers (includes all states)") |
|
| 58 |
+ flags.StringVarP(&opts.format, "format", "", "", "Pretty-print containers using a Go template") |
|
| 59 |
+ flags.StringSliceVarP(&opts.filter, "filter", "f", []string{}, "Filter output based on conditions provided")
|
|
| 60 |
+ |
|
| 61 |
+ return cmd |
|
| 62 |
+} |
|
| 63 |
+ |
|
| 64 |
+func runPs(dockerCli *client.DockerCli, opts *psOptions) error {
|
|
| 65 |
+ ctx := context.Background() |
|
| 66 |
+ |
|
| 67 |
+ if opts.nLatest && opts.last == -1 {
|
|
| 68 |
+ opts.last = 1 |
|
| 69 |
+ } |
|
| 70 |
+ |
|
| 71 |
+ containerFilterArgs := filters.NewArgs() |
|
| 72 |
+ for _, f := range opts.filter {
|
|
| 73 |
+ var err error |
|
| 74 |
+ containerFilterArgs, err = filters.ParseFlag(f, containerFilterArgs) |
|
| 75 |
+ if err != nil {
|
|
| 76 |
+ return err |
|
| 77 |
+ } |
|
| 78 |
+ } |
|
| 79 |
+ |
|
| 80 |
+ options := types.ContainerListOptions{
|
|
| 81 |
+ All: opts.all, |
|
| 82 |
+ Limit: opts.last, |
|
| 83 |
+ Size: opts.size, |
|
| 84 |
+ Filter: containerFilterArgs, |
|
| 85 |
+ } |
|
| 86 |
+ |
|
| 87 |
+ pre := &preProcessor{opts: &options}
|
|
| 88 |
+ tmpl, err := templates.Parse(opts.format) |
|
| 89 |
+ |
|
| 90 |
+ if err != nil {
|
|
| 91 |
+ return err |
|
| 92 |
+ } |
|
| 93 |
+ |
|
| 94 |
+ _ = tmpl.Execute(ioutil.Discard, pre) |
|
| 95 |
+ |
|
| 96 |
+ containers, err := dockerCli.Client().ContainerList(ctx, options) |
|
| 97 |
+ if err != nil {
|
|
| 98 |
+ return err |
|
| 99 |
+ } |
|
| 100 |
+ |
|
| 101 |
+ f := opts.format |
|
| 102 |
+ if len(f) == 0 {
|
|
| 103 |
+ if len(dockerCli.PsFormat()) > 0 && !opts.quiet {
|
|
| 104 |
+ f = dockerCli.PsFormat() |
|
| 105 |
+ } else {
|
|
| 106 |
+ f = "table" |
|
| 107 |
+ } |
|
| 108 |
+ } |
|
| 109 |
+ |
|
| 110 |
+ psCtx := formatter.ContainerContext{
|
|
| 111 |
+ Context: formatter.Context{
|
|
| 112 |
+ Output: dockerCli.Out(), |
|
| 113 |
+ Format: f, |
|
| 114 |
+ Quiet: opts.quiet, |
|
| 115 |
+ Trunc: !opts.noTrunc, |
|
| 116 |
+ }, |
|
| 117 |
+ Size: opts.size, |
|
| 118 |
+ Containers: containers, |
|
| 119 |
+ } |
|
| 120 |
+ |
|
| 121 |
+ psCtx.Write() |
|
| 122 |
+ |
|
| 123 |
+ return nil |
|
| 124 |
+} |
| 0 | 125 |
deleted file mode 100644 |
| ... | ... |
@@ -1,105 +0,0 @@ |
| 1 |
-package client |
|
| 2 |
- |
|
| 3 |
-import ( |
|
| 4 |
- "golang.org/x/net/context" |
|
| 5 |
- "io/ioutil" |
|
| 6 |
- |
|
| 7 |
- "github.com/docker/docker/api/client/formatter" |
|
| 8 |
- Cli "github.com/docker/docker/cli" |
|
| 9 |
- "github.com/docker/docker/opts" |
|
| 10 |
- flag "github.com/docker/docker/pkg/mflag" |
|
| 11 |
- "github.com/docker/docker/utils/templates" |
|
| 12 |
- "github.com/docker/engine-api/types" |
|
| 13 |
- "github.com/docker/engine-api/types/filters" |
|
| 14 |
-) |
|
| 15 |
- |
|
| 16 |
-type preProcessor struct {
|
|
| 17 |
- opts *types.ContainerListOptions |
|
| 18 |
-} |
|
| 19 |
- |
|
| 20 |
-// Size sets the size option when called by a template execution. |
|
| 21 |
-func (p *preProcessor) Size() bool {
|
|
| 22 |
- p.opts.Size = true |
|
| 23 |
- return true |
|
| 24 |
-} |
|
| 25 |
- |
|
| 26 |
-// CmdPs outputs a list of Docker containers. |
|
| 27 |
-// |
|
| 28 |
-// Usage: docker ps [OPTIONS] |
|
| 29 |
-func (cli *DockerCli) CmdPs(args ...string) error {
|
|
| 30 |
- var ( |
|
| 31 |
- err error |
|
| 32 |
- |
|
| 33 |
- psFilterArgs = filters.NewArgs() |
|
| 34 |
- |
|
| 35 |
- cmd = Cli.Subcmd("ps", nil, Cli.DockerCommands["ps"].Description, true)
|
|
| 36 |
- quiet = cmd.Bool([]string{"q", "-quiet"}, false, "Only display numeric IDs")
|
|
| 37 |
- size = cmd.Bool([]string{"s", "-size"}, false, "Display total file sizes")
|
|
| 38 |
- all = cmd.Bool([]string{"a", "-all"}, false, "Show all containers (default shows just running)")
|
|
| 39 |
- noTrunc = cmd.Bool([]string{"-no-trunc"}, false, "Don't truncate output")
|
|
| 40 |
- nLatest = cmd.Bool([]string{"l", "-latest"}, false, "Show the latest created container (includes all states)")
|
|
| 41 |
- last = cmd.Int([]string{"n"}, -1, "Show n last created containers (includes all states)")
|
|
| 42 |
- format = cmd.String([]string{"-format"}, "", "Pretty-print containers using a Go template")
|
|
| 43 |
- flFilter = opts.NewListOpts(nil) |
|
| 44 |
- ) |
|
| 45 |
- cmd.Require(flag.Exact, 0) |
|
| 46 |
- |
|
| 47 |
- cmd.Var(&flFilter, []string{"f", "-filter"}, "Filter output based on conditions provided")
|
|
| 48 |
- |
|
| 49 |
- cmd.ParseFlags(args, true) |
|
| 50 |
- if *last == -1 && *nLatest {
|
|
| 51 |
- *last = 1 |
|
| 52 |
- } |
|
| 53 |
- |
|
| 54 |
- // Consolidate all filter flags, and sanity check them. |
|
| 55 |
- // They'll get processed in the daemon/server. |
|
| 56 |
- for _, f := range flFilter.GetAll() {
|
|
| 57 |
- if psFilterArgs, err = filters.ParseFlag(f, psFilterArgs); err != nil {
|
|
| 58 |
- return err |
|
| 59 |
- } |
|
| 60 |
- } |
|
| 61 |
- |
|
| 62 |
- options := types.ContainerListOptions{
|
|
| 63 |
- All: *all, |
|
| 64 |
- Limit: *last, |
|
| 65 |
- Size: *size, |
|
| 66 |
- Filter: psFilterArgs, |
|
| 67 |
- } |
|
| 68 |
- |
|
| 69 |
- pre := &preProcessor{opts: &options}
|
|
| 70 |
- tmpl, err := templates.Parse(*format) |
|
| 71 |
- if err != nil {
|
|
| 72 |
- return err |
|
| 73 |
- } |
|
| 74 |
- |
|
| 75 |
- _ = tmpl.Execute(ioutil.Discard, pre) |
|
| 76 |
- |
|
| 77 |
- containers, err := cli.client.ContainerList(context.Background(), options) |
|
| 78 |
- if err != nil {
|
|
| 79 |
- return err |
|
| 80 |
- } |
|
| 81 |
- |
|
| 82 |
- f := *format |
|
| 83 |
- if len(f) == 0 {
|
|
| 84 |
- if len(cli.PsFormat()) > 0 && !*quiet {
|
|
| 85 |
- f = cli.PsFormat() |
|
| 86 |
- } else {
|
|
| 87 |
- f = "table" |
|
| 88 |
- } |
|
| 89 |
- } |
|
| 90 |
- |
|
| 91 |
- psCtx := formatter.ContainerContext{
|
|
| 92 |
- Context: formatter.Context{
|
|
| 93 |
- Output: cli.out, |
|
| 94 |
- Format: f, |
|
| 95 |
- Quiet: *quiet, |
|
| 96 |
- Trunc: !*noTrunc, |
|
| 97 |
- }, |
|
| 98 |
- Size: *size, |
|
| 99 |
- Containers: containers, |
|
| 100 |
- } |
|
| 101 |
- |
|
| 102 |
- psCtx.Write() |
|
| 103 |
- |
|
| 104 |
- return nil |
|
| 105 |
-} |
| ... | ... |
@@ -45,6 +45,7 @@ func NewCobraAdaptor(clientFlags *cliflags.ClientFlags) CobraAdaptor {
|
| 45 | 45 |
container.NewLogsCommand(dockerCli), |
| 46 | 46 |
container.NewPauseCommand(dockerCli), |
| 47 | 47 |
container.NewPortCommand(dockerCli), |
| 48 |
+ container.NewPsCommand(dockerCli), |
|
| 48 | 49 |
container.NewRenameCommand(dockerCli), |
| 49 | 50 |
container.NewRestartCommand(dockerCli), |
| 50 | 51 |
container.NewRmCommand(dockerCli), |
| ... | ... |
@@ -12,7 +12,6 @@ var DockerCommandUsage = []Command{
|
| 12 | 12 |
{"exec", "Run a command in a running container"},
|
| 13 | 13 |
{"info", "Display system-wide information"},
|
| 14 | 14 |
{"inspect", "Return low-level information on a container or image"},
|
| 15 |
- {"ps", "List containers"},
|
|
| 16 | 15 |
{"update", "Update configuration of one or more containers"},
|
| 17 | 16 |
} |
| 18 | 17 |
|