github.com/reds/docker@v1.11.2-rc1/integration-cli/docker_cli_inspect_test.go (about) 1 package main 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "os/exec" 7 "strconv" 8 "strings" 9 "time" 10 11 "github.com/docker/docker/pkg/integration/checker" 12 "github.com/docker/engine-api/types" 13 "github.com/docker/engine-api/types/container" 14 "github.com/go-check/check" 15 ) 16 17 func checkValidGraphDriver(c *check.C, name string) { 18 if name != "devicemapper" && name != "overlay" && name != "vfs" && name != "zfs" && name != "btrfs" && name != "aufs" { 19 c.Fatalf("%v is not a valid graph driver name", name) 20 } 21 } 22 23 func (s *DockerSuite) TestInspectImage(c *check.C) { 24 testRequires(c, DaemonIsLinux) 25 imageTest := "emptyfs" 26 // It is important that this ID remain stable. If a code change causes 27 // it to be different, this is equivalent to a cache bust when pulling 28 // a legacy-format manifest. If the check at the end of this function 29 // fails, fix the difference in the image serialization instead of 30 // updating this hash. 31 imageTestID := "sha256:11f64303f0f7ffdc71f001788132bca5346831939a956e3e975c93267d89a16d" 32 id := inspectField(c, imageTest, "Id") 33 34 c.Assert(id, checker.Equals, imageTestID) 35 } 36 37 func (s *DockerSuite) TestInspectInt64(c *check.C) { 38 testRequires(c, DaemonIsLinux) 39 40 dockerCmd(c, "run", "-d", "-m=300M", "--name", "inspectTest", "busybox", "true") 41 inspectOut := inspectField(c, "inspectTest", "HostConfig.Memory") 42 c.Assert(inspectOut, checker.Equals, "314572800") 43 } 44 45 func (s *DockerSuite) TestInspectDefault(c *check.C) { 46 testRequires(c, DaemonIsLinux) 47 //Both the container and image are named busybox. docker inspect will fetch the container JSON. 48 //If the container JSON is not available, it will go for the image JSON. 49 50 out, _ := dockerCmd(c, "run", "--name=busybox", "-d", "busybox", "true") 51 containerID := strings.TrimSpace(out) 52 53 inspectOut := inspectField(c, "busybox", "Id") 54 c.Assert(strings.TrimSpace(inspectOut), checker.Equals, containerID) 55 } 56 57 func (s *DockerSuite) TestInspectStatus(c *check.C) { 58 defer unpauseAllContainers() 59 testRequires(c, DaemonIsLinux) 60 out, _ := dockerCmd(c, "run", "-d", "busybox", "top") 61 out = strings.TrimSpace(out) 62 63 inspectOut := inspectField(c, out, "State.Status") 64 c.Assert(inspectOut, checker.Equals, "running") 65 66 dockerCmd(c, "pause", out) 67 inspectOut = inspectField(c, out, "State.Status") 68 c.Assert(inspectOut, checker.Equals, "paused") 69 70 dockerCmd(c, "unpause", out) 71 inspectOut = inspectField(c, out, "State.Status") 72 c.Assert(inspectOut, checker.Equals, "running") 73 74 dockerCmd(c, "stop", out) 75 inspectOut = inspectField(c, out, "State.Status") 76 c.Assert(inspectOut, checker.Equals, "exited") 77 78 } 79 80 func (s *DockerSuite) TestInspectTypeFlagContainer(c *check.C) { 81 testRequires(c, DaemonIsLinux) 82 //Both the container and image are named busybox. docker inspect will fetch container 83 //JSON State.Running field. If the field is true, it's a container. 84 85 dockerCmd(c, "run", "--name=busybox", "-d", "busybox", "top") 86 87 formatStr := "--format='{{.State.Running}}'" 88 out, _ := dockerCmd(c, "inspect", "--type=container", formatStr, "busybox") 89 c.Assert(out, checker.Equals, "true\n") // not a container JSON 90 } 91 92 func (s *DockerSuite) TestInspectTypeFlagWithNoContainer(c *check.C) { 93 testRequires(c, DaemonIsLinux) 94 //Run this test on an image named busybox. docker inspect will try to fetch container 95 //JSON. Since there is no container named busybox and --type=container, docker inspect will 96 //not try to get the image JSON. It will throw an error. 97 98 dockerCmd(c, "run", "-d", "busybox", "true") 99 100 _, _, err := dockerCmdWithError("inspect", "--type=container", "busybox") 101 // docker inspect should fail, as there is no container named busybox 102 c.Assert(err, checker.NotNil) 103 } 104 105 func (s *DockerSuite) TestInspectTypeFlagWithImage(c *check.C) { 106 testRequires(c, DaemonIsLinux) 107 //Both the container and image are named busybox. docker inspect will fetch image 108 //JSON as --type=image. if there is no image with name busybox, docker inspect 109 //will throw an error. 110 111 dockerCmd(c, "run", "--name=busybox", "-d", "busybox", "true") 112 113 out, _ := dockerCmd(c, "inspect", "--type=image", "busybox") 114 c.Assert(out, checker.Not(checker.Contains), "State") // not an image JSON 115 } 116 117 func (s *DockerSuite) TestInspectTypeFlagWithInvalidValue(c *check.C) { 118 testRequires(c, DaemonIsLinux) 119 //Both the container and image are named busybox. docker inspect will fail 120 //as --type=foobar is not a valid value for the flag. 121 122 dockerCmd(c, "run", "--name=busybox", "-d", "busybox", "true") 123 124 out, exitCode, err := dockerCmdWithError("inspect", "--type=foobar", "busybox") 125 c.Assert(err, checker.NotNil, check.Commentf("%s", exitCode)) 126 c.Assert(exitCode, checker.Equals, 1, check.Commentf("%s", err)) 127 c.Assert(out, checker.Contains, "not a valid value for --type") 128 } 129 130 func (s *DockerSuite) TestInspectImageFilterInt(c *check.C) { 131 testRequires(c, DaemonIsLinux) 132 imageTest := "emptyfs" 133 out := inspectField(c, imageTest, "Size") 134 135 size, err := strconv.Atoi(out) 136 c.Assert(err, checker.IsNil, check.Commentf("failed to inspect size of the image: %s, %v", out, err)) 137 138 //now see if the size turns out to be the same 139 formatStr := fmt.Sprintf("--format='{{eq .Size %d}}'", size) 140 out, _ = dockerCmd(c, "inspect", formatStr, imageTest) 141 result, err := strconv.ParseBool(strings.TrimSuffix(out, "\n")) 142 c.Assert(err, checker.IsNil) 143 c.Assert(result, checker.Equals, true) 144 } 145 146 func (s *DockerSuite) TestInspectContainerFilterInt(c *check.C) { 147 testRequires(c, DaemonIsLinux) 148 runCmd := exec.Command(dockerBinary, "run", "-i", "-a", "stdin", "busybox", "cat") 149 runCmd.Stdin = strings.NewReader("blahblah") 150 out, _, _, err := runCommandWithStdoutStderr(runCmd) 151 c.Assert(err, checker.IsNil, check.Commentf("failed to run container: %v, output: %q", err, out)) 152 153 id := strings.TrimSpace(out) 154 155 out = inspectField(c, id, "State.ExitCode") 156 157 exitCode, err := strconv.Atoi(out) 158 c.Assert(err, checker.IsNil, check.Commentf("failed to inspect exitcode of the container: %s, %v", out, err)) 159 160 //now get the exit code to verify 161 formatStr := fmt.Sprintf("--format='{{eq .State.ExitCode %d}}'", exitCode) 162 out, _ = dockerCmd(c, "inspect", formatStr, id) 163 result, err := strconv.ParseBool(strings.TrimSuffix(out, "\n")) 164 c.Assert(err, checker.IsNil) 165 c.Assert(result, checker.Equals, true) 166 } 167 168 func (s *DockerSuite) TestInspectImageGraphDriver(c *check.C) { 169 testRequires(c, DaemonIsLinux, Devicemapper) 170 imageTest := "emptyfs" 171 name := inspectField(c, imageTest, "GraphDriver.Name") 172 173 checkValidGraphDriver(c, name) 174 175 deviceID := inspectField(c, imageTest, "GraphDriver.Data.DeviceId") 176 177 _, err := strconv.Atoi(deviceID) 178 c.Assert(err, checker.IsNil, check.Commentf("failed to inspect DeviceId of the image: %s, %v", deviceID, err)) 179 180 deviceSize := inspectField(c, imageTest, "GraphDriver.Data.DeviceSize") 181 182 _, err = strconv.ParseUint(deviceSize, 10, 64) 183 c.Assert(err, checker.IsNil, check.Commentf("failed to inspect DeviceSize of the image: %s, %v", deviceSize, err)) 184 } 185 186 func (s *DockerSuite) TestInspectContainerGraphDriver(c *check.C) { 187 testRequires(c, DaemonIsLinux, Devicemapper) 188 189 out, _ := dockerCmd(c, "run", "-d", "busybox", "true") 190 out = strings.TrimSpace(out) 191 192 name := inspectField(c, out, "GraphDriver.Name") 193 194 checkValidGraphDriver(c, name) 195 196 imageDeviceID := inspectField(c, "busybox", "GraphDriver.Data.DeviceId") 197 198 deviceID := inspectField(c, out, "GraphDriver.Data.DeviceId") 199 200 c.Assert(imageDeviceID, checker.Not(checker.Equals), deviceID) 201 202 _, err := strconv.Atoi(deviceID) 203 c.Assert(err, checker.IsNil, check.Commentf("failed to inspect DeviceId of the image: %s, %v", deviceID, err)) 204 205 deviceSize := inspectField(c, out, "GraphDriver.Data.DeviceSize") 206 207 _, err = strconv.ParseUint(deviceSize, 10, 64) 208 c.Assert(err, checker.IsNil, check.Commentf("failed to inspect DeviceSize of the image: %s, %v", deviceSize, err)) 209 } 210 211 func (s *DockerSuite) TestInspectBindMountPoint(c *check.C) { 212 testRequires(c, DaemonIsLinux) 213 dockerCmd(c, "run", "-d", "--name", "test", "-v", "/data:/data:ro,z", "busybox", "cat") 214 215 vol := inspectFieldJSON(c, "test", "Mounts") 216 217 var mp []types.MountPoint 218 err := unmarshalJSON([]byte(vol), &mp) 219 c.Assert(err, checker.IsNil) 220 221 // check that there is only one mountpoint 222 c.Assert(mp, check.HasLen, 1) 223 224 m := mp[0] 225 226 c.Assert(m.Name, checker.Equals, "") 227 c.Assert(m.Driver, checker.Equals, "") 228 c.Assert(m.Source, checker.Equals, "/data") 229 c.Assert(m.Destination, checker.Equals, "/data") 230 c.Assert(m.Mode, checker.Equals, "ro,z") 231 c.Assert(m.RW, checker.Equals, false) 232 } 233 234 // #14947 235 func (s *DockerSuite) TestInspectTimesAsRFC3339Nano(c *check.C) { 236 testRequires(c, DaemonIsLinux) 237 out, _ := dockerCmd(c, "run", "-d", "busybox", "true") 238 id := strings.TrimSpace(out) 239 startedAt := inspectField(c, id, "State.StartedAt") 240 finishedAt := inspectField(c, id, "State.FinishedAt") 241 created := inspectField(c, id, "Created") 242 243 _, err := time.Parse(time.RFC3339Nano, startedAt) 244 c.Assert(err, checker.IsNil) 245 _, err = time.Parse(time.RFC3339Nano, finishedAt) 246 c.Assert(err, checker.IsNil) 247 _, err = time.Parse(time.RFC3339Nano, created) 248 c.Assert(err, checker.IsNil) 249 250 created = inspectField(c, "busybox", "Created") 251 252 _, err = time.Parse(time.RFC3339Nano, created) 253 c.Assert(err, checker.IsNil) 254 } 255 256 // #15633 257 func (s *DockerSuite) TestInspectLogConfigNoType(c *check.C) { 258 testRequires(c, DaemonIsLinux) 259 dockerCmd(c, "create", "--name=test", "--log-opt", "max-file=42", "busybox") 260 var logConfig container.LogConfig 261 262 out := inspectFieldJSON(c, "test", "HostConfig.LogConfig") 263 264 err := json.NewDecoder(strings.NewReader(out)).Decode(&logConfig) 265 c.Assert(err, checker.IsNil, check.Commentf("%v", out)) 266 267 c.Assert(logConfig.Type, checker.Equals, "json-file") 268 c.Assert(logConfig.Config["max-file"], checker.Equals, "42", check.Commentf("%v", logConfig)) 269 } 270 271 func (s *DockerSuite) TestInspectNoSizeFlagContainer(c *check.C) { 272 273 //Both the container and image are named busybox. docker inspect will fetch container 274 //JSON SizeRw and SizeRootFs field. If there is no flag --size/-s, there are no size fields. 275 276 runSleepingContainer(c, "--name=busybox", "-d") 277 278 formatStr := "--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 283 func (s *DockerSuite) TestInspectSizeFlagContainer(c *check.C) { 284 runSleepingContainer(c, "--name=busybox", "-d") 285 286 formatStr := "--format='{{.SizeRw}},{{.SizeRootFs}}'" 287 out, _ := dockerCmd(c, "inspect", "-s", "--type=container", formatStr, "busybox") 288 sz := strings.Split(out, ",") 289 290 c.Assert(strings.TrimSpace(sz[0]), check.Not(check.Equals), "<nil>") 291 c.Assert(strings.TrimSpace(sz[1]), check.Not(check.Equals), "<nil>") 292 } 293 294 func (s *DockerSuite) TestInspectSizeFlagImage(c *check.C) { 295 runSleepingContainer(c, "-d") 296 297 formatStr := "--format='{{.SizeRw}},{{.SizeRootFs}}'" 298 out, _, err := dockerCmdWithError("inspect", "-s", "--type=image", formatStr, "busybox") 299 300 // Template error rather than <no value> 301 // This is a more correct behavior because images don't have sizes associated. 302 c.Assert(err, check.Not(check.IsNil)) 303 c.Assert(out, checker.Contains, "Template parsing error") 304 } 305 306 func (s *DockerSuite) TestInspectTemplateError(c *check.C) { 307 // Template parsing error for both the container and image. 308 309 runSleepingContainer(c, "--name=container1", "-d") 310 311 out, _, err := dockerCmdWithError("inspect", "--type=container", "--format='Format container: {{.ThisDoesNotExist}}'", "container1") 312 c.Assert(err, check.Not(check.IsNil)) 313 c.Assert(out, checker.Contains, "Template parsing error") 314 315 out, _, err = dockerCmdWithError("inspect", "--type=image", "--format='Format container: {{.ThisDoesNotExist}}'", "busybox") 316 c.Assert(err, check.Not(check.IsNil)) 317 c.Assert(out, checker.Contains, "Template parsing error") 318 } 319 320 func (s *DockerSuite) TestInspectJSONFields(c *check.C) { 321 runSleepingContainer(c, "--name=busybox", "-d") 322 out, _, err := dockerCmdWithError("inspect", "--type=container", "--format='{{.HostConfig.Dns}}'", "busybox") 323 324 c.Assert(err, check.IsNil) 325 c.Assert(out, checker.Equals, "[]\n") 326 } 327 328 func (s *DockerSuite) TestInspectByPrefix(c *check.C) { 329 id := inspectField(c, "busybox", "Id") 330 c.Assert(id, checker.HasPrefix, "sha256:") 331 332 id2 := inspectField(c, id[:12], "Id") 333 c.Assert(id, checker.Equals, id2) 334 335 id3 := inspectField(c, strings.TrimPrefix(id, "sha256:")[:12], "Id") 336 c.Assert(id, checker.Equals, id3) 337 } 338 339 func (s *DockerSuite) TestInspectStopWhenNotFound(c *check.C) { 340 runSleepingContainer(c, "--name=busybox", "-d") 341 runSleepingContainer(c, "--name=not-shown", "-d") 342 out, _, err := dockerCmdWithError("inspect", "--type=container", "--format='{{.Name}}'", "busybox", "missing", "not-shown") 343 344 c.Assert(err, checker.Not(check.IsNil)) 345 c.Assert(out, checker.Contains, "busybox") 346 c.Assert(out, checker.Not(checker.Contains), "not-shown") 347 c.Assert(out, checker.Contains, "Error: No such container: missing") 348 } 349 350 func (s *DockerSuite) TestInspectHistory(c *check.C) { 351 testRequires(c, DaemonIsLinux) 352 dockerCmd(c, "run", "--name=testcont", "-d", "busybox", "top") 353 dockerCmd(c, "commit", "-m", "test comment", "testcont", "testimg") 354 out, _, err := dockerCmdWithError("inspect", "--format='{{.Comment}}'", "testimg") 355 356 c.Assert(err, check.IsNil) 357 c.Assert(out, checker.Contains, "test comment") 358 } 359 360 func (s *DockerSuite) TestInspectContainerNetworkDefault(c *check.C) { 361 testRequires(c, DaemonIsLinux) 362 363 contName := "test1" 364 dockerCmd(c, "run", "--name", contName, "-d", "busybox", "top") 365 netOut, _ := dockerCmd(c, "network", "inspect", "--format='{{.ID}}'", "bridge") 366 out := inspectField(c, contName, "NetworkSettings.Networks") 367 c.Assert(out, checker.Contains, "bridge") 368 out = inspectField(c, contName, "NetworkSettings.Networks.bridge.NetworkID") 369 c.Assert(strings.TrimSpace(out), checker.Equals, strings.TrimSpace(netOut)) 370 } 371 372 func (s *DockerSuite) TestInspectContainerNetworkCustom(c *check.C) { 373 testRequires(c, DaemonIsLinux) 374 375 netOut, _ := dockerCmd(c, "network", "create", "net1") 376 dockerCmd(c, "run", "--name=container1", "--net=net1", "-d", "busybox", "top") 377 out := inspectField(c, "container1", "NetworkSettings.Networks") 378 c.Assert(out, checker.Contains, "net1") 379 out = inspectField(c, "container1", "NetworkSettings.Networks.net1.NetworkID") 380 c.Assert(strings.TrimSpace(out), checker.Equals, strings.TrimSpace(netOut)) 381 } 382 383 func (s *DockerSuite) TestInspectRootFS(c *check.C) { 384 testRequires(c, DaemonIsLinux) 385 out, _, err := dockerCmdWithError("inspect", "busybox") 386 c.Assert(err, check.IsNil) 387 388 var imageJSON []types.ImageInspect 389 err = json.Unmarshal([]byte(out), &imageJSON) 390 c.Assert(err, checker.IsNil) 391 392 c.Assert(len(imageJSON[0].RootFS.Layers), checker.GreaterOrEqualThan, 1) 393 }