浏览代码

Added support for swarm service isolation mode

Signed-off-by: Simon Ferquel <simon.ferquel@docker.com>
Simon Ferquel 8 年之前
父节点
当前提交
f28cb422e6
共有 25 个文件被更改,包括 564 次插入196 次删除
  1. 7 1
      api/swagger.yaml
  2. 21 0
      api/types/container/host_config.go
  3. 0 14
      api/types/container/hostconfig_windows.go
  4. 5 4
      api/types/swarm/container.go
  5. 25 0
      daemon/cluster/convert/container.go
  6. 84 0
      daemon/cluster/convert/service_test.go
  7. 5 0
      daemon/cluster/executor/container/container.go
  8. 37 0
      daemon/cluster/executor/container/container_test.go
  9. 1 0
      docs/api/version-history.md
  10. 17 0
      integration-cli/daemon/daemon_swarm.go
  11. 1 1
      integration-cli/docker_cli_swarm_unix_test.go
  12. 2 0
      integration/service/inspect_test.go
  13. 1 2
      vendor.conf
  14. 2 0
      vendor/github.com/docker/swarmkit/agent/exec/controller.go
  15. 288 159
      vendor/github.com/docker/swarmkit/api/specs.pb.go
  16. 21 0
      vendor/github.com/docker/swarmkit/api/specs.proto
  17. 6 1
      vendor/github.com/docker/swarmkit/api/types.pb.go
  18. 6 1
      vendor/github.com/docker/swarmkit/api/types.proto
  19. 5 3
      vendor/github.com/docker/swarmkit/manager/allocator/network.go
  20. 2 1
      vendor/github.com/docker/swarmkit/manager/orchestrator/constraintenforcer/constraint_enforcer.go
  21. 1 1
      vendor/github.com/docker/swarmkit/manager/scheduler/filter.go
  22. 6 4
      vendor/github.com/docker/swarmkit/manager/scheduler/scheduler.go
  23. 12 3
      vendor/github.com/docker/swarmkit/manager/state/raft/raft.go
  24. 8 1
      vendor/github.com/docker/swarmkit/manager/state/raft/transport/peer.go
  25. 1 0
      vendor/github.com/docker/swarmkit/manager/state/raft/transport/transport.go

+ 7 - 1
api/swagger.yaml

@@ -2680,7 +2680,13 @@ definitions:
                     ConfigName is the name of the config that this references, but this is just provided for
                     ConfigName is the name of the config that this references, but this is just provided for
                     lookup/display purposes. The config in the reference will be identified by its ID.
                     lookup/display purposes. The config in the reference will be identified by its ID.
                   type: "string"
                   type: "string"
-
+          Isolation:
+            type: "string"
+            description: "Isolation technology of the containers running the service. (Windows only)"
+            enum:
+              - "default"
+              - "process"
+              - "hyperv"
       Resources:
       Resources:
         description: "Resource requirements which apply to each individual container created as part of the service."
         description: "Resource requirements which apply to each individual container created as part of the service."
         type: "object"
         type: "object"

+ 21 - 0
api/types/container/host_config.go

@@ -20,6 +20,27 @@ func (i Isolation) IsDefault() bool {
 	return strings.ToLower(string(i)) == "default" || string(i) == ""
 	return strings.ToLower(string(i)) == "default" || string(i) == ""
 }
 }
 
 
+// IsHyperV indicates the use of a Hyper-V partition for isolation
+func (i Isolation) IsHyperV() bool {
+	return strings.ToLower(string(i)) == "hyperv"
+}
+
+// IsProcess indicates the use of process isolation
+func (i Isolation) IsProcess() bool {
+	return strings.ToLower(string(i)) == "process"
+}
+
+const (
+	// IsolationEmpty is unspecified (same behavior as default)
+	IsolationEmpty = Isolation("")
+	// IsolationDefault is the default isolation mode on current daemon
+	IsolationDefault = Isolation("default")
+	// IsolationProcess is process isolation mode
+	IsolationProcess = Isolation("process")
+	// IsolationHyperV is HyperV isolation mode
+	IsolationHyperV = Isolation("hyperv")
+)
+
 // IpcMode represents the container ipc stack.
 // IpcMode represents the container ipc stack.
 type IpcMode string
 type IpcMode string
 
 

+ 0 - 14
api/types/container/hostconfig_windows.go

@@ -1,9 +1,5 @@
 package container
 package container
 
 
