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 }