github.com/guilhermebr/docker@v1.4.2-0.20150428121140-67da055cebca/integration-cli/docker_cli_daemon_test.go (about) 1 // +build daemon 2 3 package main 4 5 import ( 6 "encoding/json" 7 "fmt" 8 "io/ioutil" 9 "os" 10 "os/exec" 11 "path/filepath" 12 "strings" 13 "time" 14 15 "github.com/docker/libtrust" 16 "github.com/go-check/check" 17 ) 18 19 func (s *DockerSuite) TestDaemonRestartWithRunningContainersPorts(c *check.C) { 20 d := NewDaemon(c) 21 if err := d.StartWithBusybox(); err != nil { 22 c.Fatalf("Could not start daemon with busybox: %v", err) 23 } 24 defer d.Stop() 25 26 if out, err := d.Cmd("run", "-d", "--name", "top1", "-p", "1234:80", "--restart", "always", "busybox:latest", "top"); err != nil { 27 c.Fatalf("Could not run top1: err=%v\n%s", err, out) 28 } 29 // --restart=no by default 30 if out, err := d.Cmd("run", "-d", "--name", "top2", "-p", "80", "busybox:latest", "top"); err != nil { 31 c.Fatalf("Could not run top2: err=%v\n%s", err, out) 32 } 33 34 testRun := func(m map[string]bool, prefix string) { 35 var format string 36 for cont, shouldRun := range m { 37 out, err := d.Cmd("ps") 38 if err != nil { 39 c.Fatalf("Could not run ps: err=%v\n%q", err, out) 40 } 41 if shouldRun { 42 format = "%scontainer %q is not running" 43 } else { 44 format = "%scontainer %q is running" 45 } 46 if shouldRun != strings.Contains(out, cont) { 47 c.Fatalf(format, prefix, cont) 48 } 49 } 50 } 51 52 testRun(map[string]bool{"top1": true, "top2": true}, "") 53 54 if err := d.Restart(); err != nil { 55 c.Fatalf("Could not restart daemon: %v", err) 56 } 57 58 testRun(map[string]bool{"top1": true, "top2": false}, "After daemon restart: ") 59 60 } 61 62 func (s *DockerSuite) TestDaemonRestartWithVolumesRefs(c *check.C) { 63 d := NewDaemon(c) 64 if err := d.StartWithBusybox(); err != nil { 65 c.Fatal(err) 66 } 67 defer d.Stop() 68 69 if out, err := d.Cmd("run", "-d", "--name", "volrestarttest1", "-v", "/foo", "busybox"); err != nil { 70 c.Fatal(err, out) 71 } 72 if err := d.Restart(); err != nil { 73 c.Fatal(err) 74 } 75 if _, err := d.Cmd("run", "-d", "--volumes-from", "volrestarttest1", "--name", "volrestarttest2", "busybox", "top"); err != nil { 76 c.Fatal(err) 77 } 78 if out, err := d.Cmd("rm", "-fv", "volrestarttest2"); err != nil { 79 c.Fatal(err, out) 80 } 81 v, err := d.Cmd("inspect", "--format", "{{ json .Volumes }}", "volrestarttest1") 82 if err != nil { 83 c.Fatal(err) 84 } 85 volumes := make(map[string]string) 86 json.Unmarshal([]byte(v), &volumes) 87 if _, err := os.Stat(volumes["/foo"]); err != nil { 88 c.Fatalf("Expected volume to exist: %s - %s", volumes["/foo"], err) 89 } 90 91 } 92 93 func (s *DockerSuite) TestDaemonStartIptablesFalse(c *check.C) { 94 d := NewDaemon(c) 95 if err := d.Start("--iptables=false"); err != nil { 96 c.Fatalf("we should have been able to start the daemon with passing iptables=false: %v", err) 97 } 98 d.Stop() 99 100 } 101 102 // Issue #8444: If docker0 bridge is modified (intentionally or unintentionally) and 103 // no longer has an IP associated, we should gracefully handle that case and associate 104 // an IP with it rather than fail daemon start 105 func (s *DockerSuite) TestDaemonStartBridgeWithoutIPAssociation(c *check.C) { 106 d := NewDaemon(c) 107 // rather than depending on brctl commands to verify docker0 is created and up 108 // let's start the daemon and stop it, and then make a modification to run the 109 // actual test 110 if err := d.Start(); err != nil { 111 c.Fatalf("Could not start daemon: %v", err) 112 } 113 if err := d.Stop(); err != nil { 114 c.Fatalf("Could not stop daemon: %v", err) 115 } 116 117 // now we will remove the ip from docker0 and then try starting the daemon 118 ipCmd := exec.Command("ip", "addr", "flush", "dev", "docker0") 119 stdout, stderr, _, err := runCommandWithStdoutStderr(ipCmd) 120 if err != nil { 121 c.Fatalf("failed to remove docker0 IP association: %v, stdout: %q, stderr: %q", err, stdout, stderr) 122 } 123 124 if err := d.Start(); err != nil { 125 warning := "**WARNING: Docker bridge network in bad state--delete docker0 bridge interface to fix" 126 c.Fatalf("Could not start daemon when docker0 has no IP address: %v\n%s", err, warning) 127 } 128 129 // cleanup - stop the daemon if test passed 130 if err := d.Stop(); err != nil { 131 c.Fatalf("Could not stop daemon: %v", err) 132 } 133 134 } 135 136 func (s *DockerSuite) TestDaemonIptablesClean(c *check.C) { 137 138 d := NewDaemon(c) 139 if err := d.StartWithBusybox(); err != nil { 140 c.Fatalf("Could not start daemon with busybox: %v", err) 141 } 142 defer d.Stop() 143 144 if out, err := d.Cmd("run", "-d", "--name", "top", "-p", "80", "busybox:latest", "top"); err != nil { 145 c.Fatalf("Could not run top: %s, %v", out, err) 146 } 147 148 // get output from iptables with container running 149 ipTablesSearchString := "tcp dpt:80" 150 ipTablesCmd := exec.Command("iptables", "-nvL") 151 out, _, err := runCommandWithOutput(ipTablesCmd) 152 if err != nil { 153 c.Fatalf("Could not run iptables -nvL: %s, %v", out, err) 154 } 155 156 if !strings.Contains(out, ipTablesSearchString) { 157 c.Fatalf("iptables output should have contained %q, but was %q", ipTablesSearchString, out) 158 } 159 160 if err := d.Stop(); err != nil { 161 c.Fatalf("Could not stop daemon: %v", err) 162 } 163 164 // get output from iptables after restart 165 ipTablesCmd = exec.Command("iptables", "-nvL") 166 out, _, err = runCommandWithOutput(ipTablesCmd) 167 if err != nil { 168 c.Fatalf("Could not run iptables -nvL: %s, %v", out, err) 169 } 170 171 if strings.Contains(out, ipTablesSearchString) { 172 c.Fatalf("iptables output should not have contained %q, but was %q", ipTablesSearchString, out) 173 } 174 175 } 176 177 func (s *DockerSuite) TestDaemonIptablesCreate(c *check.C) { 178 179 d := NewDaemon(c) 180 if err := d.StartWithBusybox(); err != nil { 181 c.Fatalf("Could not start daemon with busybox: %v", err) 182 } 183 defer d.Stop() 184 185 if out, err := d.Cmd("run", "-d", "--name", "top", "--restart=always", "-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 := d.Restart(); err != nil { 202 c.Fatalf("Could not restart daemon: %v", err) 203 } 204 205 // make sure the container is not running 206 runningOut, err := d.Cmd("inspect", "--format='{{.State.Running}}'", "top") 207 if err != nil { 208 c.Fatalf("Could not inspect on container: %s, %v", out, err) 209 } 210 if strings.TrimSpace(runningOut) != "true" { 211 c.Fatalf("Container should have been restarted after daemon restart. Status running should have been true but was: %q", strings.TrimSpace(runningOut)) 212 } 213 214 // get output from iptables after restart 215 ipTablesCmd = exec.Command("iptables", "-nvL") 216 out, _, err = runCommandWithOutput(ipTablesCmd) 217 if err != nil { 218 c.Fatalf("Could not run iptables -nvL: %s, %v", out, err) 219 } 220 221 if !strings.Contains(out, ipTablesSearchString) { 222 c.Fatalf("iptables output after restart should have contained %q, but was %q", ipTablesSearchString, out) 223 } 224 225 } 226 227 func (s *DockerSuite) TestDaemonLoggingLevel(c *check.C) { 228 d := NewDaemon(c) 229 230 if err := d.Start("--log-level=bogus"); err == nil { 231 c.Fatal("Daemon should not have been able to start") 232 } 233 234 d = NewDaemon(c) 235 if err := d.Start("--log-level=debug"); err != nil { 236 c.Fatal(err) 237 } 238 d.Stop() 239 content, _ := ioutil.ReadFile(d.logFile.Name()) 240 if !strings.Contains(string(content), `level=debug`) { 241 c.Fatalf(`Missing level="debug" in log file:\n%s`, string(content)) 242 } 243 244 d = NewDaemon(c) 245 if err := d.Start("--log-level=fatal"); err != nil { 246 c.Fatal(err) 247 } 248 d.Stop() 249 content, _ = ioutil.ReadFile(d.logFile.Name()) 250 if strings.Contains(string(content), `level=debug`) { 251 c.Fatalf(`Should not have level="debug" in log file:\n%s`, string(content)) 252 } 253 254 d = NewDaemon(c) 255 if err := d.Start("-D"); err != nil { 256 c.Fatal(err) 257 } 258 d.Stop() 259 content, _ = ioutil.ReadFile(d.logFile.Name()) 260 if !strings.Contains(string(content), `level=debug`) { 261 c.Fatalf(`Missing level="debug" in log file using -D:\n%s`, string(content)) 262 } 263 264 d = NewDaemon(c) 265 if err := d.Start("--debug"); err != nil { 266 c.Fatal(err) 267 } 268 d.Stop() 269 content, _ = ioutil.ReadFile(d.logFile.Name()) 270 if !strings.Contains(string(content), `level=debug`) { 271 c.Fatalf(`Missing level="debug" in log file using --debug:\n%s`, string(content)) 272 } 273 274 d = NewDaemon(c) 275 if err := d.Start("--debug", "--log-level=fatal"); err != nil { 276 c.Fatal(err) 277 } 278 d.Stop() 279 content, _ = ioutil.ReadFile(d.logFile.Name()) 280 if !strings.Contains(string(content), `level=debug`) { 281 c.Fatalf(`Missing level="debug" in log file when using both --debug and --log-level=fatal:\n%s`, string(content)) 282 } 283 284 } 285 286 func (s *DockerSuite) TestDaemonAllocatesListeningPort(c *check.C) { 287 listeningPorts := [][]string{ 288 {"0.0.0.0", "0.0.0.0", "5678"}, 289 {"127.0.0.1", "127.0.0.1", "1234"}, 290 {"localhost", "127.0.0.1", "1235"}, 291 } 292 293 cmdArgs := []string{} 294 for _, hostDirective := range listeningPorts { 295 cmdArgs = append(cmdArgs, "--host", fmt.Sprintf("tcp://%s:%s", hostDirective[0], hostDirective[2])) 296 } 297 298 d := NewDaemon(c) 299 if err := d.StartWithBusybox(cmdArgs...); err != nil { 300 c.Fatalf("Could not start daemon with busybox: %v", err) 301 } 302 defer d.Stop() 303 304 for _, hostDirective := range listeningPorts { 305 output, err := d.Cmd("run", "-p", fmt.Sprintf("%s:%s:80", hostDirective[1], hostDirective[2]), "busybox", "true") 306 if err == nil { 307 c.Fatalf("Container should not start, expected port already allocated error: %q", output) 308 } else if !strings.Contains(output, "port is already allocated") { 309 c.Fatalf("Expected port is already allocated error: %q", output) 310 } 311 } 312 313 } 314 315 // #9629 316 func (s *DockerSuite) TestDaemonVolumesBindsRefs(c *check.C) { 317 d := NewDaemon(c) 318 319 if err := d.StartWithBusybox(); err != nil { 320 c.Fatal(err) 321 } 322 defer d.Stop() 323 324 tmp, err := ioutil.TempDir(os.TempDir(), "") 325 if err != nil { 326 c.Fatal(err) 327 } 328 defer os.RemoveAll(tmp) 329 330 if err := ioutil.WriteFile(tmp+"/test", []byte("testing"), 0655); err != nil { 331 c.Fatal(err) 332 } 333 334 if out, err := d.Cmd("create", "-v", tmp+":/foo", "--name=voltest", "busybox"); err != nil { 335 c.Fatal(err, out) 336 } 337 338 if err := d.Restart(); err != nil { 339 c.Fatal(err) 340 } 341 342 if out, err := d.Cmd("run", "--volumes-from=voltest", "--name=consumer", "busybox", "/bin/sh", "-c", "[ -f /foo/test ]"); err != nil { 343 c.Fatal(err, out) 344 } 345 346 } 347 348 func (s *DockerSuite) TestDaemonKeyGeneration(c *check.C) { 349 // TODO: skip or update for Windows daemon 350 os.Remove("/etc/docker/key.json") 351 d := NewDaemon(c) 352 if err := d.Start(); err != nil { 353 c.Fatalf("Could not start daemon: %v", err) 354 } 355 d.Stop() 356 357 k, err := libtrust.LoadKeyFile("/etc/docker/key.json") 358 if err != nil { 359 c.Fatalf("Error opening key file") 360 } 361 kid := k.KeyID() 362 // Test Key ID is a valid fingerprint (e.g. QQXN:JY5W:TBXI:MK3X:GX6P:PD5D:F56N:NHCS:LVRZ:JA46:R24J:XEFF) 363 if len(kid) != 59 { 364 c.Fatalf("Bad key ID: %s", kid) 365 } 366 367 } 368 369 func (s *DockerSuite) TestDaemonKeyMigration(c *check.C) { 370 // TODO: skip or update for Windows daemon 371 os.Remove("/etc/docker/key.json") 372 k1, err := libtrust.GenerateECP256PrivateKey() 373 if err != nil { 374 c.Fatalf("Error generating private key: %s", err) 375 } 376 if err := os.MkdirAll(filepath.Join(os.Getenv("HOME"), ".docker"), 0755); err != nil { 377 c.Fatalf("Error creating .docker directory: %s", err) 378 } 379 if err := libtrust.SaveKey(filepath.Join(os.Getenv("HOME"), ".docker", "key.json"), k1); err != nil { 380 c.Fatalf("Error saving private key: %s", err) 381 } 382 383 d := NewDaemon(c) 384 if err := d.Start(); err != nil { 385 c.Fatalf("Could not start daemon: %v", err) 386 } 387 d.Stop() 388 389 k2, err := libtrust.LoadKeyFile("/etc/docker/key.json") 390 if err != nil { 391 c.Fatalf("Error opening key file") 392 } 393 if k1.KeyID() != k2.KeyID() { 394 c.Fatalf("Key not migrated") 395 } 396 397 } 398 399 // Simulate an older daemon (pre 1.3) coming up with volumes specified in containers 400 // without corresponding volume json 401 func (s *DockerSuite) TestDaemonUpgradeWithVolumes(c *check.C) { 402 d := NewDaemon(c) 403 404 graphDir := filepath.Join(os.TempDir(), "docker-test") 405 defer os.RemoveAll(graphDir) 406 if err := d.StartWithBusybox("-g", graphDir); err != nil { 407 c.Fatal(err) 408 } 409 defer d.Stop() 410 411 tmpDir := filepath.Join(os.TempDir(), "test") 412 defer os.RemoveAll(tmpDir) 413 414 if out, err := d.Cmd("create", "-v", tmpDir+":/foo", "--name=test", "busybox"); err != nil { 415 c.Fatal(err, out) 416 } 417 418 if err := d.Stop(); err != nil { 419 c.Fatal(err) 420 } 421 422 // Remove this since we're expecting the daemon to re-create it too 423 if err := os.RemoveAll(tmpDir); err != nil { 424 c.Fatal(err) 425 } 426 427 configDir := filepath.Join(graphDir, "volumes") 428 429 if err := os.RemoveAll(configDir); err != nil { 430 c.Fatal(err) 431 } 432 433 if err := d.Start("-g", graphDir); err != nil { 434 c.Fatal(err) 435 } 436 437 if _, err := os.Stat(tmpDir); os.IsNotExist(err) { 438 c.Fatalf("expected volume path %s to exist but it does not", tmpDir) 439 } 440 441 dir, err := ioutil.ReadDir(configDir) 442 if err != nil { 443 c.Fatal(err) 444 } 445 if len(dir) == 0 { 446 c.Fatalf("expected volumes config dir to contain data for new volume") 447 } 448 449 // Now with just removing the volume config and not the volume data 450 if err := d.Stop(); err != nil { 451 c.Fatal(err) 452 } 453 454 if err := os.RemoveAll(configDir); err != nil { 455 c.Fatal(err) 456 } 457 458 if err := d.Start("-g", graphDir); err != nil { 459 c.Fatal(err) 460 } 461 462 dir, err = ioutil.ReadDir(configDir) 463 if err != nil { 464 c.Fatal(err) 465 } 466 467 if len(dir) == 0 { 468 c.Fatalf("expected volumes config dir to contain data for new volume") 469 } 470 471 } 472 473 // GH#11320 - verify that the daemon exits on failure properly 474 // Note that this explicitly tests the conflict of {-b,--bridge} and {--bip} options as the means 475 // to get a daemon init failure; no other tests for -b/--bip conflict are therefore required 476 func (s *DockerSuite) TestDaemonExitOnFailure(c *check.C) { 477 d := NewDaemon(c) 478 defer d.Stop() 479 480 //attempt to start daemon with incorrect flags (we know -b and --bip conflict) 481 if err := d.Start("--bridge", "nosuchbridge", "--bip", "1.1.1.1"); err != nil { 482 //verify we got the right error 483 if !strings.Contains(err.Error(), "Daemon exited and never started") { 484 c.Fatalf("Expected daemon not to start, got %v", err) 485 } 486 // look in the log and make sure we got the message that daemon is shutting down 487 runCmd := exec.Command("grep", "Error starting daemon", d.LogfileName()) 488 if out, _, err := runCommandWithOutput(runCmd); err != nil { 489 c.Fatalf("Expected 'Error starting daemon' message; but doesn't exist in log: %q, err: %v", out, err) 490 } 491 } else { 492 //if we didn't get an error and the daemon is running, this is a failure 493 d.Stop() 494 c.Fatal("Conflicting options should cause the daemon to error out with a failure") 495 } 496 497 } 498 499 func (s *DockerSuite) TestDaemonUlimitDefaults(c *check.C) { 500 testRequires(c, NativeExecDriver) 501 d := NewDaemon(c) 502 503 if err := d.StartWithBusybox("--default-ulimit", "nofile=42:42", "--default-ulimit", "nproc=1024:1024"); err != nil { 504 c.Fatal(err) 505 } 506 defer d.Stop() 507 508 out, err := d.Cmd("run", "--ulimit", "nproc=2048", "--name=test", "busybox", "/bin/sh", "-c", "echo $(ulimit -n); echo $(ulimit -p)") 509 if err != nil { 510 c.Fatal(out, err) 511 } 512 513 outArr := strings.Split(out, "\n") 514 if len(outArr) < 2 { 515 c.Fatalf("got unexpected output: %s", out) 516 } 517 nofile := strings.TrimSpace(outArr[0]) 518 nproc := strings.TrimSpace(outArr[1]) 519 520 if nofile != "42" { 521 c.Fatalf("expected `ulimit -n` to be `42`, got: %s", nofile) 522 } 523 if nproc != "2048" { 524 c.Fatalf("exepcted `ulimit -p` to be 2048, got: %s", nproc) 525 } 526 527 // Now restart daemon with a new default 528 if err := d.Restart("--default-ulimit", "nofile=43"); err != nil { 529 c.Fatal(err) 530 } 531 532 out, err = d.Cmd("start", "-a", "test") 533 if err != nil { 534 c.Fatal(err) 535 } 536 537 outArr = strings.Split(out, "\n") 538 if len(outArr) < 2 { 539 c.Fatalf("got unexpected output: %s", out) 540 } 541 nofile = strings.TrimSpace(outArr[0]) 542 nproc = strings.TrimSpace(outArr[1]) 543 544 if nofile != "43" { 545 c.Fatalf("expected `ulimit -n` to be `43`, got: %s", nofile) 546 } 547 if nproc != "2048" { 548 c.Fatalf("exepcted `ulimit -p` to be 2048, got: %s", nproc) 549 } 550 551 } 552 553 // #11315 554 func (s *DockerSuite) TestDaemonRestartRenameContainer(c *check.C) { 555 d := NewDaemon(c) 556 if err := d.StartWithBusybox(); err != nil { 557 c.Fatal(err) 558 } 559 defer d.Stop() 560 561 if out, err := d.Cmd("run", "--name=test", "busybox"); err != nil { 562 c.Fatal(err, out) 563 } 564 565 if out, err := d.Cmd("rename", "test", "test2"); err != nil { 566 c.Fatal(err, out) 567 } 568 569 if err := d.Restart(); err != nil { 570 c.Fatal(err) 571 } 572 573 if out, err := d.Cmd("start", "test2"); err != nil { 574 c.Fatal(err, out) 575 } 576 577 } 578 579 func (s *DockerSuite) TestDaemonLoggingDriverDefault(c *check.C) { 580 d := NewDaemon(c) 581 582 if err := d.StartWithBusybox(); err != nil { 583 c.Fatal(err) 584 } 585 defer d.Stop() 586 587 out, err := d.Cmd("run", "-d", "busybox", "echo", "testline") 588 if err != nil { 589 c.Fatal(out, err) 590 } 591 id := strings.TrimSpace(out) 592 593 if out, err := d.Cmd("wait", id); err != nil { 594 c.Fatal(out, err) 595 } 596 logPath := filepath.Join(d.folder, "graph", "containers", id, id+"-json.log") 597 598 if _, err := os.Stat(logPath); err != nil { 599 c.Fatal(err) 600 } 601 f, err := os.Open(logPath) 602 if err != nil { 603 c.Fatal(err) 604 } 605 var res struct { 606 Log string `json:"log"` 607 Stream string `json:"stream"` 608 Time time.Time `json:"time"` 609 } 610 if err := json.NewDecoder(f).Decode(&res); err != nil { 611 c.Fatal(err) 612 } 613 if res.Log != "testline\n" { 614 c.Fatalf("Unexpected log line: %q, expected: %q", res.Log, "testline\n") 615 } 616 if res.Stream != "stdout" { 617 c.Fatalf("Unexpected stream: %q, expected: %q", res.Stream, "stdout") 618 } 619 if !time.Now().After(res.Time) { 620 c.Fatalf("Log time %v in future", res.Time) 621 } 622 } 623 624 func (s *DockerSuite) TestDaemonLoggingDriverDefaultOverride(c *check.C) { 625 d := NewDaemon(c) 626 627 if err := d.StartWithBusybox(); err != nil { 628 c.Fatal(err) 629 } 630 defer d.Stop() 631 632 out, err := d.Cmd("run", "-d", "--log-driver=none", "busybox", "echo", "testline") 633 if err != nil { 634 c.Fatal(out, err) 635 } 636 id := strings.TrimSpace(out) 637 638 if out, err := d.Cmd("wait", id); err != nil { 639 c.Fatal(out, err) 640 } 641 logPath := filepath.Join(d.folder, "graph", "containers", id, id+"-json.log") 642 643 if _, err := os.Stat(logPath); err == nil || !os.IsNotExist(err) { 644 c.Fatalf("%s shouldn't exits, error on Stat: %s", logPath, err) 645 } 646 } 647 648 func (s *DockerSuite) TestDaemonLoggingDriverNone(c *check.C) { 649 d := NewDaemon(c) 650 651 if err := d.StartWithBusybox("--log-driver=none"); err != nil { 652 c.Fatal(err) 653 } 654 defer d.Stop() 655 656 out, err := d.Cmd("run", "-d", "busybox", "echo", "testline") 657 if err != nil { 658 c.Fatal(out, err) 659 } 660 id := strings.TrimSpace(out) 661 if out, err := d.Cmd("wait", id); err != nil { 662 c.Fatal(out, err) 663 } 664 665 logPath := filepath.Join(d.folder, "graph", "containers", id, id+"-json.log") 666 667 if _, err := os.Stat(logPath); err == nil || !os.IsNotExist(err) { 668 c.Fatalf("%s shouldn't exits, error on Stat: %s", logPath, err) 669 } 670 } 671 672 func (s *DockerSuite) TestDaemonLoggingDriverNoneOverride(c *check.C) { 673 d := NewDaemon(c) 674 675 if err := d.StartWithBusybox("--log-driver=none"); err != nil { 676 c.Fatal(err) 677 } 678 defer d.Stop() 679 680 out, err := d.Cmd("run", "-d", "--log-driver=json-file", "busybox", "echo", "testline") 681 if err != nil { 682 c.Fatal(out, err) 683 } 684 id := strings.TrimSpace(out) 685 686 if out, err := d.Cmd("wait", id); err != nil { 687 c.Fatal(out, err) 688 } 689 logPath := filepath.Join(d.folder, "graph", "containers", id, id+"-json.log") 690 691 if _, err := os.Stat(logPath); err != nil { 692 c.Fatal(err) 693 } 694 f, err := os.Open(logPath) 695 if err != nil { 696 c.Fatal(err) 697 } 698 var res struct { 699 Log string `json:"log"` 700 Stream string `json:"stream"` 701 Time time.Time `json:"time"` 702 } 703 if err := json.NewDecoder(f).Decode(&res); err != nil { 704 c.Fatal(err) 705 } 706 if res.Log != "testline\n" { 707 c.Fatalf("Unexpected log line: %q, expected: %q", res.Log, "testline\n") 708 } 709 if res.Stream != "stdout" { 710 c.Fatalf("Unexpected stream: %q, expected: %q", res.Stream, "stdout") 711 } 712 if !time.Now().After(res.Time) { 713 c.Fatalf("Log time %v in future", res.Time) 714 } 715 } 716 717 func (s *DockerSuite) TestDaemonLoggingDriverNoneLogsError(c *check.C) { 718 d := NewDaemon(c) 719 720 if err := d.StartWithBusybox("--log-driver=none"); err != nil { 721 c.Fatal(err) 722 } 723 defer d.Stop() 724 725 out, err := d.Cmd("run", "-d", "busybox", "echo", "testline") 726 if err != nil { 727 c.Fatal(out, err) 728 } 729 id := strings.TrimSpace(out) 730 out, err = d.Cmd("logs", id) 731 if err == nil { 732 c.Fatalf("Logs should fail with \"none\" driver") 733 } 734 if !strings.Contains(out, `\"logs\" command is supported only for \"json-file\" logging driver`) { 735 c.Fatalf("There should be error about non-json-file driver, got %s", out) 736 } 737 } 738 739 func (s *DockerSuite) TestDaemonDots(c *check.C) { 740 d := NewDaemon(c) 741 if err := d.StartWithBusybox(); err != nil { 742 c.Fatal(err) 743 } 744 defer d.Stop() 745 746 // Now create 4 containers 747 if _, err := d.Cmd("create", "busybox"); err != nil { 748 c.Fatalf("Error creating container: %q", err) 749 } 750 if _, err := d.Cmd("create", "busybox"); err != nil { 751 c.Fatalf("Error creating container: %q", err) 752 } 753 if _, err := d.Cmd("create", "busybox"); err != nil { 754 c.Fatalf("Error creating container: %q", err) 755 } 756 if _, err := d.Cmd("create", "busybox"); err != nil { 757 c.Fatalf("Error creating container: %q", err) 758 } 759 760 d.Stop() 761 762 d.Start("--log-level=debug") 763 d.Stop() 764 content, _ := ioutil.ReadFile(d.logFile.Name()) 765 if strings.Contains(string(content), "....") { 766 c.Fatalf("Debug level should not have ....\n%s", string(content)) 767 } 768 769 d.Start("--log-level=error") 770 d.Stop() 771 content, _ = ioutil.ReadFile(d.logFile.Name()) 772 if strings.Contains(string(content), "....") { 773 c.Fatalf("Error level should not have ....\n%s", string(content)) 774 } 775 776 d.Start("--log-level=info") 777 d.Stop() 778 content, _ = ioutil.ReadFile(d.logFile.Name()) 779 if !strings.Contains(string(content), "....") { 780 c.Fatalf("Info level should have ....\n%s", string(content)) 781 } 782 783 } 784 785 func (s *DockerSuite) TestDaemonUnixSockCleanedUp(c *check.C) { 786 d := NewDaemon(c) 787 dir, err := ioutil.TempDir("", "socket-cleanup-test") 788 if err != nil { 789 c.Fatal(err) 790 } 791 defer os.RemoveAll(dir) 792 793 sockPath := filepath.Join(dir, "docker.sock") 794 if err := d.Start("--host", "unix://"+sockPath); err != nil { 795 c.Fatal(err) 796 } 797 defer d.Stop() 798 799 if _, err := os.Stat(sockPath); err != nil { 800 c.Fatal("socket does not exist") 801 } 802 803 if err := d.Stop(); err != nil { 804 c.Fatal(err) 805 } 806 807 if _, err := os.Stat(sockPath); err == nil || !os.IsNotExist(err) { 808 c.Fatal("unix socket is not cleaned up") 809 } 810 811 } 812 813 func (s *DockerSuite) TestDaemonwithwrongkey(c *check.C) { 814 type Config struct { 815 Crv string `json:"crv"` 816 D string `json:"d"` 817 Kid string `json:"kid"` 818 Kty string `json:"kty"` 819 X string `json:"x"` 820 Y string `json:"y"` 821 } 822 823 os.Remove("/etc/docker/key.json") 824 d := NewDaemon(c) 825 if err := d.Start(); err != nil { 826 c.Fatalf("Failed to start daemon: %v", err) 827 } 828 829 if err := d.Stop(); err != nil { 830 c.Fatalf("Could not stop daemon: %v", err) 831 } 832 833 config := &Config{} 834 bytes, err := ioutil.ReadFile("/etc/docker/key.json") 835 if err != nil { 836 c.Fatalf("Error reading key.json file: %s", err) 837 } 838 839 // byte[] to Data-Struct 840 if err := json.Unmarshal(bytes, &config); err != nil { 841 c.Fatalf("Error Unmarshal: %s", err) 842 } 843 844 //replace config.Kid with the fake value 845 config.Kid = "VSAJ:FUYR:X3H2:B2VZ:KZ6U:CJD5:K7BX:ZXHY:UZXT:P4FT:MJWG:HRJ4" 846 847 // NEW Data-Struct to byte[] 848 newBytes, err := json.Marshal(&config) 849 if err != nil { 850 c.Fatalf("Error Marshal: %s", err) 851 } 852 853 // write back 854 if err := ioutil.WriteFile("/etc/docker/key.json", newBytes, 0400); err != nil { 855 c.Fatalf("Error ioutil.WriteFile: %s", err) 856 } 857 858 d1 := NewDaemon(c) 859 defer os.Remove("/etc/docker/key.json") 860 861 if err := d1.Start(); err == nil { 862 d1.Stop() 863 c.Fatalf("It should not be successful to start daemon with wrong key: %v", err) 864 } 865 866 content, _ := ioutil.ReadFile(d1.logFile.Name()) 867 868 if !strings.Contains(string(content), "Public Key ID does not match") { 869 c.Fatal("Missing KeyID message from daemon logs") 870 } 871 872 } 873 874 func (s *DockerSuite) TestDaemonRestartKillWait(c *check.C) { 875 d := NewDaemon(c) 876 if err := d.StartWithBusybox(); err != nil { 877 c.Fatalf("Could not start daemon with busybox: %v", err) 878 } 879 defer d.Stop() 880 881 out, err := d.Cmd("run", "-id", "busybox", "/bin/cat") 882 if err != nil { 883 c.Fatalf("Could not run /bin/cat: err=%v\n%s", err, out) 884 } 885 containerID := strings.TrimSpace(out) 886 887 if out, err := d.Cmd("kill", containerID); err != nil { 888 c.Fatalf("Could not kill %s: err=%v\n%s", containerID, err, out) 889 } 890 891 if err := d.Restart(); err != nil { 892 c.Fatalf("Could not restart daemon: %v", err) 893 } 894 895 errchan := make(chan error) 896 go func() { 897 if out, err := d.Cmd("wait", containerID); err != nil { 898 errchan <- fmt.Errorf("%v:\n%s", err, out) 899 } 900 close(errchan) 901 }() 902 903 select { 904 case <-time.After(5 * time.Second): 905 c.Fatal("Waiting on a stopped (killed) container timed out") 906 case err := <-errchan: 907 if err != nil { 908 c.Fatal(err) 909 } 910 } 911 912 } 913 914 // TestHttpsInfo connects via two-way authenticated HTTPS to the info endpoint 915 func (s *DockerSuite) TestHttpsInfo(c *check.C) { 916 const ( 917 testDaemonHttpsAddr = "localhost:4271" 918 ) 919 920 d := NewDaemon(c) 921 if err := d.Start("--tlsverify", "--tlscacert", "fixtures/https/ca.pem", "--tlscert", "fixtures/https/server-cert.pem", 922 "--tlskey", "fixtures/https/server-key.pem", "-H", testDaemonHttpsAddr); err != nil { 923 c.Fatalf("Could not start daemon with busybox: %v", err) 924 } 925 defer d.Stop() 926 927 //force tcp protocol 928 host := fmt.Sprintf("tcp://%s", testDaemonHttpsAddr) 929 daemonArgs := []string{"--host", host, "--tlsverify", "--tlscacert", "fixtures/https/ca.pem", "--tlscert", "fixtures/https/client-cert.pem", "--tlskey", "fixtures/https/client-key.pem"} 930 out, err := d.CmdWithArgs(daemonArgs, "info") 931 if err != nil { 932 c.Fatalf("Error Occurred: %s and output: %s", err, out) 933 } 934 } 935 936 // TestHttpsInfoRogueCert connects via two-way authenticated HTTPS to the info endpoint 937 // by using a rogue client certificate and checks that it fails with the expected error. 938 func (s *DockerSuite) TestHttpsInfoRogueCert(c *check.C) { 939 const ( 940 errBadCertificate = "remote error: bad certificate" 941 testDaemonHttpsAddr = "localhost:4271" 942 ) 943 d := NewDaemon(c) 944 if err := d.Start("--tlsverify", "--tlscacert", "fixtures/https/ca.pem", "--tlscert", "fixtures/https/server-cert.pem", 945 "--tlskey", "fixtures/https/server-key.pem", "-H", testDaemonHttpsAddr); err != nil { 946 c.Fatalf("Could not start daemon with busybox: %v", err) 947 } 948 defer d.Stop() 949 950 //force tcp protocol 951 host := fmt.Sprintf("tcp://%s", testDaemonHttpsAddr) 952 daemonArgs := []string{"--host", host, "--tlsverify", "--tlscacert", "fixtures/https/ca.pem", "--tlscert", "fixtures/https/client-rogue-cert.pem", "--tlskey", "fixtures/https/client-rogue-key.pem"} 953 out, err := d.CmdWithArgs(daemonArgs, "info") 954 if err == nil || !strings.Contains(out, errBadCertificate) { 955 c.Fatalf("Expected err: %s, got instead: %s and output: %s", errBadCertificate, err, out) 956 } 957 } 958 959 // TestHttpsInfoRogueServerCert connects via two-way authenticated HTTPS to the info endpoint 960 // which provides a rogue server certificate and checks that it fails with the expected error 961 func (s *DockerSuite) TestHttpsInfoRogueServerCert(c *check.C) { 962 const ( 963 errCaUnknown = "x509: certificate signed by unknown authority" 964 testDaemonRogueHttpsAddr = "localhost:4272" 965 ) 966 d := NewDaemon(c) 967 if err := d.Start("--tlsverify", "--tlscacert", "fixtures/https/ca.pem", "--tlscert", "fixtures/https/server-rogue-cert.pem", 968 "--tlskey", "fixtures/https/server-rogue-key.pem", "-H", testDaemonRogueHttpsAddr); err != nil { 969 c.Fatalf("Could not start daemon with busybox: %v", err) 970 } 971 defer d.Stop() 972 973 //force tcp protocol 974 host := fmt.Sprintf("tcp://%s", testDaemonRogueHttpsAddr) 975 daemonArgs := []string{"--host", host, "--tlsverify", "--tlscacert", "fixtures/https/ca.pem", "--tlscert", "fixtures/https/client-rogue-cert.pem", "--tlskey", "fixtures/https/client-rogue-key.pem"} 976 out, err := d.CmdWithArgs(daemonArgs, "info") 977 if err == nil || !strings.Contains(out, errCaUnknown) { 978 c.Fatalf("Expected err: %s, got instead: %s and output: %s", errCaUnknown, err, out) 979 } 980 }