-import (
-	"strings"
-)
-
 // IsBridge indicates whether container uses the bridge network stack
 // IsBridge indicates whether container uses the bridge network stack
 // in windows it is given the name NAT
 // in windows it is given the name NAT
 func (n NetworkMode) IsBridge() bool {
 func (n NetworkMode) IsBridge() bool {
@@ -21,16 +17,6 @@ func (n NetworkMode) IsUserDefined() bool {
 	return !n.IsDefault() && !n.IsNone() && !n.IsBridge() && !n.IsContainer()
 	return !n.IsDefault() && !n.IsNone() && !n.IsBridge() && !n.IsContainer()
 }
 }
 
 
-// IsHyperV indicates the use of a Hyper-V partition for isolation
-func (i Isolation) IsHyperV() bool {
-	return strings.ToLower(string(i)) == "hyperv"
-}
-
-// IsProcess indicates the use of process isolation
-func (i Isolation) IsProcess() bool {
-	return strings.ToLower(string(i)) == "process"
-}
-
 // IsValid indicates if an isolation technology is valid
 // IsValid indicates if an isolation technology is valid
 func (i Isolation) IsValid() bool {
 func (i Isolation) IsValid() bool {
 	return i.IsDefault() || i.IsHyperV() || i.IsProcess()
 	return i.IsDefault() || i.IsHyperV() || i.IsProcess()

+ 5 - 4
api/types/swarm/container.go

@@ -65,8 +65,9 @@ type ContainerSpec struct {
 	// The format of extra hosts on swarmkit is specified in:
 	// The format of extra hosts on swarmkit is specified in:
 	// http://man7.org/linux/man-pages/man5/hosts.5.html
 	// http://man7.org/linux/man-pages/man5/hosts.5.html
 	//    IP_address canonical_hostname [aliases...]
 	//    IP_address canonical_hostname [aliases...]
-	Hosts     []string           `json:",omitempty"`
-	DNSConfig *DNSConfig         `json:",omitempty"`
-	Secrets   []*SecretReference `json:",omitempty"`
-	Configs   []*ConfigReference `json:",omitempty"`
+	Hosts     []string            `json:",omitempty"`
+	DNSConfig *DNSConfig          `json:",omitempty"`
+	Secrets   []*SecretReference  `json:",omitempty"`
+	Configs   []*ConfigReference  `json:",omitempty"`
+	Isolation container.Isolation `json:",omitempty"`
 }
 }

+ 25 - 0
daemon/cluster/convert/container.go

@@ -34,6 +34,7 @@ func containerSpecFromGRPC(c *swarmapi.ContainerSpec) *types.ContainerSpec {
 		Hosts:      c.Hosts,
 		Hosts:      c.Hosts,
 		Secrets:    secretReferencesFromGRPC(c.Secrets),
 		Secrets:    secretReferencesFromGRPC(c.Secrets),
 		Configs:    configReferencesFromGRPC(c.Configs),
 		Configs:    configReferencesFromGRPC(c.Configs),
+		Isolation:  IsolationFromGRPC(c.Isolation),
 	}
 	}
 
 
 	if c.DNSConfig != nil {
 	if c.DNSConfig != nil {
@@ -232,6 +233,7 @@ func containerToGRPC(c *types.ContainerSpec) (*swarmapi.ContainerSpec, error) {
 		Hosts:      c.Hosts,
 		Hosts:      c.Hosts,
 		Secrets:    secretReferencesToGRPC(c.Secrets),
 		Secrets:    secretReferencesToGRPC(c.Secrets),
 		Configs:    configReferencesToGRPC(c.Configs),
 		Configs:    configReferencesToGRPC(c.Configs),
+		Isolation:  isolationToGRPC(c.Isolation),
 	}
 	}
 
 
 	if c.DNSConfig != nil {
 	if c.DNSConfig != nil {
@@ -354,3 +356,26 @@ func healthConfigToGRPC(h *container.HealthConfig) *swarmapi.HealthConfig {
 		StartPeriod: gogotypes.DurationProto(h.StartPeriod),
 		StartPeriod: gogotypes.DurationProto(h.StartPeriod),
 	}
 	}
 }
 }
+
+// IsolationFromGRPC converts a swarm api container isolation to a moby isolation representation
+func IsolationFromGRPC(i swarmapi.ContainerSpec_Isolation) container.Isolation {
+	switch i {
+	case swarmapi.ContainerIsolationHyperV:
+		return container.IsolationHyperV
+	case swarmapi.ContainerIsolationProcess:
+		return container.IsolationProcess
+	case swarmapi.ContainerIsolationDefault:
+		return container.IsolationDefault
+	}
+	return container.IsolationEmpty
+}
+
+func isolationToGRPC(i container.Isolation) swarmapi.ContainerSpec_Isolation {
+	if i.IsHyperV() {
+		return swarmapi.ContainerIsolationHyperV
+	}
+	if i.IsProcess() {
+		return swarmapi.ContainerIsolationProcess
+	}
+	return swarmapi.ContainerIsolationDefault
+}

+ 84 - 0
daemon/cluster/convert/service_test.go

@@ -3,10 +3,12 @@ package convert
 import (
 import (
 	"testing"
 	"testing"
 
 
+	containertypes "github.com/docker/docker/api/types/container"
 	swarmtypes "github.com/docker/docker/api/types/swarm"
 	swarmtypes "github.com/docker/docker/api/types/swarm"
 	"github.com/docker/docker/api/types/swarm/runtime"
 	"github.com/docker/docker/api/types/swarm/runtime"
 	swarmapi "github.com/docker/swarmkit/api"
 	swarmapi "github.com/docker/swarmkit/api"
 	google_protobuf3 "github.com/gogo/protobuf/types"
 	google_protobuf3 "github.com/gogo/protobuf/types"
+	"github.com/stretchr/testify/require"
 )
 )
 
 
 func TestServiceConvertFromGRPCRuntimeContainer(t *testing.T) {
 func TestServiceConvertFromGRPCRuntimeContainer(t *testing.T) {
@@ -148,3 +150,85 @@ func TestServiceConvertToGRPCGenericRuntimeCustom(t *testing.T) {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
 }
 }
+
+func TestServiceConvertToGRPCIsolation(t *testing.T) {
+	cases := []struct {
+		name string
+		from containertypes.Isolation
+		to   swarmapi.ContainerSpec_Isolation
+	}{
+		{name: "empty", from: containertypes.IsolationEmpty, to: swarmapi.ContainerIsolationDefault},
+		{name: "default", from: containertypes.IsolationDefault, to: swarmapi.ContainerIsolationDefault},
+		{name: "process", from: containertypes.IsolationProcess, to: swarmapi.ContainerIsolationProcess},
+		{name: "hyperv", from: containertypes.IsolationHyperV, to: swarmapi.ContainerIsolationHyperV},
+		{name: "proCess", from: containertypes.Isolation("proCess"), to: swarmapi.ContainerIsolationProcess},
+		{name: "hypErv", from: containertypes.Isolation("hypErv"), to: swarmapi.ContainerIsolationHyperV},
+	}
+	for _, c := range cases {
+		t.Run(c.name, func(t *testing.T) {
+			s := swarmtypes.ServiceSpec{
+				TaskTemplate: swarmtypes.TaskSpec{
+					ContainerSpec: &swarmtypes.ContainerSpec{
+						Image:     "alpine:latest",
+						Isolation: c.from,
+					},
+				},
+				Mode: swarmtypes.ServiceMode{
+					Global: &swarmtypes.GlobalService{},
+				},
+			}
+			res, err := ServiceSpecToGRPC(s)
+			require.NoError(t, err)
+			v, ok := res.Task.Runtime.(*swarmapi.TaskSpec_Container)
+			if !ok {
+				t.Fatal("expected type swarmapi.TaskSpec_Container")
+			}
+			require.Equal(t, c.to, v.Container.Isolation)
+		})
+	}
+}
+
+func TestServiceConvertFromGRPCIsolation(t *testing.T) {
+	cases := []struct {
+		name string
+		from swarmapi.ContainerSpec_Isolation
+		to   containertypes.Isolation
+	}{
+		{name: "default", to: containertypes.IsolationDefault, from: swarmapi.ContainerIsolationDefault},
+		{name: "process", to: containertypes.IsolationProcess, from: swarmapi.ContainerIsolationProcess},
+		{name: "hyperv", to: containertypes.IsolationHyperV, from: swarmapi.ContainerIsolationHyperV},
+	}
+	for _, c := range cases {
+		t.Run(c.name, func(t *testing.T) {
+			gs := swarmapi.Service{
+				Meta: swarmapi.Meta{
+					Version: swarmapi.Version{
+						Index: 1,
+					},
+					CreatedAt: nil,
+					UpdatedAt: nil,
+				},
+				SpecVersion: &swarmapi.Version{
+					Index: 1,
+				},
+				Spec: swarmapi.ServiceSpec{
+					Task: swarmapi.TaskSpec{
+						Runtime: &swarmapi.TaskSpec_Container{
+							Container: &swarmapi.ContainerSpec{
+								Image:     "alpine:latest",
+								Isolation: c.from,
+							},
+						},
+					},
+				},
+			}
+
+			svc, err := ServiceFromGRPC(gs)
+			if err != nil {
+				t.Fatal(err)
+			}
+
+			require.Equal(t, c.to, svc.Spec.TaskTemplate.ContainerSpec.Isolation)
+		})
+	}
+}

+ 5 - 0
daemon/cluster/executor/container/container.go

@@ -168,6 +168,10 @@ func (c *containerConfig) portBindings() nat.PortMap {
 	return portBindings
 	return portBindings
 }
 }
 
 
+func (c *containerConfig) isolation() enginecontainer.Isolation {
+	return convert.IsolationFromGRPC(c.spec().Isolation)
+}
+
 func (c *containerConfig) exposedPorts() map[nat.Port]struct{} {
 func (c *containerConfig) exposedPorts() map[nat.Port]struct{} {
 	exposedPorts := make(map[nat.Port]struct{})
 	exposedPorts := make(map[nat.Port]struct{})
 	if c.task.Endpoint == nil {
 	if c.task.Endpoint == nil {
@@ -350,6 +354,7 @@ func (c *containerConfig) hostConfig() *enginecontainer.HostConfig {
 		PortBindings:   c.portBindings(),
 		PortBindings:   c.portBindings(),
 		Mounts:         c.mounts(),
 		Mounts:         c.mounts(),
 		ReadonlyRootfs: c.spec().ReadOnly,
 		ReadonlyRootfs: c.spec().ReadOnly,
+		Isolation:      c.isolation(),
 	}
 	}
 
 
 	if c.spec().DNSConfig != nil {
 	if c.spec().DNSConfig != nil {

+ 37 - 0
daemon/cluster/executor/container/container_test.go

@@ -0,0 +1,37 @@
+package container
+
+import (
+	"testing"
+
+	container "github.com/docker/docker/api/types/container"
+	swarmapi "github.com/docker/swarmkit/api"
+	"github.com/stretchr/testify/require"
+)
+
+func TestIsolationConversion(t *testing.T) {
+	cases := []struct {
+		name string
+		from swarmapi.ContainerSpec_Isolation
+		to   container.Isolation
+	}{
+		{name: "default", from: swarmapi.ContainerIsolationDefault, to: container.IsolationDefault},
+		{name: "process", from: swarmapi.ContainerIsolationProcess, to: container.IsolationProcess},
+		{name: "hyperv", from: swarmapi.ContainerIsolationHyperV, to: container.IsolationHyperV},
+	}
+	for _, c := range cases {
+		t.Run(c.name, func(t *testing.T) {
+			task := swarmapi.Task{
+				Spec: swarmapi.TaskSpec{
+					Runtime: &swarmapi.TaskSpec_Container{
+						Container: &swarmapi.ContainerSpec{
+							Image:     "alpine:latest",
+							Isolation: c.from,
+						},
+					},
+				},
+			}
+			config := containerConfig{task: &task}
+			require.Equal(t, c.to, config.hostConfig().Isolation)
+		})
+	}
+}

+ 1 - 0
docs/api/version-history.md

@@ -23,6 +23,7 @@ keywords: "API, Docker, rcli, REST, documentation"
   If `Error` is `null`, container removal has succeeded, otherwise
   If `Error` is `null`, container removal has succeeded, otherwise
   the test of an error message indicating why container removal has failed
   the test of an error message indicating why container removal has failed
   is available from `Error.Message` field.
   is available from `Error.Message` field.
+* `POST /services/create` and `POST /services/(id)/update` now accept an `Isolation` field on container spec
 
 
 ## v1.33 API changes
 ## v1.33 API changes
 
 

+ 17 - 0
integration-cli/daemon/daemon_swarm.go

@@ -198,6 +198,23 @@ func (d *Swarm) CheckServiceTasksInState(service string, state swarm.TaskState,
 	}
 	}
 }
 }
 
 
+// CheckServiceTasksInStateWithError returns the number of tasks with a matching state,
+// and optional message substring.
+func (d *Swarm) CheckServiceTasksInStateWithError(service string, state swarm.TaskState, errorMessage string) func(*check.C) (interface{}, check.CommentInterface) {
+	return func(c *check.C) (interface{}, check.CommentInterface) {
+		tasks := d.GetServiceTasks(c, service)
+		var count int
+		for _, task := range tasks {
+			if task.Status.State == state {
+				if errorMessage == "" || strings.Contains(task.Status.Err, errorMessage) {
+					count++
+				}
+			}
+		}
+		return count, nil
+	}
+}
+
 // CheckServiceRunningTasks returns the number of running tasks for the specified service
 // CheckServiceRunningTasks returns the number of running tasks for the specified service
 func (d *Swarm) CheckServiceRunningTasks(service string) func(*check.C) (interface{}, check.CommentInterface) {
 func (d *Swarm) CheckServiceRunningTasks(service string) func(*check.C) (interface{}, check.CommentInterface) {
 	return d.CheckServiceTasksInState(service, swarm.TaskStateRunning, "")
 	return d.CheckServiceTasksInState(service, swarm.TaskStateRunning, "")

+ 1 - 1
integration-cli/docker_cli_swarm_unix_test.go

@@ -19,7 +19,7 @@ func (s *DockerSwarmSuite) TestSwarmVolumePlugin(c *check.C) {
 	c.Assert(err, checker.IsNil, check.Commentf(out))
 	c.Assert(err, checker.IsNil, check.Commentf(out))
 
 
 	// Make sure task stays pending before plugin is available
 	// Make sure task stays pending before plugin is available
-	waitAndAssert(c, defaultReconciliationTimeout, d.CheckServiceTasksInState("top", swarm.TaskStatePending, "missing plugin on 1 node"), checker.Equals, 1)
+	waitAndAssert(c, defaultReconciliationTimeout, d.CheckServiceTasksInStateWithError("top", swarm.TaskStatePending, "missing plugin on 1 node"), checker.Equals, 1)
 
 
 	plugin := newVolumePlugin(c, "customvolumedriver")
 	plugin := newVolumePlugin(c, "customvolumedriver")
 	defer plugin.Close()
 	defer plugin.Close()

+ 2 - 0
integration/service/inspect_test.go

@@ -6,6 +6,7 @@ import (
 	"time"
 	"time"
 
 
 	"github.com/docker/docker/api/types"
 	"github.com/docker/docker/api/types"
+	"github.com/docker/docker/api/types/container"
 	"github.com/docker/docker/api/types/filters"
 	"github.com/docker/docker/api/types/filters"
 	"github.com/docker/docker/api/types/swarm"
 	"github.com/docker/docker/api/types/swarm"
 	"github.com/docker/docker/client"
 	"github.com/docker/docker/client"
@@ -76,6 +77,7 @@ func fullSwarmServiceSpec(name string, replicas uint64) swarm.ServiceSpec {
 					Nameservers: []string{"8.8.8.8"},
 					Nameservers: []string{"8.8.8.8"},
 					Search:      []string{"somedomain"},
 					Search:      []string{"somedomain"},
 				},
 				},
+				Isolation: container.IsolationDefault,
 			},
 			},
 			RestartPolicy: &swarm.RestartPolicy{
 			RestartPolicy: &swarm.RestartPolicy{
 				Delay:       &restartDelay,
 				Delay:       &restartDelay,

+ 1 - 2
vendor.conf

@@ -103,7 +103,6 @@ github.com/googleapis/gax-go da06d194a00e19ce00d9011a13931c3f6f6887c7
 google.golang.org/genproto d80a6e20e776b0b17a324d0ba1ab50a39c8e8944
 google.golang.org/genproto d80a6e20e776b0b17a324d0ba1ab50a39c8e8944
 
 
 # containerd
 # containerd
-github.com/stevvooe/continuity cd7a8e21e2b6f84799f5dd4b65faf49c8d3ee02d
 github.com/containerd/containerd 992280e8e265f491f7a624ab82f3e238be086e49
 github.com/containerd/containerd 992280e8e265f491f7a624ab82f3e238be086e49
 github.com/containerd/fifo fbfb6a11ec671efbe94ad1c12c2e98773f19e1e6
 github.com/containerd/fifo fbfb6a11ec671efbe94ad1c12c2e98773f19e1e6
 github.com/containerd/continuity 35d55c5e8dd23b32037d56cf97174aff3efdfa83
 github.com/containerd/continuity 35d55c5e8dd23b32037d56cf97174aff3efdfa83
@@ -114,7 +113,7 @@ github.com/containerd/typeurl f6943554a7e7e88b3c14aad190bf05932da84788
 github.com/dmcgowan/go-tar 2e2c51242e8993c50445dab7c03c8e7febddd0cf
 github.com/dmcgowan/go-tar 2e2c51242e8993c50445dab7c03c8e7febddd0cf
 
 
 # cluster
 # cluster
-github.com/docker/swarmkit 872861d2ae46958af7ead1d5fffb092c73afbaf0
+github.com/docker/swarmkit 28f91d87bd3f75fd039dbb9be49bfd2381019261
 github.com/gogo/protobuf v0.4
 github.com/gogo/protobuf v0.4
 github.com/cloudflare/cfssl 7fb22c8cba7ecaf98e4082d22d65800cf45e042a
 github.com/cloudflare/cfssl 7fb22c8cba7ecaf98e4082d22d65800cf45e042a
 github.com/google/certificate-transparency d90e65c3a07988180c5b1ece71791c0b6506826e
 github.com/google/certificate-transparency d90e65c3a07988180c5b1ece71791c0b6506826e

+ 2 - 0
vendor/github.com/docker/swarmkit/agent/exec/controller.go

@@ -119,6 +119,7 @@ func Resolve(ctx context.Context, task *api.Task, executor Executor) (Controller
 		// we always want to proceed to accepted when we resolve the controller
 		// we always want to proceed to accepted when we resolve the controller
 		status.Message = "accepted"
 		status.Message = "accepted"
 		status.State = api.TaskStateAccepted
 		status.State = api.TaskStateAccepted
+		status.Err = ""
 	}
 	}
 
 
 	return ctlr, status, err
 	return ctlr, status, err
@@ -158,6 +159,7 @@ func Do(ctx context.Context, task *api.Task, ctlr Controller) (*api.TaskStatus,
 		current := status.State
 		current := status.State
 		status.State = state
 		status.State = state
 		status.Message = msg
 		status.Message = msg
+		status.Err = ""
 
 
 		if current > state {
 		if current > state {
 			panic("invalid state transition")
 			panic("invalid state transition")

+ 288 - 159
vendor/github.com/docker/swarmkit/api/specs.pb.go

@@ -10,6 +10,7 @@ import math "math"
 import _ "github.com/gogo/protobuf/gogoproto"
 import _ "github.com/gogo/protobuf/gogoproto"
 import google_protobuf1 "github.com/gogo/protobuf/types"
 import google_protobuf1 "github.com/gogo/protobuf/types"
 import google_protobuf3 "github.com/gogo/protobuf/types"
 import google_protobuf3 "github.com/gogo/protobuf/types"
+import google_protobuf4 "github.com/gogo/protobuf/types"
 
 
 import github_com_docker_swarmkit_api_deepcopy "github.com/docker/swarmkit/api/deepcopy"
 import github_com_docker_swarmkit_api_deepcopy "github.com/docker/swarmkit/api/deepcopy"
 
 
@@ -74,6 +75,35 @@ func (x NodeSpec_Availability) String() string {
 }
 }
 func (NodeSpec_Availability) EnumDescriptor() ([]byte, []int) { return fileDescriptorSpecs, []int{0, 1} }
 func (NodeSpec_Availability) EnumDescriptor() ([]byte, []int) { return fileDescriptorSpecs, []int{0, 1} }
 
 
+type ContainerSpec_Isolation int32
+
+const (
+	// ISOLATION_DEFAULT uses whatever default value from the container runtime
+	ContainerIsolationDefault ContainerSpec_Isolation = 0
+	// ISOLATION_PROCESS forces windows container isolation
+	ContainerIsolationProcess ContainerSpec_Isolation = 1
+	// ISOLATION_HYPERV forces Hyper-V isolation
+	ContainerIsolationHyperV ContainerSpec_Isolation = 2
+)
+
+var ContainerSpec_Isolation_name = map[int32]string{
+	0: "ISOLATION_DEFAULT",
+	1: "ISOLATION_PROCESS",
+	2: "ISOLATION_HYPERV",
+}
+var ContainerSpec_Isolation_value = map[string]int32{
+	"ISOLATION_DEFAULT": 0,
+	"ISOLATION_PROCESS": 1,
+	"ISOLATION_HYPERV":  2,
+}
+
+func (x ContainerSpec_Isolation) String() string {
+	return proto.EnumName(ContainerSpec_Isolation_name, int32(x))
+}
+func (ContainerSpec_Isolation) EnumDescriptor() ([]byte, []int) {
+	return fileDescriptorSpecs, []int{8, 0}
+}
+
 // ResolutionMode specifies the mode of resolution to use for
 // ResolutionMode specifies the mode of resolution to use for
 // internal loadbalancing between tasks which are all within
 // internal loadbalancing between tasks which are all within
 // the cluster. This is sometimes calls east-west data path.
 // the cluster. This is sometimes calls east-west data path.
@@ -542,6 +572,8 @@ type ContainerSpec struct {
 	Groups []string `protobuf:"bytes,11,rep,name=groups" json:"groups,omitempty"`
 	Groups []string `protobuf:"bytes,11,rep,name=groups" json:"groups,omitempty"`
 	// Privileges specifies security configuration/permissions.
 	// Privileges specifies security configuration/permissions.
 	Privileges *Privileges `protobuf:"bytes,22,opt,name=privileges" json:"privileges,omitempty"`
 	Privileges *Privileges `protobuf:"bytes,22,opt,name=privileges" json:"privileges,omitempty"`
+	// Init declares that a custom init will be running inside the container, if null, use the daemon's configured settings
+	Init *google_protobuf4.BoolValue `protobuf:"bytes,23,opt,name=init" json:"init,omitempty"`
 	// TTY declares that a TTY should be attached to the standard streams,
 	// TTY declares that a TTY should be attached to the standard streams,
 	// including stdin if it is still open.
 	// including stdin if it is still open.
 	TTY bool `protobuf:"varint,13,opt,name=tty,proto3" json:"tty,omitempty"`
 	TTY bool `protobuf:"varint,13,opt,name=tty,proto3" json:"tty,omitempty"`
@@ -585,6 +617,9 @@ type ContainerSpec struct {
 	// task will exit and a new task will be rescheduled elsewhere. A container
 	// task will exit and a new task will be rescheduled elsewhere. A container
 	// is considered unhealthy after `Retries` number of consecutive failures.
 	// is considered unhealthy after `Retries` number of consecutive failures.
 	Healthcheck *HealthConfig `protobuf:"bytes,16,opt,name=healthcheck" json:"healthcheck,omitempty"`
 	Healthcheck *HealthConfig `protobuf:"bytes,16,opt,name=healthcheck" json:"healthcheck,omitempty"`
+	// Isolation defines the isolation level for windows containers (default, process, hyperv).
+	// Runtimes that don't support it ignore that field
+	Isolation ContainerSpec_Isolation `protobuf:"varint,24,opt,name=isolation,proto3,enum=docker.swarmkit.v1.ContainerSpec_Isolation" json:"isolation,omitempty"`
 }
 }
 
 
 func (m *ContainerSpec) Reset()                    { *m = ContainerSpec{} }
 func (m *ContainerSpec) Reset()                    { *m = ContainerSpec{} }
@@ -830,6 +865,7 @@ func init() {
 	proto.RegisterType((*ConfigSpec)(nil), "docker.swarmkit.v1.ConfigSpec")
 	proto.RegisterType((*ConfigSpec)(nil), "docker.swarmkit.v1.ConfigSpec")
 	proto.RegisterEnum("docker.swarmkit.v1.NodeSpec_Membership", NodeSpec_Membership_name, NodeSpec_Membership_value)
 	proto.RegisterEnum("docker.swarmkit.v1.NodeSpec_Membership", NodeSpec_Membership_name, NodeSpec_Membership_value)
 	proto.RegisterEnum("docker.swarmkit.v1.NodeSpec_Availability", NodeSpec_Availability_name, NodeSpec_Availability_value)
 	proto.RegisterEnum("docker.swarmkit.v1.NodeSpec_Availability", NodeSpec_Availability_name, NodeSpec_Availability_value)
+	proto.RegisterEnum("docker.swarmkit.v1.ContainerSpec_Isolation", ContainerSpec_Isolation_name, ContainerSpec_Isolation_value)
 	proto.RegisterEnum("docker.swarmkit.v1.EndpointSpec_ResolutionMode", EndpointSpec_ResolutionMode_name, EndpointSpec_ResolutionMode_value)
 	proto.RegisterEnum("docker.swarmkit.v1.EndpointSpec_ResolutionMode", EndpointSpec_ResolutionMode_name, EndpointSpec_ResolutionMode_value)
 }
 }
 
 
@@ -1090,6 +1126,10 @@ func (m *ContainerSpec) CopyFrom(src interface{}) {
 		m.Privileges = &Privileges{}
 		m.Privileges = &Privileges{}
 		github_com_docker_swarmkit_api_deepcopy.Copy(m.Privileges, o.Privileges)
 		github_com_docker_swarmkit_api_deepcopy.Copy(m.Privileges, o.Privileges)
 	}
 	}
+	if o.Init != nil {
+		m.Init = &google_protobuf4.BoolValue{}
+		github_com_docker_swarmkit_api_deepcopy.Copy(m.Init, o.Init)
+	}
 	if o.Mounts != nil {
 	if o.Mounts != nil {
 		m.Mounts = make([]Mount, len(o.Mounts))
 		m.Mounts = make([]Mount, len(o.Mounts))
 		for i := range m.Mounts {
 		for i := range m.Mounts {
@@ -1996,6 +2036,25 @@ func (m *ContainerSpec) MarshalTo(dAtA []byte) (int, error) {
 		}
 		}
 		i += n23
 		i += n23
 	}
 	}
+	if m.Init != nil {
+		dAtA[i] = 0xba
+		i++
+		dAtA[i] = 0x1
+		i++
+		i = encodeVarintSpecs(dAtA, i, uint64(m.Init.Size()))
+		n24, err := m.Init.MarshalTo(dAtA[i:])
+		if err != nil {
+			return 0, err
+		}
+		i += n24
+	}
+	if m.Isolation != 0 {
+		dAtA[i] = 0xc0
+		i++
+		dAtA[i] = 0x1
+		i++
+		i = encodeVarintSpecs(dAtA, i, uint64(m.Isolation))
+	}
 	return i, nil
 	return i, nil
 }
 }
 
 
@@ -2141,20 +2200,20 @@ func (m *NetworkSpec) MarshalTo(dAtA []byte) (int, error) {
 	dAtA[i] = 0xa
 	dAtA[i] = 0xa
 	i++
 	i++
 	i = encodeVarintSpecs(dAtA, i, uint64(m.Annotations.Size()))
 	i = encodeVarintSpecs(dAtA, i, uint64(m.Annotations.Size()))
-	n24, err := m.Annotations.MarshalTo(dAtA[i:])
+	n25, err := m.Annotations.MarshalTo(dAtA[i:])
 	if err != nil {
 	if err != nil {
 		return 0, err
 		return 0, err
 	}
 	}
-	i += n24
+	i += n25
 	if m.DriverConfig != nil {
 	if m.DriverConfig != nil {
 		dAtA[i] = 0x12
 		dAtA[i] = 0x12
 		i++
 		i++
 		i = encodeVarintSpecs(dAtA, i, uint64(m.DriverConfig.Size()))
 		i = encodeVarintSpecs(dAtA, i, uint64(m.DriverConfig.Size()))
-		n25, err := m.DriverConfig.MarshalTo(dAtA[i:])
+		n26, err := m.DriverConfig.MarshalTo(dAtA[i:])
 		if err != nil {
 		if err != nil {
 			return 0, err
 			return 0, err
 		}
 		}
-		i += n25
+		i += n26
 	}
 	}
 	if m.Ipv6Enabled {
 	if m.Ipv6Enabled {
 		dAtA[i] = 0x18
 		dAtA[i] = 0x18
@@ -2180,11 +2239,11 @@ func (m *NetworkSpec) MarshalTo(dAtA []byte) (int, error) {
 		dAtA[i] = 0x2a
 		dAtA[i] = 0x2a
 		i++
 		i++
 		i = encodeVarintSpecs(dAtA, i, uint64(m.IPAM.Size()))
 		i = encodeVarintSpecs(dAtA, i, uint64(m.IPAM.Size()))
-		n26, err := m.IPAM.MarshalTo(dAtA[i:])
+		n27, err := m.IPAM.MarshalTo(dAtA[i:])
 		if err != nil {
 		if err != nil {
 			return 0, err
 			return 0, err
 		}
 		}
-		i += n26
+		i += n27
 	}
 	}
 	if m.Attachable {
 	if m.Attachable {
 		dAtA[i] = 0x30
 		dAtA[i] = 0x30
@@ -2207,11 +2266,11 @@ func (m *NetworkSpec) MarshalTo(dAtA []byte) (int, error) {
 		i++
 		i++
 	}
 	}
 	if m.ConfigFrom != nil {
 	if m.ConfigFrom != nil {
-		nn27, err := m.ConfigFrom.MarshalTo(dAtA[i:])
+		nn28, err := m.ConfigFrom.MarshalTo(dAtA[i:])
 		if err != nil {
 		if err != nil {
 			return 0, err
 			return 0, err
 		}
 		}
-		i += nn27
+		i += nn28
 	}
 	}
 	return i, nil
 	return i, nil
 }
 }
@@ -2242,67 +2301,67 @@ func (m *ClusterSpec) MarshalTo(dAtA []byte) (int, error) {
 	dAtA[i] = 0xa
 	dAtA[i] = 0xa
 	i++
 	i++
 	i = encodeVarintSpecs(dAtA, i, uint64(m.Annotations.Size()))
 	i = encodeVarintSpecs(dAtA, i, uint64(m.Annotations.Size()))
-	n28, err := m.Annotations.MarshalTo(dAtA[i:])
+	n29, err := m.Annotations.MarshalTo(dAtA[i:])
 	if err != nil {
 	if err != nil {
 		return 0, err
 		return 0, err
 	}
 	}
-	i += n28
+	i += n29
 	dAtA[i] = 0x12
 	dAtA[i] = 0x12
 	i++
 	i++
 	i = encodeVarintSpecs(dAtA, i, uint64(m.AcceptancePolicy.Size()))
 	i = encodeVarintSpecs(dAtA, i, uint64(m.AcceptancePolicy.Size()))
-	n29, err := m.AcceptancePolicy.MarshalTo(dAtA[i:])
+	n30, err := m.AcceptancePolicy.MarshalTo(dAtA[i:])
 	if err != nil {
 	if err != nil {
 		return 0, err
 		return 0, err
 	}
 	}
-	i += n29
+	i += n30
 	dAtA[i] = 0x1a
 	dAtA[i] = 0x1a
 	i++
 	i++
 	i = encodeVarintSpecs(dAtA, i, uint64(m.Orchestration.Size()))
 	i = encodeVarintSpecs(dAtA, i, uint64(m.Orchestration.Size()))
-	n30, err := m.Orchestration.MarshalTo(dAtA[i:])
+	n31, err := m.Orchestration.MarshalTo(dAtA[i:])
 	if err != nil {
 	if err != nil {
 		return 0, err
 		return 0, err
 	}
 	}
-	i += n30
+	i += n31
 	dAtA[i] = 0x22
 	dAtA[i] = 0x22
 	i++
 	i++
 	i = encodeVarintSpecs(dAtA, i, uint64(m.Raft.Size()))
 	i = encodeVarintSpecs(dAtA, i, uint64(m.Raft.Size()))
-	n31, err := m.Raft.MarshalTo(dAtA[i:])
+	n32, err := m.Raft.MarshalTo(dAtA[i:])
 	if err != nil {
 	if err != nil {
 		return 0, err
 		return 0, err
 	}
 	}
-	i += n31
+	i += n32
 	dAtA[i] = 0x2a
 	dAtA[i] = 0x2a
 	i++
 	i++
 	i = encodeVarintSpecs(dAtA, i, uint64(m.Dispatcher.Size()))
 	i = encodeVarintSpecs(dAtA, i, uint64(m.Dispatcher.Size()))
-	n32, err := m.Dispatcher.MarshalTo(dAtA[i:])
+	n33, err := m.Dispatcher.MarshalTo(dAtA[i:])
 	if err != nil {
 	if err != nil {
 		return 0, err
 		return 0, err
 	}
 	}
-	i += n32
+	i += n33
 	dAtA[i] = 0x32
 	dAtA[i] = 0x32
 	i++
 	i++
 	i = encodeVarintSpecs(dAtA, i, uint64(m.CAConfig.Size()))
 	i = encodeVarintSpecs(dAtA, i, uint64(m.CAConfig.Size()))
-	n33, err := m.CAConfig.MarshalTo(dAtA[i:])
+	n34, err := m.CAConfig.MarshalTo(dAtA[i:])
 	if err != nil {
 	if err != nil {
 		return 0, err
 		return 0, err
 	}
 	}
-	i += n33
+	i += n34
 	dAtA[i] = 0x3a
 	dAtA[i] = 0x3a
 	i++
 	i++
 	i = encodeVarintSpecs(dAtA, i, uint64(m.TaskDefaults.Size()))
 	i = encodeVarintSpecs(dAtA, i, uint64(m.TaskDefaults.Size()))
-	n34, err := m.TaskDefaults.MarshalTo(dAtA[i:])
+	n35, err := m.TaskDefaults.MarshalTo(dAtA[i:])
 	if err != nil {
 	if err != nil {
 		return 0, err
 		return 0, err
 	}
 	}
-	i += n34
+	i += n35
 	dAtA[i] = 0x42
 	dAtA[i] = 0x42
 	i++
 	i++
 	i = encodeVarintSpecs(dAtA, i, uint64(m.EncryptionConfig.Size()))
 	i = encodeVarintSpecs(dAtA, i, uint64(m.EncryptionConfig.Size()))
-	n35, err := m.EncryptionConfig.MarshalTo(dAtA[i:])
+	n36, err := m.EncryptionConfig.MarshalTo(dAtA[i:])
 	if err != nil {
 	if err != nil {
 		return 0, err
 		return 0, err
 	}
 	}
-	i += n35
+	i += n36
 	return i, nil
 	return i, nil
 }
 }
 
 
@@ -2324,11 +2383,11 @@ func (m *SecretSpec) MarshalTo(dAtA []byte) (int, error) {
 	dAtA[i] = 0xa
 	dAtA[i] = 0xa
 	i++
 	i++
 	i = encodeVarintSpecs(dAtA, i, uint64(m.Annotations.Size()))
 	i = encodeVarintSpecs(dAtA, i, uint64(m.Annotations.Size()))
-	n36, err := m.Annotations.MarshalTo(dAtA[i:])
+	n37, err := m.Annotations.MarshalTo(dAtA[i:])
 	if err != nil {
 	if err != nil {
 		return 0, err
 		return 0, err
 	}
 	}
-	i += n36
+	i += n37
 	if len(m.Data) > 0 {
 	if len(m.Data) > 0 {
 		dAtA[i] = 0x12
 		dAtA[i] = 0x12
 		i++
 		i++
@@ -2339,21 +2398,21 @@ func (m *SecretSpec) MarshalTo(dAtA []byte) (int, error) {
 		dAtA[i] = 0x1a
 		dAtA[i] = 0x1a
 		i++
 		i++
 		i = encodeVarintSpecs(dAtA, i, uint64(m.Templating.Size()))
 		i = encodeVarintSpecs(dAtA, i, uint64(m.Templating.Size()))
-		n37, err := m.Templating.MarshalTo(dAtA[i:])
+		n38, err := m.Templating.MarshalTo(dAtA[i:])
 		if err != nil {
 		if err != nil {
 			return 0, err
 			return 0, err
 		}
 		}
-		i += n37
+		i += n38
 	}
 	}
 	if m.Driver != nil {
 	if m.Driver != nil {
 		dAtA[i] = 0x22
 		dAtA[i] = 0x22
 		i++
 		i++
 		i = encodeVarintSpecs(dAtA, i, uint64(m.Driver.Size()))
 		i = encodeVarintSpecs(dAtA, i, uint64(m.Driver.Size()))
-		n38, err := m.Driver.MarshalTo(dAtA[i:])
+		n39, err := m.Driver.MarshalTo(dAtA[i:])
 		if err != nil {
 		if err != nil {
 			return 0, err
 			return 0, err
 		}
 		}
-		i += n38
+		i += n39
 	}
 	}
 	return i, nil
 	return i, nil
 }
 }
@@ -2376,11 +2435,11 @@ func (m *ConfigSpec) MarshalTo(dAtA []byte) (int, error) {
 	dAtA[i] = 0xa
 	dAtA[i] = 0xa
 	i++
 	i++
 	i = encodeVarintSpecs(dAtA, i, uint64(m.Annotations.Size()))
 	i = encodeVarintSpecs(dAtA, i, uint64(m.Annotations.Size()))
-	n39, err := m.Annotations.MarshalTo(dAtA[i:])
+	n40, err := m.Annotations.MarshalTo(dAtA[i:])
 	if err != nil {
 	if err != nil {
 		return 0, err
 		return 0, err
 	}
 	}
-	i += n39
+	i += n40
 	if len(m.Data) > 0 {
 	if len(m.Data) > 0 {
 		dAtA[i] = 0x12
 		dAtA[i] = 0x12
 		i++
 		i++
@@ -2391,11 +2450,11 @@ func (m *ConfigSpec) MarshalTo(dAtA []byte) (int, error) {
 		dAtA[i] = 0x1a
 		dAtA[i] = 0x1a
 		i++
 		i++
 		i = encodeVarintSpecs(dAtA, i, uint64(m.Templating.Size()))
 		i = encodeVarintSpecs(dAtA, i, uint64(m.Templating.Size()))
-		n40, err := m.Templating.MarshalTo(dAtA[i:])
+		n41, err := m.Templating.MarshalTo(dAtA[i:])
 		if err != nil {
 		if err != nil {
 			return 0, err
 			return 0, err
 		}
 		}
-		i += n40
+		i += n41
 	}
 	}
 	return i, nil
 	return i, nil
 }
 }
@@ -2721,6 +2780,13 @@ func (m *ContainerSpec) Size() (n int) {
 		l = m.Privileges.Size()
 		l = m.Privileges.Size()
 		n += 2 + l + sovSpecs(uint64(l))
 		n += 2 + l + sovSpecs(uint64(l))
 	}
 	}
+	if m.Init != nil {
+		l = m.Init.Size()
+		n += 2 + l + sovSpecs(uint64(l))
+	}
+	if m.Isolation != 0 {
+		n += 2 + sovSpecs(uint64(m.Isolation))
+	}
 	return n
 	return n
 }
 }
 
 
@@ -3066,6 +3132,8 @@ func (this *ContainerSpec) String() string {
 		`StopSignal:` + fmt.Sprintf("%v", this.StopSignal) + `,`,
 		`StopSignal:` + fmt.Sprintf("%v", this.StopSignal) + `,`,
 		`Configs:` + strings.Replace(fmt.Sprintf("%v", this.Configs), "ConfigReference", "ConfigReference", 1) + `,`,
 		`Configs:` + strings.Replace(fmt.Sprintf("%v", this.Configs), "ConfigReference", "ConfigReference", 1) + `,`,
 		`Privileges:` + strings.Replace(fmt.Sprintf("%v", this.Privileges), "Privileges", "Privileges", 1) + `,`,
 		`Privileges:` + strings.Replace(fmt.Sprintf("%v", this.Privileges), "Privileges", "Privileges", 1) + `,`,
+		`Init:` + strings.Replace(fmt.Sprintf("%v", this.Init), "BoolValue", "google_protobuf4.BoolValue", 1) + `,`,
+		`Isolation:` + fmt.Sprintf("%v", this.Isolation) + `,`,
 		`}`,
 		`}`,
 	}, "")
 	}, "")
 	return s
 	return s
