github.com/fabiokung/docker@v0.11.2-0.20170222101415-4534dcd49497/integration-cli/docker_cli_volume_test.go (about) 1 package main 2 3 import ( 4 "fmt" 5 "io/ioutil" 6 "net/http" 7 "os" 8 "os/exec" 9 "path/filepath" 10 "strings" 11 12 "github.com/docker/docker/integration-cli/checker" 13 "github.com/docker/docker/integration-cli/request" 14 icmd "github.com/docker/docker/pkg/testutil/cmd" 15 "github.com/go-check/check" 16 ) 17 18 func (s *DockerSuite) TestVolumeCLICreate(c *check.C) { 19 dockerCmd(c, "volume", "create") 20 21 _, _, err := dockerCmdWithError("volume", "create", "-d", "nosuchdriver") 22 c.Assert(err, check.NotNil) 23 24 // test using hidden --name option 25 out, _ := dockerCmd(c, "volume", "create", "--name=test") 26 name := strings.TrimSpace(out) 27 c.Assert(name, check.Equals, "test") 28 29 out, _ = dockerCmd(c, "volume", "create", "test2") 30 name = strings.TrimSpace(out) 31 c.Assert(name, check.Equals, "test2") 32 } 33 34 func (s *DockerSuite) TestVolumeCLIInspect(c *check.C) { 35 c.Assert( 36 exec.Command(dockerBinary, "volume", "inspect", "doesntexist").Run(), 37 check.Not(check.IsNil), 38 check.Commentf("volume inspect should error on non-existent volume"), 39 ) 40 41 out, _ := dockerCmd(c, "volume", "create") 42 name := strings.TrimSpace(out) 43 out, _ = dockerCmd(c, "volume", "inspect", "--format={{ .Name }}", name) 44 c.Assert(strings.TrimSpace(out), check.Equals, name) 45 46 dockerCmd(c, "volume", "create", "test") 47 out, _ = dockerCmd(c, "volume", "inspect", "--format={{ .Name }}", "test") 48 c.Assert(strings.TrimSpace(out), check.Equals, "test") 49 } 50 51 func (s *DockerSuite) TestVolumeCLIInspectMulti(c *check.C) { 52 dockerCmd(c, "volume", "create", "test1") 53 dockerCmd(c, "volume", "create", "test2") 54 dockerCmd(c, "volume", "create", "not-shown") 55 56 result := dockerCmdWithResult("volume", "inspect", "--format={{ .Name }}", "test1", "test2", "doesntexist", "not-shown") 57 c.Assert(result, icmd.Matches, icmd.Expected{ 58 ExitCode: 1, 59 Err: "No such volume: doesntexist", 60 }) 61 62 out := result.Stdout() 63 outArr := strings.Split(strings.TrimSpace(out), "\n") 64 c.Assert(len(outArr), check.Equals, 2, check.Commentf("\n%s", out)) 65 66 c.Assert(out, checker.Contains, "test1") 67 c.Assert(out, checker.Contains, "test2") 68 c.Assert(out, checker.Not(checker.Contains), "not-shown") 69 } 70 71 func (s *DockerSuite) TestVolumeCLILs(c *check.C) { 72 prefix, _ := getPrefixAndSlashFromDaemonPlatform() 73 dockerCmd(c, "volume", "create", "aaa") 74 75 dockerCmd(c, "volume", "create", "test") 76 77 dockerCmd(c, "volume", "create", "soo") 78 dockerCmd(c, "run", "-v", "soo:"+prefix+"/foo", "busybox", "ls", "/") 79 80 out, _ := dockerCmd(c, "volume", "ls") 81 outArr := strings.Split(strings.TrimSpace(out), "\n") 82 c.Assert(len(outArr), check.Equals, 4, check.Commentf("\n%s", out)) 83 84 assertVolList(c, out, []string{"aaa", "soo", "test"}) 85 } 86 87 func (s *DockerSuite) TestVolumeLsFormat(c *check.C) { 88 dockerCmd(c, "volume", "create", "aaa") 89 dockerCmd(c, "volume", "create", "test") 90 dockerCmd(c, "volume", "create", "soo") 91 92 out, _ := dockerCmd(c, "volume", "ls", "--format", "{{.Name}}") 93 lines := strings.Split(strings.TrimSpace(string(out)), "\n") 94 95 expected := []string{"aaa", "soo", "test"} 96 var names []string 97 names = append(names, lines...) 98 c.Assert(expected, checker.DeepEquals, names, check.Commentf("Expected array with truncated names: %v, got: %v", expected, names)) 99 } 100 101 func (s *DockerSuite) TestVolumeLsFormatDefaultFormat(c *check.C) { 102 dockerCmd(c, "volume", "create", "aaa") 103 dockerCmd(c, "volume", "create", "test") 104 dockerCmd(c, "volume", "create", "soo") 105 106 config := `{ 107 "volumesFormat": "{{ .Name }} default" 108 }` 109 d, err := ioutil.TempDir("", "integration-cli-") 110 c.Assert(err, checker.IsNil) 111 defer os.RemoveAll(d) 112 113 err = ioutil.WriteFile(filepath.Join(d, "config.json"), []byte(config), 0644) 114 c.Assert(err, checker.IsNil) 115 116 out, _ := dockerCmd(c, "--config", d, "volume", "ls") 117 lines := strings.Split(strings.TrimSpace(string(out)), "\n") 118 119 expected := []string{"aaa default", "soo default", "test default"} 120 var names []string 121 names = append(names, lines...) 122 c.Assert(expected, checker.DeepEquals, names, check.Commentf("Expected array with truncated names: %v, got: %v", expected, names)) 123 } 124 125 // assertVolList checks volume retrieved with ls command 126 // equals to expected volume list 127 // note: out should be `volume ls [option]` result 128 func assertVolList(c *check.C, out string, expectVols []string) { 129 lines := strings.Split(out, "\n") 130 var volList []string 131 for _, line := range lines[1 : len(lines)-1] { 132 volFields := strings.Fields(line) 133 // wrap all volume name in volList 134 volList = append(volList, volFields[1]) 135 } 136 137 // volume ls should contains all expected volumes 138 c.Assert(volList, checker.DeepEquals, expectVols) 139 } 140 141 func (s *DockerSuite) TestVolumeCLILsFilterDangling(c *check.C) { 142 prefix, _ := getPrefixAndSlashFromDaemonPlatform() 143 dockerCmd(c, "volume", "create", "testnotinuse1") 144 dockerCmd(c, "volume", "create", "testisinuse1") 145 dockerCmd(c, "volume", "create", "testisinuse2") 146 147 // Make sure both "created" (but not started), and started 148 // containers are included in reference counting 149 dockerCmd(c, "run", "--name", "volume-test1", "-v", "testisinuse1:"+prefix+"/foo", "busybox", "true") 150 dockerCmd(c, "create", "--name", "volume-test2", "-v", "testisinuse2:"+prefix+"/foo", "busybox", "true") 151 152 out, _ := dockerCmd(c, "volume", "ls") 153 154 // No filter, all volumes should show 155 c.Assert(out, checker.Contains, "testnotinuse1\n", check.Commentf("expected volume 'testnotinuse1' in output")) 156 c.Assert(out, checker.Contains, "testisinuse1\n", check.Commentf("expected volume 'testisinuse1' in output")) 157 c.Assert(out, checker.Contains, "testisinuse2\n", check.Commentf("expected volume 'testisinuse2' in output")) 158 159 out, _ = dockerCmd(c, "volume", "ls", "--filter", "dangling=false") 160 161 // Explicitly disabling dangling 162 c.Assert(out, check.Not(checker.Contains), "testnotinuse1\n", check.Commentf("expected volume 'testnotinuse1' in output")) 163 c.Assert(out, checker.Contains, "testisinuse1\n", check.Commentf("expected volume 'testisinuse1' in output")) 164 c.Assert(out, checker.Contains, "testisinuse2\n", check.Commentf("expected volume 'testisinuse2' in output")) 165 166 out, _ = dockerCmd(c, "volume", "ls", "--filter", "dangling=true") 167 168 // Filter "dangling" volumes; only "dangling" (unused) volumes should be in the output 169 c.Assert(out, checker.Contains, "testnotinuse1\n", check.Commentf("expected volume 'testnotinuse1' in output")) 170 c.Assert(out, check.Not(checker.Contains), "testisinuse1\n", check.Commentf("volume 'testisinuse1' in output, but not expected")) 171 c.Assert(out, check.Not(checker.Contains), "testisinuse2\n", check.Commentf("volume 'testisinuse2' in output, but not expected")) 172 173 out, _ = dockerCmd(c, "volume", "ls", "--filter", "dangling=1") 174 // Filter "dangling" volumes; only "dangling" (unused) volumes should be in the output, dangling also accept 1 175 c.Assert(out, checker.Contains, "testnotinuse1\n", check.Commentf("expected volume 'testnotinuse1' in output")) 176 c.Assert(out, check.Not(checker.Contains), "testisinuse1\n", check.Commentf("volume 'testisinuse1' in output, but not expected")) 177 c.Assert(out, check.Not(checker.Contains), "testisinuse2\n", check.Commentf("volume 'testisinuse2' in output, but not expected")) 178 179 out, _ = dockerCmd(c, "volume", "ls", "--filter", "dangling=0") 180 // dangling=0 is same as dangling=false case 181 c.Assert(out, check.Not(checker.Contains), "testnotinuse1\n", check.Commentf("expected volume 'testnotinuse1' in output")) 182 c.Assert(out, checker.Contains, "testisinuse1\n", check.Commentf("expected volume 'testisinuse1' in output")) 183 c.Assert(out, checker.Contains, "testisinuse2\n", check.Commentf("expected volume 'testisinuse2' in output")) 184 185 out, _ = dockerCmd(c, "volume", "ls", "--filter", "name=testisin") 186 c.Assert(out, check.Not(checker.Contains), "testnotinuse1\n", check.Commentf("expected volume 'testnotinuse1' in output")) 187 c.Assert(out, checker.Contains, "testisinuse1\n", check.Commentf("execpeted volume 'testisinuse1' in output")) 188 c.Assert(out, checker.Contains, "testisinuse2\n", check.Commentf("expected volume 'testisinuse2' in output")) 189 } 190 191 func (s *DockerSuite) TestVolumeCLILsErrorWithInvalidFilterName(c *check.C) { 192 out, _, err := dockerCmdWithError("volume", "ls", "-f", "FOO=123") 193 c.Assert(err, checker.NotNil) 194 c.Assert(out, checker.Contains, "Invalid filter") 195 } 196 197 func (s *DockerSuite) TestVolumeCLILsWithIncorrectFilterValue(c *check.C) { 198 out, _, err := dockerCmdWithError("volume", "ls", "-f", "dangling=invalid") 199 c.Assert(err, check.NotNil) 200 c.Assert(out, checker.Contains, "Invalid filter") 201 } 202 203 func (s *DockerSuite) TestVolumeCLIRm(c *check.C) { 204 prefix, _ := getPrefixAndSlashFromDaemonPlatform() 205 out, _ := dockerCmd(c, "volume", "create") 206 id := strings.TrimSpace(out) 207 208 dockerCmd(c, "volume", "create", "test") 209 dockerCmd(c, "volume", "rm", id) 210 dockerCmd(c, "volume", "rm", "test") 211 212 out, _ = dockerCmd(c, "volume", "ls") 213 outArr := strings.Split(strings.TrimSpace(out), "\n") 214 c.Assert(len(outArr), check.Equals, 1, check.Commentf("%s\n", out)) 215 216 volumeID := "testing" 217 dockerCmd(c, "run", "-v", volumeID+":"+prefix+"/foo", "--name=test", "busybox", "sh", "-c", "echo hello > /foo/bar") 218 219 icmd.RunCommand(dockerBinary, "volume", "rm", "testing").Assert(c, icmd.Expected{ 220 ExitCode: 1, 221 Error: "exit status 1", 222 }) 223 224 out, _ = dockerCmd(c, "run", "--volumes-from=test", "--name=test2", "busybox", "sh", "-c", "cat /foo/bar") 225 c.Assert(strings.TrimSpace(out), check.Equals, "hello") 226 dockerCmd(c, "rm", "-fv", "test2") 227 dockerCmd(c, "volume", "inspect", volumeID) 228 dockerCmd(c, "rm", "-f", "test") 229 230 out, _ = dockerCmd(c, "run", "--name=test2", "-v", volumeID+":"+prefix+"/foo", "busybox", "sh", "-c", "cat /foo/bar") 231 c.Assert(strings.TrimSpace(out), check.Equals, "hello", check.Commentf("volume data was removed")) 232 dockerCmd(c, "rm", "test2") 233 234 dockerCmd(c, "volume", "rm", volumeID) 235 c.Assert( 236 exec.Command("volume", "rm", "doesntexist").Run(), 237 check.Not(check.IsNil), 238 check.Commentf("volume rm should fail with non-existent volume"), 239 ) 240 } 241 242 // FIXME(vdemeester) should be a unit test in cli/command/volume package 243 func (s *DockerSuite) TestVolumeCLINoArgs(c *check.C) { 244 out, _ := dockerCmd(c, "volume") 245 // no args should produce the cmd usage output 246 usage := "Usage: docker volume COMMAND" 247 c.Assert(out, checker.Contains, usage) 248 249 // invalid arg should error and show the command usage on stderr 250 icmd.RunCommand(dockerBinary, "volume", "somearg").Assert(c, icmd.Expected{ 251 ExitCode: 1, 252 Error: "exit status 1", 253 Err: usage, 254 }) 255 256 // invalid flag should error and show the flag error and cmd usage 257 result := icmd.RunCommand(dockerBinary, "volume", "--no-such-flag") 258 result.Assert(c, icmd.Expected{ 259 ExitCode: 125, 260 Error: "exit status 125", 261 Err: usage, 262 }) 263 c.Assert(result.Stderr(), checker.Contains, "unknown flag: --no-such-flag") 264 } 265 266 func (s *DockerSuite) TestVolumeCLIInspectTmplError(c *check.C) { 267 out, _ := dockerCmd(c, "volume", "create") 268 name := strings.TrimSpace(out) 269 270 out, exitCode, err := dockerCmdWithError("volume", "inspect", "--format='{{ .FooBar }}'", name) 271 c.Assert(err, checker.NotNil, check.Commentf("Output: %s", out)) 272 c.Assert(exitCode, checker.Equals, 1, check.Commentf("Output: %s", out)) 273 c.Assert(out, checker.Contains, "Template parsing error") 274 } 275 276 func (s *DockerSuite) TestVolumeCLICreateWithOpts(c *check.C) { 277 testRequires(c, DaemonIsLinux) 278 279 dockerCmd(c, "volume", "create", "-d", "local", "test", "--opt=type=tmpfs", "--opt=device=tmpfs", "--opt=o=size=1m,uid=1000") 280 out, _ := dockerCmd(c, "run", "-v", "test:/foo", "busybox", "mount") 281 282 mounts := strings.Split(out, "\n") 283 var found bool 284 for _, m := range mounts { 285 if strings.Contains(m, "/foo") { 286 found = true 287 info := strings.Fields(m) 288 // tmpfs on <path> type tmpfs (rw,relatime,size=1024k,uid=1000) 289 c.Assert(info[0], checker.Equals, "tmpfs") 290 c.Assert(info[2], checker.Equals, "/foo") 291 c.Assert(info[4], checker.Equals, "tmpfs") 292 c.Assert(info[5], checker.Contains, "uid=1000") 293 c.Assert(info[5], checker.Contains, "size=1024k") 294 break 295 } 296 } 297 c.Assert(found, checker.Equals, true) 298 } 299 300 func (s *DockerSuite) TestVolumeCLICreateLabel(c *check.C) { 301 testVol := "testvolcreatelabel" 302 testLabel := "foo" 303 testValue := "bar" 304 305 out, _, err := dockerCmdWithError("volume", "create", "--label", testLabel+"="+testValue, testVol) 306 c.Assert(err, check.IsNil) 307 308 out, _ = dockerCmd(c, "volume", "inspect", "--format={{ .Labels."+testLabel+" }}", testVol) 309 c.Assert(strings.TrimSpace(out), check.Equals, testValue) 310 } 311 312 func (s *DockerSuite) TestVolumeCLICreateLabelMultiple(c *check.C) { 313 testVol := "testvolcreatelabel" 314 315 testLabels := map[string]string{ 316 "foo": "bar", 317 "baz": "foo", 318 } 319 320 args := []string{ 321 "volume", 322 "create", 323 testVol, 324 } 325 326 for k, v := range testLabels { 327 args = append(args, "--label", k+"="+v) 328 } 329 330 out, _, err := dockerCmdWithError(args...) 331 c.Assert(err, check.IsNil) 332 333 for k, v := range testLabels { 334 out, _ = dockerCmd(c, "volume", "inspect", "--format={{ .Labels."+k+" }}", testVol) 335 c.Assert(strings.TrimSpace(out), check.Equals, v) 336 } 337 } 338 339 func (s *DockerSuite) TestVolumeCLILsFilterLabels(c *check.C) { 340 testVol1 := "testvolcreatelabel-1" 341 out, _, err := dockerCmdWithError("volume", "create", "--label", "foo=bar1", testVol1) 342 c.Assert(err, check.IsNil) 343 344 testVol2 := "testvolcreatelabel-2" 345 out, _, err = dockerCmdWithError("volume", "create", "--label", "foo=bar2", testVol2) 346 c.Assert(err, check.IsNil) 347 348 out, _ = dockerCmd(c, "volume", "ls", "--filter", "label=foo") 349 350 // filter with label=key 351 c.Assert(out, checker.Contains, "testvolcreatelabel-1\n", check.Commentf("expected volume 'testvolcreatelabel-1' in output")) 352 c.Assert(out, checker.Contains, "testvolcreatelabel-2\n", check.Commentf("expected volume 'testvolcreatelabel-2' in output")) 353 354 out, _ = dockerCmd(c, "volume", "ls", "--filter", "label=foo=bar1") 355 356 // filter with label=key=value 357 c.Assert(out, checker.Contains, "testvolcreatelabel-1\n", check.Commentf("expected volume 'testvolcreatelabel-1' in output")) 358 c.Assert(out, check.Not(checker.Contains), "testvolcreatelabel-2\n", check.Commentf("expected volume 'testvolcreatelabel-2 in output")) 359 360 out, _ = dockerCmd(c, "volume", "ls", "--filter", "label=non-exist") 361 outArr := strings.Split(strings.TrimSpace(out), "\n") 362 c.Assert(len(outArr), check.Equals, 1, check.Commentf("\n%s", out)) 363 364 out, _ = dockerCmd(c, "volume", "ls", "--filter", "label=foo=non-exist") 365 outArr = strings.Split(strings.TrimSpace(out), "\n") 366 c.Assert(len(outArr), check.Equals, 1, check.Commentf("\n%s", out)) 367 } 368 369 func (s *DockerSuite) TestVolumeCLILsFilterDrivers(c *check.C) { 370 // using default volume driver local to create volumes 371 testVol1 := "testvol-1" 372 out, _, err := dockerCmdWithError("volume", "create", testVol1) 373 c.Assert(err, check.IsNil) 374 375 testVol2 := "testvol-2" 376 out, _, err = dockerCmdWithError("volume", "create", testVol2) 377 c.Assert(err, check.IsNil) 378 379 // filter with driver=local 380 out, _ = dockerCmd(c, "volume", "ls", "--filter", "driver=local") 381 c.Assert(out, checker.Contains, "testvol-1\n", check.Commentf("expected volume 'testvol-1' in output")) 382 c.Assert(out, checker.Contains, "testvol-2\n", check.Commentf("expected volume 'testvol-2' in output")) 383 384 // filter with driver=invaliddriver 385 out, _ = dockerCmd(c, "volume", "ls", "--filter", "driver=invaliddriver") 386 outArr := strings.Split(strings.TrimSpace(out), "\n") 387 c.Assert(len(outArr), check.Equals, 1, check.Commentf("\n%s", out)) 388 389 // filter with driver=loca 390 out, _ = dockerCmd(c, "volume", "ls", "--filter", "driver=loca") 391 outArr = strings.Split(strings.TrimSpace(out), "\n") 392 c.Assert(len(outArr), check.Equals, 1, check.Commentf("\n%s", out)) 393 394 // filter with driver= 395 out, _ = dockerCmd(c, "volume", "ls", "--filter", "driver=") 396 outArr = strings.Split(strings.TrimSpace(out), "\n") 397 c.Assert(len(outArr), check.Equals, 1, check.Commentf("\n%s", out)) 398 } 399 400 func (s *DockerSuite) TestVolumeCLIRmForceUsage(c *check.C) { 401 out, _ := dockerCmd(c, "volume", "create") 402 id := strings.TrimSpace(out) 403 404 dockerCmd(c, "volume", "rm", "-f", id) 405 dockerCmd(c, "volume", "rm", "--force", "nonexist") 406 407 out, _ = dockerCmd(c, "volume", "ls") 408 outArr := strings.Split(strings.TrimSpace(out), "\n") 409 c.Assert(len(outArr), check.Equals, 1, check.Commentf("%s\n", out)) 410 } 411 412 func (s *DockerSuite) TestVolumeCLIRmForce(c *check.C) { 413 testRequires(c, SameHostDaemon, DaemonIsLinux) 414 415 name := "test" 416 out, _ := dockerCmd(c, "volume", "create", name) 417 id := strings.TrimSpace(out) 418 c.Assert(id, checker.Equals, name) 419 420 out, _ = dockerCmd(c, "volume", "inspect", "--format", "{{.Mountpoint}}", name) 421 c.Assert(strings.TrimSpace(out), checker.Not(checker.Equals), "") 422 // Mountpoint is in the form of "/var/lib/docker/volumes/.../_data", removing `/_data` 423 path := strings.TrimSuffix(strings.TrimSpace(out), "/_data") 424 icmd.RunCommand("rm", "-rf", path).Assert(c, icmd.Success) 425 426 dockerCmd(c, "volume", "rm", "-f", "test") 427 out, _ = dockerCmd(c, "volume", "ls") 428 c.Assert(out, checker.Not(checker.Contains), name) 429 dockerCmd(c, "volume", "create", "test") 430 out, _ = dockerCmd(c, "volume", "ls") 431 c.Assert(out, checker.Contains, name) 432 } 433 434 func (s *DockerSuite) TestVolumeCliInspectWithVolumeOpts(c *check.C) { 435 testRequires(c, DaemonIsLinux) 436 437 // Without options 438 name := "test1" 439 dockerCmd(c, "volume", "create", "-d", "local", name) 440 out, _ := dockerCmd(c, "volume", "inspect", "--format={{ .Options }}", name) 441 c.Assert(strings.TrimSpace(out), checker.Contains, "map[]") 442 443 // With options 444 name = "test2" 445 k1, v1 := "type", "tmpfs" 446 k2, v2 := "device", "tmpfs" 447 k3, v3 := "o", "size=1m,uid=1000" 448 dockerCmd(c, "volume", "create", "-d", "local", name, "--opt", fmt.Sprintf("%s=%s", k1, v1), "--opt", fmt.Sprintf("%s=%s", k2, v2), "--opt", fmt.Sprintf("%s=%s", k3, v3)) 449 out, _ = dockerCmd(c, "volume", "inspect", "--format={{ .Options }}", name) 450 c.Assert(strings.TrimSpace(out), checker.Contains, fmt.Sprintf("%s:%s", k1, v1)) 451 c.Assert(strings.TrimSpace(out), checker.Contains, fmt.Sprintf("%s:%s", k2, v2)) 452 c.Assert(strings.TrimSpace(out), checker.Contains, fmt.Sprintf("%s:%s", k3, v3)) 453 } 454 455 // Test case (1) for 21845: duplicate targets for --volumes-from 456 func (s *DockerSuite) TestDuplicateMountpointsForVolumesFrom(c *check.C) { 457 testRequires(c, DaemonIsLinux) 458 459 image := "vimage" 460 buildImageSuccessfully(c, image, withDockerfile(` 461 FROM busybox 462 VOLUME ["/tmp/data"]`)) 463 464 dockerCmd(c, "run", "--name=data1", image, "true") 465 dockerCmd(c, "run", "--name=data2", image, "true") 466 467 out, _ := dockerCmd(c, "inspect", "--format", "{{(index .Mounts 0).Name}}", "data1") 468 data1 := strings.TrimSpace(out) 469 c.Assert(data1, checker.Not(checker.Equals), "") 470 471 out, _ = dockerCmd(c, "inspect", "--format", "{{(index .Mounts 0).Name}}", "data2") 472 data2 := strings.TrimSpace(out) 473 c.Assert(data2, checker.Not(checker.Equals), "") 474 475 // Both volume should exist 476 out, _ = dockerCmd(c, "volume", "ls", "-q") 477 c.Assert(strings.TrimSpace(out), checker.Contains, data1) 478 c.Assert(strings.TrimSpace(out), checker.Contains, data2) 479 480 out, _, err := dockerCmdWithError("run", "--name=app", "--volumes-from=data1", "--volumes-from=data2", "-d", "busybox", "top") 481 c.Assert(err, checker.IsNil, check.Commentf("Out: %s", out)) 482 483 // Only the second volume will be referenced, this is backward compatible 484 out, _ = dockerCmd(c, "inspect", "--format", "{{(index .Mounts 0).Name}}", "app") 485 c.Assert(strings.TrimSpace(out), checker.Equals, data2) 486 487 dockerCmd(c, "rm", "-f", "-v", "app") 488 dockerCmd(c, "rm", "-f", "-v", "data1") 489 dockerCmd(c, "rm", "-f", "-v", "data2") 490 491 // Both volume should not exist 492 out, _ = dockerCmd(c, "volume", "ls", "-q") 493 c.Assert(strings.TrimSpace(out), checker.Not(checker.Contains), data1) 494 c.Assert(strings.TrimSpace(out), checker.Not(checker.Contains), data2) 495 } 496 497 // Test case (2) for 21845: duplicate targets for --volumes-from and -v (bind) 498 func (s *DockerSuite) TestDuplicateMountpointsForVolumesFromAndBind(c *check.C) { 499 testRequires(c, DaemonIsLinux) 500 501 image := "vimage" 502 buildImageSuccessfully(c, image, withDockerfile(` 503 FROM busybox 504 VOLUME ["/tmp/data"]`)) 505 506 dockerCmd(c, "run", "--name=data1", image, "true") 507 dockerCmd(c, "run", "--name=data2", image, "true") 508 509 out, _ := dockerCmd(c, "inspect", "--format", "{{(index .Mounts 0).Name}}", "data1") 510 data1 := strings.TrimSpace(out) 511 c.Assert(data1, checker.Not(checker.Equals), "") 512 513 out, _ = dockerCmd(c, "inspect", "--format", "{{(index .Mounts 0).Name}}", "data2") 514 data2 := strings.TrimSpace(out) 515 c.Assert(data2, checker.Not(checker.Equals), "") 516 517 // Both volume should exist 518 out, _ = dockerCmd(c, "volume", "ls", "-q") 519 c.Assert(strings.TrimSpace(out), checker.Contains, data1) 520 c.Assert(strings.TrimSpace(out), checker.Contains, data2) 521 522 out, _, err := dockerCmdWithError("run", "--name=app", "--volumes-from=data1", "--volumes-from=data2", "-v", "/tmp/data:/tmp/data", "-d", "busybox", "top") 523 c.Assert(err, checker.IsNil, check.Commentf("Out: %s", out)) 524 525 // No volume will be referenced (mount is /tmp/data), this is backward compatible 526 out, _ = dockerCmd(c, "inspect", "--format", "{{(index .Mounts 0).Name}}", "app") 527 c.Assert(strings.TrimSpace(out), checker.Not(checker.Contains), data1) 528 c.Assert(strings.TrimSpace(out), checker.Not(checker.Contains), data2) 529 530 dockerCmd(c, "rm", "-f", "-v", "app") 531 dockerCmd(c, "rm", "-f", "-v", "data1") 532 dockerCmd(c, "rm", "-f", "-v", "data2") 533 534 // Both volume should not exist 535 out, _ = dockerCmd(c, "volume", "ls", "-q") 536 c.Assert(strings.TrimSpace(out), checker.Not(checker.Contains), data1) 537 c.Assert(strings.TrimSpace(out), checker.Not(checker.Contains), data2) 538 } 539 540 // Test case (3) for 21845: duplicate targets for --volumes-from and `Mounts` (API only) 541 func (s *DockerSuite) TestDuplicateMountpointsForVolumesFromAndMounts(c *check.C) { 542 testRequires(c, DaemonIsLinux) 543 544 image := "vimage" 545 buildImageSuccessfully(c, image, withDockerfile(` 546 FROM busybox 547 VOLUME ["/tmp/data"]`)) 548 549 dockerCmd(c, "run", "--name=data1", image, "true") 550 dockerCmd(c, "run", "--name=data2", image, "true") 551 552 out, _ := dockerCmd(c, "inspect", "--format", "{{(index .Mounts 0).Name}}", "data1") 553 data1 := strings.TrimSpace(out) 554 c.Assert(data1, checker.Not(checker.Equals), "") 555 556 out, _ = dockerCmd(c, "inspect", "--format", "{{(index .Mounts 0).Name}}", "data2") 557 data2 := strings.TrimSpace(out) 558 c.Assert(data2, checker.Not(checker.Equals), "") 559 560 // Both volume should exist 561 out, _ = dockerCmd(c, "volume", "ls", "-q") 562 c.Assert(strings.TrimSpace(out), checker.Contains, data1) 563 c.Assert(strings.TrimSpace(out), checker.Contains, data2) 564 565 // Mounts is available in API 566 status, body, err := request.SockRequest("POST", "/containers/create?name=app", map[string]interface{}{ 567 "Image": "busybox", 568 "Cmd": []string{"top"}, 569 "HostConfig": map[string]interface{}{ 570 "VolumesFrom": []string{ 571 "data1", 572 "data2", 573 }, 574 "Mounts": []map[string]interface{}{ 575 { 576 "Type": "bind", 577 "Source": "/tmp/data", 578 "Target": "/tmp/data", 579 }, 580 }}, 581 }, daemonHost()) 582 583 c.Assert(err, checker.IsNil, check.Commentf(string(body))) 584 c.Assert(status, checker.Equals, http.StatusCreated, check.Commentf(string(body))) 585 586 // No volume will be referenced (mount is /tmp/data), this is backward compatible 587 out, _ = dockerCmd(c, "inspect", "--format", "{{(index .Mounts 0).Name}}", "app") 588 c.Assert(strings.TrimSpace(out), checker.Not(checker.Contains), data1) 589 c.Assert(strings.TrimSpace(out), checker.Not(checker.Contains), data2) 590 591 dockerCmd(c, "rm", "-f", "-v", "app") 592 dockerCmd(c, "rm", "-f", "-v", "data1") 593 dockerCmd(c, "rm", "-f", "-v", "data2") 594 595 // Both volume should not exist 596 out, _ = dockerCmd(c, "volume", "ls", "-q") 597 c.Assert(strings.TrimSpace(out), checker.Not(checker.Contains), data1) 598 c.Assert(strings.TrimSpace(out), checker.Not(checker.Contains), data2) 599 }