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