1
0
Fork 0
mirror of https://github.com/moby/moby.git synced 2022-11-09 12:21:53 -05:00

Merge pull request #23902 from dnephin/inspect-to-cobra

Convert inspect command to Cobra
This commit is contained in:
Alexander Morozov 2016-08-04 11:20:43 -07:00 committed by GitHub
commit 979d48bbf5
12 changed files with 120 additions and 115 deletions

View file

@ -2,7 +2,5 @@ package client
// Command returns a cli command handler if one exists // Command returns a cli command handler if one exists
func (cli *DockerCli) Command(name string) func(...string) error { func (cli *DockerCli) Command(name string) func(...string) error {
return map[string]func(...string) error{ return map[string]func(...string) error{}[name]
"inspect": cli.CmdInspect,
}[name]
} }

View file

@ -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
}
}

View file

@ -0,0 +1,103 @@
package system
import (
"fmt"
"strings"
"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 exist.
t, rawTask, err := client.TaskInspectWithRaw(ctx, ref)
if err == nil || !(apiclient.IsErrNotFound(err) || isErrorNoSwarmMode(err)) {
if getSize {
fmt.Fprintln(dockerCli.Err(), "WARNING: --size ignored for tasks")
}
return t, rawTask, err
}
return nil, nil, fmt.Errorf("Error: No such container, image or task: %s", ref)
}
}
func isErrorNoSwarmMode(err error) bool {
return strings.Contains(err.Error(), "This node is not a swarm manager")
}

View file

@ -83,6 +83,7 @@ func NewCobraAdaptor(clientFlags *cliflags.ClientFlags) CobraAdaptor {
image.NewTagCommand(dockerCli), image.NewTagCommand(dockerCli),
network.NewNetworkCommand(dockerCli), network.NewNetworkCommand(dockerCli),
system.NewEventsCommand(dockerCli), system.NewEventsCommand(dockerCli),
system.NewInspectCommand(dockerCli),
registry.NewLoginCommand(dockerCli), registry.NewLoginCommand(dockerCli),
registry.NewLogoutCommand(dockerCli), registry.NewLogoutCommand(dockerCli),
system.NewVersionCommand(dockerCli), system.NewVersionCommand(dockerCli),

View file

@ -7,9 +7,7 @@ type Command struct {
} }
// DockerCommandUsage lists the top level docker commands and their short usage // DockerCommandUsage lists the top level docker commands and their short usage
var DockerCommandUsage = []Command{ var DockerCommandUsage = []Command{}
{"inspect", "Return low-level information on a container, image or task"},
}
// DockerCommands stores all the docker command // DockerCommands stores all the docker command
var DockerCommands = make(map[string]Command) var DockerCommands = make(map[string]Command)

View file

