inspect.go 3.9 KB

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