mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Refactor docker inspect
to work on all types
Signed-off-by: Arnaud Porterie (icecrime) <arnaud.porterie@docker.com>
This commit is contained in:
parent
15f3d060ac
commit
3db9f7afce
5 changed files with 98 additions and 63 deletions
|
@ -36,68 +36,101 @@ func NewInspectCommand(dockerCli *client.DockerCli) *cobra.Command {
|
||||||
|
|
||||||
flags := cmd.Flags()
|
flags := cmd.Flags()
|
||||||
flags.StringVarP(&opts.format, "format", "f", "", "Format the output using the given go template")
|
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.StringVar(&opts.inspectType, "type", "", "Return JSON for specified type")
|
||||||
flags.BoolVarP(&opts.size, "size", "s", false, "Display total file sizes if the type is container")
|
flags.BoolVarP(&opts.size, "size", "s", false, "Display total file sizes if the type is container")
|
||||||
|
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
func runInspect(dockerCli *client.DockerCli, opts inspectOptions) error {
|
func runInspect(dockerCli *client.DockerCli, opts inspectOptions) error {
|
||||||
ctx := context.Background()
|
var elementSearcher inspect.GetRefFunc
|
||||||
client := dockerCli.Client()
|
|
||||||
|
|
||||||
var getRefFunc inspect.GetRefFunc
|
|
||||||
switch opts.inspectType {
|
switch opts.inspectType {
|
||||||
case "container":
|
case "", "container", "image", "node", "network", "service", "volume", "task":
|
||||||
getRefFunc = func(ref string) (interface{}, []byte, error) {
|
elementSearcher = inspectAll(context.Background(), dockerCli, opts.size, opts.inspectType)
|
||||||
return client.ContainerInspectWithRaw(ctx, ref, opts.size)
|
|
||||||
}
|
|
||||||
case "image":
|
|
||||||
getRefFunc = func(ref string) (interface{}, []byte, error) {
|
|
||||||
return client.ImageInspectWithRaw(ctx, ref)
|
|
||||||
}
|
|
||||||
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:
|
default:
|
||||||
return fmt.Errorf("%q is not a valid value for --type", opts.inspectType)
|
return fmt.Errorf("%q is not a valid value for --type", opts.inspectType)
|
||||||
}
|
}
|
||||||
|
return inspect.Inspect(dockerCli.Out(), opts.ids, opts.format, elementSearcher)
|
||||||
return inspect.Inspect(dockerCli.Out(), opts.ids, opts.format, getRefFunc)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func inspectAll(ctx context.Context, dockerCli *client.DockerCli, getSize bool) inspect.GetRefFunc {
|
func inspectContainers(ctx context.Context, dockerCli *client.DockerCli, getSize bool) inspect.GetRefFunc {
|
||||||
client := dockerCli.Client()
|
|
||||||
|
|
||||||
return func(ref string) (interface{}, []byte, error) {
|
return func(ref string) (interface{}, []byte, error) {
|
||||||
c, rawContainer, err := client.ContainerInspectWithRaw(ctx, ref, getSize)
|
return dockerCli.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)
|
|
||||||
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 {
|
func inspectImages(ctx context.Context, dockerCli *client.DockerCli) inspect.GetRefFunc {
|
||||||
return strings.Contains(err.Error(), "This node is not a swarm manager")
|
return func(ref string) (interface{}, []byte, error) {
|
||||||
|
return dockerCli.Client().ImageInspectWithRaw(ctx, ref)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func inspectNetwork(ctx context.Context, dockerCli *client.DockerCli) inspect.GetRefFunc {
|
||||||
|
return func(ref string) (interface{}, []byte, error) {
|
||||||
|
return dockerCli.Client().NetworkInspectWithRaw(ctx, ref)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func inspectNode(ctx context.Context, dockerCli *client.DockerCli) inspect.GetRefFunc {
|
||||||
|
return func(ref string) (interface{}, []byte, error) {
|
||||||
|
return dockerCli.Client().NodeInspectWithRaw(ctx, ref)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func inspectService(ctx context.Context, dockerCli *client.DockerCli) inspect.GetRefFunc {
|
||||||
|
return func(ref string) (interface{}, []byte, error) {
|
||||||
|
return dockerCli.Client().ServiceInspectWithRaw(ctx, ref)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func inspectTasks(ctx context.Context, dockerCli *client.DockerCli) inspect.GetRefFunc {
|
||||||
|
return func(ref string) (interface{}, []byte, error) {
|
||||||
|
return dockerCli.Client().TaskInspectWithRaw(ctx, ref)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func inspectVolume(ctx context.Context, dockerCli *client.DockerCli) inspect.GetRefFunc {
|
||||||
|
return func(ref string) (interface{}, []byte, error) {
|
||||||
|
return dockerCli.Client().VolumeInspectWithRaw(ctx, ref)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func inspectAll(ctx context.Context, dockerCli *client.DockerCli, getSize bool, typeConstraint string) inspect.GetRefFunc {
|
||||||
|
var inspectAutodetect = []struct {
|
||||||
|
ObjectType string
|
||||||
|
IsSizeSupported bool
|
||||||
|
ObjectInspector func(string) (interface{}, []byte, error)
|
||||||
|
}{
|
||||||
|
{"container", true, inspectContainers(ctx, dockerCli, getSize)},
|
||||||
|
{"image", true, inspectImages(ctx, dockerCli)},
|
||||||
|
{"network", false, inspectNetwork(ctx, dockerCli)},
|
||||||
|
{"volume", false, inspectVolume(ctx, dockerCli)},
|
||||||
|
{"service", false, inspectService(ctx, dockerCli)},
|
||||||
|
{"task", false, inspectTasks(ctx, dockerCli)},
|
||||||
|
{"node", false, inspectNode(ctx, dockerCli)},
|
||||||
|
}
|
||||||
|
|
||||||
|
isErrNotSwarmManager := func(err error) bool {
|
||||||
|
return strings.Contains(err.Error(), "This node is not a swarm manager")
|
||||||
|
}
|
||||||
|
|
||||||
|
return func(ref string) (interface{}, []byte, error) {
|
||||||
|
for _, inspectData := range inspectAutodetect {
|
||||||
|
if typeConstraint != "" && inspectData.ObjectType != typeConstraint {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
v, raw, err := inspectData.ObjectInspector(ref)
|
||||||
|
if err != nil {
|
||||||
|
if typeConstraint == "" && (apiclient.IsErrNotFound(err) || isErrNotSwarmManager(err)) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
return v, raw, err
|
||||||
|
}
|
||||||
|
if !inspectData.IsSizeSupported {
|
||||||
|
fmt.Fprintf(dockerCli.Err(), "WARNING: --size ignored for %s\n", inspectData.ObjectType)
|
||||||
|
}
|
||||||
|
return v, raw, err
|
||||||
|
}
|
||||||
|
return nil, nil, fmt.Errorf("Error: No such object: %s", ref)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,15 +11,16 @@ parent = "smn_cli"
|
||||||
# inspect
|
# inspect
|
||||||
|
|
||||||
```markdown
|
```markdown
|
||||||
Usage: docker inspect [OPTIONS] CONTAINER|IMAGE|TASK [CONTAINER|IMAGE|TASK...]
|
Usage: docker inspect [OPTIONS] NAME|ID [NAME|ID...]
|
||||||
|
|
||||||
Return low-level information on a container, image or task
|
Return low-level information on one or multiple containers, images, volumes,
|
||||||
|
networks, nodes, services, or tasks identified by name or ID.
|
||||||
|
|
||||||
-f, --format Format the output using the given go template
|
-f, --format Format the output using the given go template
|
||||||
--help Print usage
|
--help Print usage
|
||||||
-s, --size Display total file sizes if the type is container
|
-s, --size Display total file sizes if the type is container
|
||||||
values are "image" or "container" or "task
|
values are "image" or "container" or "task
|
||||||
--type Return JSON for specified type, (e.g image, container or task)
|
--type Return JSON for specified type
|
||||||
```
|
```
|
||||||
|
|
||||||
By default, this will render all results in a JSON array. If the container and
|
By default, this will render all results in a JSON array. If the container and
|
||||||
|
|
|
@ -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 container, image")
|
c.Assert(err.Error(), checker.Contains, "No such object")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *DockerRegistrySuite) TestBuildByDigest(c *check.C) {
|
func (s *DockerRegistrySuite) TestBuildByDigest(c *check.C) {
|
||||||
|
|
|
@ -65,7 +65,7 @@ func (s *DockerSuite) TestRenameCheckNames(c *check.C) {
|
||||||
result := dockerCmdWithResult("inspect", "-f={{.Name}}", "first_name")
|
result := dockerCmdWithResult("inspect", "-f={{.Name}}", "first_name")
|
||||||
c.Assert(result, icmd.Matches, icmd.Expected{
|
c.Assert(result, icmd.Matches, icmd.Expected{
|
||||||
ExitCode: 1,
|
ExitCode: 1,
|
||||||
Err: "No such container, image or task: first_name",
|
Err: "No such object: first_name",
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,23 +2,23 @@
|
||||||
% Docker Community
|
% Docker Community
|
||||||
% JUNE 2014
|
% JUNE 2014
|
||||||
# NAME
|
# NAME
|
||||||
docker-inspect - Return low-level information on a container or image
|
docker-inspect - Return low-level information on docker objects
|
||||||
|
|
||||||
# SYNOPSIS
|
# SYNOPSIS
|
||||||
**docker inspect**
|
**docker inspect**
|
||||||
[**--help**]
|
[**--help**]
|
||||||
[**-f**|**--format**[=*FORMAT*]]
|
[**-f**|**--format**[=*FORMAT*]]
|
||||||
[**-s**|**--size**]
|
[**-s**|**--size**]
|
||||||
[**--type**=*container*|*image*]
|
[**--type**=*container*|*image*|*network*|*node*|*service*|*task*|*volume*]
|
||||||
CONTAINER|IMAGE [CONTAINER|IMAGE...]
|
NAME|ID [NAME|ID...]
|
||||||
|
|
||||||
# DESCRIPTION
|
# DESCRIPTION
|
||||||
|
|
||||||
This displays all the information available in Docker for a given
|
This displays all the information available in Docker for one or multiple given
|
||||||
container or image. By default, this will render all results in a JSON
|
containers, images, volumes, networks, nodes, services, or tasks. By default,
|
||||||
array. If the container and image have the same name, this will return
|
this will render all results in a JSON array. If the container and image have
|
||||||
container JSON for unspecified type. If a format is specified, the given
|
the same name, this will return container JSON for unspecified type. If a format
|
||||||
template will be executed for each result.
|
is specified, the given template will be executed for each result.
|
||||||
|
|
||||||
# OPTIONS
|
# OPTIONS
|
||||||
**--help**
|
**--help**
|
||||||
|
@ -30,8 +30,9 @@ template will be executed for each result.
|
||||||
**-s**, **--size**
|
**-s**, **--size**
|
||||||
Display total file sizes if the type is container.
|
Display total file sizes if the type is container.
|
||||||
|
|
||||||
**--type**="*container*|*image*"
|
**--type**=*container*|*image*|*network*|*node*|*service*|*task*|*volume*
|
||||||
Return JSON for specified type, permissible values are "image" or "container"
|
Return JSON for specified type, permissible values are "image", "container",
|
||||||
|
"network", "node", "service", "task", and "volume".
|
||||||
|
|
||||||
# EXAMPLES
|
# EXAMPLES
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue