github.com/damirazo/docker@v1.9.0/integration-cli/docker_cli_create_test.go (about)

     1  package main
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"os"
     7  	"reflect"
     8  	"strings"
     9  	"time"
    10  
    11  	"os/exec"
    12  
    13  	"io/ioutil"
    14  
    15  	"github.com/docker/docker/pkg/nat"
    16  	"github.com/go-check/check"
    17  )
    18  
    19  // Make sure we can create a simple container with some args
    20  func (s *DockerSuite) TestCreateArgs(c *check.C) {
    21  	testRequires(c, DaemonIsLinux)
    22  	out, _ := dockerCmd(c, "create", "busybox", "command", "arg1", "arg2", "arg with space")
    23  
    24  	cleanedContainerID := strings.TrimSpace(out)
    25  
    26  	out, _ = dockerCmd(c, "inspect", cleanedContainerID)
    27  
    28  	containers := []struct {
    29  		ID      string
    30  		Created time.Time
    31  		Path    string
    32  		Args    []string
    33  		Image   string
    34  	}{}
    35  	if err := json.Unmarshal([]byte(out), &containers); err != nil {
    36  		c.Fatalf("Error inspecting the container: %s", err)
    37  	}
    38  	if len(containers) != 1 {
    39  		c.Fatalf("Unexpected container count. Expected 0, received: %d", len(containers))
    40  	}
    41  
    42  	cont := containers[0]
    43  	if cont.Path != "command" {
    44  		c.Fatalf("Unexpected container path. Expected command, received: %s", cont.Path)
    45  	}
    46  
    47  	b := false
    48  	expected := []string{"arg1", "arg2", "arg with space"}
    49  	for i, arg := range expected {
    50  		if arg != cont.Args[i] {
    51  			b = true
    52  			break
    53  		}
    54  	}
    55  	if len(cont.Args) != len(expected) || b {
    56  		c.Fatalf("Unexpected args. Expected %v, received: %v", expected, cont.Args)
    57  	}
    58  
    59  }
    60  
    61  // Make sure we can set hostconfig options too
    62  func (s *DockerSuite) TestCreateHostConfig(c *check.C) {
    63  	testRequires(c, DaemonIsLinux)
    64  	out, _ := dockerCmd(c, "create", "-P", "busybox", "echo")
    65  
    66  	cleanedContainerID := strings.TrimSpace(out)
    67  
    68  	out, _ = dockerCmd(c, "inspect", cleanedContainerID)
    69  
    70  	containers := []struct {
    71  		HostConfig *struct {
    72  			PublishAllPorts bool
    73  		}
    74  	}{}
    75  	if err := json.Unmarshal([]byte(out), &containers); err != nil {
    76  		c.Fatalf("Error inspecting the container: %s", err)
    77  	}
    78  	if len(containers) != 1 {
    79  		c.Fatalf("Unexpected container count. Expected 0, received: %d", len(containers))
    80  	}
    81  
    82  	cont := containers[0]
    83  	if cont.HostConfig == nil {
    84  		c.Fatalf("Expected HostConfig, got none")
    85  	}
    86  
    87  	if !cont.HostConfig.PublishAllPorts {
    88  		c.Fatalf("Expected PublishAllPorts, got false")
    89  	}
    90  
    91  }
    92  
    93  func (s *DockerSuite) TestCreateWithPortRange(c *check.C) {
    94  	testRequires(c, DaemonIsLinux)
    95  	out, _ := dockerCmd(c, "create", "-p", "3300-3303:3300-3303/tcp", "busybox", "echo")
    96  
    97  	cleanedContainerID := strings.TrimSpace(out)
    98  
    99  	out, _ = dockerCmd(c, "inspect", cleanedContainerID)
   100  
   101  	containers := []struct {
   102  		HostConfig *struct {
   103  			PortBindings map[nat.Port][]nat.PortBinding
   104  		}
   105  	}{}
   106  	if err := json.Unmarshal([]byte(out), &containers); err != nil {
   107  		c.Fatalf("Error inspecting the container: %s", err)
   108  	}
   109  	if len(containers) != 1 {
   110  		c.Fatalf("Unexpected container count. Expected 0, received: %d", len(containers))
   111  	}
   112  
   113  	cont := containers[0]
   114  	if cont.HostConfig == nil {
   115  		c.Fatalf("Expected HostConfig, got none")
   116  	}
   117  
   118  	if len(cont.HostConfig.PortBindings) != 4 {
   119  		c.Fatalf("Expected 4 ports bindings, got %d", len(cont.HostConfig.PortBindings))
   120  	}
   121  	for k, v := range cont.HostConfig.PortBindings {
   122  		if len(v) != 1 {
   123  			c.Fatalf("Expected 1 ports binding, for the port  %s but found %s", k, v)
   124  		}
   125  		if k.Port() != v[0].HostPort {
   126  			c.Fatalf("Expected host port %s to match published port %s", k.Port(), v[0].HostPort)
   127  		}
   128  	}
   129  
   130  }
   131  
   132  func (s *DockerSuite) TestCreateWithiLargePortRange(c *check.C) {
   133  	testRequires(c, DaemonIsLinux)
   134  	out, _ := dockerCmd(c, "create", "-p", "1-65535:1-65535/tcp", "busybox", "echo")
   135  
   136  	cleanedContainerID := strings.TrimSpace(out)
   137  
   138  	out, _ = dockerCmd(c, "inspect", cleanedContainerID)
   139  
   140  	containers := []struct {
   141  		HostConfig *struct {
   142  			PortBindings map[nat.Port][]nat.PortBinding
   143  		}
   144  	}{}
   145  	if err := json.Unmarshal([]byte(out), &containers); err != nil {
   146  		c.Fatalf("Error inspecting the container: %s", err)
   147  	}
   148  	if len(containers) != 1 {
   149  		c.Fatalf("Unexpected container count. Expected 0, received: %d", len(containers))
   150  	}
   151  
   152  	cont := containers[0]
   153  	if cont.HostConfig == nil {
   154  		c.Fatalf("Expected HostConfig, got none")
   155  	}
   156  
   157  	if len(cont.HostConfig.PortBindings) != 65535 {
   158  		c.Fatalf("Expected 65535 ports bindings, got %d", len(cont.HostConfig.PortBindings))
   159  	}
   160  	for k, v := range cont.HostConfig.PortBindings {
   161  		if len(v) != 1 {
   162  			c.Fatalf("Expected 1 ports binding, for the port  %s but found %s", k, v)
   163  		}
   164  		if k.Port() != v[0].HostPort {
   165  			c.Fatalf("Expected host port %s to match published port %s", k.Port(), v[0].HostPort)
   166  		}
   167  	}
   168  
   169  }
   170  
   171  // "test123" should be printed by docker create + start
   172  func (s *DockerSuite) TestCreateEchoStdout(c *check.C) {
   173  	testRequires(c, DaemonIsLinux)
   174  
   175  	out, _ := dockerCmd(c, "create", "busybox", "echo", "test123")
   176  
   177  	cleanedContainerID := strings.TrimSpace(out)
   178  
   179  	out, _ = dockerCmd(c, "start", "-ai", cleanedContainerID)
   180  
   181  	if out != "test123\n" {
   182  		c.Errorf("container should've printed 'test123', got %q", out)
   183  	}
   184  
   185  }
   186  
   187  func (s *DockerSuite) TestCreateVolumesCreated(c *check.C) {
   188  	testRequires(c, DaemonIsLinux)
   189  	testRequires(c, SameHostDaemon)
   190  
   191  	name := "test_create_volume"
   192  	dockerCmd(c, "create", "--name", name, "-v", "/foo", "busybox")
   193  
   194  	dir, err := inspectMountSourceField(name, "/foo")
   195  	if err != nil {
   196  		c.Fatalf("Error getting volume host path: %q", err)
   197  	}
   198  
   199  	if _, err := os.Stat(dir); err != nil && os.IsNotExist(err) {
   200  		c.Fatalf("Volume was not created")
   201  	}
   202  	if err != nil {
   203  		c.Fatalf("Error statting volume host path: %q", err)
   204  	}
   205  
   206  }
   207  
   208  func (s *DockerSuite) TestCreateLabels(c *check.C) {
   209  	testRequires(c, DaemonIsLinux)
   210  	name := "test_create_labels"
   211  	expected := map[string]string{"k1": "v1", "k2": "v2"}
   212  	dockerCmd(c, "create", "--name", name, "-l", "k1=v1", "--label", "k2=v2", "busybox")
   213  
   214  	actual := make(map[string]string)
   215  	err := inspectFieldAndMarshall(name, "Config.Labels", &actual)
   216  	if err != nil {
   217  		c.Fatal(err)
   218  	}
   219  
   220  	if !reflect.DeepEqual(expected, actual) {
   221  		c.Fatalf("Expected %s got %s", expected, actual)
   222  	}
   223  }
   224  
   225  func (s *DockerSuite) TestCreateLabelFromImage(c *check.C) {
   226  	testRequires(c, DaemonIsLinux)
   227  	imageName := "testcreatebuildlabel"
   228  	_, err := buildImage(imageName,
   229  		`FROM busybox
   230  		LABEL k1=v1 k2=v2`,
   231  		true)
   232  	if err != nil {
   233  		c.Fatal(err)
   234  	}
   235  
   236  	name := "test_create_labels_from_image"
   237  	expected := map[string]string{"k2": "x", "k3": "v3", "k1": "v1"}
   238  	dockerCmd(c, "create", "--name", name, "-l", "k2=x", "--label", "k3=v3", imageName)
   239  
   240  	actual := make(map[string]string)
   241  	err = inspectFieldAndMarshall(name, "Config.Labels", &actual)
   242  	if err != nil {
   243  		c.Fatal(err)
   244  	}
   245  
   246  	if !reflect.DeepEqual(expected, actual) {
   247  		c.Fatalf("Expected %s got %s", expected, actual)
   248  	}
   249  }
   250  
   251  func (s *DockerSuite) TestCreateHostnameWithNumber(c *check.C) {
   252  	testRequires(c, DaemonIsLinux)
   253  	out, _ := dockerCmd(c, "run", "-h", "web.0", "busybox", "hostname")
   254  	if strings.TrimSpace(out) != "web.0" {
   255  		c.Fatalf("hostname not set, expected `web.0`, got: %s", out)
   256  	}
   257  }
   258  
   259  func (s *DockerSuite) TestCreateRM(c *check.C) {
   260  	testRequires(c, DaemonIsLinux)
   261  	// Test to make sure we can 'rm' a new container that is in
   262  	// "Created" state, and has ever been run. Test "rm -f" too.
   263  
   264  	// create a container
   265  	out, _ := dockerCmd(c, "create", "busybox")
   266  	cID := strings.TrimSpace(out)
   267  
   268  	dockerCmd(c, "rm", cID)
   269  
   270  	// Now do it again so we can "rm -f" this time
   271  	out, _ = dockerCmd(c, "create", "busybox")
   272  
   273  	cID = strings.TrimSpace(out)
   274  	dockerCmd(c, "rm", "-f", cID)
   275  }
   276  
   277  func (s *DockerSuite) TestCreateModeIpcContainer(c *check.C) {
   278  	testRequires(c, DaemonIsLinux)
   279  	testRequires(c, SameHostDaemon, NotUserNamespace)
   280  
   281  	out, _ := dockerCmd(c, "create", "busybox")
   282  	id := strings.TrimSpace(out)
   283  
   284  	dockerCmd(c, "create", fmt.Sprintf("--ipc=container:%s", id), "busybox")
   285  }
   286  
   287  func (s *DockerTrustSuite) TestTrustedCreate(c *check.C) {
   288  	repoName := s.setupTrustedImage(c, "trusted-create")
   289  
   290  	// Try create
   291  	createCmd := exec.Command(dockerBinary, "create", repoName)
   292  	s.trustedCmd(createCmd)
   293  	out, _, err := runCommandWithOutput(createCmd)
   294  	if err != nil {
   295  		c.Fatalf("Error running trusted create: %s\n%s", err, out)
   296  	}
   297  
   298  	if !strings.Contains(string(out), "Tagging") {
   299  		c.Fatalf("Missing expected output on trusted push:\n%s", out)
   300  	}
   301  
   302  	dockerCmd(c, "rmi", repoName)
   303  
   304  	// Try untrusted create to ensure we pushed the tag to the registry
   305  	createCmd = exec.Command(dockerBinary, "create", "--disable-content-trust=true", repoName)
   306  	s.trustedCmd(createCmd)
   307  	out, _, err = runCommandWithOutput(createCmd)
   308  	if err != nil {
   309  		c.Fatalf("Error running trusted create: %s\n%s", err, out)
   310  	}
   311  
   312  	if !strings.Contains(string(out), "Status: Downloaded") {
   313  		c.Fatalf("Missing expected output on trusted create with --disable-content-trust:\n%s", out)
   314  	}
   315  }
   316  
   317  func (s *DockerTrustSuite) TestUntrustedCreate(c *check.C) {
   318  	repoName := fmt.Sprintf("%v/dockercli/trusted:latest", privateRegistryURL)
   319  	// tag the image and upload it to the private registry
   320  	dockerCmd(c, "tag", "busybox", repoName)
   321  	dockerCmd(c, "push", repoName)
   322  	dockerCmd(c, "rmi", repoName)
   323  
   324  	// Try trusted create on untrusted tag
   325  	createCmd := exec.Command(dockerBinary, "create", repoName)
   326  	s.trustedCmd(createCmd)
   327  	out, _, err := runCommandWithOutput(createCmd)
   328  	if err == nil {
   329  		c.Fatalf("Error expected when running trusted create with:\n%s", out)
   330  	}
   331  
   332  	if !strings.Contains(string(out), "no trust data available") {
   333  		c.Fatalf("Missing expected output on trusted create:\n%s", out)
   334  	}
   335  }
   336  
   337  func (s *DockerTrustSuite) TestTrustedIsolatedCreate(c *check.C) {
   338  	repoName := s.setupTrustedImage(c, "trusted-isolated-create")
   339  
   340  	// Try create
   341  	createCmd := exec.Command(dockerBinary, "--config", "/tmp/docker-isolated-create", "create", repoName)
   342  	s.trustedCmd(createCmd)
   343  	out, _, err := runCommandWithOutput(createCmd)
   344  	if err != nil {
   345  		c.Fatalf("Error running trusted create: %s\n%s", err, out)
   346  	}
   347  
   348  	if !strings.Contains(string(out), "Tagging") {
   349  		c.Fatalf("Missing expected output on trusted push:\n%s", out)
   350  	}
   351  
   352  	dockerCmd(c, "rmi", repoName)
   353  }
   354  
   355  func (s *DockerTrustSuite) TestCreateWhenCertExpired(c *check.C) {
   356  	c.Skip("Currently changes system time, causing instability")
   357  	repoName := s.setupTrustedImage(c, "trusted-create-expired")
   358  
   359  	// Certificates have 10 years of expiration
   360  	elevenYearsFromNow := time.Now().Add(time.Hour * 24 * 365 * 11)
   361  
   362  	runAtDifferentDate(elevenYearsFromNow, func() {
   363  		// Try create
   364  		createCmd := exec.Command(dockerBinary, "create", repoName)
   365  		s.trustedCmd(createCmd)
   366  		out, _, err := runCommandWithOutput(createCmd)
   367  		if err == nil {
   368  			c.Fatalf("Error running trusted create in the distant future: %s\n%s", err, out)
   369  		}
   370  
   371  		if !strings.Contains(string(out), "could not validate the path to a trusted root") {
   372  			c.Fatalf("Missing expected output on trusted create in the distant future:\n%s", out)
   373  		}
   374  	})
   375  
   376  	runAtDifferentDate(elevenYearsFromNow, func() {
   377  		// Try create
   378  		createCmd := exec.Command(dockerBinary, "create", "--disable-content-trust", repoName)
   379  		s.trustedCmd(createCmd)
   380  		out, _, err := runCommandWithOutput(createCmd)
   381  		if err != nil {
   382  			c.Fatalf("Error running untrusted create in the distant future: %s\n%s", err, out)
   383  		}
   384  
   385  		if !strings.Contains(string(out), "Status: Downloaded") {
   386  			c.Fatalf("Missing expected output on untrusted create in the distant future:\n%s", out)
   387  		}
   388  	})
   389  }
   390  
   391  func (s *DockerTrustSuite) TestTrustedCreateFromBadTrustServer(c *check.C) {
   392  	repoName := fmt.Sprintf("%v/dockerclievilcreate/trusted:latest", privateRegistryURL)
   393  	evilLocalConfigDir, err := ioutil.TempDir("", "evil-local-config-dir")
   394  	if err != nil {
   395  		c.Fatalf("Failed to create local temp dir")
   396  	}
   397  
   398  	// tag the image and upload it to the private registry
   399  	dockerCmd(c, "tag", "busybox", repoName)
   400  
   401  	pushCmd := exec.Command(dockerBinary, "push", repoName)
   402  	s.trustedCmd(pushCmd)
   403  	out, _, err := runCommandWithOutput(pushCmd)
   404  	if err != nil {
   405  		c.Fatalf("Error creating trusted push: %s\n%s", err, out)
   406  	}
   407  	if !strings.Contains(string(out), "Signing and pushing trust metadata") {
   408  		c.Fatalf("Missing expected output on trusted push:\n%s", out)
   409  	}
   410  
   411  	dockerCmd(c, "rmi", repoName)
   412  
   413  	// Try create
   414  	createCmd := exec.Command(dockerBinary, "create", repoName)
   415  	s.trustedCmd(createCmd)
   416  	out, _, err = runCommandWithOutput(createCmd)
   417  	if err != nil {
   418  		c.Fatalf("Error creating trusted create: %s\n%s", err, out)
   419  	}
   420  
   421  	if !strings.Contains(string(out), "Tagging") {
   422  		c.Fatalf("Missing expected output on trusted push:\n%s", out)
   423  	}
   424  
   425  	dockerCmd(c, "rmi", repoName)
   426  
   427  	// Kill the notary server, start a new "evil" one.
   428  	s.not.Close()
   429  	s.not, err = newTestNotary(c)
   430  	if err != nil {
   431  		c.Fatalf("Restarting notary server failed.")
   432  	}
   433  
   434  	// In order to make an evil server, lets re-init a client (with a different trust dir) and push new data.
   435  	// tag an image and upload it to the private registry
   436  	dockerCmd(c, "--config", evilLocalConfigDir, "tag", "busybox", repoName)
   437  
   438  	// Push up to the new server
   439  	pushCmd = exec.Command(dockerBinary, "--config", evilLocalConfigDir, "push", repoName)
   440  	s.trustedCmd(pushCmd)
   441  	out, _, err = runCommandWithOutput(pushCmd)
   442  	if err != nil {
   443  		c.Fatalf("Error creating trusted push: %s\n%s", err, out)
   444  	}
   445  	if !strings.Contains(string(out), "Signing and pushing trust metadata") {
   446  		c.Fatalf("Missing expected output on trusted push:\n%s", out)
   447  	}
   448  
   449  	// Now, try creating with the original client from this new trust server. This should fail.
   450  	createCmd = exec.Command(dockerBinary, "create", repoName)
   451  	s.trustedCmd(createCmd)
   452  	out, _, err = runCommandWithOutput(createCmd)
   453  	if err == nil {
   454  		c.Fatalf("Expected to fail on this create due to different remote data: %s\n%s", err, out)
   455  	}
   456  
   457  	if !strings.Contains(string(out), "failed to validate data with current trusted certificates") {
   458  		c.Fatalf("Missing expected output on trusted push:\n%s", out)
   459  	}
   460  }
   461  
   462  func (s *DockerSuite) TestCreateStopSignal(c *check.C) {
   463  	name := "test_create_stop_signal"
   464  	dockerCmd(c, "create", "--name", name, "--stop-signal", "9", "busybox")
   465  
   466  	res, err := inspectFieldJSON(name, "Config.StopSignal")
   467  	c.Assert(err, check.IsNil)
   468  
   469  	if res != `"9"` {
   470  		c.Fatalf("Expected 9, got %s", res)
   471  	}
   472  }