@ -176,7 +176,7 @@ func (s *DockerRegistrySuite) TestRemoveImageByDigest(c *check.C) {
_, err = inspectFieldWithError(imageReference, "Id") _, err = inspectFieldWithError(imageReference, "Id")
//unexpected nil err trying to inspect what should be a non-existent image //unexpected nil err trying to inspect what should be a non-existent image
c.Assert(err, checker.NotNil) c.Assert(err, checker.NotNil)
c.Assert(err.Error(), checker.Contains, "No such image") c.Assert(err.Error(), checker.Contains, "No such container, image")
} }
func (s *DockerRegistrySuite) TestBuildByDigest(c *check.C) { func (s *DockerRegistrySuite) TestBuildByDigest(c *check.C) {

View file

@ -326,7 +326,7 @@ func (s *DockerDaemonSuite) TestDaemonIptablesCreate(c *check.C) {
} }
// make sure the container is not running // make sure the container is not running
runningOut, err := s.d.Cmd("inspect", "--format='{{.State.Running}}'", "top") runningOut, err := s.d.Cmd("inspect", "--format={{.State.Running}}", "top")
if err != nil { if err != nil {
c.Fatalf("Could not inspect on container: %s, %v", out, err) c.Fatalf("Could not inspect on container: %s, %v", out, err)
} }
@ -2196,7 +2196,7 @@ func (s *DockerDaemonSuite) TestCleanupMountsAfterDaemonCrash(c *check.C) {
} }
// container should be running. // container should be running.
out, err = s.d.Cmd("inspect", "--format='{{.State.Running}}'", id) out, err = s.d.Cmd("inspect", "--format={{.State.Running}}", id)
c.Assert(err, check.IsNil, check.Commentf("Output: %s", out)) c.Assert(err, check.IsNil, check.Commentf("Output: %s", out))
out = strings.TrimSpace(out) out = strings.TrimSpace(out)
if out != "true" { if out != "true" {

View file

@ -353,7 +353,7 @@ func (s *DockerExternalGraphdriverSuite) testExternalGraphDriver(name string, ex
err = s.d.Restart("-s", name) err = s.d.Restart("-s", name)
out, err = s.d.Cmd("inspect", "--format='{{.GraphDriver.Name}}'", "graphtest") out, err = s.d.Cmd("inspect", "--format={{.GraphDriver.Name}}", "graphtest")
c.Assert(err, check.IsNil, check.Commentf(out)) c.Assert(err, check.IsNil, check.Commentf(out))
c.Assert(strings.TrimSpace(out), check.Equals, name) c.Assert(strings.TrimSpace(out), check.Equals, name)

View file

@ -73,10 +73,10 @@ func (s *DockerSuite) TestHealth(c *check.C) {
// Inspect the options // Inspect the options
out, _ = dockerCmd(c, "inspect", out, _ = dockerCmd(c, "inspect",
"--format='timeout={{.Config.Healthcheck.Timeout}} "+ "--format=timeout={{.Config.Healthcheck.Timeout}} "+
"interval={{.Config.Healthcheck.Interval}} "+ "interval={{.Config.Healthcheck.Interval}} "+
"retries={{.Config.Healthcheck.Retries}} "+ "retries={{.Config.Healthcheck.Retries}} "+
"test={{.Config.Healthcheck.Test}}'", name) "test={{.Config.Healthcheck.Test}}", name)
c.Check(out, checker.Equals, "timeout=30s interval=1s retries=0 test=[CMD-SHELL cat /status]\n") c.Check(out, checker.Equals, "timeout=30s interval=1s retries=0 test=[CMD-SHELL cat /status]\n")
// Start // Start

View file

@ -85,7 +85,7 @@ func (s *DockerSuite) TestInspectTypeFlagContainer(c *check.C) {
dockerCmd(c, "run", "--name=busybox", "-d", "busybox", "top") dockerCmd(c, "run", "--name=busybox", "-d", "busybox", "top")
formatStr := "--format='{{.State.Running}}'" formatStr := "--format={{.State.Running}}"
out, _ := dockerCmd(c, "inspect", "--type=container", formatStr, "busybox") out, _ := dockerCmd(c, "inspect", "--type=container", formatStr, "busybox")
c.Assert(out, checker.Equals, "true\n") // not a container JSON c.Assert(out, checker.Equals, "true\n") // not a container JSON
} }
@ -137,7 +137,7 @@ func (s *DockerSuite) TestInspectImageFilterInt(c *check.C) {
c.Assert(err, checker.IsNil, check.Commentf("failed to inspect size of the image: %s, %v", out, err)) c.Assert(err, checker.IsNil, check.Commentf("failed to inspect size of the image: %s, %v", out, err))
//now see if the size turns out to be the same //now see if the size turns out to be the same
formatStr := fmt.Sprintf("--format='{{eq .Size %d}}'", size) formatStr := fmt.Sprintf("--format={{eq .Size %d}}", size)
out, _ = dockerCmd(c, "inspect", formatStr, imageTest) out, _ = dockerCmd(c, "inspect", formatStr, imageTest)
result, err := strconv.ParseBool(strings.TrimSuffix(out, "\n")) result, err := strconv.ParseBool(strings.TrimSuffix(out, "\n"))
c.Assert(err, checker.IsNil) c.Assert(err, checker.IsNil)
@ -159,7 +159,7 @@ func (s *DockerSuite) TestInspectContainerFilterInt(c *check.C) {
c.Assert(err, checker.IsNil, check.Commentf("failed to inspect exitcode of the container: %s, %v", out, err)) c.Assert(err, checker.IsNil, check.Commentf("failed to inspect exitcode of the container: %s, %v", out, err))
//now get the exit code to verify //now get the exit code to verify
formatStr := fmt.Sprintf("--format='{{eq .State.ExitCode %d}}'", exitCode) formatStr := fmt.Sprintf("--format={{eq .State.ExitCode %d}}", exitCode)
out, _ = dockerCmd(c, "inspect", formatStr, id) out, _ = dockerCmd(c, "inspect", formatStr, id)
result, err := strconv.ParseBool(strings.TrimSuffix(out, "\n")) result, err := strconv.ParseBool(strings.TrimSuffix(out, "\n"))
c.Assert(err, checker.IsNil) c.Assert(err, checker.IsNil)
@ -312,7 +312,7 @@ func (s *DockerSuite) TestInspectNoSizeFlagContainer(c *check.C) {
runSleepingContainer(c, "--name=busybox", "-d") runSleepingContainer(c, "--name=busybox", "-d")
formatStr := "--format='{{.SizeRw}},{{.SizeRootFs}}'" formatStr := "--format={{.SizeRw}},{{.SizeRootFs}}"
out, _ := dockerCmd(c, "inspect", "--type=container", formatStr, "busybox") out, _ := dockerCmd(c, "inspect", "--type=container", formatStr, "busybox")
c.Assert(strings.TrimSpace(out), check.Equals, "<nil>,<nil>", check.Commentf("Exepcted not to display size info: %s", out)) c.Assert(strings.TrimSpace(out), check.Equals, "<nil>,<nil>", check.Commentf("Exepcted not to display size info: %s", out))
} }
@ -356,7 +356,7 @@ func (s *DockerSuite) TestInspectTemplateError(c *check.C) {
func (s *DockerSuite) TestInspectJSONFields(c *check.C) { func (s *DockerSuite) TestInspectJSONFields(c *check.C) {
runSleepingContainer(c, "--name=busybox", "-d") runSleepingContainer(c, "--name=busybox", "-d")
out, _, err := dockerCmdWithError("inspect", "--type=container", "--format='{{.HostConfig.Dns}}'", "busybox") out, _, err := dockerCmdWithError("inspect", "--type=container", "--format={{.HostConfig.Dns}}", "busybox")
c.Assert(err, check.IsNil) c.Assert(err, check.IsNil)
c.Assert(out, checker.Equals, "[]\n") c.Assert(out, checker.Equals, "[]\n")

View file

@ -63,7 +63,7 @@ func (s *DockerSuite) TestRenameCheckNames(c *check.C) {
name, err := inspectFieldWithError("first_name", "Name") name, err := inspectFieldWithError("first_name", "Name")
c.Assert(err, checker.NotNil, check.Commentf(name)) c.Assert(err, checker.NotNil, check.Commentf(name))
c.Assert(err.Error(), checker.Contains, "No such image, container or task: first_name") c.Assert(err.Error(), checker.Contains, "No such container, image or task: first_name")
} }
func (s *DockerSuite) TestRenameInvalidName(c *check.C) { func (s *DockerSuite) TestRenameInvalidName(c *check.C) {
@ -129,7 +129,7 @@ func (s *DockerSuite) TestRenameContainerWithLinkedContainer(c *check.C) {
db1, _ := dockerCmd(c, "run", "--name", "db1", "-d", "busybox", "top") db1, _ := dockerCmd(c, "run", "--name", "db1", "-d", "busybox", "top")
dockerCmd(c, "run", "--name", "app1", "-d", "--link", "db1:/mysql", "busybox", "top") dockerCmd(c, "run", "--name", "app1", "-d", "--link", "db1:/mysql", "busybox", "top")
dockerCmd(c, "rename", "app1", "app2") dockerCmd(c, "rename", "app1", "app2")
out, _, err := dockerCmdWithError("inspect", "--format='{{ .Id }}'", "app2/mysql") out, _, err := dockerCmdWithError("inspect", "--format={{ .Id }}", "app2/mysql")
c.Assert(err, checker.IsNil) c.Assert(err, checker.IsNil)
c.Assert(strings.TrimSpace(out), checker.Equals, strings.TrimSpace(db1)) c.Assert(strings.TrimSpace(out), checker.Equals, strings.TrimSpace(db1))
} }

View file

@ -45,7 +45,7 @@ func (s *DockerDaemonSuite) TestDaemonUserNamespaceRootSetting(c *check.C) {
user := s.findUser(c, "userns") user := s.findUser(c, "userns")
c.Assert(uidgid[0], checker.Equals, user) c.Assert(uidgid[0], checker.Equals, user)
pid, err := s.d.Cmd("inspect", "--format='{{.State.Pid}}'", "userns") pid, err := s.d.Cmd("inspect", "--format={{.State.Pid}}", "userns")
c.Assert(err, checker.IsNil, check.Commentf("Could not inspect running container: out: %q", pid)) c.Assert(err, checker.IsNil, check.Commentf("Could not inspect running container: out: %q", pid))
// check the uid and gid maps for the PID to ensure root is remapped // check the uid and gid maps for the PID to ensure root is remapped
// (cmd = cat /proc/<pid>/uid_map | grep -E '0\s+9999\s+1') // (cmd = cat /proc/<pid>/uid_map | grep -E '0\s+9999\s+1')