docker_cli_inspect_test.go 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383
  1. package main
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "os/exec"
  6. "strconv"
  7. "strings"
  8. "time"
  9. "github.com/docker/docker/api/types"
  10. "github.com/docker/docker/runconfig"
  11. "github.com/go-check/check"
  12. )
  13. func (s *DockerSuite) TestInspectImage(c *check.C) {
  14. testRequires(c, DaemonIsLinux)
  15. imageTest := "emptyfs"
  16. imageTestID := "511136ea3c5a64f264b78b5433614aec563103b4d4702f3ba7d4d2698e22c158"
  17. id, err := inspectField(imageTest, "Id")
  18. c.Assert(err, check.IsNil)
  19. if id != imageTestID {
  20. c.Fatalf("Expected id: %s for image: %s but received id: %s", imageTestID, imageTest, id)
  21. }
  22. }
  23. func (s *DockerSuite) TestInspectInt64(c *check.C) {
  24. testRequires(c, DaemonIsLinux)
  25. dockerCmd(c, "run", "-d", "-m=300M", "--name", "inspectTest", "busybox", "true")
  26. inspectOut, err := inspectField("inspectTest", "HostConfig.Memory")
  27. c.Assert(err, check.IsNil)
  28. if inspectOut != "314572800" {
  29. c.Fatalf("inspect got wrong value, got: %q, expected: 314572800", inspectOut)
  30. }
  31. }
  32. func (s *DockerSuite) TestInspectDefault(c *check.C) {
  33. testRequires(c, DaemonIsLinux)
  34. //Both the container and image are named busybox. docker inspect will fetch the container JSON.
  35. //If the container JSON is not available, it will go for the image JSON.
  36. dockerCmd(c, "run", "--name=busybox", "-d", "busybox", "true")
  37. dockerCmd(c, "inspect", "busybox")
  38. }
  39. func (s *DockerSuite) TestInspectStatus(c *check.C) {
  40. defer unpauseAllContainers()
  41. testRequires(c, DaemonIsLinux)
  42. out, _ := dockerCmd(c, "run", "-d", "busybox", "top")
  43. out = strings.TrimSpace(out)
  44. inspectOut, err := inspectField(out, "State.Status")
  45. c.Assert(err, check.IsNil)
  46. if inspectOut != "running" {
  47. c.Fatalf("inspect got wrong status, got: %q, expected: running", inspectOut)
  48. }
  49. dockerCmd(c, "pause", out)
  50. inspectOut, err = inspectField(out, "State.Status")
  51. c.Assert(err, check.IsNil)
  52. if inspectOut != "paused" {
  53. c.Fatalf("inspect got wrong status, got: %q, expected: paused", inspectOut)
  54. }
  55. dockerCmd(c, "unpause", out)
  56. inspectOut, err = inspectField(out, "State.Status")
  57. c.Assert(err, check.IsNil)
  58. if inspectOut != "running" {
  59. c.Fatalf("inspect got wrong status, got: %q, expected: running", inspectOut)
  60. }
  61. dockerCmd(c, "stop", out)
  62. inspectOut, err = inspectField(out, "State.Status")
  63. c.Assert(err, check.IsNil)
  64. if inspectOut != "exited" {
  65. c.Fatalf("inspect got wrong status, got: %q, expected: exited", inspectOut)
  66. }
  67. }
  68. func (s *DockerSuite) TestInspectTypeFlagContainer(c *check.C) {
  69. testRequires(c, DaemonIsLinux)
  70. //Both the container and image are named busybox. docker inspect will fetch container
  71. //JSON State.Running field. If the field is true, it's a container.
  72. dockerCmd(c, "run", "--name=busybox", "-d", "busybox", "top")
  73. formatStr := fmt.Sprintf("--format='{{.State.Running}}'")
  74. out, exitCode, err := dockerCmdWithError("inspect", "--type=container", formatStr, "busybox")
  75. if exitCode != 0 || err != nil {
  76. c.Fatalf("failed to inspect container: %s, %v", out, err)
  77. }
  78. if out != "true\n" {
  79. c.Fatal("not a container JSON")
  80. }
  81. }
  82. func (s *DockerSuite) TestInspectTypeFlagWithNoContainer(c *check.C) {
  83. testRequires(c, DaemonIsLinux)
  84. //Run this test on an image named busybox. docker inspect will try to fetch container
  85. //JSON. Since there is no container named busybox and --type=container, docker inspect will
  86. //not try to get the image JSON. It will throw an error.
  87. dockerCmd(c, "run", "-d", "busybox", "true")
  88. _, exitCode, err := dockerCmdWithError("inspect", "--type=container", "busybox")
  89. if exitCode == 0 || err == nil {
  90. c.Fatalf("docker inspect should have failed, as there is no container named busybox")
  91. }
  92. }
  93. func (s *DockerSuite) TestInspectTypeFlagWithImage(c *check.C) {
  94. testRequires(c, DaemonIsLinux)
  95. //Both the container and image are named busybox. docker inspect will fetch image
  96. //JSON as --type=image. if there is no image with name busybox, docker inspect
  97. //will throw an error.
  98. dockerCmd(c, "run", "--name=busybox", "-d", "busybox", "true")
  99. out, exitCode, err := dockerCmdWithError("inspect", "--type=image", "busybox")
  100. if exitCode != 0 || err != nil {
  101. c.Fatalf("failed to inspect image: %s, %v", out, err)
  102. }
  103. if strings.Contains(out, "State") {
  104. c.Fatal("not an image JSON")
  105. }
  106. }
  107. func (s *DockerSuite) TestInspectTypeFlagWithInvalidValue(c *check.C) {
  108. testRequires(c, DaemonIsLinux)
  109. //Both the container and image are named busybox. docker inspect will fail
  110. //as --type=foobar is not a valid value for the flag.
  111. dockerCmd(c, "run", "--name=busybox", "-d", "busybox", "true")
  112. out, exitCode, err := dockerCmdWithError("inspect", "--type=foobar", "busybox")
  113. if exitCode != 0 || err != nil {
  114. if !strings.Contains(out, "not a valid value for --type") {
  115. c.Fatalf("failed to inspect image: %s, %v", out, err)
  116. }
  117. }
  118. }
  119. func (s *DockerSuite) TestInspectImageFilterInt(c *check.C) {
  120. testRequires(c, DaemonIsLinux)
  121. imageTest := "emptyfs"
  122. out, err := inspectField(imageTest, "Size")
  123. c.Assert(err, check.IsNil)
  124. size, err := strconv.Atoi(out)
  125. if err != nil {
  126. c.Fatalf("failed to inspect size of the image: %s, %v", out, err)
  127. }
  128. //now see if the size turns out to be the same
  129. formatStr := fmt.Sprintf("--format='{{eq .Size %d}}'", size)
  130. out, exitCode, err := dockerCmdWithError("inspect", formatStr, imageTest)
  131. if exitCode != 0 || err != nil {
  132. c.Fatalf("failed to inspect image: %s, %v", out, err)
  133. }
  134. if result, err := strconv.ParseBool(strings.TrimSuffix(out, "\n")); err != nil || !result {
  135. c.Fatalf("Expected size: %d for image: %s but received size: %s", size, imageTest, strings.TrimSuffix(out, "\n"))
  136. }
  137. }
  138. func (s *DockerSuite) TestInspectContainerFilterInt(c *check.C) {
  139. testRequires(c, DaemonIsLinux)
  140. runCmd := exec.Command(dockerBinary, "run", "-i", "-a", "stdin", "busybox", "cat")
  141. runCmd.Stdin = strings.NewReader("blahblah")
  142. out, _, _, err := runCommandWithStdoutStderr(runCmd)
  143. if err != nil {
  144. c.Fatalf("failed to run container: %v, output: %q", err, out)
  145. }
  146. id := strings.TrimSpace(out)
  147. out, err = inspectField(id, "State.ExitCode")
  148. c.Assert(err, check.IsNil)
  149. exitCode, err := strconv.Atoi(out)
  150. if err != nil {
  151. c.Fatalf("failed to inspect exitcode of the container: %s, %v", out, err)
  152. }
  153. //now get the exit code to verify
  154. formatStr := fmt.Sprintf("--format='{{eq .State.ExitCode %d}}'", exitCode)
  155. out, _ = dockerCmd(c, "inspect", formatStr, id)
  156. if result, err := strconv.ParseBool(strings.TrimSuffix(out, "\n")); err != nil || !result {
  157. c.Fatalf("Expected exitcode: %d for container: %s", exitCode, id)
  158. }
  159. }
  160. func (s *DockerSuite) TestInspectImageGraphDriver(c *check.C) {
  161. testRequires(c, DaemonIsLinux)
  162. imageTest := "emptyfs"
  163. name, err := inspectField(imageTest, "GraphDriver.Name")
  164. c.Assert(err, check.IsNil)
  165. if name != "devicemapper" && name != "overlay" && name != "vfs" && name != "zfs" && name != "btrfs" && name != "aufs" {
  166. c.Fatalf("%v is not a valid graph driver name", name)
  167. }
  168. if name != "devicemapper" {
  169. return
  170. }
  171. deviceID, err := inspectField(imageTest, "GraphDriver.Data.DeviceId")
  172. c.Assert(err, check.IsNil)
  173. _, err = strconv.Atoi(deviceID)
  174. if err != nil {
  175. c.Fatalf("failed to inspect DeviceId of the image: %s, %v", deviceID, err)
  176. }
  177. deviceSize, err := inspectField(imageTest, "GraphDriver.Data.DeviceSize")
  178. c.Assert(err, check.IsNil)
  179. _, err = strconv.ParseUint(deviceSize, 10, 64)
  180. if err != nil {
  181. c.Fatalf("failed to inspect DeviceSize of the image: %s, %v", deviceSize, err)
  182. }
  183. }
  184. func (s *DockerSuite) TestInspectContainerGraphDriver(c *check.C) {
  185. testRequires(c, DaemonIsLinux)
  186. out, _ := dockerCmd(c, "run", "-d", "busybox", "true")
  187. out = strings.TrimSpace(out)
  188. name, err := inspectField(out, "GraphDriver.Name")
  189. c.Assert(err, check.IsNil)
  190. if name != "devicemapper" && name != "overlay" && name != "vfs" && name != "zfs" && name != "btrfs" && name != "aufs" {
  191. c.Fatalf("%v is not a valid graph driver name", name)
  192. }
  193. if name != "devicemapper" {
  194. return
  195. }
  196. deviceID, err := inspectField(out, "GraphDriver.Data.DeviceId")
  197. c.Assert(err, check.IsNil)
  198. _, err = strconv.Atoi(deviceID)
  199. if err != nil {
  200. c.Fatalf("failed to inspect DeviceId of the image: %s, %v", deviceID, err)
  201. }
  202. deviceSize, err := inspectField(out, "GraphDriver.Data.DeviceSize")
  203. c.Assert(err, check.IsNil)
  204. _, err = strconv.ParseUint(deviceSize, 10, 64)
  205. if err != nil {
  206. c.Fatalf("failed to inspect DeviceSize of the image: %s, %v", deviceSize, err)
  207. }
  208. }
  209. func (s *DockerSuite) TestInspectBindMountPoint(c *check.C) {
  210. testRequires(c, DaemonIsLinux)
  211. dockerCmd(c, "run", "-d", "--name", "test", "-v", "/data:/data:ro,z", "busybox", "cat")
  212. vol, err := inspectFieldJSON("test", "Mounts")
  213. c.Assert(err, check.IsNil)
  214. var mp []types.MountPoint
  215. err = unmarshalJSON([]byte(vol), &mp)
  216. c.Assert(err, check.IsNil)
  217. if len(mp) != 1 {
  218. c.Fatalf("Expected 1 mount point, was %v\n", len(mp))
  219. }
  220. m := mp[0]
  221. if m.Name != "" {
  222. c.Fatal("Expected name to be empty")
  223. }
  224. if m.Driver != "" {
  225. c.Fatal("Expected driver to be empty")
  226. }
  227. if m.Source != "/data" {
  228. c.Fatalf("Expected source /data, was %s\n", m.Source)
  229. }
  230. if m.Destination != "/data" {
  231. c.Fatalf("Expected destination /data, was %s\n", m.Destination)
  232. }
  233. if m.Mode != "ro,z" {
  234. c.Fatalf("Expected mode `ro,z`, was %s\n", m.Mode)
  235. }
  236. if m.RW != false {
  237. c.Fatalf("Expected rw to be false")
  238. }
  239. }
  240. // #14947
  241. func (s *DockerSuite) TestInspectTimesAsRFC3339Nano(c *check.C) {
  242. testRequires(c, DaemonIsLinux)
  243. out, _ := dockerCmd(c, "run", "-d", "busybox", "true")
  244. id := strings.TrimSpace(out)
  245. startedAt, err := inspectField(id, "State.StartedAt")
  246. c.Assert(err, check.IsNil)
  247. finishedAt, err := inspectField(id, "State.FinishedAt")
  248. c.Assert(err, check.IsNil)
  249. created, err := inspectField(id, "Created")
  250. c.Assert(err, check.IsNil)
  251. _, err = time.Parse(time.RFC3339Nano, startedAt)
  252. c.Assert(err, check.IsNil)
  253. _, err = time.Parse(time.RFC3339Nano, finishedAt)
  254. c.Assert(err, check.IsNil)
  255. _, err = time.Parse(time.RFC3339Nano, created)
  256. c.Assert(err, check.IsNil)
  257. created, err = inspectField("busybox", "Created")
  258. c.Assert(err, check.IsNil)
  259. _, err = time.Parse(time.RFC3339Nano, created)
  260. c.Assert(err, check.IsNil)
  261. }
  262. // #15633
  263. func (s *DockerSuite) TestInspectLogConfigNoType(c *check.C) {
  264. testRequires(c, DaemonIsLinux)
  265. dockerCmd(c, "create", "--name=test", "--log-opt", "max-file=42", "busybox")
  266. var logConfig runconfig.LogConfig
  267. out, err := inspectFieldJSON("test", "HostConfig.LogConfig")
  268. c.Assert(err, check.IsNil)
  269. err = json.NewDecoder(strings.NewReader(out)).Decode(&logConfig)
  270. c.Assert(err, check.IsNil)
  271. c.Assert(logConfig.Type, check.Equals, "json-file")
  272. c.Assert(logConfig.Config["max-file"], check.Equals, "42", check.Commentf("%v", logConfig))
  273. }
  274. func (s *DockerSuite) TestInspectNoSizeFlagContainer(c *check.C) {
  275. //Both the container and image are named busybox. docker inspect will fetch container
  276. //JSON SizeRw and SizeRootFs field. If there is no flag --size/-s, there are no size fields.
  277. dockerCmd(c, "run", "--name=busybox", "-d", "busybox", "top")
  278. formatStr := fmt.Sprintf("--format='{{.SizeRw}},{{.SizeRootFs}}'")
  279. out, _ := dockerCmd(c, "inspect", "--type=container", formatStr, "busybox")
  280. c.Assert(strings.TrimSpace(out), check.Equals, "<nil>,<nil>", check.Commentf("Exepcted not to display size info: %s", out))
  281. }
  282. func (s *DockerSuite) TestInspectSizeFlagContainer(c *check.C) {
  283. //Both the container and image are named busybox. docker inspect will fetch container
  284. //JSON SizeRw and SizeRootFs field. If there is a flag --size/-s, the fields are not <no value>.
  285. dockerCmd(c, "run", "--name=busybox", "-d", "busybox", "top")
  286. formatStr := fmt.Sprintf("--format='{{.SizeRw}},{{.SizeRootFs}}'")
  287. out, _ := dockerCmd(c, "inspect", "-s", "--type=container", formatStr, "busybox")
  288. sz := strings.Split(out, ",")
  289. c.Assert(strings.TrimSpace(sz[0]), check.Not(check.Equals), "<nil>")
  290. c.Assert(strings.TrimSpace(sz[1]), check.Not(check.Equals), "<nil>")
  291. }
  292. func (s *DockerSuite) TestInspectSizeFlagImage(c *check.C) {
  293. //Both the container and image are named busybox. docker inspect will fetch image
  294. //JSON SizeRw and SizeRootFs field. There are no these fields since they are only in containers.
  295. dockerCmd(c, "run", "--name=busybox", "-d", "busybox", "top")
  296. formatStr := fmt.Sprintf("--format='{{.SizeRw}},{{.SizeRootFs}}'")
  297. out, _ := dockerCmd(c, "inspect", "-s", "--type=image", formatStr, "busybox")
  298. c.Assert(strings.TrimSpace(out), check.Equals, "<no value>,<no value>", check.Commentf("Fields SizeRw and SizeRootFs are not exepcted to exist"))
  299. }