github.com/damirazo/docker@v1.9.0/integration-cli/docker_cli_daemon_test.go (about) 1 // +build daemon,!windows 2 3 package main 4 5 import ( 6 "bytes" 7 "encoding/json" 8 "fmt" 9 "io/ioutil" 10 "net" 11 "os" 12 "os/exec" 13 "path/filepath" 14 "regexp" 15 "strconv" 16 "strings" 17 "time" 18 19 "github.com/docker/docker/pkg/integration/checker" 20 "github.com/docker/libnetwork/iptables" 21 "github.com/docker/libtrust" 22 "github.com/go-check/check" 23 ) 24 25 func (s *DockerDaemonSuite) TestDaemonRestartWithRunningContainersPorts(c *check.C) { 26 if err := s.d.StartWithBusybox(); err != nil { 27 c.Fatalf("Could not start daemon with busybox: %v", err) 28 } 29 30 if out, err := s.d.Cmd("run", "-d", "--name", "top1", "-p", "1234:80", "--restart", "always", "busybox:latest", "top"); err != nil { 31 c.Fatalf("Could not run top1: err=%v\n%s", err, out) 32 } 33 // --restart=no by default 34 if out, err := s.d.Cmd("run", "-d", "--name", "top2", "-p", "80", "busybox:latest", "top"); err != nil { 35 c.Fatalf("Could not run top2: err=%v\n%s", err, out) 36 } 37 38 testRun := func(m map[string]bool, prefix string) { 39 var format string 40 for cont, shouldRun := range m { 41 out, err := s.d.Cmd("ps") 42 if err != nil { 43 c.Fatalf("Could not run ps: err=%v\n%q", err, out) 44 } 45 if shouldRun { 46 format = "%scontainer %q is not running" 47 } else { 48 format = "%scontainer %q is running" 49 } 50 if shouldRun != strings.Contains(out, cont) { 51 c.Fatalf(format, prefix, cont) 52 } 53 } 54 } 55 56 testRun(map[string]bool{"top1": true, "top2": true}, "") 57 58 if err := s.d.Restart(); err != nil { 59 c.Fatalf("Could not restart daemon: %v", err) 60 } 61 testRun(map[string]bool{"top1": true, "top2": false}, "After daemon restart: ") 62 } 63 64 func (s *DockerDaemonSuite) TestDaemonRestartWithVolumesRefs(c *check.C) { 65 if err := s.d.StartWithBusybox(); err != nil { 66 c.Fatal(err) 67 } 68 69 if out, err := s.d.Cmd("run", "-d", "--name", "volrestarttest1", "-v", "/foo", "busybox"); err != nil { 70 c.Fatal(err, out) 71 } 72 73 if err := s.d.Restart(); err != nil { 74 c.Fatal(err) 75 } 76 77 if _, err := s.d.Cmd("run", "-d", "--volumes-from", "volrestarttest1", "--name", "volrestarttest2", "busybox", "top"); err != nil { 78 c.Fatal(err) 79 } 80 81 if out, err := s.d.Cmd("rm", "-fv", "volrestarttest2"); err != nil { 82 c.Fatal(err, out) 83 } 84 85 out, err := s.d.Cmd("inspect", "-f", "{{json .Mounts}}", "volrestarttest1") 86 c.Assert(err, check.IsNil) 87 88 if _, err := inspectMountPointJSON(out, "/foo"); err != nil { 89 c.Fatalf("Expected volume to exist: /foo, error: %v\n", err) 90 } 91 } 92 93 // #11008 94 func (s *DockerDaemonSuite) TestDaemonRestartUnlessStopped(c *check.C) { 95 err := s.d.StartWithBusybox() 96 c.Assert(err, check.IsNil) 97 98 out, err := s.d.Cmd("run", "-d", "--name", "top1", "--restart", "always", "busybox:latest", "top") 99 c.Assert(err, check.IsNil, check.Commentf("run top1: %v", out)) 100 101 out, err = s.d.Cmd("run", "-d", "--name", "top2", "--restart", "unless-stopped", "busybox:latest", "top") 102 c.Assert(err, check.IsNil, check.Commentf("run top2: %v", out)) 103 104 testRun := func(m map[string]bool, prefix string) { 105 var format string 106 for name, shouldRun := range m { 107 out, err := s.d.Cmd("ps") 108 c.Assert(err, check.IsNil, check.Commentf("run ps: %v", out)) 109 if shouldRun { 110 format = "%scontainer %q is not running" 111 } else { 112 format = "%scontainer %q is running" 113 } 114 c.Assert(strings.Contains(out, name), check.Equals, shouldRun, check.Commentf(format, prefix, name)) 115 } 116 } 117 118 // both running 119 testRun(map[string]bool{"top1": true, "top2": true}, "") 120 121 out, err = s.d.Cmd("stop", "top1") 122 c.Assert(err, check.IsNil, check.Commentf(out)) 123 124 out, err = s.d.Cmd("stop", "top2") 125 c.Assert(err, check.IsNil, check.Commentf(out)) 126 127 // both stopped 128 testRun(map[string]bool{"top1": false, "top2": false}, "") 129 130 err = s.d.Restart() 131 c.Assert(err, check.IsNil) 132 133 // restart=always running 134 testRun(map[string]bool{"top1": true, "top2": false}, "After daemon restart: ") 135 136 out, err = s.d.Cmd("start", "top2") 137 c.Assert(err, check.IsNil, check.Commentf("start top2: %v", out)) 138 139 err = s.d.Restart() 140 c.Assert(err, check.IsNil) 141 142 // both running 143 testRun(map[string]bool{"top1": true, "top2": true}, "After second daemon restart: ") 144 145 } 146 147 func (s *DockerDaemonSuite) TestDaemonStartIptablesFalse(c *check.C) { 148 if err := s.d.Start("--iptables=false"); err != nil { 149 c.Fatalf("we should have been able to start the daemon with passing iptables=false: %v", err) 150 } 151 } 152 153 // Issue #8444: If docker0 bridge is modified (intentionally or unintentionally) and 154 // no longer has an IP associated, we should gracefully handle that case and associate 155 // an IP with it rather than fail daemon start 156 func (s *DockerDaemonSuite) TestDaemonStartBridgeWithoutIPAssociation(c *check.C) { 157 // rather than depending on brctl commands to verify docker0 is created and up 158 // let's start the daemon and stop it, and then make a modification to run the 159 // actual test 160 if err := s.d.Start(); err != nil { 161 c.Fatalf("Could not start daemon: %v", err) 162 } 163 if err := s.d.Stop(); err != nil { 164 c.Fatalf("Could not stop daemon: %v", err) 165 } 166 167 // now we will remove the ip from docker0 and then try starting the daemon 168 ipCmd := exec.Command("ip", "addr", "flush", "dev", "docker0") 169 stdout, stderr, _, err := runCommandWithStdoutStderr(ipCmd) 170 if err != nil { 171 c.Fatalf("failed to remove docker0 IP association: %v, stdout: %q, stderr: %q", err, stdout, stderr) 172 } 173 174 if err := s.d.Start(); err != nil { 175 warning := "**WARNING: Docker bridge network in bad state--delete docker0 bridge interface to fix" 176 c.Fatalf("Could not start daemon when docker0 has no IP address: %v\n%s", err, warning) 177 } 178 } 179 180 func (s *DockerDaemonSuite) TestDaemonIptablesClean(c *check.C) { 181 if err := s.d.StartWithBusybox(); err != nil { 182 c.Fatalf("Could not start daemon with busybox: %v", err) 183 } 184 185 if out, err := s.d.Cmd("run", "-d", "--name", "top", "-p", "80", "busybox:latest", "top"); err != nil { 186 c.Fatalf("Could not run top: %s, %v", out, err) 187 } 188 189 // get output from iptables with container running 190 ipTablesSearchString := "tcp dpt:80" 191 ipTablesCmd := exec.Command("iptables", "-nvL") 192 out, _, err := runCommandWithOutput(ipTablesCmd) 193 if err != nil { 194 c.Fatalf("Could not run iptables -nvL: %s, %v", out, err) 195 } 196 197 if !strings.Contains(out, ipTablesSearchString) { 198 c.Fatalf("iptables output should have contained %q, but was %q", ipTablesSearchString, out) 199 } 200 201 if err := s.d.Stop(); err != nil { 202 c.Fatalf("Could not stop daemon: %v", err) 203 } 204 205 // get output from iptables after restart 206 ipTablesCmd = exec.Command("iptables", "-nvL") 207 out, _, err = runCommandWithOutput(ipTablesCmd) 208 if err != nil { 209 c.Fatalf("Could not run iptables -nvL: %s, %v", out, err) 210 } 211 212 if strings.Contains(out, ipTablesSearchString) { 213 c.Fatalf("iptables output should not have contained %q, but was %q", ipTablesSearchString, out) 214 } 215 } 216 217 func (s *DockerDaemonSuite) TestDaemonIptablesCreate(c *check.C) { 218 if err := s.d.StartWithBusybox(); err != nil { 219 c.Fatalf("Could not start daemon with busybox: %v", err) 220 } 221 222 if out, err := s.d.Cmd("run", "-d", "--name", "top", "--restart=always", "-p", "80", "busybox:latest", "top"); err != nil { 223 c.Fatalf("Could not run top: %s, %v", out, err) 224 } 225 226 // get output from iptables with container running 227 ipTablesSearchString := "tcp dpt:80" 228 ipTablesCmd := exec.Command("iptables", "-nvL") 229 out, _, err := runCommandWithOutput(ipTablesCmd) 230 if err != nil { 231 c.Fatalf("Could not run iptables -nvL: %s, %v", out, err) 232 } 233 234 if !strings.Contains(out, ipTablesSearchString) { 235 c.Fatalf("iptables output should have contained %q, but was %q", ipTablesSearchString, out) 236 } 237 238 if err := s.d.Restart(); err != nil { 239 c.Fatalf("Could not restart daemon: %v", err) 240 } 241 242 // make sure the container is not running 243 runningOut, err := s.d.Cmd("inspect", "--format='{{.State.Running}}'", "top") 244 if err != nil { 245 c.Fatalf("Could not inspect on container: %s, %v", out, err) 246 } 247 if strings.TrimSpace(runningOut) != "true" { 248 c.Fatalf("Container should have been restarted after daemon restart. Status running should have been true but was: %q", strings.TrimSpace(runningOut)) 249 } 250 251 // get output from iptables after restart 252 ipTablesCmd = exec.Command("iptables", "-nvL") 253 out, _, err = runCommandWithOutput(ipTablesCmd) 254 if err != nil { 255 c.Fatalf("Could not run iptables -nvL: %s, %v", out, err) 256 } 257 258 if !strings.Contains(out, ipTablesSearchString) { 259 c.Fatalf("iptables output after restart should have contained %q, but was %q", ipTablesSearchString, out) 260 } 261 } 262 263 // TestDaemonIPv6Enabled checks that when the daemon is started with --ipv6=true that the docker0 bridge 264 // has the fe80::1 address and that a container is assigned a link-local address 265 func (s *DockerSuite) TestDaemonIPv6Enabled(c *check.C) { 266 testRequires(c, IPv6) 267 268 if err := setupV6(); err != nil { 269 c.Fatal("Could not set up host for IPv6 tests") 270 } 271 272 d := NewDaemon(c) 273 274 if err := d.StartWithBusybox("--ipv6"); err != nil { 275 c.Fatal(err) 276 } 277 defer d.Stop() 278 279 iface, err := net.InterfaceByName("docker0") 280 if err != nil { 281 c.Fatalf("Error getting docker0 interface: %v", err) 282 } 283 284 addrs, err := iface.Addrs() 285 if err != nil { 286 c.Fatalf("Error getting addresses for docker0 interface: %v", err) 287 } 288 289 var found bool 290 expected := "fe80::1/64" 291 292 for i := range addrs { 293 if addrs[i].String() == expected { 294 found = true 295 } 296 } 297 298 if !found { 299 c.Fatalf("Bridge does not have an IPv6 Address") 300 } 301 302 if out, err := d.Cmd("run", "-itd", "--name=ipv6test", "busybox:latest"); err != nil { 303 c.Fatalf("Could not run container: %s, %v", out, err) 304 } 305 306 out, err := d.Cmd("inspect", "--format", "'{{.NetworkSettings.Networks.bridge.LinkLocalIPv6Address}}'", "ipv6test") 307 out = strings.Trim(out, " \r\n'") 308 309 if err != nil { 310 c.Fatalf("Error inspecting container: %s, %v", out, err) 311 } 312 313 if ip := net.ParseIP(out); ip == nil { 314 c.Fatalf("Container should have a link-local IPv6 address") 315 } 316 317 out, err = d.Cmd("inspect", "--format", "'{{.NetworkSettings.Networks.bridge.GlobalIPv6Address}}'", "ipv6test") 318 out = strings.Trim(out, " \r\n'") 319 320 if err != nil { 321 c.Fatalf("Error inspecting container: %s, %v", out, err) 322 } 323 324 if ip := net.ParseIP(out); ip != nil { 325 c.Fatalf("Container should not have a global IPv6 address: %v", out) 326 } 327 328 if err := teardownV6(); err != nil { 329 c.Fatal("Could not perform teardown for IPv6 tests") 330 } 331 332 } 333 334 // TestDaemonIPv6FixedCIDR checks that when the daemon is started with --ipv6=true and a fixed CIDR 335 // that running containers are given a link-local and global IPv6 address 336 func (s *DockerSuite) TestDaemonIPv6FixedCIDR(c *check.C) { 337 testRequires(c, IPv6) 338 339 if err := setupV6(); err != nil { 340 c.Fatal("Could not set up host for IPv6 tests") 341 } 342 343 d := NewDaemon(c) 344 345 if err := d.StartWithBusybox("--ipv6", "--fixed-cidr-v6='2001:db8:1::/64'"); err != nil { 346 c.Fatalf("Could not start daemon with busybox: %v", err) 347 } 348 defer d.Stop() 349 350 if out, err := d.Cmd("run", "-itd", "--name=ipv6test", "busybox:latest"); err != nil { 351 c.Fatalf("Could not run container: %s, %v", out, err) 352 } 353 354 out, err := d.Cmd("inspect", "--format", "'{{.NetworkSettings.Networks.bridge.LinkLocalIPv6Address}}'", "ipv6test") 355 out = strings.Trim(out, " \r\n'") 356 357 if err != nil { 358 c.Fatalf("Error inspecting container: %s, %v", out, err) 359 } 360 361 if ip := net.ParseIP(out); ip == nil { 362 c.Fatalf("Container should have a link-local IPv6 address") 363 } 364 365 out, err = d.Cmd("inspect", "--format", "'{{.NetworkSettings.Networks.bridge.GlobalIPv6Address}}'", "ipv6test") 366 out = strings.Trim(out, " \r\n'") 367 368 if err != nil { 369 c.Fatalf("Error inspecting container: %s, %v", out, err) 370 } 371 372 if ip := net.ParseIP(out); ip == nil { 373 c.Fatalf("Container should have a global IPv6 address") 374 } 375 if err := teardownV6(); err != nil { 376 c.Fatal("Could not perform teardown for IPv6 tests") 377 } 378 } 379 380 func (s *DockerDaemonSuite) TestDaemonLogLevelWrong(c *check.C) { 381 c.Assert(s.d.Start("--log-level=bogus"), check.NotNil, check.Commentf("Daemon shouldn't start with wrong log level")) 382 } 383 384 func (s *DockerSuite) TestDaemonStartWithBackwardCompatibility(c *check.C) { 385 386 var validCommandArgs = [][]string{ 387 {"--selinux-enabled", "-l", "info"}, 388 {"--insecure-registry", "daemon"}, 389 } 390 391 var invalidCommandArgs = [][]string{ 392 {"--selinux-enabled", "--storage-opt"}, 393 {"-D", "-b"}, 394 {"--config", "/tmp"}, 395 } 396 397 for _, args := range validCommandArgs { 398 d := NewDaemon(c) 399 d.Command = "--daemon" 400 if err := d.Start(args...); err != nil { 401 c.Fatalf("Daemon should have started successfully with --daemon %v: %v", args, err) 402 } 403 d.Stop() 404 } 405 406 for _, args := range invalidCommandArgs { 407 d := NewDaemon(c) 408 if err := d.Start(args...); err == nil { 409 d.Stop() 410 c.Fatalf("Daemon should have failed to start with %v", args) 411 } 412 } 413 } 414 415 func (s *DockerSuite) TestDaemonStartWithDaemonCommand(c *check.C) { 416 417 type kind int 418 419 const ( 420 common kind = iota 421 daemon 422 ) 423 424 var flags = []map[kind][]string{ 425 {common: {"-l", "info"}, daemon: {"--selinux-enabled"}}, 426 {common: {"-D"}, daemon: {"--selinux-enabled", "-r"}}, 427 {common: {"-D"}, daemon: {"--restart"}}, 428 {common: {"--debug"}, daemon: {"--log-driver=json-file", "--log-opt=max-size=1k"}}, 429 } 430 431 var invalidGlobalFlags = [][]string{ 432 //Invalid because you cannot pass daemon flags as global flags. 433 {"--selinux-enabled", "-l", "info"}, 434 {"-D", "-r"}, 435 {"--config", "/tmp"}, 436 } 437 438 // `docker daemon -l info --selinux-enabled` 439 // should NOT error out 440 for _, f := range flags { 441 d := NewDaemon(c) 442 args := append(f[common], f[daemon]...) 443 if err := d.Start(args...); err != nil { 444 c.Fatalf("Daemon should have started successfully with %v: %v", args, err) 445 } 446 d.Stop() 447 } 448 449 // `docker -l info daemon --selinux-enabled` 450 // should error out 451 for _, f := range flags { 452 d := NewDaemon(c) 453 d.GlobalFlags = f[common] 454 if err := d.Start(f[daemon]...); err == nil { 455 d.Stop() 456 c.Fatalf("Daemon should have failed to start with docker %v daemon %v", d.GlobalFlags, f[daemon]) 457 } 458 } 459 460 for _, f := range invalidGlobalFlags { 461 cmd := exec.Command(dockerBinary, append(f, "daemon")...) 462 errch := make(chan error) 463 var err error 464 go func() { 465 errch <- cmd.Run() 466 }() 467 select { 468 case <-time.After(time.Second): 469 cmd.Process.Kill() 470 case err = <-errch: 471 } 472 if err == nil { 473 c.Fatalf("Daemon should have failed to start with docker %v daemon", f) 474 } 475 } 476 } 477 478 func (s *DockerDaemonSuite) TestDaemonLogLevelDebug(c *check.C) { 479 if err := s.d.Start("--log-level=debug"); err != nil { 480 c.Fatal(err) 481 } 482 content, _ := ioutil.ReadFile(s.d.logFile.Name()) 483 if !strings.Contains(string(content), `level=debug`) { 484 c.Fatalf(`Missing level="debug" in log file:\n%s`, string(content)) 485 } 486 } 487 488 func (s *DockerDaemonSuite) TestDaemonLogLevelFatal(c *check.C) { 489 // we creating new daemons to create new logFile 490 if err := s.d.Start("--log-level=fatal"); err != nil { 491 c.Fatal(err) 492 } 493 content, _ := ioutil.ReadFile(s.d.logFile.Name()) 494 if strings.Contains(string(content), `level=debug`) { 495 c.Fatalf(`Should not have level="debug" in log file:\n%s`, string(content)) 496 } 497 } 498 499 func (s *DockerDaemonSuite) TestDaemonFlagD(c *check.C) { 500 if err := s.d.Start("-D"); err != nil { 501 c.Fatal(err) 502 } 503 content, _ := ioutil.ReadFile(s.d.logFile.Name()) 504 if !strings.Contains(string(content), `level=debug`) { 505 c.Fatalf(`Should have level="debug" in log file using -D:\n%s`, string(content)) 506 } 507 } 508 509 func (s *DockerDaemonSuite) TestDaemonFlagDebug(c *check.C) { 510 if err := s.d.Start("--debug"); err != nil { 511 c.Fatal(err) 512 } 513 content, _ := ioutil.ReadFile(s.d.logFile.Name()) 514 if !strings.Contains(string(content), `level=debug`) { 515 c.Fatalf(`Should have level="debug" in log file using --debug:\n%s`, string(content)) 516 } 517 } 518 519 func (s *DockerDaemonSuite) TestDaemonFlagDebugLogLevelFatal(c *check.C) { 520 if err := s.d.Start("--debug", "--log-level=fatal"); err != nil { 521 c.Fatal(err) 522 } 523 content, _ := ioutil.ReadFile(s.d.logFile.Name()) 524 if !strings.Contains(string(content), `level=debug`) { 525 c.Fatalf(`Should have level="debug" in log file when using both --debug and --log-level=fatal:\n%s`, string(content)) 526 } 527 } 528 529 func (s *DockerDaemonSuite) TestDaemonAllocatesListeningPort(c *check.C) { 530 listeningPorts := [][]string{ 531 {"0.0.0.0", "0.0.0.0", "5678"}, 532 {"127.0.0.1", "127.0.0.1", "1234"}, 533 {"localhost", "127.0.0.1", "1235"}, 534 } 535 536 cmdArgs := make([]string, 0, len(listeningPorts)*2) 537 for _, hostDirective := range listeningPorts { 538 cmdArgs = append(cmdArgs, "--host", fmt.Sprintf("tcp://%s:%s", hostDirective[0], hostDirective[2])) 539 } 540 541 if err := s.d.StartWithBusybox(cmdArgs...); err != nil { 542 c.Fatalf("Could not start daemon with busybox: %v", err) 543 } 544 545 for _, hostDirective := range listeningPorts { 546 output, err := s.d.Cmd("run", "-p", fmt.Sprintf("%s:%s:80", hostDirective[1], hostDirective[2]), "busybox", "true") 547 if err == nil { 548 c.Fatalf("Container should not start, expected port already allocated error: %q", output) 549 } else if !strings.Contains(output, "port is already allocated") { 550 c.Fatalf("Expected port is already allocated error: %q", output) 551 } 552 } 553 } 554 555 func (s *DockerDaemonSuite) TestDaemonKeyGeneration(c *check.C) { 556 // TODO: skip or update for Windows daemon 557 os.Remove("/etc/docker/key.json") 558 if err := s.d.Start(); err != nil { 559 c.Fatalf("Could not start daemon: %v", err) 560 } 561 s.d.Stop() 562 563 k, err := libtrust.LoadKeyFile("/etc/docker/key.json") 564 if err != nil { 565 c.Fatalf("Error opening key file") 566 } 567 kid := k.KeyID() 568 // Test Key ID is a valid fingerprint (e.g. QQXN:JY5W:TBXI:MK3X:GX6P:PD5D:F56N:NHCS:LVRZ:JA46:R24J:XEFF) 569 if len(kid) != 59 { 570 c.Fatalf("Bad key ID: %s", kid) 571 } 572 } 573 574 func (s *DockerDaemonSuite) TestDaemonKeyMigration(c *check.C) { 575 // TODO: skip or update for Windows daemon 576 os.Remove("/etc/docker/key.json") 577 k1, err := libtrust.GenerateECP256PrivateKey() 578 if err != nil { 579 c.Fatalf("Error generating private key: %s", err) 580 } 581 if err := os.MkdirAll(filepath.Join(os.Getenv("HOME"), ".docker"), 0755); err != nil { 582 c.Fatalf("Error creating .docker directory: %s", err) 583 } 584 if err := libtrust.SaveKey(filepath.Join(os.Getenv("HOME"), ".docker", "key.json"), k1); err != nil { 585 c.Fatalf("Error saving private key: %s", err) 586 } 587 588 if err := s.d.Start(); err != nil { 589 c.Fatalf("Could not start daemon: %v", err) 590 } 591 s.d.Stop() 592 593 k2, err := libtrust.LoadKeyFile("/etc/docker/key.json") 594 if err != nil { 595 c.Fatalf("Error opening key file") 596 } 597 if k1.KeyID() != k2.KeyID() { 598 c.Fatalf("Key not migrated") 599 } 600 } 601 602 // GH#11320 - verify that the daemon exits on failure properly 603 // Note that this explicitly tests the conflict of {-b,--bridge} and {--bip} options as the means 604 // to get a daemon init failure; no other tests for -b/--bip conflict are therefore required 605 func (s *DockerDaemonSuite) TestDaemonExitOnFailure(c *check.C) { 606 //attempt to start daemon with incorrect flags (we know -b and --bip conflict) 607 if err := s.d.Start("--bridge", "nosuchbridge", "--bip", "1.1.1.1"); err != nil { 608 //verify we got the right error 609 if !strings.Contains(err.Error(), "Daemon exited and never started") { 610 c.Fatalf("Expected daemon not to start, got %v", err) 611 } 612 // look in the log and make sure we got the message that daemon is shutting down 613 runCmd := exec.Command("grep", "Error starting daemon", s.d.LogfileName()) 614 if out, _, err := runCommandWithOutput(runCmd); err != nil { 615 c.Fatalf("Expected 'Error starting daemon' message; but doesn't exist in log: %q, err: %v", out, err) 616 } 617 } else { 618 //if we didn't get an error and the daemon is running, this is a failure 619 c.Fatal("Conflicting options should cause the daemon to error out with a failure") 620 } 621 } 622 623 func (s *DockerDaemonSuite) TestDaemonBridgeExternal(c *check.C) { 624 d := s.d 625 err := d.Start("--bridge", "nosuchbridge") 626 c.Assert(err, check.NotNil, check.Commentf("--bridge option with an invalid bridge should cause the daemon to fail")) 627 defer d.Restart() 628 629 bridgeName := "external-bridge" 630 bridgeIP := "192.169.1.1/24" 631 _, bridgeIPNet, _ := net.ParseCIDR(bridgeIP) 632 633 out, err := createInterface(c, "bridge", bridgeName, bridgeIP) 634 c.Assert(err, check.IsNil, check.Commentf(out)) 635 defer deleteInterface(c, bridgeName) 636 637 err = d.StartWithBusybox("--bridge", bridgeName) 638 c.Assert(err, check.IsNil) 639 640 ipTablesSearchString := bridgeIPNet.String() 641 ipTablesCmd := exec.Command("iptables", "-t", "nat", "-nvL") 642 out, _, err = runCommandWithOutput(ipTablesCmd) 643 c.Assert(err, check.IsNil) 644 645 c.Assert(strings.Contains(out, ipTablesSearchString), check.Equals, true, 646 check.Commentf("iptables output should have contained %q, but was %q", 647 ipTablesSearchString, out)) 648 649 _, err = d.Cmd("run", "-d", "--name", "ExtContainer", "busybox", "top") 650 c.Assert(err, check.IsNil) 651 652 containerIP := d.findContainerIP("ExtContainer") 653 ip := net.ParseIP(containerIP) 654 c.Assert(bridgeIPNet.Contains(ip), check.Equals, true, 655 check.Commentf("Container IP-Address must be in the same subnet range : %s", 656 containerIP)) 657 } 658 659 func createInterface(c *check.C, ifType string, ifName string, ipNet string) (string, error) { 660 args := []string{"link", "add", "name", ifName, "type", ifType} 661 ipLinkCmd := exec.Command("ip", args...) 662 out, _, err := runCommandWithOutput(ipLinkCmd) 663 if err != nil { 664 return out, err 665 } 666 667 ifCfgCmd := exec.Command("ifconfig", ifName, ipNet, "up") 668 out, _, err = runCommandWithOutput(ifCfgCmd) 669 return out, err 670 } 671 672 func deleteInterface(c *check.C, ifName string) { 673 ifCmd := exec.Command("ip", "link", "delete", ifName) 674 out, _, err := runCommandWithOutput(ifCmd) 675 c.Assert(err, check.IsNil, check.Commentf(out)) 676 677 flushCmd := exec.Command("iptables", "-t", "nat", "--flush") 678 out, _, err = runCommandWithOutput(flushCmd) 679 c.Assert(err, check.IsNil, check.Commentf(out)) 680 681 flushCmd = exec.Command("iptables", "--flush") 682 out, _, err = runCommandWithOutput(flushCmd) 683 c.Assert(err, check.IsNil, check.Commentf(out)) 684 } 685 686 func (s *DockerDaemonSuite) TestDaemonBridgeIP(c *check.C) { 687 // TestDaemonBridgeIP Steps 688 // 1. Delete the existing docker0 Bridge 689 // 2. Set --bip daemon configuration and start the new Docker Daemon 690 // 3. Check if the bip config has taken effect using ifconfig and iptables commands 691 // 4. Launch a Container and make sure the IP-Address is in the expected subnet 692 // 5. Delete the docker0 Bridge 693 // 6. Restart the Docker Daemon (via deferred action) 694 // This Restart takes care of bringing docker0 interface back to auto-assigned IP 695 696 defaultNetworkBridge := "docker0" 697 deleteInterface(c, defaultNetworkBridge) 698 699 d := s.d 700 701 bridgeIP := "192.169.1.1/24" 702 ip, bridgeIPNet, _ := net.ParseCIDR(bridgeIP) 703 704 err := d.StartWithBusybox("--bip", bridgeIP) 705 c.Assert(err, check.IsNil) 706 defer d.Restart() 707 708 ifconfigSearchString := ip.String() 709 ifconfigCmd := exec.Command("ifconfig", defaultNetworkBridge) 710 out, _, _, err := runCommandWithStdoutStderr(ifconfigCmd) 711 c.Assert(err, check.IsNil) 712 713 c.Assert(strings.Contains(out, ifconfigSearchString), check.Equals, true, 714 check.Commentf("ifconfig output should have contained %q, but was %q", 715 ifconfigSearchString, out)) 716 717 ipTablesSearchString := bridgeIPNet.String() 718 ipTablesCmd := exec.Command("iptables", "-t", "nat", "-nvL") 719 out, _, err = runCommandWithOutput(ipTablesCmd) 720 c.Assert(err, check.IsNil) 721 722 c.Assert(strings.Contains(out, ipTablesSearchString), check.Equals, true, 723 check.Commentf("iptables output should have contained %q, but was %q", 724 ipTablesSearchString, out)) 725 726 out, err = d.Cmd("run", "-d", "--name", "test", "busybox", "top") 727 c.Assert(err, check.IsNil) 728 729 containerIP := d.findContainerIP("test") 730 ip = net.ParseIP(containerIP) 731 c.Assert(bridgeIPNet.Contains(ip), check.Equals, true, 732 check.Commentf("Container IP-Address must be in the same subnet range : %s", 733 containerIP)) 734 deleteInterface(c, defaultNetworkBridge) 735 } 736 737 func (s *DockerDaemonSuite) TestDaemonRestartWithBridgeIPChange(c *check.C) { 738 if err := s.d.Start(); err != nil { 739 c.Fatalf("Could not start daemon: %v", err) 740 } 741 defer s.d.Restart() 742 if err := s.d.Stop(); err != nil { 743 c.Fatalf("Could not stop daemon: %v", err) 744 } 745 746 // now we will change the docker0's IP and then try starting the daemon 747 bridgeIP := "192.169.100.1/24" 748 _, bridgeIPNet, _ := net.ParseCIDR(bridgeIP) 749 750 ipCmd := exec.Command("ifconfig", "docker0", bridgeIP) 751 stdout, stderr, _, err := runCommandWithStdoutStderr(ipCmd) 752 if err != nil { 753 c.Fatalf("failed to change docker0's IP association: %v, stdout: %q, stderr: %q", err, stdout, stderr) 754 } 755 756 if err := s.d.Start("--bip", bridgeIP); err != nil { 757 c.Fatalf("Could not start daemon: %v", err) 758 } 759 760 //check if the iptables contains new bridgeIP MASQUERADE rule 761 ipTablesSearchString := bridgeIPNet.String() 762 ipTablesCmd := exec.Command("iptables", "-t", "nat", "-nvL") 763 out, _, err := runCommandWithOutput(ipTablesCmd) 764 if err != nil { 765 c.Fatalf("Could not run iptables -nvL: %s, %v", out, err) 766 } 767 if !strings.Contains(out, ipTablesSearchString) { 768 c.Fatalf("iptables output should have contained new MASQUERADE rule with IP %q, but was %q", ipTablesSearchString, out) 769 } 770 } 771 772 func (s *DockerDaemonSuite) TestDaemonBridgeFixedCidr(c *check.C) { 773 d := s.d 774 775 bridgeName := "external-bridge" 776 bridgeIP := "192.169.1.1/24" 777 778 out, err := createInterface(c, "bridge", bridgeName, bridgeIP) 779 c.Assert(err, check.IsNil, check.Commentf(out)) 780 defer deleteInterface(c, bridgeName) 781 782 args := []string{"--bridge", bridgeName, "--fixed-cidr", "192.169.1.0/30"} 783 err = d.StartWithBusybox(args...) 784 c.Assert(err, check.IsNil) 785 defer d.Restart() 786 787 for i := 0; i < 4; i++ { 788 cName := "Container" + strconv.Itoa(i) 789 out, err := d.Cmd("run", "-d", "--name", cName, "busybox", "top") 790 if err != nil { 791 c.Assert(strings.Contains(out, "no available IPv4 addresses"), check.Equals, true, 792 check.Commentf("Could not run a Container : %s %s", err.Error(), out)) 793 } 794 } 795 } 796 797 func (s *DockerDaemonSuite) TestDaemonBridgeFixedCidrFixedCIDREqualBridgeNetwork(c *check.C) { 798 d := s.d 799 800 bridgeName := "external-bridge" 801 bridgeIP := "172.27.42.1/16" 802 803 out, err := createInterface(c, "bridge", bridgeName, bridgeIP) 804 c.Assert(err, check.IsNil, check.Commentf(out)) 805 defer deleteInterface(c, bridgeName) 806 807 err = d.StartWithBusybox("--bridge", bridgeName, "--fixed-cidr", bridgeIP) 808 c.Assert(err, check.IsNil) 809 defer s.d.Restart() 810 811 out, err = d.Cmd("run", "-d", "busybox", "top") 812 c.Assert(err, check.IsNil, check.Commentf(out)) 813 cid1 := strings.TrimSpace(out) 814 defer d.Cmd("stop", cid1) 815 } 816 817 func (s *DockerDaemonSuite) TestDaemonDefaultGatewayIPv4Implicit(c *check.C) { 818 defaultNetworkBridge := "docker0" 819 deleteInterface(c, defaultNetworkBridge) 820 821 d := s.d 822 823 bridgeIP := "192.169.1.1" 824 bridgeIPNet := fmt.Sprintf("%s/24", bridgeIP) 825 826 err := d.StartWithBusybox("--bip", bridgeIPNet) 827 c.Assert(err, check.IsNil) 828 defer d.Restart() 829 830 expectedMessage := fmt.Sprintf("default via %s dev", bridgeIP) 831 out, err := d.Cmd("run", "busybox", "ip", "-4", "route", "list", "0/0") 832 c.Assert(strings.Contains(out, expectedMessage), check.Equals, true, 833 check.Commentf("Implicit default gateway should be bridge IP %s, but default route was '%s'", 834 bridgeIP, strings.TrimSpace(out))) 835 deleteInterface(c, defaultNetworkBridge) 836 } 837 838 func (s *DockerDaemonSuite) TestDaemonDefaultGatewayIPv4Explicit(c *check.C) { 839 defaultNetworkBridge := "docker0" 840 deleteInterface(c, defaultNetworkBridge) 841 842 d := s.d 843 844 bridgeIP := "192.169.1.1" 845 bridgeIPNet := fmt.Sprintf("%s/24", bridgeIP) 846 gatewayIP := "192.169.1.254" 847 848 err := d.StartWithBusybox("--bip", bridgeIPNet, "--default-gateway", gatewayIP) 849 c.Assert(err, check.IsNil) 850 defer d.Restart() 851 852 expectedMessage := fmt.Sprintf("default via %s dev", gatewayIP) 853 out, err := d.Cmd("run", "busybox", "ip", "-4", "route", "list", "0/0") 854 c.Assert(strings.Contains(out, expectedMessage), check.Equals, true, 855 check.Commentf("Explicit default gateway should be %s, but default route was '%s'", 856 gatewayIP, strings.TrimSpace(out))) 857 deleteInterface(c, defaultNetworkBridge) 858 } 859 860 func (s *DockerDaemonSuite) TestDaemonDefaultGatewayIPv4ExplicitOutsideContainerSubnet(c *check.C) { 861 defaultNetworkBridge := "docker0" 862 deleteInterface(c, defaultNetworkBridge) 863 864 // Program a custom default gateway outside of the container subnet, daemon should accept it and start 865 err := s.d.StartWithBusybox("--bip", "172.16.0.10/16", "--fixed-cidr", "172.16.1.0/24", "--default-gateway", "172.16.0.254") 866 c.Assert(err, check.IsNil) 867 868 deleteInterface(c, defaultNetworkBridge) 869 s.d.Restart() 870 } 871 872 func (s *DockerDaemonSuite) TestDaemonDefaultNetworkInvalidClusterConfig(c *check.C) { 873 testRequires(c, SameHostDaemon) 874 875 // Start daemon without docker0 bridge 876 defaultNetworkBridge := "docker0" 877 deleteInterface(c, defaultNetworkBridge) 878 879 d := NewDaemon(c) 880 discoveryBackend := "consul://consuladdr:consulport/some/path" 881 err := d.Start(fmt.Sprintf("--cluster-store=%s", discoveryBackend)) 882 c.Assert(err, checker.IsNil) 883 884 // Start daemon with docker0 bridge 885 ifconfigCmd := exec.Command("ifconfig", defaultNetworkBridge) 886 _, err = runCommand(ifconfigCmd) 887 c.Assert(err, check.IsNil) 888 889 err = d.Restart(fmt.Sprintf("--cluster-store=%s", discoveryBackend)) 890 c.Assert(err, checker.IsNil) 891 892 d.Stop() 893 } 894 895 func (s *DockerDaemonSuite) TestDaemonIP(c *check.C) { 896 d := s.d 897 898 ipStr := "192.170.1.1/24" 899 ip, _, _ := net.ParseCIDR(ipStr) 900 args := []string{"--ip", ip.String()} 901 err := d.StartWithBusybox(args...) 902 c.Assert(err, check.IsNil) 903 defer d.Restart() 904 905 out, err := d.Cmd("run", "-d", "-p", "8000:8000", "busybox", "top") 906 c.Assert(err, check.NotNil, 907 check.Commentf("Running a container must fail with an invalid --ip option")) 908 c.Assert(strings.Contains(out, "Error starting userland proxy"), check.Equals, true) 909 910 ifName := "dummy" 911 out, err = createInterface(c, "dummy", ifName, ipStr) 912 c.Assert(err, check.IsNil, check.Commentf(out)) 913 defer deleteInterface(c, ifName) 914 915 _, err = d.Cmd("run", "-d", "-p", "8000:8000", "busybox", "top") 916 c.Assert(err, check.IsNil) 917 918 ipTablesCmd := exec.Command("iptables", "-t", "nat", "-nvL") 919 out, _, err = runCommandWithOutput(ipTablesCmd) 920 c.Assert(err, check.IsNil) 921 922 regex := fmt.Sprintf("DNAT.*%s.*dpt:8000", ip.String()) 923 matched, _ := regexp.MatchString(regex, out) 924 c.Assert(matched, check.Equals, true, 925 check.Commentf("iptables output should have contained %q, but was %q", regex, out)) 926 } 927 928 func (s *DockerDaemonSuite) TestDaemonICCPing(c *check.C) { 929 d := s.d 930 931 bridgeName := "external-bridge" 932 bridgeIP := "192.169.1.1/24" 933 934 out, err := createInterface(c, "bridge", bridgeName, bridgeIP) 935 c.Assert(err, check.IsNil, check.Commentf(out)) 936 defer deleteInterface(c, bridgeName) 937 938 args := []string{"--bridge", bridgeName, "--icc=false"} 939 err = d.StartWithBusybox(args...) 940 c.Assert(err, check.IsNil) 941 defer d.Restart() 942 943 ipTablesCmd := exec.Command("iptables", "-nvL", "FORWARD") 944 out, _, err = runCommandWithOutput(ipTablesCmd) 945 c.Assert(err, check.IsNil) 946 947 regex := fmt.Sprintf("DROP.*all.*%s.*%s", bridgeName, bridgeName) 948 matched, _ := regexp.MatchString(regex, out) 949 c.Assert(matched, check.Equals, true, 950 check.Commentf("iptables output should have contained %q, but was %q", regex, out)) 951 952 // Pinging another container must fail with --icc=false 953 pingContainers(c, d, true) 954 955 ipStr := "192.171.1.1/24" 956 ip, _, _ := net.ParseCIDR(ipStr) 957 ifName := "icc-dummy" 958 959 createInterface(c, "dummy", ifName, ipStr) 960 961 // But, Pinging external or a Host interface must succeed 962 pingCmd := fmt.Sprintf("ping -c 1 %s -W 1", ip.String()) 963 runArgs := []string{"--rm", "busybox", "sh", "-c", pingCmd} 964 _, err = d.Cmd("run", runArgs...) 965 c.Assert(err, check.IsNil) 966 } 967 968 func (s *DockerDaemonSuite) TestDaemonICCLinkExpose(c *check.C) { 969 d := s.d 970 971 bridgeName := "external-bridge" 972 bridgeIP := "192.169.1.1/24" 973 974 out, err := createInterface(c, "bridge", bridgeName, bridgeIP) 975 c.Assert(err, check.IsNil, check.Commentf(out)) 976 defer deleteInterface(c, bridgeName) 977 978 args := []string{"--bridge", bridgeName, "--icc=false"} 979 err = d.StartWithBusybox(args...) 980 c.Assert(err, check.IsNil) 981 defer d.Restart() 982 983 ipTablesCmd := exec.Command("iptables", "-nvL", "FORWARD") 984 out, _, err = runCommandWithOutput(ipTablesCmd) 985 c.Assert(err, check.IsNil) 986 987 regex := fmt.Sprintf("DROP.*all.*%s.*%s", bridgeName, bridgeName) 988 matched, _ := regexp.MatchString(regex, out) 989 c.Assert(matched, check.Equals, true, 990 check.Commentf("iptables output should have contained %q, but was %q", regex, out)) 991 992 out, err = d.Cmd("run", "-d", "--expose", "4567", "--name", "icc1", "busybox", "nc", "-l", "-p", "4567") 993 c.Assert(err, check.IsNil, check.Commentf(out)) 994 995 out, err = d.Cmd("run", "--link", "icc1:icc1", "busybox", "nc", "icc1", "4567") 996 c.Assert(err, check.IsNil, check.Commentf(out)) 997 } 998 999 func (s *DockerDaemonSuite) TestDaemonLinksIpTablesRulesWhenLinkAndUnlink(c *check.C) { 1000 bridgeName := "external-bridge" 1001 bridgeIP := "192.169.1.1/24" 1002 1003 out, err := createInterface(c, "bridge", bridgeName, bridgeIP) 1004 c.Assert(err, check.IsNil, check.Commentf(out)) 1005 defer deleteInterface(c, bridgeName) 1006 1007 err = s.d.StartWithBusybox("--bridge", bridgeName, "--icc=false") 1008 c.Assert(err, check.IsNil) 1009 defer s.d.Restart() 1010 1011 _, err = s.d.Cmd("run", "-d", "--name", "child", "--publish", "8080:80", "busybox", "top") 1012 c.Assert(err, check.IsNil) 1013 _, err = s.d.Cmd("run", "-d", "--name", "parent", "--link", "child:http", "busybox", "top") 1014 c.Assert(err, check.IsNil) 1015 1016 childIP := s.d.findContainerIP("child") 1017 parentIP := s.d.findContainerIP("parent") 1018 1019 sourceRule := []string{"-i", bridgeName, "-o", bridgeName, "-p", "tcp", "-s", childIP, "--sport", "80", "-d", parentIP, "-j", "ACCEPT"} 1020 destinationRule := []string{"-i", bridgeName, "-o", bridgeName, "-p", "tcp", "-s", parentIP, "--dport", "80", "-d", childIP, "-j", "ACCEPT"} 1021 if !iptables.Exists("filter", "DOCKER", sourceRule...) || !iptables.Exists("filter", "DOCKER", destinationRule...) { 1022 c.Fatal("Iptables rules not found") 1023 } 1024 1025 s.d.Cmd("rm", "--link", "parent/http") 1026 if iptables.Exists("filter", "DOCKER", sourceRule...) || iptables.Exists("filter", "DOCKER", destinationRule...) { 1027 c.Fatal("Iptables rules should be removed when unlink") 1028 } 1029 1030 s.d.Cmd("kill", "child") 1031 s.d.Cmd("kill", "parent") 1032 } 1033 1034 func (s *DockerDaemonSuite) TestDaemonUlimitDefaults(c *check.C) { 1035 testRequires(c, NativeExecDriver) 1036 1037 if err := s.d.StartWithBusybox("--default-ulimit", "nofile=42:42", "--default-ulimit", "nproc=1024:1024"); err != nil { 1038 c.Fatal(err) 1039 } 1040 1041 out, err := s.d.Cmd("run", "--ulimit", "nproc=2048", "--name=test", "busybox", "/bin/sh", "-c", "echo $(ulimit -n); echo $(ulimit -p)") 1042 if err != nil { 1043 c.Fatal(out, err) 1044 } 1045 1046 outArr := strings.Split(out, "\n") 1047 if len(outArr) < 2 { 1048 c.Fatalf("got unexpected output: %s", out) 1049 } 1050 nofile := strings.TrimSpace(outArr[0]) 1051 nproc := strings.TrimSpace(outArr[1]) 1052 1053 if nofile != "42" { 1054 c.Fatalf("expected `ulimit -n` to be `42`, got: %s", nofile) 1055 } 1056 if nproc != "2048" { 1057 c.Fatalf("exepcted `ulimit -p` to be 2048, got: %s", nproc) 1058 } 1059 1060 // Now restart daemon with a new default 1061 if err := s.d.Restart("--default-ulimit", "nofile=43"); err != nil { 1062 c.Fatal(err) 1063 } 1064 1065 out, err = s.d.Cmd("start", "-a", "test") 1066 if err != nil { 1067 c.Fatal(err) 1068 } 1069 1070 outArr = strings.Split(out, "\n") 1071 if len(outArr) < 2 { 1072 c.Fatalf("got unexpected output: %s", out) 1073 } 1074 nofile = strings.TrimSpace(outArr[0]) 1075 nproc = strings.TrimSpace(outArr[1]) 1076 1077 if nofile != "43" { 1078 c.Fatalf("expected `ulimit -n` to be `43`, got: %s", nofile) 1079 } 1080 if nproc != "2048" { 1081 c.Fatalf("exepcted `ulimit -p` to be 2048, got: %s", nproc) 1082 } 1083 } 1084 1085 // #11315 1086 func (s *DockerDaemonSuite) TestDaemonRestartRenameContainer(c *check.C) { 1087 if err := s.d.StartWithBusybox(); err != nil { 1088 c.Fatal(err) 1089 } 1090 1091 if out, err := s.d.Cmd("run", "--name=test", "busybox"); err != nil { 1092 c.Fatal(err, out) 1093 } 1094 1095 if out, err := s.d.Cmd("rename", "test", "test2"); err != nil { 1096 c.Fatal(err, out) 1097 } 1098 1099 if err := s.d.Restart(); err != nil { 1100 c.Fatal(err) 1101 } 1102 1103 if out, err := s.d.Cmd("start", "test2"); err != nil { 1104 c.Fatal(err, out) 1105 } 1106 } 1107 1108 func (s *DockerDaemonSuite) TestDaemonLoggingDriverDefault(c *check.C) { 1109 if err := s.d.StartWithBusybox(); err != nil { 1110 c.Fatal(err) 1111 } 1112 1113 out, err := s.d.Cmd("run", "-d", "busybox", "echo", "testline") 1114 if err != nil { 1115 c.Fatal(out, err) 1116 } 1117 id := strings.TrimSpace(out) 1118 1119 if out, err := s.d.Cmd("wait", id); err != nil { 1120 c.Fatal(out, err) 1121 } 1122 logPath := filepath.Join(s.d.root, "containers", id, id+"-json.log") 1123 1124 if _, err := os.Stat(logPath); err != nil { 1125 c.Fatal(err) 1126 } 1127 f, err := os.Open(logPath) 1128 if err != nil { 1129 c.Fatal(err) 1130 } 1131 var res struct { 1132 Log string `json:"log"` 1133 Stream string `json:"stream"` 1134 Time time.Time `json:"time"` 1135 } 1136 if err := json.NewDecoder(f).Decode(&res); err != nil { 1137 c.Fatal(err) 1138 } 1139 if res.Log != "testline\n" { 1140 c.Fatalf("Unexpected log line: %q, expected: %q", res.Log, "testline\n") 1141 } 1142 if res.Stream != "stdout" { 1143 c.Fatalf("Unexpected stream: %q, expected: %q", res.Stream, "stdout") 1144 } 1145 if !time.Now().After(res.Time) { 1146 c.Fatalf("Log time %v in future", res.Time) 1147 } 1148 } 1149 1150 func (s *DockerDaemonSuite) TestDaemonLoggingDriverDefaultOverride(c *check.C) { 1151 if err := s.d.StartWithBusybox(); err != nil { 1152 c.Fatal(err) 1153 } 1154 1155 out, err := s.d.Cmd("run", "-d", "--log-driver=none", "busybox", "echo", "testline") 1156 if err != nil { 1157 c.Fatal(out, err) 1158 } 1159 id := strings.TrimSpace(out) 1160 1161 if out, err := s.d.Cmd("wait", id); err != nil { 1162 c.Fatal(out, err) 1163 } 1164 logPath := filepath.Join(s.d.root, "containers", id, id+"-json.log") 1165 1166 if _, err := os.Stat(logPath); err == nil || !os.IsNotExist(err) { 1167 c.Fatalf("%s shouldn't exits, error on Stat: %s", logPath, err) 1168 } 1169 } 1170 1171 func (s *DockerDaemonSuite) TestDaemonLoggingDriverNone(c *check.C) { 1172 if err := s.d.StartWithBusybox("--log-driver=none"); err != nil { 1173 c.Fatal(err) 1174 } 1175 1176 out, err := s.d.Cmd("run", "-d", "busybox", "echo", "testline") 1177 if err != nil { 1178 c.Fatal(out, err) 1179 } 1180 id := strings.TrimSpace(out) 1181 if out, err := s.d.Cmd("wait", id); err != nil { 1182 c.Fatal(out, err) 1183 } 1184 1185 logPath := filepath.Join(s.d.folder, "graph", "containers", id, id+"-json.log") 1186 1187 if _, err := os.Stat(logPath); err == nil || !os.IsNotExist(err) { 1188 c.Fatalf("%s shouldn't exits, error on Stat: %s", logPath, err) 1189 } 1190 } 1191 1192 func (s *DockerDaemonSuite) TestDaemonLoggingDriverNoneOverride(c *check.C) { 1193 if err := s.d.StartWithBusybox("--log-driver=none"); err != nil { 1194 c.Fatal(err) 1195 } 1196 1197 out, err := s.d.Cmd("run", "-d", "--log-driver=json-file", "busybox", "echo", "testline") 1198 if err != nil { 1199 c.Fatal(out, err) 1200 } 1201 id := strings.TrimSpace(out) 1202 1203 if out, err := s.d.Cmd("wait", id); err != nil { 1204 c.Fatal(out, err) 1205 } 1206 logPath := filepath.Join(s.d.root, "containers", id, id+"-json.log") 1207 1208 if _, err := os.Stat(logPath); err != nil { 1209 c.Fatal(err) 1210 } 1211 f, err := os.Open(logPath) 1212 if err != nil { 1213 c.Fatal(err) 1214 } 1215 var res struct { 1216 Log string `json:"log"` 1217 Stream string `json:"stream"` 1218 Time time.Time `json:"time"` 1219 } 1220 if err := json.NewDecoder(f).Decode(&res); err != nil { 1221 c.Fatal(err) 1222 } 1223 if res.Log != "testline\n" { 1224 c.Fatalf("Unexpected log line: %q, expected: %q", res.Log, "testline\n") 1225 } 1226 if res.Stream != "stdout" { 1227 c.Fatalf("Unexpected stream: %q, expected: %q", res.Stream, "stdout") 1228 } 1229 if !time.Now().After(res.Time) { 1230 c.Fatalf("Log time %v in future", res.Time) 1231 } 1232 } 1233 1234 func (s *DockerDaemonSuite) TestDaemonLoggingDriverNoneLogsError(c *check.C) { 1235 if err := s.d.StartWithBusybox("--log-driver=none"); err != nil { 1236 c.Fatal(err) 1237 } 1238 1239 out, err := s.d.Cmd("run", "-d", "busybox", "echo", "testline") 1240 if err != nil { 1241 c.Fatal(out, err) 1242 } 1243 id := strings.TrimSpace(out) 1244 out, err = s.d.Cmd("logs", id) 1245 if err != nil { 1246 c.Fatalf("Logs request should be sent and then fail with \"none\" driver") 1247 } 1248 if !strings.Contains(out, `Error running logs job: Failed to get logging factory: logger: no log driver named 'none' is registered`) { 1249 c.Fatalf("There should be an error about none not being a recognized log driver, got: %s", out) 1250 } 1251 } 1252 1253 func (s *DockerDaemonSuite) TestDaemonDots(c *check.C) { 1254 if err := s.d.StartWithBusybox(); err != nil { 1255 c.Fatal(err) 1256 } 1257 1258 // Now create 4 containers 1259 if _, err := s.d.Cmd("create", "busybox"); err != nil { 1260 c.Fatalf("Error creating container: %q", err) 1261 } 1262 if _, err := s.d.Cmd("create", "busybox"); err != nil { 1263 c.Fatalf("Error creating container: %q", err) 1264 } 1265 if _, err := s.d.Cmd("create", "busybox"); err != nil { 1266 c.Fatalf("Error creating container: %q", err) 1267 } 1268 if _, err := s.d.Cmd("create", "busybox"); err != nil { 1269 c.Fatalf("Error creating container: %q", err) 1270 } 1271 1272 s.d.Stop() 1273 1274 s.d.Start("--log-level=debug") 1275 s.d.Stop() 1276 content, _ := ioutil.ReadFile(s.d.logFile.Name()) 1277 if strings.Contains(string(content), "....") { 1278 c.Fatalf("Debug level should not have ....\n%s", string(content)) 1279 } 1280 1281 s.d.Start("--log-level=error") 1282 s.d.Stop() 1283 content, _ = ioutil.ReadFile(s.d.logFile.Name()) 1284 if strings.Contains(string(content), "....") { 1285 c.Fatalf("Error level should not have ....\n%s", string(content)) 1286 } 1287 1288 s.d.Start("--log-level=info") 1289 s.d.Stop() 1290 content, _ = ioutil.ReadFile(s.d.logFile.Name()) 1291 if !strings.Contains(string(content), "....") { 1292 c.Fatalf("Info level should have ....\n%s", string(content)) 1293 } 1294 } 1295 1296 func (s *DockerDaemonSuite) TestDaemonUnixSockCleanedUp(c *check.C) { 1297 dir, err := ioutil.TempDir("", "socket-cleanup-test") 1298 if err != nil { 1299 c.Fatal(err) 1300 } 1301 defer os.RemoveAll(dir) 1302 1303 sockPath := filepath.Join(dir, "docker.sock") 1304 if err := s.d.Start("--host", "unix://"+sockPath); err != nil { 1305 c.Fatal(err) 1306 } 1307 1308 if _, err := os.Stat(sockPath); err != nil { 1309 c.Fatal("socket does not exist") 1310 } 1311 1312 if err := s.d.Stop(); err != nil { 1313 c.Fatal(err) 1314 } 1315 1316 if _, err := os.Stat(sockPath); err == nil || !os.IsNotExist(err) { 1317 c.Fatal("unix socket is not cleaned up") 1318 } 1319 } 1320 1321 func (s *DockerDaemonSuite) TestDaemonWithWrongkey(c *check.C) { 1322 type Config struct { 1323 Crv string `json:"crv"` 1324 D string `json:"d"` 1325 Kid string `json:"kid"` 1326 Kty string `json:"kty"` 1327 X string `json:"x"` 1328 Y string `json:"y"` 1329 } 1330 1331 os.Remove("/etc/docker/key.json") 1332 if err := s.d.Start(); err != nil { 1333 c.Fatalf("Failed to start daemon: %v", err) 1334 } 1335 1336 if err := s.d.Stop(); err != nil { 1337 c.Fatalf("Could not stop daemon: %v", err) 1338 } 1339 1340 config := &Config{} 1341 bytes, err := ioutil.ReadFile("/etc/docker/key.json") 1342 if err != nil { 1343 c.Fatalf("Error reading key.json file: %s", err) 1344 } 1345 1346 // byte[] to Data-Struct 1347 if err := json.Unmarshal(bytes, &config); err != nil { 1348 c.Fatalf("Error Unmarshal: %s", err) 1349 } 1350 1351 //replace config.Kid with the fake value 1352 config.Kid = "VSAJ:FUYR:X3H2:B2VZ:KZ6U:CJD5:K7BX:ZXHY:UZXT:P4FT:MJWG:HRJ4" 1353 1354 // NEW Data-Struct to byte[] 1355 newBytes, err := json.Marshal(&config) 1356 if err != nil { 1357 c.Fatalf("Error Marshal: %s", err) 1358 } 1359 1360 // write back 1361 if err := ioutil.WriteFile("/etc/docker/key.json", newBytes, 0400); err != nil { 1362 c.Fatalf("Error ioutil.WriteFile: %s", err) 1363 } 1364 1365 defer os.Remove("/etc/docker/key.json") 1366 1367 if err := s.d.Start(); err == nil { 1368 c.Fatalf("It should not be successful to start daemon with wrong key: %v", err) 1369 } 1370 1371 content, _ := ioutil.ReadFile(s.d.logFile.Name()) 1372 1373 if !strings.Contains(string(content), "Public Key ID does not match") { 1374 c.Fatal("Missing KeyID message from daemon logs") 1375 } 1376 } 1377 1378 func (s *DockerDaemonSuite) TestDaemonRestartKillWait(c *check.C) { 1379 if err := s.d.StartWithBusybox(); err != nil { 1380 c.Fatalf("Could not start daemon with busybox: %v", err) 1381 } 1382 1383 out, err := s.d.Cmd("run", "-id", "busybox", "/bin/cat") 1384 if err != nil { 1385 c.Fatalf("Could not run /bin/cat: err=%v\n%s", err, out) 1386 } 1387 containerID := strings.TrimSpace(out) 1388 1389 if out, err := s.d.Cmd("kill", containerID); err != nil { 1390 c.Fatalf("Could not kill %s: err=%v\n%s", containerID, err, out) 1391 } 1392 1393 if err := s.d.Restart(); err != nil { 1394 c.Fatalf("Could not restart daemon: %v", err) 1395 } 1396 1397 errchan := make(chan error) 1398 go func() { 1399 if out, err := s.d.Cmd("wait", containerID); err != nil { 1400 errchan <- fmt.Errorf("%v:\n%s", err, out) 1401 } 1402 close(errchan) 1403 }() 1404 1405 select { 1406 case <-time.After(5 * time.Second): 1407 c.Fatal("Waiting on a stopped (killed) container timed out") 1408 case err := <-errchan: 1409 if err != nil { 1410 c.Fatal(err) 1411 } 1412 } 1413 } 1414 1415 // TestHttpsInfo connects via two-way authenticated HTTPS to the info endpoint 1416 func (s *DockerDaemonSuite) TestHttpsInfo(c *check.C) { 1417 const ( 1418 testDaemonHTTPSAddr = "tcp://localhost:4271" 1419 ) 1420 1421 if err := s.d.Start("--tlsverify", "--tlscacert", "fixtures/https/ca.pem", "--tlscert", "fixtures/https/server-cert.pem", 1422 "--tlskey", "fixtures/https/server-key.pem", "-H", testDaemonHTTPSAddr); err != nil { 1423 c.Fatalf("Could not start daemon with busybox: %v", err) 1424 } 1425 1426 daemonArgs := []string{"--host", testDaemonHTTPSAddr, "--tlsverify", "--tlscacert", "fixtures/https/ca.pem", "--tlscert", "fixtures/https/client-cert.pem", "--tlskey", "fixtures/https/client-key.pem"} 1427 out, err := s.d.CmdWithArgs(daemonArgs, "info") 1428 if err != nil { 1429 c.Fatalf("Error Occurred: %s and output: %s", err, out) 1430 } 1431 } 1432 1433 // TestTlsVerify verifies that --tlsverify=false turns on tls 1434 func (s *DockerDaemonSuite) TestTlsVerify(c *check.C) { 1435 out, err := exec.Command(dockerBinary, "daemon", "--tlsverify=false").CombinedOutput() 1436 if err == nil || !strings.Contains(string(out), "Could not load X509 key pair") { 1437 c.Fatalf("Daemon should not have started due to missing certs: %v\n%s", err, string(out)) 1438 } 1439 } 1440 1441 // TestHttpsInfoRogueCert connects via two-way authenticated HTTPS to the info endpoint 1442 // by using a rogue client certificate and checks that it fails with the expected error. 1443 func (s *DockerDaemonSuite) TestHttpsInfoRogueCert(c *check.C) { 1444 const ( 1445 errBadCertificate = "remote error: bad certificate" 1446 testDaemonHTTPSAddr = "tcp://localhost:4271" 1447 ) 1448 1449 if err := s.d.Start("--tlsverify", "--tlscacert", "fixtures/https/ca.pem", "--tlscert", "fixtures/https/server-cert.pem", 1450 "--tlskey", "fixtures/https/server-key.pem", "-H", testDaemonHTTPSAddr); err != nil { 1451 c.Fatalf("Could not start daemon with busybox: %v", err) 1452 } 1453 1454 daemonArgs := []string{"--host", testDaemonHTTPSAddr, "--tlsverify", "--tlscacert", "fixtures/https/ca.pem", "--tlscert", "fixtures/https/client-rogue-cert.pem", "--tlskey", "fixtures/https/client-rogue-key.pem"} 1455 out, err := s.d.CmdWithArgs(daemonArgs, "info") 1456 if err == nil || !strings.Contains(out, errBadCertificate) { 1457 c.Fatalf("Expected err: %s, got instead: %s and output: %s", errBadCertificate, err, out) 1458 } 1459 } 1460 1461 // TestHttpsInfoRogueServerCert connects via two-way authenticated HTTPS to the info endpoint 1462 // which provides a rogue server certificate and checks that it fails with the expected error 1463 func (s *DockerDaemonSuite) TestHttpsInfoRogueServerCert(c *check.C) { 1464 const ( 1465 errCaUnknown = "x509: certificate signed by unknown authority" 1466 testDaemonRogueHTTPSAddr = "tcp://localhost:4272" 1467 ) 1468 if err := s.d.Start("--tlsverify", "--tlscacert", "fixtures/https/ca.pem", "--tlscert", "fixtures/https/server-rogue-cert.pem", 1469 "--tlskey", "fixtures/https/server-rogue-key.pem", "-H", testDaemonRogueHTTPSAddr); err != nil { 1470 c.Fatalf("Could not start daemon with busybox: %v", err) 1471 } 1472 1473 daemonArgs := []string{"--host", testDaemonRogueHTTPSAddr, "--tlsverify", "--tlscacert", "fixtures/https/ca.pem", "--tlscert", "fixtures/https/client-rogue-cert.pem", "--tlskey", "fixtures/https/client-rogue-key.pem"} 1474 out, err := s.d.CmdWithArgs(daemonArgs, "info") 1475 if err == nil || !strings.Contains(out, errCaUnknown) { 1476 c.Fatalf("Expected err: %s, got instead: %s and output: %s", errCaUnknown, err, out) 1477 } 1478 } 1479 1480 func pingContainers(c *check.C, d *Daemon, expectFailure bool) { 1481 var dargs []string 1482 if d != nil { 1483 dargs = []string{"--host", d.sock()} 1484 } 1485 1486 args := append(dargs, "run", "-d", "--name", "container1", "busybox", "top") 1487 dockerCmd(c, args...) 1488 1489 args = append(dargs, "run", "--rm", "--link", "container1:alias1", "busybox", "sh", "-c") 1490 pingCmd := "ping -c 1 %s -W 1" 1491 args = append(args, fmt.Sprintf(pingCmd, "alias1")) 1492 _, _, err := dockerCmdWithError(args...) 1493 1494 if expectFailure { 1495 c.Assert(err, check.NotNil) 1496 } else { 1497 c.Assert(err, check.IsNil) 1498 } 1499 1500 args = append(dargs, "rm", "-f", "container1") 1501 dockerCmd(c, args...) 1502 } 1503 1504 func (s *DockerDaemonSuite) TestDaemonRestartWithSocketAsVolume(c *check.C) { 1505 c.Assert(s.d.StartWithBusybox(), check.IsNil) 1506 1507 socket := filepath.Join(s.d.folder, "docker.sock") 1508 1509 out, err := s.d.Cmd("run", "-d", "--restart=always", "-v", socket+":/sock", "busybox") 1510 c.Assert(err, check.IsNil, check.Commentf("Output: %s", out)) 1511 c.Assert(s.d.Restart(), check.IsNil) 1512 } 1513 1514 func (s *DockerDaemonSuite) TestCleanupMountsAfterCrash(c *check.C) { 1515 c.Assert(s.d.StartWithBusybox(), check.IsNil) 1516 1517 out, err := s.d.Cmd("run", "-d", "busybox", "top") 1518 c.Assert(err, check.IsNil, check.Commentf("Output: %s", out)) 1519 id := strings.TrimSpace(out) 1520 c.Assert(s.d.cmd.Process.Signal(os.Kill), check.IsNil) 1521 c.Assert(s.d.Start(), check.IsNil) 1522 mountOut, err := ioutil.ReadFile("/proc/self/mountinfo") 1523 c.Assert(err, check.IsNil, check.Commentf("Output: %s", mountOut)) 1524 1525 comment := check.Commentf("%s is still mounted from older daemon start:\nDaemon root repository %s\n%s", id, s.d.folder, mountOut) 1526 c.Assert(strings.Contains(string(mountOut), id), check.Equals, false, comment) 1527 } 1528 1529 func (s *DockerDaemonSuite) TestRunContainerWithBridgeNone(c *check.C) { 1530 testRequires(c, NativeExecDriver, NotUserNamespace) 1531 c.Assert(s.d.StartWithBusybox("-b", "none"), check.IsNil) 1532 1533 out, err := s.d.Cmd("run", "--rm", "busybox", "ip", "l") 1534 c.Assert(err, check.IsNil, check.Commentf("Output: %s", out)) 1535 c.Assert(strings.Contains(out, "eth0"), check.Equals, false, 1536 check.Commentf("There shouldn't be eth0 in container in default(bridge) mode when bridge network is disabled: %s", out)) 1537 1538 out, err = s.d.Cmd("run", "--rm", "--net=bridge", "busybox", "ip", "l") 1539 c.Assert(err, check.IsNil, check.Commentf("Output: %s", out)) 1540 c.Assert(strings.Contains(out, "eth0"), check.Equals, false, 1541 check.Commentf("There shouldn't be eth0 in container in bridge mode when bridge network is disabled: %s", out)) 1542 cmd := exec.Command("ip", "l") 1543 stdout := bytes.NewBuffer(nil) 1544 cmd.Stdout = stdout 1545 if err := cmd.Run(); err != nil { 1546 c.Fatal("Failed to get host network interface") 1547 } 1548 out, err = s.d.Cmd("run", "--rm", "--net=host", "busybox", "ip", "l") 1549 c.Assert(err, check.IsNil, check.Commentf("Output: %s", out)) 1550 c.Assert(out, check.Equals, fmt.Sprintf("%s", stdout), 1551 check.Commentf("The network interfaces in container should be the same with host when --net=host when bridge network is disabled: %s", out)) 1552 } 1553 1554 func (s *DockerDaemonSuite) TestDaemonRestartWithContainerRunning(t *check.C) { 1555 if err := s.d.StartWithBusybox(); err != nil { 1556 t.Fatal(err) 1557 } 1558 if out, err := s.d.Cmd("run", "-ti", "-d", "--name", "test", "busybox"); err != nil { 1559 t.Fatal(out, err) 1560 } 1561 1562 if err := s.d.Restart(); err != nil { 1563 t.Fatal(err) 1564 } 1565 // Container 'test' should be removed without error 1566 if out, err := s.d.Cmd("rm", "test"); err != nil { 1567 t.Fatal(out, err) 1568 } 1569 } 1570 1571 func (s *DockerDaemonSuite) TestDaemonRestartCleanupNetns(c *check.C) { 1572 if err := s.d.StartWithBusybox(); err != nil { 1573 c.Fatal(err) 1574 } 1575 out, err := s.d.Cmd("run", "--name", "netns", "-d", "busybox", "top") 1576 if err != nil { 1577 c.Fatal(out, err) 1578 } 1579 1580 // Get sandbox key via inspect 1581 out, err = s.d.Cmd("inspect", "--format", "'{{.NetworkSettings.SandboxKey}}'", "netns") 1582 if err != nil { 1583 c.Fatalf("Error inspecting container: %s, %v", out, err) 1584 } 1585 fileName := strings.Trim(out, " \r\n'") 1586 1587 if out, err := s.d.Cmd("stop", "netns"); err != nil { 1588 c.Fatal(out, err) 1589 } 1590 1591 // Test if the file still exists 1592 out, _, err = runCommandWithOutput(exec.Command("stat", "-c", "%n", fileName)) 1593 out = strings.TrimSpace(out) 1594 c.Assert(err, check.IsNil, check.Commentf("Output: %s", out)) 1595 c.Assert(out, check.Equals, fileName, check.Commentf("Output: %s", out)) 1596 1597 // Remove the container and restart the daemon 1598 if out, err := s.d.Cmd("rm", "netns"); err != nil { 1599 c.Fatal(out, err) 1600 } 1601 1602 if err := s.d.Restart(); err != nil { 1603 c.Fatal(err) 1604 } 1605 1606 // Test again and see now the netns file does not exist 1607 out, _, err = runCommandWithOutput(exec.Command("stat", "-c", "%n", fileName)) 1608 out = strings.TrimSpace(out) 1609 c.Assert(err, check.Not(check.IsNil), check.Commentf("Output: %s", out)) 1610 } 1611 1612 // tests regression detailed in #13964 where DOCKER_TLS_VERIFY env is ignored 1613 func (s *DockerDaemonSuite) TestDaemonNoTlsCliTlsVerifyWithEnv(c *check.C) { 1614 host := "tcp://localhost:4271" 1615 c.Assert(s.d.Start("-H", host), check.IsNil) 1616 cmd := exec.Command(dockerBinary, "-H", host, "info") 1617 cmd.Env = []string{"DOCKER_TLS_VERIFY=1", "DOCKER_CERT_PATH=fixtures/https"} 1618 out, _, err := runCommandWithOutput(cmd) 1619 c.Assert(err, check.Not(check.IsNil), check.Commentf("%s", out)) 1620 c.Assert(strings.Contains(out, "error occurred trying to connect"), check.Equals, true) 1621 1622 } 1623 1624 func setupV6() error { 1625 // Hack to get the right IPv6 address on docker0, which has already been created 1626 err := exec.Command("ip", "addr", "add", "fe80::1/64", "dev", "docker0").Run() 1627 if err != nil { 1628 return err 1629 } 1630 return nil 1631 } 1632 1633 func teardownV6() error { 1634 err := exec.Command("ip", "addr", "del", "fe80::1/64", "dev", "docker0").Run() 1635 if err != nil { 1636 return err 1637 } 1638 return nil 1639 } 1640 1641 func (s *DockerDaemonSuite) TestDaemonRestartWithContainerWithRestartPolicyAlways(c *check.C) { 1642 c.Assert(s.d.StartWithBusybox(), check.IsNil) 1643 1644 out, err := s.d.Cmd("run", "-d", "--restart", "always", "busybox", "top") 1645 c.Assert(err, check.IsNil) 1646 id := strings.TrimSpace(out) 1647 1648 _, err = s.d.Cmd("stop", id) 1649 c.Assert(err, check.IsNil) 1650 _, err = s.d.Cmd("wait", id) 1651 c.Assert(err, check.IsNil) 1652 1653 out, err = s.d.Cmd("ps", "-q") 1654 c.Assert(err, check.IsNil) 1655 c.Assert(out, check.Equals, "") 1656 1657 c.Assert(s.d.Restart(), check.IsNil) 1658 1659 out, err = s.d.Cmd("ps", "-q") 1660 c.Assert(err, check.IsNil) 1661 c.Assert(strings.TrimSpace(out), check.Equals, id[:12]) 1662 } 1663 1664 func (s *DockerDaemonSuite) TestDaemonWideLogConfig(c *check.C) { 1665 if err := s.d.StartWithBusybox("--log-driver=json-file", "--log-opt=max-size=1k"); err != nil { 1666 c.Fatal(err) 1667 } 1668 out, err := s.d.Cmd("run", "-d", "--name=logtest", "busybox", "top") 1669 c.Assert(err, check.IsNil, check.Commentf("Output: %s, err: %v", out, err)) 1670 out, err = s.d.Cmd("inspect", "-f", "{{ .HostConfig.LogConfig.Config }}", "logtest") 1671 c.Assert(err, check.IsNil, check.Commentf("Output: %s", out)) 1672 cfg := strings.TrimSpace(out) 1673 if cfg != "map[max-size:1k]" { 1674 c.Fatalf("Unexpected log-opt: %s, expected map[max-size:1k]", cfg) 1675 } 1676 } 1677 1678 func (s *DockerDaemonSuite) TestDaemonRestartWithPausedContainer(c *check.C) { 1679 if err := s.d.StartWithBusybox(); err != nil { 1680 c.Fatal(err) 1681 } 1682 if out, err := s.d.Cmd("run", "-i", "-d", "--name", "test", "busybox", "top"); err != nil { 1683 c.Fatal(err, out) 1684 } 1685 if out, err := s.d.Cmd("pause", "test"); err != nil { 1686 c.Fatal(err, out) 1687 } 1688 if err := s.d.Restart(); err != nil { 1689 c.Fatal(err) 1690 } 1691 1692 errchan := make(chan error) 1693 go func() { 1694 out, err := s.d.Cmd("start", "test") 1695 if err != nil { 1696 errchan <- fmt.Errorf("%v:\n%s", err, out) 1697 } 1698 name := strings.TrimSpace(out) 1699 if name != "test" { 1700 errchan <- fmt.Errorf("Paused container start error on docker daemon restart, expected 'test' but got '%s'", name) 1701 } 1702 close(errchan) 1703 }() 1704 1705 select { 1706 case <-time.After(5 * time.Second): 1707 c.Fatal("Waiting on start a container timed out") 1708 case err := <-errchan: 1709 if err != nil { 1710 c.Fatal(err) 1711 } 1712 } 1713 } 1714 1715 func (s *DockerDaemonSuite) TestDaemonRestartRmVolumeInUse(c *check.C) { 1716 c.Assert(s.d.StartWithBusybox(), check.IsNil) 1717 1718 out, err := s.d.Cmd("create", "-v", "test:/foo", "busybox") 1719 c.Assert(err, check.IsNil, check.Commentf(out)) 1720 1721 c.Assert(s.d.Restart(), check.IsNil) 1722 1723 out, err = s.d.Cmd("volume", "rm", "test") 1724 c.Assert(err, check.Not(check.IsNil), check.Commentf("should not be able to remove in use volume after daemon restart")) 1725 c.Assert(strings.Contains(out, "in use"), check.Equals, true) 1726 } 1727 1728 func (s *DockerDaemonSuite) TestDaemonRestartLocalVolumes(c *check.C) { 1729 c.Assert(s.d.Start(), check.IsNil) 1730 1731 _, err := s.d.Cmd("volume", "create", "--name", "test") 1732 c.Assert(err, check.IsNil) 1733 c.Assert(s.d.Restart(), check.IsNil) 1734 1735 _, err = s.d.Cmd("volume", "inspect", "test") 1736 c.Assert(err, check.IsNil) 1737 } 1738 1739 func (s *DockerDaemonSuite) TestDaemonCorruptedLogDriverAddress(c *check.C) { 1740 for _, driver := range []string{ 1741 "syslog", 1742 "gelf", 1743 } { 1744 args := []string{"--log-driver=" + driver, "--log-opt", driver + "-address=corrupted:42"} 1745 c.Assert(s.d.Start(args...), check.NotNil, check.Commentf(fmt.Sprintf("Expected daemon not to start with invalid %s-address provided", driver))) 1746 expected := fmt.Sprintf("Failed to set log opts: %s-address should be in form proto://address", driver) 1747 runCmd := exec.Command("grep", expected, s.d.LogfileName()) 1748 if out, _, err := runCommandWithOutput(runCmd); err != nil { 1749 c.Fatalf("Expected %q message; but doesn't exist in log: %q, err: %v", expected, out, err) 1750 } 1751 } 1752 } 1753 1754 func (s *DockerDaemonSuite) TestDaemonCorruptedFluentdAddress(c *check.C) { 1755 c.Assert(s.d.Start("--log-driver=fluentd", "--log-opt", "fluentd-address=corrupted:c"), check.NotNil) 1756 expected := "Failed to set log opts: invalid fluentd-address corrupted:c: " 1757 runCmd := exec.Command("grep", expected, s.d.LogfileName()) 1758 if out, _, err := runCommandWithOutput(runCmd); err != nil { 1759 c.Fatalf("Expected %q message; but doesn't exist in log: %q, err: %v", expected, out, err) 1760 } 1761 } 1762 1763 func (s *DockerDaemonSuite) TestDaemonStartWithoutHost(c *check.C) { 1764 s.d.useDefaultHost = true 1765 defer func() { 1766 s.d.useDefaultHost = false 1767 }() 1768 c.Assert(s.d.Start(), check.IsNil) 1769 } 1770 1771 func (s *DockerDaemonSuite) TestDaemonStartWithDefalutTlsHost(c *check.C) { 1772 s.d.useDefaultTLSHost = true 1773 defer func() { 1774 s.d.useDefaultTLSHost = false 1775 }() 1776 if err := s.d.Start( 1777 "--tlsverify", 1778 "--tlscacert", "fixtures/https/ca.pem", 1779 "--tlscert", "fixtures/https/server-cert.pem", 1780 "--tlskey", "fixtures/https/server-key.pem"); err != nil { 1781 c.Fatalf("Could not start daemon: %v", err) 1782 } 1783 1784 // The client with --tlsverify should also use default host localhost:2376 1785 tmpHost := os.Getenv("DOCKER_HOST") 1786 defer func() { 1787 os.Setenv("DOCKER_HOST", tmpHost) 1788 }() 1789 1790 os.Setenv("DOCKER_HOST", "") 1791 1792 out, _ := dockerCmd( 1793 c, 1794 "--tlsverify", 1795 "--tlscacert", "fixtures/https/ca.pem", 1796 "--tlscert", "fixtures/https/client-cert.pem", 1797 "--tlskey", "fixtures/https/client-key.pem", 1798 "version", 1799 ) 1800 if !strings.Contains(out, "Server") { 1801 c.Fatalf("docker version should return information of server side") 1802 } 1803 }