Browse code

Merge pull request #20774 from hqhq/hq_vender_engine_api

Vendor engine-api to 70d266e96080e3c3d63c55a4d8659e00ac1f7e6c

Sebastiaan van Stijn authored on 2016/03/01 02:48:55
Showing 35 changed files
... ...
@@ -310,20 +310,20 @@ func run(b *Builder, args []string, attributes map[string]bool, original string)
310 310
 	}
311 311
 
312 312
 	config := &container.Config{
313
-		Cmd:   strslice.New(args...),
313
+		Cmd:   strslice.StrSlice(args),
314 314
 		Image: b.image,
315 315
 	}
316 316
 
317 317
 	// stash the cmd
318 318
 	cmd := b.runConfig.Cmd
319
-	if b.runConfig.Entrypoint.Len() == 0 && b.runConfig.Cmd.Len() == 0 {
319
+	if len(b.runConfig.Entrypoint) == 0 && len(b.runConfig.Cmd) == 0 {
320 320
 		b.runConfig.Cmd = config.Cmd
321 321
 	}
322 322
 
323 323
 	// stash the config environment
324 324
 	env := b.runConfig.Env
325 325
 
326
-	defer func(cmd *strslice.StrSlice) { b.runConfig.Cmd = cmd }(cmd)
326
+	defer func(cmd strslice.StrSlice) { b.runConfig.Cmd = cmd }(cmd)
327 327
 	defer func(env []string) { b.runConfig.Env = env }(env)
328 328
 
329 329
 	// derive the net build-time environment for this run. We let config
... ...
@@ -366,7 +366,7 @@ func run(b *Builder, args []string, attributes map[string]bool, original string)
366 366
 	if len(cmdBuildEnv) > 0 {
367 367
 		sort.Strings(cmdBuildEnv)
368 368
 		tmpEnv := append([]string{fmt.Sprintf("|%d", len(cmdBuildEnv))}, cmdBuildEnv...)
369
-		saveCmd = strslice.New(append(tmpEnv, saveCmd.Slice()...)...)
369
+		saveCmd = strslice.StrSlice(append(tmpEnv, saveCmd...))
370 370
 	}
371 371
 
372 372
 	b.runConfig.Cmd = saveCmd
... ...
@@ -424,7 +424,7 @@ func cmd(b *Builder, args []string, attributes map[string]bool, original string)
424 424
 		}
425 425
 	}
426 426
 
427
-	b.runConfig.Cmd = strslice.New(cmdSlice...)
427
+	b.runConfig.Cmd = strslice.StrSlice(cmdSlice)
428 428
 
