inspect.go 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. package client
  2. import (
  3. "fmt"
  4. "github.com/docker/docker/api/client/inspect"
  5. Cli "github.com/docker/docker/cli"
  6. flag "github.com/docker/docker/pkg/mflag"
  7. "github.com/docker/docker/utils/templates"
  8. "github.com/docker/engine-api/client"
  9. )
  10. // CmdInspect displays low-level information on one or more containers or images.
  11. //
  12. // Usage: docker inspect [OPTIONS] CONTAINER|IMAGE [CONTAINER|IMAGE...]
  13. func (cli *DockerCli) CmdInspect(args ...string) error {
  14. cmd := Cli.Subcmd("inspect", []string{"CONTAINER|IMAGE [CONTAINER|IMAGE...]"}, Cli.DockerCommands["inspect"].Description, true)
  15. tmplStr := cmd.String([]string{"f", "-format"}, "", "Format the output using the given go template")
  16. inspectType := cmd.String([]string{"-type"}, "", "Return JSON for specified type, (e.g image or container)")
  17. size := cmd.Bool([]string{"s", "-size"}, false, "Display total file sizes if the type is container")
  18. cmd.Require(flag.Min, 1)
  19. cmd.ParseFlags(args, true)
  20. if *inspectType != "" && *inspectType != "container" && *inspectType != "image" {
  21. return fmt.Errorf("%q is not a valid value for --type", *inspectType)
  22. }
  23. var elementSearcher inspectSearcher
  24. switch *inspectType {
  25. case "container":
  26. elementSearcher = cli.inspectContainers(*size)
  27. case "image":
  28. elementSearcher = cli.inspectImages(*size)
  29. default:
  30. elementSearcher = cli.inspectAll(*size)
  31. }
  32. return cli.inspectElements(*tmplStr, cmd.Args(), elementSearcher)
  33. }
  34. func (cli *DockerCli) inspectContainers(getSize bool) inspectSearcher {
  35. return func(ref string) (interface{}, []byte, error) {
  36. return cli.client.ContainerInspectWithRaw(ref, getSize)
  37. }
  38. }
  39. func (cli *DockerCli) inspectImages(getSize bool) inspectSearcher {
  40. return func(ref string) (interface{}, []byte, error) {
  41. return cli.client.ImageInspectWithRaw(ref, getSize)
  42. }
  43. }
  44. func (cli *DockerCli) inspectAll(getSize bool) inspectSearcher {
  45. return func(ref string) (interface{}, []byte, error) {
  46. c, rawContainer, err := cli.client.ContainerInspectWithRaw(ref, getSize)
  47. if err != nil {
  48. // Search for image with that id if a container doesn't exist.
  49. if client.IsErrContainerNotFound(err) {
  50. i, rawImage, err := cli.client.ImageInspectWithRaw(ref, getSize)
  51. if err != nil {
  52. if client.IsErrImageNotFound(err) {
  53. return nil, nil, fmt.Errorf("Error: No such image or container: %s", ref)
  54. }
  55. return nil, nil, err
  56. }
  57. return i, rawImage, err
  58. }
  59. return nil, nil, err
  60. }
  61. return c, rawContainer, err
  62. }
  63. }
  64. type inspectSearcher func(ref string) (interface{}, []byte, error)
  65. func (cli *DockerCli) inspectElements(tmplStr string, references []string, searchByReference inspectSearcher) error {
  66. elementInspector, err := cli.newInspectorWithTemplate(tmplStr)
  67. if err != nil {
  68. return Cli.StatusError{StatusCode: 64, Status: err.Error()}
  69. }
  70. var inspectErr error
  71. for _, ref := range references {
  72. element, raw, err := searchByReference(ref)
  73. if err != nil {
  74. inspectErr = err
  75. break
  76. }
  77. if err := elementInspector.Inspect(element, raw); err != nil {
  78. inspectErr = err
  79. break
  80. }
  81. }
  82. if err := elementInspector.Flush(); err != nil {
  83. cli.inspectErrorStatus(err)
  84. }
  85. if status := cli.inspectErrorStatus(inspectErr); status != 0 {
  86. return Cli.StatusError{StatusCode: status}
  87. }
  88. return nil
  89. }
  90. func (cli *DockerCli) inspectErrorStatus(err error) (status int) {
  91. if err != nil {
  92. fmt.Fprintf(cli.err, "%s\n", err)
  93. status = 1
  94. }
  95. return
  96. }
  97. func (cli *DockerCli) newInspectorWithTemplate(tmplStr string) (inspect.Inspector, error) {
  98. elementInspector := inspect.NewIndentedInspector(cli.out)
  99. if tmplStr != "" {
  100. tmpl, err := templates.Parse(tmplStr)
  101. if err != nil {
  102. return nil, fmt.Errorf("Template parsing error: %s", err)
  103. }
  104. elementInspector = inspect.NewTemplateInspector(cli.out, tmpl)
  105. }
  106. return elementInspector, nil
  107. }