Browse code

Merge pull request #31140 from thaJeztah/1.13.2-cherry-picks

17.03 cherry picks

Victor Vieux authored on 2017/02/19 17:36:22
Showing 23 changed files
... ...
@@ -63,6 +63,8 @@ func GetHTTPErrorStatusCode(err error) int {
63 63
 			{"unauthorized", http.StatusUnauthorized},
64 64
 			{"hasn't been activated", http.StatusForbidden},
65 65
 			{"this node", http.StatusServiceUnavailable},
66
+			{"needs to be unlocked", http.StatusServiceUnavailable},
67
+			{"certificates have expired", http.StatusServiceUnavailable},
66 68
 		} {
67 69
 			if strings.Contains(errStr, status.keyword) {
68 70
 				statusCode = status.code
... ...
@@ -369,6 +369,11 @@ func (s *containerRouter) postContainersCreate(ctx context.Context, w http.Respo
369 369
 	version := httputils.VersionFromContext(ctx)
370 370
 	adjustCPUShares := versions.LessThan(version, "1.19")
371 371
 
372
+	// When using API 1.24 and under, the client is responsible for removing the container
373
+	if hostConfig != nil && versions.LessThan(version, "1.25") {
374
+		hostConfig.AutoRemove = false
375
+	}
376
+
372 377
 	ccr, err := s.backend.ContainerCreate(types.ContainerCreateConfig{
373 378
 		Name:             name,
374 379
 		Config:           config,
... ...
@@ -104,7 +104,8 @@ func MakeTarSumContext(tarStream io.Reader) (ModifiableContext, error) {
104 104
 		return nil, err
105 105
 	}
106 106
 
107
-	if err := chrootarchive.Untar(sum, root, nil); err != nil {
107
+	err = chrootarchive.Untar(sum, root, nil)
108
+	if err != nil {
108 109
 		return nil, err
109 110
 	}
110 111
 
... ...
@@ -74,9 +74,8 @@ func runRun(dockerCli *command.DockerCli, flags *pflag.FlagSet, opts *runOptions
74 74
 	cmdPath := "run"
75 75
 
76 76
 	var (
77
-		flAttach                              *opttypes.ListOpts
78
-		ErrConflictAttachDetach               = fmt.Errorf("Conflicting options: -a and -d")
79
-		ErrConflictRestartPolicyAndAutoRemove = fmt.Errorf("Conflicting options: --restart and --rm")
77
+		flAttach                *opttypes.ListOpts
78
+		ErrConflictAttachDetach = fmt.Errorf("Conflicting options: -a and -d")
80 79
 	)
81 80
 
82 81
 	config, hostConfig, networkingConfig, err := runconfigopts.Parse(flags, copts)
... ...
@@ -87,9 +86,6 @@ func runRun(dockerCli *command.DockerCli, flags *pflag.FlagSet, opts *runOptions
87 87
 		return cli.StatusError{StatusCode: 125}
88 88
 	}
89 89
 
90
-	if hostConfig.AutoRemove && !hostConfig.RestartPolicy.IsNone() {
91
-		return ErrConflictRestartPolicyAndAutoRemove
92
-	}
93 90
 	if hostConfig.OomKillDisable != nil && *hostConfig.OomKillDisable && hostConfig.Memory == 0 {
94 91
 		fmt.Fprintf(stderr, "WARNING: Disabling the OOM killer on containers without setting a '-m/--memory' limit may be dangerous.\n")
95 92
 	}
... ...
@@ -145,8 +145,10 @@ func (c *containerStatsContext) Container() string {
145 145
 
146 146
 func (c *containerStatsContext) Name() string {
147 147
 	c.AddHeader(nameHeader)
148
-	name := c.s.Name[1:]
149
-	return name
148
+	if len(c.s.Name) > 1 {
149
+		return c.s.Name[1:]
150
+	}
151
+	return "--"
150 152
 }
151 153
 
152 154
 func (c *containerStatsContext) ID() string {
... ...
@@ -72,6 +72,12 @@ func TestContainerStatsContextWrite(t *testing.T) {
72 72
 `,
73 73
 		},
74 74
 		{
75
+			Context{Format: "{{.Container}}  {{.ID}}  {{.Name}}"},
76
+			`container1  abcdef  foo
77
+container2    --
78
+`,
79
+		},
80
+		{
75 81
 			Context{Format: "{{.Container}}  {{.CPUPerc}}"},
76 82
 			`container1  20.00%
77 83
 container2  --
... ...
@@ -83,6 +89,8 @@ container2  --
83 83
 		stats := []StatsEntry{
84 84
 			{
85 85
 				Container:        "container1",
86
+				ID:               "abcdef",
87
+				Name:             "/foo",
86 88
 				CPUPercentage:    20,
87 89
 				Memory:           20,
88 90
 				MemoryLimit:      20,
... ...
@@ -219,19 +219,27 @@ func convertServiceSecrets(
219 219
 		if gid == "" {
220 220
 			gid = "0"
221 221
 		}
222
+		mode := secret.Mode
223
+		if mode == nil {
224
+			mode = uint32Ptr(0444)
225
+		}
222 226
 
223 227
 		opts = append(opts, &types.SecretRequestOption{
224 228
 			Source: source,
225 229
 			Target: target,
226 230
 			UID:    uid,
227 231
 			GID:    gid,
228
-			Mode:   os.FileMode(secret.Mode),
232
+			Mode:   os.FileMode(*mode),
229 233
 		})
230 234
 	}
231 235
 
232 236
 	return servicecli.ParseSecrets(client, opts)
233 237
 }
234 238
 
239
+func uint32Ptr(value uint32) *uint32 {
240
+	return &value
241
+}
242
+
235 243
 func convertExtraHosts(extraHosts map[string]string) []string {
236 244
 	hosts := []string{}
237 245
 	for host, ip := range extraHosts {
... ...
@@ -199,7 +199,7 @@ type ServiceSecretConfig struct {
199 199
 	Target string
200 200
 	UID    string
201 201
 	GID    string
202
-	Mode   uint32
202
+	Mode   *uint32
203 203
 }
204 204
 
205 205
 // UlimitsConfig the ulimit configuration
... ...
@@ -7,6 +7,7 @@ import (
7 7
 
8 8
 	"github.com/docker/docker/api/types/container"
9 9
 	"github.com/docker/docker/api/types/network"
10
+	"github.com/docker/docker/api/types/versions"
10 11
 	"golang.org/x/net/context"
11 12
 )
12 13
 
... ...
@@ -25,6 +26,11 @@ func (cli *Client) ContainerCreate(ctx context.Context, config *container.Config
25 25
 		return response, err
26 26
 	}
27 27
 
28
+	// When using API 1.24 and under, the client is responsible for removing the container
29
+	if hostConfig != nil && versions.LessThan(cli.ClientVersion(), "1.25") {
30
+		hostConfig.AutoRemove = false
31
+	}
32
+
28 33
 	query := url.Values{}
29 34
 	if containerName != "" {
30 35
 		query.Set("name", containerName)
... ...
@@ -74,3 +74,45 @@ func TestContainerCreateWithName(t *testing.T) {
74 74
 		t.Fatalf("expected `container_id`, got %s", r.ID)
75 75
 	}
76 76
 }
77
+
78
+// TestContainerCreateAutoRemove validates that a client using API 1.24 always disables AutoRemove. When using API 1.25
79
+// or up, AutoRemove should not be disabled.
80
+func TestContainerCreateAutoRemove(t *testing.T) {
81
+	autoRemoveValidator := func(expectedValue bool) func(req *http.Request) (*http.Response, error) {
82
+		return func(req *http.Request) (*http.Response, error) {
83
+			var config configWrapper
84
+
85
+			if err := json.NewDecoder(req.Body).Decode(&config); err != nil {
86
+				return nil, err
87
+			}
88
+			if config.HostConfig.AutoRemove != expectedValue {
89
+				return nil, fmt.Errorf("expected AutoRemove to be %v, got %v", expectedValue, config.HostConfig.AutoRemove)
90
+			}
91
+			b, err := json.Marshal(container.ContainerCreateCreatedBody{
92
+				ID: "container_id",
93
+			})
94
+			if err != nil {
95
+				return nil, err
96
+			}
97
+			return &http.Response{
98
+				StatusCode: http.StatusOK,
99
+				Body:       ioutil.NopCloser(bytes.NewReader(b)),
100
+			}, nil
101
+		}
102
+	}
103
+
104
+	client := &Client{
105
+		client:  newMockClient(autoRemoveValidator(false)),
106
+		version: "1.24",
107
+	}
108
+	if _, err := client.ContainerCreate(context.Background(), nil, &container.HostConfig{AutoRemove: true}, nil, ""); err != nil {
109
+		t.Fatal(err)
110
+	}
111
+	client = &Client{
112
+		client:  newMockClient(autoRemoveValidator(true)),
113
+		version: "1.25",
114
+	}
115
+	if _, err := client.ContainerCreate(context.Background(), nil, &container.HostConfig{AutoRemove: true}, nil, ""); err != nil {
116
+		t.Fatal(err)
117
+	}
118
+}
... ...
@@ -28,7 +28,7 @@ import (
28 28
 	"github.com/docker/docker/pkg/loopback"
29 29
 	"github.com/docker/docker/pkg/mount"
30 30
 	"github.com/docker/docker/pkg/parsers"
31
-	"github.com/docker/go-units"
31
+	units "github.com/docker/go-units"
32 32
 
33 33
 	"github.com/opencontainers/runc/libcontainer/label"
34 34
 )
... ...
@@ -1713,9 +1713,9 @@ func (devices *DeviceSet) initDevmapper(doInit bool) error {
1713 1713
 	// https://github.com/docker/docker/issues/4036
1714 1714
 	if supported := devicemapper.UdevSetSyncSupport(true); !supported {
1715 1715
 		if dockerversion.IAmStatic == "true" {
1716
-			logrus.Error("devmapper: Udev sync is not supported. This will lead to data loss and unexpected behavior. Install a dynamic binary to use devicemapper or select a different storage driver. For more information, see https://docs.docker.com/engine/reference/commandline/daemon/#daemon-storage-driver-option")
1716
+			logrus.Error("devmapper: Udev sync is not supported. This will lead to data loss and unexpected behavior. Install a dynamic binary to use devicemapper or select a different storage driver. For more information, see https://docs.docker.com/engine/reference/commandline/dockerd/#storage-driver-options")
1717 1717
 		} else {
1718
-			logrus.Error("devmapper: Udev sync is not supported. This will lead to data loss and unexpected behavior. Install a more recent version of libdevmapper or select a different storage driver. For more information, see https://docs.docker.com/engine/reference/commandline/daemon/#daemon-storage-driver-option")
1718
+			logrus.Error("devmapper: Udev sync is not supported. This will lead to data loss and unexpected behavior. Install a more recent version of libdevmapper or select a different storage driver. For more information, see https://docs.docker.com/engine/reference/commandline/dockerd/#storage-driver-options")
1719 1719
 		}
1720 1720
 
1721 1721
 		if !devices.overrideUdevSyncCheck {
... ...
@@ -31,6 +31,7 @@ import (
31 31
 	"github.com/docker/docker/pkg/ioutils"
32 32
 	"github.com/docker/docker/pkg/longpath"
33 33
 	"github.com/docker/docker/pkg/reexec"
34
+	"github.com/docker/docker/pkg/system"
34 35
 	units "github.com/docker/go-units"
35 36
 	"golang.org/x/sys/windows"
36 37
 )
... ...
@@ -265,19 +266,35 @@ func (d *Driver) Remove(id string) error {
265 265
 	// it is a transient error. Retry until it succeeds.
266 266
 	var computeSystems []hcsshim.ContainerProperties
267 267
 	retryCount := 0
268
+	osv := system.GetOSVersion()
268 269
 	for {
269
-		// Get and terminate any template VMs that are currently using the layer
270
+		// Get and terminate any template VMs that are currently using the layer.
271
+		// Note: It is unfortunate that we end up in the graphdrivers Remove() call
272
+		// for both containers and images, but the logic for template VMs is only
273
+		// needed for images - specifically we are looking to see if a base layer
274
+		// is in use by a template VM as a result of having started a Hyper-V
275
+		// container at some point.
276
+		//
277
+		// We have a retry loop for ErrVmcomputeOperationInvalidState and
278
+		// ErrVmcomputeOperationAccessIsDenied as there is a race condition
279
+		// in RS1 and RS2 building during enumeration when a silo is going away
280
+		// for example under it, in HCS. AccessIsDenied added to fix 30278.
281
+		//
282
+		// TODO @jhowardmsft - For RS3, we can remove the retries. Also consider
283
+		// using platform APIs (if available) to get this more succinctly. Also
284
+		// consider enlighting the Remove() interface to have context of why
285
+		// the remove is being called - that could improve efficiency by not
286
+		// enumerating compute systems during a remove of a container as it's
287
+		// not required.
270 288
 		computeSystems, err = hcsshim.GetContainers(hcsshim.ComputeSystemQuery{})
271 289
 		if err != nil {
272
-			if err == hcsshim.ErrVmcomputeOperationInvalidState {
273
-				if retryCount >= 5 {
274
-					// If we are unable to get the list of containers
275
-					// go ahead and attempt to delete the layer anyway
276
-					// as it will most likely work.
290
+			if (osv.Build < 15139) &&
291
+				((err == hcsshim.ErrVmcomputeOperationInvalidState) || (err == hcsshim.ErrVmcomputeOperationAccessIsDenied)) {
292
+				if retryCount >= 500 {
277 293
 					break
278 294
 				}
279 295
 				retryCount++
280
-				time.Sleep(2 * time.Second)
296
+				time.Sleep(10 * time.Millisecond)
281 297
 				continue
282 298
 			}
283 299
 			return err
... ...
@@ -137,7 +137,11 @@ func tailFile(f io.ReadSeeker, logWatcher *logger.LogWatcher, tail int, since ti
137 137
 		if !since.IsZero() && msg.Timestamp.Before(since) {
138 138
 			continue
139 139
 		}
140
-		logWatcher.Msg <- msg
140
+		select {
141
+		case <-logWatcher.WatchClose():
142
+			return
143
+		case logWatcher.Msg <- msg:
144
+		}
141 145
 	}
142 146
 }
143 147
 
... ...
@@ -252,9 +256,12 @@ func followLogs(f *os.File, logWatcher *logger.LogWatcher, notifyRotate chan int
252 252
 
253 253
 	handleDecodeErr := func(err error) error {
254 254
 		if err == io.EOF {
255
-			for err := waitRead(); err != nil; {
255
+			for {
256
+				err := waitRead()
257
+				if err == nil {
258
+					break
259
+				}
256 260
 				if err == errRetry {
257
-					// retry the waitRead
258 261
 					continue
259 262
 				}
260 263
 				return err
... ...
@@ -61,6 +61,18 @@ func (daemon *Daemon) ContainerLogs(ctx context.Context, containerName string, c
61 61
 		Follow: follow,
62 62
 	}
63 63
 	logs := logReader.ReadLogs(readConfig)
64
+	// Close logWatcher on exit
65
+	defer func() {
66
+		logs.Close()
67
+		if cLog != container.LogDriver {
68
+			// Since the logger isn't cached in the container, which
69
+			// occurs if it is running, it must get explicitly closed
70
+			// here to avoid leaking it and any file handles it has.
71
+			if err := cLog.Close(); err != nil {
72
+				logrus.Errorf("Error closing logger: %v", err)
73
+			}
74
+		}
75
+	}()
64 76
 
65 77
 	wf := ioutils.NewWriteFlusher(config.OutStream)
66 78
 	defer wf.Close()
... ...
@@ -81,19 +93,11 @@ func (daemon *Daemon) ContainerLogs(ctx context.Context, containerName string, c
81 81
 			logrus.Errorf("Error streaming logs: %v", err)
82 82
 			return nil
83 83
 		case <-ctx.Done():
84
-			logs.Close()
84
+			logrus.Debugf("logs: end stream, ctx is done: %v", ctx.Err())
85 85
 			return nil
86 86
 		case msg, ok := <-logs.Msg:
87 87
 			if !ok {
88 88
 				logrus.Debug("logs: end stream")
89
-				logs.Close()
90
-				if cLog != container.LogDriver {
91
-					// Since the logger isn't cached in the container, which occurs if it is running, it
92
-					// must get explicitly closed here to avoid leaking it and any file handles it has.
93
-					if err := cLog.Close(); err != nil {
94
-						logrus.Errorf("Error closing logger: %v", err)
95
-					}
96
-				}
97 89
 				return nil
98 90
 			}
99 91
 			logLine := msg.Line
... ...
@@ -33,7 +33,9 @@ func (daemon *Daemon) ContainerStats(ctx context.Context, prefixOrName string, c
33 33
 
34 34
 	// If the container is either not running or restarting and requires no stream, return an empty stats.
35 35
 	if (!container.IsRunning() || container.IsRestarting()) && !config.Stream {
36
-		return json.NewEncoder(config.OutStream).Encode(&types.Stats{})
36
+		return json.NewEncoder(config.OutStream).Encode(&types.StatsJSON{
37
+			Name: container.Name,
38
+			ID:   container.ID})
37 39
 	}
38 40
 
39 41
 	outStream := config.OutStream
... ...
@@ -120,7 +120,14 @@ func (s *statsCollector) run() {
120 120
 			if err != nil {
121 121
 				if _, ok := err.(errNotRunning); !ok {
122 122
 					logrus.Errorf("collecting stats for %s: %v", pair.container.ID, err)
123
+					continue
123 124
 				}
125
+
126
+				// publish empty stats containing only name and ID if not running
127
+				pair.publisher.Publish(types.StatsJSON{
128
+					Name: pair.container.Name,
129
+					ID:   pair.container.ID,
130
+				})
124 131
 				continue
125 132
 			}
126 133
 			// FIXME: move to containerd on Linux (not Windows)
... ...
@@ -531,6 +531,10 @@ func (s *DockerSuite) TestBuildCacheAdd(c *check.C) {
531 531
 }
532 532
 
533 533
 func (s *DockerSuite) TestBuildLastModified(c *check.C) {
534
+	// Temporary fix for #30890. TODO @jhowardmsft figure out what
535
+	// has changed in the master busybox image.
536
+	testRequires(c, DaemonIsLinux)
537
+
534 538
 	name := "testbuildlastmodified"
535 539
 
536 540
 	server, err := fakeStorage(map[string]string{
... ...
@@ -3647,6 +3651,7 @@ RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1042:1043/10
3647 3647
 	}
3648 3648
 }
3649 3649
 
3650
+// FIXME(vdemeester) rename this test (and probably "merge" it with the one below TestBuildEnvUsage2)
3650 3651
 func (s *DockerSuite) TestBuildEnvUsage(c *check.C) {
3651 3652
 	// /docker/world/hello is not owned by the correct user
3652 3653
 	testRequires(c, NotUserNamespace)
... ...
@@ -3685,6 +3690,7 @@ RUN    [ "$ghi" = "def" ]
3685 3685
 	}
3686 3686
 }
3687 3687
 
3688
+// FIXME(vdemeester) rename this test (and probably "merge" it with the one above TestBuildEnvUsage)
3688 3689
 func (s *DockerSuite) TestBuildEnvUsage2(c *check.C) {
3689 3690
 	// /docker/world/hello is not owned by the correct user
3690 3691
 	testRequires(c, NotUserNamespace)
... ...
@@ -4811,6 +4817,7 @@ CMD cat /foo/file`,
4811 4811
 
4812 4812
 }
4813 4813
 
4814
+// FIXME(vdemeester) part of this should be unit test, other part should be clearer
4814 4815
 func (s *DockerSuite) TestBuildRenamedDockerfile(c *check.C) {
4815 4816
 
4816 4817
 	ctx, err := fakeContext(`FROM busybox
... ...
@@ -157,3 +157,22 @@ func (s *DockerSuite) TestStatsAllNewContainersAdded(c *check.C) {
157 157
 		// ignore, done
158 158
 	}
159 159
 }
160
+
161
+func (s *DockerSuite) TestStatsFormatAll(c *check.C) {
162
+	// Windows does not support stats
163
+	testRequires(c, DaemonIsLinux)
164
+
165
+	dockerCmd(c, "run", "-d", "--name=RunningOne", "busybox", "top")
166
+	c.Assert(waitRun("RunningOne"), check.IsNil)
167
+	dockerCmd(c, "run", "-d", "--name=ExitedOne", "busybox", "top")
168
+	dockerCmd(c, "stop", "ExitedOne")
169
+	c.Assert(waitExited("ExitedOne", 5*time.Second), check.IsNil)
170
+
171
+	out, _ := dockerCmd(c, "stats", "--no-stream", "--format", "{{.Name}}")
172
+	c.Assert(out, checker.Contains, "RunningOne")
173
+	c.Assert(out, checker.Not(checker.Contains), "ExitedOne")
174
+
175
+	out, _ = dockerCmd(c, "stats", "--all", "--no-stream", "--format", "{{.Name}}")
176
+	c.Assert(out, checker.Contains, "RunningOne")
177
+	c.Assert(out, checker.Contains, "ExitedOne")
178
+}
... ...
@@ -621,6 +621,10 @@ func Parse(flags *pflag.FlagSet, copts *ContainerOptions) (*container.Config, *c
621 621
 		Runtime:        copts.runtime,
622 622
 	}
623 623
 
624
+	if copts.autoRemove && !hostConfig.RestartPolicy.IsNone() {
625
+		return nil, nil, nil, fmt.Errorf("Conflicting options: --restart and --rm")
626
+	}
627
+
624 628
 	// only set this value if the user provided the flag, else it should default to nil
625 629
 	if flags.Changed("init") {
626 630
 		hostConfig.Init = &copts.init
... ...
@@ -586,6 +586,14 @@ func TestParseRestartPolicy(t *testing.T) {
586 586
 	}
587 587
 }
588 588
 
589
+func TestParseRestartPolicyAutoRemove(t *testing.T) {
590
+	expected := "Conflicting options: --restart and --rm"
591
+	_, _, _, err := parseRun([]string{"--rm", "--restart=always", "img", "cmd"})
592
+	if err == nil || err.Error() != expected {
593
+		t.Fatalf("Expected error %v, but got none", expected)
594
+	}
595
+}
596
+
589 597
 func TestParseHealth(t *testing.T) {
590 598
 	checkOk := func(args ...string) *container.HealthConfig {
591 599
 		config, _, _, err := parseRun(args)
... ...
@@ -1,6 +1,6 @@
1 1
 # the following lines are in sorted order, FYI
2 2
 github.com/Azure/go-ansiterm 388960b655244e76e24c75f48631564eaefade62
3
-github.com/Microsoft/hcsshim v0.5.9
3
+github.com/Microsoft/hcsshim v0.5.12
4 4
 github.com/Microsoft/go-winio v0.3.8
5 5
 github.com/Sirupsen/logrus v0.11.0
6 6
 github.com/davecgh/go-spew 6d212800a42e8ab5c146b8ace3490ee17e5225f9
... ...
@@ -50,6 +50,10 @@ var (
50 50
 
51 51
 	// ErrProcNotFound is an error encountered when the the process cannot be found
52 52
 	ErrProcNotFound = syscall.Errno(0x7f)
53
+
54
+	// ErrVmcomputeOperationAccessIsDenied is an error which can be encountered when enumerating compute systems in RS1/RS2
55
+	// builds when the underlying silo might be in the process of terminating. HCS was fixed in RS3.
56
+	ErrVmcomputeOperationAccessIsDenied = syscall.Errno(0x5)
53 57
 )
54 58
 
55 59
 // ProcessError is an error encountered in HCS during an operation on a Process object
... ...
@@ -41,30 +41,32 @@ type HvRuntime struct {
41 41
 // ContainerConfig is used as both the input of CreateContainer
42 42
 // and to convert the parameters to JSON for passing onto the HCS
43 43
 type ContainerConfig struct {
44
-	SystemType               string      // HCS requires this to be hard-coded to "Container"
45
-	Name                     string      // Name of the container. We use the docker ID.
46
-	Owner                    string      // The management platform that created this container
47
-	IsDummy                  bool        // Used for development purposes.
48
-	VolumePath               string      `json:",omitempty"` // Windows volume path for scratch space. Used by Windows Server Containers only. Format \\?\\Volume{GUID}
49
-	IgnoreFlushesDuringBoot  bool        // Optimization hint for container startup in Windows
50
-	LayerFolderPath          string      `json:",omitempty"` // Where the layer folders are located. Used by Windows Server Containers only. Format  %root%\windowsfilter\containerID
51
-	Layers                   []Layer     // List of storage layers. Required for Windows Server and Hyper-V Containers. Format ID=GUID;Path=%root%\windowsfilter\layerID
52
-	Credentials              string      `json:",omitempty"` // Credentials information
53
-	ProcessorCount           uint32      `json:",omitempty"` // Number of processors to assign to the container.
54
-	ProcessorWeight          uint64      `json:",omitempty"` // CPU Shares 0..10000 on Windows; where 0 will be omitted and HCS will default.
55
-	ProcessorMaximum         int64       `json:",omitempty"` // CPU maximum usage percent 1..100
56
-	StorageIOPSMaximum       uint64      `json:",omitempty"` // Maximum Storage IOPS
57
-	StorageBandwidthMaximum  uint64      `json:",omitempty"` // Maximum Storage Bandwidth in bytes per second
58
-	StorageSandboxSize       uint64      `json:",omitempty"` // Size in bytes that the container system drive should be expanded to if smaller
59
-	MemoryMaximumInMB        int64       `json:",omitempty"` // Maximum memory available to the container in Megabytes
60
-	HostName                 string      // Hostname
61
-	MappedDirectories        []MappedDir // List of mapped directories (volumes/mounts)
62
-	SandboxPath              string      `json:",omitempty"` // Location of unmounted sandbox. Used by Hyper-V containers only. Format %root%\windowsfilter
63
-	HvPartition              bool        // True if it a Hyper-V Container
64
-	EndpointList             []string    // List of networking endpoints to be attached to container
65
-	HvRuntime                *HvRuntime  `json:",omitempty"` // Hyper-V container settings. Used by Hyper-V containers only. Format ImagePath=%root%\BaseLayerID\UtilityVM
66
-	Servicing                bool        // True if this container is for servicing
67
-	AllowUnqualifiedDNSQuery bool        // True to allow unqualified DNS name resolution
44
+	SystemType                 string      // HCS requires this to be hard-coded to "Container"
45
+	Name                       string      // Name of the container. We use the docker ID.
46
+	Owner                      string      // The management platform that created this container
47
+	IsDummy                    bool        // Used for development purposes.
48
+	VolumePath                 string      `json:",omitempty"` // Windows volume path for scratch space. Used by Windows Server Containers only. Format \\?\\Volume{GUID}
49
+	IgnoreFlushesDuringBoot    bool        // Optimization hint for container startup in Windows
50
+	LayerFolderPath            string      `json:",omitempty"` // Where the layer folders are located. Used by Windows Server Containers only. Format  %root%\windowsfilter\containerID
51
+	Layers                     []Layer     // List of storage layers. Required for Windows Server and Hyper-V Containers. Format ID=GUID;Path=%root%\windowsfilter\layerID
52
+	Credentials                string      `json:",omitempty"` // Credentials information
53
+	ProcessorCount             uint32      `json:",omitempty"` // Number of processors to assign to the container.
54
+	ProcessorWeight            uint64      `json:",omitempty"` // CPU Shares 0..10000 on Windows; where 0 will be omitted and HCS will default.
55
+	ProcessorMaximum           int64       `json:",omitempty"` // CPU maximum usage percent 1..100
56
+	StorageIOPSMaximum         uint64      `json:",omitempty"` // Maximum Storage IOPS
57
+	StorageBandwidthMaximum    uint64      `json:",omitempty"` // Maximum Storage Bandwidth in bytes per second
58
+	StorageSandboxSize         uint64      `json:",omitempty"` // Size in bytes that the container system drive should be expanded to if smaller
59
+	MemoryMaximumInMB          int64       `json:",omitempty"` // Maximum memory available to the container in Megabytes
60
+	HostName                   string      // Hostname
61
+	MappedDirectories          []MappedDir // List of mapped directories (volumes/mounts)
62
+	SandboxPath                string      `json:",omitempty"` // Location of unmounted sandbox. Used by Hyper-V containers only. Format %root%\windowsfilter
63
+	HvPartition                bool        // True if it a Hyper-V Container
64
+	EndpointList               []string    // List of networking endpoints to be attached to container
65
+	NetworkSharedContainerName string      `json:",omitempty"` // Name (ID) of the container that we will share the network stack with.
66
+	HvRuntime                  *HvRuntime  `json:",omitempty"` // Hyper-V container settings. Used by Hyper-V containers only. Format ImagePath=%root%\BaseLayerID\UtilityVM
67
+	Servicing                  bool        // True if this container is for servicing
68
+	AllowUnqualifiedDNSQuery   bool        // True to allow unqualified DNS name resolution
69
+	DNSSearchList              string      `json:",omitempty"` // Comma seperated list of DNS suffixes to use for name resolution
68 70
 }
69 71
 
70 72
 type ComputeSystemQuery struct {