github.com/yp-engineering/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 }