Browse code

Added support for swarm service isolation mode

Signed-off-by: Simon Ferquel <simon.ferquel@docker.com>

Simon Ferquel authored on 2017/08/07 23:07:17
Showing 25 changed files
... ...
@@ -2680,7 +2680,13 @@ definitions:
2680 2680
                     ConfigName is the name of the config that this references, but this is just provided for
2681 2681
                     lookup/display purposes. The config in the reference will be identified by its ID.
2682 2682
                   type: "string"
2683
-
2683
+          Isolation:
2684
+            type: "string"
2685
+            description: "Isolation technology of the containers running the service. (Windows only)"
2686
+            enum:
2687
+              - "default"
2688
+              - "process"
2689
+              - "hyperv"
2684 2690
       Resources:
2685 2691
         description: "Resource requirements which apply to each individual container created as part of the service."
2686 2692
         type: "object"
... ...
@@ -20,6 +20,27 @@ func (i Isolation) IsDefault() bool {
20 20
 	return strings.ToLower(string(i)) == "default" || string(i) == ""
21 21
 }
22 22
 
23
+// IsHyperV indicates the use of a Hyper-V partition for isolation
24
+func (i Isolation) IsHyperV() bool {
25
+	return strings.ToLower(string(i)) == "hyperv"
26
+}
27
+
28
+// IsProcess indicates the use of process isolation
29
+func (i Isolation) IsProcess() bool {
30
+	return strings.ToLower(string(i)) == "process"
31
+}
32
+
33
+const (
34
+	// IsolationEmpty is unspecified (same behavior as default)
35
+	IsolationEmpty = Isolation("")
36
+	// IsolationDefault is the default isolation mode on current daemon
37
+	IsolationDefault = Isolation("default")
38
+	// IsolationProcess is process isolation mode
39
+	IsolationProcess = Isolation("process")
40
+	// IsolationHyperV is HyperV isolation mode
41
+	IsolationHyperV = Isolation("hyperv")
42
+)
43
+
23 44
 // IpcMode represents the container ipc stack.
24 45
 type IpcMode string
25 46
 
... ...
@@ -1,9 +1,5 @@
1 1
 package container
2 2
 
3
-import (
4
-	"strings"
5
-)
6
-
7 3
 // IsBridge indicates whether container uses the bridge network stack
8 4
 // in windows it is given the name NAT
