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  }