429 429
 	if err := b.commit("", b.runConfig.Cmd, fmt.Sprintf("CMD %q", cmdSlice)); err != nil {
430 430
 		return err
... ...
@@ -455,16 +455,16 @@ func entrypoint(b *Builder, args []string, attributes map[string]bool, original
455 455
 	switch {
456 456
 	case attributes["json"]:
457 457
 		// ENTRYPOINT ["echo", "hi"]
458
-		b.runConfig.Entrypoint = strslice.New(parsed...)
458
+		b.runConfig.Entrypoint = strslice.StrSlice(parsed)
459 459
 	case len(parsed) == 0:
460 460
 		// ENTRYPOINT []
461 461
 		b.runConfig.Entrypoint = nil
462 462
 	default:
463 463
 		// ENTRYPOINT echo hi
464 464
 		if runtime.GOOS != "windows" {
465
-			b.runConfig.Entrypoint = strslice.New("/bin/sh", "-c", parsed[0])
465
+			b.runConfig.Entrypoint = strslice.StrSlice{"/bin/sh", "-c", parsed[0]}
466 466
 		} else {
467
-			b.runConfig.Entrypoint = strslice.New("cmd", "/S", "/C", parsed[0])
467
+			b.runConfig.Entrypoint = strslice.StrSlice{"cmd", "/S", "/C", parsed[0]}
468 468
 		}
469 469
 	}
470 470
 
... ...
@@ -37,7 +37,7 @@ import (
37 37
 	"github.com/docker/engine-api/types/strslice"
38 38
 )
39 39
 
40
-func (b *Builder) commit(id string, autoCmd *strslice.StrSlice, comment string) error {
40
+func (b *Builder) commit(id string, autoCmd strslice.StrSlice, comment string) error {
41 41
 	if b.disableCommit {
42 42
 		return nil
43 43
 	}
... ...
@@ -48,11 +48,11 @@ func (b *Builder) commit(id string, autoCmd *strslice.StrSlice, comment string)
48 48
 	if id == "" {
49 49
 		cmd := b.runConfig.Cmd
50 50
 		if runtime.GOOS != "windows" {
51
-			b.runConfig.Cmd = strslice.New("/bin/sh", "-c", "#(nop) "+comment)
51
+			b.runConfig.Cmd = strslice.StrSlice{"/bin/sh", "-c", "#(nop) " + comment}
52 52
 		} else {
53
-			b.runConfig.Cmd = strslice.New("cmd", "/S /C", "REM (nop) "+comment)
53
+			b.runConfig.Cmd = strslice.StrSlice{"cmd", "/S /C", "REM (nop) " + comment}
54 54
 		}
55
-		defer func(cmd *strslice.StrSlice) { b.runConfig.Cmd = cmd }(cmd)
55
+		defer func(cmd strslice.StrSlice) { b.runConfig.Cmd = cmd }(cmd)
56 56
 
57 57
 		hit, err := b.probeCache()
58 58
 		if err != nil {
... ...
@@ -171,11 +171,11 @@ func (b *Builder) runContextCommand(args []string, allowRemote bool, allowLocalD
171 171
 
172 172
 	cmd := b.runConfig.Cmd
173 173
 	if runtime.GOOS != "windows" {
174
-		b.runConfig.Cmd = strslice.New("/bin/sh", "-c", fmt.Sprintf("#(nop) %s %s in %s", cmdName, srcHash, dest))
174
+		b.runConfig.Cmd = strslice.StrSlice{"/bin/sh", "-c", fmt.Sprintf("#(nop) %s %s in %s", cmdName, srcHash, dest)}
175 175
 	} else {
176
-		b.runConfig.Cmd = strslice.New("cmd", "/S", "/C", fmt.Sprintf("REM (nop) %s %s in %s", cmdName, srcHash, dest))
176
+		b.runConfig.Cmd = strslice.StrSlice{"cmd", "/S", "/C", fmt.Sprintf("REM (nop) %s %s in %s", cmdName, srcHash, dest)}
177 177
 	}
178
-	defer func(cmd *strslice.StrSlice) { b.runConfig.Cmd = cmd }(cmd)
178
+	defer func(cmd strslice.StrSlice) { b.runConfig.Cmd = cmd }(cmd)
179 179
 
180 180
 	if hit, err := b.probeCache(); err != nil {
181 181
 		return err
... ...
@@ -527,9 +527,9 @@ func (b *Builder) create() (string, error) {
527 527
 	b.tmpContainers[c.ID] = struct{}{}
528 528
 	fmt.Fprintf(b.Stdout, " ---> Running in %s\n", stringid.TruncateID(c.ID))
529 529
 
530
-	if config.Cmd.Len() > 0 {
530
+	if len(config.Cmd) > 0 {
531 531
 		// override the entry point that may have been picked up from the base image
532
-		if err := b.docker.ContainerUpdateCmdOnBuild(c.ID, config.Cmd.Slice()); err != nil {
532
+		if err := b.docker.ContainerUpdateCmdOnBuild(c.ID, config.Cmd); err != nil {
533 533
 			return "", err
534 534
 		}
535 535
 	}
... ...
@@ -567,7 +567,7 @@ func (b *Builder) run(cID string) (err error) {
567 567
 	if ret, _ := b.docker.ContainerWait(cID, -1); ret != 0 {
568 568
 		// TODO: change error type, because jsonmessage.JSONError assumes HTTP
569 569
 		return &jsonmessage.JSONError{
570
-			Message: fmt.Sprintf("The command '%s' returned a non-zero code: %d", b.runConfig.Cmd.ToString(), ret),
570
+			Message: fmt.Sprintf("The command '%s' returned a non-zero code: %d", strings.Join(b.runConfig.Cmd, " "), ret),
571 571
 			Code:    ret,
572 572
 		}
573 573
 	}
... ...
@@ -70,8 +70,8 @@ func merge(userConf, imageConf *containertypes.Config) error {
70 70
 		userConf.Labels = imageConf.Labels
71 71
 	}
72 72
 
73
-	if userConf.Entrypoint.Len() == 0 {
74
-		if userConf.Cmd.Len() == 0 {
73
+	if len(userConf.Entrypoint) == 0 {
74
+		if len(userConf.Cmd) == 0 {
75 75
 			userConf.Cmd = imageConf.Cmd
76 76
 		}
77 77
 
... ...
@@ -151,7 +151,7 @@ func (daemon *Daemon) Commit(name string, c *types.ContainerCommitConfig) (strin
151 151
 	h := image.History{
152 152
 		Author:     c.Author,
153 153
 		Created:    time.Now().UTC(),
154
-		CreatedBy:  strings.Join(container.Config.Cmd.Slice(), " "),
154
+		CreatedBy:  strings.Join(container.Config.Cmd, " "),
155 155
 		Comment:    c.Comment,
156 156
 		EmptyLayer: true,
157 157
 	}
... ...
@@ -257,8 +257,8 @@ func (daemon *Daemon) populateCommand(c *container.Container, env []string) erro
257 257
 		AllowedDevices:     allowedDevices,
258 258
 		AppArmorProfile:    c.AppArmorProfile,
259 259
 		AutoCreatedDevices: autoCreatedDevices,
260
-		CapAdd:             c.HostConfig.CapAdd.Slice(),
261
-		CapDrop:            c.HostConfig.CapDrop.Slice(),
260
+		CapAdd:             c.HostConfig.CapAdd,
261
+		CapDrop:            c.HostConfig.CapDrop,
262 262
 		CgroupParent:       defaultCgroupParent,
263 263
 		GIDMapping:         gidMap,
264 264
 		GroupAdd:           c.HostConfig.GroupAdd,
... ...
@@ -412,7 +412,7 @@ func (daemon *Daemon) mergeAndVerifyConfig(config *containertypes.Config, img *i
412 412
 			return err
413 413
 		}
414 414
 	}
415
-	if config.Entrypoint.Len() == 0 && config.Cmd.Len() == 0 {
415
+	if len(config.Entrypoint) == 0 && len(config.Cmd) == 0 {
416 416
 		return fmt.Errorf("No command specified")
417 417
 	}
418 418
 	return nil
... ...
@@ -495,13 +495,11 @@ func (daemon *Daemon) generateHostname(id string, config *containertypes.Config)
495 495
 	}
496 496
 }
497 497
 
498
-func (daemon *Daemon) getEntrypointAndArgs(configEntrypoint *strslice.StrSlice, configCmd *strslice.StrSlice) (string, []string) {
499
-	cmdSlice := configCmd.Slice()
500
-	if configEntrypoint.Len() != 0 {
501
-		eSlice := configEntrypoint.Slice()
502
-		return eSlice[0], append(eSlice[1:], cmdSlice...)
498
+func (daemon *Daemon) getEntrypointAndArgs(configEntrypoint strslice.StrSlice, configCmd strslice.StrSlice) (string, []string) {
499
+	if len(configEntrypoint) != 0 {
500
+		return configEntrypoint[0], append(configEntrypoint[1:], configCmd...)
503 501
 	}
504
-	return cmdSlice[0], cmdSlice[1:]
502
+	return configCmd[0], configCmd[1:]
505 503
 }
506 504
 
507 505
 func (daemon *Daemon) newContainer(name string, config *containertypes.Config, imgID image.ID) (*container.Container, error) {
... ...
@@ -93,8 +93,8 @@ func (d *Daemon) ContainerExecCreate(config *types.ExecConfig) (string, error) {
93 93
 		return "", err
94 94
 	}
95 95
 
96
-	cmd := strslice.New(config.Cmd...)
97
-	entrypoint, args := d.getEntrypointAndArgs(strslice.New(), cmd)
96
+	cmd := strslice.StrSlice(config.Cmd)
97
+	entrypoint, args := d.getEntrypointAndArgs(strslice.StrSlice{}, cmd)
98 98
 
99 99
 	keys := []byte{}
100 100
 	if config.DetachKeys != "" {
... ...
@@ -24,7 +24,7 @@ clone git golang.org/x/net 47990a1ba55743e6ef1affd3a14e5bac8553615d https://gith
24 24
 clone git golang.org/x/sys eb2c74142fd19a79b3f237334c7384d5167b1b46 https://github.com/golang/sys.git
25 25
 clone git github.com/docker/go-units 651fc226e7441360384da338d0fd37f2440ffbe3
26 26
 clone git github.com/docker/go-connections v0.2.0
27
-clone git github.com/docker/engine-api 575694d38967b53e06cafe8b722c72892dd64db0
27
+clone git github.com/docker/engine-api 70d266e96080e3c3d63c55a4d8659e00ac1f7e6c
28 28
 clone git github.com/RackSec/srslog 6eb773f331e46fbba8eecb8e794e635e75fc04de
29 29
 clone git github.com/imdario/mergo 0.2.1
30 30
 
... ...
@@ -31,7 +31,7 @@ func HistoryFromConfig(imageJSON []byte, emptyLayer bool) (image.History, error)
31 31
 	return image.History{
32 32
 		Author:     v1Image.Author,
33 33
 		Created:    v1Image.Created,
34
-		CreatedBy:  strings.Join(v1Image.ContainerConfig.Cmd.Slice(), " "),
34
+		CreatedBy:  strings.Join(v1Image.ContainerConfig.Cmd, " "),
35 35
 		Comment:    v1Image.Comment,
36 36
 		EmptyLayer: emptyLayer,
37 37
 	}, nil
... ...
@@ -532,7 +532,7 @@ func (s *DockerSuite) TestContainerApiCommit(c *check.C) {
532 532
 	c.Assert(json.Unmarshal(b, &img), checker.IsNil)
533 533
 
534 534
 	cmd := inspectField(c, img.ID, "Config.Cmd")
535
-	c.Assert(cmd, checker.Equals, "{[/bin/sh -c touch /test]}", check.Commentf("got wrong Cmd from commit: %q", cmd))
535
+	c.Assert(cmd, checker.Equals, "[/bin/sh -c touch /test]", check.Commentf("got wrong Cmd from commit: %q", cmd))
536 536
 
537 537
 	// sanity check, make sure the image is what we think it is
538 538
 	dockerCmd(c, "run", img.ID, "ls", "/test")
... ...
@@ -564,7 +564,7 @@ func (s *DockerSuite) TestContainerApiCommitWithLabelInConfig(c *check.C) {
564 564
 	c.Assert(label2, checker.Equals, "value2")
565 565
 
566 566
 	cmd := inspectField(c, img.ID, "Config.Cmd")
567
-	c.Assert(cmd, checker.Equals, "{[/bin/sh -c touch /test]}", check.Commentf("got wrong Cmd from commit: %q", cmd))
567
+	c.Assert(cmd, checker.Equals, "[/bin/sh -c touch /test]", check.Commentf("got wrong Cmd from commit: %q", cmd))
568 568
 
569 569
 	// sanity check, make sure the image is what we think it is
570 570
 	dockerCmd(c, "run", img.ID, "ls", "/test")
... ...
@@ -2230,7 +2230,7 @@ func (s *DockerSuite) TestBuildContextCleanupFailedBuild(c *check.C) {
2230 2230
 func (s *DockerSuite) TestBuildCmd(c *check.C) {
2231 2231
 	name := "testbuildcmd"
2232 2232
 
2233
-	expected := "{[/bin/echo Hello World]}"
2233
+	expected := "[/bin/echo Hello World]"
2234 2234
 	_, err := buildImage(name,
2235 2235
 		`FROM `+minimalBaseImage()+`
2236 2236
         CMD ["/bin/echo", "Hello World"]`,
... ...
@@ -2362,7 +2362,7 @@ func (s *DockerSuite) TestBuildEmptyEntrypointInheritance(c *check.C) {
2362 2362
 	}
2363 2363
 	res := inspectField(c, name, "Config.Entrypoint")
2364 2364
 
2365
-	expected := "{[/bin/echo]}"
2365
+	expected := "[/bin/echo]"
2366 2366
 	if res != expected {
2367 2367
 		c.Fatalf("Entrypoint %s, expected %s", res, expected)
2368 2368
 	}
... ...
@@ -2376,7 +2376,7 @@ func (s *DockerSuite) TestBuildEmptyEntrypointInheritance(c *check.C) {
2376 2376
 	}
2377 2377
 	res = inspectField(c, name2, "Config.Entrypoint")
2378 2378
 
2379
-	expected = "{[]}"
2379
+	expected = "[]"
2380 2380
 
2381 2381
 	if res != expected {
2382 2382
 		c.Fatalf("Entrypoint %s, expected %s", res, expected)
... ...
@@ -2386,7 +2386,7 @@ func (s *DockerSuite) TestBuildEmptyEntrypointInheritance(c *check.C) {
2386 2386
 
2387 2387
 func (s *DockerSuite) TestBuildEmptyEntrypoint(c *check.C) {
2388 2388
 	name := "testbuildentrypoint"
2389
-	expected := "{[]}"
2389
+	expected := "[]"
2390 2390
 
2391 2391
 	_, err := buildImage(name,
2392 2392
 		`FROM busybox
... ...
@@ -2405,7 +2405,7 @@ func (s *DockerSuite) TestBuildEmptyEntrypoint(c *check.C) {
2405 2405
 func (s *DockerSuite) TestBuildEntrypoint(c *check.C) {
2406 2406
 	name := "testbuildentrypoint"
2407 2407
 
2408
-	expected := "{[/bin/echo]}"
2408
+	expected := "[/bin/echo]"
2409 2409
 	_, err := buildImage(name,
2410 2410
 		`FROM `+minimalBaseImage()+`
2411 2411
         ENTRYPOINT ["/bin/echo"]`,
... ...
@@ -3087,7 +3087,7 @@ func (s *DockerSuite) TestBuildEntrypointRunCleanup(c *check.C) {
3087 3087
 	}
3088 3088
 	res := inspectField(c, name, "Config.Cmd")
3089 3089
 	// Cmd must be cleaned up
3090
-	if res != "<nil>" {
3090
+	if res != "[]" {
3091 3091
 		c.Fatalf("Cmd %s, expected nil", res)
3092 3092
 	}
3093 3093
 }
... ...
@@ -3164,7 +3164,7 @@ func (s *DockerSuite) TestBuildInheritance(c *check.C) {
3164 3164
 	}
3165 3165
 
3166 3166
 	res := inspectField(c, name, "Config.Entrypoint")
3167
-	if expected := "{[/bin/echo]}"; res != expected {
3167
+	if expected := "[/bin/echo]"; res != expected {
3168 3168
 		c.Fatalf("Entrypoint %s, expected %s", res, expected)
3169 3169
 	}
3170 3170
 	ports2 := inspectField(c, name, "Config.ExposedPorts")
... ...
@@ -4367,12 +4367,12 @@ func (s *DockerSuite) TestBuildCleanupCmdOnEntrypoint(c *check.C) {
4367 4367
 		c.Fatal(err)
4368 4368
 	}
4369 4369
 	res := inspectField(c, name, "Config.Cmd")
4370
-	if res != "<nil>" {
4370
+	if res != "[]" {
4371 4371
 		c.Fatalf("Cmd %s, expected nil", res)
4372 4372
 	}
4373 4373
 
4374 4374
 	res = inspectField(c, name, "Config.Entrypoint")
4375
-	if expected := "{[cat]}"; res != expected {
4375
+	if expected := "[cat]"; res != expected {
4376 4376
 		c.Fatalf("Entrypoint %s, expected %s", res, expected)
4377 4377
 	}
4378 4378
 }
... ...
@@ -129,9 +129,9 @@ func (s *DockerSuite) TestCommitChange(c *check.C) {
129 129
 		"Config.ExposedPorts": "map[8080/tcp:{}]",
130 130
 		"Config.Env":          "[DEBUG=true test=1 PATH=/foo]",
131 131
 		"Config.Labels":       "map[foo:bar]",
132
-		"Config.Cmd":          "{[/bin/sh]}",
132
+		"Config.Cmd":          "[/bin/sh]",
133 133
 		"Config.WorkingDir":   "/opt",
134
-		"Config.Entrypoint":   "{[/bin/sh]}",
134
+		"Config.Entrypoint":   "[/bin/sh]",
135 135
 		"Config.User":         "testuser",
136 136
 		"Config.Volumes":      "map[/var/lib/docker:{}]",
137 137
 		"Config.OnBuild":      "[/usr/local/bin/python-build --dir /app/src]",
... ...
@@ -17,19 +17,17 @@ func Compare(a, b *container.Config) bool {
17 17
 		return false
18 18
 	}
19 19
 
20
-	if a.Cmd.Len() != b.Cmd.Len() ||
20
+	if len(a.Cmd) != len(b.Cmd) ||
21 21
 		len(a.Env) != len(b.Env) ||
22 22
 		len(a.Labels) != len(b.Labels) ||
23 23
 		len(a.ExposedPorts) != len(b.ExposedPorts) ||
24
-		a.Entrypoint.Len() != b.Entrypoint.Len() ||
24
+		len(a.Entrypoint) != len(b.Entrypoint) ||
25 25
 		len(a.Volumes) != len(b.Volumes) {
26 26
 		return false
27 27
 	}
28 28
 
29
-	aCmd := a.Cmd.Slice()
30
-	bCmd := b.Cmd.Slice()
31
-	for i := 0; i < len(aCmd); i++ {
32
-		if aCmd[i] != bCmd[i] {
29
+	for i := 0; i < len(a.Cmd); i++ {
30
+		if a.Cmd[i] != b.Cmd[i] {
33 31
 			return false
34 32
 		}
35 33
 	}
... ...
@@ -49,10 +47,8 @@ func Compare(a, b *container.Config) bool {
49 49
 		}
50 50
 	}
51 51
 
52
-	aEntrypoint := a.Entrypoint.Slice()
53
-	bEntrypoint := b.Entrypoint.Slice()
54
-	for i := 0; i < len(aEntrypoint); i++ {
55
-		if aEntrypoint[i] != bEntrypoint[i] {
52
+	for i := 0; i < len(a.Entrypoint); i++ {
53
+		if a.Entrypoint[i] != b.Entrypoint[i] {
56 54
 			return false
57 55
 		}
58 56
 	}
... ...
@@ -34,12 +34,12 @@ func TestCompare(t *testing.T) {
34 34
 	volumes3["/test3"] = struct{}{}
35 35
 	envs1 := []string{"ENV1=value1", "ENV2=value2"}
36 36
 	envs2 := []string{"ENV1=value1", "ENV3=value3"}
37
-	entrypoint1 := strslice.New("/bin/sh", "-c")
38
-	entrypoint2 := strslice.New("/bin/sh", "-d")
39
-	entrypoint3 := strslice.New("/bin/sh", "-c", "echo")
40
-	cmd1 := strslice.New("/bin/sh", "-c")
41
-	cmd2 := strslice.New("/bin/sh", "-d")
42
-	cmd3 := strslice.New("/bin/sh", "-c", "echo")
37
+	entrypoint1 := strslice.StrSlice{"/bin/sh", "-c"}
38
+	entrypoint2 := strslice.StrSlice{"/bin/sh", "-d"}
39
+	entrypoint3 := strslice.StrSlice{"/bin/sh", "-c", "echo"}
40
+	cmd1 := strslice.StrSlice{"/bin/sh", "-c"}
41
+	cmd2 := strslice.StrSlice{"/bin/sh", "-d"}
42
+	cmd3 := strslice.StrSlice{"/bin/sh", "-c", "echo"}
43 43
 	labels1 := map[string]string{"LABEL1": "value1", "LABEL2": "value2"}
44 44
 	labels2 := map[string]string{"LABEL1": "value1", "LABEL2": "value3"}
45 45
 	labels3 := map[string]string{"LABEL1": "value1", "LABEL2": "value2", "LABEL3": "value3"}
... ...
@@ -16,7 +16,7 @@ import (
16 16
 
17 17
 type f struct {
18 18
 	file       string
19
-	entrypoint *strslice.StrSlice
19
+	entrypoint strslice.StrSlice
20 20
 }
21 21
 
22 22
 func TestDecodeContainerConfig(t *testing.T) {
... ...
@@ -29,14 +29,14 @@ func TestDecodeContainerConfig(t *testing.T) {
29 29
 	if runtime.GOOS != "windows" {
30 30
 		image = "ubuntu"
31 31
 		fixtures = []f{
32
-			{"fixtures/unix/container_config_1_14.json", strslice.New()},
33
-			{"fixtures/unix/container_config_1_17.json", strslice.New("bash")},
34
-			{"fixtures/unix/container_config_1_19.json", strslice.New("bash")},
32
+			{"fixtures/unix/container_config_1_14.json", strslice.StrSlice{}},
33
+			{"fixtures/unix/container_config_1_17.json", strslice.StrSlice{"bash"}},
34
+			{"fixtures/unix/container_config_1_19.json", strslice.StrSlice{"bash"}},
35 35
 		}
36 36
 	} else {
37 37
 		image = "windows"
38 38
 		fixtures = []f{
39
-			{"fixtures/windows/container_config_1_19.json", strslice.New("cmd")},
39
+			{"fixtures/windows/container_config_1_19.json", strslice.StrSlice{"cmd"}},
40 40
 		}
41 41
 	}
42 42
 
... ...
@@ -55,7 +55,7 @@ func TestDecodeContainerConfig(t *testing.T) {
55 55
 			t.Fatalf("Expected %s image, found %s\n", image, c.Image)
56 56
 		}
57 57
 
58
-		if c.Entrypoint.Len() != f.entrypoint.Len() {
58
+		if len(c.Entrypoint) != len(f.entrypoint) {
59 59
 			t.Fatalf("Expected %v, found %v\n", f.entrypoint, c.Entrypoint)
60 60
 		}
61 61
 
... ...
@@ -190,11 +190,11 @@ func TestDecodeHostConfig(t *testing.T) {
190 190
 			t.Fatalf("Expected 1 bind, found %d\n", l)
191 191
 		}
192 192
 
193
-		if c.CapAdd.Len() != 1 && c.CapAdd.Slice()[0] != "NET_ADMIN" {
193
+		if len(c.CapAdd) != 1 && c.CapAdd[0] != "NET_ADMIN" {
194 194
 			t.Fatalf("Expected CapAdd NET_ADMIN, got %v", c.CapAdd)
195 195
 		}
196 196
 
197
-		if c.CapDrop.Len() != 1 && c.CapDrop.Slice()[0] != "NET_ADMIN" {
197
+		if len(c.CapDrop) != 1 && c.CapDrop[0] != "NET_ADMIN" {
198 198
 			t.Fatalf("Expected CapDrop MKNOD, got %v", c.CapDrop)
199 199
 		}
200 200
 	}
... ...
@@ -228,15 +228,15 @@ func Parse(cmd *flag.FlagSet, args []string) (*container.Config, *container.Host
228 228
 
229 229
 	var (
230 230
 		parsedArgs = cmd.Args()
231
-		runCmd     *strslice.StrSlice
232
-		entrypoint *strslice.StrSlice
231
+		runCmd     strslice.StrSlice
232
+		entrypoint strslice.StrSlice
233 233
 		image      = cmd.Arg(0)
234 234
 	)
235 235
 	if len(parsedArgs) > 1 {
236
-		runCmd = strslice.New(parsedArgs[1:]...)
236
+		runCmd = strslice.StrSlice(parsedArgs[1:])
237 237
 	}
238 238
 	if *flEntrypoint != "" {
239
-		entrypoint = strslice.New(*flEntrypoint)
239
+		entrypoint = strslice.StrSlice{*flEntrypoint}
240 240
 	}
241 241
 
242 242
 	var (
... ...
@@ -402,8 +402,8 @@ func Parse(cmd *flag.FlagSet, args []string) (*container.Config, *container.Host
402 402
 		IpcMode:        ipcMode,
403 403
 		PidMode:        pidMode,
404 404
 		UTSMode:        utsMode,
405
-		CapAdd:         strslice.New(flCapAdd.GetAll()...),
406
-		CapDrop:        strslice.New(flCapDrop.GetAll()...),
405
+		CapAdd:         strslice.StrSlice(flCapAdd.GetAll()),
406
+		CapDrop:        strslice.StrSlice(flCapDrop.GetAll()),
407 407
 		GroupAdd:       flGroupAdd.GetAll(),
408 408
 		RestartPolicy:  restartPolicy,
409 409
 		SecurityOpt:    securityOpts,
... ...
@@ -648,7 +648,7 @@ func TestParseEntryPoint(t *testing.T) {
648 648
 	if err != nil {
649 649
 		t.Fatal(err)
650 650
 	}
651
-	if config.Entrypoint.Len() != 1 && config.Entrypoint.Slice()[0] != "anything" {
651
+	if len(config.Entrypoint) != 1 && config.Entrypoint[0] != "anything" {
652 652
 		t.Fatalf("Expected entrypoint 'anything', got %v", config.Entrypoint)
653 653
 	}
654 654
 }
655 655
deleted file mode 100644
... ...
@@ -1,86 +0,0 @@
1
-package client
2
-
3
-import (
4
-	"encoding/json"
5
-	"net/http"
6
-	"net/url"
7
-
8
-	"github.com/docker/engine-api/types"
9
-	"github.com/docker/engine-api/types/filters"
10
-	"github.com/docker/engine-api/types/network"
11
-)
12
-
13
-// NetworkCreate creates a new network in the docker host.
14
-func (cli *Client) NetworkCreate(options types.NetworkCreate) (types.NetworkCreateResponse, error) {
15
-	var response types.NetworkCreateResponse
16
-	serverResp, err := cli.post("/networks/create", nil, options, nil)
17
-	if err != nil {
18
-		return response, err
19
-	}
20
-
21
-	json.NewDecoder(serverResp.body).Decode(&response)
22
-	ensureReaderClosed(serverResp)
23
-	return response, err
24
-}
25
-
26
-// NetworkRemove removes an existent network from the docker host.
27
-func (cli *Client) NetworkRemove(networkID string) error {
28
-	resp, err := cli.delete("/networks/"+networkID, nil, nil)
29
-	ensureReaderClosed(resp)
30
-	return err
31
-}
32
-
33
-// NetworkConnect connects a container to an existent network in the docker host.
34
-func (cli *Client) NetworkConnect(networkID, containerID string, config *network.EndpointSettings) error {
35
-	nc := types.NetworkConnect{
36
-		Container:      containerID,
37
-		EndpointConfig: config,
38
-	}
39
-	resp, err := cli.post("/networks/"+networkID+"/connect", nil, nc, nil)
40
-	ensureReaderClosed(resp)
41
-	return err
42
-}
43
-
44
-// NetworkDisconnect disconnects a container from an existent network in the docker host.
45
-func (cli *Client) NetworkDisconnect(networkID, containerID string, force bool) error {
46
-	nd := types.NetworkDisconnect{Container: containerID, Force: force}
47
-	resp, err := cli.post("/networks/"+networkID+"/disconnect", nil, nd, nil)
48
-	ensureReaderClosed(resp)
49
-	return err
50
-}
51
-
52
-// NetworkList returns the list of networks configured in the docker host.
53
-func (cli *Client) NetworkList(options types.NetworkListOptions) ([]types.NetworkResource, error) {
54
-	query := url.Values{}
55
-	if options.Filters.Len() > 0 {
56
-		filterJSON, err := filters.ToParam(options.Filters)
57
-		if err != nil {
58
-			return nil, err
59
-		}
60
-
61
-		query.Set("filters", filterJSON)
62
-	}
63
-	var networkResources []types.NetworkResource
64
-	resp, err := cli.get("/networks", query, nil)
65
-	if err != nil {
66
-		return networkResources, err
67
-	}
68
-	err = json.NewDecoder(resp.body).Decode(&networkResources)
69
-	ensureReaderClosed(resp)
70
-	return networkResources, err
71
-}
72
-
73
-// NetworkInspect returns the information for a specific network configured in the docker host.
74
-func (cli *Client) NetworkInspect(networkID string) (types.NetworkResource, error) {
75
-	var networkResource types.NetworkResource
76
-	resp, err := cli.get("/networks/"+networkID, nil, nil)
77
-	if err != nil {
78
-		if resp.statusCode == http.StatusNotFound {
79
-			return networkResource, networkNotFoundError{networkID}
80
-		}
81
-		return networkResource, err
82
-	}
83
-	err = json.NewDecoder(resp.body).Decode(&networkResource)
84
-	ensureReaderClosed(resp)
85
-	return networkResource, err
86
-}
87 1
new file mode 100644
... ...
@@ -0,0 +1,17 @@
0
+package client
1
+
2
+import (
3
+	"github.com/docker/engine-api/types"
4
+	"github.com/docker/engine-api/types/network"
5
+)
6
+
7
+// NetworkConnect connects a container to an existent network in the docker host.
8
+func (cli *Client) NetworkConnect(networkID, containerID string, config *network.EndpointSettings) error {
9
+	nc := types.NetworkConnect{
10
+		Container:      containerID,
11
+		EndpointConfig: config,
12
+	}
13
+	resp, err := cli.post("/networks/"+networkID+"/connect", nil, nc, nil)
14
+	ensureReaderClosed(resp)
15
+	return err
16
+}
0 17
new file mode 100644
... ...
@@ -0,0 +1,20 @@
0
+package client
1
+
2
+import (
3
+	"encoding/json"
4
+
5
+	"github.com/docker/engine-api/types"
6
+)
7
+
8
+// NetworkCreate creates a new network in the docker host.
9
+func (cli *Client) NetworkCreate(options types.NetworkCreate) (types.NetworkCreateResponse, error) {
10
+	var response types.NetworkCreateResponse
11
+	serverResp, err := cli.post("/networks/create", nil, options, nil)
12
+	if err != nil {
13
+		return response, err
14
+	}
15
+
16
+	json.NewDecoder(serverResp.body).Decode(&response)
17
+	ensureReaderClosed(serverResp)
18
+	return response, err
19
+}
0 20
new file mode 100644
... ...
@@ -0,0 +1,13 @@
0
+package client
1
+
2
+import (
3
+	"github.com/docker/engine-api/types"
4
+)
5
+
6
+// NetworkDisconnect disconnects a container from an existent network in the docker host.
7
+func (cli *Client) NetworkDisconnect(networkID, containerID string, force bool) error {
8
+	nd := types.NetworkDisconnect{Container: containerID, Force: force}
9
+	resp, err := cli.post("/networks/"+networkID+"/disconnect", nil, nd, nil)
10
+	ensureReaderClosed(resp)
11
+	return err
12
+}
0 13
new file mode 100644
... ...
@@ -0,0 +1,23 @@
0
+package client
1
+
2
+import (
3
+	"encoding/json"
4
+	"net/http"
5
+
6
+	"github.com/docker/engine-api/types"
7
+)
8
+
9
+// NetworkInspect returns the information for a specific network configured in the docker host.
10
+func (cli *Client) NetworkInspect(networkID string) (types.NetworkResource, error) {
11
+	var networkResource types.NetworkResource
12
+	resp, err := cli.get("/networks/"+networkID, nil, nil)
13
+	if err != nil {
14
+		if resp.statusCode == http.StatusNotFound {
15
+			return networkResource, networkNotFoundError{networkID}
16
+		}
17
+		return networkResource, err
18
+	}
19
+	err = json.NewDecoder(resp.body).Decode(&networkResource)
20
+	ensureReaderClosed(resp)
21
+	return networkResource, err
22
+}
0 23
new file mode 100644
... ...
@@ -0,0 +1,30 @@
0
+package client
1
+
2
+import (
3
+	"encoding/json"
4
+	"net/url"
5
+
6
+	"github.com/docker/engine-api/types"
7
+	"github.com/docker/engine-api/types/filters"
8
+)
9
+
10
+// NetworkList returns the list of networks configured in the docker host.
11
+func (cli *Client) NetworkList(options types.NetworkListOptions) ([]types.NetworkResource, error) {
12
+	query := url.Values{}
13
+	if options.Filters.Len() > 0 {
14
+		filterJSON, err := filters.ToParam(options.Filters)
15
+		if err != nil {
16
+			return nil, err
17
+		}
18
+
19
+		query.Set("filters", filterJSON)
20
+	}
21
+	var networkResources []types.NetworkResource
22
+	resp, err := cli.get("/networks", query, nil)
23
+	if err != nil {
24
+		return networkResources, err
25
+	}
26
+	err = json.NewDecoder(resp.body).Decode(&networkResources)
27
+	ensureReaderClosed(resp)
28
+	return networkResources, err
29
+}
0 30
new file mode 100644
... ...
@@ -0,0 +1,8 @@
0
+package client
1
+
2
+// NetworkRemove removes an existent network from the docker host.
3
+func (cli *Client) NetworkRemove(networkID string) error {
4
+	resp, err := cli.delete("/networks/"+networkID, nil, nil)
5
+	ensureReaderClosed(resp)
6
+	return err
7
+}
0 8
deleted file mode 100644
... ...
@@ -1,66 +0,0 @@
1
-package client
2
-
3
-import (
4
-	"encoding/json"
5
-	"net/http"
6
-	"net/url"
7
-
8
-	"github.com/docker/engine-api/types"
9
-	"github.com/docker/engine-api/types/filters"
10
-)
11
-
12
-// VolumeList returns the volumes configured in the docker host.
13
-func (cli *Client) VolumeList(filter filters.Args) (types.VolumesListResponse, error) {
14
-	var volumes types.VolumesListResponse
15
-	query := url.Values{}
16
-
17
-	if filter.Len() > 0 {
18
-		filterJSON, err := filters.ToParam(filter)
19
-		if err != nil {
20
-			return volumes, err
21
-		}
22
-		query.Set("filters", filterJSON)
23
-	}
24
-	resp, err := cli.get("/volumes", query, nil)
25
-	if err != nil {
26
-		return volumes, err
27
-	}
28
-
29
-	err = json.NewDecoder(resp.body).Decode(&volumes)
30
-	ensureReaderClosed(resp)
31
-	return volumes, err
32
-}
33
-
34
-// VolumeInspect returns the information about a specific volume in the docker host.
35
-func (cli *Client) VolumeInspect(volumeID string) (types.Volume, error) {
36
-	var volume types.Volume
37
-	resp, err := cli.get("/volumes/"+volumeID, nil, nil)
38
-	if err != nil {
39
-		if resp.statusCode == http.StatusNotFound {
40
-			return volume, volumeNotFoundError{volumeID}
41
-		}
42
-		return volume, err
43
-	}
44
-	err = json.NewDecoder(resp.body).Decode(&volume)
45
-	ensureReaderClosed(resp)
46
-	return volume, err
47
-}
48
-
49
-// VolumeCreate creates a volume in the docker host.
50
-func (cli *Client) VolumeCreate(options types.VolumeCreateRequest) (types.Volume, error) {
51
-	var volume types.Volume
52
-	resp, err := cli.post("/volumes/create", nil, options, nil)
53
-	if err != nil {
54
-		return volume, err
55
-	}
56
-	err = json.NewDecoder(resp.body).Decode(&volume)
57
-	ensureReaderClosed(resp)
58
-	return volume, err
59
-}
60
-
61
-// VolumeRemove removes a volume from the docker host.
62
-func (cli *Client) VolumeRemove(volumeID string) error {
63
-	resp, err := cli.delete("/volumes/"+volumeID, nil, nil)
64
-	ensureReaderClosed(resp)
65
-	return err
66
-}
67 1
new file mode 100644
... ...
@@ -0,0 +1,19 @@
0
+package client
1
+
2
+import (
3
+	"encoding/json"
4
+
5
+	"github.com/docker/engine-api/types"
6
+)
7
+
8
+// VolumeCreate creates a volume in the docker host.
9
+func (cli *Client) VolumeCreate(options types.VolumeCreateRequest) (types.Volume, error) {
10
+	var volume types.Volume
11
+	resp, err := cli.post("/volumes/create", nil, options, nil)
12
+	if err != nil {
13
+		return volume, err
14
+	}
15
+	err = json.NewDecoder(resp.body).Decode(&volume)
16
+	ensureReaderClosed(resp)
17
+	return volume, err
18
+}
0 19
new file mode 100644
... ...
@@ -0,0 +1,23 @@
0
+package client
1
+
2
+import (
3
+	"encoding/json"
4
+	"net/http"
5
+
6
+	"github.com/docker/engine-api/types"
7
+)
8
+
9
+// VolumeInspect returns the information about a specific volume in the docker host.
10
+func (cli *Client) VolumeInspect(volumeID string) (types.Volume, error) {
11
+	var volume types.Volume
12
+	resp, err := cli.get("/volumes/"+volumeID, nil, nil)
13
+	if err != nil {
14
+		if resp.statusCode == http.StatusNotFound {
15
+			return volume, volumeNotFoundError{volumeID}
16
+		}
17
+		return volume, err
18
+	}
19
+	err = json.NewDecoder(resp.body).Decode(&volume)
20
+	ensureReaderClosed(resp)
21
+	return volume, err
22
+}
0 23
new file mode 100644
... ...
@@ -0,0 +1,31 @@
0
+package client
1
+
2
+import (
3
+	"encoding/json"
4
+	"net/url"
5
+
6
+	"github.com/docker/engine-api/types"
7
+	"github.com/docker/engine-api/types/filters"
8
+)
9
+
10
+// VolumeList returns the volumes configured in the docker host.
11
+func (cli *Client) VolumeList(filter filters.Args) (types.VolumesListResponse, error) {
12
+	var volumes types.VolumesListResponse
13
+	query := url.Values{}
14
+
15
+	if filter.Len() > 0 {
16
+		filterJSON, err := filters.ToParam(filter)
17
+		if err != nil {
18
+			return volumes, err
19
+		}
20
+		query.Set("filters", filterJSON)
21
+	}
22
+	resp, err := cli.get("/volumes", query, nil)
23
+	if err != nil {
24
+		return volumes, err
25
+	}
26
+
27
+	err = json.NewDecoder(resp.body).Decode(&volumes)
28
+	ensureReaderClosed(resp)
29
+	return volumes, err
30
+}
0 31
new file mode 100644
... ...
@@ -0,0 +1,8 @@
0
+package client
1
+
2
+// VolumeRemove removes a volume from the docker host.
3
+func (cli *Client) VolumeRemove(volumeID string) error {
4
+	resp, err := cli.delete("/volumes/"+volumeID, nil, nil)
5
+	ensureReaderClosed(resp)
6
+	return err
7
+}
... ...
@@ -2,10 +2,15 @@ package types
2 2
 
3 3
 // AuthConfig contains authorization information for connecting to a Registry
4 4
 type AuthConfig struct {
5
-	Username      string `json:"username,omitempty"`
6
-	Password      string `json:"password,omitempty"`
7
-	Auth          string `json:"auth,omitempty"`
8
-	Email         string `json:"email"`
5
+	Username string `json:"username,omitempty"`
6
+	Password string `json:"password,omitempty"`
7
+	Auth     string `json:"auth,omitempty"`
8
+
9
+	// Email is an optional value associated with the username.
10
+	// This field is deprecated and will be removed in a later
11
+	// version of docker.
12
+	Email string `json:"email,omitempty"`
13
+
9 14
 	ServerAddress string `json:"serveraddress,omitempty"`
10 15
 	RegistryToken string `json:"registrytoken,omitempty"`
11 16
 }
... ...
@@ -24,12 +24,12 @@ type Config struct {
24 24
 	OpenStdin       bool                  // Open stdin
25 25
 	StdinOnce       bool                  // If true, close stdin after the 1 attached client disconnects.
26 26
 	Env             []string              // List of environment variable to set in the container
27
-	Cmd             *strslice.StrSlice    // Command to run when starting the container
27
+	Cmd             strslice.StrSlice     // Command to run when starting the container
28 28
 	ArgsEscaped     bool                  `json:",omitempty"` // True if command is already escaped (Windows specific)
29 29
 	Image           string                // Name of the image as it was passed by the operator (eg. could be symbolic)
30 30
 	Volumes         map[string]struct{}   // List of volumes (mounts) used for the container
31 31
 	WorkingDir      string                // Current directory (PWD) in the command will be launched
32
-	Entrypoint      *strslice.StrSlice    // Entrypoint to run when starting the container
32
+	Entrypoint      strslice.StrSlice     // Entrypoint to run when starting the container
33 33
 	NetworkDisabled bool                  `json:",omitempty"` // Is network disabled
34 34
 	MacAddress      string                `json:",omitempty"` // Mac Address of the container
35 35
 	OnBuild         []string              // ONBUILD metadata that were defined on the image Dockerfile
... ...
@@ -213,24 +213,24 @@ type HostConfig struct {
213 213
 	VolumesFrom     []string      // List of volumes to take from other container
214 214
 
215 215
 	// Applicable to UNIX platforms
216
-	CapAdd          *strslice.StrSlice // List of kernel capabilities to add to the container
217
-	CapDrop         *strslice.StrSlice // List of kernel capabilities to remove from the container
218
-	DNS             []string           `json:"Dns"`        // List of DNS server to lookup
219
-	DNSOptions      []string           `json:"DnsOptions"` // List of DNSOption to look for
220
-	DNSSearch       []string           `json:"DnsSearch"`  // List of DNSSearch to look for
221
-	ExtraHosts      []string           // List of extra hosts
222
-	GroupAdd        []string           // List of additional groups that the container process will run as
223
-	IpcMode         IpcMode            // IPC namespace to use for the container
224
-	Links           []string           // List of links (in the name:alias form)
225
-	OomScoreAdj     int                // Container preference for OOM-killing
226
-	PidMode         PidMode            // PID namespace to use for the container
227
-	Privileged      bool               // Is the container in privileged mode
228
-	PublishAllPorts bool               // Should docker publish all exposed port for the container
229
-	ReadonlyRootfs  bool               // Is the container root filesystem in read-only
230
-	SecurityOpt     []string           // List of string values to customize labels for MLS systems, such as SELinux.
231
-	Tmpfs           map[string]string  `json:",omitempty"` // List of tmpfs (mounts) used for the container
232
-	UTSMode         UTSMode            // UTS namespace to use for the container
233
-	ShmSize         int64              // Total shm memory usage
216
+	CapAdd          strslice.StrSlice // List of kernel capabilities to add to the container
217
+	CapDrop         strslice.StrSlice // List of kernel capabilities to remove from the container
218
+	DNS             []string          `json:"Dns"`        // List of DNS server to lookup
219
+	DNSOptions      []string          `json:"DnsOptions"` // List of DNSOption to look for
220
+	DNSSearch       []string          `json:"DnsSearch"`  // List of DNSSearch to look for
221
+	ExtraHosts      []string          // List of extra hosts
222
+	GroupAdd        []string          // List of additional groups that the container process will run as
223
+	IpcMode         IpcMode           // IPC namespace to use for the container
224
+	Links           []string          // List of links (in the name:alias form)
225
+	OomScoreAdj     int               // Container preference for OOM-killing
226
+	PidMode         PidMode           // PID namespace to use for the container
227
+	Privileged      bool              // Is the container in privileged mode
228
+	PublishAllPorts bool              // Should docker publish all exposed port for the container
229
+	ReadonlyRootfs  bool              // Is the container root filesystem in read-only
230
+	SecurityOpt     []string          // List of string values to customize labels for MLS systems, such as SELinux.
231
+	Tmpfs           map[string]string `json:",omitempty"` // List of tmpfs (mounts) used for the container
232
+	UTSMode         UTSMode           // UTS namespace to use for the container
233
+	ShmSize         int64             // Total shm memory usage
234 234
 
235 235
 	// Applicable to Windows
236 236
 	ConsoleSize [2]int    // Initial console size
... ...
@@ -15,9 +15,38 @@ func (n NetworkMode) IsNone() bool {
15 15
 	return n == "none"
16 16
 }
17 17
 
18
+// IsContainer indicates whether container uses a container network stack.
19
+// Returns false as windows doesn't support this mode
20
+func (n NetworkMode) IsContainer() bool {
21
+	return false
22
+}
23
+
24
+// IsBridge indicates whether container uses the bridge network stack
25
+// in windows it is given the name NAT
26
+func (n NetworkMode) IsBridge() bool {
27
+	return n == "nat"
28
+}
29
+
30
+// IsHost indicates whether container uses the host network stack.
31
+// returns false as this is not supported by windows
32
+func (n NetworkMode) IsHost() bool {
33
+	return false
34
+}
35
+
36
+// IsPrivate indicates whether container uses it's private network stack.
37
+func (n NetworkMode) IsPrivate() bool {
38
+	return !(n.IsHost() || n.IsContainer())
39
+}
40
+
41
+// ConnectedContainer is the id of the container which network this container is connected to.
42
+// Returns blank string on windows
43
+func (n NetworkMode) ConnectedContainer() string {
44
+	return ""
45
+}
46
+
18 47
 // IsUserDefined indicates user-created network
19 48
 func (n NetworkMode) IsUserDefined() bool {
20
-	return !n.IsDefault() && !n.IsNone()
49
+	return !n.IsDefault() && !n.IsNone() && !n.IsBridge()
21 50
 }
22 51
 
23 52
 // IsHyperV indicates the use of a Hyper-V partition for isolation
... ...
@@ -35,34 +64,19 @@ func (i Isolation) IsValid() bool {
35 35
 	return i.IsDefault() || i.IsHyperV() || i.IsProcess()
36 36
 }
37 37
 
38
-// DefaultDaemonNetworkMode returns the default network stack the daemon should
39
-// use.
40
-func DefaultDaemonNetworkMode() NetworkMode {
41
-	return NetworkMode("default")
42
-}
43
-
44 38
 // NetworkName returns the name of the network stack.
45 39
 func (n NetworkMode) NetworkName() string {
46 40
 	if n.IsDefault() {
47 41
 		return "default"
42
+	} else if n.IsBridge() {
43
+		return "nat"
44
+	} else if n.IsNone() {
45
+		return "none"
46
+	} else if n.IsUserDefined() {
47
+		return n.UserDefined()
48 48
 	}
49
-	return ""
50
-}
51 49
 
52
-// ValidateNetMode ensures that the various combinations of requested
53
-// network settings are valid.
54
-func ValidateNetMode(c *Config, hc *HostConfig) error {
55
-	// We may not be passed a host config, such as in the case of docker commit
56
-	if hc == nil {
57
-		return nil
58
-	}
59
-	parts := strings.Split(string(hc.NetworkMode), ":")
60
-	switch mode := parts[0]; mode {
61
-	case "default", "none":
62
-	default:
63
-		return fmt.Errorf("invalid --net: %s", hc.NetworkMode)
64
-	}
65
-	return nil
50
+	return ""
66 51
 }
67 52
 
68 53
 // ValidateIsolationperforms platform specific validation of the
... ...
@@ -78,3 +92,11 @@ func ValidateIsolation(hc *HostConfig) error {
78 78
 	}
79 79
 	return nil
80 80
 }
81
+
82
+//UserDefined indicates user-created network
83
+func (n NetworkMode) UserDefined() string {
84
+	if n.IsUserDefined() {
85
+		return string(n)
86
+	}
87
+	return ""
88
+}
... ...
@@ -1,29 +1,18 @@
1 1
 package strslice
2 2
 
3
-import (
4
-	"encoding/json"
5
-	"strings"
6
-)
3
+import "encoding/json"
7 4
 
8 5
 // StrSlice represents a string or an array of strings.
9 6
 // We need to override the json decoder to accept both options.
10
-type StrSlice struct {
11
-	parts []string
12
-}
13
-
14
-// MarshalJSON Marshals (or serializes) the StrSlice into the json format.
15
-// This method is needed to implement json.Marshaller.
16
-func (e *StrSlice) MarshalJSON() ([]byte, error) {
17
-	if e == nil {
18
-		return []byte{}, nil
19
-	}
20
-	return json.Marshal(e.Slice())
21
-}
7
+type StrSlice []string
22 8
 
23
-// UnmarshalJSON decodes the byte slice whether it's a string or an array of strings.
24
-// This method is needed to implement json.Unmarshaler.
9
+// UnmarshalJSON decodes the byte slice whether it's a string or an array of
10
+// strings. This method is needed to implement json.Unmarshaler.
25 11
 func (e *StrSlice) UnmarshalJSON(b []byte) error {
26 12
 	if len(b) == 0 {
13
+		// With no input, we preserve the existing value by returning nil and
14
+		// leaving the target alone. This allows defining default values for
15
+		// the type.
27 16
 		return nil
28 17
 	}
29 18
 
... ...
@@ -36,36 +25,6 @@ func (e *StrSlice) UnmarshalJSON(b []byte) error {
36 36
 		p = append(p, s)
37 37
 	}
38 38
 
39
-	e.parts = p
39
+	*e = p
40 40
 	return nil
41 41
 }
42
-
43
-// Len returns the number of parts of the StrSlice.
44
-func (e *StrSlice) Len() int {
45
-	if e == nil {
46
-		return 0
47
-	}
48
-	return len(e.parts)
49
-}
50
-
51
-// Slice gets the parts of the StrSlice as a Slice of string.
52
-func (e *StrSlice) Slice() []string {
53
-	if e == nil {
54
-		return nil
55
-	}
56
-	return e.parts
57
-}
58
-
59
-// ToString gets space separated string of all the parts.
60
-func (e *StrSlice) ToString() string {
61
-	s := e.Slice()
62
-	if s == nil {
63
-		return ""
64
-	}
65
-	return strings.Join(s, " ")
66
-}
67
-
68
-// New creates an StrSlice based on the specified parts (as strings).
69
-func New(parts ...string) *StrSlice {
70
-	return &StrSlice{parts}
71
-}
... ...
@@ -218,6 +218,7 @@ type Info struct {
218 218
 	SystemTime         string
219 219
 	ExecutionDriver    string
220 220
 	LoggingDriver      string
221
+	CgroupDriver       string
221 222
 	NEventsListener    int
222 223
 	KernelVersion      string
223 224
 	OperatingSystem    string