9 5
 func (n NetworkMode) IsBridge() bool {
... ...
@@ -21,16 +17,6 @@ func (n NetworkMode) IsUserDefined() bool {
21 21
 	return !n.IsDefault() && !n.IsNone() && !n.IsBridge() && !n.IsContainer()
22 22
 }
23 23
 
24
-// IsHyperV indicates the use of a Hyper-V partition for isolation
25
-func (i Isolation) IsHyperV() bool {
26
-	return strings.ToLower(string(i)) == "hyperv"
27
-}
28
-
29
-// IsProcess indicates the use of process isolation
30
-func (i Isolation) IsProcess() bool {
31
-	return strings.ToLower(string(i)) == "process"
32
-}
33
-
34 24
 // IsValid indicates if an isolation technology is valid
35 25
 func (i Isolation) IsValid() bool {
36 26
 	return i.IsDefault() || i.IsHyperV() || i.IsProcess()
... ...
@@ -65,8 +65,9 @@ type ContainerSpec struct {
65 65
 	// The format of extra hosts on swarmkit is specified in:
66 66
 	// http://man7.org/linux/man-pages/man5/hosts.5.html
67 67
 	//    IP_address canonical_hostname [aliases...]
68
-	Hosts     []string           `json:",omitempty"`
69
-	DNSConfig *DNSConfig         `json:",omitempty"`
70
-	Secrets   []*SecretReference `json:",omitempty"`
71
-	Configs   []*ConfigReference `json:",omitempty"`
68
+	Hosts     []string            `json:",omitempty"`
69
+	DNSConfig *DNSConfig          `json:",omitempty"`
70
+	Secrets   []*SecretReference  `json:",omitempty"`
71
+	Configs   []*ConfigReference  `json:",omitempty"`
72
+	Isolation container.Isolation `json:",omitempty"`
72 73
 }
... ...
@@ -34,6 +34,7 @@ func containerSpecFromGRPC(c *swarmapi.ContainerSpec) *types.ContainerSpec {
34 34
 		Hosts:      c.Hosts,
35 35
 		Secrets:    secretReferencesFromGRPC(c.Secrets),
36 36
 		Configs:    configReferencesFromGRPC(c.Configs),
37
+		Isolation:  IsolationFromGRPC(c.Isolation),
37 38
 	}
38 39
 
39 40
 	if c.DNSConfig != nil {
... ...
@@ -232,6 +233,7 @@ func containerToGRPC(c *types.ContainerSpec) (*swarmapi.ContainerSpec, error) {
232 232
 		Hosts:      c.Hosts,
233 233
 		Secrets:    secretReferencesToGRPC(c.Secrets),
234 234
 		Configs:    configReferencesToGRPC(c.Configs),
235
+		Isolation:  isolationToGRPC(c.Isolation),
235 236
 	}
236 237
 
237 238
 	if c.DNSConfig != nil {
... ...
@@ -354,3 +356,26 @@ func healthConfigToGRPC(h *container.HealthConfig) *swarmapi.HealthConfig {
354 354
 		StartPeriod: gogotypes.DurationProto(h.StartPeriod),
355 355
 	}
356 356
 }
357
+
358
+// IsolationFromGRPC converts a swarm api container isolation to a moby isolation representation
359
+func IsolationFromGRPC(i swarmapi.ContainerSpec_Isolation) container.Isolation {
360
+	switch i {
361
+	case swarmapi.ContainerIsolationHyperV:
362
+		return container.IsolationHyperV
363
+	case swarmapi.ContainerIsolationProcess:
364
+		return container.IsolationProcess
365
+	case swarmapi.ContainerIsolationDefault:
366
+		return container.IsolationDefault
367
+	}
368
+	return container.IsolationEmpty
369
+}
370
+
371
+func isolationToGRPC(i container.Isolation) swarmapi.ContainerSpec_Isolation {
372
+	if i.IsHyperV() {
373
+		return swarmapi.ContainerIsolationHyperV
374
+	}
375
+	if i.IsProcess() {
376
+		return swarmapi.ContainerIsolationProcess
377
+	}
378
+	return swarmapi.ContainerIsolationDefault
379
+}
... ...
@@ -3,10 +3,12 @@ package convert
3 3
 import (
4 4
 	"testing"
5 5
 
6
+	containertypes "github.com/docker/docker/api/types/container"
6 7
 	swarmtypes "github.com/docker/docker/api/types/swarm"
7 8
 	"github.com/docker/docker/api/types/swarm/runtime"
8 9
 	swarmapi "github.com/docker/swarmkit/api"
9 10
 	google_protobuf3 "github.com/gogo/protobuf/types"
11
+	"github.com/stretchr/testify/require"
10 12
 )
11 13
 
12 14
 func TestServiceConvertFromGRPCRuntimeContainer(t *testing.T) {
... ...
@@ -148,3 +150,85 @@ func TestServiceConvertToGRPCGenericRuntimeCustom(t *testing.T) {
148 148
 		t.Fatal(err)
149 149
 	}
150 150
 }
151
+
152
+func TestServiceConvertToGRPCIsolation(t *testing.T) {
153
+	cases := []struct {
154
+		name string
155
+		from containertypes.Isolation
156
+		to   swarmapi.ContainerSpec_Isolation
157
+	}{
158
+		{name: "empty", from: containertypes.IsolationEmpty, to: swarmapi.ContainerIsolationDefault},
159
+		{name: "default", from: containertypes.IsolationDefault, to: swarmapi.ContainerIsolationDefault},
160
+		{name: "process", from: containertypes.IsolationProcess, to: swarmapi.ContainerIsolationProcess},
161
+		{name: "hyperv", from: containertypes.IsolationHyperV, to: swarmapi.ContainerIsolationHyperV},
162
+		{name: "proCess", from: containertypes.Isolation("proCess"), to: swarmapi.ContainerIsolationProcess},
163
+		{name: "hypErv", from: containertypes.Isolation("hypErv"), to: swarmapi.ContainerIsolationHyperV},
164
+	}
165
+	for _, c := range cases {
166
+		t.Run(c.name, func(t *testing.T) {
167
+			s := swarmtypes.ServiceSpec{
168
+				TaskTemplate: swarmtypes.TaskSpec{
169
+					ContainerSpec: &swarmtypes.ContainerSpec{
170
+						Image:     "alpine:latest",
171
+						Isolation: c.from,
172
+					},
173
+				},
174
+				Mode: swarmtypes.ServiceMode{
175
+					Global: &swarmtypes.GlobalService{},
176
+				},
177
+			}
178
+			res, err := ServiceSpecToGRPC(s)
179
+			require.NoError(t, err)
180
+			v, ok := res.Task.Runtime.(*swarmapi.TaskSpec_Container)
181
+			if !ok {
182
+				t.Fatal("expected type swarmapi.TaskSpec_Container")
183
+			}
184
+			require.Equal(t, c.to, v.Container.Isolation)
185
+		})
186
+	}
187
+}
188
+
189
+func TestServiceConvertFromGRPCIsolation(t *testing.T) {
190
+	cases := []struct {
191
+		name string
192
+		from swarmapi.ContainerSpec_Isolation
193
+		to   containertypes.Isolation
194
+	}{
195
+		{name: "default", to: containertypes.IsolationDefault, from: swarmapi.ContainerIsolationDefault},
196
+		{name: "process", to: containertypes.IsolationProcess, from: swarmapi.ContainerIsolationProcess},
197
+		{name: "hyperv", to: containertypes.IsolationHyperV, from: swarmapi.ContainerIsolationHyperV},
198
+	}
199
+	for _, c := range cases {
200
+		t.Run(c.name, func(t *testing.T) {
201
+			gs := swarmapi.Service{
202
+				Meta: swarmapi.Meta{
203
+					Version: swarmapi.Version{
204
+						Index: 1,
205
+					},
206
+					CreatedAt: nil,
207
+					UpdatedAt: nil,
208
+				},
209
+				SpecVersion: &swarmapi.Version{
210
+					Index: 1,
211
+				},
212
+				Spec: swarmapi.ServiceSpec{
213
+					Task: swarmapi.TaskSpec{
214
+						Runtime: &swarmapi.TaskSpec_Container{
215
+							Container: &swarmapi.ContainerSpec{
216
+								Image:     "alpine:latest",
217
+								Isolation: c.from,
218
+							},
219
+						},
220
+					},
221
+				},
222
+			}
223
+
224
+			svc, err := ServiceFromGRPC(gs)
225
+			if err != nil {
226
+				t.Fatal(err)
227
+			}
228
+
229
+			require.Equal(t, c.to, svc.Spec.TaskTemplate.ContainerSpec.Isolation)
230
+		})
231
+	}
232
+}
... ...
@@ -168,6 +168,10 @@ func (c *containerConfig) portBindings() nat.PortMap {
168 168
 	return portBindings
169 169
 }
170 170
 
171
+func (c *containerConfig) isolation() enginecontainer.Isolation {
172
+	return convert.IsolationFromGRPC(c.spec().Isolation)
173
+}
174
+
171 175
 func (c *containerConfig) exposedPorts() map[nat.Port]struct{} {
172 176
 	exposedPorts := make(map[nat.Port]struct{})
173 177
 	if c.task.Endpoint == nil {
... ...
@@ -350,6 +354,7 @@ func (c *containerConfig) hostConfig() *enginecontainer.HostConfig {
350 350
 		PortBindings:   c.portBindings(),
351 351
 		Mounts:         c.mounts(),
352 352
 		ReadonlyRootfs: c.spec().ReadOnly,
353
+		Isolation:      c.isolation(),
353 354
 	}
354 355
 
355 356
 	if c.spec().DNSConfig != nil {
356 357
new file mode 100644
... ...
@@ -0,0 +1,37 @@
0
+package container
1
+
2
+import (
3
+	"testing"
4
+
5
+	container "github.com/docker/docker/api/types/container"
6
+	swarmapi "github.com/docker/swarmkit/api"
7
+	"github.com/stretchr/testify/require"
8
+)
9
+
10
+func TestIsolationConversion(t *testing.T) {
11
+	cases := []struct {
12
+		name string
13
+		from swarmapi.ContainerSpec_Isolation
14
+		to   container.Isolation
15
+	}{
16
+		{name: "default", from: swarmapi.ContainerIsolationDefault, to: container.IsolationDefault},
17
+		{name: "process", from: swarmapi.ContainerIsolationProcess, to: container.IsolationProcess},
18
+		{name: "hyperv", from: swarmapi.ContainerIsolationHyperV, to: container.IsolationHyperV},
19
+	}
20
+	for _, c := range cases {
21
+		t.Run(c.name, func(t *testing.T) {
22
+			task := swarmapi.Task{
23
+				Spec: swarmapi.TaskSpec{
24
+					Runtime: &swarmapi.TaskSpec_Container{
25
+						Container: &swarmapi.ContainerSpec{
26
+							Image:     "alpine:latest",
27
+							Isolation: c.from,
28
+						},
29
+					},
30
+				},
31
+			}
32
+			config := containerConfig{task: &task}
33
+			require.Equal(t, c.to, config.hostConfig().Isolation)
34
+		})
35
+	}
36
+}
... ...
@@ -23,6 +23,7 @@ keywords: "API, Docker, rcli, REST, documentation"
23 23
   If `Error` is `null`, container removal has succeeded, otherwise
24 24
   the test of an error message indicating why container removal has failed
25 25
   is available from `Error.Message` field.
26
+* `POST /services/create` and `POST /services/(id)/update` now accept an `Isolation` field on container spec
26 27
 
27 28
 ## v1.33 API changes
28 29
 
... ...
@@ -198,6 +198,23 @@ func (d *Swarm) CheckServiceTasksInState(service string, state swarm.TaskState,
198 198
 	}
199 199
 }
200 200
 
201
+// CheckServiceTasksInStateWithError returns the number of tasks with a matching state,
202
+// and optional message substring.
203
+func (d *Swarm) CheckServiceTasksInStateWithError(service string, state swarm.TaskState, errorMessage string) func(*check.C) (interface{}, check.CommentInterface) {
204
+	return func(c *check.C) (interface{}, check.CommentInterface) {
205
+		tasks := d.GetServiceTasks(c, service)
206
+		var count int
207
+		for _, task := range tasks {
208
+			if task.Status.State == state {
209
+				if errorMessage == "" || strings.Contains(task.Status.Err, errorMessage) {
210
+					count++
211
+				}
212
+			}
213
+		}
214
+		return count, nil
215
+	}
216
+}
217
+
201 218
 // CheckServiceRunningTasks returns the number of running tasks for the specified service
202 219
 func (d *Swarm) CheckServiceRunningTasks(service string) func(*check.C) (interface{}, check.CommentInterface) {
203 220
 	return d.CheckServiceTasksInState(service, swarm.TaskStateRunning, "")
... ...
@@ -19,7 +19,7 @@ func (s *DockerSwarmSuite) TestSwarmVolumePlugin(c *check.C) {
19 19
 	c.Assert(err, checker.IsNil, check.Commentf(out))
20 20
 
21 21
 	// Make sure task stays pending before plugin is available
22
-	waitAndAssert(c, defaultReconciliationTimeout, d.CheckServiceTasksInState("top", swarm.TaskStatePending, "missing plugin on 1 node"), checker.Equals, 1)
22
+	waitAndAssert(c, defaultReconciliationTimeout, d.CheckServiceTasksInStateWithError("top", swarm.TaskStatePending, "missing plugin on 1 node"), checker.Equals, 1)
23 23
 
24 24
 	plugin := newVolumePlugin(c, "customvolumedriver")
25 25
 	defer plugin.Close()
... ...
@@ -6,6 +6,7 @@ import (
6 6
 	"time"
7 7
 
8 8
 	"github.com/docker/docker/api/types"
9
+	"github.com/docker/docker/api/types/container"
9 10
 	"github.com/docker/docker/api/types/filters"
10 11
 	"github.com/docker/docker/api/types/swarm"
11 12
 	"github.com/docker/docker/client"
... ...
@@ -76,6 +77,7 @@ func fullSwarmServiceSpec(name string, replicas uint64) swarm.ServiceSpec {
76 76
 					Nameservers: []string{"8.8.8.8"},
77 77
 					Search:      []string{"somedomain"},
78 78
 				},
79
+				Isolation: container.IsolationDefault,
79 80
 			},
80 81
 			RestartPolicy: &swarm.RestartPolicy{
81 82
 				Delay:       &restartDelay,
... ...
@@ -103,7 +103,6 @@ github.com/googleapis/gax-go da06d194a00e19ce00d9011a13931c3f6f6887c7
103 103
 google.golang.org/genproto d80a6e20e776b0b17a324d0ba1ab50a39c8e8944
104 104
 
105 105
 # containerd
106
-github.com/stevvooe/continuity cd7a8e21e2b6f84799f5dd4b65faf49c8d3ee02d
107 106
 github.com/containerd/containerd 992280e8e265f491f7a624ab82f3e238be086e49
108 107
 github.com/containerd/fifo fbfb6a11ec671efbe94ad1c12c2e98773f19e1e6
109 108
 github.com/containerd/continuity 35d55c5e8dd23b32037d56cf97174aff3efdfa83
... ...
@@ -114,7 +113,7 @@ github.com/containerd/typeurl f6943554a7e7e88b3c14aad190bf05932da84788
114 114
 github.com/dmcgowan/go-tar 2e2c51242e8993c50445dab7c03c8e7febddd0cf
115 115
 
116 116
 # cluster
117
-github.com/docker/swarmkit 872861d2ae46958af7ead1d5fffb092c73afbaf0
117
+github.com/docker/swarmkit 28f91d87bd3f75fd039dbb9be49bfd2381019261
118 118
 github.com/gogo/protobuf v0.4
119 119
 github.com/cloudflare/cfssl 7fb22c8cba7ecaf98e4082d22d65800cf45e042a
120 120
 github.com/google/certificate-transparency d90e65c3a07988180c5b1ece71791c0b6506826e
... ...
@@ -119,6 +119,7 @@ func Resolve(ctx context.Context, task *api.Task, executor Executor) (Controller
119 119
 		// we always want to proceed to accepted when we resolve the controller
120 120
 		status.Message = "accepted"
121 121
 		status.State = api.TaskStateAccepted
122
+		status.Err = ""
122 123
 	}
123 124
 
124 125
 	return ctlr, status, err
... ...
@@ -158,6 +159,7 @@ func Do(ctx context.Context, task *api.Task, ctlr Controller) (*api.TaskStatus,
158 158
 		current := status.State
159 159
 		status.State = state
160 160
 		status.Message = msg
161
+		status.Err = ""
161 162
 
162 163
 		if current > state {
163 164
 			panic("invalid state transition")
... ...
@@ -10,6 +10,7 @@ import math "math"
10 10
 import _ "github.com/gogo/protobuf/gogoproto"
11 11
 import google_protobuf1 "github.com/gogo/protobuf/types"
12 12
 import google_protobuf3 "github.com/gogo/protobuf/types"
13
+import google_protobuf4 "github.com/gogo/protobuf/types"
13 14
 
14 15
 import github_com_docker_swarmkit_api_deepcopy "github.com/docker/swarmkit/api/deepcopy"
15 16
 
... ...
@@ -74,6 +75,35 @@ func (x NodeSpec_Availability) String() string {
74 74
 }
75 75
 func (NodeSpec_Availability) EnumDescriptor() ([]byte, []int) { return fileDescriptorSpecs, []int{0, 1} }
76 76
 
77
+type ContainerSpec_Isolation int32
78
+
79
+const (
80
+	// ISOLATION_DEFAULT uses whatever default value from the container runtime
81
+	ContainerIsolationDefault ContainerSpec_Isolation = 0
82
+	// ISOLATION_PROCESS forces windows container isolation
83
+	ContainerIsolationProcess ContainerSpec_Isolation = 1
84
+	// ISOLATION_HYPERV forces Hyper-V isolation
85
+	ContainerIsolationHyperV ContainerSpec_Isolation = 2
86
+)
87
+
88
+var ContainerSpec_Isolation_name = map[int32]string{
89
+	0: "ISOLATION_DEFAULT",
90
+	1: "ISOLATION_PROCESS",
91
+	2: "ISOLATION_HYPERV",
92
+}
93
+var ContainerSpec_Isolation_value = map[string]int32{
94
+	"ISOLATION_DEFAULT": 0,
95
+	"ISOLATION_PROCESS": 1,
96
+	"ISOLATION_HYPERV":  2,
97
+}
98
+
99
+func (x ContainerSpec_Isolation) String() string {
100
+	return proto.EnumName(ContainerSpec_Isolation_name, int32(x))
101
+}
102
+func (ContainerSpec_Isolation) EnumDescriptor() ([]byte, []int) {
103
+	return fileDescriptorSpecs, []int{8, 0}
104
+}
105
+
77 106
 // ResolutionMode specifies the mode of resolution to use for
78 107
 // internal loadbalancing between tasks which are all within
79 108
 // the cluster. This is sometimes calls east-west data path.
... ...
@@ -542,6 +572,8 @@ type ContainerSpec struct {
542 542
 	Groups []string `protobuf:"bytes,11,rep,name=groups" json:"groups,omitempty"`
543 543
 	// Privileges specifies security configuration/permissions.
544 544
 	Privileges *Privileges `protobuf:"bytes,22,opt,name=privileges" json:"privileges,omitempty"`
545
+	// Init declares that a custom init will be running inside the container, if null, use the daemon's configured settings
546
+	Init *google_protobuf4.BoolValue `protobuf:"bytes,23,opt,name=init" json:"init,omitempty"`
545 547
 	// TTY declares that a TTY should be attached to the standard streams,
546 548
 	// including stdin if it is still open.
547 549
 	TTY bool `protobuf:"varint,13,opt,name=tty,proto3" json:"tty,omitempty"`
... ...
@@ -585,6 +617,9 @@ type ContainerSpec struct {
585 585
 	// task will exit and a new task will be rescheduled elsewhere. A container
586 586
 	// is considered unhealthy after `Retries` number of consecutive failures.
587 587
 	Healthcheck *HealthConfig `protobuf:"bytes,16,opt,name=healthcheck" json:"healthcheck,omitempty"`
588
+	// Isolation defines the isolation level for windows containers (default, process, hyperv).
589
+	// Runtimes that don't support it ignore that field
590
+	Isolation ContainerSpec_Isolation `protobuf:"varint,24,opt,name=isolation,proto3,enum=docker.swarmkit.v1.ContainerSpec_Isolation" json:"isolation,omitempty"`
588 591
 }
589 592
 
590 593
 func (m *ContainerSpec) Reset()                    { *m = ContainerSpec{} }
... ...
@@ -830,6 +865,7 @@ func init() {
830 830
 	proto.RegisterType((*ConfigSpec)(nil), "docker.swarmkit.v1.ConfigSpec")
831 831
 	proto.RegisterEnum("docker.swarmkit.v1.NodeSpec_Membership", NodeSpec_Membership_name, NodeSpec_Membership_value)
832 832
 	proto.RegisterEnum("docker.swarmkit.v1.NodeSpec_Availability", NodeSpec_Availability_name, NodeSpec_Availability_value)
833
+	proto.RegisterEnum("docker.swarmkit.v1.ContainerSpec_Isolation", ContainerSpec_Isolation_name, ContainerSpec_Isolation_value)
833 834
 	proto.RegisterEnum("docker.swarmkit.v1.EndpointSpec_ResolutionMode", EndpointSpec_ResolutionMode_name, EndpointSpec_ResolutionMode_value)
834 835
 }
835 836
 
... ...
@@ -1090,6 +1126,10 @@ func (m *ContainerSpec) CopyFrom(src interface{}) {
1090 1090
 		m.Privileges = &Privileges{}
1091 1091
 		github_com_docker_swarmkit_api_deepcopy.Copy(m.Privileges, o.Privileges)
1092 1092
 	}
1093
+	if o.Init != nil {
1094
+		m.Init = &google_protobuf4.BoolValue{}
1095
+		github_com_docker_swarmkit_api_deepcopy.Copy(m.Init, o.Init)
1096
+	}
1093 1097
 	if o.Mounts != nil {
1094 1098
 		m.Mounts = make([]Mount, len(o.Mounts))
1095 1099
 		for i := range m.Mounts {
... ...
@@ -1996,6 +2036,25 @@ func (m *ContainerSpec) MarshalTo(dAtA []byte) (int, error) {
1996 1996
 		}
1997 1997
 		i += n23
1998 1998
 	}
1999
+	if m.Init != nil {
2000
+		dAtA[i] = 0xba
2001
+		i++
2002
+		dAtA[i] = 0x1
2003
+		i++
2004
+		i = encodeVarintSpecs(dAtA, i, uint64(m.Init.Size()))
2005
+		n24, err := m.Init.MarshalTo(dAtA[i:])
2006
+		if err != nil {
2007
+			return 0, err
2008
+		}
2009
+		i += n24
2010
+	}
2011
+	if m.Isolation != 0 {
2012
+		dAtA[i] = 0xc0
2013
+		i++
2014
+		dAtA[i] = 0x1
2015
+		i++
2016
+		i = encodeVarintSpecs(dAtA, i, uint64(m.Isolation))
2017
+	}
1999 2018
 	return i, nil
2000 2019
 }
2001 2020
 
... ...
@@ -2141,20 +2200,20 @@ func (m *NetworkSpec) MarshalTo(dAtA []byte) (int, error) {
2141 2141
 	dAtA[i] = 0xa
2142 2142
 	i++
2143 2143
 	i = encodeVarintSpecs(dAtA, i, uint64(m.Annotations.Size()))
2144
-	n24, err := m.Annotations.MarshalTo(dAtA[i:])
2144
+	n25, err := m.Annotations.MarshalTo(dAtA[i:])
2145 2145
 	if err != nil {
2146 2146
 		return 0, err
2147 2147
 	}
2148
-	i += n24
2148
+	i += n25
2149 2149
 	if m.DriverConfig != nil {
2150 2150
 		dAtA[i] = 0x12
2151 2151
 		i++
2152 2152
 		i = encodeVarintSpecs(dAtA, i, uint64(m.DriverConfig.Size()))
2153
-		n25, err := m.DriverConfig.MarshalTo(dAtA[i:])
2153
+		n26, err := m.DriverConfig.MarshalTo(dAtA[i:])
2154 2154
 		if err != nil {
2155 2155
 			return 0, err
2156 2156
 		}
2157
-		i += n25
2157
+		i += n26
2158 2158
 	}
2159 2159
 	if m.Ipv6Enabled {
2160 2160
 		dAtA[i] = 0x18
... ...
@@ -2180,11 +2239,11 @@ func (m *NetworkSpec) MarshalTo(dAtA []byte) (int, error) {
2180 2180
 		dAtA[i] = 0x2a
2181 2181
 		i++
2182 2182
 		i = encodeVarintSpecs(dAtA, i, uint64(m.IPAM.Size()))
2183
-		n26, err := m.IPAM.MarshalTo(dAtA[i:])
2183
+		n27, err := m.IPAM.MarshalTo(dAtA[i:])
2184 2184
 		if err != nil {
2185 2185
 			return 0, err
2186 2186
 		}
2187
-		i += n26
2187
+		i += n27
2188 2188
 	}
2189 2189
 	if m.Attachable {
2190 2190
 		dAtA[i] = 0x30
... ...
@@ -2207,11 +2266,11 @@ func (m *NetworkSpec) MarshalTo(dAtA []byte) (int, error) {
2207 2207
 		i++
2208 2208
 	}
2209 2209
 	if m.ConfigFrom != nil {
2210
-		nn27, err := m.ConfigFrom.MarshalTo(dAtA[i:])
2210
+		nn28, err := m.ConfigFrom.MarshalTo(dAtA[i:])
2211 2211
 		if err != nil {
2212 2212
 			return 0, err
2213 2213
 		}
2214
-		i += nn27
2214
+		i += nn28
2215 2215
 	}
2216 2216
 	return i, nil
2217 2217
 }
... ...
@@ -2242,67 +2301,67 @@ func (m *ClusterSpec) MarshalTo(dAtA []byte) (int, error) {
2242 2242
 	dAtA[i] = 0xa
2243 2243
 	i++
2244 2244
 	i = encodeVarintSpecs(dAtA, i, uint64(m.Annotations.Size()))
2245
-	n28, err := m.Annotations.MarshalTo(dAtA[i:])
2245
+	n29, err := m.Annotations.MarshalTo(dAtA[i:])
2246 2246
 	if err != nil {
2247 2247
 		return 0, err
2248 2248
 	}
2249
-	i += n28
2249
+	i += n29
2250 2250
 	dAtA[i] = 0x12
2251 2251
 	i++
2252 2252
 	i = encodeVarintSpecs(dAtA, i, uint64(m.AcceptancePolicy.Size()))
2253
-	n29, err := m.AcceptancePolicy.MarshalTo(dAtA[i:])
2253
+	n30, err := m.AcceptancePolicy.MarshalTo(dAtA[i:])
2254 2254
 	if err != nil {
2255 2255
 		return 0, err
2256 2256
 	}
2257
-	i += n29
2257
+	i += n30
2258 2258
 	dAtA[i] = 0x1a
2259 2259
 	i++
2260 2260
 	i = encodeVarintSpecs(dAtA, i, uint64(m.Orchestration.Size()))
2261
-	n30, err := m.Orchestration.MarshalTo(dAtA[i:])
2261
+	n31, err := m.Orchestration.MarshalTo(dAtA[i:])
2262 2262
 	if err != nil {
2263 2263
 		return 0, err
2264 2264
 	}
2265
-	i += n30
2265
+	i += n31
2266 2266
 	dAtA[i] = 0x22
2267 2267
 	i++
2268 2268
 	i = encodeVarintSpecs(dAtA, i, uint64(m.Raft.Size()))
2269
-	n31, err := m.Raft.MarshalTo(dAtA[i:])
2269
+	n32, err := m.Raft.MarshalTo(dAtA[i:])
2270 2270
 	if err != nil {
2271 2271
 		return 0, err
2272 2272
 	}
2273
-	i += n31
2273
+	i += n32
2274 2274
 	dAtA[i] = 0x2a
2275 2275
 	i++
2276 2276
 	i = encodeVarintSpecs(dAtA, i, uint64(m.Dispatcher.Size()))
2277
-	n32, err := m.Dispatcher.MarshalTo(dAtA[i:])
2277
+	n33, err := m.Dispatcher.MarshalTo(dAtA[i:])
2278 2278
 	if err != nil {
2279 2279
 		return 0, err
2280 2280
 	}
2281
-	i += n32
2281
+	i += n33
2282 2282
 	dAtA[i] = 0x32
2283 2283
 	i++
2284 2284
 	i = encodeVarintSpecs(dAtA, i, uint64(m.CAConfig.Size()))
2285
-	n33, err := m.CAConfig.MarshalTo(dAtA[i:])
2285
+	n34, err := m.CAConfig.MarshalTo(dAtA[i:])
2286 2286
 	if err != nil {
2287 2287
 		return 0, err
2288 2288
 	}
2289
-	i += n33
2289
+	i += n34
2290 2290
 	dAtA[i] = 0x3a
2291 2291
 	i++
2292 2292
 	i = encodeVarintSpecs(dAtA, i, uint64(m.TaskDefaults.Size()))
2293
-	n34, err := m.TaskDefaults.MarshalTo(dAtA[i:])
2293
+	n35, err := m.TaskDefaults.MarshalTo(dAtA[i:])
2294 2294
 	if err != nil {
2295 2295
 		return 0, err
2296 2296
 	}
2297
-	i += n34
2297
+	i += n35
2298 2298
 	dAtA[i] = 0x42
2299 2299
 	i++
2300 2300
 	i = encodeVarintSpecs(dAtA, i, uint64(m.EncryptionConfig.Size()))
2301
-	n35, err := m.EncryptionConfig.MarshalTo(dAtA[i:])
2301
+	n36, err := m.EncryptionConfig.MarshalTo(dAtA[i:])
2302 2302
 	if err != nil {
2303 2303
 		return 0, err
2304 2304
 	}
2305
-	i += n35
2305
+	i += n36
2306 2306
 	return i, nil
2307 2307
 }
2308 2308
 
... ...
@@ -2324,11 +2383,11 @@ func (m *SecretSpec) MarshalTo(dAtA []byte) (int, error) {
2324 2324
 	dAtA[i] = 0xa
2325 2325
 	i++
2326 2326
 	i = encodeVarintSpecs(dAtA, i, uint64(m.Annotations.Size()))
2327
-	n36, err := m.Annotations.MarshalTo(dAtA[i:])
2327
+	n37, err := m.Annotations.MarshalTo(dAtA[i:])
2328 2328
 	if err != nil {
2329 2329
 		return 0, err
2330 2330
 	}
2331
-	i += n36
2331
+	i += n37
2332 2332
 	if len(m.Data) > 0 {
2333 2333
 		dAtA[i] = 0x12
2334 2334
 		i++
... ...
@@ -2339,21 +2398,21 @@ func (m *SecretSpec) MarshalTo(dAtA []byte) (int, error) {
2339 2339
 		dAtA[i] = 0x1a
2340 2340
 		i++
2341 2341
 		i = encodeVarintSpecs(dAtA, i, uint64(m.Templating.Size()))
2342
-		n37, err := m.Templating.MarshalTo(dAtA[i:])
2342
+		n38, err := m.Templating.MarshalTo(dAtA[i:])
2343 2343
 		if err != nil {
2344 2344
 			return 0, err
2345 2345
 		}
2346
-		i += n37
2346
+		i += n38
2347 2347
 	}
2348 2348
 	if m.Driver != nil {
2349 2349
 		dAtA[i] = 0x22
2350 2350
 		i++
2351 2351
 		i = encodeVarintSpecs(dAtA, i, uint64(m.Driver.Size()))
2352
-		n38, err := m.Driver.MarshalTo(dAtA[i:])
2352
+		n39, err := m.Driver.MarshalTo(dAtA[i:])
2353 2353
 		if err != nil {
2354 2354
 			return 0, err
2355 2355
 		}
2356
-		i += n38
2356
+		i += n39
2357 2357
 	}
2358 2358
 	return i, nil
2359 2359
 }
... ...
@@ -2376,11 +2435,11 @@ func (m *ConfigSpec) MarshalTo(dAtA []byte) (int, error) {
2376 2376
 	dAtA[i] = 0xa
2377 2377
 	i++
2378 2378
 	i = encodeVarintSpecs(dAtA, i, uint64(m.Annotations.Size()))
2379
-	n39, err := m.Annotations.MarshalTo(dAtA[i:])
2379
+	n40, err := m.Annotations.MarshalTo(dAtA[i:])
2380 2380
 	if err != nil {
2381 2381
 		return 0, err
2382 2382
 	}
2383
-	i += n39
2383
+	i += n40
2384 2384
 	if len(m.Data) > 0 {
2385 2385
 		dAtA[i] = 0x12
2386 2386
 		i++
... ...
@@ -2391,11 +2450,11 @@ func (m *ConfigSpec) MarshalTo(dAtA []byte) (int, error) {
2391 2391
 		dAtA[i] = 0x1a
2392 2392
 		i++
2393 2393
 		i = encodeVarintSpecs(dAtA, i, uint64(m.Templating.Size()))
2394
-		n40, err := m.Templating.MarshalTo(dAtA[i:])
2394
+		n41, err := m.Templating.MarshalTo(dAtA[i:])
2395 2395
 		if err != nil {
2396 2396
 			return 0, err
2397 2397
 		}
2398
-		i += n40
2398
+		i += n41
2399 2399
 	}
2400 2400
 	return i, nil
2401 2401
 }
... ...
@@ -2721,6 +2780,13 @@ func (m *ContainerSpec) Size() (n int) {
2721 2721
 		l = m.Privileges.Size()
2722 2722
 		n += 2 + l + sovSpecs(uint64(l))
2723 2723
 	}
2724
+	if m.Init != nil {
2725
+		l = m.Init.Size()
2726
+		n += 2 + l + sovSpecs(uint64(l))
2727
+	}
2728
+	if m.Isolation != 0 {
2729
+		n += 2 + sovSpecs(uint64(m.Isolation))
2730
+	}
2724 2731
 	return n
2725 2732
 }
2726 2733
 
... ...
@@ -3066,6 +3132,8 @@ func (this *ContainerSpec) String() string {
3066 3066
 		`StopSignal:` + fmt.Sprintf("%v", this.StopSignal) + `,`,
3067 3067
 		`Configs:` + strings.Replace(fmt.Sprintf("%v", this.Configs), "ConfigReference", "ConfigReference", 1) + `,`,
3068 3068
 		`Privileges:` + strings.Replace(fmt.Sprintf("%v", this.Privileges), "Privileges", "Privileges", 1) + `,`,
3069
+		`Init:` + strings.Replace(fmt.Sprintf("%v", this.Init), "BoolValue", "google_protobuf4.BoolValue", 1) + `,`,
3070
+		`Isolation:` + fmt.Sprintf("%v", this.Isolation) + `,`,
3069 3071
 		`}`,
3070 3072
 	}, "")
3071 3073
 	return s
... ...
@@ -5141,6 +5209,58 @@ func (m *ContainerSpec) Unmarshal(dAtA []byte) error {
5141 5141
 				return err
5142 5142
 			}
5143 5143
 			iNdEx = postIndex
5144
+		case 23:
5145
+			if wireType != 2 {
5146
+				return fmt.Errorf("proto: wrong wireType = %d for field Init", wireType)
5147
+			}
5148
+			var msglen int
5149
+			for shift := uint(0); ; shift += 7 {
5150
+				if shift >= 64 {
5151
+					return ErrIntOverflowSpecs
5152
+				}
5153
+				if iNdEx >= l {
5154
+					return io.ErrUnexpectedEOF
5155
+				}
5156
+				b := dAtA[iNdEx]
5157
+				iNdEx++
5158
+				msglen |= (int(b) & 0x7F) << shift
5159
+				if b < 0x80 {
5160
+					break
5161
+				}
5162
+			}
5163
+			if msglen < 0 {
5164
+				return ErrInvalidLengthSpecs
5165
+			}
5166
+			postIndex := iNdEx + msglen
5167
+			if postIndex > l {
5168
+				return io.ErrUnexpectedEOF
5169
+			}
5170
+			if m.Init == nil {
5171
+				m.Init = &google_protobuf4.BoolValue{}
5172
+			}
5173
+			if err := m.Init.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
5174
+				return err
5175
+			}
5176
+			iNdEx = postIndex
5177
+		case 24:
5178
+			if wireType != 0 {
5179
+				return fmt.Errorf("proto: wrong wireType = %d for field Isolation", wireType)
5180
+			}
5181
+			m.Isolation = 0
5182
+			for shift := uint(0); ; shift += 7 {
5183
+				if shift >= 64 {
5184
+					return ErrIntOverflowSpecs
5185
+				}
5186
+				if iNdEx >= l {
5187
+					return io.ErrUnexpectedEOF
5188
+				}
5189
+				b := dAtA[iNdEx]
5190
+				iNdEx++
5191
+				m.Isolation |= (ContainerSpec_Isolation(b) & 0x7F) << shift
5192
+				if b < 0x80 {
5193
+					break
5194
+				}
5195
+			}
5144 5196
 		default:
5145 5197
 			iNdEx = preIndex
5146 5198
 			skippy, err := skipSpecs(dAtA[iNdEx:])
... ...
@@ -6452,129 +6572,138 @@ var (
6452 6452
 func init() { proto.RegisterFile("github.com/docker/swarmkit/api/specs.proto", fileDescriptorSpecs) }
6453 6453
 
6454 6454
 var fileDescriptorSpecs = []byte{
6455
-	// 1975 bytes of a gzipped FileDescriptorProto
6456
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x57, 0xcf, 0x6f, 0x1b, 0xb9,
6457
-	0x15, 0xb6, 0x6c, 0x59, 0x3f, 0xde, 0xc8, 0x89, 0xc2, 0xcd, 0xa6, 0x13, 0xa5, 0x6b, 0x2b, 0xda,
6458
-	0x6c, 0xea, 0xdd, 0x45, 0x25, 0xd4, 0x2d, 0xb6, 0xd9, 0x4d, 0xb7, 0xad, 0x64, 0xa9, 0x8e, 0x9b,
6459
-	0xc6, 0x11, 0x68, 0x6f, 0xda, 0x00, 0x05, 0x04, 0x6a, 0x86, 0x1e, 0x0d, 0x3c, 0x1a, 0x4e, 0x39,
6460
-	0x1c, 0x2d, 0x74, 0xeb, 0x71, 0x91, 0x1e, 0x7b, 0x0e, 0x7a, 0x28, 0x7a, 0xef, 0x9f, 0x91, 0x63,
6461
-	0x8f, 0xed, 0xc5, 0xe8, 0xea, 0x5f, 0xe8, 0xad, 0x97, 0x16, 0xe4, 0x70, 0x46, 0xa3, 0x64, 0x6c,
6462
-	0x07, 0x68, 0x0e, 0xbd, 0x91, 0x8f, 0xdf, 0xf7, 0x48, 0x3e, 0x7e, 0x8f, 0x7c, 0x84, 0x4f, 0x1c,
6463
-	0x57, 0x4c, 0xa2, 0x71, 0xdb, 0x62, 0xd3, 0x8e, 0xcd, 0xac, 0x33, 0xca, 0x3b, 0xe1, 0xd7, 0x84,
6464
-	0x4f, 0xcf, 0x5c, 0xd1, 0x21, 0x81, 0xdb, 0x09, 0x03, 0x6a, 0x85, 0xed, 0x80, 0x33, 0xc1, 0x10,
6465
-	0x8a, 0x01, 0xed, 0x04, 0xd0, 0x9e, 0xfd, 0xa0, 0x71, 0x15, 0x5f, 0xcc, 0x03, 0xaa, 0xf9, 0x8d,
6466
-	0x9b, 0x0e, 0x73, 0x98, 0x6a, 0x76, 0x64, 0x4b, 0x5b, 0xb7, 0x1d, 0xc6, 0x1c, 0x8f, 0x76, 0x54,
6467
-	0x6f, 0x1c, 0x9d, 0x76, 0xec, 0x88, 0x13, 0xe1, 0x32, 0x5f, 0x8f, 0xdf, 0x7e, 0x7d, 0x9c, 0xf8,
6468
-	0xf3, 0x78, 0xa8, 0xf5, 0xb2, 0x08, 0x95, 0x23, 0x66, 0xd3, 0xe3, 0x80, 0x5a, 0xe8, 0x00, 0x0c,
6469
-	0xe2, 0xfb, 0x4c, 0x28, 0x6e, 0x68, 0x16, 0x9a, 0x85, 0x5d, 0x63, 0x6f, 0xa7, 0xfd, 0xe6, 0x9a,
6470
-	0xdb, 0xdd, 0x25, 0xac, 0x57, 0x7c, 0x75, 0xbe, 0xb3, 0x86, 0xb3, 0x4c, 0xf4, 0x33, 0xa8, 0xd9,
6471
-	0x34, 0x74, 0x39, 0xb5, 0x47, 0x9c, 0x79, 0xd4, 0x5c, 0x6f, 0x16, 0x76, 0xaf, 0xed, 0x7d, 0x37,
6472
-	0xcf, 0x93, 0x9c, 0x1c, 0x33, 0x8f, 0x62, 0x43, 0x33, 0x64, 0x07, 0x1d, 0x00, 0x4c, 0xe9, 0x74,
6473
-	0x4c, 0x79, 0x38, 0x71, 0x03, 0x73, 0x43, 0xd1, 0xbf, 0x77, 0x11, 0x5d, 0xae, 0xbd, 0xfd, 0x24,
6474
-	0x85, 0xe3, 0x0c, 0x15, 0x3d, 0x81, 0x1a, 0x99, 0x11, 0xd7, 0x23, 0x63, 0xd7, 0x73, 0xc5, 0xdc,
6475
-	0x2c, 0x2a, 0x57, 0x1f, 0x5f, 0xea, 0xaa, 0x9b, 0x21, 0xe0, 0x15, 0x7a, 0xcb, 0x06, 0x58, 0x4e,
6476
-	0x84, 0xee, 0x43, 0x79, 0x38, 0x38, 0xea, 0x1f, 0x1e, 0x1d, 0xd4, 0xd7, 0x1a, 0xb7, 0x5f, 0xbc,
6477
-	0x6c, 0xbe, 0x2f, 0x7d, 0x2c, 0x01, 0x43, 0xea, 0xdb, 0xae, 0xef, 0xa0, 0x5d, 0xa8, 0x74, 0xf7,
6478
-	0xf7, 0x07, 0xc3, 0x93, 0x41, 0xbf, 0x5e, 0x68, 0x34, 0x5e, 0xbc, 0x6c, 0xde, 0x5a, 0x05, 0x76,
6479
-	0x2d, 0x8b, 0x06, 0x82, 0xda, 0x8d, 0xe2, 0x37, 0x7f, 0xde, 0x5e, 0x6b, 0x7d, 0x53, 0x80, 0x5a,
6480
-	0x76, 0x11, 0xe8, 0x3e, 0x94, 0xba, 0xfb, 0x27, 0x87, 0xcf, 0x06, 0xf5, 0xb5, 0x25, 0x3d, 0x8b,
6481
-	0xe8, 0x5a, 0xc2, 0x9d, 0x51, 0x74, 0x0f, 0x36, 0x87, 0xdd, 0xaf, 0x8e, 0x07, 0xf5, 0xc2, 0x72,
6482
-	0x39, 0x59, 0xd8, 0x90, 0x44, 0xa1, 0x42, 0xf5, 0x71, 0xf7, 0xf0, 0xa8, 0xbe, 0x9e, 0x8f, 0xea,
6483
-	0x73, 0xe2, 0xfa, 0x7a, 0x29, 0x7f, 0x2a, 0x82, 0x71, 0x4c, 0xf9, 0xcc, 0xb5, 0xde, 0xb1, 0x44,
6484
-	0x3e, 0x83, 0xa2, 0x20, 0xe1, 0x99, 0x92, 0x86, 0x91, 0x2f, 0x8d, 0x13, 0x12, 0x9e, 0xc9, 0x49,
6485
-	0x35, 0x5d, 0xe1, 0xa5, 0x32, 0x38, 0x0d, 0x3c, 0xd7, 0x22, 0x82, 0xda, 0x4a, 0x19, 0xc6, 0xde,
6486
-	0x47, 0x79, 0x6c, 0x9c, 0xa2, 0xf4, 0xfa, 0x1f, 0xad, 0xe1, 0x0c, 0x15, 0x3d, 0x84, 0x92, 0xe3,
6487
-	0xb1, 0x31, 0xf1, 0x94, 0x26, 0x8c, 0xbd, 0xbb, 0x79, 0x4e, 0x0e, 0x14, 0x62, 0xe9, 0x40, 0x53,
6488
-	0xd0, 0x03, 0x28, 0x45, 0x81, 0x4d, 0x04, 0x35, 0x4b, 0x8a, 0xdc, 0xcc, 0x23, 0x7f, 0xa5, 0x10,
6489
-	0xfb, 0xcc, 0x3f, 0x75, 0x1d, 0xac, 0xf1, 0xe8, 0x31, 0x54, 0x7c, 0x2a, 0xbe, 0x66, 0xfc, 0x2c,
6490
-	0x34, 0xcb, 0xcd, 0x8d, 0x5d, 0x63, 0xef, 0xd3, 0x5c, 0x31, 0xc6, 0x98, 0xae, 0x10, 0xc4, 0x9a,
6491
-	0x4c, 0xa9, 0x2f, 0x62, 0x37, 0xbd, 0x75, 0xb3, 0x80, 0x53, 0x07, 0xe8, 0x27, 0x50, 0xa1, 0xbe,
6492
-	0x1d, 0x30, 0xd7, 0x17, 0x66, 0xe5, 0xe2, 0x85, 0x0c, 0x34, 0x46, 0x06, 0x13, 0xa7, 0x0c, 0xc9,
6493
-	0xe6, 0xcc, 0xf3, 0xc6, 0xc4, 0x3a, 0x33, 0xab, 0x6f, 0xb9, 0x8d, 0x94, 0xd1, 0x2b, 0x41, 0x71,
6494
-	0xca, 0x6c, 0xda, 0xea, 0xc0, 0x8d, 0x37, 0x42, 0x8d, 0x1a, 0x50, 0xd1, 0xa1, 0x8e, 0x35, 0x52,
6495
-	0xc4, 0x69, 0xbf, 0x75, 0x1d, 0xb6, 0x56, 0xc2, 0xda, 0xfa, 0xeb, 0x26, 0x54, 0x92, 0xb3, 0x46,
6496
-	0x5d, 0xa8, 0x5a, 0xcc, 0x17, 0xc4, 0xf5, 0x29, 0xd7, 0xf2, 0xca, 0x3d, 0x99, 0xfd, 0x04, 0x24,
6497
-	0x59, 0x8f, 0xd6, 0xf0, 0x92, 0x85, 0x7e, 0x01, 0x55, 0x4e, 0x43, 0x16, 0x71, 0x8b, 0x86, 0x5a,
6498
-	0x5f, 0xbb, 0xf9, 0x0a, 0x89, 0x41, 0x98, 0xfe, 0x2e, 0x72, 0x39, 0x95, 0x51, 0x0e, 0xf1, 0x92,
6499
-	0x8a, 0x1e, 0x42, 0x99, 0xd3, 0x50, 0x10, 0x2e, 0x2e, 0x93, 0x08, 0x8e, 0x21, 0x43, 0xe6, 0xb9,
6500
-	0xd6, 0x1c, 0x27, 0x0c, 0xf4, 0x10, 0xaa, 0x81, 0x47, 0x2c, 0xe5, 0xd5, 0xdc, 0x54, 0xf4, 0x0f,
6501
-	0xf2, 0xe8, 0xc3, 0x04, 0x84, 0x97, 0x78, 0xf4, 0x39, 0x80, 0xc7, 0x9c, 0x91, 0xcd, 0xdd, 0x19,
6502
-	0xe5, 0x5a, 0x62, 0x8d, 0x3c, 0x76, 0x5f, 0x21, 0x70, 0xd5, 0x63, 0x4e, 0xdc, 0x44, 0x07, 0xff,
6503
-	0x93, 0xbe, 0x32, 0xda, 0x7a, 0x0c, 0x40, 0xd2, 0x51, 0xad, 0xae, 0x8f, 0xdf, 0xca, 0x95, 0x3e,
6504
-	0x91, 0x0c, 0x1d, 0xdd, 0x85, 0xda, 0x29, 0xe3, 0x16, 0x1d, 0xe9, 0xac, 0xa9, 0x2a, 0x4d, 0x18,
6505
-	0xca, 0x16, 0xeb, 0x0b, 0xf5, 0xa0, 0xec, 0x50, 0x9f, 0x72, 0xd7, 0x32, 0x41, 0x4d, 0x76, 0x3f,
6506
-	0x37, 0x21, 0x63, 0x08, 0x8e, 0x7c, 0xe1, 0x4e, 0xa9, 0x9e, 0x29, 0x21, 0xa2, 0xdf, 0xc2, 0x7b,
6507
-	0xc9, 0xf1, 0x8d, 0x38, 0x3d, 0xa5, 0x9c, 0xfa, 0x52, 0x03, 0x86, 0x8a, 0xc3, 0x47, 0x97, 0x6b,
6508
-	0x40, 0xa3, 0xf5, 0x65, 0x83, 0xf8, 0xeb, 0x03, 0x61, 0xaf, 0x0a, 0x65, 0x1e, 0xcf, 0xdb, 0xfa,
6509
-	0x43, 0x41, 0xaa, 0xfe, 0x35, 0x04, 0xea, 0x80, 0x91, 0x4e, 0xef, 0xda, 0x4a, 0xbd, 0xd5, 0xde,
6510
-	0xb5, 0xc5, 0xf9, 0x0e, 0x24, 0xd8, 0xc3, 0xbe, 0xbc, 0x83, 0x74, 0xdb, 0x46, 0x03, 0xd8, 0x4a,
6511
-	0x09, 0xf2, 0x99, 0xd7, 0x0f, 0x65, 0xf3, 0xb2, 0x95, 0x9e, 0xcc, 0x03, 0x8a, 0x6b, 0x3c, 0xd3,
6512
-	0x6b, 0xfd, 0x06, 0xd0, 0x9b, 0x71, 0x41, 0x08, 0x8a, 0x67, 0xae, 0xaf, 0x97, 0x81, 0x55, 0x1b,
6513
-	0xb5, 0xa1, 0x1c, 0x90, 0xb9, 0xc7, 0x88, 0xad, 0x13, 0xe3, 0x66, 0x3b, 0xae, 0x0d, 0xda, 0x49,
6514
-	0x6d, 0xd0, 0xee, 0xfa, 0x73, 0x9c, 0x80, 0x5a, 0x8f, 0xe1, 0xfd, 0xdc, 0xe3, 0x45, 0x7b, 0x50,
6515
-	0x4b, 0x13, 0x6e, 0xb9, 0xd7, 0xeb, 0x8b, 0xf3, 0x1d, 0x23, 0xcd, 0xcc, 0xc3, 0x3e, 0x36, 0x52,
6516
-	0xd0, 0xa1, 0xdd, 0xfa, 0x63, 0x15, 0xb6, 0x56, 0xd2, 0x16, 0xdd, 0x84, 0x4d, 0x77, 0x4a, 0x1c,
6517
-	0xaa, 0xd7, 0x18, 0x77, 0xd0, 0x00, 0x4a, 0x1e, 0x19, 0x53, 0x4f, 0x26, 0xaf, 0x3c, 0xb8, 0xef,
6518
-	0x5f, 0x99, 0xff, 0xed, 0x5f, 0x29, 0xfc, 0xc0, 0x17, 0x7c, 0x8e, 0x35, 0x19, 0x99, 0x50, 0xb6,
6519
-	0xd8, 0x74, 0x4a, 0x7c, 0xf9, 0x4c, 0x6c, 0xec, 0x56, 0x71, 0xd2, 0x95, 0x91, 0x21, 0xdc, 0x09,
6520
-	0xcd, 0xa2, 0x32, 0xab, 0x36, 0xaa, 0xc3, 0x06, 0xf5, 0x67, 0xe6, 0xa6, 0x32, 0xc9, 0xa6, 0xb4,
6521
-	0xd8, 0x6e, 0x9c, 0x7d, 0x55, 0x2c, 0x9b, 0x92, 0x17, 0x85, 0x94, 0x9b, 0xe5, 0x38, 0xa2, 0xb2,
6522
-	0x8d, 0x7e, 0x0c, 0xa5, 0x29, 0x8b, 0x7c, 0x11, 0x9a, 0x15, 0xb5, 0xd8, 0xdb, 0x79, 0x8b, 0x7d,
6523
-	0x22, 0x11, 0x5a, 0x59, 0x1a, 0x8e, 0x06, 0x70, 0x23, 0x14, 0x2c, 0x18, 0x39, 0x9c, 0x58, 0x74,
6524
-	0x14, 0x50, 0xee, 0x32, 0x5b, 0x5f, 0xc3, 0xb7, 0xdf, 0x38, 0x94, 0xbe, 0x2e, 0xe8, 0xf0, 0x75,
6525
-	0xc9, 0x39, 0x90, 0x94, 0xa1, 0x62, 0xa0, 0x21, 0xd4, 0x82, 0xc8, 0xf3, 0x46, 0x2c, 0x88, 0x5f,
6526
-	0xe4, 0x38, 0x77, 0xde, 0x22, 0x64, 0xc3, 0xc8, 0xf3, 0x9e, 0xc6, 0x24, 0x6c, 0x04, 0xcb, 0x0e,
6527
-	0xba, 0x05, 0x25, 0x87, 0xb3, 0x28, 0x88, 0xf3, 0xa6, 0x8a, 0x75, 0x0f, 0x7d, 0x09, 0xe5, 0x90,
6528
-	0x5a, 0x9c, 0x8a, 0xd0, 0xac, 0xa9, 0xad, 0x7e, 0x98, 0x37, 0xc9, 0xb1, 0x82, 0xa4, 0x39, 0x81,
6529
-	0x13, 0x0e, 0xba, 0x0d, 0x1b, 0x42, 0xcc, 0xcd, 0xad, 0x66, 0x61, 0xb7, 0xd2, 0x2b, 0x2f, 0xce,
6530
-	0x77, 0x36, 0x4e, 0x4e, 0x9e, 0x63, 0x69, 0x93, 0xaf, 0xc5, 0x84, 0x85, 0xc2, 0x27, 0x53, 0x6a,
6531
-	0x5e, 0x53, 0xb1, 0x4d, 0xfb, 0xe8, 0x39, 0x80, 0xed, 0x87, 0x23, 0x4b, 0x5d, 0x4f, 0xe6, 0x75,
6532
-	0xb5, 0xbb, 0x4f, 0xaf, 0xde, 0x5d, 0xff, 0xe8, 0x58, 0xbf, 0x98, 0x5b, 0x8b, 0xf3, 0x9d, 0x6a,
6533
-	0xda, 0xc5, 0x55, 0xdb, 0x0f, 0xe3, 0x26, 0xea, 0x81, 0x31, 0xa1, 0xc4, 0x13, 0x13, 0x6b, 0x42,
6534
-	0xad, 0x33, 0xb3, 0x7e, 0xf1, 0x13, 0xf8, 0x48, 0xc1, 0xb4, 0x87, 0x2c, 0x49, 0x2a, 0x58, 0x2e,
6535
-	0x35, 0x34, 0x6f, 0xa8, 0x58, 0xc5, 0x1d, 0xf4, 0x01, 0x00, 0x0b, 0xa8, 0x3f, 0x0a, 0x85, 0xed,
6536
-	0xfa, 0x26, 0x92, 0x5b, 0xc6, 0x55, 0x69, 0x39, 0x96, 0x06, 0x74, 0x47, 0x3e, 0x50, 0xc4, 0x1e,
6537
-	0x31, 0xdf, 0x9b, 0x9b, 0xef, 0xa9, 0xd1, 0x8a, 0x34, 0x3c, 0xf5, 0xbd, 0x39, 0xda, 0x01, 0x43,
6538
-	0xe9, 0x22, 0x74, 0x1d, 0x9f, 0x78, 0xe6, 0x4d, 0x15, 0x0f, 0x90, 0xa6, 0x63, 0x65, 0x91, 0xe7,
6539
-	0x10, 0x47, 0x23, 0x34, 0xdf, 0xbf, 0xf8, 0x1c, 0xf4, 0x62, 0x97, 0xe7, 0xa0, 0x39, 0xe8, 0xa7,
6540
-	0x00, 0x01, 0x77, 0x67, 0xae, 0x47, 0x1d, 0x1a, 0x9a, 0xb7, 0xd4, 0xa6, 0xb7, 0x73, 0x5f, 0xa6,
6541
-	0x14, 0x85, 0x33, 0x8c, 0xc6, 0xe7, 0x60, 0x64, 0xb2, 0x4d, 0x66, 0xc9, 0x19, 0x9d, 0xeb, 0x04,
6542
-	0x96, 0x4d, 0x19, 0x92, 0x19, 0xf1, 0xa2, 0xf8, 0x32, 0xab, 0xe2, 0xb8, 0xf3, 0xc5, 0xfa, 0x83,
6543
-	0x42, 0x63, 0x0f, 0x8c, 0x8c, 0xea, 0xd0, 0x87, 0xf2, 0xf6, 0x73, 0xdc, 0x50, 0xf0, 0xf9, 0x88,
6544
-	0x44, 0x62, 0x62, 0xfe, 0x5c, 0x11, 0x6a, 0x89, 0xb1, 0x1b, 0x89, 0x49, 0x63, 0x04, 0xcb, 0xc3,
6545
-	0x43, 0x4d, 0x30, 0xa4, 0x28, 0x42, 0xca, 0x67, 0x94, 0xcb, 0xca, 0x42, 0xc6, 0x3c, 0x6b, 0x92,
6546
-	0xe2, 0x0d, 0x29, 0xe1, 0xd6, 0x44, 0xdd, 0x1d, 0x55, 0xac, 0x7b, 0xf2, 0x32, 0x48, 0x32, 0x44,
6547
-	0x5f, 0x06, 0xba, 0xdb, 0xfa, 0x57, 0x01, 0x6a, 0xd9, 0x02, 0x09, 0xed, 0xc7, 0x85, 0x8d, 0xda,
6548
-	0xd2, 0xb5, 0xbd, 0xce, 0x55, 0x05, 0x95, 0xba, 0x98, 0xbd, 0x48, 0x3a, 0x7b, 0x22, 0xff, 0x32,
6549
-	0x8a, 0x8c, 0x7e, 0x04, 0x9b, 0x01, 0xe3, 0x22, 0xb9, 0xc2, 0xf2, 0x03, 0xcc, 0x78, 0xf2, 0xec,
6550
-	0xc6, 0xe0, 0xd6, 0x04, 0xae, 0xad, 0x7a, 0x43, 0xf7, 0x60, 0xe3, 0xd9, 0xe1, 0xb0, 0xbe, 0xd6,
6551
-	0xb8, 0xf3, 0xe2, 0x65, 0xf3, 0x3b, 0xab, 0x83, 0xcf, 0x5c, 0x2e, 0x22, 0xe2, 0x1d, 0x0e, 0xd1,
6552
-	0x27, 0xb0, 0xd9, 0x3f, 0x3a, 0xc6, 0xb8, 0x5e, 0x68, 0xec, 0xbc, 0x78, 0xd9, 0xbc, 0xb3, 0x8a,
6553
-	0x93, 0x43, 0x2c, 0xf2, 0x6d, 0xcc, 0xc6, 0x69, 0x5d, 0xff, 0xef, 0x75, 0x30, 0xf4, 0xcd, 0xfe,
6554
-	0xae, 0xbf, 0x7e, 0x5b, 0x71, 0xd9, 0x92, 0xa4, 0xec, 0xfa, 0x95, 0xd5, 0x4b, 0x2d, 0x26, 0xe8,
6555
-	0x33, 0xbe, 0x0b, 0x35, 0x37, 0x98, 0x7d, 0x36, 0xa2, 0x3e, 0x19, 0x7b, 0xba, 0xc4, 0xaf, 0x60,
6556
-	0x43, 0xda, 0x06, 0xb1, 0x49, 0xde, 0x17, 0xae, 0x2f, 0x28, 0xf7, 0x75, 0xf1, 0x5e, 0xc1, 0x69,
6557
-	0x1f, 0x7d, 0x09, 0x45, 0x37, 0x20, 0x53, 0x5d, 0x72, 0xe5, 0xee, 0xe0, 0x70, 0xd8, 0x7d, 0xa2,
6558
-	0x35, 0xd8, 0xab, 0x2c, 0xce, 0x77, 0x8a, 0xd2, 0x80, 0x15, 0x0d, 0x6d, 0x27, 0x55, 0x8f, 0x9c,
6559
-	0x49, 0xdd, 0xfd, 0x15, 0x9c, 0xb1, 0x48, 0x1d, 0xb9, 0xbe, 0xc3, 0x69, 0x18, 0xaa, 0x57, 0xa0,
6560
-	0x82, 0x93, 0x2e, 0x6a, 0x40, 0x59, 0xd7, 0x4e, 0xaa, 0x58, 0xaa, 0xca, 0xba, 0x44, 0x1b, 0x7a,
6561
-	0x5b, 0x60, 0xc4, 0xd1, 0x18, 0x9d, 0x72, 0x36, 0x6d, 0xfd, 0xa7, 0x08, 0xc6, 0xbe, 0x17, 0x85,
6562
-	0x42, 0x3f, 0x83, 0xef, 0x2c, 0xf8, 0xcf, 0xe1, 0x06, 0x51, 0x5f, 0x49, 0xe2, 0xcb, 0x37, 0x45,
6563
-	0x95, 0xa4, 0xfa, 0x00, 0xee, 0xe5, 0xba, 0x4b, 0xc1, 0x71, 0xf9, 0xda, 0x2b, 0x49, 0x9f, 0x66,
6564
-	0x01, 0xd7, 0xc9, 0x6b, 0x23, 0xe8, 0x18, 0xb6, 0x18, 0xb7, 0x26, 0x34, 0x14, 0xf1, 0x4b, 0xa4,
6565
-	0xbf, 0x5e, 0xb9, 0x9f, 0xf2, 0xa7, 0x59, 0xa0, 0xbe, 0x86, 0xe3, 0xd5, 0xae, 0xfa, 0x40, 0x0f,
6566
-	0xa0, 0xc8, 0xc9, 0x69, 0x52, 0x5e, 0xe7, 0x26, 0x09, 0x26, 0xa7, 0x62, 0xc5, 0x85, 0x62, 0xa0,
6567
-	0x5f, 0x02, 0xd8, 0x6e, 0x18, 0x10, 0x61, 0x4d, 0x28, 0xd7, 0x87, 0x9d, 0xbb, 0xc5, 0x7e, 0x8a,
6568
-	0x5a, 0xf1, 0x92, 0x61, 0xa3, 0xc7, 0x50, 0xb5, 0x48, 0x22, 0xd7, 0xd2, 0xc5, 0xff, 0xd1, 0xfd,
6569
-	0xae, 0x76, 0x51, 0x97, 0x2e, 0x16, 0xe7, 0x3b, 0x95, 0xc4, 0x82, 0x2b, 0x16, 0xd1, 0xf2, 0x7d,
6570
-	0x0c, 0x5b, 0xf2, 0x9f, 0x3a, 0xb2, 0xe9, 0x29, 0x89, 0x3c, 0x11, 0xcb, 0xe4, 0x82, 0x67, 0x45,
6571
-	0x7e, 0x7a, 0xfa, 0x1a, 0xa7, 0xd7, 0x55, 0x13, 0x19, 0x1b, 0xfa, 0x35, 0xdc, 0xa0, 0xbe, 0xc5,
6572
-	0xe7, 0x4a, 0xac, 0xc9, 0x0a, 0x2b, 0x17, 0x6f, 0x76, 0x90, 0x82, 0x57, 0x36, 0x5b, 0xa7, 0xaf,
6573
-	0xd9, 0x5b, 0xff, 0x28, 0x00, 0xc4, 0x2f, 0xf5, 0xbb, 0x15, 0x20, 0x82, 0xa2, 0x4d, 0x04, 0x51,
6574
-	0x9a, 0xab, 0x61, 0xd5, 0x46, 0x5f, 0x00, 0x08, 0x3a, 0x0d, 0x3c, 0x22, 0x5c, 0xdf, 0xd1, 0xb2,
6575
-	0xb9, 0xec, 0x3a, 0xc8, 0xa0, 0xd1, 0x1e, 0x94, 0xf4, 0x27, 0xa8, 0x78, 0x25, 0x4f, 0x23, 0x5b,
6576
-	0x7f, 0x29, 0x00, 0xc4, 0xdb, 0xfc, 0xbf, 0xde, 0x5b, 0xcf, 0x7c, 0xf5, 0xed, 0xf6, 0xda, 0xdf,
6577
-	0xbf, 0xdd, 0x5e, 0xfb, 0xfd, 0x62, 0xbb, 0xf0, 0x6a, 0xb1, 0x5d, 0xf8, 0xdb, 0x62, 0xbb, 0xf0,
6578
-	0xcf, 0xc5, 0x76, 0x61, 0x5c, 0x52, 0x75, 0xdf, 0x0f, 0xff, 0x1b, 0x00, 0x00, 0xff, 0xff, 0xae,
6579
-	0x88, 0xf9, 0x3c, 0x5a, 0x14, 0x00, 0x00,
6455
+	// 2114 bytes of a gzipped FileDescriptorProto
6456
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x58, 0x4f, 0x6f, 0xdb, 0xc8,
6457
+	0x15, 0xb7, 0x6c, 0x59, 0x96, 0x1e, 0xe5, 0x44, 0x9e, 0x4d, 0xb2, 0xb4, 0xb2, 0xb1, 0x15, 0x6d,
6458
+	0x36, 0xf5, 0xee, 0xa2, 0x32, 0xea, 0x2e, 0xb6, 0xd9, 0x4d, 0xb7, 0xad, 0x64, 0x69, 0x1d, 0x35,
6459
+	0x89, 0x2d, 0x8c, 0x1c, 0xb7, 0x01, 0x0a, 0x08, 0x63, 0x72, 0x2c, 0x11, 0xa6, 0x38, 0xec, 0x70,
6460
+	0xe8, 0x40, 0xb7, 0x1e, 0x17, 0xee, 0x67, 0x30, 0x7a, 0x28, 0x7a, 0x6f, 0xbf, 0x42, 0x4f, 0x39,
6461
+	0xf6, 0xd8, 0x5e, 0x8c, 0xae, 0xbf, 0x42, 0x6f, 0xbd, 0xb4, 0x98, 0xe1, 0x90, 0xa2, 0x1c, 0x3a,
6462
+	0x0e, 0xd0, 0x1c, 0x7a, 0x9b, 0x79, 0xfc, 0xfd, 0xde, 0xfc, 0xfb, 0xbd, 0x37, 0x6f, 0x08, 0x9f,
6463
+	0x0d, 0x1d, 0x31, 0x0a, 0x0f, 0x1b, 0x16, 0x1b, 0x6f, 0xda, 0xcc, 0x3a, 0xa6, 0x7c, 0x33, 0x78,
6464
+	0x45, 0xf8, 0xf8, 0xd8, 0x11, 0x9b, 0xc4, 0x77, 0x36, 0x03, 0x9f, 0x5a, 0x41, 0xc3, 0xe7, 0x4c,
6465
+	0x30, 0x84, 0x22, 0x40, 0x23, 0x06, 0x34, 0x4e, 0x7e, 0x54, 0xbd, 0x8e, 0x2f, 0x26, 0x3e, 0xd5,
6466
+	0xfc, 0xea, 0xad, 0x21, 0x1b, 0x32, 0xd5, 0xdc, 0x94, 0x2d, 0x6d, 0x5d, 0x1b, 0x32, 0x36, 0x74,
6467
+	0xe9, 0xa6, 0xea, 0x1d, 0x86, 0x47, 0x9b, 0x76, 0xc8, 0x89, 0x70, 0x98, 0xa7, 0xbf, 0xaf, 0x5e,
6468
+	0xfe, 0x4e, 0xbc, 0xc9, 0x55, 0xd4, 0x57, 0x9c, 0xf8, 0x3e, 0xe5, 0x7a, 0xc0, 0xfa, 0x59, 0x1e,
6469
+	0x8a, 0xbb, 0xcc, 0xa6, 0x7d, 0x9f, 0x5a, 0x68, 0x07, 0x0c, 0xe2, 0x79, 0x4c, 0x28, 0xdf, 0x81,
6470
+	0x99, 0xab, 0xe5, 0x36, 0x8c, 0xad, 0xf5, 0xc6, 0x9b, 0x6b, 0x6a, 0x34, 0xa7, 0xb0, 0x56, 0xfe,
6471
+	0xf5, 0xf9, 0xfa, 0x1c, 0x4e, 0x33, 0xd1, 0xcf, 0xa1, 0x6c, 0xd3, 0xc0, 0xe1, 0xd4, 0x1e, 0x70,
6472
+	0xe6, 0x52, 0x73, 0xbe, 0x96, 0xdb, 0xb8, 0xb1, 0xf5, 0x51, 0x96, 0x27, 0x39, 0x38, 0x66, 0x2e,
6473
+	0xc5, 0x86, 0x66, 0xc8, 0x0e, 0xda, 0x01, 0x18, 0xd3, 0xf1, 0x21, 0xe5, 0xc1, 0xc8, 0xf1, 0xcd,
6474
+	0x05, 0x45, 0xff, 0xc1, 0x55, 0x74, 0x39, 0xf7, 0xc6, 0xf3, 0x04, 0x8e, 0x53, 0x54, 0xf4, 0x1c,
6475
+	0xca, 0xe4, 0x84, 0x38, 0x2e, 0x39, 0x74, 0x5c, 0x47, 0x4c, 0xcc, 0xbc, 0x72, 0xf5, 0xe9, 0x5b,
6476
+	0x5d, 0x35, 0x53, 0x04, 0x3c, 0x43, 0xaf, 0xdb, 0x00, 0xd3, 0x81, 0xd0, 0x43, 0x58, 0xea, 0x75,
6477
+	0x76, 0xdb, 0xdd, 0xdd, 0x9d, 0xca, 0x5c, 0x75, 0xf5, 0xf4, 0xac, 0x76, 0x5b, 0xfa, 0x98, 0x02,
6478
+	0x7a, 0xd4, 0xb3, 0x1d, 0x6f, 0x88, 0x36, 0xa0, 0xd8, 0xdc, 0xde, 0xee, 0xf4, 0xf6, 0x3b, 0xed,
6479
+	0x4a, 0xae, 0x5a, 0x3d, 0x3d, 0xab, 0xdd, 0x99, 0x05, 0x36, 0x2d, 0x8b, 0xfa, 0x82, 0xda, 0xd5,
6480
+	0xfc, 0x77, 0x7f, 0x5c, 0x9b, 0xab, 0x7f, 0x97, 0x83, 0x72, 0x7a, 0x12, 0xe8, 0x21, 0x14, 0x9a,
6481
+	0xdb, 0xfb, 0xdd, 0x83, 0x4e, 0x65, 0x6e, 0x4a, 0x4f, 0x23, 0x9a, 0x96, 0x70, 0x4e, 0x28, 0x7a,
6482
+	0x00, 0x8b, 0xbd, 0xe6, 0x8b, 0x7e, 0xa7, 0x92, 0x9b, 0x4e, 0x27, 0x0d, 0xeb, 0x91, 0x30, 0x50,
6483
+	0xa8, 0x36, 0x6e, 0x76, 0x77, 0x2b, 0xf3, 0xd9, 0xa8, 0x36, 0x27, 0x8e, 0xa7, 0xa7, 0xf2, 0x87,
6484
+	0x3c, 0x18, 0x7d, 0xca, 0x4f, 0x1c, 0xeb, 0x3d, 0x4b, 0xe4, 0x4b, 0xc8, 0x0b, 0x12, 0x1c, 0x2b,
6485
+	0x69, 0x18, 0xd9, 0xd2, 0xd8, 0x27, 0xc1, 0xb1, 0x1c, 0x54, 0xd3, 0x15, 0x5e, 0x2a, 0x83, 0x53,
6486
+	0xdf, 0x75, 0x2c, 0x22, 0xa8, 0xad, 0x94, 0x61, 0x6c, 0x7d, 0x92, 0xc5, 0xc6, 0x09, 0x4a, 0xcf,
6487
+	0xff, 0xc9, 0x1c, 0x4e, 0x51, 0xd1, 0x63, 0x28, 0x0c, 0x5d, 0x76, 0x48, 0x5c, 0xa5, 0x09, 0x63,
6488
+	0xeb, 0x7e, 0x96, 0x93, 0x1d, 0x85, 0x98, 0x3a, 0xd0, 0x14, 0xf4, 0x08, 0x0a, 0xa1, 0x6f, 0x13,
6489
+	0x41, 0xcd, 0x82, 0x22, 0xd7, 0xb2, 0xc8, 0x2f, 0x14, 0x62, 0x9b, 0x79, 0x47, 0xce, 0x10, 0x6b,
6490
+	0x3c, 0x7a, 0x0a, 0x45, 0x8f, 0x8a, 0x57, 0x8c, 0x1f, 0x07, 0xe6, 0x52, 0x6d, 0x61, 0xc3, 0xd8,
6491
+	0xfa, 0x3c, 0x53, 0x8c, 0x11, 0xa6, 0x29, 0x04, 0xb1, 0x46, 0x63, 0xea, 0x89, 0xc8, 0x4d, 0x6b,
6492
+	0xde, 0xcc, 0xe1, 0xc4, 0x01, 0xfa, 0x29, 0x14, 0xa9, 0x67, 0xfb, 0xcc, 0xf1, 0x84, 0x59, 0xbc,
6493
+	0x7a, 0x22, 0x1d, 0x8d, 0x91, 0x9b, 0x89, 0x13, 0x86, 0x64, 0x73, 0xe6, 0xba, 0x87, 0xc4, 0x3a,
6494
+	0x36, 0x4b, 0xef, 0xb8, 0x8c, 0x84, 0xd1, 0x2a, 0x40, 0x7e, 0xcc, 0x6c, 0x5a, 0xdf, 0x84, 0x95,
6495
+	0x37, 0xb6, 0x1a, 0x55, 0xa1, 0xa8, 0xb7, 0x3a, 0xd2, 0x48, 0x1e, 0x27, 0xfd, 0xfa, 0x4d, 0x58,
6496
+	0x9e, 0xd9, 0xd6, 0xfa, 0x9f, 0x17, 0xa1, 0x18, 0x9f, 0x35, 0x6a, 0x42, 0xc9, 0x62, 0x9e, 0x20,
6497
+	0x8e, 0x47, 0xb9, 0x96, 0x57, 0xe6, 0xc9, 0x6c, 0xc7, 0x20, 0xc9, 0x7a, 0x32, 0x87, 0xa7, 0x2c,
6498
+	0xf4, 0x2d, 0x94, 0x38, 0x0d, 0x58, 0xc8, 0x2d, 0x1a, 0x68, 0x7d, 0x6d, 0x64, 0x2b, 0x24, 0x02,
6499
+	0x61, 0xfa, 0xdb, 0xd0, 0xe1, 0x54, 0xee, 0x72, 0x80, 0xa7, 0x54, 0xf4, 0x18, 0x96, 0x38, 0x0d,
6500
+	0x04, 0xe1, 0xe2, 0x6d, 0x12, 0xc1, 0x11, 0xa4, 0xc7, 0x5c, 0xc7, 0x9a, 0xe0, 0x98, 0x81, 0x1e,
6501
+	0x43, 0xc9, 0x77, 0x89, 0xa5, 0xbc, 0x9a, 0x8b, 0x8a, 0x7e, 0x2f, 0x8b, 0xde, 0x8b, 0x41, 0x78,
6502
+	0x8a, 0x47, 0x5f, 0x01, 0xb8, 0x6c, 0x38, 0xb0, 0xb9, 0x73, 0x42, 0xb9, 0x96, 0x58, 0x35, 0x8b,
6503
+	0xdd, 0x56, 0x08, 0x5c, 0x72, 0xd9, 0x30, 0x6a, 0xa2, 0x9d, 0xff, 0x49, 0x5f, 0x29, 0x6d, 0x3d,
6504
+	0x05, 0x20, 0xc9, 0x57, 0xad, 0xae, 0x4f, 0xdf, 0xc9, 0x95, 0x3e, 0x91, 0x14, 0x1d, 0xdd, 0x87,
6505
+	0xf2, 0x11, 0xe3, 0x16, 0x1d, 0xe8, 0xa8, 0x29, 0x29, 0x4d, 0x18, 0xca, 0x16, 0xe9, 0x0b, 0xb5,
6506
+	0x60, 0x69, 0x48, 0x3d, 0xca, 0x1d, 0xcb, 0x04, 0x35, 0xd8, 0xc3, 0xcc, 0x80, 0x8c, 0x20, 0x38,
6507
+	0xf4, 0x84, 0x33, 0xa6, 0x7a, 0xa4, 0x98, 0x88, 0x7e, 0x03, 0x1f, 0xc4, 0xc7, 0x37, 0xe0, 0xf4,
6508
+	0x88, 0x72, 0xea, 0x49, 0x0d, 0x18, 0x6a, 0x1f, 0x3e, 0x79, 0xbb, 0x06, 0x34, 0x5a, 0x27, 0x1b,
6509
+	0xc4, 0x2f, 0x7f, 0x08, 0x5a, 0x25, 0x58, 0xe2, 0xd1, 0xb8, 0xf5, 0xdf, 0xe7, 0xa4, 0xea, 0x2f,
6510
+	0x21, 0xd0, 0x26, 0x18, 0xc9, 0xf0, 0x8e, 0xad, 0xd4, 0x5b, 0x6a, 0xdd, 0xb8, 0x38, 0x5f, 0x87,
6511
+	0x18, 0xdb, 0x6d, 0xcb, 0x1c, 0xa4, 0xdb, 0x36, 0xea, 0xc0, 0x72, 0x42, 0x90, 0x65, 0x80, 0xbe,
6512
+	0x28, 0x6b, 0x6f, 0x9b, 0xe9, 0xfe, 0xc4, 0xa7, 0xb8, 0xcc, 0x53, 0xbd, 0xfa, 0xaf, 0x01, 0xbd,
6513
+	0xb9, 0x2f, 0x08, 0x41, 0xfe, 0xd8, 0xf1, 0xf4, 0x34, 0xb0, 0x6a, 0xa3, 0x06, 0x2c, 0xf9, 0x64,
6514
+	0xe2, 0x32, 0x62, 0xeb, 0xc0, 0xb8, 0xd5, 0x88, 0x0a, 0x84, 0x46, 0x5c, 0x20, 0x34, 0x9a, 0xde,
6515
+	0x04, 0xc7, 0xa0, 0xfa, 0x53, 0xb8, 0x9d, 0x79, 0xbc, 0x68, 0x0b, 0xca, 0x49, 0xc0, 0x4d, 0xd7,
6516
+	0x7a, 0xf3, 0xe2, 0x7c, 0xdd, 0x48, 0x22, 0xb3, 0xdb, 0xc6, 0x46, 0x02, 0xea, 0xda, 0xf5, 0xbf,
6517
+	0x1a, 0xb0, 0x3c, 0x13, 0xb6, 0xe8, 0x16, 0x2c, 0x3a, 0x63, 0x32, 0xa4, 0x7a, 0x8e, 0x51, 0x07,
6518
+	0x75, 0xa0, 0xe0, 0x92, 0x43, 0xea, 0xca, 0xe0, 0x95, 0x07, 0xf7, 0xc3, 0x6b, 0xe3, 0xbf, 0xf1,
6519
+	0x4c, 0xe1, 0x3b, 0x9e, 0xe0, 0x13, 0xac, 0xc9, 0xc8, 0x84, 0x25, 0x8b, 0x8d, 0xc7, 0xc4, 0x93,
6520
+	0xd7, 0xc4, 0xc2, 0x46, 0x09, 0xc7, 0x5d, 0xb9, 0x33, 0x84, 0x0f, 0x03, 0x33, 0xaf, 0xcc, 0xaa,
6521
+	0x8d, 0x2a, 0xb0, 0x40, 0xbd, 0x13, 0x73, 0x51, 0x99, 0x64, 0x53, 0x5a, 0x6c, 0x27, 0x8a, 0xbe,
6522
+	0x12, 0x96, 0x4d, 0xc9, 0x0b, 0x03, 0xca, 0xcd, 0xa5, 0x68, 0x47, 0x65, 0x1b, 0xfd, 0x04, 0x0a,
6523
+	0x63, 0x16, 0x7a, 0x22, 0x30, 0x8b, 0x6a, 0xb2, 0xab, 0x59, 0x93, 0x7d, 0x2e, 0x11, 0x5a, 0x59,
6524
+	0x1a, 0x8e, 0x3a, 0xb0, 0x12, 0x08, 0xe6, 0x0f, 0x86, 0x9c, 0x58, 0x74, 0xe0, 0x53, 0xee, 0x30,
6525
+	0x5b, 0xa7, 0xe1, 0xd5, 0x37, 0x0e, 0xa5, 0xad, 0x0b, 0x3e, 0x7c, 0x53, 0x72, 0x76, 0x24, 0xa5,
6526
+	0xa7, 0x18, 0xa8, 0x07, 0x65, 0x3f, 0x74, 0xdd, 0x01, 0xf3, 0xa3, 0x1b, 0x39, 0x8a, 0x9d, 0x77,
6527
+	0xd8, 0xb2, 0x5e, 0xe8, 0xba, 0x7b, 0x11, 0x09, 0x1b, 0xfe, 0xb4, 0x83, 0xee, 0x40, 0x61, 0xc8,
6528
+	0x59, 0xe8, 0x47, 0x71, 0x53, 0xc2, 0xba, 0x87, 0xbe, 0x81, 0xa5, 0x80, 0x5a, 0x9c, 0x8a, 0xc0,
6529
+	0x2c, 0xab, 0xa5, 0x7e, 0x9c, 0x35, 0x48, 0x5f, 0x41, 0x92, 0x98, 0xc0, 0x31, 0x07, 0xad, 0xc2,
6530
+	0x82, 0x10, 0x13, 0x73, 0xb9, 0x96, 0xdb, 0x28, 0xb6, 0x96, 0x2e, 0xce, 0xd7, 0x17, 0xf6, 0xf7,
6531
+	0x5f, 0x62, 0x69, 0x93, 0xb7, 0xc5, 0x88, 0x05, 0xc2, 0x23, 0x63, 0x6a, 0xde, 0x50, 0x7b, 0x9b,
6532
+	0xf4, 0xd1, 0x4b, 0x00, 0xdb, 0x0b, 0x06, 0x96, 0x4a, 0x4f, 0xe6, 0x4d, 0xb5, 0xba, 0xcf, 0xaf,
6533
+	0x5f, 0x5d, 0x7b, 0xb7, 0xaf, 0x6f, 0xcc, 0xe5, 0x8b, 0xf3, 0xf5, 0x52, 0xd2, 0xc5, 0x25, 0xdb,
6534
+	0x0b, 0xa2, 0x26, 0x6a, 0x81, 0x31, 0xa2, 0xc4, 0x15, 0x23, 0x6b, 0x44, 0xad, 0x63, 0xb3, 0x72,
6535
+	0xf5, 0x15, 0xf8, 0x44, 0xc1, 0xb4, 0x87, 0x34, 0x49, 0x2a, 0x58, 0x4e, 0x35, 0x30, 0x57, 0xd4,
6536
+	0x5e, 0x45, 0x1d, 0x74, 0x0f, 0x80, 0xf9, 0xd4, 0x1b, 0x04, 0xc2, 0x76, 0x3c, 0x13, 0xc9, 0x25,
6537
+	0xe3, 0x92, 0xb4, 0xf4, 0xa5, 0x01, 0xdd, 0x95, 0x17, 0x14, 0xb1, 0x07, 0xcc, 0x73, 0x27, 0xe6,
6538
+	0x07, 0xea, 0x6b, 0x51, 0x1a, 0xf6, 0x3c, 0x77, 0x82, 0xd6, 0xc1, 0x50, 0xba, 0x08, 0x9c, 0xa1,
6539
+	0x47, 0x5c, 0xf3, 0x96, 0xda, 0x0f, 0x90, 0xa6, 0xbe, 0xb2, 0xc8, 0x73, 0x88, 0x76, 0x23, 0x30,
6540
+	0x6f, 0x5f, 0x7d, 0x0e, 0x7a, 0xb2, 0xd3, 0x73, 0xd0, 0x1c, 0xf4, 0x33, 0x00, 0x9f, 0x3b, 0x27,
6541
+	0x8e, 0x4b, 0x87, 0x34, 0x30, 0xef, 0xa8, 0x45, 0xaf, 0x65, 0xde, 0x4c, 0x09, 0x0a, 0xa7, 0x18,
6542
+	0xa8, 0x01, 0x79, 0xc7, 0x73, 0x84, 0xf9, 0xa1, 0xbe, 0x95, 0x2e, 0x4b, 0xb5, 0xc5, 0x98, 0x7b,
6543
+	0x40, 0xdc, 0x90, 0x62, 0x85, 0x43, 0x5d, 0x28, 0x39, 0x01, 0x73, 0x95, 0x7c, 0x4d, 0x53, 0xe5,
6544
+	0xb7, 0x77, 0x38, 0xbf, 0x6e, 0x4c, 0xc1, 0x53, 0x76, 0xf5, 0x2b, 0x30, 0x52, 0x81, 0x2e, 0x03,
6545
+	0xf4, 0x98, 0x4e, 0x74, 0xee, 0x90, 0x4d, 0x79, 0x1a, 0x27, 0x72, 0x68, 0x95, 0xdc, 0x4a, 0x38,
6546
+	0xea, 0x7c, 0x3d, 0xff, 0x28, 0x57, 0xdd, 0x02, 0x23, 0x25, 0x78, 0xf4, 0xb1, 0x4c, 0xbc, 0x43,
6547
+	0x27, 0x10, 0x7c, 0x32, 0x20, 0xa1, 0x18, 0x99, 0xbf, 0x50, 0x84, 0x72, 0x6c, 0x6c, 0x86, 0x62,
6548
+	0x54, 0x1d, 0xc0, 0x54, 0x37, 0xa8, 0x06, 0x86, 0xd4, 0x63, 0x40, 0xf9, 0x09, 0xe5, 0xb2, 0xa8,
6549
+	0x91, 0xc7, 0x9d, 0x36, 0xc9, 0xb8, 0x09, 0x28, 0xe1, 0xd6, 0x48, 0xa5, 0xad, 0x12, 0xd6, 0x3d,
6550
+	0x99, 0x87, 0xe2, 0xe0, 0xd4, 0x79, 0x48, 0x77, 0xeb, 0x7f, 0xc9, 0x41, 0x29, 0x59, 0x28, 0xfa,
6551
+	0x02, 0x56, 0xba, 0xfd, 0xbd, 0x67, 0xcd, 0xfd, 0xee, 0xde, 0xee, 0xa0, 0xdd, 0xf9, 0xb6, 0xf9,
6552
+	0xe2, 0xd9, 0x7e, 0x65, 0xae, 0x7a, 0xef, 0xf4, 0xac, 0xb6, 0x3a, 0xcd, 0xa9, 0x31, 0xbc, 0x4d,
6553
+	0x8f, 0x48, 0xe8, 0x8a, 0x59, 0x56, 0x0f, 0xef, 0x6d, 0x77, 0xfa, 0xfd, 0x4a, 0xee, 0x2a, 0x56,
6554
+	0x8f, 0x33, 0x8b, 0x06, 0x01, 0xda, 0x82, 0xca, 0x94, 0xf5, 0xe4, 0x65, 0xaf, 0x83, 0x0f, 0x2a,
6555
+	0xf3, 0xd5, 0x8f, 0x4e, 0xcf, 0x6a, 0xe6, 0x9b, 0xa4, 0x27, 0x13, 0x9f, 0xf2, 0x03, 0xfd, 0x20,
6556
+	0xf8, 0x57, 0x0e, 0xca, 0xe9, 0x7a, 0x12, 0x6d, 0x47, 0x75, 0xa0, 0x3a, 0x86, 0x1b, 0x5b, 0x9b,
6557
+	0xd7, 0xd5, 0x9f, 0xea, 0x1e, 0x73, 0x43, 0xe9, 0xf7, 0xb9, 0x7c, 0xfa, 0x29, 0x32, 0xfa, 0x02,
6558
+	0x16, 0x7d, 0xc6, 0x45, 0x9c, 0xf1, 0xb3, 0xf5, 0xc8, 0x78, 0x5c, 0xa5, 0x44, 0xe0, 0xfa, 0x08,
6559
+	0x6e, 0xcc, 0x7a, 0x43, 0x0f, 0x60, 0xe1, 0xa0, 0xdb, 0xab, 0xcc, 0x55, 0xef, 0x9e, 0x9e, 0xd5,
6560
+	0x3e, 0x9c, 0xfd, 0x78, 0xe0, 0x70, 0x11, 0x12, 0xb7, 0xdb, 0x43, 0x9f, 0xc1, 0x62, 0x7b, 0xb7,
6561
+	0x8f, 0x71, 0x25, 0x57, 0x5d, 0x3f, 0x3d, 0xab, 0xdd, 0x9d, 0xc5, 0xc9, 0x4f, 0x2c, 0xf4, 0x6c,
6562
+	0xcc, 0x0e, 0x93, 0x67, 0xd0, 0xbf, 0xe7, 0xc1, 0xd0, 0x17, 0xe1, 0xfb, 0x7e, 0x29, 0x2f, 0x47,
6563
+	0x55, 0x5e, 0x9c, 0xe1, 0xe6, 0xaf, 0x2d, 0xf6, 0xca, 0x11, 0x41, 0xeb, 0xf2, 0x3e, 0x94, 0x1d,
6564
+	0xff, 0xe4, 0xcb, 0x01, 0xf5, 0xc8, 0xa1, 0xab, 0x5f, 0x44, 0x45, 0x6c, 0x48, 0x5b, 0x27, 0x32,
6565
+	0xc9, 0xf4, 0xea, 0x78, 0x82, 0x72, 0x4f, 0xbf, 0x75, 0x8a, 0x38, 0xe9, 0xa3, 0x6f, 0x20, 0xef,
6566
+	0xf8, 0x64, 0xac, 0x2b, 0xd4, 0xcc, 0x15, 0x74, 0x7b, 0xcd, 0xe7, 0x3a, 0x6e, 0x5a, 0xc5, 0x8b,
6567
+	0xf3, 0xf5, 0xbc, 0x34, 0x60, 0x45, 0x43, 0x6b, 0x71, 0x91, 0x28, 0x47, 0x52, 0x57, 0x65, 0x11,
6568
+	0xa7, 0x2c, 0x52, 0xfb, 0x8e, 0x37, 0xe4, 0x34, 0x08, 0xd4, 0xa5, 0x59, 0xc4, 0x71, 0x17, 0x55,
6569
+	0x61, 0x49, 0x97, 0x9a, 0xaa, 0xb6, 0x2c, 0xc9, 0x32, 0x4e, 0x1b, 0x5a, 0xcb, 0x60, 0x44, 0xbb,
6570
+	0x31, 0x38, 0xe2, 0x6c, 0x5c, 0xff, 0x4f, 0x1e, 0x8c, 0x6d, 0x37, 0x0c, 0x84, 0xae, 0x1a, 0xde,
6571
+	0xdb, 0xe6, 0xbf, 0x84, 0x15, 0xa2, 0x5e, 0xde, 0xc4, 0x93, 0x57, 0xb0, 0xaa, 0xe0, 0xf5, 0x01,
6572
+	0x3c, 0xc8, 0x74, 0x97, 0x80, 0xa3, 0x6a, 0xbf, 0x55, 0x90, 0x3e, 0xcd, 0x1c, 0xae, 0x90, 0x4b,
6573
+	0x5f, 0x50, 0x1f, 0x96, 0x19, 0xb7, 0x46, 0x34, 0x10, 0xd1, 0xc5, 0xad, 0x5f, 0xaa, 0x99, 0xff,
6574
+	0x30, 0xf6, 0xd2, 0x40, 0x7d, 0x6b, 0x45, 0xb3, 0x9d, 0xf5, 0x81, 0x1e, 0x41, 0x9e, 0x93, 0xa3,
6575
+	0xf8, 0x35, 0x92, 0x19, 0x24, 0x98, 0x1c, 0x89, 0x19, 0x17, 0x8a, 0x81, 0x7e, 0x09, 0x60, 0x3b,
6576
+	0x81, 0x4f, 0x84, 0x35, 0xa2, 0x5c, 0x1f, 0x76, 0xe6, 0x12, 0xdb, 0x09, 0x6a, 0xc6, 0x4b, 0x8a,
6577
+	0x8d, 0x9e, 0x42, 0xc9, 0x22, 0xb1, 0x5c, 0x0b, 0x57, 0x3f, 0xdf, 0xb7, 0x9b, 0xda, 0x45, 0x45,
6578
+	0xba, 0xb8, 0x38, 0x5f, 0x2f, 0xc6, 0x16, 0x5c, 0xb4, 0x88, 0x96, 0xef, 0x53, 0x58, 0x96, 0xcf,
6579
+	0xfa, 0x81, 0x1d, 0xa5, 0xb3, 0x48, 0x26, 0x57, 0xdc, 0xc2, 0xf2, 0x8d, 0xa8, 0xd3, 0x5e, 0x7c,
6580
+	0x9c, 0x65, 0x91, 0xb2, 0xa1, 0x5f, 0xc1, 0x0a, 0xf5, 0x2c, 0x3e, 0x51, 0x62, 0x8d, 0x67, 0x58,
6581
+	0xbc, 0x7a, 0xb1, 0x9d, 0x04, 0x3c, 0xb3, 0xd8, 0x0a, 0xbd, 0x64, 0xaf, 0xff, 0x23, 0x07, 0x10,
6582
+	0x15, 0x36, 0xef, 0x57, 0x80, 0x08, 0xf2, 0x36, 0x11, 0x44, 0x69, 0xae, 0x8c, 0x55, 0x1b, 0x7d,
6583
+	0x0d, 0x20, 0xe8, 0xd8, 0x97, 0xa9, 0xd7, 0x1b, 0x6a, 0xd9, 0xbc, 0x2d, 0x1d, 0xa4, 0xd0, 0x68,
6584
+	0x0b, 0x0a, 0xfa, 0xcd, 0x98, 0xbf, 0x96, 0xa7, 0x91, 0xf5, 0x3f, 0xe5, 0x00, 0xa2, 0x65, 0xfe,
6585
+	0x5f, 0xaf, 0xad, 0x65, 0xbe, 0xfe, 0x7e, 0x6d, 0xee, 0xef, 0xdf, 0xaf, 0xcd, 0xfd, 0xee, 0x62,
6586
+	0x2d, 0xf7, 0xfa, 0x62, 0x2d, 0xf7, 0xb7, 0x8b, 0xb5, 0xdc, 0x3f, 0x2f, 0xd6, 0x72, 0x87, 0x05,
6587
+	0x55, 0x7b, 0xfc, 0xf8, 0xbf, 0x01, 0x00, 0x00, 0xff, 0xff, 0x1a, 0xbd, 0x13, 0xac, 0xa9, 0x15,
6588
+	0x00, 0x00,
6580 6589
 }
... ...
@@ -6,6 +6,7 @@ import "github.com/docker/swarmkit/api/types.proto";
6 6
 import "gogoproto/gogo.proto";
7 7
 import "google/protobuf/duration.proto";
8 8
 import "google/protobuf/any.proto";
9
+import "google/protobuf/wrappers.proto";
9 10
 
10 11
 // Specs are container objects for user provided input. All creations and
11 12
 // updates are done through spec types. As a convention, user input from a spec
... ...
@@ -215,6 +216,9 @@ message ContainerSpec {
215 215
 	// Privileges specifies security configuration/permissions.
216 216
 	Privileges privileges = 22;
217 217
 
218
+	// Init declares that a custom init will be running inside the container, if null, use the daemon's configured settings
219
+	google.protobuf.BoolValue init = 23;
220
+
218 221
 	// TTY declares that a TTY should be attached to the standard streams,
219 222
 	// including stdin if it is still open.
220 223
 	bool tty = 13 [(gogoproto.customname) = "TTY"];
... ...
@@ -293,6 +297,23 @@ message ContainerSpec {
293 293
 	// task will exit and a new task will be rescheduled elsewhere. A container
294 294
 	// is considered unhealthy after `Retries` number of consecutive failures.
295 295
 	HealthConfig healthcheck = 16;
296
+
297
+	enum Isolation {
298
+		option (gogoproto.goproto_enum_prefix) = false;
299
+
300
+		// ISOLATION_DEFAULT uses whatever default value from the container runtime
301
+		ISOLATION_DEFAULT = 0 [(gogoproto.enumvalue_customname) = "ContainerIsolationDefault"];
302
+
303
+		// ISOLATION_PROCESS forces windows container isolation
304
+		ISOLATION_PROCESS = 1 [(gogoproto.enumvalue_customname) = "ContainerIsolationProcess"];
305
+
306
+		// ISOLATION_HYPERV forces Hyper-V isolation
307
+		ISOLATION_HYPERV = 2 [(gogoproto.enumvalue_customname) = "ContainerIsolationHyperV"];
308
+	}
309
+
310
+	// Isolation defines the isolation level for windows containers (default, process, hyperv).
311
+	// Runtimes that don't support it ignore that field
312
+	Isolation isolation = 24;
296 313
 }
297 314
 
298 315
 // EndpointSpec defines the properties that can be configured to
... ...
@@ -1085,12 +1085,17 @@ type TaskStatus struct {
1085 1085
 	// because the task is prepared, we would put "already prepared" in this
1086 1086
 	// field.
1087 1087
 	Message string `protobuf:"bytes,3,opt,name=message,proto3" json:"message,omitempty"`
1088
-	// Err is set if the task is in an error state.
1088
+	// Err is set if the task is in an error state, or is unable to
1089
+	// progress from an earlier state because a precondition is
1090
+	// unsatisfied.
1089 1091
 	//
1090 1092
 	// The following states should report a companion error:
1091 1093
 	//
1092 1094
 	// 	FAILED, REJECTED
1093 1095
 	//
1096
+	// In general, messages that should be surfaced to users belong in the
1097
+	// Err field, and notes on routine state transitions belong in Message.
1098
+	//
1094 1099
 	// TODO(stevvooe) Integrate this field with the error interface.
1095 1100
 	Err string `protobuf:"bytes,4,opt,name=err,proto3" json:"err,omitempty"`
1096 1101
 	// Container status contains container specific status information.
... ...
@@ -509,12 +509,17 @@ message TaskStatus {
509 509
 	// field.
510 510
 	string message = 3;
511 511
 
512
-	// Err is set if the task is in an error state.
512
+	// Err is set if the task is in an error state, or is unable to
513
+	// progress from an earlier state because a precondition is
514
+	// unsatisfied.
513 515
 	//
514 516
 	// The following states should report a companion error:
515 517
 	//
516 518
 	//	FAILED, REJECTED
517 519
 	//
520
+	// In general, messages that should be surfaced to users belong in the
521
+	// Err field, and notes on routine state transitions belong in Message.
522
+	//
518 523
 	// TODO(stevvooe) Integrate this field with the error interface.
519 524
 	string err = 4;
520 525
 
... ...
@@ -1284,9 +1284,11 @@ func PredefinedNetworks() []networkallocator.PredefinedNetworkData {
1284 1284
 
1285 1285
 // updateTaskStatus sets TaskStatus and updates timestamp.
1286 1286
 func updateTaskStatus(t *api.Task, newStatus api.TaskState, message string) {
1287
-	t.Status.State = newStatus
1288
-	t.Status.Message = message
1289
-	t.Status.Timestamp = ptypes.MustTimestampProto(time.Now())
1287
+	t.Status = api.TaskStatus{
1288
+		State:     newStatus,
1289
+		Message:   message,
1290
+		Timestamp: ptypes.MustTimestampProto(time.Now()),
1291
+	}
1290 1292
 }
1291 1293
 
1292 1294
 // IsIngressNetwork returns whether the passed network is an ingress network.
... ...
@@ -159,7 +159,8 @@ loop:
159 159
 					// restarting the task on another node
160 160
 					// (if applicable).
161 161
 					t.Status.State = api.TaskStateRejected
162
-					t.Status.Message = "assigned node no longer meets constraints"
162
+					t.Status.Message = "task rejected by constraint enforcer"
163
+					t.Status.Err = "assigned node no longer meets constraints"
163 164
 					t.Status.Timestamp = ptypes.MustTimestampProto(time.Now())
164 165
 					return store.UpdateTask(tx, t)
165 166
 				})
... ...
@@ -169,7 +169,7 @@ func (f *PluginFilter) Check(n *NodeInfo) bool {
169 169
 		}
170 170
 	}
171 171
 
172
-	if f.t.Spec.LogDriver != nil {
172
+	if f.t.Spec.LogDriver != nil && f.t.Spec.LogDriver.Name != "none" {
173 173
 		// If there are no log driver types in the list at all, most likely this is
174 174
 		// an older daemon that did not report this information. In this case don't filter
175 175
 		if typeFound, exists := f.pluginExistsOnNode("Log", f.t.Spec.LogDriver.Name, nodePlugins); !exists && typeFound {
... ...
@@ -446,7 +446,9 @@ func (s *Scheduler) applySchedulingDecisions(ctx context.Context, schedulingDeci
446 446
 						continue
447 447
 					}
448 448
 
449
-					if t.Status.State == decision.new.Status.State && t.Status.Message == decision.new.Status.Message {
449
+					if t.Status.State == decision.new.Status.State &&
450
+						t.Status.Message == decision.new.Status.Message &&
451
+						t.Status.Err == decision.new.Status.Err {
450 452
 						// No changes, ignore
451 453
 						continue
452 454
 					}
... ...
@@ -502,7 +504,7 @@ func (s *Scheduler) taskFitNode(ctx context.Context, t *api.Task, nodeID string)
502 502
 	if !s.pipeline.Process(&nodeInfo) {
503 503
 		// this node cannot accommodate this task
504 504
 		newT.Status.Timestamp = ptypes.MustTimestampProto(time.Now())
505
-		newT.Status.Message = s.pipeline.Explain()
505
+		newT.Status.Err = s.pipeline.Explain()
506 506
 		s.allTasks[t.ID] = &newT
507 507
 
508 508
 		return &newT
... ...
@@ -702,9 +704,9 @@ func (s *Scheduler) noSuitableNode(ctx context.Context, taskGroup map[string]*ap
702 702
 		newT := *t
703 703
 		newT.Status.Timestamp = ptypes.MustTimestampProto(time.Now())
704 704
 		if explanation != "" {
705
-			newT.Status.Message = "no suitable node (" + explanation + ")"
705
+			newT.Status.Err = "no suitable node (" + explanation + ")"
706 706
 		} else {
707
-			newT.Status.Message = "no suitable node"
707
+			newT.Status.Err = "no suitable node"
708 708
 		}
709 709
 		s.allTasks[t.ID] = &newT
710 710
 		schedulingDecisions[t.ID] = schedulingDecision{old: t, new: &newT}
... ...
@@ -180,9 +180,12 @@ type NodeOptions struct {
180 180
 	ClockSource clock.Clock
181 181
 	// SendTimeout is the timeout on the sending messages to other raft
182 182
 	// nodes. Leave this as 0 to get the default value.
183
-	SendTimeout    time.Duration
184
-	TLSCredentials credentials.TransportCredentials
185
-	KeyRotator     EncryptionKeyRotator
183
+	SendTimeout time.Duration
184
+	// LargeSendTimeout is the timeout on the sending snapshots to other raft
185
+	// nodes. Leave this as 0 to get the default value.
186
+	LargeSendTimeout time.Duration
187
+	TLSCredentials   credentials.TransportCredentials
188
+	KeyRotator       EncryptionKeyRotator
186 189
 	// DisableStackDump prevents Run from dumping goroutine stacks when the
187 190
 	// store becomes stuck.
188 191
 	DisableStackDump bool
... ...
@@ -204,6 +207,11 @@ func NewNode(opts NodeOptions) *Node {
204 204
 	if opts.SendTimeout == 0 {
205 205
 		opts.SendTimeout = 2 * time.Second
206 206
 	}
207
+	if opts.LargeSendTimeout == 0 {
208
+		// a "slow" 100Mbps connection can send over 240MB data in 20 seconds
209
+		// which is well over the gRPC message limit of 128MB allowed by SwarmKit
210
+		opts.LargeSendTimeout = 20 * time.Second
211
+	}
207 212
 
208 213
 	raftStore := raft.NewMemoryStorage()
209 214
 
... ...
@@ -349,6 +357,7 @@ func (n *Node) initTransport() {
349 349
 	transportConfig := &transport.Config{
350 350
 		HeartbeatInterval: time.Duration(n.Config.ElectionTick) * n.opts.TickInterval,
351 351
 		SendTimeout:       n.opts.SendTimeout,
352
+		LargeSendTimeout:  n.opts.LargeSendTimeout,
352 353
 		Credentials:       n.opts.TLSCredentials,
353 354
 		Raft:              n,
354 355
 	}
... ...
@@ -133,7 +133,14 @@ func (p *peer) resolveAddr(ctx context.Context, id uint64) (string, error) {
133 133
 }
134 134
 
135 135
 func (p *peer) sendProcessMessage(ctx context.Context, m raftpb.Message) error {
136
-	ctx, cancel := context.WithTimeout(ctx, p.tr.config.SendTimeout)
136
+	timeout := p.tr.config.SendTimeout
137
+	// if a snapshot is being sent, set timeout to LargeSendTimeout because
138
+	// sending snapshots can take more time than other messages sent between peers.
139
+	// The same applies to AppendEntries as well, where messages can get large.
140
+	if m.Type == raftpb.MsgSnap || m.Type == raftpb.MsgApp {
141
+		timeout = p.tr.config.LargeSendTimeout
142
+	}
143
+	ctx, cancel := context.WithTimeout(ctx, timeout)
137 144
 	defer cancel()
138 145
 	_, err := api.NewRaftClient(p.conn()).ProcessRaftMessage(ctx, &api.ProcessRaftMessageRequest{Message: &m})
139 146
 	if grpc.Code(err) == codes.NotFound && grpc.ErrorDesc(err) == membership.ErrMemberRemoved.Error() {
... ...
@@ -35,6 +35,7 @@ type Raft interface {
35 35
 type Config struct {
36 36
 	HeartbeatInterval time.Duration
37 37
 	SendTimeout       time.Duration
38
+	LargeSendTimeout  time.Duration
38 39
 	Credentials       credentials.TransportCredentials
39 40
 	RaftID            string
40 41