This fix is part of the effort to convert commands to spf13/cobra #23211.
Thif fix coverted command `docker images` to use spf13/cobra
NOTE: As part of this fix, a new function `RequiresMaxArgs()`
has been defined in `cli/required.go`. This func returns an
error if there is not at most max args
Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
| 15 | 14 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,103 @@ |
| 0 |
+package image |
|
| 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 |
+ "github.com/spf13/cobra" |
|
| 11 |
+) |
|
| 12 |
+ |
|
| 13 |
+type imagesOptions struct {
|
|
| 14 |
+ matchName string |
|
| 15 |
+ |
|
| 16 |
+ quiet bool |
|
| 17 |
+ all bool |
|
| 18 |
+ noTrunc bool |
|
| 19 |
+ showDigests bool |
|
| 20 |
+ format string |
|
| 21 |
+ filter []string |
|
| 22 |
+} |
|
| 23 |
+ |
|
| 24 |
+// NewImagesCommand create a new `docker images` command |
|
| 25 |
+func NewImagesCommand(dockerCli *client.DockerCli) *cobra.Command {
|
|
| 26 |
+ var opts imagesOptions |
|
| 27 |
+ |
|
| 28 |
+ cmd := &cobra.Command{
|
|
| 29 |
+ Use: "images [OPTIONS] [REPOSITORY[:TAG]]", |
|
| 30 |
+ Short: "List images", |
|
| 31 |
+ Args: cli.RequiresMaxArgs(1), |
|
| 32 |
+ RunE: func(cmd *cobra.Command, args []string) error {
|
|
| 33 |
+ if len(args) > 0 {
|
|
| 34 |
+ opts.matchName = args[0] |
|
| 35 |
+ } |
|
| 36 |
+ return runImages(dockerCli, opts) |
|
| 37 |
+ }, |
|
| 38 |
+ } |
|
| 39 |
+ |
|
| 40 |
+ flags := cmd.Flags() |
|
| 41 |
+ |
|
| 42 |
+ flags.BoolVarP(&opts.quiet, "quiet", "q", false, "Only show numeric IDs") |
|
| 43 |
+ flags.BoolVarP(&opts.all, "all", "a", false, "Show all images (default hides intermediate images)") |
|
| 44 |
+ flags.BoolVar(&opts.noTrunc, "no-trunc", false, "Don't truncate output") |
|
| 45 |
+ flags.BoolVar(&opts.showDigests, "digests", false, "Show digests") |
|
| 46 |
+ flags.StringVar(&opts.format, "format", "", "Pretty-print images using a Go template") |
|
| 47 |
+ flags.StringSliceVarP(&opts.filter, "filter", "f", []string{}, "Filter output based on conditions provided")
|
|
| 48 |
+ |
|
| 49 |
+ return cmd |
|
| 50 |
+} |
|
| 51 |
+ |
|
| 52 |
+func runImages(dockerCli *client.DockerCli, opts imagesOptions) error {
|
|
| 53 |
+ ctx := context.Background() |
|
| 54 |
+ |
|
| 55 |
+ // Consolidate all filter flags, and sanity check them early. |
|
| 56 |
+ // They'll get process in the daemon/server. |
|
| 57 |
+ imageFilterArgs := filters.NewArgs() |
|
| 58 |
+ for _, f := range opts.filter {
|
|
| 59 |
+ var err error |
|
| 60 |
+ imageFilterArgs, err = filters.ParseFlag(f, imageFilterArgs) |
|
| 61 |
+ if err != nil {
|
|
| 62 |
+ return err |
|
| 63 |
+ } |
|
| 64 |
+ } |
|
| 65 |
+ |
|
| 66 |
+ matchName := opts.matchName |
|
| 67 |
+ |
|
| 68 |
+ options := types.ImageListOptions{
|
|
| 69 |
+ MatchName: matchName, |
|
| 70 |
+ All: opts.all, |
|
| 71 |
+ Filters: imageFilterArgs, |
|
| 72 |
+ } |
|
| 73 |
+ |
|
| 74 |
+ images, err := dockerCli.Client().ImageList(ctx, options) |
|
| 75 |
+ if err != nil {
|
|
| 76 |
+ return err |
|
| 77 |
+ } |
|
| 78 |
+ |
|
| 79 |
+ f := opts.format |
|
| 80 |
+ if len(f) == 0 {
|
|
| 81 |
+ if len(dockerCli.ImagesFormat()) > 0 && !opts.quiet {
|
|
| 82 |
+ f = dockerCli.ImagesFormat() |
|
| 83 |
+ } else {
|
|
| 84 |
+ f = "table" |
|
| 85 |
+ } |
|
| 86 |
+ } |
|
| 87 |
+ |
|
| 88 |
+ imagesCtx := formatter.ImageContext{
|
|
| 89 |
+ Context: formatter.Context{
|
|
| 90 |
+ Output: dockerCli.Out(), |
|
| 91 |
+ Format: f, |
|
| 92 |
+ Quiet: opts.quiet, |
|
| 93 |
+ Trunc: !opts.noTrunc, |
|
| 94 |
+ }, |
|
| 95 |
+ Digest: opts.showDigests, |
|
| 96 |
+ Images: images, |
|
| 97 |
+ } |
|
| 98 |
+ |
|
| 99 |
+ imagesCtx.Write() |
|
| 100 |
+ |
|
| 101 |
+ return nil |
|
| 102 |
+} |
| 0 | 103 |
deleted file mode 100644 |
| ... | ... |
@@ -1,81 +0,0 @@ |
| 1 |
-package client |
|
| 2 |
- |
|
| 3 |
-import ( |
|
| 4 |
- "golang.org/x/net/context" |
|
| 5 |
- |
|
| 6 |
- "github.com/docker/docker/api/client/formatter" |
|
| 7 |
- Cli "github.com/docker/docker/cli" |
|
| 8 |
- "github.com/docker/docker/opts" |
|
| 9 |
- flag "github.com/docker/docker/pkg/mflag" |
|
| 10 |
- "github.com/docker/engine-api/types" |
|
| 11 |
- "github.com/docker/engine-api/types/filters" |
|
| 12 |
-) |
|
| 13 |
- |
|
| 14 |
-// CmdImages lists the images in a specified repository, or all top-level images if no repository is specified. |
|
| 15 |
-// |
|
| 16 |
-// Usage: docker images [OPTIONS] [REPOSITORY] |
|
| 17 |
-func (cli *DockerCli) CmdImages(args ...string) error {
|
|
| 18 |
- cmd := Cli.Subcmd("images", []string{"[REPOSITORY[:TAG]]"}, Cli.DockerCommands["images"].Description, true)
|
|
| 19 |
- quiet := cmd.Bool([]string{"q", "-quiet"}, false, "Only show numeric IDs")
|
|
| 20 |
- all := cmd.Bool([]string{"a", "-all"}, false, "Show all images (default hides intermediate images)")
|
|
| 21 |
- noTrunc := cmd.Bool([]string{"-no-trunc"}, false, "Don't truncate output")
|
|
| 22 |
- showDigests := cmd.Bool([]string{"-digests"}, false, "Show digests")
|
|
| 23 |
- format := cmd.String([]string{"-format"}, "", "Pretty-print images using a Go template")
|
|
| 24 |
- |
|
| 25 |
- flFilter := opts.NewListOpts(nil) |
|
| 26 |
- cmd.Var(&flFilter, []string{"f", "-filter"}, "Filter output based on conditions provided")
|
|
| 27 |
- cmd.Require(flag.Max, 1) |
|
| 28 |
- |
|
| 29 |
- cmd.ParseFlags(args, true) |
|
| 30 |
- |
|
| 31 |
- // Consolidate all filter flags, and sanity check them early. |
|
| 32 |
- // They'll get process in the daemon/server. |
|
| 33 |
- imageFilterArgs := filters.NewArgs() |
|
| 34 |
- for _, f := range flFilter.GetAll() {
|
|
| 35 |
- var err error |
|
| 36 |
- imageFilterArgs, err = filters.ParseFlag(f, imageFilterArgs) |
|
| 37 |
- if err != nil {
|
|
| 38 |
- return err |
|
| 39 |
- } |
|
| 40 |
- } |
|
| 41 |
- |
|
| 42 |
- var matchName string |
|
| 43 |
- if cmd.NArg() == 1 {
|
|
| 44 |
- matchName = cmd.Arg(0) |
|
| 45 |
- } |
|
| 46 |
- |
|
| 47 |
- options := types.ImageListOptions{
|
|
| 48 |
- MatchName: matchName, |
|
| 49 |
- All: *all, |
|
| 50 |
- Filters: imageFilterArgs, |
|
| 51 |
- } |
|
| 52 |
- |
|
| 53 |
- images, err := cli.client.ImageList(context.Background(), options) |
|
| 54 |
- if err != nil {
|
|
| 55 |
- return err |
|
| 56 |
- } |
|
| 57 |
- |
|
| 58 |
- f := *format |
|
| 59 |
- if len(f) == 0 {
|
|
| 60 |
- if len(cli.ImagesFormat()) > 0 && !*quiet {
|
|
| 61 |
- f = cli.ImagesFormat() |
|
| 62 |
- } else {
|
|
| 63 |
- f = "table" |
|
| 64 |
- } |
|
| 65 |
- } |
|
| 66 |
- |
|
| 67 |
- imagesCtx := formatter.ImageContext{
|
|
| 68 |
- Context: formatter.Context{
|
|
| 69 |
- Output: cli.out, |
|
| 70 |
- Format: f, |
|
| 71 |
- Quiet: *quiet, |
|
| 72 |
- Trunc: !*noTrunc, |
|
| 73 |
- }, |
|
| 74 |
- Digest: *showDigests, |
|
| 75 |
- Images: images, |
|
| 76 |
- } |
|
| 77 |
- |
|
| 78 |
- imagesCtx.Write() |
|
| 79 |
- |
|
| 80 |
- return nil |
|
| 81 |
-} |
| ... | ... |
@@ -51,6 +51,7 @@ func NewCobraAdaptor(clientFlags *cliflags.ClientFlags) CobraAdaptor {
|
| 51 | 51 |
container.NewUnpauseCommand(dockerCli), |
| 52 | 52 |
container.NewWaitCommand(dockerCli), |
| 53 | 53 |
image.NewHistoryCommand(dockerCli), |
| 54 |
+ image.NewImagesCommand(dockerCli), |
|
| 54 | 55 |
image.NewRemoveCommand(dockerCli), |
| 55 | 56 |
image.NewSearchCommand(dockerCli), |
| 56 | 57 |
image.NewImportCommand(dockerCli), |
| ... | ... |
@@ -43,6 +43,23 @@ func RequiresMinArgs(min int) cobra.PositionalArgs {
|
| 43 | 43 |
} |
| 44 | 44 |
} |
| 45 | 45 |
|
| 46 |
+// RequiresMaxArgs returns an error if there is not at most max args |
|
| 47 |
+func RequiresMaxArgs(max int) cobra.PositionalArgs {
|
|
| 48 |
+ return func(cmd *cobra.Command, args []string) error {
|
|
| 49 |
+ if len(args) <= max {
|
|
| 50 |
+ return nil |
|
| 51 |
+ } |
|
| 52 |
+ return fmt.Errorf( |
|
| 53 |
+ "\"%s\" requires at most %d argument(s).\nSee '%s --help'.\n\nUsage: %s\n\n%s", |
|
| 54 |
+ cmd.CommandPath(), |
|
| 55 |
+ max, |
|
| 56 |
+ cmd.CommandPath(), |
|
| 57 |
+ cmd.UseLine(), |
|
| 58 |
+ cmd.Short, |
|
| 59 |
+ ) |
|
| 60 |
+ } |
|
| 61 |
+} |
|
| 62 |
+ |
|
| 46 | 63 |
// RequiresMinMaxArgs returns an error if there is not at least min args and at most max args |
| 47 | 64 |
func RequiresMinMaxArgs(min int, max int) cobra.PositionalArgs {
|
| 48 | 65 |
return func(cmd *cobra.Command, args []string) error {
|
| ... | ... |
@@ -13,7 +13,6 @@ var DockerCommandUsage = []Command{
|
| 13 | 13 |
{"cp", "Copy files/folders between a container and the local filesystem"},
|
| 14 | 14 |
{"events", "Get real time events from the server"},
|
| 15 | 15 |
{"exec", "Run a command in a running container"},
|
| 16 |
- {"images", "List images"},
|
|
| 17 | 16 |
{"info", "Display system-wide information"},
|
| 18 | 17 |
{"inspect", "Return low-level information on a container or image"},
|
| 19 | 18 |
{"load", "Load an image from a tar archive or STDIN"},
|