diff --git a/api/client/commands.go b/api/client/commands.go index d746466316..745180e19c 100644 --- a/api/client/commands.go +++ b/api/client/commands.go @@ -2,7 +2,5 @@ package client // Command returns a cli command handler if one exists func (cli *DockerCli) Command(name string) func(...string) error { - return map[string]func(...string) error{ - "inspect": cli.CmdInspect, - }[name] + return map[string]func(...string) error{}[name] } diff --git a/api/client/inspect.go b/api/client/inspect.go deleted file mode 100644 index 2c22d5dc65..0000000000 --- a/api/client/inspect.go +++ /dev/null @@ -1,95 +0,0 @@ -package client - -import ( - "fmt" - - "golang.org/x/net/context" - - "github.com/docker/docker/api/client/inspect" - Cli "github.com/docker/docker/cli" - flag "github.com/docker/docker/pkg/mflag" - "github.com/docker/engine-api/client" -) - -// CmdInspect displays low-level information on one or more containers, images or tasks. -// -// Usage: docker inspect [OPTIONS] CONTAINER|IMAGE|TASK [CONTAINER|IMAGE|TASK...] -func (cli *DockerCli) CmdInspect(args ...string) error { - cmd := Cli.Subcmd("inspect", []string{"[OPTIONS] CONTAINER|IMAGE|TASK [CONTAINER|IMAGE|TASK...]"}, Cli.DockerCommands["inspect"].Description, true) - tmplStr := cmd.String([]string{"f", "-format"}, "", "Format the output using the given go template") - inspectType := cmd.String([]string{"-type"}, "", "Return JSON for specified type, (e.g image, container or task)") - size := cmd.Bool([]string{"s", "-size"}, false, "Display total file sizes if the type is container") - cmd.Require(flag.Min, 1) - - cmd.ParseFlags(args, true) - - if *inspectType != "" && *inspectType != "container" && *inspectType != "image" && *inspectType != "task" { - return fmt.Errorf("%q is not a valid value for --type", *inspectType) - } - - ctx := context.Background() - - var elementSearcher inspect.GetRefFunc - switch *inspectType { - case "container": - elementSearcher = cli.inspectContainers(ctx, *size) - case "image": - elementSearcher = cli.inspectImages(ctx, *size) - case "task": - if *size { - fmt.Fprintln(cli.err, "WARNING: --size ignored for tasks") - } - elementSearcher = cli.inspectTasks(ctx) - default: - elementSearcher = cli.inspectAll(ctx, *size) - } - - return inspect.Inspect(cli.out, cmd.Args(), *tmplStr, elementSearcher) -} - -func (cli *DockerCli) inspectContainers(ctx context.Context, getSize bool) inspect.GetRefFunc { - return func(ref string) (interface{}, []byte, error) { - return cli.client.ContainerInspectWithRaw(ctx, ref, getSize) - } -} - -func (cli *DockerCli) inspectImages(ctx context.Context, getSize bool) inspect.GetRefFunc { - return func(ref string) (interface{}, []byte, error) { - return cli.client.ImageInspectWithRaw(ctx, ref, getSize) - } -} - -func (cli *DockerCli) inspectTasks(ctx context.Context) inspect.GetRefFunc { - return func(ref string) (interface{}, []byte, error) { - return cli.client.TaskInspectWithRaw(ctx, ref) - } -} - -func (cli *DockerCli) inspectAll(ctx context.Context, getSize bool) inspect.GetRefFunc { - return func(ref string) (interface{}, []byte, error) { - c, rawContainer, err := cli.client.ContainerInspectWithRaw(ctx, ref, getSize) - if err != nil { - // Search for image with that id if a container doesn't exist. - if client.IsErrContainerNotFound(err) { - i, rawImage, err := cli.client.ImageInspectWithRaw(ctx, ref, getSize) - if err != nil { - if client.IsErrImageNotFound(err) { - // Search for task with that id if an image doesn't exists. - t, rawTask, err := cli.client.TaskInspectWithRaw(ctx, ref) - if err != nil { - return nil, nil, fmt.Errorf("Error: No such image, container or task: %s", ref) - } - if getSize { - fmt.Fprintln(cli.err, "WARNING: --size ignored for tasks") - } - return t, rawTask, nil - } - return nil, nil, err - } - return i, rawImage, nil - } - return nil, nil, err - } - return c, rawContainer, nil - } -} diff --git a/api/client/system/inspect.go b/api/client/system/inspect.go new file mode 100644 index 0000000000..f6b1189c69 --- /dev/null +++ b/api/client/system/inspect.go @@ -0,0 +1,98 @@ +package system + +import ( + "fmt" + + "golang.org/x/net/context" + + "github.com/docker/docker/api/client" + "github.com/docker/docker/api/client/inspect" + "github.com/docker/docker/cli" + apiclient "github.com/docker/engine-api/client" + "github.com/spf13/cobra" +) + +type inspectOptions struct { + format string + inspectType string + size bool + ids []string +} + +// NewInspectCommand creates a new cobra.Command for `docker inspect` +func NewInspectCommand(dockerCli *client.DockerCli) *cobra.Command { + var opts inspectOptions + + cmd := &cobra.Command{ + Use: "inspect [OPTIONS] CONTAINER|IMAGE|TASK [CONTAINER|IMAGE|TASK...]", + Short: "Return low-level information on a container, image or task", + Args: cli.RequiresMinArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + opts.ids = args + return runInspect(dockerCli, opts) + }, + } + + flags := cmd.Flags() + flags.StringVarP(&opts.format, "format", "f", "", "Format the output using the given go template") + flags.StringVar(&opts.inspectType, "type", "", "Return JSON for specified type, (e.g image, container or task)") + flags.BoolVarP(&opts.size, "size", "s", false, "Display total file sizes if the type is container") + + return cmd +} + +func runInspect(dockerCli *client.DockerCli, opts inspectOptions) error { + ctx := context.Background() + client := dockerCli.Client() + + var getRefFunc inspect.GetRefFunc + switch opts.inspectType { + case "container": + getRefFunc = func(ref string) (interface{}, []byte, error) { + return client.ContainerInspectWithRaw(ctx, ref, opts.size) + } + case "image": + getRefFunc = func(ref string) (interface{}, []byte, error) { + return client.ImageInspectWithRaw(ctx, ref, opts.size) + } + case "task": + if opts.size { + fmt.Fprintln(dockerCli.Err(), "WARNING: --size ignored for tasks") + } + getRefFunc = func(ref string) (interface{}, []byte, error) { + return client.TaskInspectWithRaw(ctx, ref) + } + case "": + getRefFunc = inspectAll(ctx, dockerCli, opts.size) + default: + return fmt.Errorf("%q is not a valid value for --type", opts.inspectType) + } + + return inspect.Inspect(dockerCli.Out(), opts.ids, opts.format, getRefFunc) +} + +func inspectAll(ctx context.Context, dockerCli *client.DockerCli, getSize bool) inspect.GetRefFunc { + client := dockerCli.Client() + + return func(ref string) (interface{}, []byte, error) { + c, rawContainer, err := client.ContainerInspectWithRaw(ctx, ref, getSize) + if err == nil || !apiclient.IsErrNotFound(err) { + return c, rawContainer, err + } + // Search for image with that id if a container doesn't exist. + i, rawImage, err := client.ImageInspectWithRaw(ctx, ref, getSize) + if err == nil || !apiclient.IsErrNotFound(err) { + return i, rawImage, err + } + + // Search for task with that id if an image doesn't exists. + t, rawTask, err := client.TaskInspectWithRaw(ctx, ref) + if err == nil || !apiclient.IsErrNotFound(err) { + if getSize { + fmt.Fprintln(dockerCli.Err(), "WARNING: --size ignored for tasks") + } + return t, rawTask, err + } + return nil, nil, fmt.Errorf("Error: No such image, container or task: %s", ref) + } +} diff --git a/cli/cobraadaptor/adaptor.go b/cli/cobraadaptor/adaptor.go index 6614f1fa69..2df553bea1 100644 --- a/cli/cobraadaptor/adaptor.go +++ b/cli/cobraadaptor/adaptor.go @@ -83,6 +83,7 @@ func NewCobraAdaptor(clientFlags *cliflags.ClientFlags) CobraAdaptor { image.NewTagCommand(dockerCli), network.NewNetworkCommand(dockerCli), system.NewEventsCommand(dockerCli), + system.NewInspectCommand(dockerCli), registry.NewLoginCommand(dockerCli), registry.NewLogoutCommand(dockerCli), system.NewVersionCommand(dockerCli), diff --git a/cli/usage.go b/cli/usage.go index 0ad053d734..a8a0328643 100644 --- a/cli/usage.go +++ b/cli/usage.go @@ -7,9 +7,7 @@ type Command struct { } // DockerCommandUsage lists the top level docker commands and their short usage -var DockerCommandUsage = []Command{ - {"inspect", "Return low-level information on a container, image or task"}, -} +var DockerCommandUsage = []Command{} // DockerCommands stores all the docker command var DockerCommands = make(map[string]Command)