@@ -5141,6 +5209,58 @@ func (m *ContainerSpec) Unmarshal(dAtA []byte) error {
 				return err
 				return err
 			}
 			}
 			iNdEx = postIndex
 			iNdEx = postIndex
+		case 23:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Init", wireType)
+			}
+			var msglen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowSpecs
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				msglen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if msglen < 0 {
+				return ErrInvalidLengthSpecs
+			}
+			postIndex := iNdEx + msglen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			if m.Init == nil {
+				m.Init = &google_protobuf4.BoolValue{}
+			}
+			if err := m.Init.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		case 24:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Isolation", wireType)
+			}
+			m.Isolation = 0
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowSpecs
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				m.Isolation |= (ContainerSpec_Isolation(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
 		default:
 		default:
 			iNdEx = preIndex
 			iNdEx = preIndex
 			skippy, err := skipSpecs(dAtA[iNdEx:])
 			skippy, err := skipSpecs(dAtA[iNdEx:])
@@ -6452,129 +6572,138 @@ var (
 func init() { proto.RegisterFile("github.com/docker/swarmkit/api/specs.proto", fileDescriptorSpecs) }
 func init() { proto.RegisterFile("github.com/docker/swarmkit/api/specs.proto", fileDescriptorSpecs) }
 
 
 var fileDescriptorSpecs = []byte{
 var fileDescriptorSpecs = []byte{
-	// 1975 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x57, 0xcf, 0x6f, 0x1b, 0xb9,
-	0x15, 0xb6, 0x6c, 0x59, 0x3f, 0xde, 0xc8, 0x89, 0xc2, 0xcd, 0xa6, 0x13, 0xa5, 0x6b, 0x2b, 0xda,
-	0x6c, 0xea, 0xdd, 0x45, 0x25, 0xd4, 0x2d, 0xb6, 0xd9, 0x4d, 0xb7, 0xad, 0x64, 0xa9, 0x8e, 0x9b,
-	0xc6, 0x11, 0x68, 0x6f, 0xda, 0x00, 0x05, 0x04, 0x6a, 0x86, 0x1e, 0x0d, 0x3c, 0x1a, 0x4e, 0x39,
-	0x1c, 0x2d, 0x74, 0xeb, 0x71, 0x91, 0x1e, 0x7b, 0x0e, 0x7a, 0x28, 0x7a, 0xef, 0x9f, 0x91, 0x63,
-	0x8f, 0xed, 0xc5, 0xe8, 0xea, 0x5f, 0xe8, 0xad, 0x97, 0x16, 0xe4, 0x70, 0x46, 0xa3, 0x64, 0x6c,
-	0x07, 0x68, 0x0e, 0xbd, 0x91, 0x8f, 0xdf, 0xf7, 0x48, 0x3e, 0x7e, 0x8f, 0x7c, 0x84, 0x4f, 0x1c,
-	0x57, 0x4c, 0xa2, 0x71, 0xdb, 0x62, 0xd3, 0x8e, 0xcd, 0xac, 0x33, 0xca, 0x3b, 0xe1, 0xd7, 0x84,
-	0x4f, 0xcf, 0x5c, 0xd1, 0x21, 0x81, 0xdb, 0x09, 0x03, 0x6a, 0x85, 0xed, 0x80, 0x33, 0xc1, 0x10,
-	0x8a, 0x01, 0xed, 0x04, 0xd0, 0x9e, 0xfd, 0xa0, 0x71, 0x15, 0x5f, 0xcc, 0x03, 0xaa, 0xf9, 0x8d,
-	0x9b, 0x0e, 0x73, 0x98, 0x6a, 0x76, 0x64, 0x4b, 0x5b, 0xb7, 0x1d, 0xc6, 0x1c, 0x8f, 0x76, 0x54,
-	0x6f, 0x1c, 0x9d, 0x76, 0xec, 0x88, 0x13, 0xe1, 0x32, 0x5f, 0x8f, 0xdf, 0x7e, 0x7d, 0x9c, 0xf8,
-	0xf3, 0x78, 0xa8, 0xf5, 0xb2, 0x08, 0x95, 0x23, 0x66, 0xd3, 0xe3, 0x80, 0x5a, 0xe8, 0x00, 0x0c,
-	0xe2, 0xfb, 0x4c, 0x28, 0x6e, 0x68, 0x16, 0x9a, 0x85, 0x5d, 0x63, 0x6f, 0xa7, 0xfd, 0xe6, 0x9a,
-	0xdb, 0xdd, 0x25, 0xac, 0x57, 0x7c, 0x75, 0xbe, 0xb3, 0x86, 0xb3, 0x4c, 0xf4, 0x33, 0xa8, 0xd9,
-	0x34, 0x74, 0x39, 0xb5, 0x47, 0x9c, 0x79, 0xd4, 0x5c, 0x6f, 0x16, 0x76, 0xaf, 0xed, 0x7d, 0x37,
-	0xcf, 0x93, 0x9c, 0x1c, 0x33, 0x8f, 0x62, 0x43, 0x33, 0x64, 0x07, 0x1d, 0x00, 0x4c, 0xe9, 0x74,
-	0x4c, 0x79, 0x38, 0x71, 0x03, 0x73, 0x43, 0xd1, 0xbf, 0x77, 0x11, 0x5d, 0xae, 0xbd, 0xfd, 0x24,
-	0x85, 0xe3, 0x0c, 0x15, 0x3d, 0x81, 0x1a, 0x99, 0x11, 0xd7, 0x23, 0x63, 0xd7, 0x73, 0xc5, 0xdc,
-	0x2c, 0x2a, 0x57, 0x1f, 0x5f, 0xea, 0xaa, 0x9b, 0x21, 0xe0, 0x15, 0x7a, 0xcb, 0x06, 0x58, 0x4e,
-	0x84, 0xee, 0x43, 0x79, 0x38, 0x38, 0xea, 0x1f, 0x1e, 0x1d, 0xd4, 0xd7, 0x1a, 0xb7, 0x5f, 0xbc,
-	0x6c, 0xbe, 0x2f, 0x7d, 0x2c, 0x01, 0x43, 0xea, 0xdb, 0xae, 0xef, 0xa0, 0x5d, 0xa8, 0x74, 0xf7,
-	0xf7, 0x07, 0xc3, 0x93, 0x41, 0xbf, 0x5e, 0x68, 0x34, 0x5e, 0xbc, 0x6c, 0xde, 0x5a, 0x05, 0x76,
-	0x2d, 0x8b, 0x06, 0x82, 0xda, 0x8d, 0xe2, 0x37, 0x7f, 0xde, 0x5e, 0x6b, 0x7d, 0x53, 0x80, 0x5a,
-	0x76, 0x11, 0xe8, 0x3e, 0x94, 0xba, 0xfb, 0x27, 0x87, 0xcf, 0x06, 0xf5, 0xb5, 0x25, 0x3d, 0x8b,
-	0xe8, 0x5a, 0xc2, 0x9d, 0x51, 0x74, 0x0f, 0x36, 0x87, 0xdd, 0xaf, 0x8e, 0x07, 0xf5, 0xc2, 0x72,
-	0x39, 0x59, 0xd8, 0x90, 0x44, 0xa1, 0x42, 0xf5, 0x71, 0xf7, 0xf0, 0xa8, 0xbe, 0x9e, 0x8f, 0xea,
-	0x73, 0xe2, 0xfa, 0x7a, 0x29, 0x7f, 0x2a, 0x82, 0x71, 0x4c, 0xf9, 0xcc, 0xb5, 0xde, 0xb1, 0x44,
-	0x3e, 0x83, 0xa2, 0x20, 0xe1, 0x99, 0x92, 0x86, 0x91, 0x2f, 0x8d, 0x13, 0x12, 0x9e, 0xc9, 0x49,
-	0x35, 0x5d, 0xe1, 0xa5, 0x32, 0x38, 0x0d, 0x3c, 0xd7, 0x22, 0x82, 0xda, 0x4a, 0x19, 0xc6, 0xde,
-	0x47, 0x79, 0x6c, 0x9c, 0xa2, 0xf4, 0xfa, 0x1f, 0xad, 0xe1, 0x0c, 0x15, 0x3d, 0x84, 0x92, 0xe3,
-	0xb1, 0x31, 0xf1, 0x94, 0x26, 0x8c, 0xbd, 0xbb, 0x79, 0x4e, 0x0e, 0x14, 0x62, 0xe9, 0x40, 0x53,
-	0xd0, 0x03, 0x28, 0x45, 0x81, 0x4d, 0x04, 0x35, 0x4b, 0x8a, 0xdc, 0xcc, 0x23, 0x7f, 0xa5, 0x10,
-	0xfb, 0xcc, 0x3f, 0x75, 0x1d, 0xac, 0xf1, 0xe8, 0x31, 0x54, 0x7c, 0x2a, 0xbe, 0x66, 0xfc, 0x2c,
-	0x34, 0xcb, 0xcd, 0x8d, 0x5d, 0x63, 0xef, 0xd3, 0x5c, 0x31, 0xc6, 0x98, 0xae, 0x10, 0xc4, 0x9a,
-	0x4c, 0xa9, 0x2f, 0x62, 0x37, 0xbd, 0x75, 0xb3, 0x80, 0x53, 0x07, 0xe8, 0x27, 0x50, 0xa1, 0xbe,
-	0x1d, 0x30, 0xd7, 0x17, 0x66, 0xe5, 0xe2, 0x85, 0x0c, 0x34, 0x46, 0x06, 0x13, 0xa7, 0x0c, 0xc9,
-	0xe6, 0xcc, 0xf3, 0xc6, 0xc4, 0x3a, 0x33, 0xab, 0x6f, 0xb9, 0x8d, 0x94, 0xd1, 0x2b, 0x41, 0x71,
-	0xca, 0x6c, 0xda, 0xea, 0xc0, 0x8d, 0x37, 0x42, 0x8d, 0x1a, 0x50, 0xd1, 0xa1, 0x8e, 0x35, 0x52,
-	0xc4, 0x69, 0xbf, 0x75, 0x1d, 0xb6, 0x56, 0xc2, 0xda, 0xfa, 0xeb, 0x26, 0x54, 0x92, 0xb3, 0x46,
-	0x5d, 0xa8, 0x5a, 0xcc, 0x17, 0xc4, 0xf5, 0x29, 0xd7, 0xf2, 0xca, 0x3d, 0x99, 0xfd, 0x04, 0x24,
-	0x59, 0x8f, 0xd6, 0xf0, 0x92, 0x85, 0x7e, 0x01, 0x55, 0x4e, 0x43, 0x16, 0x71, 0x8b, 0x86, 0x5a,
-	0x5f, 0xbb, 0xf9, 0x0a, 0x89, 0x41, 0x98, 0xfe, 0x2e, 0x72, 0x39, 0x95, 0x51, 0x0e, 0xf1, 0x92,
-	0x8a, 0x1e, 0x42, 0x99, 0xd3, 0x50, 0x10, 0x2e, 0x2e, 0x93, 0x08, 0x8e, 0x21, 0x43, 0xe6, 0xb9,
-	0xd6, 0x1c, 0x27, 0x0c, 0xf4, 0x10, 0xaa, 0x81, 0x47, 0x2c, 0xe5, 0xd5, 0xdc, 0x54, 0xf4, 0x0f,
-	0xf2, 0xe8, 0xc3, 0x04, 0x84, 0x97, 0x78, 0xf4, 0x39, 0x80, 0xc7, 0x9c, 0x91, 0xcd, 0xdd, 0x19,
-	0xe5, 0x5a, 0x62, 0x8d, 0x3c, 0x76, 0x5f, 0x21, 0x70, 0xd5, 0x63, 0x4e, 0xdc, 0x44, 0x07, 0xff,
-	0x93, 0xbe, 0x32, 0xda, 0x7a, 0x0c, 0x40, 0xd2, 0x51, 0xad, 0xae, 0x8f, 0xdf, 0xca, 0x95, 0x3e,
-	0x91, 0x0c, 0x1d, 0xdd, 0x85, 0xda, 0x29, 0xe3, 0x16, 0x1d, 0xe9, 0xac, 0xa9, 0x2a, 0x4d, 0x18,
-	0xca, 0x16, 0xeb, 0x0b, 0xf5, 0xa0, 0xec, 0x50, 0x9f, 0x72, 0xd7, 0x32, 0x41, 0x4d, 0x76, 0x3f,
-	0x37, 0x21, 0x63, 0x08, 0x8e, 0x7c, 0xe1, 0x4e, 0xa9, 0x9e, 0x29, 0x21, 0xa2, 0xdf, 0xc2, 0x7b,
-	0xc9, 0xf1, 0x8d, 0x38, 0x3d, 0xa5, 0x9c, 0xfa, 0x52, 0x03, 0x86, 0x8a, 0xc3, 0x47, 0x97, 0x6b,
-	0x40, 0xa3, 0xf5, 0x65, 0x83, 0xf8, 0xeb, 0x03, 0x61, 0xaf, 0x0a, 0x65, 0x1e, 0xcf, 0xdb, 0xfa,
-	0x43, 0x41, 0xaa, 0xfe, 0x35, 0x04, 0xea, 0x80, 0x91, 0x4e, 0xef, 0xda, 0x4a, 0xbd, 0xd5, 0xde,
-	0xb5, 0xc5, 0xf9, 0x0e, 0x24, 0xd8, 0xc3, 0xbe, 0xbc, 0x83, 0x74, 0xdb, 0x46, 0x03, 0xd8, 0x4a,
-	0x09, 0xf2, 0x99, 0xd7, 0x0f, 0x65, 0xf3, 0xb2, 0x95, 0x9e, 0xcc, 0x03, 0x8a, 0x6b, 0x3c, 0xd3,
-	0x6b, 0xfd, 0x06, 0xd0, 0x9b, 0x71, 0x41, 0x08, 0x8a, 0x67, 0xae, 0xaf, 0x97, 0x81, 0x55, 0x1b,
-	0xb5, 0xa1, 0x1c, 0x90, 0xb9, 0xc7, 0x88, 0xad, 0x13, 0xe3, 0x66, 0x3b, 0xae, 0x0d, 0xda, 0x49,
-	0x6d, 0xd0, 0xee, 0xfa, 0x73, 0x9c, 0x80, 0x5a, 0x8f, 0xe1, 0xfd, 0xdc, 0xe3, 0x45, 0x7b, 0x50,
-	0x4b, 0x13, 0x6e, 0xb9, 0xd7, 0xeb, 0x8b, 0xf3, 0x1d, 0x23, 0xcd, 0xcc, 0xc3, 0x3e, 0x36, 0x52,
-	0xd0, 0xa1, 0xdd, 0xfa, 0x63, 0x15, 0xb6, 0x56, 0xd2, 0x16, 0xdd, 0x84, 0x4d, 0x77, 0x4a, 0x1c,
-	0xaa, 0xd7, 0x18, 0x77, 0xd0, 0x00, 0x4a, 0x1e, 0x19, 0x53, 0x4f, 0x26, 0xaf, 0x3c, 0xb8, 0xef,
-	0x5f, 0x99, 0xff, 0xed, 0x5f, 0x29, 0xfc, 0xc0, 0x17, 0x7c, 0x8e, 0x35, 0x19, 0x99, 0x50, 0xb6,
-	0xd8, 0x74, 0x4a, 0x7c, 0xf9, 0x4c, 0x6c, 0xec, 0x56, 0x71, 0xd2, 0x95, 0x91, 0x21, 0xdc, 0x09,
-	0xcd, 0xa2, 0x32, 0xab, 0x36, 0xaa, 0xc3, 0x06, 0xf5, 0x67, 0xe6, 0xa6, 0x32, 0xc9, 0xa6, 0xb4,
-	0xd8, 0x6e, 0x9c, 0x7d, 0x55, 0x2c, 0x9b, 0x92, 0x17, 0x85, 0x94, 0x9b, 0xe5, 0x38, 0xa2, 0xb2,
-	0x8d, 0x7e, 0x0c, 0xa5, 0x29, 0x8b, 0x7c, 0x11, 0x9a, 0x15, 0xb5, 0xd8, 0xdb, 0x79, 0x8b, 0x7d,
-	0x22, 0x11, 0x5a, 0x59, 0x1a, 0x8e, 0x06, 0x70, 0x23, 0x14, 0x2c, 0x18, 0x39, 0x9c, 0x58, 0x74,
-	0x14, 0x50, 0xee, 0x32, 0x5b, 0x5f, 0xc3, 0xb7, 0xdf, 0x38, 0x94, 0xbe, 0x2e, 0xe8, 0xf0, 0x75,
-	0xc9, 0x39, 0x90, 0x94, 0xa1, 0x62, 0xa0, 0x21, 0xd4, 0x82, 0xc8, 0xf3, 0x46, 0x2c, 0x88, 0x5f,
-	0xe4, 0x38, 0x77, 0xde, 0x22, 0x64, 0xc3, 0xc8, 0xf3, 0x9e, 0xc6, 0x24, 0x6c, 0x04, 0xcb, 0x0e,
-	0xba, 0x05, 0x25, 0x87, 0xb3, 0x28, 0x88, 0xf3, 0xa6, 0x8a, 0x75, 0x0f, 0x7d, 0x09, 0xe5, 0x90,
-	0x5a, 0x9c, 0x8a, 0xd0, 0xac, 0xa9, 0xad, 0x7e, 0x98, 0x37, 0xc9, 0xb1, 0x82, 0xa4, 0x39, 0x81,
-	0x13, 0x0e, 0xba, 0x0d, 0x1b, 0x42, 0xcc, 0xcd, 0xad, 0x66, 0x61, 0xb7, 0xd2, 0x2b, 0x2f, 0xce,
-	0x77, 0x36, 0x4e, 0x4e, 0x9e, 0x63, 0x69, 0x93, 0xaf, 0xc5, 0x84, 0x85, 0xc2, 0x27, 0x53, 0x6a,
-	0x5e, 0x53, 0xb1, 0x4d, 0xfb, 0xe8, 0x39, 0x80, 0xed, 0x87, 0x23, 0x4b, 0x5d, 0x4f, 0xe6, 0x75,
-	0xb5, 0xbb, 0x4f, 0xaf, 0xde, 0x5d, 0xff, 0xe8, 0x58, 0xbf, 0x98, 0x5b, 0x8b, 0xf3, 0x9d, 0x6a,
-	0xda, 0xc5, 0x55, 0xdb, 0x0f, 0xe3, 0x26, 0xea, 0x81, 0x31, 0xa1, 0xc4, 0x13, 0x13, 0x6b, 0x42,
-	0xad, 0x33, 0xb3, 0x7e, 0xf1, 0x13, 0xf8, 0x48, 0xc1, 0xb4, 0x87, 0x2c, 0x49, 0x2a, 0x58, 0x2e,
-	0x35, 0x34, 0x6f, 0xa8, 0x58, 0xc5, 0x1d, 0xf4, 0x01, 0x00, 0x0b, 0xa8, 0x3f, 0x0a, 0x85, 0xed,
-	0xfa, 0x26, 0x92, 0x5b, 0xc6, 0x55, 0x69, 0x39, 0x96, 0x06, 0x74, 0x47, 0x3e, 0x50, 0xc4, 0x1e,
-	0x31, 0xdf, 0x9b, 0x9b, 0xef, 0xa9, 0xd1, 0x8a, 0x34, 0x3c, 0xf5, 0xbd, 0x39, 0xda, 0x01, 0x43,
-	0xe9, 0x22, 0x74, 0x1d, 0x9f, 0x78, 0xe6, 0x4d, 0x15, 0x0f, 0x90, 0xa6, 0x63, 0x65, 0x91, 0xe7,
-	0x10, 0x47, 0x23, 0x34, 0xdf, 0xbf, 0xf8, 0x1c, 0xf4, 0x62, 0x97, 0xe7, 0xa0, 0x39, 0xe8, 0xa7,
-	0x00, 0x01, 0x77, 0x67, 0xae, 0x47, 0x1d, 0x1a, 0x9a, 0xb7, 0xd4, 0xa6, 0xb7, 0x73, 0x5f, 0xa6,
-	0x14, 0x85, 0x33, 0x8c, 0xc6, 0xe7, 0x60, 0x64, 0xb2, 0x4d, 0x66, 0xc9, 0x19, 0x9d, 0xeb, 0x04,
-	0x96, 0x4d, 0x19, 0x92, 0x19, 0xf1, 0xa2, 0xf8, 0x32, 0xab, 0xe2, 0xb8, 0xf3, 0xc5, 0xfa, 0x83,
-	0x42, 0x63, 0x0f, 0x8c, 0x8c, 0xea, 0xd0, 0x87, 0xf2, 0xf6, 0x73, 0xdc, 0x50, 0xf0, 0xf9, 0x88,
-	0x44, 0x62, 0x62, 0xfe, 0x5c, 0x11, 0x6a, 0x89, 0xb1, 0x1b, 0x89, 0x49, 0x63, 0x04, 0xcb, 0xc3,
-	0x43, 0x4d, 0x30, 0xa4, 0x28, 0x42, 0xca, 0x67, 0x94, 0xcb, 0xca, 0x42, 0xc6, 0x3c, 0x6b, 0x92,
-	0xe2, 0x0d, 0x29, 0xe1, 0xd6, 0x44, 0xdd, 0x1d, 0x55, 0xac, 0x7b, 0xf2, 0x32, 0x48, 0x32, 0x44,
-	0x5f, 0x06, 0xba, 0xdb, 0xfa, 0x57, 0x01, 0x6a, 0xd9, 0x02, 0x09, 0xed, 0xc7, 0x85, 0x8d, 0xda,
-	0xd2, 0xb5, 0xbd, 0xce, 0x55, 0x05, 0x95, 0xba, 0x98, 0xbd, 0x48, 0x3a, 0x7b, 0x22, 0xff, 0x32,
-	0x8a, 0x8c, 0x7e, 0x04, 0x9b, 0x01, 0xe3, 0x22, 0xb9, 0xc2, 0xf2, 0x03, 0xcc, 0x78, 0xf2, 0xec,
-	0xc6, 0xe0, 0xd6, 0x04, 0xae, 0xad, 0x7a, 0x43, 0xf7, 0x60, 0xe3, 0xd9, 0xe1, 0xb0, 0xbe, 0xd6,
-	0xb8, 0xf3, 0xe2, 0x65, 0xf3, 0x3b, 0xab, 0x83, 0xcf, 0x5c, 0x2e, 0x22, 0xe2, 0x1d, 0x0e, 0xd1,
-	0x27, 0xb0, 0xd9, 0x3f, 0x3a, 0xc6, 0xb8, 0x5e, 0x68, 0xec, 0xbc, 0x78, 0xd9, 0xbc, 0xb3, 0x8a,
-	0x93, 0x43, 0x2c, 0xf2, 0x6d, 0xcc, 0xc6, 0x69, 0x5d, 0xff, 0xef, 0x75, 0x30, 0xf4, 0xcd, 0xfe,
-	0xae, 0xbf, 0x7e, 0x5b, 0x71, 0xd9, 0x92, 0xa4, 0xec, 0xfa, 0x95, 0xd5, 0x4b, 0x2d, 0x26, 0xe8,
-	0x33, 0xbe, 0x0b, 0x35, 0x37, 0x98, 0x7d, 0x36, 0xa2, 0x3e, 0x19, 0x7b, 0xba, 0xc4, 0xaf, 0x60,
-	0x43, 0xda, 0x06, 0xb1, 0x49, 0xde, 0x17, 0xae, 0x2f, 0x28, 0xf7, 0x75, 0xf1, 0x5e, 0xc1, 0x69,
-	0x1f, 0x7d, 0x09, 0x45, 0x37, 0x20, 0x53, 0x5d, 0x72, 0xe5, 0xee, 0xe0, 0x70, 0xd8, 0x7d, 0xa2,
-	0x35, 0xd8, 0xab, 0x2c, 0xce, 0x77, 0x8a, 0xd2, 0x80, 0x15, 0x0d, 0x6d, 0x27, 0x55, 0x8f, 0x9c,
-	0x49, 0xdd, 0xfd, 0x15, 0x9c, 0xb1, 0x48, 0x1d, 0xb9, 0xbe, 0xc3, 0x69, 0x18, 0xaa, 0x57, 0xa0,
-	0x82, 0x93, 0x2e, 0x6a, 0x40, 0x59, 0xd7, 0x4e, 0xaa, 0x58, 0xaa, 0xca, 0xba, 0x44, 0x1b, 0x7a,
-	0x5b, 0x60, 0xc4, 0xd1, 0x18, 0x9d, 0x72, 0x36, 0x6d, 0xfd, 0xa7, 0x08, 0xc6, 0xbe, 0x17, 0x85,
-	0x42, 0x3f, 0x83, 0xef, 0x2c, 0xf8, 0xcf, 0xe1, 0x06, 0x51, 0x5f, 0x49, 0xe2, 0xcb, 0x37, 0x45,
-	0x95, 0xa4, 0xfa, 0x00, 0xee, 0xe5, 0xba, 0x4b, 0xc1, 0x71, 0xf9, 0xda, 0x2b, 0x49, 0x9f, 0x66,
-	0x01, 0xd7, 0xc9, 0x6b, 0x23, 0xe8, 0x18, 0xb6, 0x18, 0xb7, 0x26, 0x34, 0x14, 0xf1, 0x4b, 0xa4,
-	0xbf, 0x5e, 0xb9, 0x9f, 0xf2, 0xa7, 0x59, 0xa0, 0xbe, 0x86, 0xe3, 0xd5, 0xae, 0xfa, 0x40, 0x0f,
-	0xa0, 0xc8, 0xc9, 0x69, 0x52, 0x5e, 0xe7, 0x26, 0x09, 0x26, 0xa7, 0x62, 0xc5, 0x85, 0x62, 0xa0,
-	0x5f, 0x02, 0xd8, 0x6e, 0x18, 0x10, 0x61, 0x4d, 0x28, 0xd7, 0x87, 0x9d, 0xbb, 0xc5, 0x7e, 0x8a,
-	0x5a, 0xf1, 0x92, 0x61, 0xa3, 0xc7, 0x50, 0xb5, 0x48, 0x22, 0xd7, 0xd2, 0xc5, 0xff, 0xd1, 0xfd,
-	0xae, 0x76, 0x51, 0x97, 0x2e, 0x16, 0xe7, 0x3b, 0x95, 0xc4, 0x82, 0x2b, 0x16, 0xd1, 0xf2, 0x7d,
-	0x0c, 0x5b, 0xf2, 0x9f, 0x3a, 0xb2, 0xe9, 0x29, 0x89, 0x3c, 0x11, 0xcb, 0xe4, 0x82, 0x67, 0x45,
-	0x7e, 0x7a, 0xfa, 0x1a, 0xa7, 0xd7, 0x55, 0x13, 0x19, 0x1b, 0xfa, 0x35, 0xdc, 0xa0, 0xbe, 0xc5,
-	0xe7, 0x4a, 0xac, 0xc9, 0x0a, 0x2b, 0x17, 0x6f, 0x76, 0x90, 0x82, 0x57, 0x36, 0x5b, 0xa7, 0xaf,
-	0xd9, 0x5b, 0xff, 0x28, 0x00, 0xc4, 0x2f, 0xf5, 0xbb, 0x15, 0x20, 0x82, 0xa2, 0x4d, 0x04, 0x51,
-	0x9a, 0xab, 0x61, 0xd5, 0x46, 0x5f, 0x00, 0x08, 0x3a, 0x0d, 0x3c, 0x22, 0x5c, 0xdf, 0xd1, 0xb2,
-	0xb9, 0xec, 0x3a, 0xc8, 0xa0, 0xd1, 0x1e, 0x94, 0xf4, 0x27, 0xa8, 0x78, 0x25, 0x4f, 0x23, 0x5b,
-	0x7f, 0x29, 0x00, 0xc4, 0xdb, 0xfc, 0xbf, 0xde, 0x5b, 0xcf, 0x7c, 0xf5, 0xed, 0xf6, 0xda, 0xdf,
-	0xbf, 0xdd, 0x5e, 0xfb, 0xfd, 0x62, 0xbb, 0xf0, 0x6a, 0xb1, 0x5d, 0xf8, 0xdb, 0x62, 0xbb, 0xf0,
-	0xcf, 0xc5, 0x76, 0x61, 0x5c, 0x52, 0x75, 0xdf, 0x0f, 0xff, 0x1b, 0x00, 0x00, 0xff, 0xff, 0xae,
-	0x88, 0xf9, 0x3c, 0x5a, 0x14, 0x00, 0x00,
+	// 2114 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x58, 0x4f, 0x6f, 0xdb, 0xc8,
+	0x15, 0xb7, 0x6c, 0x59, 0x96, 0x1e, 0xe5, 0x44, 0x9e, 0x4d, 0xb2, 0xb4, 0xb2, 0xb1, 0x15, 0x6d,
+	0x36, 0xf5, 0xee, 0xa2, 0x32, 0xea, 0x2e, 0xb6, 0xd9, 0x4d, 0xb7, 0xad, 0x64, 0x69, 0x1d, 0x35,
+	0x89, 0x2d, 0x8c, 0x1c, 0xb7, 0x01, 0x0a, 0x08, 0x63, 0x72, 0x2c, 0x11, 0xa6, 0x38, 0xec, 0x70,
+	0xe8, 0x40, 0xb7, 0x1e, 0x17, 0xee, 0x67, 0x30, 0x7a, 0x28, 0x7a, 0x6f, 0xbf, 0x42, 0x4f, 0x39,
+	0xf6, 0xd8, 0x5e, 0x8c, 0xae, 0xbf, 0x42, 0x6f, 0xbd, 0xb4, 0x98, 0xe1, 0x90, 0xa2, 0x1c, 0x3a,
+	0x0e, 0xd0, 0x1c, 0x7a, 0x9b, 0x79, 0xfc, 0xfd, 0xde, 0xfc, 0xfb, 0xbd, 0x37, 0x6f, 0x08, 0x9f,
+	0x0d, 0x1d, 0x31, 0x0a, 0x0f, 0x1b, 0x16, 0x1b, 0x6f, 0xda, 0xcc, 0x3a, 0xa6, 0x7c, 0x33, 0x78,
+	0x45, 0xf8, 0xf8, 0xd8, 0x11, 0x9b, 0xc4, 0x77, 0x36, 0x03, 0x9f, 0x5a, 0x41, 0xc3, 0xe7, 0x4c,
+	0x30, 0x84, 0x22, 0x40, 0x23, 0x06, 0x34, 0x4e, 0x7e, 0x54, 0xbd, 0x8e, 0x2f, 0x26, 0x3e, 0xd5,
+	0xfc, 0xea, 0xad, 0x21, 0x1b, 0x32, 0xd5, 0xdc, 0x94, 0x2d, 0x6d, 0x5d, 0x1b, 0x32, 0x36, 0x74,
+	0xe9, 0xa6, 0xea, 0x1d, 0x86, 0x47, 0x9b, 0x76, 0xc8, 0x89, 0x70, 0x98, 0xa7, 0xbf, 0xaf, 0x5e,
+	0xfe, 0x4e, 0xbc, 0xc9, 0x55, 0xd4, 0x57, 0x9c, 0xf8, 0x3e, 0xe5, 0x7a, 0xc0, 0xfa, 0x59, 0x1e,
+	0x8a, 0xbb, 0xcc, 0xa6, 0x7d, 0x9f, 0x5a, 0x68, 0x07, 0x0c, 0xe2, 0x79, 0x4c, 0x28, 0xdf, 0x81,
+	0x99, 0xab, 0xe5, 0x36, 0x8c, 0xad, 0xf5, 0xc6, 0x9b, 0x6b, 0x6a, 0x34, 0xa7, 0xb0, 0x56, 0xfe,
+	0xf5, 0xf9, 0xfa, 0x1c, 0x4e, 0x33, 0xd1, 0xcf, 0xa1, 0x6c, 0xd3, 0xc0, 0xe1, 0xd4, 0x1e, 0x70,
+	0xe6, 0x52, 0x73, 0xbe, 0x96, 0xdb, 0xb8, 0xb1, 0xf5, 0x51, 0x96, 0x27, 0x39, 0x38, 0x66, 0x2e,
+	0xc5, 0x86, 0x66, 0xc8, 0x0e, 0xda, 0x01, 0x18, 0xd3, 0xf1, 0x21, 0xe5, 0xc1, 0xc8, 0xf1, 0xcd,
+	0x05, 0x45, 0xff, 0xc1, 0x55, 0x74, 0x39, 0xf7, 0xc6, 0xf3, 0x04, 0x8e, 0x53, 0x54, 0xf4, 0x1c,
+	0xca, 0xe4, 0x84, 0x38, 0x2e, 0x39, 0x74, 0x5c, 0x47, 0x4c, 0xcc, 0xbc, 0x72, 0xf5, 0xe9, 0x5b,
+	0x5d, 0x35, 0x53, 0x04, 0x3c, 0x43, 0xaf, 0xdb, 0x00, 0xd3, 0x81, 0xd0, 0x43, 0x58, 0xea, 0x75,
+	0x76, 0xdb, 0xdd, 0xdd, 0x9d, 0xca, 0x5c, 0x75, 0xf5, 0xf4, 0xac, 0x76, 0x5b, 0xfa, 0x98, 0x02,
+	0x7a, 0xd4, 0xb3, 0x1d, 0x6f, 0x88, 0x36, 0xa0, 0xd8, 0xdc, 0xde, 0xee, 0xf4, 0xf6, 0x3b, 0xed,
+	0x4a, 0xae, 0x5a, 0x3d, 0x3d, 0xab, 0xdd, 0x99, 0x05, 0x36, 0x2d, 0x8b, 0xfa, 0x82, 0xda, 0xd5,
+	0xfc, 0x77, 0x7f, 0x5c, 0x9b, 0xab, 0x7f, 0x97, 0x83, 0x72, 0x7a, 0x12, 0xe8, 0x21, 0x14, 0x9a,
+	0xdb, 0xfb, 0xdd, 0x83, 0x4e, 0x65, 0x6e, 0x4a, 0x4f, 0x23, 0x9a, 0x96, 0x70, 0x4e, 0x28, 0x7a,
+	0x00, 0x8b, 0xbd, 0xe6, 0x8b, 0x7e, 0xa7, 0x92, 0x9b, 0x4e, 0x27, 0x0d, 0xeb, 0x91, 0x30, 0x50,
+	0xa8, 0x36, 0x6e, 0x76, 0x77, 0x2b, 0xf3, 0xd9, 0xa8, 0x36, 0x27, 0x8e, 0xa7, 0xa7, 0xf2, 0x87,
+	0x3c, 0x18, 0x7d, 0xca, 0x4f, 0x1c, 0xeb, 0x3d, 0x4b, 0xe4, 0x4b, 0xc8, 0x0b, 0x12, 0x1c, 0x2b,
+	0x69, 0x18, 0xd9, 0xd2, 0xd8, 0x27, 0xc1, 0xb1, 0x1c, 0x54, 0xd3, 0x15, 0x5e, 0x2a, 0x83, 0x53,
+	0xdf, 0x75, 0x2c, 0x22, 0xa8, 0xad, 0x94, 0x61, 0x6c, 0x7d, 0x92, 0xc5, 0xc6, 0x09, 0x4a, 0xcf,
+	0xff, 0xc9, 0x1c, 0x4e, 0x51, 0xd1, 0x63, 0x28, 0x0c, 0x5d, 0x76, 0x48, 0x5c, 0xa5, 0x09, 0x63,
+	0xeb, 0x7e, 0x96, 0x93, 0x1d, 0x85, 0x98, 0x3a, 0xd0, 0x14, 0xf4, 0x08, 0x0a, 0xa1, 0x6f, 0x13,
+	0x41, 0xcd, 0x82, 0x22, 0xd7, 0xb2, 0xc8, 0x2f, 0x14, 0x62, 0x9b, 0x79, 0x47, 0xce, 0x10, 0x6b,
+	0x3c, 0x7a, 0x0a, 0x45, 0x8f, 0x8a, 0x57, 0x8c, 0x1f, 0x07, 0xe6, 0x52, 0x6d, 0x61, 0xc3, 0xd8,
+	0xfa, 0x3c, 0x53, 0x8c, 0x11, 0xa6, 0x29, 0x04, 0xb1, 0x46, 0x63, 0xea, 0x89, 0xc8, 0x4d, 0x6b,
+	0xde, 0xcc, 0xe1, 0xc4, 0x01, 0xfa, 0x29, 0x14, 0xa9, 0x67, 0xfb, 0xcc, 0xf1, 0x84, 0x59, 0xbc,
+	0x7a, 0x22, 0x1d, 0x8d, 0x91, 0x9b, 0x89, 0x13, 0x86, 0x64, 0x73, 0xe6, 0xba, 0x87, 0xc4, 0x3a,
+	0x36, 0x4b, 0xef, 0xb8, 0x8c, 0x84, 0xd1, 0x2a, 0x40, 0x7e, 0xcc, 0x6c, 0x5a, 0xdf, 0x84, 0x95,
+	0x37, 0xb6, 0x1a, 0x55, 0xa1, 0xa8, 0xb7, 0x3a, 0xd2, 0x48, 0x1e, 0x27, 0xfd, 0xfa, 0x4d, 0x58,
+	0x9e, 0xd9, 0xd6, 0xfa, 0x9f, 0x17, 0xa1, 0x18, 0x9f, 0x35, 0x6a, 0x42, 0xc9, 0x62, 0x9e, 0x20,
+	0x8e, 0x47, 0xb9, 0x96, 0x57, 0xe6, 0xc9, 0x6c, 0xc7, 0x20, 0xc9, 0x7a, 0x32, 0x87, 0xa7, 0x2c,
+	0xf4, 0x2d, 0x94, 0x38, 0x0d, 0x58, 0xc8, 0x2d, 0x1a, 0x68, 0x7d, 0x6d, 0x64, 0x2b, 0x24, 0x02,
+	0x61, 0xfa, 0xdb, 0xd0, 0xe1, 0x54, 0xee, 0x72, 0x80, 0xa7, 0x54, 0xf4, 0x18, 0x96, 0x38, 0x0d,
+	0x04, 0xe1, 0xe2, 0x6d, 0x12, 0xc1, 0x11, 0xa4, 0xc7, 0x5c, 0xc7, 0x9a, 0xe0, 0x98, 0x81, 0x1e,
+	0x43, 0xc9, 0x77, 0x89, 0xa5, 0xbc, 0x9a, 0x8b, 0x8a, 0x7e, 0x2f, 0x8b, 0xde, 0x8b, 0x41, 0x78,
+	0x8a, 0x47, 0x5f, 0x01, 0xb8, 0x6c, 0x38, 0xb0, 0xb9, 0x73, 0x42, 0xb9, 0x96, 0x58, 0x35, 0x8b,
+	0xdd, 0x56, 0x08, 0x5c, 0x72, 0xd9, 0x30, 0x6a, 0xa2, 0x9d, 0xff, 0x49, 0x5f, 0x29, 0x6d, 0x3d,
+	0x05, 0x20, 0xc9, 0x57, 0xad, 0xae, 0x4f, 0xdf, 0xc9, 0x95, 0x3e, 0x91, 0x14, 0x1d, 0xdd, 0x87,
+	0xf2, 0x11, 0xe3, 0x16, 0x1d, 0xe8, 0xa8, 0x29, 0x29, 0x4d, 0x18, 0xca, 0x16, 0xe9, 0x0b, 0xb5,
+	0x60, 0x69, 0x48, 0x3d, 0xca, 0x1d, 0xcb, 0x04, 0x35, 0xd8, 0xc3, 0xcc, 0x80, 0x8c, 0x20, 0x38,
+	0xf4, 0x84, 0x33, 0xa6, 0x7a, 0xa4, 0x98, 0x88, 0x7e, 0x03, 0x1f, 0xc4, 0xc7, 0x37, 0xe0, 0xf4,
+	0x88, 0x72, 0xea, 0x49, 0x0d, 0x18, 0x6a, 0x1f, 0x3e, 0x79, 0xbb, 0x06, 0x34, 0x5a, 0x27, 0x1b,
+	0xc4, 0x2f, 0x7f, 0x08, 0x5a, 0x25, 0x58, 0xe2, 0xd1, 0xb8, 0xf5, 0xdf, 0xe7, 0xa4, 0xea, 0x2f,
+	0x21, 0xd0, 0x26, 0x18, 0xc9, 0xf0, 0x8e, 0xad, 0xd4, 0x5b, 0x6a, 0xdd, 0xb8, 0x38, 0x5f, 0x87,
+	0x18, 0xdb, 0x6d, 0xcb, 0x1c, 0xa4, 0xdb, 0x36, 0xea, 0xc0, 0x72, 0x42, 0x90, 0x65, 0x80, 0xbe,
+	0x28, 0x6b, 0x6f, 0x9b, 0xe9, 0xfe, 0xc4, 0xa7, 0xb8, 0xcc, 0x53, 0xbd, 0xfa, 0xaf, 0x01, 0xbd,
+	0xb9, 0x2f, 0x08, 0x41, 0xfe, 0xd8, 0xf1, 0xf4, 0x34, 0xb0, 0x6a, 0xa3, 0x06, 0x2c, 0xf9, 0x64,
+	0xe2, 0x32, 0x62, 0xeb, 0xc0, 0xb8, 0xd5, 0x88, 0x0a, 0x84, 0x46, 0x5c, 0x20, 0x34, 0x9a, 0xde,
+	0x04, 0xc7, 0xa0, 0xfa, 0x53, 0xb8, 0x9d, 0x79, 0xbc, 0x68, 0x0b, 0xca, 0x49, 0xc0, 0x4d, 0xd7,
+	0x7a, 0xf3, 0xe2, 0x7c, 0xdd, 0x48, 0x22, 0xb3, 0xdb, 0xc6, 0x46, 0x02, 0xea, 0xda, 0xf5, 0xbf,
+	0x1a, 0xb0, 0x3c, 0x13, 0xb6, 0xe8, 0x16, 0x2c, 0x3a, 0x63, 0x32, 0xa4, 0x7a, 0x8e, 0x51, 0x07,
+	0x75, 0xa0, 0xe0, 0x92, 0x43, 0xea, 0xca, 0xe0, 0x95, 0x07, 0xf7, 0xc3, 0x6b, 0xe3, 0xbf, 0xf1,
+	0x4c, 0xe1, 0x3b, 0x9e, 0xe0, 0x13, 0xac, 0xc9, 0xc8, 0x84, 0x25, 0x8b, 0x8d, 0xc7, 0xc4, 0x93,
+	0xd7, 0xc4, 0xc2, 0x46, 0x09, 0xc7, 0x5d, 0xb9, 0x33, 0x84, 0x0f, 0x03, 0x33, 0xaf, 0xcc, 0xaa,
+	0x8d, 0x2a, 0xb0, 0x40, 0xbd, 0x13, 0x73, 0x51, 0x99, 0x64, 0x53, 0x5a, 0x6c, 0x27, 0x8a, 0xbe,
+	0x12, 0x96, 0x4d, 0xc9, 0x0b, 0x03, 0xca, 0xcd, 0xa5, 0x68, 0x47, 0x65, 0x1b, 0xfd, 0x04, 0x0a,
+	0x63, 0x16, 0x7a, 0x22, 0x30, 0x8b, 0x6a, 0xb2, 0xab, 0x59, 0x93, 0x7d, 0x2e, 0x11, 0x5a, 0x59,
+	0x1a, 0x8e, 0x3a, 0xb0, 0x12, 0x08, 0xe6, 0x0f, 0x86, 0x9c, 0x58, 0x74, 0xe0, 0x53, 0xee, 0x30,
+	0x5b, 0xa7, 0xe1, 0xd5, 0x37, 0x0e, 0xa5, 0xad, 0x0b, 0x3e, 0x7c, 0x53, 0x72, 0x76, 0x24, 0xa5,
+	0xa7, 0x18, 0xa8, 0x07, 0x65, 0x3f, 0x74, 0xdd, 0x01, 0xf3, 0xa3, 0x1b, 0x39, 0x8a, 0x9d, 0x77,
+	0xd8, 0xb2, 0x5e, 0xe8, 0xba, 0x7b, 0x11, 0x09, 0x1b, 0xfe, 0xb4, 0x83, 0xee, 0x40, 0x61, 0xc8,
+	0x59, 0xe8, 0x47, 0x71, 0x53, 0xc2, 0xba, 0x87, 0xbe, 0x81, 0xa5, 0x80, 0x5a, 0x9c, 0x8a, 0xc0,
+	0x2c, 0xab, 0xa5, 0x7e, 0x9c, 0x35, 0x48, 0x5f, 0x41, 0x92, 0x98, 0xc0, 0x31, 0x07, 0xad, 0xc2,
+	0x82, 0x10, 0x13, 0x73, 0xb9, 0x96, 0xdb, 0x28, 0xb6, 0x96, 0x2e, 0xce, 0xd7, 0x17, 0xf6, 0xf7,
+	0x5f, 0x62, 0x69, 0x93, 0xb7, 0xc5, 0x88, 0x05, 0xc2, 0x23, 0x63, 0x6a, 0xde, 0x50, 0x7b, 0x9b,
+	0xf4, 0xd1, 0x4b, 0x00, 0xdb, 0x0b, 0x06, 0x96, 0x4a, 0x4f, 0xe6, 0x4d, 0xb5, 0xba, 0xcf, 0xaf,
+	0x5f, 0x5d, 0x7b, 0xb7, 0xaf, 0x6f, 0xcc, 0xe5, 0x8b, 0xf3, 0xf5, 0x52, 0xd2, 0xc5, 0x25, 0xdb,
+	0x0b, 0xa2, 0x26, 0x6a, 0x81, 0x31, 0xa2, 0xc4, 0x15, 0x23, 0x6b, 0x44, 0xad, 0x63, 0xb3, 0x72,
+	0xf5, 0x15, 0xf8, 0x44, 0xc1, 0xb4, 0x87, 0x34, 0x49, 0x2a, 0x58, 0x4e, 0x35, 0x30, 0x57, 0xd4,
+	0x5e, 0x45, 0x1d, 0x74, 0x0f, 0x80, 0xf9, 0xd4, 0x1b, 0x04, 0xc2, 0x76, 0x3c, 0x13, 0xc9, 0x25,
+	0xe3, 0x92, 0xb4, 0xf4, 0xa5, 0x01, 0xdd, 0x95, 0x17, 0x14, 0xb1, 0x07, 0xcc, 0x73, 0x27, 0xe6,
+	0x07, 0xea, 0x6b, 0x51, 0x1a, 0xf6, 0x3c, 0x77, 0x82, 0xd6, 0xc1, 0x50, 0xba, 0x08, 0x9c, 0xa1,
+	0x47, 0x5c, 0xf3, 0x96, 0xda, 0x0f, 0x90, 0xa6, 0xbe, 0xb2, 0xc8, 0x73, 0x88, 0x76, 0x23, 0x30,
+	0x6f, 0x5f, 0x7d, 0x0e, 0x7a, 0xb2, 0xd3, 0x73, 0xd0, 0x1c, 0xf4, 0x33, 0x00, 0x9f, 0x3b, 0x27,
+	0x8e, 0x4b, 0x87, 0x34, 0x30, 0xef, 0xa8, 0x45, 0xaf, 0x65, 0xde, 0x4c, 0x09, 0x0a, 0xa7, 0x18,
+	0xa8, 0x01, 0x79, 0xc7, 0x73, 0x84, 0xf9, 0xa1, 0xbe, 0x95, 0x2e, 0x4b, 0xb5, 0xc5, 0x98, 0x7b,
+	0x40, 0xdc, 0x90, 0x62, 0x85, 0x43, 0x5d, 0x28, 0x39, 0x01, 0x73, 0x95, 0x7c, 0x4d, 0x53, 0xe5,
+	0xb7, 0x77, 0x38, 0xbf, 0x6e, 0x4c, 0xc1, 0x53, 0x76, 0xf5, 0x2b, 0x30, 0x52, 0x81, 0x2e, 0x03,
+	0xf4, 0x98, 0x4e, 0x74, 0xee, 0x90, 0x4d, 0x79, 0x1a, 0x27, 0x72, 0x68, 0x95, 0xdc, 0x4a, 0x38,
+	0xea, 0x7c, 0x3d, 0xff, 0x28, 0x57, 0xdd, 0x02, 0x23, 0x25, 0x78, 0xf4, 0xb1, 0x4c, 0xbc, 0x43,
+	0x27, 0x10, 0x7c, 0x32, 0x20, 0xa1, 0x18, 0x99, 0xbf, 0x50, 0x84, 0x72, 0x6c, 0x6c, 0x86, 0x62,
+	0x54, 0x1d, 0xc0, 0x54, 0x37, 0xa8, 0x06, 0x86, 0xd4, 0x63, 0x40, 0xf9, 0x09, 0xe5, 0xb2, 0xa8,
+	0x91, 0xc7, 0x9d, 0x36, 0xc9, 0xb8, 0x09, 0x28, 0xe1, 0xd6, 0x48, 0xa5, 0xad, 0x12, 0xd6, 0x3d,
+	0x99, 0x87, 0xe2, 0xe0, 0xd4, 0x79, 0x48, 0x77, 0xeb, 0x7f, 0xc9, 0x41, 0x29, 0x59, 0x28, 0xfa,
+	0x02, 0x56, 0xba, 0xfd, 0xbd, 0x67, 0xcd, 0xfd, 0xee, 0xde, 0xee, 0xa0, 0xdd, 0xf9, 0xb6, 0xf9,
+	0xe2, 0xd9, 0x7e, 0x65, 0xae, 0x7a, 0xef, 0xf4, 0xac, 0xb6, 0x3a, 0xcd, 0xa9, 0x31, 0xbc, 0x4d,
+	0x8f, 0x48, 0xe8, 0x8a, 0x59, 0x56, 0x0f, 0xef, 0x6d, 0x77, 0xfa, 0xfd, 0x4a, 0xee, 0x2a, 0x56,
+	0x8f, 0x33, 0x8b, 0x06, 0x01, 0xda, 0x82, 0xca, 0x94, 0xf5, 0xe4, 0x65, 0xaf, 0x83, 0x0f, 0x2a,
+	0xf3, 0xd5, 0x8f, 0x4e, 0xcf, 0x6a, 0xe6, 0x9b, 0xa4, 0x27, 0x13, 0x9f, 0xf2, 0x03, 0xfd, 0x20,
+	0xf8, 0x57, 0x0e, 0xca, 0xe9, 0x7a, 0x12, 0x6d, 0x47, 0x75, 0xa0, 0x3a, 0x86, 0x1b, 0x5b, 0x9b,
+	0xd7, 0xd5, 0x9f, 0xea, 0x1e, 0x73, 0x43, 0xe9, 0xf7, 0xb9, 0x7c, 0xfa, 0x29, 0x32, 0xfa, 0x02,
+	0x16, 0x7d, 0xc6, 0x45, 0x9c, 0xf1, 0xb3, 0xf5, 0xc8, 0x78, 0x5c, 0xa5, 0x44, 0xe0, 0xfa, 0x08,
+	0x6e, 0xcc, 0x7a, 0x43, 0x0f, 0x60, 0xe1, 0xa0, 0xdb, 0xab, 0xcc, 0x55, 0xef, 0x9e, 0x9e, 0xd5,
+	0x3e, 0x9c, 0xfd, 0x78, 0xe0, 0x70, 0x11, 0x12, 0xb7, 0xdb, 0x43, 0x9f, 0xc1, 0x62, 0x7b, 0xb7,
+	0x8f, 0x71, 0x25, 0x57, 0x5d, 0x3f, 0x3d, 0xab, 0xdd, 0x9d, 0xc5, 0xc9, 0x4f, 0x2c, 0xf4, 0x6c,
+	0xcc, 0x0e, 0x93, 0x67, 0xd0, 0xbf, 0xe7, 0xc1, 0xd0, 0x17, 0xe1, 0xfb, 0x7e, 0x29, 0x2f, 0x47,
+	0x55, 0x5e, 0x9c, 0xe1, 0xe6, 0xaf, 0x2d, 0xf6, 0xca, 0x11, 0x41, 0xeb, 0xf2, 0x3e, 0x94, 0x1d,
+	0xff, 0xe4, 0xcb, 0x01, 0xf5, 0xc8, 0xa1, 0xab, 0x5f, 0x44, 0x45, 0x6c, 0x48, 0x5b, 0x27, 0x32,
+	0xc9, 0xf4, 0xea, 0x78, 0x82, 0x72, 0x4f, 0xbf, 0x75, 0x8a, 0x38, 0xe9, 0xa3, 0x6f, 0x20, 0xef,
+	0xf8, 0x64, 0xac, 0x2b, 0xd4, 0xcc, 0x15, 0x74, 0x7b, 0xcd, 0xe7, 0x3a, 0x6e, 0x5a, 0xc5, 0x8b,
+	0xf3, 0xf5, 0xbc, 0x34, 0x60, 0x45, 0x43, 0x6b, 0x71, 0x91, 0x28, 0x47, 0x52, 0x57, 0x65, 0x11,
+	0xa7, 0x2c, 0x52, 0xfb, 0x8e, 0x37, 0xe4, 0x34, 0x08, 0xd4, 0xa5, 0x59, 0xc4, 0x71, 0x17, 0x55,
+	0x61, 0x49, 0x97, 0x9a, 0xaa, 0xb6, 0x2c, 0xc9, 0x32, 0x4e, 0x1b, 0x5a, 0xcb, 0x60, 0x44, 0xbb,
+	0x31, 0x38, 0xe2, 0x6c, 0x5c, 0xff, 0x4f, 0x1e, 0x8c, 0x6d, 0x37, 0x0c, 0x84, 0xae, 0x1a, 0xde,
+	0xdb, 0xe6, 0xbf, 0x84, 0x15, 0xa2, 0x5e, 0xde, 0xc4, 0x93, 0x57, 0xb0, 0xaa, 0xe0, 0xf5, 0x01,
+	0x3c, 0xc8, 0x74, 0x97, 0x80, 0xa3, 0x6a, 0xbf, 0x55, 0x90, 0x3e, 0xcd, 0x1c, 0xae, 0x90, 0x4b,
+	0x5f, 0x50, 0x1f, 0x96, 0x19, 0xb7, 0x46, 0x34, 0x10, 0xd1, 0xc5, 0xad, 0x5f, 0xaa, 0x99, 0xff,
+	0x30, 0xf6, 0xd2, 0x40, 0x7d, 0x6b, 0x45, 0xb3, 0x9d, 0xf5, 0x81, 0x1e, 0x41, 0x9e, 0x93, 0xa3,
+	0xf8, 0x35, 0x92, 0x19, 0x24, 0x98, 0x1c, 0x89, 0x19, 0x17, 0x8a, 0x81, 0x7e, 0x09, 0x60, 0x3b,
+	0x81, 0x4f, 0x84, 0x35, 0xa2, 0x5c, 0x1f, 0x76, 0xe6, 0x12, 0xdb, 0x09, 0x6a, 0xc6, 0x4b, 0x8a,
+	0x8d, 0x9e, 0x42, 0xc9, 0x22, 0xb1, 0x5c, 0x0b, 0x57, 0x3f, 0xdf, 0xb7, 0x9b, 0xda, 0x45, 0x45,
+	0xba, 0xb8, 0x38, 0x5f, 0x2f, 0xc6, 0x16, 0x5c, 0xb4, 0x88, 0x96, 0xef, 0x53, 0x58, 0x96, 0xcf,
+	0xfa, 0x81, 0x1d, 0xa5, 0xb3, 0x48, 0x26, 0x57, 0xdc, 0xc2, 0xf2, 0x8d, 0xa8, 0xd3, 0x5e, 0x7c,
+	0x9c, 0x65, 0x91, 0xb2, 0xa1, 0x5f, 0xc1, 0x0a, 0xf5, 0x2c, 0x3e, 0x51, 0x62, 0x8d, 0x67, 0x58,
+	0xbc, 0x7a, 0xb1, 0x9d, 0x04, 0x3c, 0xb3, 0xd8, 0x0a, 0xbd, 0x64, 0xaf, 0xff, 0x23, 0x07, 0x10,
+	0x15, 0x36, 0xef, 0x57, 0x80, 0x08, 0xf2, 0x36, 0x11, 0x44, 0x69, 0xae, 0x8c, 0x55, 0x1b, 0x7d,
+	0x0d, 0x20, 0xe8, 0xd8, 0x97, 0xa9, 0xd7, 0x1b, 0x6a, 0xd9, 0xbc, 0x2d, 0x1d, 0xa4, 0xd0, 0x68,
+	0x0b, 0x0a, 0xfa, 0xcd, 0x98, 0xbf, 0x96, 0xa7, 0x91, 0xf5, 0x3f, 0xe5, 0x00, 0xa2, 0x65, 0xfe,
+	0x5f, 0xaf, 0xad, 0x65, 0xbe, 0xfe, 0x7e, 0x6d, 0xee, 0xef, 0xdf, 0xaf, 0xcd, 0xfd, 0xee, 0x62,
+	0x2d, 0xf7, 0xfa, 0x62, 0x2d, 0xf7, 0xb7, 0x8b, 0xb5, 0xdc, 0x3f, 0x2f, 0xd6, 0x72, 0x87, 0x05,
+	0x55, 0x7b, 0xfc, 0xf8, 0xbf, 0x01, 0x00, 0x00, 0xff, 0xff, 0x1a, 0xbd, 0x13, 0xac, 0xa9, 0x15,
+	0x00, 0x00,
 }
 }

+ 21 - 0
vendor/github.com/docker/swarmkit/api/specs.proto

@@ -6,6 +6,7 @@ import "github.com/docker/swarmkit/api/types.proto";
 import "gogoproto/gogo.proto";
 import "gogoproto/gogo.proto";
 import "google/protobuf/duration.proto";
 import "google/protobuf/duration.proto";
 import "google/protobuf/any.proto";
 import "google/protobuf/any.proto";
+import "google/protobuf/wrappers.proto";
 
 
 // Specs are container objects for user provided input. All creations and
 // Specs are container objects for user provided input. All creations and
 // updates are done through spec types. As a convention, user input from a spec
 // updates are done through spec types. As a convention, user input from a spec
@@ -215,6 +216,9 @@ message ContainerSpec {
 	// Privileges specifies security configuration/permissions.
 	// Privileges specifies security configuration/permissions.
 	Privileges privileges = 22;
 	Privileges privileges = 22;
 
 
+	// Init declares that a custom init will be running inside the container, if null, use the daemon's configured settings
+	google.protobuf.BoolValue init = 23;
+
 	// TTY declares that a TTY should be attached to the standard streams,
 	// TTY declares that a TTY should be attached to the standard streams,
 	// including stdin if it is still open.
 	// including stdin if it is still open.
 	bool tty = 13 [(gogoproto.customname) = "TTY"];
 	bool tty = 13 [(gogoproto.customname) = "TTY"];
@@ -293,6 +297,23 @@ message ContainerSpec {
 	// task will exit and a new task will be rescheduled elsewhere. A container
 	// task will exit and a new task will be rescheduled elsewhere. A container
 	// is considered unhealthy after `Retries` number of consecutive failures.
 	// is considered unhealthy after `Retries` number of consecutive failures.
 	HealthConfig healthcheck = 16;
 	HealthConfig healthcheck = 16;
+
+	enum Isolation {
+		option (gogoproto.goproto_enum_prefix) = false;
+
+		// ISOLATION_DEFAULT uses whatever default value from the container runtime
+		ISOLATION_DEFAULT = 0 [(gogoproto.enumvalue_customname) = "ContainerIsolationDefault"];
+
+		// ISOLATION_PROCESS forces windows container isolation
+		ISOLATION_PROCESS = 1 [(gogoproto.enumvalue_customname) = "ContainerIsolationProcess"];
+
+		// ISOLATION_HYPERV forces Hyper-V isolation
+		ISOLATION_HYPERV = 2 [(gogoproto.enumvalue_customname) = "ContainerIsolationHyperV"];
+	}
+
+	// Isolation defines the isolation level for windows containers (default, process, hyperv).
+	// Runtimes that don't support it ignore that field
+	Isolation isolation = 24;
 }
 }
 
 
 // EndpointSpec defines the properties that can be configured to
 // EndpointSpec defines the properties that can be configured to

+ 6 - 1
vendor/github.com/docker/swarmkit/api/types.pb.go

@@ -1085,12 +1085,17 @@ type TaskStatus struct {
 	// because the task is prepared, we would put "already prepared" in this
 	// because the task is prepared, we would put "already prepared" in this
 	// field.
 	// field.
 	Message string `protobuf:"bytes,3,opt,name=message,proto3" json:"message,omitempty"`
 	Message string `protobuf:"bytes,3,opt,name=message,proto3" json:"message,omitempty"`
-	// Err is set if the task is in an error state.
+	// Err is set if the task is in an error state, or is unable to
+	// progress from an earlier state because a precondition is
+	// unsatisfied.
 	//
 	//
 	// The following states should report a companion error:
 	// The following states should report a companion error:
 	//
 	//
 	// 	FAILED, REJECTED
 	// 	FAILED, REJECTED
 	//
 	//
+	// In general, messages that should be surfaced to users belong in the
+	// Err field, and notes on routine state transitions belong in Message.
+	//
 	// TODO(stevvooe) Integrate this field with the error interface.
 	// TODO(stevvooe) Integrate this field with the error interface.
 	Err string `protobuf:"bytes,4,opt,name=err,proto3" json:"err,omitempty"`
 	Err string `protobuf:"bytes,4,opt,name=err,proto3" json:"err,omitempty"`
 	// Container status contains container specific status information.
 	// Container status contains container specific status information.

+ 6 - 1
vendor/github.com/docker/swarmkit/api/types.proto

@@ -509,12 +509,17 @@ message TaskStatus {
 	// field.
 	// field.
 	string message = 3;
 	string message = 3;
 
 
-	// Err is set if the task is in an error state.
+	// Err is set if the task is in an error state, or is unable to
+	// progress from an earlier state because a precondition is
+	// unsatisfied.
 	//
 	//
 	// The following states should report a companion error:
 	// The following states should report a companion error:
 	//
 	//
 	//	FAILED, REJECTED
 	//	FAILED, REJECTED
 	//
 	//
+	// In general, messages that should be surfaced to users belong in the
+	// Err field, and notes on routine state transitions belong in Message.
+	//
 	// TODO(stevvooe) Integrate this field with the error interface.
 	// TODO(stevvooe) Integrate this field with the error interface.
 	string err = 4;
 	string err = 4;
 
 

+ 5 - 3
vendor/github.com/docker/swarmkit/manager/allocator/network.go

@@ -1284,9 +1284,11 @@ func PredefinedNetworks() []networkallocator.PredefinedNetworkData {
 
 
 // updateTaskStatus sets TaskStatus and updates timestamp.
 // updateTaskStatus sets TaskStatus and updates timestamp.
 func updateTaskStatus(t *api.Task, newStatus api.TaskState, message string) {
 func updateTaskStatus(t *api.Task, newStatus api.TaskState, message string) {
-	t.Status.State = newStatus
-	t.Status.Message = message
-	t.Status.Timestamp = ptypes.MustTimestampProto(time.Now())
+	t.Status = api.TaskStatus{
+		State:     newStatus,
+		Message:   message,
+		Timestamp: ptypes.MustTimestampProto(time.Now()),
+	}
 }
 }
 
 
 // IsIngressNetwork returns whether the passed network is an ingress network.
 // IsIngressNetwork returns whether the passed network is an ingress network.

+ 2 - 1
vendor/github.com/docker/swarmkit/manager/orchestrator/constraintenforcer/constraint_enforcer.go

@@ -159,7 +159,8 @@ loop:
 					// restarting the task on another node
 					// restarting the task on another node
 					// (if applicable).
 					// (if applicable).
 					t.Status.State = api.TaskStateRejected
 					t.Status.State = api.TaskStateRejected
-					t.Status.Message = "assigned node no longer meets constraints"
+					t.Status.Message = "task rejected by constraint enforcer"
+					t.Status.Err = "assigned node no longer meets constraints"
 					t.Status.Timestamp = ptypes.MustTimestampProto(time.Now())
 					t.Status.Timestamp = ptypes.MustTimestampProto(time.Now())
 					return store.UpdateTask(tx, t)
 					return store.UpdateTask(tx, t)
 				})
 				})

+ 1 - 1
vendor/github.com/docker/swarmkit/manager/scheduler/filter.go

@@ -169,7 +169,7 @@ func (f *PluginFilter) Check(n *NodeInfo) bool {
 		}
 		}
 	}
 	}
 
 
