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