github.com/walkingsparrow/docker@v1.4.2-0.20151218153551-b708a2249bfa/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 // TestDaemonIPv6FixedCIDRAndMac checks that when the daemon is started with ipv6 fixed CIDR 381 // the running containers are given a an IPv6 address derived from the MAC address and the ipv6 fixed CIDR 382 func (s *DockerSuite) TestDaemonIPv6FixedCIDRAndMac(c *check.C) { 383 err := setupV6() 384 c.Assert(err, checker.IsNil) 385 386 d := NewDaemon(c) 387 388 err = d.StartWithBusybox("--ipv6", "--fixed-cidr-v6='2001:db8:1::/64'") 389 c.Assert(err, checker.IsNil) 390 defer d.Stop() 391 392 out, err := d.Cmd("run", "-itd", "--name=ipv6test", "--mac-address", "AA:BB:CC:DD:EE:FF", "busybox") 393 c.Assert(err, checker.IsNil) 394 395 out, err = d.Cmd("inspect", "--format", "'{{.NetworkSettings.Networks.bridge.GlobalIPv6Address}}'", "ipv6test") 396 c.Assert(err, checker.IsNil) 397 c.Assert(strings.Trim(out, " \r\n'"), checker.Equals, "2001:db8:1::aabb:ccdd:eeff") 398 399 err = teardownV6() 400 c.Assert(err, checker.IsNil) 401 } 402 403 func (s *DockerDaemonSuite) TestDaemonLogLevelWrong(c *check.C) { 404 c.Assert(s.d.Start("--log-level=bogus"), check.NotNil, check.Commentf("Daemon shouldn't start with wrong log level")) 405 } 406 407 func (s *DockerSuite) TestDaemonStartWithDaemonCommand(c *check.C) { 408 409 type kind int 410 411 const ( 412 common kind = iota 413 daemon 414 ) 415 416 var flags = []map[kind][]string{ 417 {common: {"-l", "info"}, daemon: {"--selinux-enabled"}}, 418 {common: {"-D"}, daemon: {"--selinux-enabled", "-r"}}, 419 {common: {"-D"}, daemon: {"--restart"}}, 420 {common: {"--debug"}, daemon: {"--log-driver=json-file", "--log-opt=max-size=1k"}}, 421 } 422 423 var invalidGlobalFlags = [][]string{ 424 //Invalid because you cannot pass daemon flags as global flags. 425 {"--selinux-enabled", "-l", "info"}, 426 {"-D", "-r"}, 427 {"--config", "/tmp"}, 428 } 429 430 // `docker daemon -l info --selinux-enabled` 431 // should NOT error out 432 for _, f := range flags { 433 d := NewDaemon(c) 434 args := append(f[common], f[daemon]...) 435 if err := d.Start(args...); err != nil { 436 c.Fatalf("Daemon should have started successfully with %v: %v", args, err) 437 } 438 d.Stop() 439 } 440 441 // `docker -l info daemon --selinux-enabled` 442 // should error out 443 for _, f := range flags { 444 d := NewDaemon(c) 445 d.GlobalFlags = f[common] 446 if err := d.Start(f[daemon]...); err == nil { 447 d.Stop() 448 c.Fatalf("Daemon should have failed to start with docker %v daemon %v", d.GlobalFlags, f[daemon]) 449 } 450 } 451 452 for _, f := range invalidGlobalFlags { 453 cmd := exec.Command(dockerBinary, append(f, "daemon")...) 454 errch := make(chan error) 455 var err error 456 go func() { 457 errch <- cmd.Run() 458 }() 459 select { 460 case <-time.After(time.Second): 461 cmd.Process.Kill() 462 case err = <-errch: 463 } 464 if err == nil { 465 c.Fatalf("Daemon should have failed to start with docker %v daemon", f) 466 } 467 } 468 } 469 470 func (s *DockerDaemonSuite) TestDaemonLogLevelDebug(c *check.C) { 471 if err := s.d.Start("--log-level=debug"); err != nil { 472 c.Fatal(err) 473 } 474 content, _ := ioutil.ReadFile(s.d.logFile.Name()) 475 if !strings.Contains(string(content), `level=debug`) { 476 c.Fatalf(`Missing level="debug" in log file:\n%s`, string(content)) 477 } 478 } 479 480 func (s *DockerDaemonSuite) TestDaemonLogLevelFatal(c *check.C) { 481 // we creating new daemons to create new logFile 482 if err := s.d.Start("--log-level=fatal"); err != nil { 483 c.Fatal(err) 484 } 485 content, _ := ioutil.ReadFile(s.d.logFile.Name()) 486 if strings.Contains(string(content), `level=debug`) { 487 c.Fatalf(`Should not have level="debug" in log file:\n%s`, string(content)) 488 } 489 } 490 491 func (s *DockerDaemonSuite) TestDaemonFlagD(c *check.C) { 492 if err := s.d.Start("-D"); err != nil { 493 c.Fatal(err) 494 } 495 content, _ := ioutil.ReadFile(s.d.logFile.Name()) 496 if !strings.Contains(string(content), `level=debug`) { 497 c.Fatalf(`Should have level="debug" in log file using -D:\n%s`, string(content)) 498 } 499 } 500 501 func (s *DockerDaemonSuite) TestDaemonFlagDebug(c *check.C) { 502 if err := s.d.Start("--debug"); err != nil { 503 c.Fatal(err) 504 } 505 content, _ := ioutil.ReadFile(s.d.logFile.Name()) 506 if !strings.Contains(string(content), `level=debug`) { 507 c.Fatalf(`Should have level="debug" in log file using --debug:\n%s`, string(content)) 508 } 509 } 510 511 func (s *DockerDaemonSuite) TestDaemonFlagDebugLogLevelFatal(c *check.C) { 512 if err := s.d.Start("--debug", "--log-level=fatal"); err != nil { 513 c.Fatal(err) 514 } 515 content, _ := ioutil.ReadFile(s.d.logFile.Name()) 516 if !strings.Contains(string(content), `level=debug`) { 517 c.Fatalf(`Should have level="debug" in log file when using both --debug and --log-level=fatal:\n%s`, string(content)) 518 } 519 } 520 521 func (s *DockerDaemonSuite) TestDaemonAllocatesListeningPort(c *check.C) { 522 listeningPorts := [][]string{ 523 {"0.0.0.0", "0.0.0.0", "5678"}, 524 {"127.0.0.1", "127.0.0.1", "1234"}, 525 {"localhost", "127.0.0.1", "1235"}, 526 } 527 528 cmdArgs := make([]string, 0, len(listeningPorts)*2) 529 for _, hostDirective := range listeningPorts { 530 cmdArgs = append(cmdArgs, "--host", fmt.Sprintf("tcp://%s:%s", hostDirective[0], hostDirective[2])) 531 } 532 533 if err := s.d.StartWithBusybox(cmdArgs...); err != nil { 534 c.Fatalf("Could not start daemon with busybox: %v", err) 535 } 536 537 for _, hostDirective := range listeningPorts { 538 output, err := s.d.Cmd("run", "-p", fmt.Sprintf("%s:%s:80", hostDirective[1], hostDirective[2]), "busybox", "true") 539 if err == nil { 540 c.Fatalf("Container should not start, expected port already allocated error: %q", output) 541 } else if !strings.Contains(output, "port is already allocated") { 542 c.Fatalf("Expected port is already allocated error: %q", output) 543 } 544 } 545 } 546 547 func (s *DockerDaemonSuite) TestDaemonKeyGeneration(c *check.C) { 548 // TODO: skip or update for Windows daemon 549 os.Remove("/etc/docker/key.json") 550 if err := s.d.Start(); err != nil { 551 c.Fatalf("Could not start daemon: %v", err) 552 } 553 s.d.Stop() 554 555 k, err := libtrust.LoadKeyFile("/etc/docker/key.json") 556 if err != nil { 557 c.Fatalf("Error opening key file") 558 } 559 kid := k.KeyID() 560 // Test Key ID is a valid fingerprint (e.g. QQXN:JY5W:TBXI:MK3X:GX6P:PD5D:F56N:NHCS:LVRZ:JA46:R24J:XEFF) 561 if len(kid) != 59 { 562 c.Fatalf("Bad key ID: %s", kid) 563 } 564 } 565 566 func (s *DockerDaemonSuite) TestDaemonKeyMigration(c *check.C) { 567 // TODO: skip or update for Windows daemon 568 os.Remove("/etc/docker/key.json") 569 k1, err := libtrust.GenerateECP256PrivateKey() 570 if err != nil { 571 c.Fatalf("Error generating private key: %s", err) 572 } 573 if err := os.MkdirAll(filepath.Join(os.Getenv("HOME"), ".docker"), 0755); err != nil { 574 c.Fatalf("Error creating .docker directory: %s", err) 575 } 576 if err := libtrust.SaveKey(filepath.Join(os.Getenv("HOME"), ".docker", "key.json"), k1); err != nil { 577 c.Fatalf("Error saving private key: %s", err) 578 } 579 580 if err := s.d.Start(); err != nil { 581 c.Fatalf("Could not start daemon: %v", err) 582 } 583 s.d.Stop() 584 585 k2, err := libtrust.LoadKeyFile("/etc/docker/key.json") 586 if err != nil { 587 c.Fatalf("Error opening key file") 588 } 589 if k1.KeyID() != k2.KeyID() { 590 c.Fatalf("Key not migrated") 591 } 592 } 593 594 // GH#11320 - verify that the daemon exits on failure properly 595 // Note that this explicitly tests the conflict of {-b,--bridge} and {--bip} options as the means 596 // to get a daemon init failure; no other tests for -b/--bip conflict are therefore required 597 func (s *DockerDaemonSuite) TestDaemonExitOnFailure(c *check.C) { 598 //attempt to start daemon with incorrect flags (we know -b and --bip conflict) 599 if err := s.d.Start("--bridge", "nosuchbridge", "--bip", "1.1.1.1"); err != nil { 600 //verify we got the right error 601 if !strings.Contains(err.Error(), "Daemon exited and never started") { 602 c.Fatalf("Expected daemon not to start, got %v", err) 603 } 604 // look in the log and make sure we got the message that daemon is shutting down 605 runCmd := exec.Command("grep", "Error starting daemon", s.d.LogfileName()) 606 if out, _, err := runCommandWithOutput(runCmd); err != nil { 607 c.Fatalf("Expected 'Error starting daemon' message; but doesn't exist in log: %q, err: %v", out, err) 608 } 609 } else { 610 //if we didn't get an error and the daemon is running, this is a failure 611 c.Fatal("Conflicting options should cause the daemon to error out with a failure") 612 } 613 } 614 615 func (s *DockerDaemonSuite) TestDaemonBridgeExternal(c *check.C) { 616 d := s.d 617 err := d.Start("--bridge", "nosuchbridge") 618 c.Assert(err, check.NotNil, check.Commentf("--bridge option with an invalid bridge should cause the daemon to fail")) 619 defer d.Restart() 620 621 bridgeName := "external-bridge" 622 bridgeIP := "192.169.1.1/24" 623 _, bridgeIPNet, _ := net.ParseCIDR(bridgeIP) 624 625 out, err := createInterface(c, "bridge", bridgeName, bridgeIP) 626 c.Assert(err, check.IsNil, check.Commentf(out)) 627 defer deleteInterface(c, bridgeName) 628 629 err = d.StartWithBusybox("--bridge", bridgeName) 630 c.Assert(err, check.IsNil) 631 632 ipTablesSearchString := bridgeIPNet.String() 633 ipTablesCmd := exec.Command("iptables", "-t", "nat", "-nvL") 634 out, _, err = runCommandWithOutput(ipTablesCmd) 635 c.Assert(err, check.IsNil) 636 637 c.Assert(strings.Contains(out, ipTablesSearchString), check.Equals, true, 638 check.Commentf("iptables output should have contained %q, but was %q", 639 ipTablesSearchString, out)) 640 641 _, err = d.Cmd("run", "-d", "--name", "ExtContainer", "busybox", "top") 642 c.Assert(err, check.IsNil) 643 644 containerIP := d.findContainerIP("ExtContainer") 645 ip := net.ParseIP(containerIP) 646 c.Assert(bridgeIPNet.Contains(ip), check.Equals, true, 647 check.Commentf("Container IP-Address must be in the same subnet range : %s", 648 containerIP)) 649 } 650 651 func createInterface(c *check.C, ifType string, ifName string, ipNet string) (string, error) { 652 args := []string{"link", "add", "name", ifName, "type", ifType} 653 ipLinkCmd := exec.Command("ip", args...) 654 out, _, err := runCommandWithOutput(ipLinkCmd) 655 if err != nil { 656 return out, err 657 } 658 659 ifCfgCmd := exec.Command("ifconfig", ifName, ipNet, "up") 660 out, _, err = runCommandWithOutput(ifCfgCmd) 661 return out, err 662 } 663 664 func deleteInterface(c *check.C, ifName string) { 665 ifCmd := exec.Command("ip", "link", "delete", ifName) 666 out, _, err := runCommandWithOutput(ifCmd) 667 c.Assert(err, check.IsNil, check.Commentf(out)) 668 669 flushCmd := exec.Command("iptables", "-t", "nat", "--flush") 670 out, _, err = runCommandWithOutput(flushCmd) 671 c.Assert(err, check.IsNil, check.Commentf(out)) 672 673 flushCmd = exec.Command("iptables", "--flush") 674 out, _, err = runCommandWithOutput(flushCmd) 675 c.Assert(err, check.IsNil, check.Commentf(out)) 676 } 677 678 func (s *DockerDaemonSuite) TestDaemonBridgeIP(c *check.C) { 679 // TestDaemonBridgeIP Steps 680 // 1. Delete the existing docker0 Bridge 681 // 2. Set --bip daemon configuration and start the new Docker Daemon 682 // 3. Check if the bip config has taken effect using ifconfig and iptables commands 683 // 4. Launch a Container and make sure the IP-Address is in the expected subnet 684 // 5. Delete the docker0 Bridge 685 // 6. Restart the Docker Daemon (via deferred action) 686 // This Restart takes care of bringing docker0 interface back to auto-assigned IP 687 688 defaultNetworkBridge := "docker0" 689 deleteInterface(c, defaultNetworkBridge) 690 691 d := s.d 692 693 bridgeIP := "192.169.1.1/24" 694 ip, bridgeIPNet, _ := net.ParseCIDR(bridgeIP) 695 696 err := d.StartWithBusybox("--bip", bridgeIP) 697 c.Assert(err, check.IsNil) 698 defer d.Restart() 699 700 ifconfigSearchString := ip.String() 701 ifconfigCmd := exec.Command("ifconfig", defaultNetworkBridge) 702 out, _, _, err := runCommandWithStdoutStderr(ifconfigCmd) 703 c.Assert(err, check.IsNil) 704 705 c.Assert(strings.Contains(out, ifconfigSearchString), check.Equals, true, 706 check.Commentf("ifconfig output should have contained %q, but was %q", 707 ifconfigSearchString, out)) 708 709 ipTablesSearchString := bridgeIPNet.String() 710 ipTablesCmd := exec.Command("iptables", "-t", "nat", "-nvL") 711 out, _, err = runCommandWithOutput(ipTablesCmd) 712 c.Assert(err, check.IsNil) 713 714 c.Assert(strings.Contains(out, ipTablesSearchString), check.Equals, true, 715 check.Commentf("iptables output should have contained %q, but was %q", 716 ipTablesSearchString, out)) 717 718 out, err = d.Cmd("run", "-d", "--name", "test", "busybox", "top") 719 c.Assert(err, check.IsNil) 720 721 containerIP := d.findContainerIP("test") 722 ip = net.ParseIP(containerIP) 723 c.Assert(bridgeIPNet.Contains(ip), check.Equals, true, 724 check.Commentf("Container IP-Address must be in the same subnet range : %s", 725 containerIP)) 726 deleteInterface(c, defaultNetworkBridge) 727 } 728 729 func (s *DockerDaemonSuite) TestDaemonRestartWithBridgeIPChange(c *check.C) { 730 if err := s.d.Start(); err != nil { 731 c.Fatalf("Could not start daemon: %v", err) 732 } 733 defer s.d.Restart() 734 if err := s.d.Stop(); err != nil { 735 c.Fatalf("Could not stop daemon: %v", err) 736 } 737 738 // now we will change the docker0's IP and then try starting the daemon 739 bridgeIP := "192.169.100.1/24" 740 _, bridgeIPNet, _ := net.ParseCIDR(bridgeIP) 741 742 ipCmd := exec.Command("ifconfig", "docker0", bridgeIP) 743 stdout, stderr, _, err := runCommandWithStdoutStderr(ipCmd) 744 if err != nil { 745 c.Fatalf("failed to change docker0's IP association: %v, stdout: %q, stderr: %q", err, stdout, stderr) 746 } 747 748 if err := s.d.Start("--bip", bridgeIP); err != nil { 749 c.Fatalf("Could not start daemon: %v", err) 750 } 751 752 //check if the iptables contains new bridgeIP MASQUERADE rule 753 ipTablesSearchString := bridgeIPNet.String() 754 ipTablesCmd := exec.Command("iptables", "-t", "nat", "-nvL") 755 out, _, err := runCommandWithOutput(ipTablesCmd) 756 if err != nil { 757 c.Fatalf("Could not run iptables -nvL: %s, %v", out, err) 758 } 759 if !strings.Contains(out, ipTablesSearchString) { 760 c.Fatalf("iptables output should have contained new MASQUERADE rule with IP %q, but was %q", ipTablesSearchString, out) 761 } 762 } 763 764 func (s *DockerDaemonSuite) TestDaemonBridgeFixedCidr(c *check.C) { 765 d := s.d 766 767 bridgeName := "external-bridge" 768 bridgeIP := "192.169.1.1/24" 769 770 out, err := createInterface(c, "bridge", bridgeName, bridgeIP) 771 c.Assert(err, check.IsNil, check.Commentf(out)) 772 defer deleteInterface(c, bridgeName) 773 774 args := []string{"--bridge", bridgeName, "--fixed-cidr", "192.169.1.0/30"} 775 err = d.StartWithBusybox(args...) 776 c.Assert(err, check.IsNil) 777 defer d.Restart() 778 779 for i := 0; i < 4; i++ { 780 cName := "Container" + strconv.Itoa(i) 781 out, err := d.Cmd("run", "-d", "--name", cName, "busybox", "top") 782 if err != nil { 783 c.Assert(strings.Contains(out, "no available IPv4 addresses"), check.Equals, true, 784 check.Commentf("Could not run a Container : %s %s", err.Error(), out)) 785 } 786 } 787 } 788 789 func (s *DockerDaemonSuite) TestDaemonBridgeFixedCidr2(c *check.C) { 790 d := s.d 791 792 bridgeName := "external-bridge" 793 bridgeIP := "10.2.2.1/16" 794 795 out, err := createInterface(c, "bridge", bridgeName, bridgeIP) 796 c.Assert(err, check.IsNil, check.Commentf(out)) 797 defer deleteInterface(c, bridgeName) 798 799 err = d.StartWithBusybox("--bip", bridgeIP, "--fixed-cidr", "10.2.2.0/24") 800 c.Assert(err, check.IsNil) 801 defer s.d.Restart() 802 803 out, err = d.Cmd("run", "-d", "--name", "bb", "busybox", "top") 804 c.Assert(err, checker.IsNil, check.Commentf(out)) 805 defer d.Cmd("stop", "bb") 806 807 out, err = d.Cmd("exec", "bb", "/bin/sh", "-c", "ifconfig eth0 | awk '/inet addr/{print substr($2,6)}'") 808 c.Assert(out, checker.Equals, "10.2.2.0\n") 809 810 out, err = d.Cmd("run", "--rm", "busybox", "/bin/sh", "-c", "ifconfig eth0 | awk '/inet addr/{print substr($2,6)}'") 811 c.Assert(err, checker.IsNil, check.Commentf(out)) 812 c.Assert(out, checker.Equals, "10.2.2.2\n") 813 } 814 815 func (s *DockerDaemonSuite) TestDaemonBridgeFixedCIDREqualBridgeNetwork(c *check.C) { 816 d := s.d 817 818 bridgeName := "external-bridge" 819 bridgeIP := "172.27.42.1/16" 820 821 out, err := createInterface(c, "bridge", bridgeName, bridgeIP) 822 c.Assert(err, check.IsNil, check.Commentf(out)) 823 defer deleteInterface(c, bridgeName) 824 825 err = d.StartWithBusybox("--bridge", bridgeName, "--fixed-cidr", bridgeIP) 826 c.Assert(err, check.IsNil) 827 defer s.d.Restart() 828 829 out, err = d.Cmd("run", "-d", "busybox", "top") 830 c.Assert(err, check.IsNil, check.Commentf(out)) 831 cid1 := strings.TrimSpace(out) 832 defer d.Cmd("stop", cid1) 833 } 834 835 func (s *DockerDaemonSuite) TestDaemonDefaultGatewayIPv4Implicit(c *check.C) { 836 defaultNetworkBridge := "docker0" 837 deleteInterface(c, defaultNetworkBridge) 838 839 d := s.d 840 841 bridgeIP := "192.169.1.1" 842 bridgeIPNet := fmt.Sprintf("%s/24", bridgeIP) 843 844 err := d.StartWithBusybox("--bip", bridgeIPNet) 845 c.Assert(err, check.IsNil) 846 defer d.Restart() 847 848 expectedMessage := fmt.Sprintf("default via %s dev", bridgeIP) 849 out, err := d.Cmd("run", "busybox", "ip", "-4", "route", "list", "0/0") 850 c.Assert(strings.Contains(out, expectedMessage), check.Equals, true, 851 check.Commentf("Implicit default gateway should be bridge IP %s, but default route was '%s'", 852 bridgeIP, strings.TrimSpace(out))) 853 deleteInterface(c, defaultNetworkBridge) 854 } 855 856 func (s *DockerDaemonSuite) TestDaemonDefaultGatewayIPv4Explicit(c *check.C) { 857 defaultNetworkBridge := "docker0" 858 deleteInterface(c, defaultNetworkBridge) 859 860 d := s.d 861 862 bridgeIP := "192.169.1.1" 863 bridgeIPNet := fmt.Sprintf("%s/24", bridgeIP) 864 gatewayIP := "192.169.1.254" 865 866 err := d.StartWithBusybox("--bip", bridgeIPNet, "--default-gateway", gatewayIP) 867 c.Assert(err, check.IsNil) 868 defer d.Restart() 869 870 expectedMessage := fmt.Sprintf("default via %s dev", gatewayIP) 871 out, err := d.Cmd("run", "busybox", "ip", "-4", "route", "list", "0/0") 872 c.Assert(strings.Contains(out, expectedMessage), check.Equals, true, 873 check.Commentf("Explicit default gateway should be %s, but default route was '%s'", 874 gatewayIP, strings.TrimSpace(out))) 875 deleteInterface(c, defaultNetworkBridge) 876 } 877 878 func (s *DockerDaemonSuite) TestDaemonDefaultGatewayIPv4ExplicitOutsideContainerSubnet(c *check.C) { 879 defaultNetworkBridge := "docker0" 880 deleteInterface(c, defaultNetworkBridge) 881 882 // Program a custom default gateway outside of the container subnet, daemon should accept it and start 883 err := s.d.StartWithBusybox("--bip", "172.16.0.10/16", "--fixed-cidr", "172.16.1.0/24", "--default-gateway", "172.16.0.254") 884 c.Assert(err, check.IsNil) 885 886 deleteInterface(c, defaultNetworkBridge) 887 s.d.Restart() 888 } 889 890 func (s *DockerDaemonSuite) TestDaemonDefaultNetworkInvalidClusterConfig(c *check.C) { 891 testRequires(c, DaemonIsLinux, SameHostDaemon) 892 893 // Start daemon without docker0 bridge 894 defaultNetworkBridge := "docker0" 895 deleteInterface(c, defaultNetworkBridge) 896 897 d := NewDaemon(c) 898 discoveryBackend := "consul://consuladdr:consulport/some/path" 899 err := d.Start(fmt.Sprintf("--cluster-store=%s", discoveryBackend)) 900 c.Assert(err, checker.IsNil) 901 902 // Start daemon with docker0 bridge 903 ifconfigCmd := exec.Command("ifconfig", defaultNetworkBridge) 904 _, err = runCommand(ifconfigCmd) 905 c.Assert(err, check.IsNil) 906 907 err = d.Restart(fmt.Sprintf("--cluster-store=%s", discoveryBackend)) 908 c.Assert(err, checker.IsNil) 909 910 d.Stop() 911 } 912 913 func (s *DockerDaemonSuite) TestDaemonIP(c *check.C) { 914 d := s.d 915 916 ipStr := "192.170.1.1/24" 917 ip, _, _ := net.ParseCIDR(ipStr) 918 args := []string{"--ip", ip.String()} 919 err := d.StartWithBusybox(args...) 920 c.Assert(err, check.IsNil) 921 defer d.Restart() 922 923 out, err := d.Cmd("run", "-d", "-p", "8000:8000", "busybox", "top") 924 c.Assert(err, check.NotNil, 925 check.Commentf("Running a container must fail with an invalid --ip option")) 926 c.Assert(strings.Contains(out, "Error starting userland proxy"), check.Equals, true) 927 928 ifName := "dummy" 929 out, err = createInterface(c, "dummy", ifName, ipStr) 930 c.Assert(err, check.IsNil, check.Commentf(out)) 931 defer deleteInterface(c, ifName) 932 933 _, err = d.Cmd("run", "-d", "-p", "8000:8000", "busybox", "top") 934 c.Assert(err, check.IsNil) 935 936 ipTablesCmd := exec.Command("iptables", "-t", "nat", "-nvL") 937 out, _, err = runCommandWithOutput(ipTablesCmd) 938 c.Assert(err, check.IsNil) 939 940 regex := fmt.Sprintf("DNAT.*%s.*dpt:8000", ip.String()) 941 matched, _ := regexp.MatchString(regex, out) 942 c.Assert(matched, check.Equals, true, 943 check.Commentf("iptables output should have contained %q, but was %q", regex, out)) 944 } 945 946 func (s *DockerDaemonSuite) TestDaemonICCPing(c *check.C) { 947 d := s.d 948 949 bridgeName := "external-bridge" 950 bridgeIP := "192.169.1.1/24" 951 952 out, err := createInterface(c, "bridge", bridgeName, bridgeIP) 953 c.Assert(err, check.IsNil, check.Commentf(out)) 954 defer deleteInterface(c, bridgeName) 955 956 args := []string{"--bridge", bridgeName, "--icc=false"} 957 err = d.StartWithBusybox(args...) 958 c.Assert(err, check.IsNil) 959 defer d.Restart() 960 961 ipTablesCmd := exec.Command("iptables", "-nvL", "FORWARD") 962 out, _, err = runCommandWithOutput(ipTablesCmd) 963 c.Assert(err, check.IsNil) 964 965 regex := fmt.Sprintf("DROP.*all.*%s.*%s", bridgeName, bridgeName) 966 matched, _ := regexp.MatchString(regex, out) 967 c.Assert(matched, check.Equals, true, 968 check.Commentf("iptables output should have contained %q, but was %q", regex, out)) 969 970 // Pinging another container must fail with --icc=false 971 pingContainers(c, d, true) 972 973 ipStr := "192.171.1.1/24" 974 ip, _, _ := net.ParseCIDR(ipStr) 975 ifName := "icc-dummy" 976 977 createInterface(c, "dummy", ifName, ipStr) 978 979 // But, Pinging external or a Host interface must succeed 980 pingCmd := fmt.Sprintf("ping -c 1 %s -W 1", ip.String()) 981 runArgs := []string{"--rm", "busybox", "sh", "-c", pingCmd} 982 _, err = d.Cmd("run", runArgs...) 983 c.Assert(err, check.IsNil) 984 } 985 986 func (s *DockerDaemonSuite) TestDaemonICCLinkExpose(c *check.C) { 987 d := s.d 988 989 bridgeName := "external-bridge" 990 bridgeIP := "192.169.1.1/24" 991 992 out, err := createInterface(c, "bridge", bridgeName, bridgeIP) 993 c.Assert(err, check.IsNil, check.Commentf(out)) 994 defer deleteInterface(c, bridgeName) 995 996 args := []string{"--bridge", bridgeName, "--icc=false"} 997 err = d.StartWithBusybox(args...) 998 c.Assert(err, check.IsNil) 999 defer d.Restart() 1000 1001 ipTablesCmd := exec.Command("iptables", "-nvL", "FORWARD") 1002 out, _, err = runCommandWithOutput(ipTablesCmd) 1003 c.Assert(err, check.IsNil) 1004 1005 regex := fmt.Sprintf("DROP.*all.*%s.*%s", bridgeName, bridgeName) 1006 matched, _ := regexp.MatchString(regex, out) 1007 c.Assert(matched, check.Equals, true, 1008 check.Commentf("iptables output should have contained %q, but was %q", regex, out)) 1009 1010 out, err = d.Cmd("run", "-d", "--expose", "4567", "--name", "icc1", "busybox", "nc", "-l", "-p", "4567") 1011 c.Assert(err, check.IsNil, check.Commentf(out)) 1012 1013 out, err = d.Cmd("run", "--link", "icc1:icc1", "busybox", "nc", "icc1", "4567") 1014 c.Assert(err, check.IsNil, check.Commentf(out)) 1015 } 1016 1017 func (s *DockerDaemonSuite) TestDaemonLinksIpTablesRulesWhenLinkAndUnlink(c *check.C) { 1018 bridgeName := "external-bridge" 1019 bridgeIP := "192.169.1.1/24" 1020 1021 out, err := createInterface(c, "bridge", bridgeName, bridgeIP) 1022 c.Assert(err, check.IsNil, check.Commentf(out)) 1023 defer deleteInterface(c, bridgeName) 1024 1025 err = s.d.StartWithBusybox("--bridge", bridgeName, "--icc=false") 1026 c.Assert(err, check.IsNil) 1027 defer s.d.Restart() 1028 1029 _, err = s.d.Cmd("run", "-d", "--name", "child", "--publish", "8080:80", "busybox", "top") 1030 c.Assert(err, check.IsNil) 1031 _, err = s.d.Cmd("run", "-d", "--name", "parent", "--link", "child:http", "busybox", "top") 1032 c.Assert(err, check.IsNil) 1033 1034 childIP := s.d.findContainerIP("child") 1035 parentIP := s.d.findContainerIP("parent") 1036 1037 sourceRule := []string{"-i", bridgeName, "-o", bridgeName, "-p", "tcp", "-s", childIP, "--sport", "80", "-d", parentIP, "-j", "ACCEPT"} 1038 destinationRule := []string{"-i", bridgeName, "-o", bridgeName, "-p", "tcp", "-s", parentIP, "--dport", "80", "-d", childIP, "-j", "ACCEPT"} 1039 if !iptables.Exists("filter", "DOCKER", sourceRule...) || !iptables.Exists("filter", "DOCKER", destinationRule...) { 1040 c.Fatal("Iptables rules not found") 1041 } 1042 1043 s.d.Cmd("rm", "--link", "parent/http") 1044 if iptables.Exists("filter", "DOCKER", sourceRule...) || iptables.Exists("filter", "DOCKER", destinationRule...) { 1045 c.Fatal("Iptables rules should be removed when unlink") 1046 } 1047 1048 s.d.Cmd("kill", "child") 1049 s.d.Cmd("kill", "parent") 1050 } 1051 1052 func (s *DockerDaemonSuite) TestDaemonUlimitDefaults(c *check.C) { 1053 testRequires(c, DaemonIsLinux) 1054 1055 if err := s.d.StartWithBusybox("--default-ulimit", "nofile=42:42", "--default-ulimit", "nproc=1024:1024"); err != nil { 1056 c.Fatal(err) 1057 } 1058 1059 out, err := s.d.Cmd("run", "--ulimit", "nproc=2048", "--name=test", "busybox", "/bin/sh", "-c", "echo $(ulimit -n); echo $(ulimit -p)") 1060 if err != nil { 1061 c.Fatal(out, err) 1062 } 1063 1064 outArr := strings.Split(out, "\n") 1065 if len(outArr) < 2 { 1066 c.Fatalf("got unexpected output: %s", out) 1067 } 1068 nofile := strings.TrimSpace(outArr[0]) 1069 nproc := strings.TrimSpace(outArr[1]) 1070 1071 if nofile != "42" { 1072 c.Fatalf("expected `ulimit -n` to be `42`, got: %s", nofile) 1073 } 1074 if nproc != "2048" { 1075 c.Fatalf("exepcted `ulimit -p` to be 2048, got: %s", nproc) 1076 } 1077 1078 // Now restart daemon with a new default 1079 if err := s.d.Restart("--default-ulimit", "nofile=43"); err != nil { 1080 c.Fatal(err) 1081 } 1082 1083 out, err = s.d.Cmd("start", "-a", "test") 1084 if err != nil { 1085 c.Fatal(err) 1086 } 1087 1088 outArr = strings.Split(out, "\n") 1089 if len(outArr) < 2 { 1090 c.Fatalf("got unexpected output: %s", out) 1091 } 1092 nofile = strings.TrimSpace(outArr[0]) 1093 nproc = strings.TrimSpace(outArr[1]) 1094 1095 if nofile != "43" { 1096 c.Fatalf("expected `ulimit -n` to be `43`, got: %s", nofile) 1097 } 1098 if nproc != "2048" { 1099 c.Fatalf("exepcted `ulimit -p` to be 2048, got: %s", nproc) 1100 } 1101 } 1102 1103 // #11315 1104 func (s *DockerDaemonSuite) TestDaemonRestartRenameContainer(c *check.C) { 1105 if err := s.d.StartWithBusybox(); err != nil { 1106 c.Fatal(err) 1107 } 1108 1109 if out, err := s.d.Cmd("run", "--name=test", "busybox"); err != nil { 1110 c.Fatal(err, out) 1111 } 1112 1113 if out, err := s.d.Cmd("rename", "test", "test2"); err != nil { 1114 c.Fatal(err, out) 1115 } 1116 1117 if err := s.d.Restart(); err != nil { 1118 c.Fatal(err) 1119 } 1120 1121 if out, err := s.d.Cmd("start", "test2"); err != nil { 1122 c.Fatal(err, out) 1123 } 1124 } 1125 1126 func (s *DockerDaemonSuite) TestDaemonLoggingDriverDefault(c *check.C) { 1127 if err := s.d.StartWithBusybox(); err != nil { 1128 c.Fatal(err) 1129 } 1130 1131 out, err := s.d.Cmd("run", "-d", "busybox", "echo", "testline") 1132 if err != nil { 1133 c.Fatal(out, err) 1134 } 1135 id := strings.TrimSpace(out) 1136 1137 if out, err := s.d.Cmd("wait", id); err != nil { 1138 c.Fatal(out, err) 1139 } 1140 logPath := filepath.Join(s.d.root, "containers", id, id+"-json.log") 1141 1142 if _, err := os.Stat(logPath); err != nil { 1143 c.Fatal(err) 1144 } 1145 f, err := os.Open(logPath) 1146 if err != nil { 1147 c.Fatal(err) 1148 } 1149 var res struct { 1150 Log string `json:"log"` 1151 Stream string `json:"stream"` 1152 Time time.Time `json:"time"` 1153 } 1154 if err := json.NewDecoder(f).Decode(&res); err != nil { 1155 c.Fatal(err) 1156 } 1157 if res.Log != "testline\n" { 1158 c.Fatalf("Unexpected log line: %q, expected: %q", res.Log, "testline\n") 1159 } 1160 if res.Stream != "stdout" { 1161 c.Fatalf("Unexpected stream: %q, expected: %q", res.Stream, "stdout") 1162 } 1163 if !time.Now().After(res.Time) { 1164 c.Fatalf("Log time %v in future", res.Time) 1165 } 1166 } 1167 1168 func (s *DockerDaemonSuite) TestDaemonLoggingDriverDefaultOverride(c *check.C) { 1169 if err := s.d.StartWithBusybox(); err != nil { 1170 c.Fatal(err) 1171 } 1172 1173 out, err := s.d.Cmd("run", "-d", "--log-driver=none", "busybox", "echo", "testline") 1174 if err != nil { 1175 c.Fatal(out, err) 1176 } 1177 id := strings.TrimSpace(out) 1178 1179 if out, err := s.d.Cmd("wait", id); err != nil { 1180 c.Fatal(out, err) 1181 } 1182 logPath := filepath.Join(s.d.root, "containers", id, id+"-json.log") 1183 1184 if _, err := os.Stat(logPath); err == nil || !os.IsNotExist(err) { 1185 c.Fatalf("%s shouldn't exits, error on Stat: %s", logPath, err) 1186 } 1187 } 1188 1189 func (s *DockerDaemonSuite) TestDaemonLoggingDriverNone(c *check.C) { 1190 if err := s.d.StartWithBusybox("--log-driver=none"); err != nil { 1191 c.Fatal(err) 1192 } 1193 1194 out, err := s.d.Cmd("run", "-d", "busybox", "echo", "testline") 1195 if err != nil { 1196 c.Fatal(out, err) 1197 } 1198 id := strings.TrimSpace(out) 1199 if out, err := s.d.Cmd("wait", id); err != nil { 1200 c.Fatal(out, err) 1201 } 1202 1203 logPath := filepath.Join(s.d.folder, "graph", "containers", id, id+"-json.log") 1204 1205 if _, err := os.Stat(logPath); err == nil || !os.IsNotExist(err) { 1206 c.Fatalf("%s shouldn't exits, error on Stat: %s", logPath, err) 1207 } 1208 } 1209 1210 func (s *DockerDaemonSuite) TestDaemonLoggingDriverNoneOverride(c *check.C) { 1211 if err := s.d.StartWithBusybox("--log-driver=none"); err != nil { 1212 c.Fatal(err) 1213 } 1214 1215 out, err := s.d.Cmd("run", "-d", "--log-driver=json-file", "busybox", "echo", "testline") 1216 if err != nil { 1217 c.Fatal(out, err) 1218 } 1219 id := strings.TrimSpace(out) 1220 1221 if out, err := s.d.Cmd("wait", id); err != nil { 1222 c.Fatal(out, err) 1223 } 1224 logPath := filepath.Join(s.d.root, "containers", id, id+"-json.log") 1225 1226 if _, err := os.Stat(logPath); err != nil { 1227 c.Fatal(err) 1228 } 1229 f, err := os.Open(logPath) 1230 if err != nil { 1231 c.Fatal(err) 1232 } 1233 var res struct { 1234 Log string `json:"log"` 1235 Stream string `json:"stream"` 1236 Time time.Time `json:"time"` 1237 } 1238 if err := json.NewDecoder(f).Decode(&res); err != nil { 1239 c.Fatal(err) 1240 } 1241 if res.Log != "testline\n" { 1242 c.Fatalf("Unexpected log line: %q, expected: %q", res.Log, "testline\n") 1243 } 1244 if res.Stream != "stdout" { 1245 c.Fatalf("Unexpected stream: %q, expected: %q", res.Stream, "stdout") 1246 } 1247 if !time.Now().After(res.Time) { 1248 c.Fatalf("Log time %v in future", res.Time) 1249 } 1250 } 1251 1252 func (s *DockerDaemonSuite) TestDaemonLoggingDriverNoneLogsError(c *check.C) { 1253 if err := s.d.StartWithBusybox("--log-driver=none"); err != nil { 1254 c.Fatal(err) 1255 } 1256 1257 out, err := s.d.Cmd("run", "-d", "busybox", "echo", "testline") 1258 if err != nil { 1259 c.Fatal(out, err) 1260 } 1261 id := strings.TrimSpace(out) 1262 out, err = s.d.Cmd("logs", id) 1263 if err == nil { 1264 c.Fatalf("Logs should fail with 'none' driver") 1265 } 1266 if !strings.Contains(out, `"logs" command is supported only for "json-file" and "journald" logging drivers (got: none)`) { 1267 c.Fatalf("There should be an error about none not being a recognized log driver, got: %s", out) 1268 } 1269 } 1270 1271 func (s *DockerDaemonSuite) TestDaemonDots(c *check.C) { 1272 if err := s.d.StartWithBusybox(); err != nil { 1273 c.Fatal(err) 1274 } 1275 1276 // Now create 4 containers 1277 if _, err := s.d.Cmd("create", "busybox"); err != nil { 1278 c.Fatalf("Error creating container: %q", err) 1279 } 1280 if _, err := s.d.Cmd("create", "busybox"); err != nil { 1281 c.Fatalf("Error creating container: %q", err) 1282 } 1283 if _, err := s.d.Cmd("create", "busybox"); err != nil { 1284 c.Fatalf("Error creating container: %q", err) 1285 } 1286 if _, err := s.d.Cmd("create", "busybox"); err != nil { 1287 c.Fatalf("Error creating container: %q", err) 1288 } 1289 1290 s.d.Stop() 1291 1292 s.d.Start("--log-level=debug") 1293 s.d.Stop() 1294 content, _ := ioutil.ReadFile(s.d.logFile.Name()) 1295 if strings.Contains(string(content), "....") { 1296 c.Fatalf("Debug level should not have ....\n%s", string(content)) 1297 } 1298 1299 s.d.Start("--log-level=error") 1300 s.d.Stop() 1301 content, _ = ioutil.ReadFile(s.d.logFile.Name()) 1302 if strings.Contains(string(content), "....") { 1303 c.Fatalf("Error level should not have ....\n%s", string(content)) 1304 } 1305 1306 s.d.Start("--log-level=info") 1307 s.d.Stop() 1308 content, _ = ioutil.ReadFile(s.d.logFile.Name()) 1309 if !strings.Contains(string(content), "....") { 1310 c.Fatalf("Info level should have ....\n%s", string(content)) 1311 } 1312 } 1313 1314 func (s *DockerDaemonSuite) TestDaemonUnixSockCleanedUp(c *check.C) { 1315 dir, err := ioutil.TempDir("", "socket-cleanup-test") 1316 if err != nil { 1317 c.Fatal(err) 1318 } 1319 defer os.RemoveAll(dir) 1320 1321 sockPath := filepath.Join(dir, "docker.sock") 1322 if err := s.d.Start("--host", "unix://"+sockPath); err != nil { 1323 c.Fatal(err) 1324 } 1325 1326 if _, err := os.Stat(sockPath); err != nil { 1327 c.Fatal("socket does not exist") 1328 } 1329 1330 if err := s.d.Stop(); err != nil { 1331 c.Fatal(err) 1332 } 1333 1334 if _, err := os.Stat(sockPath); err == nil || !os.IsNotExist(err) { 1335 c.Fatal("unix socket is not cleaned up") 1336 } 1337 } 1338 1339 func (s *DockerDaemonSuite) TestDaemonWithWrongkey(c *check.C) { 1340 type Config struct { 1341 Crv string `json:"crv"` 1342 D string `json:"d"` 1343 Kid string `json:"kid"` 1344 Kty string `json:"kty"` 1345 X string `json:"x"` 1346 Y string `json:"y"` 1347 } 1348 1349 os.Remove("/etc/docker/key.json") 1350 if err := s.d.Start(); err != nil { 1351 c.Fatalf("Failed to start daemon: %v", err) 1352 } 1353 1354 if err := s.d.Stop(); err != nil { 1355 c.Fatalf("Could not stop daemon: %v", err) 1356 } 1357 1358 config := &Config{} 1359 bytes, err := ioutil.ReadFile("/etc/docker/key.json") 1360 if err != nil { 1361 c.Fatalf("Error reading key.json file: %s", err) 1362 } 1363 1364 // byte[] to Data-Struct 1365 if err := json.Unmarshal(bytes, &config); err != nil { 1366 c.Fatalf("Error Unmarshal: %s", err) 1367 } 1368 1369 //replace config.Kid with the fake value 1370 config.Kid = "VSAJ:FUYR:X3H2:B2VZ:KZ6U:CJD5:K7BX:ZXHY:UZXT:P4FT:MJWG:HRJ4" 1371 1372 // NEW Data-Struct to byte[] 1373 newBytes, err := json.Marshal(&config) 1374 if err != nil { 1375 c.Fatalf("Error Marshal: %s", err) 1376 } 1377 1378 // write back 1379 if err := ioutil.WriteFile("/etc/docker/key.json", newBytes, 0400); err != nil { 1380 c.Fatalf("Error ioutil.WriteFile: %s", err) 1381 } 1382 1383 defer os.Remove("/etc/docker/key.json") 1384 1385 if err := s.d.Start(); err == nil { 1386 c.Fatalf("It should not be successful to start daemon with wrong key: %v", err) 1387 } 1388 1389 content, _ := ioutil.ReadFile(s.d.logFile.Name()) 1390 1391 if !strings.Contains(string(content), "Public Key ID does not match") { 1392 c.Fatal("Missing KeyID message from daemon logs") 1393 } 1394 } 1395 1396 func (s *DockerDaemonSuite) TestDaemonRestartKillWait(c *check.C) { 1397 if err := s.d.StartWithBusybox(); err != nil { 1398 c.Fatalf("Could not start daemon with busybox: %v", err) 1399 } 1400 1401 out, err := s.d.Cmd("run", "-id", "busybox", "/bin/cat") 1402 if err != nil { 1403 c.Fatalf("Could not run /bin/cat: err=%v\n%s", err, out) 1404 } 1405 containerID := strings.TrimSpace(out) 1406 1407 if out, err := s.d.Cmd("kill", containerID); err != nil { 1408 c.Fatalf("Could not kill %s: err=%v\n%s", containerID, err, out) 1409 } 1410 1411 if err := s.d.Restart(); err != nil { 1412 c.Fatalf("Could not restart daemon: %v", err) 1413 } 1414 1415 errchan := make(chan error) 1416 go func() { 1417 if out, err := s.d.Cmd("wait", containerID); err != nil { 1418 errchan <- fmt.Errorf("%v:\n%s", err, out) 1419 } 1420 close(errchan) 1421 }() 1422 1423 select { 1424 case <-time.After(5 * time.Second): 1425 c.Fatal("Waiting on a stopped (killed) container timed out") 1426 case err := <-errchan: 1427 if err != nil { 1428 c.Fatal(err) 1429 } 1430 } 1431 } 1432 1433 // TestHttpsInfo connects via two-way authenticated HTTPS to the info endpoint 1434 func (s *DockerDaemonSuite) TestHttpsInfo(c *check.C) { 1435 const ( 1436 testDaemonHTTPSAddr = "tcp://localhost:4271" 1437 ) 1438 1439 if err := s.d.Start("--tlsverify", "--tlscacert", "fixtures/https/ca.pem", "--tlscert", "fixtures/https/server-cert.pem", 1440 "--tlskey", "fixtures/https/server-key.pem", "-H", testDaemonHTTPSAddr); err != nil { 1441 c.Fatalf("Could not start daemon with busybox: %v", err) 1442 } 1443 1444 daemonArgs := []string{"--host", testDaemonHTTPSAddr, "--tlsverify", "--tlscacert", "fixtures/https/ca.pem", "--tlscert", "fixtures/https/client-cert.pem", "--tlskey", "fixtures/https/client-key.pem"} 1445 out, err := s.d.CmdWithArgs(daemonArgs, "info") 1446 if err != nil { 1447 c.Fatalf("Error Occurred: %s and output: %s", err, out) 1448 } 1449 } 1450 1451 // TestTlsVerify verifies that --tlsverify=false turns on tls 1452 func (s *DockerDaemonSuite) TestTlsVerify(c *check.C) { 1453 out, err := exec.Command(dockerBinary, "daemon", "--tlsverify=false").CombinedOutput() 1454 if err == nil || !strings.Contains(string(out), "Could not load X509 key pair") { 1455 c.Fatalf("Daemon should not have started due to missing certs: %v\n%s", err, string(out)) 1456 } 1457 } 1458 1459 // TestHttpsInfoRogueCert connects via two-way authenticated HTTPS to the info endpoint 1460 // by using a rogue client certificate and checks that it fails with the expected error. 1461 func (s *DockerDaemonSuite) TestHttpsInfoRogueCert(c *check.C) { 1462 const ( 1463 errBadCertificate = "remote error: bad certificate" 1464 testDaemonHTTPSAddr = "tcp://localhost:4271" 1465 ) 1466 1467 if err := s.d.Start("--tlsverify", "--tlscacert", "fixtures/https/ca.pem", "--tlscert", "fixtures/https/server-cert.pem", 1468 "--tlskey", "fixtures/https/server-key.pem", "-H", testDaemonHTTPSAddr); err != nil { 1469 c.Fatalf("Could not start daemon with busybox: %v", err) 1470 } 1471 1472 daemonArgs := []string{"--host", testDaemonHTTPSAddr, "--tlsverify", "--tlscacert", "fixtures/https/ca.pem", "--tlscert", "fixtures/https/client-rogue-cert.pem", "--tlskey", "fixtures/https/client-rogue-key.pem"} 1473 out, err := s.d.CmdWithArgs(daemonArgs, "info") 1474 if err == nil || !strings.Contains(out, errBadCertificate) { 1475 c.Fatalf("Expected err: %s, got instead: %s and output: %s", errBadCertificate, err, out) 1476 } 1477 } 1478 1479 // TestHttpsInfoRogueServerCert connects via two-way authenticated HTTPS to the info endpoint 1480 // which provides a rogue server certificate and checks that it fails with the expected error 1481 func (s *DockerDaemonSuite) TestHttpsInfoRogueServerCert(c *check.C) { 1482 const ( 1483 errCaUnknown = "x509: certificate signed by unknown authority" 1484 testDaemonRogueHTTPSAddr = "tcp://localhost:4272" 1485 ) 1486 if err := s.d.Start("--tlsverify", "--tlscacert", "fixtures/https/ca.pem", "--tlscert", "fixtures/https/server-rogue-cert.pem", 1487 "--tlskey", "fixtures/https/server-rogue-key.pem", "-H", testDaemonRogueHTTPSAddr); err != nil { 1488 c.Fatalf("Could not start daemon with busybox: %v", err) 1489 } 1490 1491 daemonArgs := []string{"--host", testDaemonRogueHTTPSAddr, "--tlsverify", "--tlscacert", "fixtures/https/ca.pem", "--tlscert", "fixtures/https/client-rogue-cert.pem", "--tlskey", "fixtures/https/client-rogue-key.pem"} 1492 out, err := s.d.CmdWithArgs(daemonArgs, "info") 1493 if err == nil || !strings.Contains(out, errCaUnknown) { 1494 c.Fatalf("Expected err: %s, got instead: %s and output: %s", errCaUnknown, err, out) 1495 } 1496 } 1497 1498 func pingContainers(c *check.C, d *Daemon, expectFailure bool) { 1499 var dargs []string 1500 if d != nil { 1501 dargs = []string{"--host", d.sock()} 1502 } 1503 1504 args := append(dargs, "run", "-d", "--name", "container1", "busybox", "top") 1505 dockerCmd(c, args...) 1506 1507 args = append(dargs, "run", "--rm", "--link", "container1:alias1", "busybox", "sh", "-c") 1508 pingCmd := "ping -c 1 %s -W 1" 1509 args = append(args, fmt.Sprintf(pingCmd, "alias1")) 1510 _, _, err := dockerCmdWithError(args...) 1511 1512 if expectFailure { 1513 c.Assert(err, check.NotNil) 1514 } else { 1515 c.Assert(err, check.IsNil) 1516 } 1517 1518 args = append(dargs, "rm", "-f", "container1") 1519 dockerCmd(c, args...) 1520 } 1521 1522 func (s *DockerDaemonSuite) TestDaemonRestartWithSocketAsVolume(c *check.C) { 1523 c.Assert(s.d.StartWithBusybox(), check.IsNil) 1524 1525 socket := filepath.Join(s.d.folder, "docker.sock") 1526 1527 out, err := s.d.Cmd("run", "-d", "--restart=always", "-v", socket+":/sock", "busybox") 1528 c.Assert(err, check.IsNil, check.Commentf("Output: %s", out)) 1529 c.Assert(s.d.Restart(), check.IsNil) 1530 } 1531 1532 func (s *DockerDaemonSuite) TestCleanupMountsAfterCrash(c *check.C) { 1533 c.Assert(s.d.StartWithBusybox(), check.IsNil) 1534 1535 out, err := s.d.Cmd("run", "-d", "busybox", "top") 1536 c.Assert(err, check.IsNil, check.Commentf("Output: %s", out)) 1537 id := strings.TrimSpace(out) 1538 c.Assert(s.d.cmd.Process.Signal(os.Kill), check.IsNil) 1539 c.Assert(s.d.Start(), check.IsNil) 1540 mountOut, err := ioutil.ReadFile("/proc/self/mountinfo") 1541 c.Assert(err, check.IsNil, check.Commentf("Output: %s", mountOut)) 1542 1543 comment := check.Commentf("%s is still mounted from older daemon start:\nDaemon root repository %s\n%s", id, s.d.folder, mountOut) 1544 c.Assert(strings.Contains(string(mountOut), id), check.Equals, false, comment) 1545 } 1546 1547 func (s *DockerDaemonSuite) TestRunContainerWithBridgeNone(c *check.C) { 1548 testRequires(c, DaemonIsLinux, NotUserNamespace) 1549 c.Assert(s.d.StartWithBusybox("-b", "none"), check.IsNil) 1550 1551 out, err := s.d.Cmd("run", "--rm", "busybox", "ip", "l") 1552 c.Assert(err, check.IsNil, check.Commentf("Output: %s", out)) 1553 c.Assert(strings.Contains(out, "eth0"), check.Equals, false, 1554 check.Commentf("There shouldn't be eth0 in container in default(bridge) mode when bridge network is disabled: %s", out)) 1555 1556 out, err = s.d.Cmd("run", "--rm", "--net=bridge", "busybox", "ip", "l") 1557 c.Assert(err, check.IsNil, check.Commentf("Output: %s", out)) 1558 c.Assert(strings.Contains(out, "eth0"), check.Equals, false, 1559 check.Commentf("There shouldn't be eth0 in container in bridge mode when bridge network is disabled: %s", out)) 1560 // the extra grep and awk clean up the output of `ip` to only list the number and name of 1561 // interfaces, allowing for different versions of ip (e.g. inside and outside the container) to 1562 // be used while still verifying that the interface list is the exact same 1563 cmd := exec.Command("sh", "-c", "ip l | grep -E '^[0-9]+:' | awk -F: ' { print $1\":\"$2 } '") 1564 stdout := bytes.NewBuffer(nil) 1565 cmd.Stdout = stdout 1566 if err := cmd.Run(); err != nil { 1567 c.Fatal("Failed to get host network interface") 1568 } 1569 out, err = s.d.Cmd("run", "--rm", "--net=host", "busybox", "sh", "-c", "ip l | grep -E '^[0-9]+:' | awk -F: ' { print $1\":\"$2 } '") 1570 c.Assert(err, check.IsNil, check.Commentf("Output: %s", out)) 1571 c.Assert(out, check.Equals, fmt.Sprintf("%s", stdout), 1572 check.Commentf("The network interfaces in container should be the same with host when --net=host when bridge network is disabled: %s", out)) 1573 } 1574 1575 func (s *DockerDaemonSuite) TestDaemonRestartWithContainerRunning(t *check.C) { 1576 if err := s.d.StartWithBusybox(); err != nil { 1577 t.Fatal(err) 1578 } 1579 if out, err := s.d.Cmd("run", "-ti", "-d", "--name", "test", "busybox"); err != nil { 1580 t.Fatal(out, err) 1581 } 1582 1583 if err := s.d.Restart(); err != nil { 1584 t.Fatal(err) 1585 } 1586 // Container 'test' should be removed without error 1587 if out, err := s.d.Cmd("rm", "test"); err != nil { 1588 t.Fatal(out, err) 1589 } 1590 } 1591 1592 func (s *DockerDaemonSuite) TestDaemonRestartCleanupNetns(c *check.C) { 1593 if err := s.d.StartWithBusybox(); err != nil { 1594 c.Fatal(err) 1595 } 1596 out, err := s.d.Cmd("run", "--name", "netns", "-d", "busybox", "top") 1597 if err != nil { 1598 c.Fatal(out, err) 1599 } 1600 1601 // Get sandbox key via inspect 1602 out, err = s.d.Cmd("inspect", "--format", "'{{.NetworkSettings.SandboxKey}}'", "netns") 1603 if err != nil { 1604 c.Fatalf("Error inspecting container: %s, %v", out, err) 1605 } 1606 fileName := strings.Trim(out, " \r\n'") 1607 1608 if out, err := s.d.Cmd("stop", "netns"); err != nil { 1609 c.Fatal(out, err) 1610 } 1611 1612 // Test if the file still exists 1613 out, _, err = runCommandWithOutput(exec.Command("stat", "-c", "%n", fileName)) 1614 out = strings.TrimSpace(out) 1615 c.Assert(err, check.IsNil, check.Commentf("Output: %s", out)) 1616 c.Assert(out, check.Equals, fileName, check.Commentf("Output: %s", out)) 1617 1618 // Remove the container and restart the daemon 1619 if out, err := s.d.Cmd("rm", "netns"); err != nil { 1620 c.Fatal(out, err) 1621 } 1622 1623 if err := s.d.Restart(); err != nil { 1624 c.Fatal(err) 1625 } 1626 1627 // Test again and see now the netns file does not exist 1628 out, _, err = runCommandWithOutput(exec.Command("stat", "-c", "%n", fileName)) 1629 out = strings.TrimSpace(out) 1630 c.Assert(err, check.Not(check.IsNil), check.Commentf("Output: %s", out)) 1631 } 1632 1633 // tests regression detailed in #13964 where DOCKER_TLS_VERIFY env is ignored 1634 func (s *DockerDaemonSuite) TestDaemonNoTlsCliTlsVerifyWithEnv(c *check.C) { 1635 host := "tcp://localhost:4271" 1636 c.Assert(s.d.Start("-H", host), check.IsNil) 1637 cmd := exec.Command(dockerBinary, "-H", host, "info") 1638 cmd.Env = []string{"DOCKER_TLS_VERIFY=1", "DOCKER_CERT_PATH=fixtures/https"} 1639 out, _, err := runCommandWithOutput(cmd) 1640 c.Assert(err, check.Not(check.IsNil), check.Commentf("%s", out)) 1641 c.Assert(strings.Contains(out, "error occurred trying to connect"), check.Equals, true) 1642 1643 } 1644 1645 func setupV6() error { 1646 // Hack to get the right IPv6 address on docker0, which has already been created 1647 err := exec.Command("ip", "addr", "add", "fe80::1/64", "dev", "docker0").Run() 1648 if err != nil { 1649 return err 1650 } 1651 return nil 1652 } 1653 1654 func teardownV6() error { 1655 err := exec.Command("ip", "addr", "del", "fe80::1/64", "dev", "docker0").Run() 1656 if err != nil { 1657 return err 1658 } 1659 return nil 1660 } 1661 1662 func (s *DockerDaemonSuite) TestDaemonRestartWithContainerWithRestartPolicyAlways(c *check.C) { 1663 c.Assert(s.d.StartWithBusybox(), check.IsNil) 1664 1665 out, err := s.d.Cmd("run", "-d", "--restart", "always", "busybox", "top") 1666 c.Assert(err, check.IsNil) 1667 id := strings.TrimSpace(out) 1668 1669 _, err = s.d.Cmd("stop", id) 1670 c.Assert(err, check.IsNil) 1671 _, err = s.d.Cmd("wait", id) 1672 c.Assert(err, check.IsNil) 1673 1674 out, err = s.d.Cmd("ps", "-q") 1675 c.Assert(err, check.IsNil) 1676 c.Assert(out, check.Equals, "") 1677 1678 c.Assert(s.d.Restart(), check.IsNil) 1679 1680 out, err = s.d.Cmd("ps", "-q") 1681 c.Assert(err, check.IsNil) 1682 c.Assert(strings.TrimSpace(out), check.Equals, id[:12]) 1683 } 1684 1685 func (s *DockerDaemonSuite) TestDaemonWideLogConfig(c *check.C) { 1686 if err := s.d.StartWithBusybox("--log-driver=json-file", "--log-opt=max-size=1k"); err != nil { 1687 c.Fatal(err) 1688 } 1689 out, err := s.d.Cmd("run", "-d", "--name=logtest", "busybox", "top") 1690 c.Assert(err, check.IsNil, check.Commentf("Output: %s, err: %v", out, err)) 1691 out, err = s.d.Cmd("inspect", "-f", "{{ .HostConfig.LogConfig.Config }}", "logtest") 1692 c.Assert(err, check.IsNil, check.Commentf("Output: %s", out)) 1693 cfg := strings.TrimSpace(out) 1694 if cfg != "map[max-size:1k]" { 1695 c.Fatalf("Unexpected log-opt: %s, expected map[max-size:1k]", cfg) 1696 } 1697 } 1698 1699 func (s *DockerDaemonSuite) TestDaemonRestartWithPausedContainer(c *check.C) { 1700 if err := s.d.StartWithBusybox(); err != nil { 1701 c.Fatal(err) 1702 } 1703 if out, err := s.d.Cmd("run", "-i", "-d", "--name", "test", "busybox", "top"); err != nil { 1704 c.Fatal(err, out) 1705 } 1706 if out, err := s.d.Cmd("pause", "test"); err != nil { 1707 c.Fatal(err, out) 1708 } 1709 if err := s.d.Restart(); err != nil { 1710 c.Fatal(err) 1711 } 1712 1713 errchan := make(chan error) 1714 go func() { 1715 out, err := s.d.Cmd("start", "test") 1716 if err != nil { 1717 errchan <- fmt.Errorf("%v:\n%s", err, out) 1718 } 1719 name := strings.TrimSpace(out) 1720 if name != "test" { 1721 errchan <- fmt.Errorf("Paused container start error on docker daemon restart, expected 'test' but got '%s'", name) 1722 } 1723 close(errchan) 1724 }() 1725 1726 select { 1727 case <-time.After(5 * time.Second): 1728 c.Fatal("Waiting on start a container timed out") 1729 case err := <-errchan: 1730 if err != nil { 1731 c.Fatal(err) 1732 } 1733 } 1734 } 1735 1736 func (s *DockerDaemonSuite) TestDaemonRestartRmVolumeInUse(c *check.C) { 1737 c.Assert(s.d.StartWithBusybox(), check.IsNil) 1738 1739 out, err := s.d.Cmd("create", "-v", "test:/foo", "busybox") 1740 c.Assert(err, check.IsNil, check.Commentf(out)) 1741 1742 c.Assert(s.d.Restart(), check.IsNil) 1743 1744 out, err = s.d.Cmd("volume", "rm", "test") 1745 c.Assert(err, check.Not(check.IsNil), check.Commentf("should not be able to remove in use volume after daemon restart")) 1746 c.Assert(strings.Contains(out, "in use"), check.Equals, true) 1747 } 1748 1749 func (s *DockerDaemonSuite) TestDaemonRestartLocalVolumes(c *check.C) { 1750 c.Assert(s.d.Start(), check.IsNil) 1751 1752 _, err := s.d.Cmd("volume", "create", "--name", "test") 1753 c.Assert(err, check.IsNil) 1754 c.Assert(s.d.Restart(), check.IsNil) 1755 1756 _, err = s.d.Cmd("volume", "inspect", "test") 1757 c.Assert(err, check.IsNil) 1758 } 1759 1760 func (s *DockerDaemonSuite) TestDaemonCorruptedLogDriverAddress(c *check.C) { 1761 for _, driver := range []string{ 1762 "syslog", 1763 "gelf", 1764 } { 1765 args := []string{"--log-driver=" + driver, "--log-opt", driver + "-address=corrupted:42"} 1766 c.Assert(s.d.Start(args...), check.NotNil, check.Commentf(fmt.Sprintf("Expected daemon not to start with invalid %s-address provided", driver))) 1767 expected := fmt.Sprintf("Failed to set log opts: %s-address should be in form proto://address", driver) 1768 runCmd := exec.Command("grep", expected, s.d.LogfileName()) 1769 if out, _, err := runCommandWithOutput(runCmd); err != nil { 1770 c.Fatalf("Expected %q message; but doesn't exist in log: %q, err: %v", expected, out, err) 1771 } 1772 } 1773 } 1774 1775 func (s *DockerDaemonSuite) TestDaemonCorruptedFluentdAddress(c *check.C) { 1776 c.Assert(s.d.Start("--log-driver=fluentd", "--log-opt", "fluentd-address=corrupted:c"), check.NotNil) 1777 expected := "Failed to set log opts: invalid fluentd-address corrupted:c: " 1778 runCmd := exec.Command("grep", expected, s.d.LogfileName()) 1779 if out, _, err := runCommandWithOutput(runCmd); err != nil { 1780 c.Fatalf("Expected %q message; but doesn't exist in log: %q, err: %v", expected, out, err) 1781 } 1782 } 1783 1784 func (s *DockerDaemonSuite) TestDaemonStartWithoutHost(c *check.C) { 1785 s.d.useDefaultHost = true 1786 defer func() { 1787 s.d.useDefaultHost = false 1788 }() 1789 c.Assert(s.d.Start(), check.IsNil) 1790 } 1791 1792 func (s *DockerDaemonSuite) TestDaemonStartWithDefalutTlsHost(c *check.C) { 1793 s.d.useDefaultTLSHost = true 1794 defer func() { 1795 s.d.useDefaultTLSHost = false 1796 }() 1797 if err := s.d.Start( 1798 "--tlsverify", 1799 "--tlscacert", "fixtures/https/ca.pem", 1800 "--tlscert", "fixtures/https/server-cert.pem", 1801 "--tlskey", "fixtures/https/server-key.pem"); err != nil { 1802 c.Fatalf("Could not start daemon: %v", err) 1803 } 1804 1805 // The client with --tlsverify should also use default host localhost:2376 1806 tmpHost := os.Getenv("DOCKER_HOST") 1807 defer func() { 1808 os.Setenv("DOCKER_HOST", tmpHost) 1809 }() 1810 1811 os.Setenv("DOCKER_HOST", "") 1812 1813 out, _ := dockerCmd( 1814 c, 1815 "--tlsverify", 1816 "--tlscacert", "fixtures/https/ca.pem", 1817 "--tlscert", "fixtures/https/client-cert.pem", 1818 "--tlskey", "fixtures/https/client-key.pem", 1819 "version", 1820 ) 1821 if !strings.Contains(out, "Server") { 1822 c.Fatalf("docker version should return information of server side") 1823 } 1824 } 1825 1826 func (s *DockerDaemonSuite) TestBridgeIPIsExcludedFromAllocatorPool(c *check.C) { 1827 defaultNetworkBridge := "docker0" 1828 deleteInterface(c, defaultNetworkBridge) 1829 1830 bridgeIP := "192.169.1.1" 1831 bridgeRange := bridgeIP + "/30" 1832 1833 err := s.d.StartWithBusybox("--bip", bridgeRange) 1834 c.Assert(err, check.IsNil) 1835 defer s.d.Restart() 1836 1837 var cont int 1838 for { 1839 contName := fmt.Sprintf("container%d", cont) 1840 _, err = s.d.Cmd("run", "--name", contName, "-d", "busybox", "/bin/sleep", "2") 1841 if err != nil { 1842 // pool exhausted 1843 break 1844 } 1845 ip, err := s.d.Cmd("inspect", "--format", "'{{.NetworkSettings.IPAddress}}'", contName) 1846 c.Assert(err, check.IsNil) 1847 1848 c.Assert(ip, check.Not(check.Equals), bridgeIP) 1849 cont++ 1850 } 1851 } 1852 1853 // Test daemon for no space left on device error 1854 func (s *DockerDaemonSuite) TestDaemonNoSpaceleftOnDeviceError(c *check.C) { 1855 testRequires(c, SameHostDaemon, DaemonIsLinux) 1856 1857 // create a 2MiB image and mount it as graph root 1858 cmd := exec.Command("dd", "of=/tmp/testfs.img", "bs=1M", "seek=2", "count=0") 1859 if err := cmd.Run(); err != nil { 1860 c.Fatalf("dd failed: %v", err) 1861 } 1862 cmd = exec.Command("mkfs.ext4", "-F", "/tmp/testfs.img") 1863 if err := cmd.Run(); err != nil { 1864 c.Fatalf("mkfs.ext4 failed: %v", err) 1865 } 1866 cmd = exec.Command("mkdir", "-p", "/tmp/testfs-mount") 1867 if err := cmd.Run(); err != nil { 1868 c.Fatalf("mkdir failed: %v", err) 1869 } 1870 cmd = exec.Command("mount", "-t", "ext4", "-no", "loop,rw", "/tmp/testfs.img", "/tmp/testfs-mount") 1871 if err := cmd.Run(); err != nil { 1872 c.Fatalf("mount failed: %v", err) 1873 } 1874 err := s.d.Start("--graph", "/tmp/testfs-mount") 1875 c.Assert(err, check.IsNil) 1876 1877 // pull a repository large enough to fill the mount point 1878 out, err := s.d.Cmd("pull", "registry:2") 1879 c.Assert(out, check.Not(check.Equals), 1, check.Commentf("no space left on device")) 1880 }