Added support for swarm service isolation mode

Signed-off-by: Simon Ferquel <simon.ferquel@docker.com>
This commit is contained in:
Simon Ferquel 2017-08-07 16:07:17 +02:00
parent ba3bf8191e
commit f28cb422e6
25 changed files with 575 additions and 207 deletions

View file

@ -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"

View file

@ -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

View file

@ -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()

View file

@ -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"` Hosts []string `json:",omitempty"`
DNSConfig *DNSConfig `json:",omitempty"` DNSConfig *DNSConfig `json:",omitempty"`
Secrets []*SecretReference `json:",omitempty"` Secrets []*SecretReference `json:",omitempty"`
Configs []*ConfigReference `json:",omitempty"` Configs []*ConfigReference `json:",omitempty"`
Isolation container.Isolation `json:",omitempty"`
} }

View file

@ -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
}

View file

@ -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)
})
}
}

View file

@ -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 {

View file

@ -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)
})
}
}

View file

@ -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

View file

@ -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, "")

View file

@ -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()

View file

@ -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,

View file

@ -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

View file

@ -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")

View file

@ -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 {
return 0, err
}
i += n28
dAtA[i] = 0x12
i++
i = encodeVarintSpecs(dAtA, i, uint64(m.AcceptancePolicy.Size()))
n29, err := m.AcceptancePolicy.MarshalTo(dAtA[i:])
if err != nil { if err != nil {
return 0, err return 0, err
} }
i += n29 i += n29
dAtA[i] = 0x1a dAtA[i] = 0x12
i++ i++
i = encodeVarintSpecs(dAtA, i, uint64(m.Orchestration.Size())) i = encodeVarintSpecs(dAtA, i, uint64(m.AcceptancePolicy.Size()))
n30, err := m.Orchestration.MarshalTo(dAtA[i:]) n30, err := m.AcceptancePolicy.MarshalTo(dAtA[i:])
if err != nil { if err != nil {
return 0, err return 0, err
} }
i += n30 i += n30
dAtA[i] = 0x22 dAtA[i] = 0x1a
i++ i++
i = encodeVarintSpecs(dAtA, i, uint64(m.Raft.Size())) i = encodeVarintSpecs(dAtA, i, uint64(m.Orchestration.Size()))
n31, err := m.Raft.MarshalTo(dAtA[i:]) n31, err := m.Orchestration.MarshalTo(dAtA[i:])
if err != nil { if err != nil {
return 0, err return 0, err
} }
i += n31 i += n31
dAtA[i] = 0x2a dAtA[i] = 0x22
i++ i++
i = encodeVarintSpecs(dAtA, i, uint64(m.Dispatcher.Size())) i = encodeVarintSpecs(dAtA, i, uint64(m.Raft.Size()))
n32, err := m.Dispatcher.MarshalTo(dAtA[i:]) n32, err := m.Raft.MarshalTo(dAtA[i:])
if err != nil { if err != nil {
return 0, err return 0, err
} }
i += n32 i += n32
dAtA[i] = 0x32 dAtA[i] = 0x2a
i++ i++
i = encodeVarintSpecs(dAtA, i, uint64(m.CAConfig.Size())) i = encodeVarintSpecs(dAtA, i, uint64(m.Dispatcher.Size()))
n33, err := m.CAConfig.MarshalTo(dAtA[i:]) n33, err := m.Dispatcher.MarshalTo(dAtA[i:])
if err != nil { if err != nil {
return 0, err return 0, err
} }
i += n33 i += n33
dAtA[i] = 0x3a dAtA[i] = 0x32
i++ i++
i = encodeVarintSpecs(dAtA, i, uint64(m.TaskDefaults.Size())) i = encodeVarintSpecs(dAtA, i, uint64(m.CAConfig.Size()))
n34, err := m.TaskDefaults.MarshalTo(dAtA[i:]) n34, err := m.CAConfig.MarshalTo(dAtA[i:])
if err != nil { if err != nil {
return 0, err return 0, err
} }
i += n34 i += n34
dAtA[i] = 0x42 dAtA[i] = 0x3a
i++ i++
i = encodeVarintSpecs(dAtA, i, uint64(m.EncryptionConfig.Size())) i = encodeVarintSpecs(dAtA, i, uint64(m.TaskDefaults.Size()))
n35, err := m.EncryptionConfig.MarshalTo(dAtA[i:]) n35, err := m.TaskDefaults.MarshalTo(dAtA[i:])
if err != nil { if err != nil {
return 0, err return 0, err
} }
i += n35 i += n35
dAtA[i] = 0x42
i++
i = encodeVarintSpecs(dAtA, i, uint64(m.EncryptionConfig.Size()))
n36, err := m.EncryptionConfig.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
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 // 2114 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x57, 0xcf, 0x6f, 0x1b, 0xb9, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x58, 0x4f, 0x6f, 0xdb, 0xc8,
0x15, 0xb6, 0x6c, 0x59, 0x3f, 0xde, 0xc8, 0x89, 0xc2, 0xcd, 0xa6, 0x13, 0xa5, 0x6b, 0x2b, 0xda, 0x15, 0xb7, 0x6c, 0x59, 0x96, 0x1e, 0xe5, 0x44, 0x9e, 0x4d, 0xb2, 0xb4, 0xb2, 0xb1, 0x15, 0x6d,
0x6c, 0xea, 0xdd, 0x45, 0x25, 0xd4, 0x2d, 0xb6, 0xd9, 0x4d, 0xb7, 0xad, 0x64, 0xa9, 0x8e, 0x9b, 0x36, 0xf5, 0xee, 0xa2, 0x32, 0xea, 0x2e, 0xb6, 0xd9, 0x4d, 0xb7, 0xad, 0x64, 0x69, 0x1d, 0x35,
0xc6, 0x11, 0x68, 0x6f, 0xda, 0x00, 0x05, 0x04, 0x6a, 0x86, 0x1e, 0x0d, 0x3c, 0x1a, 0x4e, 0x39, 0x89, 0x2d, 0x8c, 0x1c, 0xb7, 0x01, 0x0a, 0x08, 0x63, 0x72, 0x2c, 0x11, 0xa6, 0x38, 0xec, 0x70,
0x1c, 0x2d, 0x74, 0xeb, 0x71, 0x91, 0x1e, 0x7b, 0x0e, 0x7a, 0x28, 0x7a, 0xef, 0x9f, 0x91, 0x63, 0xe8, 0x40, 0xb7, 0x1e, 0x17, 0xee, 0x67, 0x30, 0x7a, 0x28, 0x7a, 0x6f, 0xbf, 0x42, 0x4f, 0x39,
0x8f, 0xed, 0xc5, 0xe8, 0xea, 0x5f, 0xe8, 0xad, 0x97, 0x16, 0xe4, 0x70, 0x46, 0xa3, 0x64, 0x6c, 0xf6, 0xd8, 0x5e, 0x8c, 0xae, 0xbf, 0x42, 0x6f, 0xbd, 0xb4, 0x98, 0xe1, 0x90, 0xa2, 0x1c, 0x3a,
0x07, 0x68, 0x0e, 0xbd, 0x91, 0x8f, 0xdf, 0xf7, 0x48, 0x3e, 0x7e, 0x8f, 0x7c, 0x84, 0x4f, 0x1c, 0x0e, 0xd0, 0x1c, 0x7a, 0x9b, 0x79, 0xfc, 0xfd, 0xde, 0xfc, 0xfb, 0xbd, 0x37, 0x6f, 0x08, 0x9f,
0x57, 0x4c, 0xa2, 0x71, 0xdb, 0x62, 0xd3, 0x8e, 0xcd, 0xac, 0x33, 0xca, 0x3b, 0xe1, 0xd7, 0x84, 0x0d, 0x1d, 0x31, 0x0a, 0x0f, 0x1b, 0x16, 0x1b, 0x6f, 0xda, 0xcc, 0x3a, 0xa6, 0x7c, 0x33, 0x78,
0x4f, 0xcf, 0x5c, 0xd1, 0x21, 0x81, 0xdb, 0x09, 0x03, 0x6a, 0x85, 0xed, 0x80, 0x33, 0xc1, 0x10, 0x45, 0xf8, 0xf8, 0xd8, 0x11, 0x9b, 0xc4, 0x77, 0x36, 0x03, 0x9f, 0x5a, 0x41, 0xc3, 0xe7, 0x4c,
0x8a, 0x01, 0xed, 0x04, 0xd0, 0x9e, 0xfd, 0xa0, 0x71, 0x15, 0x5f, 0xcc, 0x03, 0xaa, 0xf9, 0x8d, 0x30, 0x84, 0x22, 0x40, 0x23, 0x06, 0x34, 0x4e, 0x7e, 0x54, 0xbd, 0x8e, 0x2f, 0x26, 0x3e, 0xd5,
0x9b, 0x0e, 0x73, 0x98, 0x6a, 0x76, 0x64, 0x4b, 0x5b, 0xb7, 0x1d, 0xc6, 0x1c, 0x8f, 0x76, 0x54, 0xfc, 0xea, 0xad, 0x21, 0x1b, 0x32, 0xd5, 0xdc, 0x94, 0x2d, 0x6d, 0x5d, 0x1b, 0x32, 0x36, 0x74,
0x6f, 0x1c, 0x9d, 0x76, 0xec, 0x88, 0x13, 0xe1, 0x32, 0x5f, 0x8f, 0xdf, 0x7e, 0x7d, 0x9c, 0xf8, 0xe9, 0xa6, 0xea, 0x1d, 0x86, 0x47, 0x9b, 0x76, 0xc8, 0x89, 0x70, 0x98, 0xa7, 0xbf, 0xaf, 0x5e,
0xf3, 0x78, 0xa8, 0xf5, 0xb2, 0x08, 0x95, 0x23, 0x66, 0xd3, 0xe3, 0x80, 0x5a, 0xe8, 0x00, 0x0c, 0xfe, 0x4e, 0xbc, 0xc9, 0x55, 0xd4, 0x57, 0x9c, 0xf8, 0x3e, 0xe5, 0x7a, 0xc0, 0xfa, 0x59, 0x1e,
0xe2, 0xfb, 0x4c, 0x28, 0x6e, 0x68, 0x16, 0x9a, 0x85, 0x5d, 0x63, 0x6f, 0xa7, 0xfd, 0xe6, 0x9a, 0x8a, 0xbb, 0xcc, 0xa6, 0x7d, 0x9f, 0x5a, 0x68, 0x07, 0x0c, 0xe2, 0x79, 0x4c, 0x28, 0xdf, 0x81,
0xdb, 0xdd, 0x25, 0xac, 0x57, 0x7c, 0x75, 0xbe, 0xb3, 0x86, 0xb3, 0x4c, 0xf4, 0x33, 0xa8, 0xd9, 0x99, 0xab, 0xe5, 0x36, 0x8c, 0xad, 0xf5, 0xc6, 0x9b, 0x6b, 0x6a, 0x34, 0xa7, 0xb0, 0x56, 0xfe,
0x34, 0x74, 0x39, 0xb5, 0x47, 0x9c, 0x79, 0xd4, 0x5c, 0x6f, 0x16, 0x76, 0xaf, 0xed, 0x7d, 0x37, 0xf5, 0xf9, 0xfa, 0x1c, 0x4e, 0x33, 0xd1, 0xcf, 0xa1, 0x6c, 0xd3, 0xc0, 0xe1, 0xd4, 0x1e, 0x70,
0xcf, 0x93, 0x9c, 0x1c, 0x33, 0x8f, 0x62, 0x43, 0x33, 0x64, 0x07, 0x1d, 0x00, 0x4c, 0xe9, 0x74, 0xe6, 0x52, 0x73, 0xbe, 0x96, 0xdb, 0xb8, 0xb1, 0xf5, 0x51, 0x96, 0x27, 0x39, 0x38, 0x66, 0x2e,
0x4c, 0x79, 0x38, 0x71, 0x03, 0x73, 0x43, 0xd1, 0xbf, 0x77, 0x11, 0x5d, 0xae, 0xbd, 0xfd, 0x24, 0xc5, 0x86, 0x66, 0xc8, 0x0e, 0xda, 0x01, 0x18, 0xd3, 0xf1, 0x21, 0xe5, 0xc1, 0xc8, 0xf1, 0xcd,
0x85, 0xe3, 0x0c, 0x15, 0x3d, 0x81, 0x1a, 0x99, 0x11, 0xd7, 0x23, 0x63, 0xd7, 0x73, 0xc5, 0xdc, 0x05, 0x45, 0xff, 0xc1, 0x55, 0x74, 0x39, 0xf7, 0xc6, 0xf3, 0x04, 0x8e, 0x53, 0x54, 0xf4, 0x1c,
0x2c, 0x2a, 0x57, 0x1f, 0x5f, 0xea, 0xaa, 0x9b, 0x21, 0xe0, 0x15, 0x7a, 0xcb, 0x06, 0x58, 0x4e, 0xca, 0xe4, 0x84, 0x38, 0x2e, 0x39, 0x74, 0x5c, 0x47, 0x4c, 0xcc, 0xbc, 0x72, 0xf5, 0xe9, 0x5b,
0x84, 0xee, 0x43, 0x79, 0x38, 0x38, 0xea, 0x1f, 0x1e, 0x1d, 0xd4, 0xd7, 0x1a, 0xb7, 0x5f, 0xbc, 0x5d, 0x35, 0x53, 0x04, 0x3c, 0x43, 0xaf, 0xdb, 0x00, 0xd3, 0x81, 0xd0, 0x43, 0x58, 0xea, 0x75,
0x6c, 0xbe, 0x2f, 0x7d, 0x2c, 0x01, 0x43, 0xea, 0xdb, 0xae, 0xef, 0xa0, 0x5d, 0xa8, 0x74, 0xf7, 0x76, 0xdb, 0xdd, 0xdd, 0x9d, 0xca, 0x5c, 0x75, 0xf5, 0xf4, 0xac, 0x76, 0x5b, 0xfa, 0x98, 0x02,
0xf7, 0x07, 0xc3, 0x93, 0x41, 0xbf, 0x5e, 0x68, 0x34, 0x5e, 0xbc, 0x6c, 0xde, 0x5a, 0x05, 0x76, 0x7a, 0xd4, 0xb3, 0x1d, 0x6f, 0x88, 0x36, 0xa0, 0xd8, 0xdc, 0xde, 0xee, 0xf4, 0xf6, 0x3b, 0xed,
0x2d, 0x8b, 0x06, 0x82, 0xda, 0x8d, 0xe2, 0x37, 0x7f, 0xde, 0x5e, 0x6b, 0x7d, 0x53, 0x80, 0x5a, 0x4a, 0xae, 0x5a, 0x3d, 0x3d, 0xab, 0xdd, 0x99, 0x05, 0x36, 0x2d, 0x8b, 0xfa, 0x82, 0xda, 0xd5,
0x76, 0x11, 0xe8, 0x3e, 0x94, 0xba, 0xfb, 0x27, 0x87, 0xcf, 0x06, 0xf5, 0xb5, 0x25, 0x3d, 0x8b, 0xfc, 0x77, 0x7f, 0x5c, 0x9b, 0xab, 0x7f, 0x97, 0x83, 0x72, 0x7a, 0x12, 0xe8, 0x21, 0x14, 0x9a,
0xe8, 0x5a, 0xc2, 0x9d, 0x51, 0x74, 0x0f, 0x36, 0x87, 0xdd, 0xaf, 0x8e, 0x07, 0xf5, 0xc2, 0x72, 0xdb, 0xfb, 0xdd, 0x83, 0x4e, 0x65, 0x6e, 0x4a, 0x4f, 0x23, 0x9a, 0x96, 0x70, 0x4e, 0x28, 0x7a,
0x39, 0x59, 0xd8, 0x90, 0x44, 0xa1, 0x42, 0xf5, 0x71, 0xf7, 0xf0, 0xa8, 0xbe, 0x9e, 0x8f, 0xea, 0x00, 0x8b, 0xbd, 0xe6, 0x8b, 0x7e, 0xa7, 0x92, 0x9b, 0x4e, 0x27, 0x0d, 0xeb, 0x91, 0x30, 0x50,
0x73, 0xe2, 0xfa, 0x7a, 0x29, 0x7f, 0x2a, 0x82, 0x71, 0x4c, 0xf9, 0xcc, 0xb5, 0xde, 0xb1, 0x44, 0xa8, 0x36, 0x6e, 0x76, 0x77, 0x2b, 0xf3, 0xd9, 0xa8, 0x36, 0x27, 0x8e, 0xa7, 0xa7, 0xf2, 0x87,
0x3e, 0x83, 0xa2, 0x20, 0xe1, 0x99, 0x92, 0x86, 0x91, 0x2f, 0x8d, 0x13, 0x12, 0x9e, 0xc9, 0x49, 0x3c, 0x18, 0x7d, 0xca, 0x4f, 0x1c, 0xeb, 0x3d, 0x4b, 0xe4, 0x4b, 0xc8, 0x0b, 0x12, 0x1c, 0x2b,
0x35, 0x5d, 0xe1, 0xa5, 0x32, 0x38, 0x0d, 0x3c, 0xd7, 0x22, 0x82, 0xda, 0x4a, 0x19, 0xc6, 0xde, 0x69, 0x18, 0xd9, 0xd2, 0xd8, 0x27, 0xc1, 0xb1, 0x1c, 0x54, 0xd3, 0x15, 0x5e, 0x2a, 0x83, 0x53,
0x47, 0x79, 0x6c, 0x9c, 0xa2, 0xf4, 0xfa, 0x1f, 0xad, 0xe1, 0x0c, 0x15, 0x3d, 0x84, 0x92, 0xe3, 0xdf, 0x75, 0x2c, 0x22, 0xa8, 0xad, 0x94, 0x61, 0x6c, 0x7d, 0x92, 0xc5, 0xc6, 0x09, 0x4a, 0xcf,
0xb1, 0x31, 0xf1, 0x94, 0x26, 0x8c, 0xbd, 0xbb, 0x79, 0x4e, 0x0e, 0x14, 0x62, 0xe9, 0x40, 0x53, 0xff, 0xc9, 0x1c, 0x4e, 0x51, 0xd1, 0x63, 0x28, 0x0c, 0x5d, 0x76, 0x48, 0x5c, 0xa5, 0x09, 0x63,
0xd0, 0x03, 0x28, 0x45, 0x81, 0x4d, 0x04, 0x35, 0x4b, 0x8a, 0xdc, 0xcc, 0x23, 0x7f, 0xa5, 0x10, 0xeb, 0x7e, 0x96, 0x93, 0x1d, 0x85, 0x98, 0x3a, 0xd0, 0x14, 0xf4, 0x08, 0x0a, 0xa1, 0x6f, 0x13,
0xfb, 0xcc, 0x3f, 0x75, 0x1d, 0xac, 0xf1, 0xe8, 0x31, 0x54, 0x7c, 0x2a, 0xbe, 0x66, 0xfc, 0x2c, 0x41, 0xcd, 0x82, 0x22, 0xd7, 0xb2, 0xc8, 0x2f, 0x14, 0x62, 0x9b, 0x79, 0x47, 0xce, 0x10, 0x6b,
0x34, 0xcb, 0xcd, 0x8d, 0x5d, 0x63, 0xef, 0xd3, 0x5c, 0x31, 0xc6, 0x98, 0xae, 0x10, 0xc4, 0x9a, 0x3c, 0x7a, 0x0a, 0x45, 0x8f, 0x8a, 0x57, 0x8c, 0x1f, 0x07, 0xe6, 0x52, 0x6d, 0x61, 0xc3, 0xd8,
0x4c, 0xa9, 0x2f, 0x62, 0x37, 0xbd, 0x75, 0xb3, 0x80, 0x53, 0x07, 0xe8, 0x27, 0x50, 0xa1, 0xbe, 0xfa, 0x3c, 0x53, 0x8c, 0x11, 0xa6, 0x29, 0x04, 0xb1, 0x46, 0x63, 0xea, 0x89, 0xc8, 0x4d, 0x6b,
0x1d, 0x30, 0xd7, 0x17, 0x66, 0xe5, 0xe2, 0x85, 0x0c, 0x34, 0x46, 0x06, 0x13, 0xa7, 0x0c, 0xc9, 0xde, 0xcc, 0xe1, 0xc4, 0x01, 0xfa, 0x29, 0x14, 0xa9, 0x67, 0xfb, 0xcc, 0xf1, 0x84, 0x59, 0xbc,
0xe6, 0xcc, 0xf3, 0xc6, 0xc4, 0x3a, 0x33, 0xab, 0x6f, 0xb9, 0x8d, 0x94, 0xd1, 0x2b, 0x41, 0x71, 0x7a, 0x22, 0x1d, 0x8d, 0x91, 0x9b, 0x89, 0x13, 0x86, 0x64, 0x73, 0xe6, 0xba, 0x87, 0xc4, 0x3a,
0xca, 0x6c, 0xda, 0xea, 0xc0, 0x8d, 0x37, 0x42, 0x8d, 0x1a, 0x50, 0xd1, 0xa1, 0x8e, 0x35, 0x52, 0x36, 0x4b, 0xef, 0xb8, 0x8c, 0x84, 0xd1, 0x2a, 0x40, 0x7e, 0xcc, 0x6c, 0x5a, 0xdf, 0x84, 0x95,
0xc4, 0x69, 0xbf, 0x75, 0x1d, 0xb6, 0x56, 0xc2, 0xda, 0xfa, 0xeb, 0x26, 0x54, 0x92, 0xb3, 0x46, 0x37, 0xb6, 0x1a, 0x55, 0xa1, 0xa8, 0xb7, 0x3a, 0xd2, 0x48, 0x1e, 0x27, 0xfd, 0xfa, 0x4d, 0x58,
0x5d, 0xa8, 0x5a, 0xcc, 0x17, 0xc4, 0xf5, 0x29, 0xd7, 0xf2, 0xca, 0x3d, 0x99, 0xfd, 0x04, 0x24, 0x9e, 0xd9, 0xd6, 0xfa, 0x9f, 0x17, 0xa1, 0x18, 0x9f, 0x35, 0x6a, 0x42, 0xc9, 0x62, 0x9e, 0x20,
0x59, 0x8f, 0xd6, 0xf0, 0x92, 0x85, 0x7e, 0x01, 0x55, 0x4e, 0x43, 0x16, 0x71, 0x8b, 0x86, 0x5a, 0x8e, 0x47, 0xb9, 0x96, 0x57, 0xe6, 0xc9, 0x6c, 0xc7, 0x20, 0xc9, 0x7a, 0x32, 0x87, 0xa7, 0x2c,
0x5f, 0xbb, 0xf9, 0x0a, 0x89, 0x41, 0x98, 0xfe, 0x2e, 0x72, 0x39, 0x95, 0x51, 0x0e, 0xf1, 0x92, 0xf4, 0x2d, 0x94, 0x38, 0x0d, 0x58, 0xc8, 0x2d, 0x1a, 0x68, 0x7d, 0x6d, 0x64, 0x2b, 0x24, 0x02,
0x8a, 0x1e, 0x42, 0x99, 0xd3, 0x50, 0x10, 0x2e, 0x2e, 0x93, 0x08, 0x8e, 0x21, 0x43, 0xe6, 0xb9, 0x61, 0xfa, 0xdb, 0xd0, 0xe1, 0x54, 0xee, 0x72, 0x80, 0xa7, 0x54, 0xf4, 0x18, 0x96, 0x38, 0x0d,
0xd6, 0x1c, 0x27, 0x0c, 0xf4, 0x10, 0xaa, 0x81, 0x47, 0x2c, 0xe5, 0xd5, 0xdc, 0x54, 0xf4, 0x0f, 0x04, 0xe1, 0xe2, 0x6d, 0x12, 0xc1, 0x11, 0xa4, 0xc7, 0x5c, 0xc7, 0x9a, 0xe0, 0x98, 0x81, 0x1e,
0xf2, 0xe8, 0xc3, 0x04, 0x84, 0x97, 0x78, 0xf4, 0x39, 0x80, 0xc7, 0x9c, 0x91, 0xcd, 0xdd, 0x19, 0x43, 0xc9, 0x77, 0x89, 0xa5, 0xbc, 0x9a, 0x8b, 0x8a, 0x7e, 0x2f, 0x8b, 0xde, 0x8b, 0x41, 0x78,
0xe5, 0x5a, 0x62, 0x8d, 0x3c, 0x76, 0x5f, 0x21, 0x70, 0xd5, 0x63, 0x4e, 0xdc, 0x44, 0x07, 0xff, 0x8a, 0x47, 0x5f, 0x01, 0xb8, 0x6c, 0x38, 0xb0, 0xb9, 0x73, 0x42, 0xb9, 0x96, 0x58, 0x35, 0x8b,
0x93, 0xbe, 0x32, 0xda, 0x7a, 0x0c, 0x40, 0xd2, 0x51, 0xad, 0xae, 0x8f, 0xdf, 0xca, 0x95, 0x3e, 0xdd, 0x56, 0x08, 0x5c, 0x72, 0xd9, 0x30, 0x6a, 0xa2, 0x9d, 0xff, 0x49, 0x5f, 0x29, 0x6d, 0x3d,
0x91, 0x0c, 0x1d, 0xdd, 0x85, 0xda, 0x29, 0xe3, 0x16, 0x1d, 0xe9, 0xac, 0xa9, 0x2a, 0x4d, 0x18, 0x05, 0x20, 0xc9, 0x57, 0xad, 0xae, 0x4f, 0xdf, 0xc9, 0x95, 0x3e, 0x91, 0x14, 0x1d, 0xdd, 0x87,
0xca, 0x16, 0xeb, 0x0b, 0xf5, 0xa0, 0xec, 0x50, 0x9f, 0x72, 0xd7, 0x32, 0x41, 0x4d, 0x76, 0x3f, 0xf2, 0x11, 0xe3, 0x16, 0x1d, 0xe8, 0xa8, 0x29, 0x29, 0x4d, 0x18, 0xca, 0x16, 0xe9, 0x0b, 0xb5,
0x37, 0x21, 0x63, 0x08, 0x8e, 0x7c, 0xe1, 0x4e, 0xa9, 0x9e, 0x29, 0x21, 0xa2, 0xdf, 0xc2, 0x7b, 0x60, 0x69, 0x48, 0x3d, 0xca, 0x1d, 0xcb, 0x04, 0x35, 0xd8, 0xc3, 0xcc, 0x80, 0x8c, 0x20, 0x38,
0xc9, 0xf1, 0x8d, 0x38, 0x3d, 0xa5, 0x9c, 0xfa, 0x52, 0x03, 0x86, 0x8a, 0xc3, 0x47, 0x97, 0x6b, 0xf4, 0x84, 0x33, 0xa6, 0x7a, 0xa4, 0x98, 0x88, 0x7e, 0x03, 0x1f, 0xc4, 0xc7, 0x37, 0xe0, 0xf4,
0x40, 0xa3, 0xf5, 0x65, 0x83, 0xf8, 0xeb, 0x03, 0x61, 0xaf, 0x0a, 0x65, 0x1e, 0xcf, 0xdb, 0xfa, 0x88, 0x72, 0xea, 0x49, 0x0d, 0x18, 0x6a, 0x1f, 0x3e, 0x79, 0xbb, 0x06, 0x34, 0x5a, 0x27, 0x1b,
0x43, 0x41, 0xaa, 0xfe, 0x35, 0x04, 0xea, 0x80, 0x91, 0x4e, 0xef, 0xda, 0x4a, 0xbd, 0xd5, 0xde, 0xc4, 0x2f, 0x7f, 0x08, 0x5a, 0x25, 0x58, 0xe2, 0xd1, 0xb8, 0xf5, 0xdf, 0xe7, 0xa4, 0xea, 0x2f,
0xb5, 0xc5, 0xf9, 0x0e, 0x24, 0xd8, 0xc3, 0xbe, 0xbc, 0x83, 0x74, 0xdb, 0x46, 0x03, 0xd8, 0x4a, 0x21, 0xd0, 0x26, 0x18, 0xc9, 0xf0, 0x8e, 0xad, 0xd4, 0x5b, 0x6a, 0xdd, 0xb8, 0x38, 0x5f, 0x87,
0x09, 0xf2, 0x99, 0xd7, 0x0f, 0x65, 0xf3, 0xb2, 0x95, 0x9e, 0xcc, 0x03, 0x8a, 0x6b, 0x3c, 0xd3, 0x18, 0xdb, 0x6d, 0xcb, 0x1c, 0xa4, 0xdb, 0x36, 0xea, 0xc0, 0x72, 0x42, 0x90, 0x65, 0x80, 0xbe,
0x6b, 0xfd, 0x06, 0xd0, 0x9b, 0x71, 0x41, 0x08, 0x8a, 0x67, 0xae, 0xaf, 0x97, 0x81, 0x55, 0x1b, 0x28, 0x6b, 0x6f, 0x9b, 0xe9, 0xfe, 0xc4, 0xa7, 0xb8, 0xcc, 0x53, 0xbd, 0xfa, 0xaf, 0x01, 0xbd,
0xb5, 0xa1, 0x1c, 0x90, 0xb9, 0xc7, 0x88, 0xad, 0x13, 0xe3, 0x66, 0x3b, 0xae, 0x0d, 0xda, 0x49, 0xb9, 0x2f, 0x08, 0x41, 0xfe, 0xd8, 0xf1, 0xf4, 0x34, 0xb0, 0x6a, 0xa3, 0x06, 0x2c, 0xf9, 0x64,
0x6d, 0xd0, 0xee, 0xfa, 0x73, 0x9c, 0x80, 0x5a, 0x8f, 0xe1, 0xfd, 0xdc, 0xe3, 0x45, 0x7b, 0x50, 0xe2, 0x32, 0x62, 0xeb, 0xc0, 0xb8, 0xd5, 0x88, 0x0a, 0x84, 0x46, 0x5c, 0x20, 0x34, 0x9a, 0xde,
0x4b, 0x13, 0x6e, 0xb9, 0xd7, 0xeb, 0x8b, 0xf3, 0x1d, 0x23, 0xcd, 0xcc, 0xc3, 0x3e, 0x36, 0x52, 0x04, 0xc7, 0xa0, 0xfa, 0x53, 0xb8, 0x9d, 0x79, 0xbc, 0x68, 0x0b, 0xca, 0x49, 0xc0, 0x4d, 0xd7,
0xd0, 0xa1, 0xdd, 0xfa, 0x63, 0x15, 0xb6, 0x56, 0xd2, 0x16, 0xdd, 0x84, 0x4d, 0x77, 0x4a, 0x1c, 0x7a, 0xf3, 0xe2, 0x7c, 0xdd, 0x48, 0x22, 0xb3, 0xdb, 0xc6, 0x46, 0x02, 0xea, 0xda, 0xf5, 0xbf,
0xaa, 0xd7, 0x18, 0x77, 0xd0, 0x00, 0x4a, 0x1e, 0x19, 0x53, 0x4f, 0x26, 0xaf, 0x3c, 0xb8, 0xef, 0x1a, 0xb0, 0x3c, 0x13, 0xb6, 0xe8, 0x16, 0x2c, 0x3a, 0x63, 0x32, 0xa4, 0x7a, 0x8e, 0x51, 0x07,
0x5f, 0x99, 0xff, 0xed, 0x5f, 0x29, 0xfc, 0xc0, 0x17, 0x7c, 0x8e, 0x35, 0x19, 0x99, 0x50, 0xb6, 0x75, 0xa0, 0xe0, 0x92, 0x43, 0xea, 0xca, 0xe0, 0x95, 0x07, 0xf7, 0xc3, 0x6b, 0xe3, 0xbf, 0xf1,
0xd8, 0x74, 0x4a, 0x7c, 0xf9, 0x4c, 0x6c, 0xec, 0x56, 0x71, 0xd2, 0x95, 0x91, 0x21, 0xdc, 0x09, 0x4c, 0xe1, 0x3b, 0x9e, 0xe0, 0x13, 0xac, 0xc9, 0xc8, 0x84, 0x25, 0x8b, 0x8d, 0xc7, 0xc4, 0x93,
0xcd, 0xa2, 0x32, 0xab, 0x36, 0xaa, 0xc3, 0x06, 0xf5, 0x67, 0xe6, 0xa6, 0x32, 0xc9, 0xa6, 0xb4, 0xd7, 0xc4, 0xc2, 0x46, 0x09, 0xc7, 0x5d, 0xb9, 0x33, 0x84, 0x0f, 0x03, 0x33, 0xaf, 0xcc, 0xaa,
0xd8, 0x6e, 0x9c, 0x7d, 0x55, 0x2c, 0x9b, 0x92, 0x17, 0x85, 0x94, 0x9b, 0xe5, 0x38, 0xa2, 0xb2, 0x8d, 0x2a, 0xb0, 0x40, 0xbd, 0x13, 0x73, 0x51, 0x99, 0x64, 0x53, 0x5a, 0x6c, 0x27, 0x8a, 0xbe,
0x8d, 0x7e, 0x0c, 0xa5, 0x29, 0x8b, 0x7c, 0x11, 0x9a, 0x15, 0xb5, 0xd8, 0xdb, 0x79, 0x8b, 0x7d, 0x12, 0x96, 0x4d, 0xc9, 0x0b, 0x03, 0xca, 0xcd, 0xa5, 0x68, 0x47, 0x65, 0x1b, 0xfd, 0x04, 0x0a,
0x22, 0x11, 0x5a, 0x59, 0x1a, 0x8e, 0x06, 0x70, 0x23, 0x14, 0x2c, 0x18, 0x39, 0x9c, 0x58, 0x74, 0x63, 0x16, 0x7a, 0x22, 0x30, 0x8b, 0x6a, 0xb2, 0xab, 0x59, 0x93, 0x7d, 0x2e, 0x11, 0x5a, 0x59,
0x14, 0x50, 0xee, 0x32, 0x5b, 0x5f, 0xc3, 0xb7, 0xdf, 0x38, 0x94, 0xbe, 0x2e, 0xe8, 0xf0, 0x75, 0x1a, 0x8e, 0x3a, 0xb0, 0x12, 0x08, 0xe6, 0x0f, 0x86, 0x9c, 0x58, 0x74, 0xe0, 0x53, 0xee, 0x30,
0xc9, 0x39, 0x90, 0x94, 0xa1, 0x62, 0xa0, 0x21, 0xd4, 0x82, 0xc8, 0xf3, 0x46, 0x2c, 0x88, 0x5f, 0x5b, 0xa7, 0xe1, 0xd5, 0x37, 0x0e, 0xa5, 0xad, 0x0b, 0x3e, 0x7c, 0x53, 0x72, 0x76, 0x24, 0xa5,
0xe4, 0x38, 0x77, 0xde, 0x22, 0x64, 0xc3, 0xc8, 0xf3, 0x9e, 0xc6, 0x24, 0x6c, 0x04, 0xcb, 0x0e, 0xa7, 0x18, 0xa8, 0x07, 0x65, 0x3f, 0x74, 0xdd, 0x01, 0xf3, 0xa3, 0x1b, 0x39, 0x8a, 0x9d, 0x77,
0xba, 0x05, 0x25, 0x87, 0xb3, 0x28, 0x88, 0xf3, 0xa6, 0x8a, 0x75, 0x0f, 0x7d, 0x09, 0xe5, 0x90, 0xd8, 0xb2, 0x5e, 0xe8, 0xba, 0x7b, 0x11, 0x09, 0x1b, 0xfe, 0xb4, 0x83, 0xee, 0x40, 0x61, 0xc8,
0x5a, 0x9c, 0x8a, 0xd0, 0xac, 0xa9, 0xad, 0x7e, 0x98, 0x37, 0xc9, 0xb1, 0x82, 0xa4, 0x39, 0x81, 0x59, 0xe8, 0x47, 0x71, 0x53, 0xc2, 0xba, 0x87, 0xbe, 0x81, 0xa5, 0x80, 0x5a, 0x9c, 0x8a, 0xc0,
0x13, 0x0e, 0xba, 0x0d, 0x1b, 0x42, 0xcc, 0xcd, 0xad, 0x66, 0x61, 0xb7, 0xd2, 0x2b, 0x2f, 0xce, 0x2c, 0xab, 0xa5, 0x7e, 0x9c, 0x35, 0x48, 0x5f, 0x41, 0x92, 0x98, 0xc0, 0x31, 0x07, 0xad, 0xc2,
0x77, 0x36, 0x4e, 0x4e, 0x9e, 0x63, 0x69, 0x93, 0xaf, 0xc5, 0x84, 0x85, 0xc2, 0x27, 0x53, 0x6a, 0x82, 0x10, 0x13, 0x73, 0xb9, 0x96, 0xdb, 0x28, 0xb6, 0x96, 0x2e, 0xce, 0xd7, 0x17, 0xf6, 0xf7,
0x5e, 0x53, 0xb1, 0x4d, 0xfb, 0xe8, 0x39, 0x80, 0xed, 0x87, 0x23, 0x4b, 0x5d, 0x4f, 0xe6, 0x75, 0x5f, 0x62, 0x69, 0x93, 0xb7, 0xc5, 0x88, 0x05, 0xc2, 0x23, 0x63, 0x6a, 0xde, 0x50, 0x7b, 0x9b,
0xb5, 0xbb, 0x4f, 0xaf, 0xde, 0x5d, 0xff, 0xe8, 0x58, 0xbf, 0x98, 0x5b, 0x8b, 0xf3, 0x9d, 0x6a, 0xf4, 0xd1, 0x4b, 0x00, 0xdb, 0x0b, 0x06, 0x96, 0x4a, 0x4f, 0xe6, 0x4d, 0xb5, 0xba, 0xcf, 0xaf,
0xda, 0xc5, 0x55, 0xdb, 0x0f, 0xe3, 0x26, 0xea, 0x81, 0x31, 0xa1, 0xc4, 0x13, 0x13, 0x6b, 0x42, 0x5f, 0x5d, 0x7b, 0xb7, 0xaf, 0x6f, 0xcc, 0xe5, 0x8b, 0xf3, 0xf5, 0x52, 0xd2, 0xc5, 0x25, 0xdb,
0xad, 0x33, 0xb3, 0x7e, 0xf1, 0x13, 0xf8, 0x48, 0xc1, 0xb4, 0x87, 0x2c, 0x49, 0x2a, 0x58, 0x2e, 0x0b, 0xa2, 0x26, 0x6a, 0x81, 0x31, 0xa2, 0xc4, 0x15, 0x23, 0x6b, 0x44, 0xad, 0x63, 0xb3, 0x72,
0x35, 0x34, 0x6f, 0xa8, 0x58, 0xc5, 0x1d, 0xf4, 0x01, 0x00, 0x0b, 0xa8, 0x3f, 0x0a, 0x85, 0xed, 0xf5, 0x15, 0xf8, 0x44, 0xc1, 0xb4, 0x87, 0x34, 0x49, 0x2a, 0x58, 0x4e, 0x35, 0x30, 0x57, 0xd4,
0xfa, 0x26, 0x92, 0x5b, 0xc6, 0x55, 0x69, 0x39, 0x96, 0x06, 0x74, 0x47, 0x3e, 0x50, 0xc4, 0x1e, 0x5e, 0x45, 0x1d, 0x74, 0x0f, 0x80, 0xf9, 0xd4, 0x1b, 0x04, 0xc2, 0x76, 0x3c, 0x13, 0xc9, 0x25,
0x31, 0xdf, 0x9b, 0x9b, 0xef, 0xa9, 0xd1, 0x8a, 0x34, 0x3c, 0xf5, 0xbd, 0x39, 0xda, 0x01, 0x43, 0xe3, 0x92, 0xb4, 0xf4, 0xa5, 0x01, 0xdd, 0x95, 0x17, 0x14, 0xb1, 0x07, 0xcc, 0x73, 0x27, 0xe6,
0xe9, 0x22, 0x74, 0x1d, 0x9f, 0x78, 0xe6, 0x4d, 0x15, 0x0f, 0x90, 0xa6, 0x63, 0x65, 0x91, 0xe7, 0x07, 0xea, 0x6b, 0x51, 0x1a, 0xf6, 0x3c, 0x77, 0x82, 0xd6, 0xc1, 0x50, 0xba, 0x08, 0x9c, 0xa1,
0x10, 0x47, 0x23, 0x34, 0xdf, 0xbf, 0xf8, 0x1c, 0xf4, 0x62, 0x97, 0xe7, 0xa0, 0x39, 0xe8, 0xa7, 0x47, 0x5c, 0xf3, 0x96, 0xda, 0x0f, 0x90, 0xa6, 0xbe, 0xb2, 0xc8, 0x73, 0x88, 0x76, 0x23, 0x30,
0x00, 0x01, 0x77, 0x67, 0xae, 0x47, 0x1d, 0x1a, 0x9a, 0xb7, 0xd4, 0xa6, 0xb7, 0x73, 0x5f, 0xa6, 0x6f, 0x5f, 0x7d, 0x0e, 0x7a, 0xb2, 0xd3, 0x73, 0xd0, 0x1c, 0xf4, 0x33, 0x00, 0x9f, 0x3b, 0x27,
0x14, 0x85, 0x33, 0x8c, 0xc6, 0xe7, 0x60, 0x64, 0xb2, 0x4d, 0x66, 0xc9, 0x19, 0x9d, 0xeb, 0x04, 0x8e, 0x4b, 0x87, 0x34, 0x30, 0xef, 0xa8, 0x45, 0xaf, 0x65, 0xde, 0x4c, 0x09, 0x0a, 0xa7, 0x18,
0x96, 0x4d, 0x19, 0x92, 0x19, 0xf1, 0xa2, 0xf8, 0x32, 0xab, 0xe2, 0xb8, 0xf3, 0xc5, 0xfa, 0x83, 0xa8, 0x01, 0x79, 0xc7, 0x73, 0x84, 0xf9, 0xa1, 0xbe, 0x95, 0x2e, 0x4b, 0xb5, 0xc5, 0x98, 0x7b,
0x42, 0x63, 0x0f, 0x8c, 0x8c, 0xea, 0xd0, 0x87, 0xf2, 0xf6, 0x73, 0xdc, 0x50, 0xf0, 0xf9, 0x88, 0x40, 0xdc, 0x90, 0x62, 0x85, 0x43, 0x5d, 0x28, 0x39, 0x01, 0x73, 0x95, 0x7c, 0x4d, 0x53, 0xe5,
0x44, 0x62, 0x62, 0xfe, 0x5c, 0x11, 0x6a, 0x89, 0xb1, 0x1b, 0x89, 0x49, 0x63, 0x04, 0xcb, 0xc3, 0xb7, 0x77, 0x38, 0xbf, 0x6e, 0x4c, 0xc1, 0x53, 0x76, 0xf5, 0x2b, 0x30, 0x52, 0x81, 0x2e, 0x03,
0x43, 0x4d, 0x30, 0xa4, 0x28, 0x42, 0xca, 0x67, 0x94, 0xcb, 0xca, 0x42, 0xc6, 0x3c, 0x6b, 0x92, 0xf4, 0x98, 0x4e, 0x74, 0xee, 0x90, 0x4d, 0x79, 0x1a, 0x27, 0x72, 0x68, 0x95, 0xdc, 0x4a, 0x38,
0xe2, 0x0d, 0x29, 0xe1, 0xd6, 0x44, 0xdd, 0x1d, 0x55, 0xac, 0x7b, 0xf2, 0x32, 0x48, 0x32, 0x44, 0xea, 0x7c, 0x3d, 0xff, 0x28, 0x57, 0xdd, 0x02, 0x23, 0x25, 0x78, 0xf4, 0xb1, 0x4c, 0xbc, 0x43,
0x5f, 0x06, 0xba, 0xdb, 0xfa, 0x57, 0x01, 0x6a, 0xd9, 0x02, 0x09, 0xed, 0xc7, 0x85, 0x8d, 0xda, 0x27, 0x10, 0x7c, 0x32, 0x20, 0xa1, 0x18, 0x99, 0xbf, 0x50, 0x84, 0x72, 0x6c, 0x6c, 0x86, 0x62,
0xd2, 0xb5, 0xbd, 0xce, 0x55, 0x05, 0x95, 0xba, 0x98, 0xbd, 0x48, 0x3a, 0x7b, 0x22, 0xff, 0x32, 0x54, 0x1d, 0xc0, 0x54, 0x37, 0xa8, 0x06, 0x86, 0xd4, 0x63, 0x40, 0xf9, 0x09, 0xe5, 0xb2, 0xa8,
0x8a, 0x8c, 0x7e, 0x04, 0x9b, 0x01, 0xe3, 0x22, 0xb9, 0xc2, 0xf2, 0x03, 0xcc, 0x78, 0xf2, 0xec, 0x91, 0xc7, 0x9d, 0x36, 0xc9, 0xb8, 0x09, 0x28, 0xe1, 0xd6, 0x48, 0xa5, 0xad, 0x12, 0xd6, 0x3d,
0xc6, 0xe0, 0xd6, 0x04, 0xae, 0xad, 0x7a, 0x43, 0xf7, 0x60, 0xe3, 0xd9, 0xe1, 0xb0, 0xbe, 0xd6, 0x99, 0x87, 0xe2, 0xe0, 0xd4, 0x79, 0x48, 0x77, 0xeb, 0x7f, 0xc9, 0x41, 0x29, 0x59, 0x28, 0xfa,
0xb8, 0xf3, 0xe2, 0x65, 0xf3, 0x3b, 0xab, 0x83, 0xcf, 0x5c, 0x2e, 0x22, 0xe2, 0x1d, 0x0e, 0xd1, 0x02, 0x56, 0xba, 0xfd, 0xbd, 0x67, 0xcd, 0xfd, 0xee, 0xde, 0xee, 0xa0, 0xdd, 0xf9, 0xb6, 0xf9,
0x27, 0xb0, 0xd9, 0x3f, 0x3a, 0xc6, 0xb8, 0x5e, 0x68, 0xec, 0xbc, 0x78, 0xd9, 0xbc, 0xb3, 0x8a, 0xe2, 0xd9, 0x7e, 0x65, 0xae, 0x7a, 0xef, 0xf4, 0xac, 0xb6, 0x3a, 0xcd, 0xa9, 0x31, 0xbc, 0x4d,
0x93, 0x43, 0x2c, 0xf2, 0x6d, 0xcc, 0xc6, 0x69, 0x5d, 0xff, 0xef, 0x75, 0x30, 0xf4, 0xcd, 0xfe, 0x8f, 0x48, 0xe8, 0x8a, 0x59, 0x56, 0x0f, 0xef, 0x6d, 0x77, 0xfa, 0xfd, 0x4a, 0xee, 0x2a, 0x56,
0xae, 0xbf, 0x7e, 0x5b, 0x71, 0xd9, 0x92, 0xa4, 0xec, 0xfa, 0x95, 0xd5, 0x4b, 0x2d, 0x26, 0xe8, 0x8f, 0x33, 0x8b, 0x06, 0x01, 0xda, 0x82, 0xca, 0x94, 0xf5, 0xe4, 0x65, 0xaf, 0x83, 0x0f, 0x2a,
0x33, 0xbe, 0x0b, 0x35, 0x37, 0x98, 0x7d, 0x36, 0xa2, 0x3e, 0x19, 0x7b, 0xba, 0xc4, 0xaf, 0x60, 0xf3, 0xd5, 0x8f, 0x4e, 0xcf, 0x6a, 0xe6, 0x9b, 0xa4, 0x27, 0x13, 0x9f, 0xf2, 0x03, 0xfd, 0x20,
0x43, 0xda, 0x06, 0xb1, 0x49, 0xde, 0x17, 0xae, 0x2f, 0x28, 0xf7, 0x75, 0xf1, 0x5e, 0xc1, 0x69, 0xf8, 0x57, 0x0e, 0xca, 0xe9, 0x7a, 0x12, 0x6d, 0x47, 0x75, 0xa0, 0x3a, 0x86, 0x1b, 0x5b, 0x9b,
0x1f, 0x7d, 0x09, 0x45, 0x37, 0x20, 0x53, 0x5d, 0x72, 0xe5, 0xee, 0xe0, 0x70, 0xd8, 0x7d, 0xa2, 0xd7, 0xd5, 0x9f, 0xea, 0x1e, 0x73, 0x43, 0xe9, 0xf7, 0xb9, 0x7c, 0xfa, 0x29, 0x32, 0xfa, 0x02,
0x35, 0xd8, 0xab, 0x2c, 0xce, 0x77, 0x8a, 0xd2, 0x80, 0x15, 0x0d, 0x6d, 0x27, 0x55, 0x8f, 0x9c, 0x16, 0x7d, 0xc6, 0x45, 0x9c, 0xf1, 0xb3, 0xf5, 0xc8, 0x78, 0x5c, 0xa5, 0x44, 0xe0, 0xfa, 0x08,
0x49, 0xdd, 0xfd, 0x15, 0x9c, 0xb1, 0x48, 0x1d, 0xb9, 0xbe, 0xc3, 0x69, 0x18, 0xaa, 0x57, 0xa0, 0x6e, 0xcc, 0x7a, 0x43, 0x0f, 0x60, 0xe1, 0xa0, 0xdb, 0xab, 0xcc, 0x55, 0xef, 0x9e, 0x9e, 0xd5,
0x82, 0x93, 0x2e, 0x6a, 0x40, 0x59, 0xd7, 0x4e, 0xaa, 0x58, 0xaa, 0xca, 0xba, 0x44, 0x1b, 0x7a, 0x3e, 0x9c, 0xfd, 0x78, 0xe0, 0x70, 0x11, 0x12, 0xb7, 0xdb, 0x43, 0x9f, 0xc1, 0x62, 0x7b, 0xb7,
0x5b, 0x60, 0xc4, 0xd1, 0x18, 0x9d, 0x72, 0x36, 0x6d, 0xfd, 0xa7, 0x08, 0xc6, 0xbe, 0x17, 0x85, 0x8f, 0x71, 0x25, 0x57, 0x5d, 0x3f, 0x3d, 0xab, 0xdd, 0x9d, 0xc5, 0xc9, 0x4f, 0x2c, 0xf4, 0x6c,
0x42, 0x3f, 0x83, 0xef, 0x2c, 0xf8, 0xcf, 0xe1, 0x06, 0x51, 0x5f, 0x49, 0xe2, 0xcb, 0x37, 0x45, 0xcc, 0x0e, 0x93, 0x67, 0xd0, 0xbf, 0xe7, 0xc1, 0xd0, 0x17, 0xe1, 0xfb, 0x7e, 0x29, 0x2f, 0x47,
0x95, 0xa4, 0xfa, 0x00, 0xee, 0xe5, 0xba, 0x4b, 0xc1, 0x71, 0xf9, 0xda, 0x2b, 0x49, 0x9f, 0x66, 0x55, 0x5e, 0x9c, 0xe1, 0xe6, 0xaf, 0x2d, 0xf6, 0xca, 0x11, 0x41, 0xeb, 0xf2, 0x3e, 0x94, 0x1d,
0x01, 0xd7, 0xc9, 0x6b, 0x23, 0xe8, 0x18, 0xb6, 0x18, 0xb7, 0x26, 0x34, 0x14, 0xf1, 0x4b, 0xa4, 0xff, 0xe4, 0xcb, 0x01, 0xf5, 0xc8, 0xa1, 0xab, 0x5f, 0x44, 0x45, 0x6c, 0x48, 0x5b, 0x27, 0x32,
0xbf, 0x5e, 0xb9, 0x9f, 0xf2, 0xa7, 0x59, 0xa0, 0xbe, 0x86, 0xe3, 0xd5, 0xae, 0xfa, 0x40, 0x0f, 0xc9, 0xf4, 0xea, 0x78, 0x82, 0x72, 0x4f, 0xbf, 0x75, 0x8a, 0x38, 0xe9, 0xa3, 0x6f, 0x20, 0xef,
0xa0, 0xc8, 0xc9, 0x69, 0x52, 0x5e, 0xe7, 0x26, 0x09, 0x26, 0xa7, 0x62, 0xc5, 0x85, 0x62, 0xa0, 0xf8, 0x64, 0xac, 0x2b, 0xd4, 0xcc, 0x15, 0x74, 0x7b, 0xcd, 0xe7, 0x3a, 0x6e, 0x5a, 0xc5, 0x8b,
0x5f, 0x02, 0xd8, 0x6e, 0x18, 0x10, 0x61, 0x4d, 0x28, 0xd7, 0x87, 0x9d, 0xbb, 0xc5, 0x7e, 0x8a, 0xf3, 0xf5, 0xbc, 0x34, 0x60, 0x45, 0x43, 0x6b, 0x71, 0x91, 0x28, 0x47, 0x52, 0x57, 0x65, 0x11,
0x5a, 0xf1, 0x92, 0x61, 0xa3, 0xc7, 0x50, 0xb5, 0x48, 0x22, 0xd7, 0xd2, 0xc5, 0xff, 0xd1, 0xfd, 0xa7, 0x2c, 0x52, 0xfb, 0x8e, 0x37, 0xe4, 0x34, 0x08, 0xd4, 0xa5, 0x59, 0xc4, 0x71, 0x17, 0x55,
0xae, 0x76, 0x51, 0x97, 0x2e, 0x16, 0xe7, 0x3b, 0x95, 0xc4, 0x82, 0x2b, 0x16, 0xd1, 0xf2, 0x7d, 0x61, 0x49, 0x97, 0x9a, 0xaa, 0xb6, 0x2c, 0xc9, 0x32, 0x4e, 0x1b, 0x5a, 0xcb, 0x60, 0x44, 0xbb,
0x0c, 0x5b, 0xf2, 0x9f, 0x3a, 0xb2, 0xe9, 0x29, 0x89, 0x3c, 0x11, 0xcb, 0xe4, 0x82, 0x67, 0x45, 0x31, 0x38, 0xe2, 0x6c, 0x5c, 0xff, 0x4f, 0x1e, 0x8c, 0x6d, 0x37, 0x0c, 0x84, 0xae, 0x1a, 0xde,
0x7e, 0x7a, 0xfa, 0x1a, 0xa7, 0xd7, 0x55, 0x13, 0x19, 0x1b, 0xfa, 0x35, 0xdc, 0xa0, 0xbe, 0xc5, 0xdb, 0xe6, 0xbf, 0x84, 0x15, 0xa2, 0x5e, 0xde, 0xc4, 0x93, 0x57, 0xb0, 0xaa, 0xe0, 0xf5, 0x01,
0xe7, 0x4a, 0xac, 0xc9, 0x0a, 0x2b, 0x17, 0x6f, 0x76, 0x90, 0x82, 0x57, 0x36, 0x5b, 0xa7, 0xaf, 0x3c, 0xc8, 0x74, 0x97, 0x80, 0xa3, 0x6a, 0xbf, 0x55, 0x90, 0x3e, 0xcd, 0x1c, 0xae, 0x90, 0x4b,
0xd9, 0x5b, 0xff, 0x28, 0x00, 0xc4, 0x2f, 0xf5, 0xbb, 0x15, 0x20, 0x82, 0xa2, 0x4d, 0x04, 0x51, 0x5f, 0x50, 0x1f, 0x96, 0x19, 0xb7, 0x46, 0x34, 0x10, 0xd1, 0xc5, 0xad, 0x5f, 0xaa, 0x99, 0xff,
0x9a, 0xab, 0x61, 0xd5, 0x46, 0x5f, 0x00, 0x08, 0x3a, 0x0d, 0x3c, 0x22, 0x5c, 0xdf, 0xd1, 0xb2, 0x30, 0xf6, 0xd2, 0x40, 0x7d, 0x6b, 0x45, 0xb3, 0x9d, 0xf5, 0x81, 0x1e, 0x41, 0x9e, 0x93, 0xa3,
0xb9, 0xec, 0x3a, 0xc8, 0xa0, 0xd1, 0x1e, 0x94, 0xf4, 0x27, 0xa8, 0x78, 0x25, 0x4f, 0x23, 0x5b, 0xf8, 0x35, 0x92, 0x19, 0x24, 0x98, 0x1c, 0x89, 0x19, 0x17, 0x8a, 0x81, 0x7e, 0x09, 0x60, 0x3b,
0x7f, 0x29, 0x00, 0xc4, 0xdb, 0xfc, 0xbf, 0xde, 0x5b, 0xcf, 0x7c, 0xf5, 0xed, 0xf6, 0xda, 0xdf, 0x81, 0x4f, 0x84, 0x35, 0xa2, 0x5c, 0x1f, 0x76, 0xe6, 0x12, 0xdb, 0x09, 0x6a, 0xc6, 0x4b, 0x8a,
0xbf, 0xdd, 0x5e, 0xfb, 0xfd, 0x62, 0xbb, 0xf0, 0x6a, 0xb1, 0x5d, 0xf8, 0xdb, 0x62, 0xbb, 0xf0, 0x8d, 0x9e, 0x42, 0xc9, 0x22, 0xb1, 0x5c, 0x0b, 0x57, 0x3f, 0xdf, 0xb7, 0x9b, 0xda, 0x45, 0x45,
0xcf, 0xc5, 0x76, 0x61, 0x5c, 0x52, 0x75, 0xdf, 0x0f, 0xff, 0x1b, 0x00, 0x00, 0xff, 0xff, 0xae, 0xba, 0xb8, 0x38, 0x5f, 0x2f, 0xc6, 0x16, 0x5c, 0xb4, 0x88, 0x96, 0xef, 0x53, 0x58, 0x96, 0xcf,
0x88, 0xf9, 0x3c, 0x5a, 0x14, 0x00, 0x00, 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,
} }

View file

@ -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

View file

@ -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.

View file

@ -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;

View file

@ -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 = api.TaskStatus{
t.Status.Message = message State: newStatus,
t.Status.Timestamp = ptypes.MustTimestampProto(time.Now()) 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.

View file

@ -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)
}) })

View file

@ -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 {

View file

@ -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}

View file

@ -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 SendTimeout time.Duration
TLSCredentials credentials.TransportCredentials // LargeSendTimeout is the timeout on the sending snapshots to other raft
KeyRotator EncryptionKeyRotator // 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,
} }

View file

@ -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() {

View file

@ -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