-	if f.t.Spec.LogDriver != nil {
+	if f.t.Spec.LogDriver != nil && f.t.Spec.LogDriver.Name != "none" {
 		// If there are no log driver types in the list at all, most likely this is
 		// If there are no log driver types in the list at all, most likely this is
 		// an older daemon that did not report this information. In this case don't filter
 		// an older daemon that did not report this information. In this case don't filter
 		if typeFound, exists := f.pluginExistsOnNode("Log", f.t.Spec.LogDriver.Name, nodePlugins); !exists && typeFound {
 		if typeFound, exists := f.pluginExistsOnNode("Log", f.t.Spec.LogDriver.Name, nodePlugins); !exists && typeFound {

+ 6 - 4
vendor/github.com/docker/swarmkit/manager/scheduler/scheduler.go

@@ -446,7 +446,9 @@ func (s *Scheduler) applySchedulingDecisions(ctx context.Context, schedulingDeci
 						continue
 						continue
 					}
 					}
 
 
-					if t.Status.State == decision.new.Status.State && t.Status.Message == decision.new.Status.Message {
+					if t.Status.State == decision.new.Status.State &&
+						t.Status.Message == decision.new.Status.Message &&
+						t.Status.Err == decision.new.Status.Err {
 						// No changes, ignore
 						// No changes, ignore
 						continue
 						continue
 					}
 					}
@@ -502,7 +504,7 @@ func (s *Scheduler) taskFitNode(ctx context.Context, t *api.Task, nodeID string)
 	if !s.pipeline.Process(&nodeInfo) {
 	if !s.pipeline.Process(&nodeInfo) {
 		// this node cannot accommodate this task
 		// this node cannot accommodate this task
 		newT.Status.Timestamp = ptypes.MustTimestampProto(time.Now())
 		newT.Status.Timestamp = ptypes.MustTimestampProto(time.Now())
-		newT.Status.Message = s.pipeline.Explain()
+		newT.Status.Err = s.pipeline.Explain()
 		s.allTasks[t.ID] = &newT
 		s.allTasks[t.ID] = &newT
 
 
 		return &newT
 		return &newT
@@ -702,9 +704,9 @@ func (s *Scheduler) noSuitableNode(ctx context.Context, taskGroup map[string]*ap
 		newT := *t
 		newT := *t
 		newT.Status.Timestamp = ptypes.MustTimestampProto(time.Now())
 		newT.Status.Timestamp = ptypes.MustTimestampProto(time.Now())
 		if explanation != "" {
 		if explanation != "" {
-			newT.Status.Message = "no suitable node (" + explanation + ")"
+			newT.Status.Err = "no suitable node (" + explanation + ")"
 		} else {
 		} else {
-			newT.Status.Message = "no suitable node"
+			newT.Status.Err = "no suitable node"
 		}
 		}
 		s.allTasks[t.ID] = &newT
 		s.allTasks[t.ID] = &newT
 		schedulingDecisions[t.ID] = schedulingDecision{old: t, new: &newT}
 		schedulingDecisions[t.ID] = schedulingDecision{old: t, new: &newT}

+ 12 - 3
vendor/github.com/docker/swarmkit/manager/state/raft/raft.go

@@ -180,9 +180,12 @@ type NodeOptions struct {
 	ClockSource clock.Clock
 	ClockSource clock.Clock
 	// SendTimeout is the timeout on the sending messages to other raft
 	// SendTimeout is the timeout on the sending messages to other raft
 	// nodes. Leave this as 0 to get the default value.
 	// nodes. Leave this as 0 to get the default value.
-	SendTimeout    time.Duration
-	TLSCredentials credentials.TransportCredentials
-	KeyRotator     EncryptionKeyRotator
+	SendTimeout time.Duration
+	// LargeSendTimeout is the timeout on the sending snapshots to other raft
+	// nodes. Leave this as 0 to get the default value.
+	LargeSendTimeout time.Duration
+	TLSCredentials   credentials.TransportCredentials
+	KeyRotator       EncryptionKeyRotator
 	// DisableStackDump prevents Run from dumping goroutine stacks when the
 	// DisableStackDump prevents Run from dumping goroutine stacks when the
 	// store becomes stuck.
 	// store becomes stuck.
 	DisableStackDump bool
 	DisableStackDump bool
@@ -204,6 +207,11 @@ func NewNode(opts NodeOptions) *Node {
 	if opts.SendTimeout == 0 {
 	if opts.SendTimeout == 0 {
 		opts.SendTimeout = 2 * time.Second
 		opts.SendTimeout = 2 * time.Second
 	}
 	}
+	if opts.LargeSendTimeout == 0 {
+		// a "slow" 100Mbps connection can send over 240MB data in 20 seconds
+		// which is well over the gRPC message limit of 128MB allowed by SwarmKit
+		opts.LargeSendTimeout = 20 * time.Second
+	}
 
 
 	raftStore := raft.NewMemoryStorage()
 	raftStore := raft.NewMemoryStorage()
 
 
@@ -349,6 +357,7 @@ func (n *Node) initTransport() {
 	transportConfig := &transport.Config{
 	transportConfig := &transport.Config{
 		HeartbeatInterval: time.Duration(n.Config.ElectionTick) * n.opts.TickInterval,
 		HeartbeatInterval: time.Duration(n.Config.ElectionTick) * n.opts.TickInterval,
 		SendTimeout:       n.opts.SendTimeout,
 		SendTimeout:       n.opts.SendTimeout,
+		LargeSendTimeout:  n.opts.LargeSendTimeout,
 		Credentials:       n.opts.TLSCredentials,
 		Credentials:       n.opts.TLSCredentials,
 		Raft:              n,
 		Raft:              n,
 	}
 	}

+ 8 - 1
vendor/github.com/docker/swarmkit/manager/state/raft/transport/peer.go

@@ -133,7 +133,14 @@ func (p *peer) resolveAddr(ctx context.Context, id uint64) (string, error) {
 }
 }
 
 
 func (p *peer) sendProcessMessage(ctx context.Context, m raftpb.Message) error {
 func (p *peer) sendProcessMessage(ctx context.Context, m raftpb.Message) error {
-	ctx, cancel := context.WithTimeout(ctx, p.tr.config.SendTimeout)
+	timeout := p.tr.config.SendTimeout
+	// if a snapshot is being sent, set timeout to LargeSendTimeout because
+	// sending snapshots can take more time than other messages sent between peers.
+	// The same applies to AppendEntries as well, where messages can get large.
+	if m.Type == raftpb.MsgSnap || m.Type == raftpb.MsgApp {
+		timeout = p.tr.config.LargeSendTimeout
+	}
+	ctx, cancel := context.WithTimeout(ctx, timeout)
 	defer cancel()
 	defer cancel()
 	_, err := api.NewRaftClient(p.conn()).ProcessRaftMessage(ctx, &api.ProcessRaftMessageRequest{Message: &m})
 	_, err := api.NewRaftClient(p.conn()).ProcessRaftMessage(ctx, &api.ProcessRaftMessageRequest{Message: &m})
 	if grpc.Code(err) == codes.NotFound && grpc.ErrorDesc(err) == membership.ErrMemberRemoved.Error() {
 	if grpc.Code(err) == codes.NotFound && grpc.ErrorDesc(err) == membership.ErrMemberRemoved.Error() {

+ 1 - 0
vendor/github.com/docker/swarmkit/manager/state/raft/transport/transport.go

@@ -35,6 +35,7 @@ type Raft interface {
 type Config struct {
 type Config struct {
 	HeartbeatInterval time.Duration
 	HeartbeatInterval time.Duration
 	SendTimeout       time.Duration
 	SendTimeout       time.Duration
+	LargeSendTimeout  time.Duration
 	Credentials       credentials.TransportCredentials
 	Credentials       credentials.TransportCredentials
 	RaftID            string
 	RaftID            string