github.com/willmtemple/docker@v1.7.0-rc2/integration-cli/docker_cli_daemon_test.go (about) 1 // +build daemon 2 3 package main 4 5 import ( 6 "encoding/json" 7 "fmt" 8 "io/ioutil" 9 "net" 10 "os" 11 "os/exec" 12 "path/filepath" 13 "regexp" 14 "strconv" 15 "strings" 16 "time" 17 18 "github.com/docker/libnetwork/iptables" 19 "github.com/docker/libtrust" 20 "github.com/go-check/check" 21 ) 22 23 func (s *DockerDaemonSuite) TestDaemonRestartWithRunningContainersPorts(c *check.C) { 24 if err := s.d.StartWithBusybox(); err != nil { 25 c.Fatalf("Could not start daemon with busybox: %v", err) 26 } 27 28 if out, err := s.d.Cmd("run", "-d", "--name", "top1", "-p", "1234:80", "--restart", "always", "busybox:latest", "top"); err != nil { 29 c.Fatalf("Could not run top1: err=%v\n%s", err, out) 30 } 31 // --restart=no by default 32 if out, err := s.d.Cmd("run", "-d", "--name", "top2", "-p", "80", "busybox:latest", "top"); err != nil { 33 c.Fatalf("Could not run top2: err=%v\n%s", err, out) 34 } 35 36 testRun := func(m map[string]bool, prefix string) { 37 var format string 38 for cont, shouldRun := range m { 39 out, err := s.d.Cmd("ps") 40 if err != nil { 41 c.Fatalf("Could not run ps: err=%v\n%q", err, out) 42 } 43 if shouldRun { 44 format = "%scontainer %q is not running" 45 } else { 46 format = "%scontainer %q is running" 47 } 48 if shouldRun != strings.Contains(out, cont) { 49 c.Fatalf(format, prefix, cont) 50 } 51 } 52 } 53 54 testRun(map[string]bool{"top1": true, "top2": true}, "") 55 56 if err := s.d.Restart(); err != nil { 57 c.Fatalf("Could not restart daemon: %v", err) 58 } 59 testRun(map[string]bool{"top1": true, "top2": false}, "After daemon restart: ") 60 } 61 62 func (s *DockerDaemonSuite) TestDaemonRestartWithVolumesRefs(c *check.C) { 63 if err := s.d.StartWithBusybox(); err != nil { 64 c.Fatal(err) 65 } 66 67 if out, err := s.d.Cmd("run", "-d", "--name", "volrestarttest1", "-v", "/foo", "busybox"); err != nil { 68 c.Fatal(err, out) 69 } 70 if err := s.d.Restart(); err != nil { 71 c.Fatal(err) 72 } 73 if _, err := s.d.Cmd("run", "-d", "--volumes-from", "volrestarttest1", "--name", "volrestarttest2", "busybox", "top"); err != nil { 74 c.Fatal(err) 75 } 76 if out, err := s.d.Cmd("rm", "-fv", "volrestarttest2"); err != nil { 77 c.Fatal(err, out) 78 } 79 v, err := s.d.Cmd("inspect", "--format", "{{ json .Volumes }}", "volrestarttest1") 80 if err != nil { 81 c.Fatal(err) 82 } 83 volumes := make(map[string]string) 84 json.Unmarshal([]byte(v), &volumes) 85 if _, err := os.Stat(volumes["/foo"]); err != nil { 86 c.Fatalf("Expected volume to exist: %s - %s", volumes["/foo"], err) 87 } 88 } 89 90 func (s *DockerDaemonSuite) TestDaemonStartIptablesFalse(c *check.C) { 91 if err := s.d.Start("--iptables=false"); err != nil { 92 c.Fatalf("we should have been able to start the daemon with passing iptables=false: %v", err) 93 } 94 } 95 96 // Issue #8444: If docker0 bridge is modified (intentionally or unintentionally) and 97 // no longer has an IP associated, we should gracefully handle that case and associate 98 // an IP with it rather than fail daemon start 99 func (s *DockerDaemonSuite) TestDaemonStartBridgeWithoutIPAssociation(c *check.C) { 100 // rather than depending on brctl commands to verify docker0 is created and up 101 // let's start the daemon and stop it, and then make a modification to run the 102 // actual test 103 if err := s.d.Start(); err != nil { 104 c.Fatalf("Could not start daemon: %v", err) 105 } 106 if err := s.d.Stop(); err != nil { 107 c.Fatalf("Could not stop daemon: %v", err) 108 } 109 110 // now we will remove the ip from docker0 and then try starting the daemon 111 ipCmd := exec.Command("ip", "addr", "flush", "dev", "docker0") 112 stdout, stderr, _, err := runCommandWithStdoutStderr(ipCmd) 113 if err != nil { 114 c.Fatalf("failed to remove docker0 IP association: %v, stdout: %q, stderr: %q", err, stdout, stderr) 115 } 116 117 if err := s.d.Start(); err != nil { 118 warning := "**WARNING: Docker bridge network in bad state--delete docker0 bridge interface to fix" 119 c.Fatalf("Could not start daemon when docker0 has no IP address: %v\n%s", err, warning) 120 } 121 } 122 123 func (s *DockerDaemonSuite) TestDaemonIptablesClean(c *check.C) { 124 if err := s.d.StartWithBusybox(); err != nil { 125 c.Fatalf("Could not start daemon with busybox: %v", err) 126 } 127 128 if out, err := s.d.Cmd("run", "-d", "--name", "top", "-p", "80", "busybox:latest", "top"); err != nil { 129 c.Fatalf("Could not run top: %s, %v", out, err) 130 } 131 132 // get output from iptables with container running 133 ipTablesSearchString := "tcp dpt:80" 134 ipTablesCmd := exec.Command("iptables", "-nvL") 135 out, _, err := runCommandWithOutput(ipTablesCmd) 136 if err != nil { 137 c.Fatalf("Could not run iptables -nvL: %s, %v", out, err) 138 } 139 140 if !strings.Contains(out, ipTablesSearchString) { 141 c.Fatalf("iptables output should have contained %q, but was %q", ipTablesSearchString, out) 142 } 143 144 if err := s.d.Stop(); err != nil { 145 c.Fatalf("Could not stop daemon: %v", err) 146 } 147 148 // get output from iptables after restart 149 ipTablesCmd = exec.Command("iptables", "-nvL") 150 out, _, err = runCommandWithOutput(ipTablesCmd) 151 if err != nil { 152 c.Fatalf("Could not run iptables -nvL: %s, %v", out, err) 153 } 154 155 if strings.Contains(out, ipTablesSearchString) { 156 c.Fatalf("iptables output should not have contained %q, but was %q", ipTablesSearchString, out) 157 } 158 } 159 160 func (s *DockerDaemonSuite) TestDaemonIptablesCreate(c *check.C) { 161 if err := s.d.StartWithBusybox(); err != nil { 162 c.Fatalf("Could not start daemon with busybox: %v", err) 163 } 164 165 if out, err := s.d.Cmd("run", "-d", "--name", "top", "--restart=always", "-p", "80", "busybox:latest", "top"); err != nil { 166 c.Fatalf("Could not run top: %s, %v", out, err) 167 } 168 169 // get output from iptables with container running 170 ipTablesSearchString := "tcp dpt:80" 171 ipTablesCmd := exec.Command("iptables", "-nvL") 172 out, _, err := runCommandWithOutput(ipTablesCmd) 173 if err != nil { 174 c.Fatalf("Could not run iptables -nvL: %s, %v", out, err) 175 } 176 177 if !strings.Contains(out, ipTablesSearchString) { 178 c.Fatalf("iptables output should have contained %q, but was %q", ipTablesSearchString, out) 179 } 180 181 if err := s.d.Restart(); err != nil { 182 c.Fatalf("Could not restart daemon: %v", err) 183 } 184 185 // make sure the container is not running 186 runningOut, err := s.d.Cmd("inspect", "--format='{{.State.Running}}'", "top") 187 if err != nil { 188 c.Fatalf("Could not inspect on container: %s, %v", out, err) 189 } 190 if strings.TrimSpace(runningOut) != "true" { 191 c.Fatalf("Container should have been restarted after daemon restart. Status running should have been true but was: %q", strings.TrimSpace(runningOut)) 192 } 193 194 // get output from iptables after restart 195 ipTablesCmd = exec.Command("iptables", "-nvL") 196 out, _, err = runCommandWithOutput(ipTablesCmd) 197 if err != nil { 198 c.Fatalf("Could not run iptables -nvL: %s, %v", out, err) 199 } 200 201 if !strings.Contains(out, ipTablesSearchString) { 202 c.Fatalf("iptables output after restart should have contained %q, but was %q", ipTablesSearchString, out) 203 } 204 } 205 206 func (s *DockerDaemonSuite) TestDaemonLogLevelWrong(c *check.C) { 207 c.Assert(s.d.Start("--log-level=bogus"), check.NotNil, check.Commentf("Daemon shouldn't start with wrong log level")) 208 } 209 210 func (s *DockerDaemonSuite) TestDaemonLogLevelDebug(c *check.C) { 211 if err := s.d.Start("--log-level=debug"); err != nil { 212 c.Fatal(err) 213 } 214 content, _ := ioutil.ReadFile(s.d.logFile.Name()) 215 if !strings.Contains(string(content), `level=debug`) { 216 c.Fatalf(`Missing level="debug" in log file:\n%s`, string(content)) 217 } 218 } 219 220 func (s *DockerDaemonSuite) TestDaemonLogLevelFatal(c *check.C) { 221 // we creating new daemons to create new logFile 222 if err := s.d.Start("--log-level=fatal"); err != nil { 223 c.Fatal(err) 224 } 225 content, _ := ioutil.ReadFile(s.d.logFile.Name()) 226 if strings.Contains(string(content), `level=debug`) { 227 c.Fatalf(`Should not have level="debug" in log file:\n%s`, string(content)) 228 } 229 } 230 231 func (s *DockerDaemonSuite) TestDaemonFlagD(c *check.C) { 232 if err := s.d.Start("-D"); err != nil { 233 c.Fatal(err) 234 } 235 content, _ := ioutil.ReadFile(s.d.logFile.Name()) 236 if !strings.Contains(string(content), `level=debug`) { 237 c.Fatalf(`Should have level="debug" in log file using -D:\n%s`, string(content)) 238 } 239 } 240 241 func (s *DockerDaemonSuite) TestDaemonFlagDebug(c *check.C) { 242 if err := s.d.Start("--debug"); err != nil { 243 c.Fatal(err) 244 } 245 content, _ := ioutil.ReadFile(s.d.logFile.Name()) 246 if !strings.Contains(string(content), `level=debug`) { 247 c.Fatalf(`Should have level="debug" in log file using --debug:\n%s`, string(content)) 248 } 249 } 250 251 func (s *DockerDaemonSuite) TestDaemonFlagDebugLogLevelFatal(c *check.C) { 252 if err := s.d.Start("--debug", "--log-level=fatal"); err != nil { 253 c.Fatal(err) 254 } 255 content, _ := ioutil.ReadFile(s.d.logFile.Name()) 256 if !strings.Contains(string(content), `level=debug`) { 257 c.Fatalf(`Should have level="debug" in log file when using both --debug and --log-level=fatal:\n%s`, string(content)) 258 } 259 } 260 261 func (s *DockerDaemonSuite) TestDaemonAllocatesListeningPort(c *check.C) { 262 listeningPorts := [][]string{ 263 {"0.0.0.0", "0.0.0.0", "5678"}, 264 {"127.0.0.1", "127.0.0.1", "1234"}, 265 {"localhost", "127.0.0.1", "1235"}, 266 } 267 268 cmdArgs := []string{} 269 for _, hostDirective := range listeningPorts { 270 cmdArgs = append(cmdArgs, "--host", fmt.Sprintf("tcp://%s:%s", hostDirective[0], hostDirective[2])) 271 } 272 273 if err := s.d.StartWithBusybox(cmdArgs...); err != nil { 274 c.Fatalf("Could not start daemon with busybox: %v", err) 275 } 276 277 for _, hostDirective := range listeningPorts { 278 output, err := s.d.Cmd("run", "-p", fmt.Sprintf("%s:%s:80", hostDirective[1], hostDirective[2]), "busybox", "true") 279 if err == nil { 280 c.Fatalf("Container should not start, expected port already allocated error: %q", output) 281 } else if !strings.Contains(output, "port is already allocated") { 282 c.Fatalf("Expected port is already allocated error: %q", output) 283 } 284 } 285 } 286 287 func (s *DockerDaemonSuite) TestDaemonKeyGeneration(c *check.C) { 288 // TODO: skip or update for Windows daemon 289 os.Remove("/etc/docker/key.json") 290 if err := s.d.Start(); err != nil { 291 c.Fatalf("Could not start daemon: %v", err) 292 } 293 s.d.Stop() 294 295 k, err := libtrust.LoadKeyFile("/etc/docker/key.json") 296 if err != nil { 297 c.Fatalf("Error opening key file") 298 } 299 kid := k.KeyID() 300 // Test Key ID is a valid fingerprint (e.g. QQXN:JY5W:TBXI:MK3X:GX6P:PD5D:F56N:NHCS:LVRZ:JA46:R24J:XEFF) 301 if len(kid) != 59 { 302 c.Fatalf("Bad key ID: %s", kid) 303 } 304 } 305 306 func (s *DockerDaemonSuite) TestDaemonKeyMigration(c *check.C) { 307 // TODO: skip or update for Windows daemon 308 os.Remove("/etc/docker/key.json") 309 k1, err := libtrust.GenerateECP256PrivateKey() 310 if err != nil { 311 c.Fatalf("Error generating private key: %s", err) 312 } 313 if err := os.MkdirAll(filepath.Join(os.Getenv("HOME"), ".docker"), 0755); err != nil { 314 c.Fatalf("Error creating .docker directory: %s", err) 315 } 316 if err := libtrust.SaveKey(filepath.Join(os.Getenv("HOME"), ".docker", "key.json"), k1); err != nil { 317 c.Fatalf("Error saving private key: %s", err) 318 } 319 320 if err := s.d.Start(); err != nil { 321 c.Fatalf("Could not start daemon: %v", err) 322 } 323 s.d.Stop() 324 325 k2, err := libtrust.LoadKeyFile("/etc/docker/key.json") 326 if err != nil { 327 c.Fatalf("Error opening key file") 328 } 329 if k1.KeyID() != k2.KeyID() { 330 c.Fatalf("Key not migrated") 331 } 332 } 333 334 // GH#11320 - verify that the daemon exits on failure properly 335 // Note that this explicitly tests the conflict of {-b,--bridge} and {--bip} options as the means 336 // to get a daemon init failure; no other tests for -b/--bip conflict are therefore required 337 func (s *DockerDaemonSuite) TestDaemonExitOnFailure(c *check.C) { 338 //attempt to start daemon with incorrect flags (we know -b and --bip conflict) 339 if err := s.d.Start("--bridge", "nosuchbridge", "--bip", "1.1.1.1"); err != nil { 340 //verify we got the right error 341 if !strings.Contains(err.Error(), "Daemon exited and never started") { 342 c.Fatalf("Expected daemon not to start, got %v", err) 343 } 344 // look in the log and make sure we got the message that daemon is shutting down 345 runCmd := exec.Command("grep", "Error starting daemon", s.d.LogfileName()) 346 if out, _, err := runCommandWithOutput(runCmd); err != nil { 347 c.Fatalf("Expected 'Error starting daemon' message; but doesn't exist in log: %q, err: %v", out, err) 348 } 349 } else { 350 //if we didn't get an error and the daemon is running, this is a failure 351 c.Fatal("Conflicting options should cause the daemon to error out with a failure") 352 } 353 } 354 355 func (s *DockerDaemonSuite) TestDaemonBridgeExternal(c *check.C) { 356 d := s.d 357 err := d.Start("--bridge", "nosuchbridge") 358 c.Assert(err, check.NotNil, check.Commentf("--bridge option with an invalid bridge should cause the daemon to fail")) 359 defer d.Restart() 360 361 bridgeName := "external-bridge" 362 bridgeIp := "192.169.1.1/24" 363 _, bridgeIPNet, _ := net.ParseCIDR(bridgeIp) 364 365 out, err := createInterface(c, "bridge", bridgeName, bridgeIp) 366 c.Assert(err, check.IsNil, check.Commentf(out)) 367 defer deleteInterface(c, bridgeName) 368 369 err = d.StartWithBusybox("--bridge", bridgeName) 370 c.Assert(err, check.IsNil) 371 372 ipTablesSearchString := bridgeIPNet.String() 373 ipTablesCmd := exec.Command("iptables", "-t", "nat", "-nvL") 374 out, _, err = runCommandWithOutput(ipTablesCmd) 375 c.Assert(err, check.IsNil) 376 377 c.Assert(strings.Contains(out, ipTablesSearchString), check.Equals, true, 378 check.Commentf("iptables output should have contained %q, but was %q", 379 ipTablesSearchString, out)) 380 381 _, err = d.Cmd("run", "-d", "--name", "ExtContainer", "busybox", "top") 382 c.Assert(err, check.IsNil) 383 384 containerIp := d.findContainerIP("ExtContainer") 385 ip := net.ParseIP(containerIp) 386 c.Assert(bridgeIPNet.Contains(ip), check.Equals, true, 387 check.Commentf("Container IP-Address must be in the same subnet range : %s", 388 containerIp)) 389 } 390 391 func createInterface(c *check.C, ifType string, ifName string, ipNet string) (string, error) { 392 args := []string{"link", "add", "name", ifName, "type", ifType} 393 ipLinkCmd := exec.Command("ip", args...) 394 out, _, err := runCommandWithOutput(ipLinkCmd) 395 if err != nil { 396 return out, err 397 } 398 399 ifCfgCmd := exec.Command("ifconfig", ifName, ipNet, "up") 400 out, _, err = runCommandWithOutput(ifCfgCmd) 401 return out, err 402 } 403 404 func deleteInterface(c *check.C, ifName string) { 405 ifCmd := exec.Command("ip", "link", "delete", ifName) 406 out, _, err := runCommandWithOutput(ifCmd) 407 c.Assert(err, check.IsNil, check.Commentf(out)) 408 409 flushCmd := exec.Command("iptables", "-t", "nat", "--flush") 410 out, _, err = runCommandWithOutput(flushCmd) 411 c.Assert(err, check.IsNil, check.Commentf(out)) 412 413 flushCmd = exec.Command("iptables", "--flush") 414 out, _, err = runCommandWithOutput(flushCmd) 415 c.Assert(err, check.IsNil, check.Commentf(out)) 416 } 417 418 func (s *DockerDaemonSuite) TestDaemonBridgeIP(c *check.C) { 419 // TestDaemonBridgeIP Steps 420 // 1. Delete the existing docker0 Bridge 421 // 2. Set --bip daemon configuration and start the new Docker Daemon 422 // 3. Check if the bip config has taken effect using ifconfig and iptables commands 423 // 4. Launch a Container and make sure the IP-Address is in the expected subnet 424 // 5. Delete the docker0 Bridge 425 // 6. Restart the Docker Daemon (via defered action) 426 // This Restart takes care of bringing docker0 interface back to auto-assigned IP 427 428 defaultNetworkBridge := "docker0" 429 deleteInterface(c, defaultNetworkBridge) 430 431 d := s.d 432 433 bridgeIp := "192.169.1.1/24" 434 ip, bridgeIPNet, _ := net.ParseCIDR(bridgeIp) 435 436 err := d.StartWithBusybox("--bip", bridgeIp) 437 c.Assert(err, check.IsNil) 438 defer d.Restart() 439 440 ifconfigSearchString := ip.String() 441 ifconfigCmd := exec.Command("ifconfig", defaultNetworkBridge) 442 out, _, _, err := runCommandWithStdoutStderr(ifconfigCmd) 443 c.Assert(err, check.IsNil) 444 445 c.Assert(strings.Contains(out, ifconfigSearchString), check.Equals, true, 446 check.Commentf("ifconfig output should have contained %q, but was %q", 447 ifconfigSearchString, out)) 448 449 ipTablesSearchString := bridgeIPNet.String() 450 ipTablesCmd := exec.Command("iptables", "-t", "nat", "-nvL") 451 out, _, err = runCommandWithOutput(ipTablesCmd) 452 c.Assert(err, check.IsNil) 453 454 c.Assert(strings.Contains(out, ipTablesSearchString), check.Equals, true, 455 check.Commentf("iptables output should have contained %q, but was %q", 456 ipTablesSearchString, out)) 457 458 out, err = d.Cmd("run", "-d", "--name", "test", "busybox", "top") 459 c.Assert(err, check.IsNil) 460 461 containerIp := d.findContainerIP("test") 462 ip = net.ParseIP(containerIp) 463 c.Assert(bridgeIPNet.Contains(ip), check.Equals, true, 464 check.Commentf("Container IP-Address must be in the same subnet range : %s", 465 containerIp)) 466 deleteInterface(c, defaultNetworkBridge) 467 } 468 469 func (s *DockerDaemonSuite) TestDaemonRestartWithBridgeIPChange(c *check.C) { 470 if err := s.d.Start(); err != nil { 471 c.Fatalf("Could not start daemon: %v", err) 472 } 473 defer s.d.Restart() 474 if err := s.d.Stop(); err != nil { 475 c.Fatalf("Could not stop daemon: %v", err) 476 } 477 478 // now we will change the docker0's IP and then try starting the daemon 479 bridgeIP := "192.169.100.1/24" 480 _, bridgeIPNet, _ := net.ParseCIDR(bridgeIP) 481 482 ipCmd := exec.Command("ifconfig", "docker0", bridgeIP) 483 stdout, stderr, _, err := runCommandWithStdoutStderr(ipCmd) 484 if err != nil { 485 c.Fatalf("failed to change docker0's IP association: %v, stdout: %q, stderr: %q", err, stdout, stderr) 486 } 487 488 if err := s.d.Start("--bip", bridgeIP); err != nil { 489 c.Fatalf("Could not start daemon: %v", err) 490 } 491 492 //check if the iptables contains new bridgeIP MASQUERADE rule 493 ipTablesSearchString := bridgeIPNet.String() 494 ipTablesCmd := exec.Command("iptables", "-t", "nat", "-nvL") 495 out, _, err := runCommandWithOutput(ipTablesCmd) 496 if err != nil { 497 c.Fatalf("Could not run iptables -nvL: %s, %v", out, err) 498 } 499 if !strings.Contains(out, ipTablesSearchString) { 500 c.Fatalf("iptables output should have contained new MASQUERADE rule with IP %q, but was %q", ipTablesSearchString, out) 501 } 502 } 503 504 func (s *DockerDaemonSuite) TestDaemonBridgeFixedCidr(c *check.C) { 505 d := s.d 506 507 bridgeName := "external-bridge" 508 bridgeIp := "192.169.1.1/24" 509 510 out, err := createInterface(c, "bridge", bridgeName, bridgeIp) 511 c.Assert(err, check.IsNil, check.Commentf(out)) 512 defer deleteInterface(c, bridgeName) 513 514 args := []string{"--bridge", bridgeName, "--fixed-cidr", "192.169.1.0/30"} 515 err = d.StartWithBusybox(args...) 516 c.Assert(err, check.IsNil) 517 defer d.Restart() 518 519 for i := 0; i < 4; i++ { 520 cName := "Container" + strconv.Itoa(i) 521 out, err := d.Cmd("run", "-d", "--name", cName, "busybox", "top") 522 if err != nil { 523 c.Assert(strings.Contains(out, "no available ip addresses"), check.Equals, true, 524 check.Commentf("Could not run a Container : %s %s", err.Error(), out)) 525 } 526 } 527 } 528 529 func (s *DockerDaemonSuite) TestDaemonIP(c *check.C) { 530 d := s.d 531 532 ipStr := "192.170.1.1/24" 533 ip, _, _ := net.ParseCIDR(ipStr) 534 args := []string{"--ip", ip.String()} 535 err := d.StartWithBusybox(args...) 536 c.Assert(err, check.IsNil) 537 defer d.Restart() 538 539 out, err := d.Cmd("run", "-d", "-p", "8000:8000", "busybox", "top") 540 c.Assert(err, check.NotNil, 541 check.Commentf("Running a container must fail with an invalid --ip option")) 542 c.Assert(strings.Contains(out, "Error starting userland proxy"), check.Equals, true) 543 544 ifName := "dummy" 545 out, err = createInterface(c, "dummy", ifName, ipStr) 546 c.Assert(err, check.IsNil, check.Commentf(out)) 547 defer deleteInterface(c, ifName) 548 549 _, err = d.Cmd("run", "-d", "-p", "8000:8000", "busybox", "top") 550 c.Assert(err, check.IsNil) 551 552 ipTablesCmd := exec.Command("iptables", "-t", "nat", "-nvL") 553 out, _, err = runCommandWithOutput(ipTablesCmd) 554 c.Assert(err, check.IsNil) 555 556 regex := fmt.Sprintf("DNAT.*%s.*dpt:8000", ip.String()) 557 matched, _ := regexp.MatchString(regex, out) 558 c.Assert(matched, check.Equals, true, 559 check.Commentf("iptables output should have contained %q, but was %q", regex, out)) 560 } 561 562 func (s *DockerDaemonSuite) TestDaemonICCPing(c *check.C) { 563 d := s.d 564 565 bridgeName := "external-bridge" 566 bridgeIp := "192.169.1.1/24" 567 568 out, err := createInterface(c, "bridge", bridgeName, bridgeIp) 569 c.Assert(err, check.IsNil, check.Commentf(out)) 570 defer deleteInterface(c, bridgeName) 571 572 args := []string{"--bridge", bridgeName, "--icc=false"} 573 err = d.StartWithBusybox(args...) 574 c.Assert(err, check.IsNil) 575 defer d.Restart() 576 577 ipTablesCmd := exec.Command("iptables", "-nvL", "FORWARD") 578 out, _, err = runCommandWithOutput(ipTablesCmd) 579 c.Assert(err, check.IsNil) 580 581 regex := fmt.Sprintf("DROP.*all.*%s.*%s", bridgeName, bridgeName) 582 matched, _ := regexp.MatchString(regex, out) 583 c.Assert(matched, check.Equals, true, 584 check.Commentf("iptables output should have contained %q, but was %q", regex, out)) 585 586 // Pinging another container must fail with --icc=false 587 pingContainers(c, d, true) 588 589 ipStr := "192.171.1.1/24" 590 ip, _, _ := net.ParseCIDR(ipStr) 591 ifName := "icc-dummy" 592 593 createInterface(c, "dummy", ifName, ipStr) 594 595 // But, Pinging external or a Host interface must succeed 596 pingCmd := fmt.Sprintf("ping -c 1 %s -W 1", ip.String()) 597 runArgs := []string{"--rm", "busybox", "sh", "-c", pingCmd} 598 _, err = d.Cmd("run", runArgs...) 599 c.Assert(err, check.IsNil) 600 } 601 602 func (s *DockerDaemonSuite) TestDaemonICCLinkExpose(c *check.C) { 603 d := s.d 604 605 bridgeName := "external-bridge" 606 bridgeIp := "192.169.1.1/24" 607 608 out, err := createInterface(c, "bridge", bridgeName, bridgeIp) 609 c.Assert(err, check.IsNil, check.Commentf(out)) 610 defer deleteInterface(c, bridgeName) 611 612 args := []string{"--bridge", bridgeName, "--icc=false"} 613 err = d.StartWithBusybox(args...) 614 c.Assert(err, check.IsNil) 615 defer d.Restart() 616 617 ipTablesCmd := exec.Command("iptables", "-nvL", "FORWARD") 618 out, _, err = runCommandWithOutput(ipTablesCmd) 619 c.Assert(err, check.IsNil) 620 621 regex := fmt.Sprintf("DROP.*all.*%s.*%s", bridgeName, bridgeName) 622 matched, _ := regexp.MatchString(regex, out) 623 c.Assert(matched, check.Equals, true, 624 check.Commentf("iptables output should have contained %q, but was %q", regex, out)) 625 626 out, err = d.Cmd("run", "-d", "--expose", "4567", "--name", "icc1", "busybox", "nc", "-l", "-p", "4567") 627 c.Assert(err, check.IsNil, check.Commentf(out)) 628 629 out, err = d.Cmd("run", "--link", "icc1:icc1", "busybox", "nc", "icc1", "4567") 630 c.Assert(err, check.IsNil, check.Commentf(out)) 631 } 632 633 func (s *DockerDaemonSuite) TestDaemonLinksIpTablesRulesWhenLinkAndUnlink(c *check.C) { 634 bridgeName := "external-bridge" 635 bridgeIp := "192.169.1.1/24" 636 637 out, err := createInterface(c, "bridge", bridgeName, bridgeIp) 638 c.Assert(err, check.IsNil, check.Commentf(out)) 639 defer deleteInterface(c, bridgeName) 640 641 args := []string{"--bridge", bridgeName, "--icc=false"} 642 err = s.d.StartWithBusybox(args...) 643 c.Assert(err, check.IsNil) 644 defer s.d.Restart() 645 646 _, err = s.d.Cmd("run", "-d", "--name", "child", "--publish", "8080:80", "busybox", "top") 647 c.Assert(err, check.IsNil) 648 _, err = s.d.Cmd("run", "-d", "--name", "parent", "--link", "child:http", "busybox", "top") 649 c.Assert(err, check.IsNil) 650 651 childIP := s.d.findContainerIP("child") 652 parentIP := s.d.findContainerIP("parent") 653 654 sourceRule := []string{"-i", bridgeName, "-o", bridgeName, "-p", "tcp", "-s", childIP, "--sport", "80", "-d", parentIP, "-j", "ACCEPT"} 655 destinationRule := []string{"-i", bridgeName, "-o", bridgeName, "-p", "tcp", "-s", parentIP, "--dport", "80", "-d", childIP, "-j", "ACCEPT"} 656 if !iptables.Exists("filter", "DOCKER", sourceRule...) || !iptables.Exists("filter", "DOCKER", destinationRule...) { 657 c.Fatal("Iptables rules not found") 658 } 659 660 s.d.Cmd("rm", "--link", "parent/http") 661 if iptables.Exists("filter", "DOCKER", sourceRule...) || iptables.Exists("filter", "DOCKER", destinationRule...) { 662 c.Fatal("Iptables rules should be removed when unlink") 663 } 664 665 s.d.Cmd("kill", "child") 666 s.d.Cmd("kill", "parent") 667 } 668 669 func (s *DockerDaemonSuite) TestDaemonUlimitDefaults(c *check.C) { 670 testRequires(c, NativeExecDriver) 671 672 if err := s.d.StartWithBusybox("--default-ulimit", "nofile=42:42", "--default-ulimit", "nproc=1024:1024"); err != nil { 673 c.Fatal(err) 674 } 675 676 out, err := s.d.Cmd("run", "--ulimit", "nproc=2048", "--name=test", "busybox", "/bin/sh", "-c", "echo $(ulimit -n); echo $(ulimit -p)") 677 if err != nil { 678 c.Fatal(out, err) 679 } 680 681 outArr := strings.Split(out, "\n") 682 if len(outArr) < 2 { 683 c.Fatalf("got unexpected output: %s", out) 684 } 685 nofile := strings.TrimSpace(outArr[0]) 686 nproc := strings.TrimSpace(outArr[1]) 687 688 if nofile != "42" { 689 c.Fatalf("expected `ulimit -n` to be `42`, got: %s", nofile) 690 } 691 if nproc != "2048" { 692 c.Fatalf("exepcted `ulimit -p` to be 2048, got: %s", nproc) 693 } 694 695 // Now restart daemon with a new default 696 if err := s.d.Restart("--default-ulimit", "nofile=43"); err != nil { 697 c.Fatal(err) 698 } 699 700 out, err = s.d.Cmd("start", "-a", "test") 701 if err != nil { 702 c.Fatal(err) 703 } 704 705 outArr = strings.Split(out, "\n") 706 if len(outArr) < 2 { 707 c.Fatalf("got unexpected output: %s", out) 708 } 709 nofile = strings.TrimSpace(outArr[0]) 710 nproc = strings.TrimSpace(outArr[1]) 711 712 if nofile != "43" { 713 c.Fatalf("expected `ulimit -n` to be `43`, got: %s", nofile) 714 } 715 if nproc != "2048" { 716 c.Fatalf("exepcted `ulimit -p` to be 2048, got: %s", nproc) 717 } 718 } 719 720 // #11315 721 func (s *DockerDaemonSuite) TestDaemonRestartRenameContainer(c *check.C) { 722 if err := s.d.StartWithBusybox(); err != nil { 723 c.Fatal(err) 724 } 725 726 if out, err := s.d.Cmd("run", "--name=test", "busybox"); err != nil { 727 c.Fatal(err, out) 728 } 729 730 if out, err := s.d.Cmd("rename", "test", "test2"); err != nil { 731 c.Fatal(err, out) 732 } 733 734 if err := s.d.Restart(); err != nil { 735 c.Fatal(err) 736 } 737 738 if out, err := s.d.Cmd("start", "test2"); err != nil { 739 c.Fatal(err, out) 740 } 741 } 742 743 func (s *DockerDaemonSuite) TestDaemonLoggingDriverDefault(c *check.C) { 744 if err := s.d.StartWithBusybox(); err != nil { 745 c.Fatal(err) 746 } 747 748 out, err := s.d.Cmd("run", "-d", "busybox", "echo", "testline") 749 if err != nil { 750 c.Fatal(out, err) 751 } 752 id := strings.TrimSpace(out) 753 754 if out, err := s.d.Cmd("wait", id); err != nil { 755 c.Fatal(out, err) 756 } 757 logPath := filepath.Join(s.d.folder, "graph", "containers", id, id+"-json.log") 758 759 if _, err := os.Stat(logPath); err != nil { 760 c.Fatal(err) 761 } 762 f, err := os.Open(logPath) 763 if err != nil { 764 c.Fatal(err) 765 } 766 var res struct { 767 Log string `json:"log"` 768 Stream string `json:"stream"` 769 Time time.Time `json:"time"` 770 } 771 if err := json.NewDecoder(f).Decode(&res); err != nil { 772 c.Fatal(err) 773 } 774 if res.Log != "testline\n" { 775 c.Fatalf("Unexpected log line: %q, expected: %q", res.Log, "testline\n") 776 } 777 if res.Stream != "stdout" { 778 c.Fatalf("Unexpected stream: %q, expected: %q", res.Stream, "stdout") 779 } 780 if !time.Now().After(res.Time) { 781 c.Fatalf("Log time %v in future", res.Time) 782 } 783 } 784 785 func (s *DockerDaemonSuite) TestDaemonLoggingDriverDefaultOverride(c *check.C) { 786 if err := s.d.StartWithBusybox(); err != nil { 787 c.Fatal(err) 788 } 789 790 out, err := s.d.Cmd("run", "-d", "--log-driver=none", "busybox", "echo", "testline") 791 if err != nil { 792 c.Fatal(out, err) 793 } 794 id := strings.TrimSpace(out) 795 796 if out, err := s.d.Cmd("wait", id); err != nil { 797 c.Fatal(out, err) 798 } 799 logPath := filepath.Join(s.d.folder, "graph", "containers", id, id+"-json.log") 800 801 if _, err := os.Stat(logPath); err == nil || !os.IsNotExist(err) { 802 c.Fatalf("%s shouldn't exits, error on Stat: %s", logPath, err) 803 } 804 } 805 806 func (s *DockerDaemonSuite) TestDaemonLoggingDriverNone(c *check.C) { 807 if err := s.d.StartWithBusybox("--log-driver=none"); err != nil { 808 c.Fatal(err) 809 } 810 811 out, err := s.d.Cmd("run", "-d", "busybox", "echo", "testline") 812 if err != nil { 813 c.Fatal(out, err) 814 } 815 id := strings.TrimSpace(out) 816 if out, err := s.d.Cmd("wait", id); err != nil { 817 c.Fatal(out, err) 818 } 819 820 logPath := filepath.Join(s.d.folder, "graph", "containers", id, id+"-json.log") 821 822 if _, err := os.Stat(logPath); err == nil || !os.IsNotExist(err) { 823 c.Fatalf("%s shouldn't exits, error on Stat: %s", logPath, err) 824 } 825 } 826 827 func (s *DockerDaemonSuite) TestDaemonLoggingDriverNoneOverride(c *check.C) { 828 if err := s.d.StartWithBusybox("--log-driver=none"); err != nil { 829 c.Fatal(err) 830 } 831 832 out, err := s.d.Cmd("run", "-d", "--log-driver=json-file", "busybox", "echo", "testline") 833 if err != nil { 834 c.Fatal(out, err) 835 } 836 id := strings.TrimSpace(out) 837 838 if out, err := s.d.Cmd("wait", id); err != nil { 839 c.Fatal(out, err) 840 } 841 logPath := filepath.Join(s.d.folder, "graph", "containers", id, id+"-json.log") 842 843 if _, err := os.Stat(logPath); err != nil { 844 c.Fatal(err) 845 } 846 f, err := os.Open(logPath) 847 if err != nil { 848 c.Fatal(err) 849 } 850 var res struct { 851 Log string `json:"log"` 852 Stream string `json:"stream"` 853 Time time.Time `json:"time"` 854 } 855 if err := json.NewDecoder(f).Decode(&res); err != nil { 856 c.Fatal(err) 857 } 858 if res.Log != "testline\n" { 859 c.Fatalf("Unexpected log line: %q, expected: %q", res.Log, "testline\n") 860 } 861 if res.Stream != "stdout" { 862 c.Fatalf("Unexpected stream: %q, expected: %q", res.Stream, "stdout") 863 } 864 if !time.Now().After(res.Time) { 865 c.Fatalf("Log time %v in future", res.Time) 866 } 867 } 868 869 func (s *DockerDaemonSuite) TestDaemonLoggingDriverNoneLogsError(c *check.C) { 870 if err := s.d.StartWithBusybox("--log-driver=none"); err != nil { 871 c.Fatal(err) 872 } 873 874 out, err := s.d.Cmd("run", "-d", "busybox", "echo", "testline") 875 if err != nil { 876 c.Fatal(out, err) 877 } 878 id := strings.TrimSpace(out) 879 out, err = s.d.Cmd("logs", id) 880 if err == nil { 881 c.Fatalf("Logs should fail with \"none\" driver") 882 } 883 if !strings.Contains(out, `"logs" command is supported only for "json-file" logging driver`) { 884 c.Fatalf("There should be error about non-json-file driver, got: %s", out) 885 } 886 } 887 888 func (s *DockerDaemonSuite) TestDaemonDots(c *check.C) { 889 if err := s.d.StartWithBusybox(); err != nil { 890 c.Fatal(err) 891 } 892 893 // Now create 4 containers 894 if _, err := s.d.Cmd("create", "busybox"); err != nil { 895 c.Fatalf("Error creating container: %q", err) 896 } 897 if _, err := s.d.Cmd("create", "busybox"); err != nil { 898 c.Fatalf("Error creating container: %q", err) 899 } 900 if _, err := s.d.Cmd("create", "busybox"); err != nil { 901 c.Fatalf("Error creating container: %q", err) 902 } 903 if _, err := s.d.Cmd("create", "busybox"); err != nil { 904 c.Fatalf("Error creating container: %q", err) 905 } 906 907 s.d.Stop() 908 909 s.d.Start("--log-level=debug") 910 s.d.Stop() 911 content, _ := ioutil.ReadFile(s.d.logFile.Name()) 912 if strings.Contains(string(content), "....") { 913 c.Fatalf("Debug level should not have ....\n%s", string(content)) 914 } 915 916 s.d.Start("--log-level=error") 917 s.d.Stop() 918 content, _ = ioutil.ReadFile(s.d.logFile.Name()) 919 if strings.Contains(string(content), "....") { 920 c.Fatalf("Error level should not have ....\n%s", string(content)) 921 } 922 923 s.d.Start("--log-level=info") 924 s.d.Stop() 925 content, _ = ioutil.ReadFile(s.d.logFile.Name()) 926 if !strings.Contains(string(content), "....") { 927 c.Fatalf("Info level should have ....\n%s", string(content)) 928 } 929 } 930 931 func (s *DockerDaemonSuite) TestDaemonUnixSockCleanedUp(c *check.C) { 932 dir, err := ioutil.TempDir("", "socket-cleanup-test") 933 if err != nil { 934 c.Fatal(err) 935 } 936 defer os.RemoveAll(dir) 937 938 sockPath := filepath.Join(dir, "docker.sock") 939 if err := s.d.Start("--host", "unix://"+sockPath); err != nil { 940 c.Fatal(err) 941 } 942 943 if _, err := os.Stat(sockPath); err != nil { 944 c.Fatal("socket does not exist") 945 } 946 947 if err := s.d.Stop(); err != nil { 948 c.Fatal(err) 949 } 950 951 if _, err := os.Stat(sockPath); err == nil || !os.IsNotExist(err) { 952 c.Fatal("unix socket is not cleaned up") 953 } 954 } 955 956 func (s *DockerDaemonSuite) TestDaemonWithWrongkey(c *check.C) { 957 type Config struct { 958 Crv string `json:"crv"` 959 D string `json:"d"` 960 Kid string `json:"kid"` 961 Kty string `json:"kty"` 962 X string `json:"x"` 963 Y string `json:"y"` 964 } 965 966 os.Remove("/etc/docker/key.json") 967 if err := s.d.Start(); err != nil { 968 c.Fatalf("Failed to start daemon: %v", err) 969 } 970 971 if err := s.d.Stop(); err != nil { 972 c.Fatalf("Could not stop daemon: %v", err) 973 } 974 975 config := &Config{} 976 bytes, err := ioutil.ReadFile("/etc/docker/key.json") 977 if err != nil { 978 c.Fatalf("Error reading key.json file: %s", err) 979 } 980 981 // byte[] to Data-Struct 982 if err := json.Unmarshal(bytes, &config); err != nil { 983 c.Fatalf("Error Unmarshal: %s", err) 984 } 985 986 //replace config.Kid with the fake value 987 config.Kid = "VSAJ:FUYR:X3H2:B2VZ:KZ6U:CJD5:K7BX:ZXHY:UZXT:P4FT:MJWG:HRJ4" 988 989 // NEW Data-Struct to byte[] 990 newBytes, err := json.Marshal(&config) 991 if err != nil { 992 c.Fatalf("Error Marshal: %s", err) 993 } 994 995 // write back 996 if err := ioutil.WriteFile("/etc/docker/key.json", newBytes, 0400); err != nil { 997 c.Fatalf("Error ioutil.WriteFile: %s", err) 998 } 999 1000 defer os.Remove("/etc/docker/key.json") 1001 1002 if err := s.d.Start(); err == nil { 1003 c.Fatalf("It should not be successful to start daemon with wrong key: %v", err) 1004 } 1005 1006 content, _ := ioutil.ReadFile(s.d.logFile.Name()) 1007 1008 if !strings.Contains(string(content), "Public Key ID does not match") { 1009 c.Fatal("Missing KeyID message from daemon logs") 1010 } 1011 } 1012 1013 func (s *DockerDaemonSuite) TestDaemonRestartKillWait(c *check.C) { 1014 if err := s.d.StartWithBusybox(); err != nil { 1015 c.Fatalf("Could not start daemon with busybox: %v", err) 1016 } 1017 1018 out, err := s.d.Cmd("run", "-id", "busybox", "/bin/cat") 1019 if err != nil { 1020 c.Fatalf("Could not run /bin/cat: err=%v\n%s", err, out) 1021 } 1022 containerID := strings.TrimSpace(out) 1023 1024 if out, err := s.d.Cmd("kill", containerID); err != nil { 1025 c.Fatalf("Could not kill %s: err=%v\n%s", containerID, err, out) 1026 } 1027 1028 if err := s.d.Restart(); err != nil { 1029 c.Fatalf("Could not restart daemon: %v", err) 1030 } 1031 1032 errchan := make(chan error) 1033 go func() { 1034 if out, err := s.d.Cmd("wait", containerID); err != nil { 1035 errchan <- fmt.Errorf("%v:\n%s", err, out) 1036 } 1037 close(errchan) 1038 }() 1039 1040 select { 1041 case <-time.After(5 * time.Second): 1042 c.Fatal("Waiting on a stopped (killed) container timed out") 1043 case err := <-errchan: 1044 if err != nil { 1045 c.Fatal(err) 1046 } 1047 } 1048 } 1049 1050 // TestHttpsInfo connects via two-way authenticated HTTPS to the info endpoint 1051 func (s *DockerDaemonSuite) TestHttpsInfo(c *check.C) { 1052 const ( 1053 testDaemonHttpsAddr = "localhost:4271" 1054 ) 1055 1056 if err := s.d.Start("--tlsverify", "--tlscacert", "fixtures/https/ca.pem", "--tlscert", "fixtures/https/server-cert.pem", 1057 "--tlskey", "fixtures/https/server-key.pem", "-H", testDaemonHttpsAddr); err != nil { 1058 c.Fatalf("Could not start daemon with busybox: %v", err) 1059 } 1060 1061 //force tcp protocol 1062 host := fmt.Sprintf("tcp://%s", testDaemonHttpsAddr) 1063 daemonArgs := []string{"--host", host, "--tlsverify", "--tlscacert", "fixtures/https/ca.pem", "--tlscert", "fixtures/https/client-cert.pem", "--tlskey", "fixtures/https/client-key.pem"} 1064 out, err := s.d.CmdWithArgs(daemonArgs, "info") 1065 if err != nil { 1066 c.Fatalf("Error Occurred: %s and output: %s", err, out) 1067 } 1068 } 1069 1070 // TestHttpsInfoRogueCert connects via two-way authenticated HTTPS to the info endpoint 1071 // by using a rogue client certificate and checks that it fails with the expected error. 1072 func (s *DockerDaemonSuite) TestHttpsInfoRogueCert(c *check.C) { 1073 const ( 1074 errBadCertificate = "remote error: bad certificate" 1075 testDaemonHttpsAddr = "localhost:4271" 1076 ) 1077 if err := s.d.Start("--tlsverify", "--tlscacert", "fixtures/https/ca.pem", "--tlscert", "fixtures/https/server-cert.pem", 1078 "--tlskey", "fixtures/https/server-key.pem", "-H", testDaemonHttpsAddr); err != nil { 1079 c.Fatalf("Could not start daemon with busybox: %v", err) 1080 } 1081 1082 //force tcp protocol 1083 host := fmt.Sprintf("tcp://%s", testDaemonHttpsAddr) 1084 daemonArgs := []string{"--host", host, "--tlsverify", "--tlscacert", "fixtures/https/ca.pem", "--tlscert", "fixtures/https/client-rogue-cert.pem", "--tlskey", "fixtures/https/client-rogue-key.pem"} 1085 out, err := s.d.CmdWithArgs(daemonArgs, "info") 1086 if err == nil || !strings.Contains(out, errBadCertificate) { 1087 c.Fatalf("Expected err: %s, got instead: %s and output: %s", errBadCertificate, err, out) 1088 } 1089 } 1090 1091 // TestHttpsInfoRogueServerCert connects via two-way authenticated HTTPS to the info endpoint 1092 // which provides a rogue server certificate and checks that it fails with the expected error 1093 func (s *DockerDaemonSuite) TestHttpsInfoRogueServerCert(c *check.C) { 1094 const ( 1095 errCaUnknown = "x509: certificate signed by unknown authority" 1096 testDaemonRogueHttpsAddr = "localhost:4272" 1097 ) 1098 if err := s.d.Start("--tlsverify", "--tlscacert", "fixtures/https/ca.pem", "--tlscert", "fixtures/https/server-rogue-cert.pem", 1099 "--tlskey", "fixtures/https/server-rogue-key.pem", "-H", testDaemonRogueHttpsAddr); err != nil { 1100 c.Fatalf("Could not start daemon with busybox: %v", err) 1101 } 1102 1103 //force tcp protocol 1104 host := fmt.Sprintf("tcp://%s", testDaemonRogueHttpsAddr) 1105 daemonArgs := []string{"--host", host, "--tlsverify", "--tlscacert", "fixtures/https/ca.pem", "--tlscert", "fixtures/https/client-rogue-cert.pem", "--tlskey", "fixtures/https/client-rogue-key.pem"} 1106 out, err := s.d.CmdWithArgs(daemonArgs, "info") 1107 if err == nil || !strings.Contains(out, errCaUnknown) { 1108 c.Fatalf("Expected err: %s, got instead: %s and output: %s", errCaUnknown, err, out) 1109 } 1110 } 1111 1112 func pingContainers(c *check.C, d *Daemon, expectFailure bool) { 1113 var dargs []string 1114 if d != nil { 1115 dargs = []string{"--host", d.sock()} 1116 } 1117 1118 args := append(dargs, "run", "-d", "--name", "container1", "busybox", "top") 1119 _, err := runCommand(exec.Command(dockerBinary, args...)) 1120 c.Assert(err, check.IsNil) 1121 1122 args = append(dargs, "run", "--rm", "--link", "container1:alias1", "busybox", "sh", "-c") 1123 pingCmd := "ping -c 1 %s -W 1" 1124 args = append(args, fmt.Sprintf(pingCmd, "alias1")) 1125 _, err = runCommand(exec.Command(dockerBinary, args...)) 1126 1127 if expectFailure { 1128 c.Assert(err, check.NotNil) 1129 } else { 1130 c.Assert(err, check.IsNil) 1131 } 1132 1133 args = append(dargs, "rm", "-f", "container1") 1134 runCommand(exec.Command(dockerBinary, args...)) 1135 } 1136 1137 func (s *DockerDaemonSuite) TestDaemonRestartWithSocketAsVolume(c *check.C) { 1138 c.Assert(s.d.StartWithBusybox(), check.IsNil) 1139 1140 socket := filepath.Join(s.d.folder, "docker.sock") 1141 1142 out, err := s.d.Cmd("run", "-d", "-v", socket+":/sock", "busybox") 1143 c.Assert(err, check.IsNil, check.Commentf("Output: %s", out)) 1144 c.Assert(s.d.Restart(), check.IsNil) 1145 } 1146 1147 func (s *DockerDaemonSuite) TestCleanupMountsAfterCrash(c *check.C) { 1148 c.Assert(s.d.StartWithBusybox(), check.IsNil) 1149 1150 out, err := s.d.Cmd("run", "-d", "busybox", "top") 1151 c.Assert(err, check.IsNil, check.Commentf("Output: %s", out)) 1152 id := strings.TrimSpace(out) 1153 c.Assert(s.d.cmd.Process.Signal(os.Kill), check.IsNil) 1154 c.Assert(s.d.Start(), check.IsNil) 1155 mountOut, err := exec.Command("mount").CombinedOutput() 1156 c.Assert(err, check.IsNil, check.Commentf("Output: %s", mountOut)) 1157 c.Assert(strings.Contains(string(mountOut), id), check.Equals, false, check.Commentf("Something mounted from older daemon start: %s", mountOut)) 1158 } 1159 1160 func (s *DockerDaemonSuite) TestRunContainerWithBridgeNone(c *check.C) { 1161 c.Assert(s.d.StartWithBusybox("-b", "none"), check.IsNil) 1162 1163 out, err := s.d.Cmd("run", "--rm", "busybox", "ip", "l") 1164 c.Assert(err, check.IsNil, check.Commentf("Output: %s", out)) 1165 c.Assert(strings.Contains(out, "eth0"), check.Equals, false, 1166 check.Commentf("There shouldn't be eth0 in container when network is disabled: %s", out)) 1167 } 1168 1169 func (s *DockerDaemonSuite) TestDaemonRestartWithContainerRunning(t *check.C) { 1170 if err := s.d.StartWithBusybox(); err != nil { 1171 t.Fatal(err) 1172 } 1173 if out, err := s.d.Cmd("run", "-ti", "-d", "--name", "test", "busybox"); err != nil { 1174 t.Fatal(out, err) 1175 } 1176 if err := s.d.Restart(); err != nil { 1177 t.Fatal(err) 1178 } 1179 // Container 'test' should be removed without error 1180 if out, err := s.d.Cmd("rm", "test"); err != nil { 1181 t.Fatal(out, err) 1182 } 1183 }