From f10437130230cc68f246b7acb99f390cc904dabf Mon Sep 17 00:00:00 2001 From: Aaron Lehmann Date: Mon, 12 Jun 2017 10:27:11 -0700 Subject: [PATCH] Vendor swarmkit a4bf013 Signed-off-by: Aaron Lehmann Upstream-commit: 32d7b0f3601258edf94ecf0e2e9018a406846888 Component: engine --- components/engine/vendor.conf | 2 +- .../github.com/docker/swarmkit/agent/agent.go | 20 +- .../docker/swarmkit/agent/config.go | 17 + .../docker/swarmkit/agent/session.go | 2 +- .../swarmkit/api/genericresource/helpers.go | 111 ++ .../swarmkit/api/genericresource/parse.go | 47 + .../genericresource/resource_management.go | 202 ++ .../swarmkit/api/genericresource/string.go | 54 + .../swarmkit/api/genericresource/validate.go | 84 + .../docker/swarmkit/api/objects.pb.go | 248 ++- .../docker/swarmkit/api/objects.proto | 2 + .../docker/swarmkit/api/types.pb.go | 1714 ++++++++++++----- .../docker/swarmkit/api/types.proto | 20 + .../docker/swarmkit/ca/certificates.go | 2 +- .../github.com/docker/swarmkit/ca/config.go | 51 +- .../github.com/docker/swarmkit/ca/external.go | 20 +- .../docker/swarmkit/ca/reconciler.go | 6 +- .../swarmkit/manager/allocator/allocator.go | 80 +- .../drivers_darwin.go | 5 +- .../drivers_ipam.go | 2 +- .../drivers_network_linux.go | 11 +- .../drivers_network_windows.go | 5 +- .../cnmallocator/drivers_unsupported.go | 14 + .../cnmallocator/networkallocator.go | 957 +++++++++ .../portallocator.go | 2 +- .../swarmkit/manager/allocator/network.go | 286 +-- .../networkallocator/drivers_unsupported.go | 10 - .../networkallocator/networkallocator.go | 1018 +--------- .../swarmkit/manager/controlapi/common.go | 8 +- .../swarmkit/manager/controlapi/service.go | 4 + .../docker/swarmkit/manager/manager.go | 12 +- .../constraintenforcer/constraint_enforcer.go | 28 +- .../swarmkit/manager/orchestrator/task.go | 2 +- .../swarmkit/manager/scheduler/filter.go | 19 +- .../swarmkit/manager/scheduler/nodeinfo.go | 35 +- .../swarmkit/manager/scheduler/scheduler.go | 11 +- .../swarmkit/manager/state/raft/raft.go | 2 +- .../github.com/docker/swarmkit/node/node.go | 59 +- .../github.com/docker/swarmkit/vendor.conf | 7 +- 39 files changed, 3468 insertions(+), 1711 deletions(-) create mode 100644 components/engine/vendor/github.com/docker/swarmkit/api/genericresource/helpers.go create mode 100644 components/engine/vendor/github.com/docker/swarmkit/api/genericresource/parse.go create mode 100644 components/engine/vendor/github.com/docker/swarmkit/api/genericresource/resource_management.go create mode 100644 components/engine/vendor/github.com/docker/swarmkit/api/genericresource/string.go create mode 100644 components/engine/vendor/github.com/docker/swarmkit/api/genericresource/validate.go rename components/engine/vendor/github.com/docker/swarmkit/manager/allocator/{networkallocator => cnmallocator}/drivers_darwin.go (65%) rename components/engine/vendor/github.com/docker/swarmkit/manager/allocator/{networkallocator => cnmallocator}/drivers_ipam.go (95%) rename components/engine/vendor/github.com/docker/swarmkit/manager/allocator/{networkallocator => cnmallocator}/drivers_network_linux.go (68%) rename components/engine/vendor/github.com/docker/swarmkit/manager/allocator/{networkallocator => cnmallocator}/drivers_network_windows.go (65%) create mode 100644 components/engine/vendor/github.com/docker/swarmkit/manager/allocator/cnmallocator/drivers_unsupported.go create mode 100644 components/engine/vendor/github.com/docker/swarmkit/manager/allocator/cnmallocator/networkallocator.go rename components/engine/vendor/github.com/docker/swarmkit/manager/allocator/{networkallocator => cnmallocator}/portallocator.go (99%) delete mode 100644 components/engine/vendor/github.com/docker/swarmkit/manager/allocator/networkallocator/drivers_unsupported.go diff --git a/components/engine/vendor.conf b/components/engine/vendor.conf index 184c02dc9b..e524c518ab 100644 --- a/components/engine/vendor.conf +++ b/components/engine/vendor.conf @@ -104,7 +104,7 @@ github.com/containerd/containerd 3addd840653146c90a254301d6c3a663c7fd6429 github.com/tonistiigi/fifo 1405643975692217d6720f8b54aeee1bf2cd5cf4 # cluster -github.com/docker/swarmkit eb07af52aa2216100cff1ad0b13df48daa8914bf +github.com/docker/swarmkit a4bf0135f63fb60f0e76ae81579cde87f580db6e github.com/gogo/protobuf v0.4 github.com/cloudflare/cfssl 7fb22c8cba7ecaf98e4082d22d65800cf45e042a github.com/google/certificate-transparency d90e65c3a07988180c5b1ece71791c0b6506826e diff --git a/components/engine/vendor/github.com/docker/swarmkit/agent/agent.go b/components/engine/vendor/github.com/docker/swarmkit/agent/agent.go index 841048ffe0..dc72fa0407 100644 --- a/components/engine/vendor/github.com/docker/swarmkit/agent/agent.go +++ b/components/engine/vendor/github.com/docker/swarmkit/agent/agent.go @@ -206,6 +206,9 @@ func (a *Agent) run(ctx context.Context) { leaving = a.leaving subscriptions = map[string]context.CancelFunc{} ) + defer func() { + session.close() + }() if err := a.worker.Init(ctx); err != nil { log.G(ctx).WithError(err).Error("worker initialization failed") @@ -314,6 +317,9 @@ func (a *Agent) run(ctx context.Context) { if ready != nil { close(ready) } + if a.config.SessionTracker != nil { + a.config.SessionTracker.SessionEstablished() + } ready = nil registered = nil // we only care about this once per session backoff = 0 // reset backoff @@ -323,6 +329,10 @@ func (a *Agent) run(ctx context.Context) { // but no error was sent. This must be the only place // session.close is called in response to errors, for this to work. if err != nil { + if a.config.SessionTracker != nil { + a.config.SessionTracker.SessionError(err) + } + log.G(ctx).WithError(err).Error("agent: session failed") backoff = initialSessionFailureBackoff + 2*backoff if backoff > maxSessionFailureBackoff { @@ -337,6 +347,14 @@ func (a *Agent) run(ctx context.Context) { // if we're here before <-registered, do nothing for that event registered = nil case <-session.closed: + if a.config.SessionTracker != nil { + if err := a.config.SessionTracker.SessionClosed(); err != nil { + log.G(ctx).WithError(err).Error("agent: exiting") + a.err = err + return + } + } + log.G(ctx).Debugf("agent: rebuild session") // select a session registration delay from backoff range. @@ -365,8 +383,6 @@ func (a *Agent) run(ctx context.Context) { if a.err == nil { a.err = ctx.Err() } - session.close() - return } } diff --git a/components/engine/vendor/github.com/docker/swarmkit/agent/config.go b/components/engine/vendor/github.com/docker/swarmkit/agent/config.go index 70c94ecb65..98d5bf5728 100644 --- a/components/engine/vendor/github.com/docker/swarmkit/agent/config.go +++ b/components/engine/vendor/github.com/docker/swarmkit/agent/config.go @@ -43,6 +43,10 @@ type Config struct { // NodeTLSInfo contains the starting node TLS info to bootstrap into the agent NodeTLSInfo *api.NodeTLSInfo + + // SessionTracker, if provided, will have its SessionClosed and SessionError methods called + // when sessions close and error. + SessionTracker SessionTracker } func (c *Config) validate() error { @@ -64,3 +68,16 @@ func (c *Config) validate() error { return nil } + +// A SessionTracker gets notified when sessions close and error +type SessionTracker interface { + // SessionClosed is called whenever a session is closed - if the function errors, the agent + // will exit with the returned error. Otherwise the agent can continue and rebuild a new session. + SessionClosed() error + + // SessionError is called whenever a session errors + SessionError(err error) + + // SessionEstablished is called whenever a session is established + SessionEstablished() +} diff --git a/components/engine/vendor/github.com/docker/swarmkit/agent/session.go b/components/engine/vendor/github.com/docker/swarmkit/agent/session.go index 36a3a375cb..faa1fa8cac 100644 --- a/components/engine/vendor/github.com/docker/swarmkit/agent/session.go +++ b/components/engine/vendor/github.com/docker/swarmkit/agent/session.go @@ -409,7 +409,7 @@ func (s *session) sendError(err error) { } // close closing session. It should be called only in <-session.errs branch -// of event loop. +// of event loop, or when cleaning up the agent. func (s *session) close() error { s.closeOnce.Do(func() { s.cancel() diff --git a/components/engine/vendor/github.com/docker/swarmkit/api/genericresource/helpers.go b/components/engine/vendor/github.com/docker/swarmkit/api/genericresource/helpers.go new file mode 100644 index 0000000000..f9c22ac6cc --- /dev/null +++ b/components/engine/vendor/github.com/docker/swarmkit/api/genericresource/helpers.go @@ -0,0 +1,111 @@ +package genericresource + +import ( + "github.com/docker/swarmkit/api" +) + +// NewSet creates a set object +func NewSet(key string, vals ...string) []*api.GenericResource { + rs := make([]*api.GenericResource, 0, len(vals)) + + for _, v := range vals { + rs = append(rs, NewString(key, v)) + } + + return rs +} + +// NewString creates a String resource +func NewString(key, val string) *api.GenericResource { + return &api.GenericResource{ + Resource: &api.GenericResource_Str{ + Str: &api.GenericString{ + Kind: key, + Value: val, + }, + }, + } +} + +// NewDiscrete creates a Discrete resource +func NewDiscrete(key string, val int64) *api.GenericResource { + return &api.GenericResource{ + Resource: &api.GenericResource_Discrete{ + Discrete: &api.GenericDiscrete{ + Kind: key, + Value: val, + }, + }, + } +} + +// GetResource returns resources from the "resources" parameter matching the kind key +func GetResource(kind string, resources []*api.GenericResource) []*api.GenericResource { + var res []*api.GenericResource + + for _, r := range resources { + if Kind(r) != kind { + continue + } + + res = append(res, r) + } + + return res +} + +// ConsumeNodeResources removes "res" from nodeAvailableResources +func ConsumeNodeResources(nodeAvailableResources *[]*api.GenericResource, res []*api.GenericResource) { + if nodeAvailableResources == nil { + return + } + + w := 0 + +loop: + for _, na := range *nodeAvailableResources { + for _, r := range res { + if Kind(na) != Kind(r) { + continue + } + + if remove(na, r) { + continue loop + } + // If this wasn't the right element then + // we need to continue + } + + (*nodeAvailableResources)[w] = na + w++ + } + + *nodeAvailableResources = (*nodeAvailableResources)[:w] +} + +// Returns true if the element is to be removed from the list +func remove(na, r *api.GenericResource) bool { + switch tr := r.Resource.(type) { + case *api.GenericResource_Discrete: + if na.GetDiscrete() == nil { + return false // Type change, ignore + } + + na.GetDiscrete().Value -= tr.Discrete.Value + if na.GetDiscrete().Value <= 0 { + return true + } + case *api.GenericResource_Str: + if na.GetStr() == nil { + return false // Type change, ignore + } + + if tr.Str.Value != na.GetStr().Value { + return false // not the right item, ignore + } + + return true + } + + return false +} diff --git a/components/engine/vendor/github.com/docker/swarmkit/api/genericresource/parse.go b/components/engine/vendor/github.com/docker/swarmkit/api/genericresource/parse.go new file mode 100644 index 0000000000..de30908104 --- /dev/null +++ b/components/engine/vendor/github.com/docker/swarmkit/api/genericresource/parse.go @@ -0,0 +1,47 @@ +package genericresource + +import ( + "fmt" + "strconv" + "strings" + + "github.com/docker/swarmkit/api" +) + +func newParseError(format string, args ...interface{}) error { + return fmt.Errorf("could not parse GenericResource: "+format, args...) +} + +// Parse parses the GenericResource resources given by the arguments +func Parse(cmd string) ([]*api.GenericResource, error) { + var rs []*api.GenericResource + + for _, term := range strings.Split(cmd, ";") { + kva := strings.Split(term, "=") + if len(kva) != 2 { + return nil, newParseError("incorrect term %s, missing '=' or malformed expr", term) + } + + key := strings.TrimSpace(kva[0]) + val := strings.TrimSpace(kva[1]) + + u, err := strconv.ParseInt(val, 10, 64) + if err == nil { + if u < 0 { + return nil, newParseError("cannot ask for negative resource %s", key) + } + rs = append(rs, NewDiscrete(key, u)) + continue + } + + if len(val) > 2 && val[0] == '{' && val[len(val)-1] == '}' { + val = val[1 : len(val)-1] + rs = append(rs, NewSet(key, strings.Split(val, ",")...)...) + continue + } + + return nil, newParseError("could not parse expression '%s'", term) + } + + return rs, nil +} diff --git a/components/engine/vendor/github.com/docker/swarmkit/api/genericresource/resource_management.go b/components/engine/vendor/github.com/docker/swarmkit/api/genericresource/resource_management.go new file mode 100644 index 0000000000..217c52051a --- /dev/null +++ b/components/engine/vendor/github.com/docker/swarmkit/api/genericresource/resource_management.go @@ -0,0 +1,202 @@ +package genericresource + +import ( + "fmt" + "github.com/docker/swarmkit/api" +) + +// Claim assigns GenericResources to a task by taking them from the +// node's GenericResource list and storing them in the task's available list +func Claim(nodeAvailableResources, taskAssigned *[]*api.GenericResource, + taskReservations []*api.GenericResource) error { + var resSelected []*api.GenericResource + + for _, res := range taskReservations { + tr := res.GetDiscrete() + if tr == nil { + return fmt.Errorf("task should only hold Discrete type") + } + + // Select the resources + nrs, err := selectNodeResources(*nodeAvailableResources, tr) + if err != nil { + return err + } + + resSelected = append(resSelected, nrs...) + } + + ClaimResources(nodeAvailableResources, taskAssigned, resSelected) + return nil +} + +// ClaimResources adds the specified resources to the task's list +// and removes them from the node's generic resource list +func ClaimResources(nodeAvailableResources, taskAssigned *[]*api.GenericResource, + resSelected []*api.GenericResource) { + *taskAssigned = append(*taskAssigned, resSelected...) + ConsumeNodeResources(nodeAvailableResources, resSelected) +} + +func selectNodeResources(nodeRes []*api.GenericResource, + tr *api.GenericDiscrete) ([]*api.GenericResource, error) { + var nrs []*api.GenericResource + + for _, res := range nodeRes { + if Kind(res) != tr.Kind { + continue + } + + switch nr := res.Resource.(type) { + case *api.GenericResource_Discrete: + if nr.Discrete.Value >= tr.Value && tr.Value != 0 { + nrs = append(nrs, NewDiscrete(tr.Kind, tr.Value)) + } + + return nrs, nil + case *api.GenericResource_Str: + nrs = append(nrs, res.Copy()) + + if int64(len(nrs)) == tr.Value { + return nrs, nil + } + } + } + + if len(nrs) == 0 { + return nil, fmt.Errorf("not enough resources available for task reservations: %+v", tr) + } + + return nrs, nil +} + +// Reclaim adds the resources taken by the task to the node's store +func Reclaim(nodeAvailableResources *[]*api.GenericResource, taskAssigned, nodeRes []*api.GenericResource) error { + err := reclaimResources(nodeAvailableResources, taskAssigned) + if err != nil { + return err + } + + sanitize(nodeRes, nodeAvailableResources) + + return nil +} + +func reclaimResources(nodeAvailableResources *[]*api.GenericResource, taskAssigned []*api.GenericResource) error { + // The node could have been updated + if nodeAvailableResources == nil { + return fmt.Errorf("node no longer has any resources") + } + + for _, res := range taskAssigned { + switch tr := res.Resource.(type) { + case *api.GenericResource_Discrete: + nrs := GetResource(tr.Discrete.Kind, *nodeAvailableResources) + + // If the resource went down to 0 it's no longer in the + // available list + if len(nrs) == 0 { + *nodeAvailableResources = append(*nodeAvailableResources, res.Copy()) + } + + if len(nrs) != 1 { + continue // Type change + } + + nr := nrs[0].GetDiscrete() + if nr == nil { + continue // Type change + } + + nr.Value += tr.Discrete.Value + case *api.GenericResource_Str: + *nodeAvailableResources = append(*nodeAvailableResources, res.Copy()) + } + } + + return nil +} + +// sanitize checks that nodeAvailableResources does not add resources unknown +// to the nodeSpec (nodeRes) or goes over the integer bound specified +// by the spec. +// Note this is because the user is able to update a node's resources +func sanitize(nodeRes []*api.GenericResource, nodeAvailableResources *[]*api.GenericResource) { + // - We add the sanitized resources at the end, after + // having removed the elements from the list + + // - When a set changes to a Discrete we also need + // to make sure that we don't add the Discrete multiple + // time hence, the need of a map to remember that + var sanitized []*api.GenericResource + kindSanitized := make(map[string]struct{}) + w := 0 + + for _, na := range *nodeAvailableResources { + ok, nrs := sanitizeResource(nodeRes, na) + if !ok { + if _, ok = kindSanitized[Kind(na)]; ok { + continue + } + + kindSanitized[Kind(na)] = struct{}{} + sanitized = append(sanitized, nrs...) + + continue + } + + (*nodeAvailableResources)[w] = na + w++ + } + + *nodeAvailableResources = (*nodeAvailableResources)[:w] + *nodeAvailableResources = append(*nodeAvailableResources, sanitized...) +} + +// Returns true if the element is in nodeRes and "sane" +// Returns false if the element isn't in nodeRes and "sane" and the element(s) that should be replacing it +func sanitizeResource(nodeRes []*api.GenericResource, res *api.GenericResource) (ok bool, nrs []*api.GenericResource) { + switch na := res.Resource.(type) { + case *api.GenericResource_Discrete: + nrs := GetResource(na.Discrete.Kind, nodeRes) + + // Type change or removed: reset + if len(nrs) != 1 { + return false, nrs + } + + // Type change: reset + nr := nrs[0].GetDiscrete() + if nr == nil { + return false, nrs + } + + // Amount change: reset + if na.Discrete.Value > nr.Value { + return false, nrs + } + case *api.GenericResource_Str: + nrs := GetResource(na.Str.Kind, nodeRes) + + // Type change + if len(nrs) == 0 { + return false, nrs + } + + for _, nr := range nrs { + // Type change: reset + if nr.GetDiscrete() != nil { + return false, nrs + } + + if na.Str.Value == nr.GetStr().Value { + return true, nil + } + } + + // Removed + return false, nil + } + + return true, nil +} diff --git a/components/engine/vendor/github.com/docker/swarmkit/api/genericresource/string.go b/components/engine/vendor/github.com/docker/swarmkit/api/genericresource/string.go new file mode 100644 index 0000000000..a353853135 --- /dev/null +++ b/components/engine/vendor/github.com/docker/swarmkit/api/genericresource/string.go @@ -0,0 +1,54 @@ +package genericresource + +import ( + "strconv" + "strings" + + "github.com/docker/swarmkit/api" +) + +func discreteToString(d *api.GenericResource_Discrete) string { + return strconv.FormatInt(d.Discrete.Value, 10) +} + +// Kind returns the kind key as a string +func Kind(res *api.GenericResource) string { + switch r := res.Resource.(type) { + case *api.GenericResource_Discrete: + return r.Discrete.Kind + case *api.GenericResource_Str: + return r.Str.Kind + } + + return "" +} + +// Value returns the value key as a string +func Value(res *api.GenericResource) string { + switch res := res.Resource.(type) { + case *api.GenericResource_Discrete: + return discreteToString(res) + case *api.GenericResource_Str: + return res.Str.Value + } + + return "" +} + +// EnvFormat returns the environment string version of the resource +func EnvFormat(res []*api.GenericResource, prefix string) []string { + envs := make(map[string][]string) + for _, v := range res { + key := Kind(v) + val := Value(v) + envs[key] = append(envs[key], val) + } + + env := make([]string, 0, len(res)) + for k, v := range envs { + k = strings.ToUpper(prefix + "_" + k) + env = append(env, k+"="+strings.Join(v, ",")) + } + + return env +} diff --git a/components/engine/vendor/github.com/docker/swarmkit/api/genericresource/validate.go b/components/engine/vendor/github.com/docker/swarmkit/api/genericresource/validate.go new file mode 100644 index 0000000000..98953e107d --- /dev/null +++ b/components/engine/vendor/github.com/docker/swarmkit/api/genericresource/validate.go @@ -0,0 +1,84 @@ +package genericresource + +import ( + "fmt" + "github.com/docker/swarmkit/api" +) + +// ValidateTask validates that the task only uses integers +// for generic resources +func ValidateTask(resources *api.Resources) error { + for _, v := range resources.Generic { + if v.GetDiscrete() != nil { + continue + } + + return fmt.Errorf("invalid argument for resource %s", Kind(v)) + } + + return nil +} + +// HasEnough returns true if node can satisfy the task's GenericResource request +func HasEnough(nodeRes []*api.GenericResource, taskRes *api.GenericResource) (bool, error) { + t := taskRes.GetDiscrete() + if t == nil { + return false, fmt.Errorf("task should only hold Discrete type") + } + + if nodeRes == nil { + return false, nil + } + + nrs := GetResource(t.Kind, nodeRes) + if len(nrs) == 0 { + return false, nil + } + + switch nr := nrs[0].Resource.(type) { + case *api.GenericResource_Discrete: + if t.Value > nr.Discrete.Value { + return false, nil + } + case *api.GenericResource_Str: + if t.Value > int64(len(nrs)) { + return false, nil + } + } + + return true, nil +} + +// HasResource checks if there is enough "res" in the "resources" argument +func HasResource(res *api.GenericResource, resources []*api.GenericResource) bool { + for _, r := range resources { + if Kind(res) != Kind(r) { + continue + } + + switch rtype := r.Resource.(type) { + case *api.GenericResource_Discrete: + if res.GetDiscrete() == nil { + return false + } + + if res.GetDiscrete().Value < rtype.Discrete.Value { + return false + } + + return true + case *api.GenericResource_Str: + if res.GetStr() == nil { + return false + } + + if res.GetStr().Value != rtype.Str.Value { + continue + } + + return true + } + } + + return false +} diff --git a/components/engine/vendor/github.com/docker/swarmkit/api/objects.pb.go b/components/engine/vendor/github.com/docker/swarmkit/api/objects.pb.go index e9c2438502..b6a9389a6d 100644 --- a/components/engine/vendor/github.com/docker/swarmkit/api/objects.pb.go +++ b/components/engine/vendor/github.com/docker/swarmkit/api/objects.pb.go @@ -198,7 +198,8 @@ type Task struct { // such a cluster default or policy-based value. // // If not present, the daemon's default will be used. - LogDriver *Driver `protobuf:"bytes,13,opt,name=log_driver,json=logDriver" json:"log_driver,omitempty"` + LogDriver *Driver `protobuf:"bytes,13,opt,name=log_driver,json=logDriver" json:"log_driver,omitempty"` + AssignedGenericResources []*GenericResource `protobuf:"bytes,15,rep,name=assigned_generic_resources,json=assignedGenericResources" json:"assigned_generic_resources,omitempty"` } func (m *Task) Reset() { *m = Task{} } @@ -529,6 +530,14 @@ func (m *Task) CopyFrom(src interface{}) { m.LogDriver = &Driver{} github_com_docker_swarmkit_api_deepcopy.Copy(m.LogDriver, o.LogDriver) } + if o.AssignedGenericResources != nil { + m.AssignedGenericResources = make([]*GenericResource, len(o.AssignedGenericResources)) + for i := range m.AssignedGenericResources { + m.AssignedGenericResources[i] = &GenericResource{} + github_com_docker_swarmkit_api_deepcopy.Copy(m.AssignedGenericResources[i], o.AssignedGenericResources[i]) + } + } + } func (m *NetworkAttachment) Copy() *NetworkAttachment { @@ -1140,6 +1149,18 @@ func (m *Task) MarshalTo(dAtA []byte) (int, error) { } i += n26 } + if len(m.AssignedGenericResources) > 0 { + for _, msg := range m.AssignedGenericResources { + dAtA[i] = 0x7a + i++ + i = encodeVarintObjects(dAtA, i, uint64(msg.Size())) + n, err := msg.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n + } + } return i, nil } @@ -1771,6 +1792,12 @@ func (m *Task) Size() (n int) { l = m.SpecVersion.Size() n += 1 + l + sovObjects(uint64(l)) } + if len(m.AssignedGenericResources) > 0 { + for _, e := range m.AssignedGenericResources { + l = e.Size() + n += 1 + l + sovObjects(uint64(l)) + } + } return n } @@ -4419,6 +4446,7 @@ func (this *Task) String() string { `Endpoint:` + strings.Replace(fmt.Sprintf("%v", this.Endpoint), "Endpoint", "Endpoint", 1) + `,`, `LogDriver:` + strings.Replace(fmt.Sprintf("%v", this.LogDriver), "Driver", "Driver", 1) + `,`, `SpecVersion:` + strings.Replace(fmt.Sprintf("%v", this.SpecVersion), "Version", "Version", 1) + `,`, + `AssignedGenericResources:` + strings.Replace(fmt.Sprintf("%v", this.AssignedGenericResources), "GenericResource", "GenericResource", 1) + `,`, `}`, }, "") return s @@ -6001,6 +6029,37 @@ func (m *Task) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 15: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AssignedGenericResources", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowObjects + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthObjects + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.AssignedGenericResources = append(m.AssignedGenericResources, &GenericResource{}) + if err := m.AssignedGenericResources[len(m.AssignedGenericResources)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipObjects(dAtA[iNdEx:]) @@ -7630,96 +7689,99 @@ var ( func init() { proto.RegisterFile("objects.proto", fileDescriptorObjects) } var fileDescriptorObjects = []byte{ - // 1451 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x58, 0xcd, 0x6f, 0x1b, 0x45, - 0x14, 0xef, 0xda, 0x1b, 0x7f, 0x3c, 0x27, 0x56, 0x98, 0x86, 0xe0, 0x9a, 0x60, 0x07, 0x57, 0xa0, - 0x0a, 0x55, 0x4e, 0x09, 0x05, 0xa5, 0x81, 0xd2, 0xda, 0x49, 0xd4, 0x5a, 0xa5, 0x34, 0x9a, 0x96, - 0x96, 0x9b, 0x99, 0xec, 0x4e, 0xdd, 0xc5, 0xeb, 0x9d, 0xd5, 0xce, 0xd8, 0xc5, 0x37, 0xce, 0xf9, - 0x07, 0x72, 0xe3, 0xd0, 0x13, 0x77, 0xb8, 0x70, 0xe1, 0xc0, 0xa9, 0x47, 0x4e, 0x88, 0x53, 0x44, - 0xfd, 0x5f, 0x20, 0x71, 0x40, 0x33, 0x3b, 0x6b, 0x6f, 0xea, 0x75, 0x92, 0xa2, 0x2a, 0xe2, 0xe4, - 0xf9, 0xf8, 0xfd, 0xde, 0xd7, 0xbc, 0xf7, 0x66, 0xd6, 0xb0, 0xc0, 0xf6, 0xbe, 0xa5, 0x96, 0xe0, - 0x75, 0x3f, 0x60, 0x82, 0x21, 0x64, 0x33, 0xab, 0x4b, 0x83, 0x3a, 0x7f, 0x4a, 0x82, 0x5e, 0xd7, - 0x11, 0xf5, 0xc1, 0x87, 0xe5, 0x82, 0x18, 0xfa, 0x54, 0x03, 0xca, 0x05, 0xee, 0x53, 0x2b, 0x9a, - 0x54, 0x3b, 0x8c, 0x75, 0x5c, 0xba, 0xa6, 0x66, 0x7b, 0xfd, 0xc7, 0x6b, 0xc2, 0xe9, 0x51, 0x2e, - 0x48, 0xcf, 0xd7, 0x80, 0xa5, 0x0e, 0xeb, 0x30, 0x35, 0x5c, 0x93, 0x23, 0xbd, 0x7a, 0xe1, 0x65, - 0x1a, 0xf1, 0x86, 0x7a, 0xeb, 0xbc, 0xef, 0xf6, 0x3b, 0x8e, 0xb7, 0x16, 0xfe, 0x84, 0x8b, 0xb5, - 0x5f, 0x0c, 0x30, 0xef, 0x52, 0x41, 0xd0, 0xa7, 0x90, 0x1d, 0xd0, 0x80, 0x3b, 0xcc, 0x2b, 0x19, - 0xab, 0xc6, 0xa5, 0xc2, 0xfa, 0xdb, 0xf5, 0x69, 0x7b, 0xeb, 0x0f, 0x43, 0x48, 0xd3, 0x7c, 0x7e, - 0x58, 0x3d, 0x87, 0x23, 0x06, 0xba, 0x06, 0x60, 0x05, 0x94, 0x08, 0x6a, 0xb7, 0x89, 0x28, 0xa5, - 0x14, 0xbf, 0x5c, 0x0f, 0x4d, 0xa9, 0x47, 0xa6, 0xd4, 0x1f, 0x44, 0x1e, 0xe0, 0xbc, 0x46, 0x37, - 0x84, 0xa4, 0xf6, 0x7d, 0x3b, 0xa2, 0xa6, 0x4f, 0xa6, 0x6a, 0x74, 0x43, 0xd4, 0x7e, 0x32, 0xc1, - 0xfc, 0x92, 0xd9, 0x14, 0x2d, 0x43, 0xca, 0xb1, 0x95, 0xd9, 0xf9, 0x66, 0x66, 0x74, 0x58, 0x4d, - 0xb5, 0xb6, 0x71, 0xca, 0xb1, 0xd1, 0x3a, 0x98, 0x3d, 0x2a, 0x88, 0x36, 0xa8, 0x94, 0xe4, 0x90, - 0xf4, 0x5d, 0x7b, 0xa3, 0xb0, 0xe8, 0x13, 0x30, 0xe5, 0x31, 0x68, 0x4b, 0x56, 0x92, 0x38, 0x52, - 0xe7, 0x7d, 0x9f, 0x5a, 0x11, 0x4f, 0xe2, 0xd1, 0x0e, 0x14, 0x6c, 0xca, 0xad, 0xc0, 0xf1, 0x85, - 0x8c, 0xa1, 0xa9, 0xe8, 0x17, 0x67, 0xd1, 0xb7, 0x27, 0x50, 0x1c, 0xe7, 0xa1, 0xcf, 0x20, 0xc3, - 0x05, 0x11, 0x7d, 0x5e, 0x9a, 0x53, 0x12, 0x2a, 0x33, 0x0d, 0x50, 0x28, 0x6d, 0x82, 0xe6, 0xa0, - 0xdb, 0x50, 0xec, 0x11, 0x8f, 0x74, 0x68, 0xd0, 0xd6, 0x52, 0x32, 0x4a, 0xca, 0xbb, 0x89, 0xae, - 0x87, 0xc8, 0x50, 0x10, 0x5e, 0xe8, 0xc5, 0xa7, 0x68, 0x07, 0x80, 0x08, 0x41, 0xac, 0x27, 0x3d, - 0xea, 0x89, 0x52, 0x56, 0x49, 0x79, 0x2f, 0xd1, 0x16, 0x2a, 0x9e, 0xb2, 0xa0, 0xdb, 0x18, 0x83, - 0x71, 0x8c, 0x88, 0x6e, 0x41, 0xc1, 0xa2, 0x81, 0x70, 0x1e, 0x3b, 0x16, 0x11, 0xb4, 0x94, 0x53, - 0x72, 0xaa, 0x49, 0x72, 0xb6, 0x26, 0x30, 0xed, 0x54, 0x9c, 0x89, 0xae, 0x80, 0x19, 0x30, 0x97, - 0x96, 0xf2, 0xab, 0xc6, 0xa5, 0xe2, 0xec, 0x63, 0xc1, 0xcc, 0xa5, 0x58, 0x21, 0x37, 0x97, 0xf7, - 0x0f, 0x6a, 0x08, 0x16, 0x73, 0xc6, 0xa2, 0xa1, 0x52, 0xc3, 0xb8, 0x62, 0x7c, 0x6d, 0x7c, 0x63, - 0xd4, 0xfe, 0x49, 0x43, 0xf6, 0x3e, 0x0d, 0x06, 0x8e, 0xf5, 0x7a, 0x13, 0xe7, 0xda, 0x91, 0xc4, - 0x49, 0xf4, 0x51, 0xab, 0x9d, 0xca, 0x9d, 0x0d, 0xc8, 0x51, 0xcf, 0xf6, 0x99, 0xe3, 0x09, 0x9d, - 0x38, 0x89, 0x0e, 0xee, 0x68, 0x0c, 0x1e, 0xa3, 0xd1, 0x0e, 0x2c, 0x84, 0xf5, 0xd0, 0x3e, 0x92, - 0x35, 0xab, 0x49, 0xf4, 0xaf, 0x14, 0x50, 0x1f, 0xf7, 0x7c, 0x3f, 0x36, 0x43, 0xdb, 0xb0, 0xe0, - 0x07, 0x74, 0xe0, 0xb0, 0x3e, 0x6f, 0x2b, 0x27, 0x32, 0xa7, 0x72, 0x02, 0xcf, 0x47, 0x2c, 0x39, - 0x43, 0x9f, 0xc3, 0xbc, 0x24, 0xb7, 0xa3, 0x3e, 0x02, 0x27, 0xf6, 0x11, 0xac, 0x5a, 0x9e, 0x9e, - 0xa0, 0x7b, 0xf0, 0xe6, 0x11, 0x2b, 0xc6, 0x82, 0x0a, 0x27, 0x0b, 0x3a, 0x1f, 0xb7, 0x44, 0x2f, - 0x6e, 0xa2, 0xfd, 0x83, 0x5a, 0x11, 0xe6, 0xe3, 0x29, 0x50, 0xfb, 0x21, 0x05, 0xb9, 0x28, 0x90, - 0xe8, 0xaa, 0x3e, 0x33, 0x63, 0x76, 0xd4, 0x22, 0xac, 0xf2, 0x37, 0x3c, 0xae, 0xab, 0x30, 0xe7, - 0xb3, 0x40, 0xf0, 0x52, 0x6a, 0x35, 0x3d, 0xab, 0x44, 0x77, 0x59, 0x20, 0xb6, 0x98, 0xf7, 0xd8, - 0xe9, 0xe0, 0x10, 0x8c, 0x1e, 0x41, 0x61, 0xe0, 0x04, 0xa2, 0x4f, 0xdc, 0xb6, 0xe3, 0xf3, 0x52, - 0x5a, 0x71, 0xdf, 0x3f, 0x4e, 0x65, 0xfd, 0x61, 0x88, 0x6f, 0xed, 0x36, 0x8b, 0xa3, 0xc3, 0x2a, - 0x8c, 0xa7, 0x1c, 0x83, 0x16, 0xd5, 0xf2, 0x79, 0xf9, 0x2e, 0xe4, 0xc7, 0x3b, 0xe8, 0x32, 0x80, - 0x17, 0x56, 0x64, 0x7b, 0x9c, 0xd9, 0x0b, 0xa3, 0xc3, 0x6a, 0x5e, 0xd7, 0x69, 0x6b, 0x1b, 0xe7, - 0x35, 0xa0, 0x65, 0x23, 0x04, 0x26, 0xb1, 0xed, 0x40, 0xe5, 0x79, 0x1e, 0xab, 0x71, 0xed, 0xc7, - 0x0c, 0x98, 0x0f, 0x08, 0xef, 0x9e, 0x75, 0x57, 0x95, 0x3a, 0xa7, 0x2a, 0xe3, 0x32, 0x00, 0x0f, - 0xf3, 0x4d, 0xba, 0x63, 0x4e, 0xdc, 0xd1, 0x59, 0x28, 0xdd, 0xd1, 0x80, 0xd0, 0x1d, 0xee, 0x32, - 0xa1, 0x8a, 0xc0, 0xc4, 0x6a, 0x8c, 0x2e, 0x42, 0xd6, 0x63, 0xb6, 0xa2, 0x67, 0x14, 0x1d, 0x46, - 0x87, 0xd5, 0x8c, 0xec, 0x15, 0xad, 0x6d, 0x9c, 0x91, 0x5b, 0x2d, 0x5b, 0xb6, 0x29, 0xe2, 0x79, - 0x4c, 0x10, 0xd9, 0x83, 0xb9, 0x6e, 0x77, 0x89, 0xd9, 0xdf, 0x98, 0xc0, 0xa2, 0x36, 0x15, 0x63, - 0xa2, 0x87, 0x70, 0x3e, 0xb2, 0x37, 0x2e, 0x30, 0xf7, 0x2a, 0x02, 0x91, 0x96, 0x10, 0xdb, 0x89, - 0x5d, 0x0b, 0xf9, 0xd9, 0xd7, 0x82, 0x8a, 0x60, 0xd2, 0xb5, 0xd0, 0x84, 0x05, 0x9b, 0x72, 0x27, - 0xa0, 0xb6, 0x6a, 0x13, 0x54, 0x55, 0x66, 0x71, 0xfd, 0x9d, 0xe3, 0x84, 0x50, 0x3c, 0xaf, 0x39, - 0x6a, 0x86, 0x1a, 0x90, 0xd3, 0x79, 0xc3, 0x4b, 0x05, 0x95, 0xbb, 0xa7, 0xbc, 0x0e, 0xc6, 0xb4, - 0x23, 0x6d, 0x6e, 0xfe, 0x95, 0xda, 0xdc, 0x35, 0x00, 0x97, 0x75, 0xda, 0x76, 0xe0, 0x0c, 0x68, - 0x50, 0x5a, 0xd0, 0x8f, 0x84, 0x04, 0xee, 0xb6, 0x42, 0xe0, 0xbc, 0xcb, 0x3a, 0xe1, 0x70, 0xaa, - 0x29, 0x15, 0x5f, 0xad, 0x29, 0x6d, 0x96, 0xf7, 0x0f, 0x6a, 0xcb, 0xb0, 0x14, 0xef, 0x21, 0x1b, - 0xc6, 0x4d, 0xe3, 0xb6, 0xb1, 0x6b, 0xd4, 0x7e, 0x4b, 0xc1, 0x1b, 0x53, 0x0e, 0xa3, 0x8f, 0x21, - 0xab, 0x5d, 0x3e, 0xee, 0x25, 0xa5, 0x79, 0x38, 0xc2, 0xa2, 0x15, 0xc8, 0xcb, 0xfa, 0xa3, 0x9c, - 0xd3, 0xb0, 0xb3, 0xe4, 0xf1, 0x64, 0x01, 0x95, 0x20, 0x4b, 0x5c, 0x87, 0xc8, 0xbd, 0xb4, 0xda, - 0x8b, 0xa6, 0xa8, 0x0f, 0xcb, 0x61, 0x5c, 0xda, 0x93, 0x7b, 0xb7, 0xcd, 0x7c, 0xc1, 0x4b, 0xa6, - 0x3a, 0xa6, 0x1b, 0xa7, 0x3a, 0x26, 0x1d, 0xb9, 0xc9, 0xc2, 0x3d, 0x5f, 0xf0, 0x1d, 0x4f, 0x04, - 0x43, 0xbc, 0x64, 0x27, 0x6c, 0x95, 0x6f, 0xc1, 0x85, 0x99, 0x14, 0xb4, 0x08, 0xe9, 0x2e, 0x1d, - 0x86, 0xbd, 0x03, 0xcb, 0x21, 0x5a, 0x82, 0xb9, 0x01, 0x71, 0xfb, 0x54, 0xb7, 0x9a, 0x70, 0xb2, - 0x99, 0xda, 0x30, 0x6a, 0xcf, 0x52, 0x90, 0xd5, 0xe6, 0x9c, 0xf5, 0x7d, 0xac, 0xd5, 0x4e, 0x75, - 0x9d, 0xeb, 0x30, 0xaf, 0x43, 0x1a, 0x96, 0x8b, 0x79, 0x62, 0xc2, 0x15, 0x42, 0x7c, 0x58, 0x2a, - 0xd7, 0xc1, 0x74, 0x7c, 0xd2, 0xd3, 0x77, 0x71, 0xa2, 0xe6, 0xd6, 0x6e, 0xe3, 0xee, 0x3d, 0x3f, - 0xac, 0xfa, 0xdc, 0xe8, 0xb0, 0x6a, 0xca, 0x05, 0xac, 0x68, 0x89, 0xb7, 0xd6, 0xcf, 0x73, 0x90, - 0xdd, 0x72, 0xfb, 0x5c, 0xd0, 0xe0, 0xac, 0x83, 0xa4, 0xd5, 0x4e, 0x05, 0x69, 0x0b, 0xb2, 0x01, - 0x63, 0xa2, 0x6d, 0x91, 0xe3, 0xe2, 0x83, 0x19, 0x13, 0x5b, 0x8d, 0x66, 0x51, 0x12, 0x65, 0xe3, - 0x0d, 0xe7, 0x38, 0x23, 0xa9, 0x5b, 0x04, 0x3d, 0x82, 0xe5, 0xe8, 0xba, 0xda, 0x63, 0x4c, 0x70, - 0x11, 0x10, 0xbf, 0xdd, 0xa5, 0x43, 0xf9, 0x90, 0x49, 0xcf, 0x7a, 0xb8, 0xee, 0x78, 0x56, 0x30, - 0x54, 0xc1, 0xbb, 0x43, 0x87, 0x78, 0x49, 0x0b, 0x68, 0x46, 0xfc, 0x3b, 0x74, 0xc8, 0xd1, 0x0d, - 0x58, 0xa1, 0x63, 0x98, 0x94, 0xd8, 0x76, 0x49, 0x4f, 0x5e, 0xc4, 0x6d, 0xcb, 0x65, 0x56, 0x57, - 0xdd, 0x05, 0x26, 0xbe, 0x40, 0xe3, 0xa2, 0xbe, 0x08, 0x11, 0x5b, 0x12, 0x80, 0x38, 0x94, 0xf6, - 0x5c, 0x62, 0x75, 0x5d, 0x87, 0xcb, 0x6f, 0x93, 0xd8, 0x5b, 0x54, 0xb6, 0x73, 0x69, 0xdb, 0xc6, - 0x31, 0xd1, 0xaa, 0x37, 0x27, 0xdc, 0xd8, 0xcb, 0x56, 0x57, 0xd4, 0x5b, 0x7b, 0xc9, 0xbb, 0xa8, - 0x09, 0x85, 0xbe, 0x27, 0xd5, 0x87, 0x31, 0xc8, 0x9f, 0x36, 0x06, 0x10, 0xb2, 0xa4, 0xe7, 0xe5, - 0x01, 0xac, 0x1c, 0xa7, 0x3c, 0xa1, 0x36, 0x6f, 0xc6, 0x6b, 0xb3, 0xb0, 0xfe, 0x41, 0x92, 0xbe, - 0x64, 0x91, 0xb1, 0x3a, 0x4e, 0x4c, 0xdb, 0x5f, 0x0d, 0xc8, 0xdc, 0xa7, 0x56, 0x40, 0xc5, 0x6b, - 0xcd, 0xda, 0x8d, 0x23, 0x59, 0x5b, 0x49, 0x7e, 0xa5, 0x4a, 0xad, 0x53, 0x49, 0x5b, 0x86, 0x9c, - 0xe3, 0x09, 0x1a, 0x78, 0xc4, 0x55, 0x59, 0x9b, 0xc3, 0xe3, 0x79, 0xa2, 0x03, 0xcf, 0x0c, 0xc8, - 0x84, 0xcf, 0xb8, 0xb3, 0x76, 0x20, 0xd4, 0xfa, 0xb2, 0x03, 0x89, 0x46, 0xfe, 0x6d, 0x40, 0x0e, - 0x53, 0xce, 0xfa, 0xc1, 0x6b, 0xfe, 0xa4, 0x79, 0xe9, 0x59, 0x94, 0xfe, 0xcf, 0xcf, 0x22, 0x04, - 0x66, 0xd7, 0xf1, 0xf4, 0x03, 0x0e, 0xab, 0x31, 0xaa, 0x43, 0xd6, 0x27, 0x43, 0x97, 0x11, 0x5b, - 0x37, 0xca, 0xa5, 0xa9, 0xaf, 0xfe, 0x86, 0x37, 0xc4, 0x11, 0x68, 0x73, 0x69, 0xff, 0xa0, 0xb6, - 0x08, 0xc5, 0xb8, 0xe7, 0x4f, 0x8c, 0xda, 0x1f, 0x06, 0xe4, 0x77, 0xbe, 0x13, 0xd4, 0x53, 0x5f, - 0x10, 0xff, 0x4b, 0xe7, 0x57, 0xa7, 0xff, 0x19, 0xc8, 0x1f, 0xf9, 0xe8, 0x4f, 0x3a, 0xd4, 0x66, - 0xe9, 0xf9, 0x8b, 0xca, 0xb9, 0x3f, 0x5f, 0x54, 0xce, 0x7d, 0x3f, 0xaa, 0x18, 0xcf, 0x47, 0x15, - 0xe3, 0xf7, 0x51, 0xc5, 0xf8, 0x6b, 0x54, 0x31, 0xf6, 0x32, 0x2a, 0x3e, 0x1f, 0xfd, 0x1b, 0x00, - 0x00, 0xff, 0xff, 0x1b, 0x47, 0x17, 0xba, 0x5f, 0x12, 0x00, 0x00, + // 1491 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x58, 0xcf, 0x6f, 0x1b, 0x4f, + 0x15, 0xef, 0xda, 0x1b, 0xff, 0x78, 0x4e, 0x4c, 0x98, 0x86, 0xb0, 0x35, 0xc1, 0x0e, 0xae, 0x40, + 0x15, 0xaa, 0x9c, 0x12, 0x0a, 0x4a, 0x03, 0xa5, 0xb5, 0x93, 0xa8, 0xb5, 0x4a, 0x69, 0x34, 0x2d, + 0x2d, 0xb7, 0x65, 0xb2, 0x3b, 0x75, 0x17, 0xaf, 0x77, 0x56, 0x3b, 0x63, 0x17, 0xdf, 0x38, 0x87, + 0x3f, 0x20, 0x37, 0x0e, 0xfd, 0x17, 0xe0, 0xc2, 0x85, 0x03, 0xa7, 0x1e, 0x39, 0x21, 0x4e, 0x11, + 0xf5, 0x7f, 0x81, 0xc4, 0xe1, 0xab, 0x99, 0x9d, 0xb5, 0x37, 0xf1, 0x3a, 0x49, 0xbf, 0xaa, 0xa2, + 0xef, 0x29, 0x33, 0x3b, 0x9f, 0xcf, 0x9b, 0xf7, 0xde, 0xbc, 0x5f, 0x31, 0xac, 0xb0, 0xa3, 0x3f, + 0x50, 0x47, 0xf0, 0x56, 0x18, 0x31, 0xc1, 0x10, 0x72, 0x99, 0xd3, 0xa7, 0x51, 0x8b, 0xbf, 0x27, + 0xd1, 0xa0, 0xef, 0x89, 0xd6, 0xe8, 0x27, 0xb5, 0x8a, 0x18, 0x87, 0x54, 0x03, 0x6a, 0x15, 0x1e, + 0x52, 0x27, 0xd9, 0x34, 0x7a, 0x8c, 0xf5, 0x7c, 0xba, 0xa5, 0x76, 0x47, 0xc3, 0xb7, 0x5b, 0xc2, + 0x1b, 0x50, 0x2e, 0xc8, 0x20, 0xd4, 0x80, 0xb5, 0x1e, 0xeb, 0x31, 0xb5, 0xdc, 0x92, 0x2b, 0xfd, + 0xf5, 0xd6, 0x79, 0x1a, 0x09, 0xc6, 0xfa, 0xe8, 0x66, 0xe8, 0x0f, 0x7b, 0x5e, 0xb0, 0x15, 0xff, + 0x89, 0x3f, 0x36, 0xff, 0x6e, 0x80, 0xf9, 0x9c, 0x0a, 0x82, 0x7e, 0x01, 0xc5, 0x11, 0x8d, 0xb8, + 0xc7, 0x02, 0xcb, 0xd8, 0x34, 0xee, 0x54, 0xb6, 0xbf, 0xd7, 0x9a, 0xd7, 0xb7, 0xf5, 0x3a, 0x86, + 0x74, 0xcc, 0x8f, 0xa7, 0x8d, 0x1b, 0x38, 0x61, 0xa0, 0x07, 0x00, 0x4e, 0x44, 0x89, 0xa0, 0xae, + 0x4d, 0x84, 0x95, 0x53, 0xfc, 0x5a, 0x2b, 0x56, 0xa5, 0x95, 0xa8, 0xd2, 0x7a, 0x95, 0x58, 0x80, + 0xcb, 0x1a, 0xdd, 0x16, 0x92, 0x3a, 0x0c, 0xdd, 0x84, 0x9a, 0xbf, 0x9c, 0xaa, 0xd1, 0x6d, 0xd1, + 0xfc, 0xab, 0x09, 0xe6, 0x6f, 0x98, 0x4b, 0xd1, 0x3a, 0xe4, 0x3c, 0x57, 0xa9, 0x5d, 0xee, 0x14, + 0x26, 0xa7, 0x8d, 0x5c, 0x77, 0x1f, 0xe7, 0x3c, 0x17, 0x6d, 0x83, 0x39, 0xa0, 0x82, 0x68, 0x85, + 0xac, 0x2c, 0x83, 0xa4, 0xed, 0xda, 0x1a, 0x85, 0x45, 0x3f, 0x07, 0x53, 0x3e, 0x83, 0xd6, 0x64, + 0x23, 0x8b, 0x23, 0xef, 0x7c, 0x19, 0x52, 0x27, 0xe1, 0x49, 0x3c, 0x3a, 0x80, 0x8a, 0x4b, 0xb9, + 0x13, 0x79, 0xa1, 0x90, 0x3e, 0x34, 0x15, 0xfd, 0xf6, 0x22, 0xfa, 0xfe, 0x0c, 0x8a, 0xd3, 0x3c, + 0xf4, 0x4b, 0x28, 0x70, 0x41, 0xc4, 0x90, 0x5b, 0x4b, 0x4a, 0x42, 0x7d, 0xa1, 0x02, 0x0a, 0xa5, + 0x55, 0xd0, 0x1c, 0xf4, 0x14, 0xaa, 0x03, 0x12, 0x90, 0x1e, 0x8d, 0x6c, 0x2d, 0xa5, 0xa0, 0xa4, + 0xfc, 0x20, 0xd3, 0xf4, 0x18, 0x19, 0x0b, 0xc2, 0x2b, 0x83, 0xf4, 0x16, 0x1d, 0x00, 0x10, 0x21, + 0x88, 0xf3, 0x6e, 0x40, 0x03, 0x61, 0x15, 0x95, 0x94, 0x1f, 0x66, 0xea, 0x42, 0xc5, 0x7b, 0x16, + 0xf5, 0xdb, 0x53, 0x30, 0x4e, 0x11, 0xd1, 0x13, 0xa8, 0x38, 0x34, 0x12, 0xde, 0x5b, 0xcf, 0x21, + 0x82, 0x5a, 0x25, 0x25, 0xa7, 0x91, 0x25, 0x67, 0x6f, 0x06, 0xd3, 0x46, 0xa5, 0x99, 0xe8, 0x1e, + 0x98, 0x11, 0xf3, 0xa9, 0x55, 0xde, 0x34, 0xee, 0x54, 0x17, 0x3f, 0x0b, 0x66, 0x3e, 0xc5, 0x0a, + 0xb9, 0xbb, 0x7e, 0x7c, 0xd2, 0x44, 0xb0, 0x5a, 0x32, 0x56, 0x0d, 0x15, 0x1a, 0xc6, 0x3d, 0xe3, + 0x77, 0xc6, 0xef, 0x8d, 0xe6, 0xff, 0xf3, 0x50, 0x7c, 0x49, 0xa3, 0x91, 0xe7, 0x7c, 0xd9, 0xc0, + 0x79, 0x70, 0x26, 0x70, 0x32, 0x6d, 0xd4, 0xd7, 0xce, 0xc5, 0xce, 0x0e, 0x94, 0x68, 0xe0, 0x86, + 0xcc, 0x0b, 0x84, 0x0e, 0x9c, 0x4c, 0x03, 0x0f, 0x34, 0x06, 0x4f, 0xd1, 0xe8, 0x00, 0x56, 0xe2, + 0x7c, 0xb0, 0xcf, 0x44, 0xcd, 0x66, 0x16, 0xfd, 0xb7, 0x0a, 0xa8, 0x9f, 0x7b, 0x79, 0x98, 0xda, + 0xa1, 0x7d, 0x58, 0x09, 0x23, 0x3a, 0xf2, 0xd8, 0x90, 0xdb, 0xca, 0x88, 0xc2, 0x95, 0x8c, 0xc0, + 0xcb, 0x09, 0x4b, 0xee, 0xd0, 0xaf, 0x60, 0x59, 0x92, 0xed, 0xa4, 0x8e, 0xc0, 0xa5, 0x75, 0x04, + 0xab, 0x92, 0xa7, 0x37, 0xe8, 0x05, 0x7c, 0xe7, 0x8c, 0x16, 0x53, 0x41, 0x95, 0xcb, 0x05, 0xdd, + 0x4c, 0x6b, 0xa2, 0x3f, 0xee, 0xa2, 0xe3, 0x93, 0x66, 0x15, 0x96, 0xd3, 0x21, 0xd0, 0xfc, 0x4b, + 0x0e, 0x4a, 0x89, 0x23, 0xd1, 0x7d, 0xfd, 0x66, 0xc6, 0x62, 0xaf, 0x25, 0x58, 0x65, 0x6f, 0xfc, + 0x5c, 0xf7, 0x61, 0x29, 0x64, 0x91, 0xe0, 0x56, 0x6e, 0x33, 0xbf, 0x28, 0x45, 0x0f, 0x59, 0x24, + 0xf6, 0x58, 0xf0, 0xd6, 0xeb, 0xe1, 0x18, 0x8c, 0xde, 0x40, 0x65, 0xe4, 0x45, 0x62, 0x48, 0x7c, + 0xdb, 0x0b, 0xb9, 0x95, 0x57, 0xdc, 0x1f, 0x5d, 0x74, 0x65, 0xeb, 0x75, 0x8c, 0xef, 0x1e, 0x76, + 0xaa, 0x93, 0xd3, 0x06, 0x4c, 0xb7, 0x1c, 0x83, 0x16, 0xd5, 0x0d, 0x79, 0xed, 0x39, 0x94, 0xa7, + 0x27, 0xe8, 0x2e, 0x40, 0x10, 0x67, 0xa4, 0x3d, 0x8d, 0xec, 0x95, 0xc9, 0x69, 0xa3, 0xac, 0xf3, + 0xb4, 0xbb, 0x8f, 0xcb, 0x1a, 0xd0, 0x75, 0x11, 0x02, 0x93, 0xb8, 0x6e, 0xa4, 0xe2, 0xbc, 0x8c, + 0xd5, 0xba, 0xf9, 0xe7, 0x22, 0x98, 0xaf, 0x08, 0xef, 0x5f, 0x77, 0x55, 0x95, 0x77, 0xce, 0x65, + 0xc6, 0x5d, 0x00, 0x1e, 0xc7, 0x9b, 0x34, 0xc7, 0x9c, 0x99, 0xa3, 0xa3, 0x50, 0x9a, 0xa3, 0x01, + 0xb1, 0x39, 0xdc, 0x67, 0x42, 0x25, 0x81, 0x89, 0xd5, 0x1a, 0xdd, 0x86, 0x62, 0xc0, 0x5c, 0x45, + 0x2f, 0x28, 0x3a, 0x4c, 0x4e, 0x1b, 0x05, 0x59, 0x2b, 0xba, 0xfb, 0xb8, 0x20, 0x8f, 0xba, 0xae, + 0x2c, 0x53, 0x24, 0x08, 0x98, 0x20, 0xb2, 0x06, 0x73, 0x5d, 0xee, 0x32, 0xa3, 0xbf, 0x3d, 0x83, + 0x25, 0x65, 0x2a, 0xc5, 0x44, 0xaf, 0xe1, 0x66, 0xa2, 0x6f, 0x5a, 0x60, 0xe9, 0x73, 0x04, 0x22, + 0x2d, 0x21, 0x75, 0x92, 0x6a, 0x0b, 0xe5, 0xc5, 0x6d, 0x41, 0x79, 0x30, 0xab, 0x2d, 0x74, 0x60, + 0xc5, 0xa5, 0xdc, 0x8b, 0xa8, 0xab, 0xca, 0x04, 0x55, 0x99, 0x59, 0xdd, 0xfe, 0xfe, 0x45, 0x42, + 0x28, 0x5e, 0xd6, 0x1c, 0xb5, 0x43, 0x6d, 0x28, 0xe9, 0xb8, 0xe1, 0x56, 0x45, 0xc5, 0xee, 0x15, + 0xdb, 0xc1, 0x94, 0x76, 0xa6, 0xcc, 0x2d, 0x7f, 0x56, 0x99, 0x7b, 0x00, 0xe0, 0xb3, 0x9e, 0xed, + 0x46, 0xde, 0x88, 0x46, 0xd6, 0x8a, 0x1e, 0x12, 0x32, 0xb8, 0xfb, 0x0a, 0x81, 0xcb, 0x3e, 0xeb, + 0xc5, 0xcb, 0xb9, 0xa2, 0x54, 0xfd, 0xcc, 0xa2, 0x44, 0xa0, 0x46, 0x38, 0xf7, 0x7a, 0x01, 0x75, + 0xed, 0x1e, 0x0d, 0x68, 0xe4, 0x39, 0x76, 0x44, 0x39, 0x1b, 0x46, 0x0e, 0xe5, 0xd6, 0xb7, 0x94, + 0x27, 0x32, 0xdb, 0xfc, 0x93, 0x18, 0x8c, 0x35, 0x16, 0x5b, 0x89, 0x98, 0x73, 0x07, 0x7c, 0xb7, + 0x76, 0x7c, 0xd2, 0x5c, 0x87, 0xb5, 0x74, 0x99, 0xda, 0x31, 0x1e, 0x1b, 0x4f, 0x8d, 0x43, 0xa3, + 0xf9, 0xcf, 0x1c, 0x7c, 0x7b, 0xce, 0xa7, 0xe8, 0x67, 0x50, 0xd4, 0x5e, 0xbd, 0x68, 0x58, 0xd3, + 0x3c, 0x9c, 0x60, 0xd1, 0x06, 0x94, 0x65, 0x8a, 0x53, 0xce, 0x69, 0x5c, 0xbc, 0xca, 0x78, 0xf6, + 0x01, 0x59, 0x50, 0x24, 0xbe, 0x47, 0xe4, 0x59, 0x5e, 0x9d, 0x25, 0x5b, 0x34, 0x84, 0xf5, 0xd8, + 0xf5, 0xf6, 0xac, 0xb5, 0xdb, 0x2c, 0x14, 0xdc, 0x32, 0x95, 0xfd, 0x8f, 0xae, 0x14, 0x09, 0xfa, + 0x71, 0x66, 0x1f, 0x5e, 0x84, 0x82, 0x1f, 0x04, 0x22, 0x1a, 0xe3, 0x35, 0x37, 0xe3, 0xa8, 0xf6, + 0x04, 0x6e, 0x2d, 0xa4, 0xa0, 0x55, 0xc8, 0xf7, 0xe9, 0x38, 0x2e, 0x4f, 0x58, 0x2e, 0xd1, 0x1a, + 0x2c, 0x8d, 0x88, 0x3f, 0xa4, 0xba, 0x9a, 0xc5, 0x9b, 0xdd, 0xdc, 0x8e, 0xd1, 0xfc, 0x90, 0x83, + 0xa2, 0x56, 0xe7, 0xba, 0x5b, 0xbe, 0xbe, 0x76, 0xae, 0xb0, 0x3d, 0x84, 0x65, 0xed, 0xd2, 0x38, + 0x23, 0xcd, 0x4b, 0x63, 0xba, 0x12, 0xe3, 0xe3, 0x6c, 0x7c, 0x08, 0xa6, 0x17, 0x92, 0x81, 0x6e, + 0xf7, 0x99, 0x37, 0x77, 0x0f, 0xdb, 0xcf, 0x5f, 0x84, 0x71, 0x61, 0x29, 0x4d, 0x4e, 0x1b, 0xa6, + 0xfc, 0x80, 0x15, 0x2d, 0xb3, 0x31, 0xfe, 0x6d, 0x09, 0x8a, 0x7b, 0xfe, 0x90, 0x0b, 0x1a, 0x5d, + 0xb7, 0x93, 0xf4, 0xb5, 0x73, 0x4e, 0xda, 0x83, 0x62, 0xc4, 0x98, 0xb0, 0x1d, 0x72, 0x91, 0x7f, + 0x30, 0x63, 0x62, 0xaf, 0xdd, 0xa9, 0x4a, 0xa2, 0xac, 0xed, 0xf1, 0x1e, 0x17, 0x24, 0x75, 0x8f, + 0xa0, 0x37, 0xb0, 0x9e, 0x74, 0xc4, 0x23, 0xc6, 0x04, 0x17, 0x11, 0x09, 0xed, 0x3e, 0x1d, 0xcb, + 0x59, 0x29, 0xbf, 0x68, 0x36, 0x3e, 0x08, 0x9c, 0x68, 0xac, 0x9c, 0xf7, 0x8c, 0x8e, 0xf1, 0x9a, + 0x16, 0xd0, 0x49, 0xf8, 0xcf, 0xe8, 0x98, 0xa3, 0x47, 0xb0, 0x41, 0xa7, 0x30, 0x29, 0xd1, 0xf6, + 0xc9, 0x40, 0xf6, 0x7a, 0xdb, 0xf1, 0x99, 0xd3, 0x57, 0xed, 0xc6, 0xc4, 0xb7, 0x68, 0x5a, 0xd4, + 0xaf, 0x63, 0xc4, 0x9e, 0x04, 0x20, 0x0e, 0xd6, 0x91, 0x4f, 0x9c, 0xbe, 0xef, 0x71, 0xf9, 0xef, + 0x4f, 0x6a, 0xdc, 0x95, 0x1d, 0x43, 0xea, 0xb6, 0x73, 0x81, 0xb7, 0x5a, 0x9d, 0x19, 0x37, 0x35, + 0x3c, 0xeb, 0x8c, 0xfa, 0xee, 0x51, 0xf6, 0x29, 0xea, 0x40, 0x65, 0x18, 0xc8, 0xeb, 0x63, 0x1f, + 0x94, 0xaf, 0xea, 0x03, 0x88, 0x59, 0xd2, 0xf2, 0xda, 0x08, 0x36, 0x2e, 0xba, 0x3c, 0x23, 0x37, + 0x1f, 0xa7, 0x73, 0xb3, 0xb2, 0xfd, 0xe3, 0xac, 0xfb, 0xb2, 0x45, 0xa6, 0xf2, 0x38, 0x33, 0x6c, + 0xff, 0x61, 0x40, 0xe1, 0x25, 0x75, 0x22, 0x2a, 0xbe, 0x68, 0xd4, 0xee, 0x9c, 0x89, 0xda, 0x7a, + 0xf6, 0x20, 0x2c, 0x6f, 0x9d, 0x0b, 0xda, 0x1a, 0x94, 0xbc, 0x40, 0xd0, 0x28, 0x20, 0xbe, 0x8a, + 0xda, 0x12, 0x9e, 0xee, 0x33, 0x0d, 0xf8, 0x60, 0x40, 0x21, 0x9e, 0x14, 0xaf, 0xdb, 0x80, 0xf8, + 0xd6, 0xf3, 0x06, 0x64, 0x2a, 0xf9, 0x3f, 0x03, 0x4a, 0x49, 0xc3, 0xfa, 0xa2, 0x6a, 0x9e, 0x9b, + 0xbc, 0xf2, 0x5f, 0x7b, 0xf2, 0x42, 0x60, 0xf6, 0xbd, 0x40, 0xcf, 0x88, 0x58, 0xad, 0x51, 0x0b, + 0x8a, 0x21, 0x19, 0xfb, 0x8c, 0xb8, 0xba, 0x50, 0xae, 0xcd, 0xfd, 0xb0, 0xd0, 0x0e, 0xc6, 0x38, + 0x01, 0xed, 0xae, 0x1d, 0x9f, 0x34, 0x57, 0xa1, 0x9a, 0xb6, 0xfc, 0x9d, 0xd1, 0xfc, 0xb7, 0x01, + 0xe5, 0x83, 0x3f, 0x0a, 0x1a, 0xa8, 0x79, 0xe0, 0x1b, 0x69, 0xfc, 0xe6, 0xfc, 0x8f, 0x0f, 0xe5, + 0x33, 0xbf, 0x2b, 0x64, 0x3d, 0x6a, 0xc7, 0xfa, 0xf8, 0xa9, 0x7e, 0xe3, 0x3f, 0x9f, 0xea, 0x37, + 0xfe, 0x34, 0xa9, 0x1b, 0x1f, 0x27, 0x75, 0xe3, 0x5f, 0x93, 0xba, 0xf1, 0xdf, 0x49, 0xdd, 0x38, + 0x2a, 0x28, 0xff, 0xfc, 0xf4, 0xab, 0x00, 0x00, 0x00, 0xff, 0xff, 0xe4, 0x48, 0xcb, 0x39, 0xc2, + 0x12, 0x00, 0x00, } diff --git a/components/engine/vendor/github.com/docker/swarmkit/api/objects.proto b/components/engine/vendor/github.com/docker/swarmkit/api/objects.proto index 5f7cf26b7f..311c1f2fb6 100644 --- a/components/engine/vendor/github.com/docker/swarmkit/api/objects.proto +++ b/components/engine/vendor/github.com/docker/swarmkit/api/objects.proto @@ -239,6 +239,8 @@ message Task { // // If not present, the daemon's default will be used. Driver log_driver = 13; + + repeated GenericResource assigned_generic_resources = 15; } // NetworkAttachment specifies the network parameters of attachment to diff --git a/components/engine/vendor/github.com/docker/swarmkit/api/types.pb.go b/components/engine/vendor/github.com/docker/swarmkit/api/types.pb.go index 7ff65e47ca..2befc03577 100644 --- a/components/engine/vendor/github.com/docker/swarmkit/api/types.pb.go +++ b/components/engine/vendor/github.com/docker/swarmkit/api/types.pb.go @@ -23,6 +23,9 @@ Version IndexEntry Annotations + GenericString + GenericDiscrete + GenericResource Resources ResourceRequirements Platform @@ -354,7 +357,7 @@ func (x RaftMemberStatus_Reachability) String() string { return proto.EnumName(RaftMemberStatus_Reachability_name, int32(x)) } func (RaftMemberStatus_Reachability) EnumDescriptor() ([]byte, []int) { - return fileDescriptorTypes, []int{10, 0} + return fileDescriptorTypes, []int{13, 0} } // TODO(aluzzardi) These should be using `gogoproto.enumvalue_customname`. @@ -387,7 +390,7 @@ var NodeStatus_State_value = map[string]int32{ func (x NodeStatus_State) String() string { return proto.EnumName(NodeStatus_State_name, int32(x)) } -func (NodeStatus_State) EnumDescriptor() ([]byte, []int) { return fileDescriptorTypes, []int{11, 0} } +func (NodeStatus_State) EnumDescriptor() ([]byte, []int) { return fileDescriptorTypes, []int{14, 0} } type Mount_MountType int32 @@ -411,7 +414,7 @@ var Mount_MountType_value = map[string]int32{ func (x Mount_MountType) String() string { return proto.EnumName(Mount_MountType_name, int32(x)) } -func (Mount_MountType) EnumDescriptor() ([]byte, []int) { return fileDescriptorTypes, []int{13, 0} } +func (Mount_MountType) EnumDescriptor() ([]byte, []int) { return fileDescriptorTypes, []int{16, 0} } type Mount_BindOptions_MountPropagation int32 @@ -445,7 +448,7 @@ func (x Mount_BindOptions_MountPropagation) String() string { return proto.EnumName(Mount_BindOptions_MountPropagation_name, int32(x)) } func (Mount_BindOptions_MountPropagation) EnumDescriptor() ([]byte, []int) { - return fileDescriptorTypes, []int{13, 0, 0} + return fileDescriptorTypes, []int{16, 0, 0} } type RestartPolicy_RestartCondition int32 @@ -471,7 +474,7 @@ func (x RestartPolicy_RestartCondition) String() string { return proto.EnumName(RestartPolicy_RestartCondition_name, int32(x)) } func (RestartPolicy_RestartCondition) EnumDescriptor() ([]byte, []int) { - return fileDescriptorTypes, []int{14, 0} + return fileDescriptorTypes, []int{17, 0} } type UpdateConfig_FailureAction int32 @@ -497,7 +500,7 @@ func (x UpdateConfig_FailureAction) String() string { return proto.EnumName(UpdateConfig_FailureAction_name, int32(x)) } func (UpdateConfig_FailureAction) EnumDescriptor() ([]byte, []int) { - return fileDescriptorTypes, []int{15, 0} + return fileDescriptorTypes, []int{18, 0} } // UpdateOrder controls the order of operations when rolling out an @@ -524,7 +527,7 @@ func (x UpdateConfig_UpdateOrder) String() string { return proto.EnumName(UpdateConfig_UpdateOrder_name, int32(x)) } func (UpdateConfig_UpdateOrder) EnumDescriptor() ([]byte, []int) { - return fileDescriptorTypes, []int{15, 1} + return fileDescriptorTypes, []int{18, 1} } type UpdateStatus_UpdateState int32 @@ -562,7 +565,7 @@ func (x UpdateStatus_UpdateState) String() string { return proto.EnumName(UpdateStatus_UpdateState_name, int32(x)) } func (UpdateStatus_UpdateState) EnumDescriptor() ([]byte, []int) { - return fileDescriptorTypes, []int{16, 0} + return fileDescriptorTypes, []int{19, 0} } // AddressFamily specifies the network address family that @@ -590,7 +593,7 @@ func (x IPAMConfig_AddressFamily) String() string { return proto.EnumName(IPAMConfig_AddressFamily_name, int32(x)) } func (IPAMConfig_AddressFamily) EnumDescriptor() ([]byte, []int) { - return fileDescriptorTypes, []int{21, 0} + return fileDescriptorTypes, []int{24, 0} } type PortConfig_Protocol int32 @@ -612,7 +615,7 @@ var PortConfig_Protocol_value = map[string]int32{ func (x PortConfig_Protocol) String() string { return proto.EnumName(PortConfig_Protocol_name, int32(x)) } -func (PortConfig_Protocol) EnumDescriptor() ([]byte, []int) { return fileDescriptorTypes, []int{22, 0} } +func (PortConfig_Protocol) EnumDescriptor() ([]byte, []int) { return fileDescriptorTypes, []int{25, 0} } // PublishMode controls how ports are published on the swarm. type PortConfig_PublishMode int32 @@ -640,7 +643,7 @@ func (x PortConfig_PublishMode) String() string { return proto.EnumName(PortConfig_PublishMode_name, int32(x)) } func (PortConfig_PublishMode) EnumDescriptor() ([]byte, []int) { - return fileDescriptorTypes, []int{22, 1} + return fileDescriptorTypes, []int{25, 1} } type IssuanceStatus_State int32 @@ -680,7 +683,7 @@ var IssuanceStatus_State_value = map[string]int32{ func (x IssuanceStatus_State) String() string { return proto.EnumName(IssuanceStatus_State_name, int32(x)) } -func (IssuanceStatus_State) EnumDescriptor() ([]byte, []int) { return fileDescriptorTypes, []int{27, 0} } +func (IssuanceStatus_State) EnumDescriptor() ([]byte, []int) { return fileDescriptorTypes, []int{30, 0} } type ExternalCA_CAProtocol int32 @@ -699,7 +702,7 @@ func (x ExternalCA_CAProtocol) String() string { return proto.EnumName(ExternalCA_CAProtocol_name, int32(x)) } func (ExternalCA_CAProtocol) EnumDescriptor() ([]byte, []int) { - return fileDescriptorTypes, []int{29, 0} + return fileDescriptorTypes, []int{32, 0} } // Encryption algorithm that can implemented using this key @@ -720,7 +723,7 @@ func (x EncryptionKey_Algorithm) String() string { return proto.EnumName(EncryptionKey_Algorithm_name, int32(x)) } func (EncryptionKey_Algorithm) EnumDescriptor() ([]byte, []int) { - return fileDescriptorTypes, []int{42, 0} + return fileDescriptorTypes, []int{45, 0} } type MaybeEncryptedRecord_Algorithm int32 @@ -743,7 +746,7 @@ func (x MaybeEncryptedRecord_Algorithm) String() string { return proto.EnumName(MaybeEncryptedRecord_Algorithm_name, int32(x)) } func (MaybeEncryptedRecord_Algorithm) EnumDescriptor() ([]byte, []int) { - return fileDescriptorTypes, []int{49, 0} + return fileDescriptorTypes, []int{52, 0} } // Version tracks the last time an object in the store was updated. @@ -778,16 +781,158 @@ func (m *Annotations) Reset() { *m = Annotations{} } func (*Annotations) ProtoMessage() {} func (*Annotations) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{2} } +type GenericString struct { + Kind string `protobuf:"bytes,1,opt,name=kind,proto3" json:"kind,omitempty"` + Value string `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` +} + +func (m *GenericString) Reset() { *m = GenericString{} } +func (*GenericString) ProtoMessage() {} +func (*GenericString) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{3} } + +type GenericDiscrete struct { + Kind string `protobuf:"bytes,1,opt,name=kind,proto3" json:"kind,omitempty"` + Value int64 `protobuf:"varint,2,opt,name=value,proto3" json:"value,omitempty"` +} + +func (m *GenericDiscrete) Reset() { *m = GenericDiscrete{} } +func (*GenericDiscrete) ProtoMessage() {} +func (*GenericDiscrete) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{4} } + +type GenericResource struct { + // Types that are valid to be assigned to Resource: + // *GenericResource_Str + // *GenericResource_Discrete + Resource isGenericResource_Resource `protobuf_oneof:"resource"` +} + +func (m *GenericResource) Reset() { *m = GenericResource{} } +func (*GenericResource) ProtoMessage() {} +func (*GenericResource) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{5} } + +type isGenericResource_Resource interface { + isGenericResource_Resource() + MarshalTo([]byte) (int, error) + Size() int +} + +type GenericResource_Str struct { + Str *GenericString `protobuf:"bytes,1,opt,name=str,oneof"` +} +type GenericResource_Discrete struct { + Discrete *GenericDiscrete `protobuf:"bytes,2,opt,name=discrete,oneof"` +} + +func (*GenericResource_Str) isGenericResource_Resource() {} +func (*GenericResource_Discrete) isGenericResource_Resource() {} + +func (m *GenericResource) GetResource() isGenericResource_Resource { + if m != nil { + return m.Resource + } + return nil +} + +func (m *GenericResource) GetStr() *GenericString { + if x, ok := m.GetResource().(*GenericResource_Str); ok { + return x.Str + } + return nil +} + +func (m *GenericResource) GetDiscrete() *GenericDiscrete { + if x, ok := m.GetResource().(*GenericResource_Discrete); ok { + return x.Discrete + } + return nil +} + +// XXX_OneofFuncs is for the internal use of the proto package. +func (*GenericResource) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) { + return _GenericResource_OneofMarshaler, _GenericResource_OneofUnmarshaler, _GenericResource_OneofSizer, []interface{}{ + (*GenericResource_Str)(nil), + (*GenericResource_Discrete)(nil), + } +} + +func _GenericResource_OneofMarshaler(msg proto.Message, b *proto.Buffer) error { + m := msg.(*GenericResource) + // resource + switch x := m.Resource.(type) { + case *GenericResource_Str: + _ = b.EncodeVarint(1<<3 | proto.WireBytes) + if err := b.EncodeMessage(x.Str); err != nil { + return err + } + case *GenericResource_Discrete: + _ = b.EncodeVarint(2<<3 | proto.WireBytes) + if err := b.EncodeMessage(x.Discrete); err != nil { + return err + } + case nil: + default: + return fmt.Errorf("GenericResource.Resource has unexpected type %T", x) + } + return nil +} + +func _GenericResource_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error) { + m := msg.(*GenericResource) + switch tag { + case 1: // resource.str + if wire != proto.WireBytes { + return true, proto.ErrInternalBadWireType + } + msg := new(GenericString) + err := b.DecodeMessage(msg) + m.Resource = &GenericResource_Str{msg} + return true, err + case 2: // resource.discrete + if wire != proto.WireBytes { + return true, proto.ErrInternalBadWireType + } + msg := new(GenericDiscrete) + err := b.DecodeMessage(msg) + m.Resource = &GenericResource_Discrete{msg} + return true, err + default: + return false, nil + } +} + +func _GenericResource_OneofSizer(msg proto.Message) (n int) { + m := msg.(*GenericResource) + // resource + switch x := m.Resource.(type) { + case *GenericResource_Str: + s := proto.Size(x.Str) + n += proto.SizeVarint(1<<3 | proto.WireBytes) + n += proto.SizeVarint(uint64(s)) + n += s + case *GenericResource_Discrete: + s := proto.Size(x.Discrete) + n += proto.SizeVarint(2<<3 | proto.WireBytes) + n += proto.SizeVarint(uint64(s)) + n += s + case nil: + default: + panic(fmt.Sprintf("proto: unexpected type %T in oneof", x)) + } + return n +} + type Resources struct { // Amount of CPUs (e.g. 2000000000 = 2 CPU cores) NanoCPUs int64 `protobuf:"varint,1,opt,name=nano_cpus,json=nanoCpus,proto3" json:"nano_cpus,omitempty"` // Amount of memory in bytes. MemoryBytes int64 `protobuf:"varint,2,opt,name=memory_bytes,json=memoryBytes,proto3" json:"memory_bytes,omitempty"` + // User specified resource (e.g: bananas=2;apple={red,yellow,green}) + Generic []*GenericResource `protobuf:"bytes,3,rep,name=generic" json:"generic,omitempty"` } func (m *Resources) Reset() { *m = Resources{} } func (*Resources) ProtoMessage() {} -func (*Resources) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{3} } +func (*Resources) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{6} } type ResourceRequirements struct { Limits *Resources `protobuf:"bytes,1,opt,name=limits" json:"limits,omitempty"` @@ -796,7 +941,7 @@ type ResourceRequirements struct { func (m *ResourceRequirements) Reset() { *m = ResourceRequirements{} } func (*ResourceRequirements) ProtoMessage() {} -func (*ResourceRequirements) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{4} } +func (*ResourceRequirements) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{7} } type Platform struct { // Architecture (e.g. x86_64) @@ -807,7 +952,7 @@ type Platform struct { func (m *Platform) Reset() { *m = Platform{} } func (*Platform) ProtoMessage() {} -func (*Platform) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{5} } +func (*Platform) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{8} } // PluginDescription describes an engine plugin. type PluginDescription struct { @@ -821,7 +966,7 @@ type PluginDescription struct { func (m *PluginDescription) Reset() { *m = PluginDescription{} } func (*PluginDescription) ProtoMessage() {} -func (*PluginDescription) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{6} } +func (*PluginDescription) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{9} } type EngineDescription struct { // Docker daemon version running on the node. @@ -834,7 +979,7 @@ type EngineDescription struct { func (m *EngineDescription) Reset() { *m = EngineDescription{} } func (*EngineDescription) ProtoMessage() {} -func (*EngineDescription) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{7} } +func (*EngineDescription) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{10} } type NodeDescription struct { // Hostname of the node as reported by the agent. @@ -852,7 +997,7 @@ type NodeDescription struct { func (m *NodeDescription) Reset() { *m = NodeDescription{} } func (*NodeDescription) ProtoMessage() {} -func (*NodeDescription) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{8} } +func (*NodeDescription) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{11} } type NodeTLSInfo struct { // Information about which root certs the node trusts @@ -864,7 +1009,7 @@ type NodeTLSInfo struct { func (m *NodeTLSInfo) Reset() { *m = NodeTLSInfo{} } func (*NodeTLSInfo) ProtoMessage() {} -func (*NodeTLSInfo) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{9} } +func (*NodeTLSInfo) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{12} } type RaftMemberStatus struct { Leader bool `protobuf:"varint,1,opt,name=leader,proto3" json:"leader,omitempty"` @@ -874,7 +1019,7 @@ type RaftMemberStatus struct { func (m *RaftMemberStatus) Reset() { *m = RaftMemberStatus{} } func (*RaftMemberStatus) ProtoMessage() {} -func (*RaftMemberStatus) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{10} } +func (*RaftMemberStatus) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{13} } type NodeStatus struct { State NodeStatus_State `protobuf:"varint,1,opt,name=state,proto3,enum=docker.swarmkit.v1.NodeStatus_State" json:"state,omitempty"` @@ -885,7 +1030,7 @@ type NodeStatus struct { func (m *NodeStatus) Reset() { *m = NodeStatus{} } func (*NodeStatus) ProtoMessage() {} -func (*NodeStatus) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{11} } +func (*NodeStatus) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{14} } type Image struct { // reference is a docker image reference. This can include a rpository, tag @@ -896,7 +1041,7 @@ type Image struct { func (m *Image) Reset() { *m = Image{} } func (*Image) ProtoMessage() {} -func (*Image) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{12} } +func (*Image) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{15} } // Mount describes volume mounts for a container. // @@ -931,7 +1076,7 @@ type Mount struct { func (m *Mount) Reset() { *m = Mount{} } func (*Mount) ProtoMessage() {} -func (*Mount) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{13} } +func (*Mount) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{16} } // BindOptions specifies options that are specific to a bind mount. type Mount_BindOptions struct { @@ -941,7 +1086,7 @@ type Mount_BindOptions struct { func (m *Mount_BindOptions) Reset() { *m = Mount_BindOptions{} } func (*Mount_BindOptions) ProtoMessage() {} -func (*Mount_BindOptions) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{13, 0} } +func (*Mount_BindOptions) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{16, 0} } // VolumeOptions contains parameters for mounting the volume. type Mount_VolumeOptions struct { @@ -958,7 +1103,7 @@ type Mount_VolumeOptions struct { func (m *Mount_VolumeOptions) Reset() { *m = Mount_VolumeOptions{} } func (*Mount_VolumeOptions) ProtoMessage() {} -func (*Mount_VolumeOptions) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{13, 1} } +func (*Mount_VolumeOptions) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{16, 1} } type Mount_TmpfsOptions struct { // Size sets the size of the tmpfs, in bytes. @@ -976,7 +1121,7 @@ type Mount_TmpfsOptions struct { func (m *Mount_TmpfsOptions) Reset() { *m = Mount_TmpfsOptions{} } func (*Mount_TmpfsOptions) ProtoMessage() {} -func (*Mount_TmpfsOptions) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{13, 2} } +func (*Mount_TmpfsOptions) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{16, 2} } type RestartPolicy struct { Condition RestartPolicy_RestartCondition `protobuf:"varint,1,opt,name=condition,proto3,enum=docker.swarmkit.v1.RestartPolicy_RestartCondition" json:"condition,omitempty"` @@ -994,7 +1139,7 @@ type RestartPolicy struct { func (m *RestartPolicy) Reset() { *m = RestartPolicy{} } func (*RestartPolicy) ProtoMessage() {} -func (*RestartPolicy) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{14} } +func (*RestartPolicy) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{17} } // UpdateConfig specifies the rate and policy of updates. // TODO(aluzzardi): Consider making this a oneof with RollingStrategy and LockstepStrategy. @@ -1034,7 +1179,7 @@ type UpdateConfig struct { func (m *UpdateConfig) Reset() { *m = UpdateConfig{} } func (*UpdateConfig) ProtoMessage() {} -func (*UpdateConfig) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{15} } +func (*UpdateConfig) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{18} } // UpdateStatus is the status of an update in progress. type UpdateStatus struct { @@ -1058,7 +1203,7 @@ type UpdateStatus struct { func (m *UpdateStatus) Reset() { *m = UpdateStatus{} } func (*UpdateStatus) ProtoMessage() {} -func (*UpdateStatus) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{16} } +func (*UpdateStatus) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{19} } // Container specific status. type ContainerStatus struct { @@ -1069,7 +1214,7 @@ type ContainerStatus struct { func (m *ContainerStatus) Reset() { *m = ContainerStatus{} } func (*ContainerStatus) ProtoMessage() {} -func (*ContainerStatus) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{17} } +func (*ContainerStatus) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{20} } // PortStatus specifies the actual allocated runtime state of a list // of port configs. @@ -1079,7 +1224,7 @@ type PortStatus struct { func (m *PortStatus) Reset() { *m = PortStatus{} } func (*PortStatus) ProtoMessage() {} -func (*PortStatus) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{18} } +func (*PortStatus) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{21} } type TaskStatus struct { // Note: can't use stdtime because this field is nullable. @@ -1116,7 +1261,7 @@ type TaskStatus struct { func (m *TaskStatus) Reset() { *m = TaskStatus{} } func (*TaskStatus) ProtoMessage() {} -func (*TaskStatus) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{19} } +func (*TaskStatus) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{22} } type isTaskStatus_RuntimeStatus interface { isTaskStatus_RuntimeStatus() @@ -1220,7 +1365,7 @@ type NetworkAttachmentConfig struct { func (m *NetworkAttachmentConfig) Reset() { *m = NetworkAttachmentConfig{} } func (*NetworkAttachmentConfig) ProtoMessage() {} -func (*NetworkAttachmentConfig) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{20} } +func (*NetworkAttachmentConfig) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{23} } // IPAMConfig specifies parameters for IP Address Management. type IPAMConfig struct { @@ -1241,7 +1386,7 @@ type IPAMConfig struct { func (m *IPAMConfig) Reset() { *m = IPAMConfig{} } func (*IPAMConfig) ProtoMessage() {} -func (*IPAMConfig) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{21} } +func (*IPAMConfig) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{24} } // PortConfig specifies an exposed port which can be // addressed using the given name. This can be later queried @@ -1267,7 +1412,7 @@ type PortConfig struct { func (m *PortConfig) Reset() { *m = PortConfig{} } func (*PortConfig) ProtoMessage() {} -func (*PortConfig) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{22} } +func (*PortConfig) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{25} } // Driver is a generic driver type to be used throughout the API. For now, a // driver is simply a name and set of options. The field contents depend on the @@ -1280,7 +1425,7 @@ type Driver struct { func (m *Driver) Reset() { *m = Driver{} } func (*Driver) ProtoMessage() {} -func (*Driver) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{23} } +func (*Driver) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{26} } type IPAMOptions struct { Driver *Driver `protobuf:"bytes,1,opt,name=driver" json:"driver,omitempty"` @@ -1289,7 +1434,7 @@ type IPAMOptions struct { func (m *IPAMOptions) Reset() { *m = IPAMOptions{} } func (*IPAMOptions) ProtoMessage() {} -func (*IPAMOptions) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{24} } +func (*IPAMOptions) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{27} } // Peer should be used anywhere where we are describing a remote peer. type Peer struct { @@ -1299,7 +1444,7 @@ type Peer struct { func (m *Peer) Reset() { *m = Peer{} } func (*Peer) ProtoMessage() {} -func (*Peer) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{25} } +func (*Peer) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{28} } // WeightedPeer should be used anywhere where we are describing a remote peer // with a weight. @@ -1310,7 +1455,7 @@ type WeightedPeer struct { func (m *WeightedPeer) Reset() { *m = WeightedPeer{} } func (*WeightedPeer) ProtoMessage() {} -func (*WeightedPeer) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{26} } +func (*WeightedPeer) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{29} } type IssuanceStatus struct { State IssuanceStatus_State `protobuf:"varint,1,opt,name=state,proto3,enum=docker.swarmkit.v1.IssuanceStatus_State" json:"state,omitempty"` @@ -1322,7 +1467,7 @@ type IssuanceStatus struct { func (m *IssuanceStatus) Reset() { *m = IssuanceStatus{} } func (*IssuanceStatus) ProtoMessage() {} -func (*IssuanceStatus) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{27} } +func (*IssuanceStatus) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{30} } type AcceptancePolicy struct { Policies []*AcceptancePolicy_RoleAdmissionPolicy `protobuf:"bytes,1,rep,name=policies" json:"policies,omitempty"` @@ -1330,7 +1475,7 @@ type AcceptancePolicy struct { func (m *AcceptancePolicy) Reset() { *m = AcceptancePolicy{} } func (*AcceptancePolicy) ProtoMessage() {} -func (*AcceptancePolicy) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{28} } +func (*AcceptancePolicy) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{31} } type AcceptancePolicy_RoleAdmissionPolicy struct { Role NodeRole `protobuf:"varint,1,opt,name=role,proto3,enum=docker.swarmkit.v1.NodeRole" json:"role,omitempty"` @@ -1345,7 +1490,7 @@ type AcceptancePolicy_RoleAdmissionPolicy struct { func (m *AcceptancePolicy_RoleAdmissionPolicy) Reset() { *m = AcceptancePolicy_RoleAdmissionPolicy{} } func (*AcceptancePolicy_RoleAdmissionPolicy) ProtoMessage() {} func (*AcceptancePolicy_RoleAdmissionPolicy) Descriptor() ([]byte, []int) { - return fileDescriptorTypes, []int{28, 0} + return fileDescriptorTypes, []int{31, 0} } type AcceptancePolicy_RoleAdmissionPolicy_Secret struct { @@ -1360,7 +1505,7 @@ func (m *AcceptancePolicy_RoleAdmissionPolicy_Secret) Reset() { } func (*AcceptancePolicy_RoleAdmissionPolicy_Secret) ProtoMessage() {} func (*AcceptancePolicy_RoleAdmissionPolicy_Secret) Descriptor() ([]byte, []int) { - return fileDescriptorTypes, []int{28, 0, 0} + return fileDescriptorTypes, []int{31, 0, 0} } type ExternalCA struct { @@ -1377,7 +1522,7 @@ type ExternalCA struct { func (m *ExternalCA) Reset() { *m = ExternalCA{} } func (*ExternalCA) ProtoMessage() {} -func (*ExternalCA) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{29} } +func (*ExternalCA) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{32} } type CAConfig struct { // NodeCertExpiry is the duration certificates should be issued for @@ -1402,7 +1547,7 @@ type CAConfig struct { func (m *CAConfig) Reset() { *m = CAConfig{} } func (*CAConfig) ProtoMessage() {} -func (*CAConfig) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{30} } +func (*CAConfig) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{33} } // OrchestrationConfig defines cluster-level orchestration settings. type OrchestrationConfig struct { @@ -1413,7 +1558,7 @@ type OrchestrationConfig struct { func (m *OrchestrationConfig) Reset() { *m = OrchestrationConfig{} } func (*OrchestrationConfig) ProtoMessage() {} -func (*OrchestrationConfig) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{31} } +func (*OrchestrationConfig) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{34} } // TaskDefaults specifies default values for task creation. type TaskDefaults struct { @@ -1427,7 +1572,7 @@ type TaskDefaults struct { func (m *TaskDefaults) Reset() { *m = TaskDefaults{} } func (*TaskDefaults) ProtoMessage() {} -func (*TaskDefaults) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{32} } +func (*TaskDefaults) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{35} } // DispatcherConfig defines cluster-level dispatcher settings. type DispatcherConfig struct { @@ -1439,7 +1584,7 @@ type DispatcherConfig struct { func (m *DispatcherConfig) Reset() { *m = DispatcherConfig{} } func (*DispatcherConfig) ProtoMessage() {} -func (*DispatcherConfig) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{33} } +func (*DispatcherConfig) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{36} } // RaftConfig defines raft settings for the cluster. type RaftConfig struct { @@ -1461,7 +1606,7 @@ type RaftConfig struct { func (m *RaftConfig) Reset() { *m = RaftConfig{} } func (*RaftConfig) ProtoMessage() {} -func (*RaftConfig) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{34} } +func (*RaftConfig) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{37} } type EncryptionConfig struct { // AutoLockManagers specifies whether or not managers TLS keys and raft data @@ -1472,7 +1617,7 @@ type EncryptionConfig struct { func (m *EncryptionConfig) Reset() { *m = EncryptionConfig{} } func (*EncryptionConfig) ProtoMessage() {} -func (*EncryptionConfig) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{35} } +func (*EncryptionConfig) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{38} } type SpreadOver struct { SpreadDescriptor string `protobuf:"bytes,1,opt,name=spread_descriptor,json=spreadDescriptor,proto3" json:"spread_descriptor,omitempty"` @@ -1480,7 +1625,7 @@ type SpreadOver struct { func (m *SpreadOver) Reset() { *m = SpreadOver{} } func (*SpreadOver) ProtoMessage() {} -func (*SpreadOver) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{36} } +func (*SpreadOver) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{39} } type PlacementPreference struct { // Types that are valid to be assigned to Preference: @@ -1490,7 +1635,7 @@ type PlacementPreference struct { func (m *PlacementPreference) Reset() { *m = PlacementPreference{} } func (*PlacementPreference) ProtoMessage() {} -func (*PlacementPreference) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{37} } +func (*PlacementPreference) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{40} } type isPlacementPreference_Preference interface { isPlacementPreference_Preference() @@ -1589,7 +1734,7 @@ type Placement struct { func (m *Placement) Reset() { *m = Placement{} } func (*Placement) ProtoMessage() {} -func (*Placement) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{38} } +func (*Placement) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{41} } // JoinToken contains the join tokens for workers and managers. type JoinTokens struct { @@ -1601,7 +1746,7 @@ type JoinTokens struct { func (m *JoinTokens) Reset() { *m = JoinTokens{} } func (*JoinTokens) ProtoMessage() {} -func (*JoinTokens) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{39} } +func (*JoinTokens) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{42} } type RootCA struct { // CAKey is the root CA private key. @@ -1622,7 +1767,7 @@ type RootCA struct { func (m *RootCA) Reset() { *m = RootCA{} } func (*RootCA) ProtoMessage() {} -func (*RootCA) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{40} } +func (*RootCA) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{43} } type Certificate struct { Role NodeRole `protobuf:"varint,1,opt,name=role,proto3,enum=docker.swarmkit.v1.NodeRole" json:"role,omitempty"` @@ -1635,7 +1780,7 @@ type Certificate struct { func (m *Certificate) Reset() { *m = Certificate{} } func (*Certificate) ProtoMessage() {} -func (*Certificate) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{41} } +func (*Certificate) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{44} } // Symmetric keys to encrypt inter-agent communication. type EncryptionKey struct { @@ -1651,7 +1796,7 @@ type EncryptionKey struct { func (m *EncryptionKey) Reset() { *m = EncryptionKey{} } func (*EncryptionKey) ProtoMessage() {} -func (*EncryptionKey) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{42} } +func (*EncryptionKey) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{45} } // ManagerStatus provides informations about the state of a manager in the cluster. type ManagerStatus struct { @@ -1668,7 +1813,7 @@ type ManagerStatus struct { func (m *ManagerStatus) Reset() { *m = ManagerStatus{} } func (*ManagerStatus) ProtoMessage() {} -func (*ManagerStatus) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{43} } +func (*ManagerStatus) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{46} } // FileTarget represents a specific target that is backed by a file type FileTarget struct { @@ -1684,7 +1829,7 @@ type FileTarget struct { func (m *FileTarget) Reset() { *m = FileTarget{} } func (*FileTarget) ProtoMessage() {} -func (*FileTarget) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{44} } +func (*FileTarget) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{47} } // SecretReference is the linkage between a service and a secret that it uses. type SecretReference struct { @@ -1704,7 +1849,7 @@ type SecretReference struct { func (m *SecretReference) Reset() { *m = SecretReference{} } func (*SecretReference) ProtoMessage() {} -func (*SecretReference) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{45} } +func (*SecretReference) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{48} } type isSecretReference_Target interface { isSecretReference_Target() @@ -1804,7 +1949,7 @@ type ConfigReference struct { func (m *ConfigReference) Reset() { *m = ConfigReference{} } func (*ConfigReference) ProtoMessage() {} -func (*ConfigReference) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{46} } +func (*ConfigReference) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{49} } type isConfigReference_Target interface { isConfigReference_Target() @@ -1898,7 +2043,7 @@ type BlacklistedCertificate struct { func (m *BlacklistedCertificate) Reset() { *m = BlacklistedCertificate{} } func (*BlacklistedCertificate) ProtoMessage() {} -func (*BlacklistedCertificate) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{47} } +func (*BlacklistedCertificate) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{50} } // HealthConfig holds configuration settings for the HEALTHCHECK feature. type HealthConfig struct { @@ -1928,7 +2073,7 @@ type HealthConfig struct { func (m *HealthConfig) Reset() { *m = HealthConfig{} } func (*HealthConfig) ProtoMessage() {} -func (*HealthConfig) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{48} } +func (*HealthConfig) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{51} } type MaybeEncryptedRecord struct { Algorithm MaybeEncryptedRecord_Algorithm `protobuf:"varint,1,opt,name=algorithm,proto3,enum=docker.swarmkit.v1.MaybeEncryptedRecord_Algorithm" json:"algorithm,omitempty"` @@ -1938,7 +2083,7 @@ type MaybeEncryptedRecord struct { func (m *MaybeEncryptedRecord) Reset() { *m = MaybeEncryptedRecord{} } func (*MaybeEncryptedRecord) ProtoMessage() {} -func (*MaybeEncryptedRecord) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{49} } +func (*MaybeEncryptedRecord) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{52} } type RootRotation struct { CACert []byte `protobuf:"bytes,1,opt,name=ca_cert,json=caCert,proto3" json:"ca_cert,omitempty"` @@ -1949,7 +2094,7 @@ type RootRotation struct { func (m *RootRotation) Reset() { *m = RootRotation{} } func (*RootRotation) ProtoMessage() {} -func (*RootRotation) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{50} } +func (*RootRotation) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{53} } // Privileges specifies security configuration/permissions. type Privileges struct { @@ -1959,7 +2104,7 @@ type Privileges struct { func (m *Privileges) Reset() { *m = Privileges{} } func (*Privileges) ProtoMessage() {} -func (*Privileges) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{51} } +func (*Privileges) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{54} } // CredentialSpec for managed service account (Windows only). type Privileges_CredentialSpec struct { @@ -1972,7 +2117,7 @@ type Privileges_CredentialSpec struct { func (m *Privileges_CredentialSpec) Reset() { *m = Privileges_CredentialSpec{} } func (*Privileges_CredentialSpec) ProtoMessage() {} func (*Privileges_CredentialSpec) Descriptor() ([]byte, []int) { - return fileDescriptorTypes, []int{51, 0} + return fileDescriptorTypes, []int{54, 0} } type isPrivileges_CredentialSpec_Source interface { @@ -2090,13 +2235,16 @@ type Privileges_SELinuxContext struct { func (m *Privileges_SELinuxContext) Reset() { *m = Privileges_SELinuxContext{} } func (*Privileges_SELinuxContext) ProtoMessage() {} func (*Privileges_SELinuxContext) Descriptor() ([]byte, []int) { - return fileDescriptorTypes, []int{51, 1} + return fileDescriptorTypes, []int{54, 1} } func init() { proto.RegisterType((*Version)(nil), "docker.swarmkit.v1.Version") proto.RegisterType((*IndexEntry)(nil), "docker.swarmkit.v1.IndexEntry") proto.RegisterType((*Annotations)(nil), "docker.swarmkit.v1.Annotations") + proto.RegisterType((*GenericString)(nil), "docker.swarmkit.v1.GenericString") + proto.RegisterType((*GenericDiscrete)(nil), "docker.swarmkit.v1.GenericDiscrete") + proto.RegisterType((*GenericResource)(nil), "docker.swarmkit.v1.GenericResource") proto.RegisterType((*Resources)(nil), "docker.swarmkit.v1.Resources") proto.RegisterType((*ResourceRequirements)(nil), "docker.swarmkit.v1.ResourceRequirements") proto.RegisterType((*Platform)(nil), "docker.swarmkit.v1.Platform") @@ -2231,6 +2379,68 @@ func (m *Annotations) CopyFrom(src interface{}) { } +func (m *GenericString) Copy() *GenericString { + if m == nil { + return nil + } + o := &GenericString{} + o.CopyFrom(m) + return o +} + +func (m *GenericString) CopyFrom(src interface{}) { + + o := src.(*GenericString) + *m = *o +} + +func (m *GenericDiscrete) Copy() *GenericDiscrete { + if m == nil { + return nil + } + o := &GenericDiscrete{} + o.CopyFrom(m) + return o +} + +func (m *GenericDiscrete) CopyFrom(src interface{}) { + + o := src.(*GenericDiscrete) + *m = *o +} + +func (m *GenericResource) Copy() *GenericResource { + if m == nil { + return nil + } + o := &GenericResource{} + o.CopyFrom(m) + return o +} + +func (m *GenericResource) CopyFrom(src interface{}) { + + o := src.(*GenericResource) + *m = *o + if o.Resource != nil { + switch o.Resource.(type) { + case *GenericResource_Str: + v := GenericResource_Str{ + Str: &GenericString{}, + } + github_com_docker_swarmkit_api_deepcopy.Copy(v.Str, o.GetStr()) + m.Resource = &v + case *GenericResource_Discrete: + v := GenericResource_Discrete{ + Discrete: &GenericDiscrete{}, + } + github_com_docker_swarmkit_api_deepcopy.Copy(v.Discrete, o.GetDiscrete()) + m.Resource = &v + } + } + +} + func (m *Resources) Copy() *Resources { if m == nil { return nil @@ -2244,6 +2454,14 @@ func (m *Resources) CopyFrom(src interface{}) { o := src.(*Resources) *m = *o + if o.Generic != nil { + m.Generic = make([]*GenericResource, len(o.Generic)) + for i := range m.Generic { + m.Generic[i] = &GenericResource{} + github_com_docker_swarmkit_api_deepcopy.Copy(m.Generic[i], o.Generic[i]) + } + } + } func (m *ResourceRequirements) Copy() *ResourceRequirements { @@ -3544,6 +3762,118 @@ func (m *Annotations) MarshalTo(dAtA []byte) (int, error) { return i, nil } +func (m *GenericString) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *GenericString) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Kind) > 0 { + dAtA[i] = 0xa + i++ + i = encodeVarintTypes(dAtA, i, uint64(len(m.Kind))) + i += copy(dAtA[i:], m.Kind) + } + if len(m.Value) > 0 { + dAtA[i] = 0x12 + i++ + i = encodeVarintTypes(dAtA, i, uint64(len(m.Value))) + i += copy(dAtA[i:], m.Value) + } + return i, nil +} + +func (m *GenericDiscrete) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *GenericDiscrete) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Kind) > 0 { + dAtA[i] = 0xa + i++ + i = encodeVarintTypes(dAtA, i, uint64(len(m.Kind))) + i += copy(dAtA[i:], m.Kind) + } + if m.Value != 0 { + dAtA[i] = 0x10 + i++ + i = encodeVarintTypes(dAtA, i, uint64(m.Value)) + } + return i, nil +} + +func (m *GenericResource) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *GenericResource) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Resource != nil { + nn1, err := m.Resource.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += nn1 + } + return i, nil +} + +func (m *GenericResource_Str) MarshalTo(dAtA []byte) (int, error) { + i := 0 + if m.Str != nil { + dAtA[i] = 0xa + i++ + i = encodeVarintTypes(dAtA, i, uint64(m.Str.Size())) + n2, err := m.Str.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n2 + } + return i, nil +} +func (m *GenericResource_Discrete) MarshalTo(dAtA []byte) (int, error) { + i := 0 + if m.Discrete != nil { + dAtA[i] = 0x12 + i++ + i = encodeVarintTypes(dAtA, i, uint64(m.Discrete.Size())) + n3, err := m.Discrete.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n3 + } + return i, nil +} func (m *Resources) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -3569,6 +3899,18 @@ func (m *Resources) MarshalTo(dAtA []byte) (int, error) { i++ i = encodeVarintTypes(dAtA, i, uint64(m.MemoryBytes)) } + if len(m.Generic) > 0 { + for _, msg := range m.Generic { + dAtA[i] = 0x1a + i++ + i = encodeVarintTypes(dAtA, i, uint64(msg.Size())) + n, err := msg.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n + } + } return i, nil } @@ -3591,21 +3933,21 @@ func (m *ResourceRequirements) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintTypes(dAtA, i, uint64(m.Limits.Size())) - n1, err := m.Limits.MarshalTo(dAtA[i:]) + n4, err := m.Limits.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n1 + i += n4 } if m.Reservations != nil { dAtA[i] = 0x12 i++ i = encodeVarintTypes(dAtA, i, uint64(m.Reservations.Size())) - n2, err := m.Reservations.MarshalTo(dAtA[i:]) + n5, err := m.Reservations.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n2 + i += n5 } return i, nil } @@ -3748,41 +4090,41 @@ func (m *NodeDescription) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x12 i++ i = encodeVarintTypes(dAtA, i, uint64(m.Platform.Size())) - n3, err := m.Platform.MarshalTo(dAtA[i:]) + n6, err := m.Platform.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n3 + i += n6 } if m.Resources != nil { dAtA[i] = 0x1a i++ i = encodeVarintTypes(dAtA, i, uint64(m.Resources.Size())) - n4, err := m.Resources.MarshalTo(dAtA[i:]) + n7, err := m.Resources.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n4 + i += n7 } if m.Engine != nil { dAtA[i] = 0x22 i++ i = encodeVarintTypes(dAtA, i, uint64(m.Engine.Size())) - n5, err := m.Engine.MarshalTo(dAtA[i:]) + n8, err := m.Engine.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n5 + i += n8 } if m.TLSInfo != nil { dAtA[i] = 0x2a i++ i = encodeVarintTypes(dAtA, i, uint64(m.TLSInfo.Size())) - n6, err := m.TLSInfo.MarshalTo(dAtA[i:]) + n9, err := m.TLSInfo.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n6 + i += n9 } return i, nil } @@ -3967,31 +4309,31 @@ func (m *Mount) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x2a i++ i = encodeVarintTypes(dAtA, i, uint64(m.BindOptions.Size())) - n7, err := m.BindOptions.MarshalTo(dAtA[i:]) + n10, err := m.BindOptions.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n7 + i += n10 } if m.VolumeOptions != nil { dAtA[i] = 0x32 i++ i = encodeVarintTypes(dAtA, i, uint64(m.VolumeOptions.Size())) - n8, err := m.VolumeOptions.MarshalTo(dAtA[i:]) + n11, err := m.VolumeOptions.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n8 + i += n11 } if m.TmpfsOptions != nil { dAtA[i] = 0x3a i++ i = encodeVarintTypes(dAtA, i, uint64(m.TmpfsOptions.Size())) - n9, err := m.TmpfsOptions.MarshalTo(dAtA[i:]) + n12, err := m.TmpfsOptions.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n9 + i += n12 } return i, nil } @@ -4065,11 +4407,11 @@ func (m *Mount_VolumeOptions) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x1a i++ i = encodeVarintTypes(dAtA, i, uint64(m.DriverConfig.Size())) - n10, err := m.DriverConfig.MarshalTo(dAtA[i:]) + n13, err := m.DriverConfig.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n10 + i += n13 } return i, nil } @@ -4126,11 +4468,11 @@ func (m *RestartPolicy) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x12 i++ i = encodeVarintTypes(dAtA, i, uint64(m.Delay.Size())) - n11, err := m.Delay.MarshalTo(dAtA[i:]) + n14, err := m.Delay.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n11 + i += n14 } if m.MaxAttempts != 0 { dAtA[i] = 0x18 @@ -4141,11 +4483,11 @@ func (m *RestartPolicy) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x22 i++ i = encodeVarintTypes(dAtA, i, uint64(m.Window.Size())) - n12, err := m.Window.MarshalTo(dAtA[i:]) + n15, err := m.Window.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n12 + i += n15 } return i, nil } @@ -4173,11 +4515,11 @@ func (m *UpdateConfig) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x12 i++ i = encodeVarintTypes(dAtA, i, uint64(github_com_gogo_protobuf_types.SizeOfStdDuration(m.Delay))) - n13, err := github_com_gogo_protobuf_types.StdDurationMarshalTo(m.Delay, dAtA[i:]) + n16, err := github_com_gogo_protobuf_types.StdDurationMarshalTo(m.Delay, dAtA[i:]) if err != nil { return 0, err } - i += n13 + i += n16 if m.FailureAction != 0 { dAtA[i] = 0x18 i++ @@ -4187,11 +4529,11 @@ func (m *UpdateConfig) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x22 i++ i = encodeVarintTypes(dAtA, i, uint64(m.Monitor.Size())) - n14, err := m.Monitor.MarshalTo(dAtA[i:]) + n17, err := m.Monitor.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n14 + i += n17 } if m.MaxFailureRatio != 0 { dAtA[i] = 0x2d @@ -4230,21 +4572,21 @@ func (m *UpdateStatus) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x12 i++ i = encodeVarintTypes(dAtA, i, uint64(m.StartedAt.Size())) - n15, err := m.StartedAt.MarshalTo(dAtA[i:]) + n18, err := m.StartedAt.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n15 + i += n18 } if m.CompletedAt != nil { dAtA[i] = 0x1a i++ i = encodeVarintTypes(dAtA, i, uint64(m.CompletedAt.Size())) - n16, err := m.CompletedAt.MarshalTo(dAtA[i:]) + n19, err := m.CompletedAt.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n16 + i += n19 } if len(m.Message) > 0 { dAtA[i] = 0x22 @@ -4338,11 +4680,11 @@ func (m *TaskStatus) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintTypes(dAtA, i, uint64(m.Timestamp.Size())) - n17, err := m.Timestamp.MarshalTo(dAtA[i:]) + n20, err := m.Timestamp.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n17 + i += n20 } if m.State != 0 { dAtA[i] = 0x10 @@ -4362,21 +4704,21 @@ func (m *TaskStatus) MarshalTo(dAtA []byte) (int, error) { i += copy(dAtA[i:], m.Err) } if m.RuntimeStatus != nil { - nn18, err := m.RuntimeStatus.MarshalTo(dAtA[i:]) + nn21, err := m.RuntimeStatus.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += nn18 + i += nn21 } if m.PortStatus != nil { dAtA[i] = 0x32 i++ i = encodeVarintTypes(dAtA, i, uint64(m.PortStatus.Size())) - n19, err := m.PortStatus.MarshalTo(dAtA[i:]) + n22, err := m.PortStatus.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n19 + i += n22 } return i, nil } @@ -4387,11 +4729,11 @@ func (m *TaskStatus_Container) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x2a i++ i = encodeVarintTypes(dAtA, i, uint64(m.Container.Size())) - n20, err := m.Container.MarshalTo(dAtA[i:]) + n23, err := m.Container.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n20 + i += n23 } return i, nil } @@ -4628,11 +4970,11 @@ func (m *IPAMOptions) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintTypes(dAtA, i, uint64(m.Driver.Size())) - n21, err := m.Driver.MarshalTo(dAtA[i:]) + n24, err := m.Driver.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n21 + i += n24 } if len(m.Configs) > 0 { for _, msg := range m.Configs { @@ -4698,11 +5040,11 @@ func (m *WeightedPeer) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintTypes(dAtA, i, uint64(m.Peer.Size())) - n22, err := m.Peer.MarshalTo(dAtA[i:]) + n25, err := m.Peer.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n22 + i += n25 } if m.Weight != 0 { dAtA[i] = 0x10 @@ -4805,11 +5147,11 @@ func (m *AcceptancePolicy_RoleAdmissionPolicy) MarshalTo(dAtA []byte) (int, erro dAtA[i] = 0x1a i++ i = encodeVarintTypes(dAtA, i, uint64(m.Secret.Size())) - n23, err := m.Secret.MarshalTo(dAtA[i:]) + n26, err := m.Secret.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n23 + i += n26 } return i, nil } @@ -4915,11 +5257,11 @@ func (m *CAConfig) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintTypes(dAtA, i, uint64(m.NodeCertExpiry.Size())) - n24, err := m.NodeCertExpiry.MarshalTo(dAtA[i:]) + n27, err := m.NodeCertExpiry.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n24 + i += n27 } if len(m.ExternalCAs) > 0 { for _, msg := range m.ExternalCAs { @@ -4995,11 +5337,11 @@ func (m *TaskDefaults) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintTypes(dAtA, i, uint64(m.LogDriver.Size())) - n25, err := m.LogDriver.MarshalTo(dAtA[i:]) + n28, err := m.LogDriver.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n25 + i += n28 } return i, nil } @@ -5023,11 +5365,11 @@ func (m *DispatcherConfig) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintTypes(dAtA, i, uint64(m.HeartbeatPeriod.Size())) - n26, err := m.HeartbeatPeriod.MarshalTo(dAtA[i:]) + n29, err := m.HeartbeatPeriod.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n26 + i += n29 } return i, nil } @@ -5143,11 +5485,11 @@ func (m *PlacementPreference) MarshalTo(dAtA []byte) (int, error) { var l int _ = l if m.Preference != nil { - nn27, err := m.Preference.MarshalTo(dAtA[i:]) + nn30, err := m.Preference.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += nn27 + i += nn30 } return i, nil } @@ -5158,11 +5500,11 @@ func (m *PlacementPreference_Spread) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintTypes(dAtA, i, uint64(m.Spread.Size())) - n28, err := m.Spread.MarshalTo(dAtA[i:]) + n31, err := m.Spread.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n28 + i += n31 } return i, nil } @@ -5289,20 +5631,20 @@ func (m *RootCA) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x22 i++ i = encodeVarintTypes(dAtA, i, uint64(m.JoinTokens.Size())) - n29, err := m.JoinTokens.MarshalTo(dAtA[i:]) + n32, err := m.JoinTokens.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n29 + i += n32 if m.RootRotation != nil { dAtA[i] = 0x2a i++ i = encodeVarintTypes(dAtA, i, uint64(m.RootRotation.Size())) - n30, err := m.RootRotation.MarshalTo(dAtA[i:]) + n33, err := m.RootRotation.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n30 + i += n33 } if m.LastForcedRotation != 0 { dAtA[i] = 0x30 @@ -5341,11 +5683,11 @@ func (m *Certificate) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x1a i++ i = encodeVarintTypes(dAtA, i, uint64(m.Status.Size())) - n31, err := m.Status.MarshalTo(dAtA[i:]) + n34, err := m.Status.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n31 + i += n34 if len(m.Certificate) > 0 { dAtA[i] = 0x22 i++ @@ -5514,11 +5856,11 @@ func (m *SecretReference) MarshalTo(dAtA []byte) (int, error) { i += copy(dAtA[i:], m.SecretName) } if m.Target != nil { - nn32, err := m.Target.MarshalTo(dAtA[i:]) + nn35, err := m.Target.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += nn32 + i += nn35 } return i, nil } @@ -5529,11 +5871,11 @@ func (m *SecretReference_File) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x1a i++ i = encodeVarintTypes(dAtA, i, uint64(m.File.Size())) - n33, err := m.File.MarshalTo(dAtA[i:]) + n36, err := m.File.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n33 + i += n36 } return i, nil } @@ -5565,11 +5907,11 @@ func (m *ConfigReference) MarshalTo(dAtA []byte) (int, error) { i += copy(dAtA[i:], m.ConfigName) } if m.Target != nil { - nn34, err := m.Target.MarshalTo(dAtA[i:]) + nn37, err := m.Target.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += nn34 + i += nn37 } return i, nil } @@ -5580,11 +5922,11 @@ func (m *ConfigReference_File) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x1a i++ i = encodeVarintTypes(dAtA, i, uint64(m.File.Size())) - n35, err := m.File.MarshalTo(dAtA[i:]) + n38, err := m.File.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n35 + i += n38 } return i, nil } @@ -5607,11 +5949,11 @@ func (m *BlacklistedCertificate) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintTypes(dAtA, i, uint64(m.Expiry.Size())) - n36, err := m.Expiry.MarshalTo(dAtA[i:]) + n39, err := m.Expiry.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n36 + i += n39 } return i, nil } @@ -5650,21 +5992,21 @@ func (m *HealthConfig) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x12 i++ i = encodeVarintTypes(dAtA, i, uint64(m.Interval.Size())) - n37, err := m.Interval.MarshalTo(dAtA[i:]) + n40, err := m.Interval.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n37 + i += n40 } if m.Timeout != nil { dAtA[i] = 0x1a i++ i = encodeVarintTypes(dAtA, i, uint64(m.Timeout.Size())) - n38, err := m.Timeout.MarshalTo(dAtA[i:]) + n41, err := m.Timeout.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n38 + i += n41 } if m.Retries != 0 { dAtA[i] = 0x20 @@ -5675,11 +6017,11 @@ func (m *HealthConfig) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x2a i++ i = encodeVarintTypes(dAtA, i, uint64(m.StartPeriod.Size())) - n39, err := m.StartPeriod.MarshalTo(dAtA[i:]) + n42, err := m.StartPeriod.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n39 + i += n42 } return i, nil } @@ -5774,21 +6116,21 @@ func (m *Privileges) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintTypes(dAtA, i, uint64(m.CredentialSpec.Size())) - n40, err := m.CredentialSpec.MarshalTo(dAtA[i:]) + n43, err := m.CredentialSpec.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n40 + i += n43 } if m.SELinuxContext != nil { dAtA[i] = 0x12 i++ i = encodeVarintTypes(dAtA, i, uint64(m.SELinuxContext.Size())) - n41, err := m.SELinuxContext.MarshalTo(dAtA[i:]) + n44, err := m.SELinuxContext.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n41 + i += n44 } return i, nil } @@ -5809,11 +6151,11 @@ func (m *Privileges_CredentialSpec) MarshalTo(dAtA []byte) (int, error) { var l int _ = l if m.Source != nil { - nn42, err := m.Source.MarshalTo(dAtA[i:]) + nn45, err := m.Source.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += nn42 + i += nn45 } return i, nil } @@ -5961,6 +6303,60 @@ func (m *Annotations) Size() (n int) { return n } +func (m *GenericString) Size() (n int) { + var l int + _ = l + l = len(m.Kind) + if l > 0 { + n += 1 + l + sovTypes(uint64(l)) + } + l = len(m.Value) + if l > 0 { + n += 1 + l + sovTypes(uint64(l)) + } + return n +} + +func (m *GenericDiscrete) Size() (n int) { + var l int + _ = l + l = len(m.Kind) + if l > 0 { + n += 1 + l + sovTypes(uint64(l)) + } + if m.Value != 0 { + n += 1 + sovTypes(uint64(m.Value)) + } + return n +} + +func (m *GenericResource) Size() (n int) { + var l int + _ = l + if m.Resource != nil { + n += m.Resource.Size() + } + return n +} + +func (m *GenericResource_Str) Size() (n int) { + var l int + _ = l + if m.Str != nil { + l = m.Str.Size() + n += 1 + l + sovTypes(uint64(l)) + } + return n +} +func (m *GenericResource_Discrete) Size() (n int) { + var l int + _ = l + if m.Discrete != nil { + l = m.Discrete.Size() + n += 1 + l + sovTypes(uint64(l)) + } + return n +} func (m *Resources) Size() (n int) { var l int _ = l @@ -5970,6 +6366,12 @@ func (m *Resources) Size() (n int) { if m.MemoryBytes != 0 { n += 1 + sovTypes(uint64(m.MemoryBytes)) } + if len(m.Generic) > 0 { + for _, e := range m.Generic { + l = e.Size() + n += 1 + l + sovTypes(uint64(l)) + } + } return n } @@ -7056,6 +7458,58 @@ func (this *Annotations) String() string { }, "") return s } +func (this *GenericString) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&GenericString{`, + `Kind:` + fmt.Sprintf("%v", this.Kind) + `,`, + `Value:` + fmt.Sprintf("%v", this.Value) + `,`, + `}`, + }, "") + return s +} +func (this *GenericDiscrete) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&GenericDiscrete{`, + `Kind:` + fmt.Sprintf("%v", this.Kind) + `,`, + `Value:` + fmt.Sprintf("%v", this.Value) + `,`, + `}`, + }, "") + return s +} +func (this *GenericResource) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&GenericResource{`, + `Resource:` + fmt.Sprintf("%v", this.Resource) + `,`, + `}`, + }, "") + return s +} +func (this *GenericResource_Str) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&GenericResource_Str{`, + `Str:` + strings.Replace(fmt.Sprintf("%v", this.Str), "GenericString", "GenericString", 1) + `,`, + `}`, + }, "") + return s +} +func (this *GenericResource_Discrete) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&GenericResource_Discrete{`, + `Discrete:` + strings.Replace(fmt.Sprintf("%v", this.Discrete), "GenericDiscrete", "GenericDiscrete", 1) + `,`, + `}`, + }, "") + return s +} func (this *Resources) String() string { if this == nil { return "nil" @@ -7063,6 +7517,7 @@ func (this *Resources) String() string { s := strings.Join([]string{`&Resources{`, `NanoCPUs:` + fmt.Sprintf("%v", this.NanoCPUs) + `,`, `MemoryBytes:` + fmt.Sprintf("%v", this.MemoryBytes) + `,`, + `Generic:` + strings.Replace(fmt.Sprintf("%v", this.Generic), "GenericResource", "GenericResource", 1) + `,`, `}`, }, "") return s @@ -8258,6 +8713,326 @@ func (m *Annotations) Unmarshal(dAtA []byte) error { } return nil } +func (m *GenericString) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: GenericString: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: GenericString: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Kind", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Kind = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Value = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTypes(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthTypes + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *GenericDiscrete) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: GenericDiscrete: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: GenericDiscrete: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Kind", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Kind = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType) + } + m.Value = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Value |= (int64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipTypes(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthTypes + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *GenericResource) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: GenericResource: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: GenericResource: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Str", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + v := &GenericString{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Resource = &GenericResource_Str{v} + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Discrete", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + v := &GenericDiscrete{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Resource = &GenericResource_Discrete{v} + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTypes(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthTypes + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *Resources) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 @@ -8325,6 +9100,37 @@ func (m *Resources) Unmarshal(dAtA []byte) error { break } } + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Generic", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Generic = append(m.Generic, &GenericResource{}) + if err := m.Generic[len(m.Generic)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipTypes(dAtA[iNdEx:]) @@ -16245,300 +17051,306 @@ var ( func init() { proto.RegisterFile("types.proto", fileDescriptorTypes) } var fileDescriptorTypes = []byte{ - // 4705 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x7a, 0x4d, 0x6c, 0x24, 0xd7, - 0x56, 0xbf, 0xfb, 0xd3, 0xdd, 0xa7, 0xdb, 0x76, 0xf9, 0x8e, 0x33, 0xf1, 0x74, 0x26, 0x76, 0xa7, - 0x92, 0x79, 0xf9, 0x78, 0xf9, 0x77, 0x66, 0x3c, 0x49, 0x34, 0x49, 0xfe, 0x2f, 0x49, 0x7f, 0x79, - 0xdc, 0x6f, 0xec, 0xee, 0xd6, 0xed, 0xf6, 0xcc, 0xcb, 0x02, 0x4a, 0xe5, 0xaa, 0xeb, 0x76, 0xc5, - 0xd5, 0x75, 0x9b, 0xaa, 0x6a, 0x7b, 0x9a, 0x07, 0x62, 0xc4, 0x02, 0x90, 0x57, 0xb0, 0x43, 0x42, - 0x66, 0x03, 0x2b, 0x84, 0xc4, 0x02, 0x24, 0x04, 0x1b, 0x82, 0xc4, 0x22, 0x3b, 0x1e, 0x20, 0xa1, - 0x27, 0x90, 0x0c, 0xf1, 0x82, 0x1d, 0x82, 0xcd, 0x13, 0x1b, 0x90, 0xd0, 0xfd, 0xa8, 0xea, 0x6a, - 0x4f, 0xd9, 0x9e, 0x90, 0xb7, 0xb1, 0xeb, 0x9e, 0xf3, 0x3b, 0xe7, 0xde, 0x7b, 0xee, 0xb9, 0xe7, - 0x9e, 0x73, 0x6f, 0x43, 0xc1, 0x9f, 0x8c, 0x88, 0x57, 0x19, 0xb9, 0xd4, 0xa7, 0x08, 0x99, 0xd4, - 0x38, 0x24, 0x6e, 0xc5, 0x3b, 0xd6, 0xdd, 0xe1, 0xa1, 0xe5, 0x57, 0x8e, 0xee, 0x95, 0xd6, 0x07, - 0x94, 0x0e, 0x6c, 0xf2, 0x1e, 0x47, 0xec, 0x8d, 0xf7, 0xdf, 0xf3, 0xad, 0x21, 0xf1, 0x7c, 0x7d, - 0x38, 0x12, 0x42, 0xa5, 0xb5, 0x8b, 0x00, 0x73, 0xec, 0xea, 0xbe, 0x45, 0x1d, 0xc9, 0x5f, 0x19, - 0xd0, 0x01, 0xe5, 0x9f, 0xef, 0xb1, 0x2f, 0x41, 0x55, 0xd7, 0x61, 0xfe, 0x31, 0x71, 0x3d, 0x8b, - 0x3a, 0x68, 0x05, 0x32, 0x96, 0x63, 0x92, 0xa7, 0xab, 0x89, 0x72, 0xe2, 0xad, 0x34, 0x16, 0x0d, - 0xf5, 0x2e, 0x40, 0x8b, 0x7d, 0x34, 0x1d, 0xdf, 0x9d, 0x20, 0x05, 0x52, 0x87, 0x64, 0xc2, 0x11, - 0x79, 0xcc, 0x3e, 0x19, 0xe5, 0x48, 0xb7, 0x57, 0x93, 0x82, 0x72, 0xa4, 0xdb, 0xea, 0x37, 0x09, - 0x28, 0x54, 0x1d, 0x87, 0xfa, 0xbc, 0x77, 0x0f, 0x21, 0x48, 0x3b, 0xfa, 0x90, 0x48, 0x21, 0xfe, - 0x8d, 0xea, 0x90, 0xb5, 0xf5, 0x3d, 0x62, 0x7b, 0xab, 0xc9, 0x72, 0xea, 0xad, 0xc2, 0xc6, 0xf7, - 0x2b, 0xcf, 0x4f, 0xb9, 0x12, 0x51, 0x52, 0xd9, 0xe6, 0x68, 0x3e, 0x08, 0x2c, 0x45, 0xd1, 0xa7, - 0x30, 0x6f, 0x39, 0xa6, 0x65, 0x10, 0x6f, 0x35, 0xcd, 0xb5, 0xac, 0xc5, 0x69, 0x99, 0x8e, 0xbe, - 0x96, 0xfe, 0xfa, 0x6c, 0x7d, 0x0e, 0x07, 0x42, 0xa5, 0x8f, 0xa0, 0x10, 0x51, 0x1b, 0x33, 0xb7, - 0x15, 0xc8, 0x1c, 0xe9, 0xf6, 0x98, 0xc8, 0xd9, 0x89, 0xc6, 0xc7, 0xc9, 0x07, 0x09, 0xf5, 0x0b, - 0xc8, 0x63, 0xe2, 0xd1, 0xb1, 0x6b, 0x10, 0x0f, 0xbd, 0x0d, 0x79, 0x47, 0x77, 0xa8, 0x66, 0x8c, - 0xc6, 0x1e, 0x17, 0x4f, 0xd5, 0x8a, 0xe7, 0x67, 0xeb, 0xb9, 0xb6, 0xee, 0xd0, 0x7a, 0x77, 0xd7, - 0xc3, 0x39, 0xc6, 0xae, 0x8f, 0xc6, 0x1e, 0x7a, 0x0d, 0x8a, 0x43, 0x32, 0xa4, 0xee, 0x44, 0xdb, - 0x9b, 0xf8, 0xc4, 0xe3, 0x8a, 0x53, 0xb8, 0x20, 0x68, 0x35, 0x46, 0x52, 0x7f, 0x3b, 0x01, 0x2b, - 0x81, 0x6e, 0x4c, 0x7e, 0x69, 0x6c, 0xb9, 0x64, 0x48, 0x1c, 0xdf, 0x43, 0x1f, 0x40, 0xd6, 0xb6, - 0x86, 0x96, 0x2f, 0xfa, 0x28, 0x6c, 0xbc, 0x1a, 0x37, 0xdb, 0x70, 0x54, 0x58, 0x82, 0x51, 0x15, - 0x8a, 0x2e, 0xf1, 0x88, 0x7b, 0x24, 0x2c, 0xc9, 0xbb, 0xbc, 0x56, 0x78, 0x46, 0x44, 0xdd, 0x84, - 0x5c, 0xd7, 0xd6, 0xfd, 0x7d, 0xea, 0x0e, 0x91, 0x0a, 0x45, 0xdd, 0x35, 0x0e, 0x2c, 0x9f, 0x18, - 0xfe, 0xd8, 0x0d, 0x56, 0x75, 0x86, 0x86, 0x6e, 0x42, 0x92, 0x8a, 0x8e, 0xf2, 0xb5, 0xec, 0xf9, - 0xd9, 0x7a, 0xb2, 0xd3, 0xc3, 0x49, 0xea, 0xa9, 0x9f, 0xc0, 0x72, 0xd7, 0x1e, 0x0f, 0x2c, 0xa7, - 0x41, 0x3c, 0xc3, 0xb5, 0x46, 0x4c, 0x3b, 0x73, 0x0f, 0xe6, 0xfb, 0x81, 0x7b, 0xb0, 0xef, 0xd0, - 0x65, 0x92, 0x53, 0x97, 0x51, 0x7f, 0x33, 0x09, 0xcb, 0x4d, 0x67, 0x60, 0x39, 0x24, 0x2a, 0x7d, - 0x07, 0x16, 0x09, 0x27, 0x6a, 0x47, 0xc2, 0x8d, 0xa5, 0x9e, 0x05, 0x41, 0x0d, 0x7c, 0xbb, 0x75, - 0xc1, 0xdf, 0xee, 0xc5, 0x4d, 0xff, 0x39, 0xed, 0xb1, 0x5e, 0xd7, 0x84, 0xf9, 0x11, 0x9f, 0x84, - 0xb7, 0x9a, 0xe2, 0xba, 0xee, 0xc4, 0xe9, 0x7a, 0x6e, 0x9e, 0x81, 0xf3, 0x49, 0xd9, 0xef, 0xe2, - 0x7c, 0x7f, 0x9c, 0x84, 0xa5, 0x36, 0x35, 0x67, 0xec, 0x50, 0x82, 0xdc, 0x01, 0xf5, 0xfc, 0xc8, - 0x46, 0x0b, 0xdb, 0xe8, 0x01, 0xe4, 0x46, 0x72, 0xf9, 0xe4, 0xea, 0xdf, 0x8e, 0x1f, 0xb2, 0xc0, - 0xe0, 0x10, 0x8d, 0x3e, 0x81, 0xbc, 0x1b, 0xf8, 0xc4, 0x6a, 0xea, 0x45, 0x1c, 0x67, 0x8a, 0x47, - 0x3f, 0x80, 0xac, 0x58, 0x84, 0xd5, 0x34, 0x97, 0xbc, 0xf3, 0x42, 0x36, 0xc7, 0x52, 0x08, 0x3d, - 0x84, 0x9c, 0x6f, 0x7b, 0x9a, 0xe5, 0xec, 0xd3, 0xd5, 0x0c, 0x57, 0xb0, 0x1e, 0xa7, 0x80, 0x19, - 0xa2, 0xbf, 0xdd, 0x6b, 0x39, 0xfb, 0xb4, 0x56, 0x38, 0x3f, 0x5b, 0x9f, 0x97, 0x0d, 0x3c, 0xef, - 0xdb, 0x1e, 0xfb, 0x50, 0x7f, 0x27, 0x01, 0x85, 0x08, 0x0a, 0xbd, 0x0a, 0xe0, 0xbb, 0x63, 0xcf, - 0xd7, 0x5c, 0x4a, 0x7d, 0x6e, 0xac, 0x22, 0xce, 0x73, 0x0a, 0xa6, 0xd4, 0x47, 0x15, 0xb8, 0x61, - 0x10, 0xd7, 0xd7, 0x2c, 0xcf, 0x1b, 0x13, 0x57, 0xf3, 0xc6, 0x7b, 0x5f, 0x12, 0xc3, 0xe7, 0x86, - 0x2b, 0xe2, 0x65, 0xc6, 0x6a, 0x71, 0x4e, 0x4f, 0x30, 0xd0, 0x7d, 0xb8, 0x19, 0xc5, 0x8f, 0xc6, - 0x7b, 0xb6, 0x65, 0x68, 0x6c, 0x31, 0x53, 0x5c, 0xe4, 0xc6, 0x54, 0xa4, 0xcb, 0x79, 0x8f, 0xc8, - 0x44, 0xfd, 0x69, 0x02, 0x14, 0xac, 0xef, 0xfb, 0x3b, 0x64, 0xb8, 0x47, 0xdc, 0x9e, 0xaf, 0xfb, - 0x63, 0x0f, 0xdd, 0x84, 0xac, 0x4d, 0x74, 0x93, 0xb8, 0x7c, 0x50, 0x39, 0x2c, 0x5b, 0x68, 0x97, - 0xed, 0x60, 0xdd, 0x38, 0xd0, 0xf7, 0x2c, 0xdb, 0xf2, 0x27, 0x7c, 0x28, 0x8b, 0xf1, 0x2e, 0x7c, - 0x51, 0x67, 0x05, 0x47, 0x04, 0xf1, 0x8c, 0x1a, 0xb4, 0x0a, 0xf3, 0x43, 0xe2, 0x79, 0xfa, 0x80, - 0xf0, 0x91, 0xe6, 0x71, 0xd0, 0x54, 0x3f, 0x81, 0x62, 0x54, 0x0e, 0x15, 0x60, 0x7e, 0xb7, 0xfd, - 0xa8, 0xdd, 0x79, 0xd2, 0x56, 0xe6, 0xd0, 0x12, 0x14, 0x76, 0xdb, 0xb8, 0x59, 0xad, 0x6f, 0x55, - 0x6b, 0xdb, 0x4d, 0x25, 0x81, 0x16, 0x20, 0x3f, 0x6d, 0x26, 0xd5, 0x3f, 0x4d, 0x00, 0x30, 0x73, - 0xcb, 0x49, 0x7d, 0x0c, 0x19, 0xcf, 0xd7, 0x7d, 0xe1, 0x95, 0x8b, 0x1b, 0x6f, 0x5c, 0xb6, 0x86, - 0x72, 0xbc, 0xec, 0x1f, 0xc1, 0x42, 0x24, 0x3a, 0xc2, 0xe4, 0xcc, 0x08, 0x59, 0x80, 0xd0, 0x4d, - 0xd3, 0x95, 0x03, 0xe7, 0xdf, 0xea, 0x27, 0x90, 0xe1, 0xd2, 0xb3, 0xc3, 0xcd, 0x41, 0xba, 0xc1, - 0xbe, 0x12, 0x28, 0x0f, 0x19, 0xdc, 0xac, 0x36, 0xbe, 0x50, 0x92, 0x48, 0x81, 0x62, 0xa3, 0xd5, - 0xab, 0x77, 0xda, 0xed, 0x66, 0xbd, 0xdf, 0x6c, 0x28, 0x29, 0xf5, 0x0e, 0x64, 0x5a, 0x43, 0xa6, - 0xf9, 0x36, 0x73, 0xf9, 0x7d, 0xe2, 0x12, 0xc7, 0x08, 0x76, 0xd2, 0x94, 0xa0, 0xfe, 0x24, 0x0f, - 0x99, 0x1d, 0x3a, 0x76, 0x7c, 0xb4, 0x11, 0x09, 0x5b, 0x8b, 0xf1, 0x27, 0x0f, 0x07, 0x56, 0xfa, - 0x93, 0x11, 0x91, 0x61, 0xed, 0x26, 0x64, 0xc5, 0xe6, 0x90, 0xd3, 0x91, 0x2d, 0x46, 0xf7, 0x75, - 0x77, 0x40, 0x7c, 0x39, 0x1f, 0xd9, 0x42, 0x6f, 0x41, 0xce, 0x25, 0xba, 0x49, 0x1d, 0x7b, 0xc2, - 0xf7, 0x50, 0x4e, 0x9c, 0x2b, 0x98, 0xe8, 0x66, 0xc7, 0xb1, 0x27, 0x38, 0xe4, 0xa2, 0x2d, 0x28, - 0xee, 0x59, 0x8e, 0xa9, 0xd1, 0x91, 0x08, 0xf2, 0x99, 0xcb, 0x77, 0x9c, 0x18, 0x55, 0xcd, 0x72, - 0xcc, 0x8e, 0x00, 0xe3, 0xc2, 0xde, 0xb4, 0x81, 0xda, 0xb0, 0x78, 0x44, 0xed, 0xf1, 0x90, 0x84, - 0xba, 0xb2, 0x5c, 0xd7, 0x9b, 0x97, 0xeb, 0x7a, 0xcc, 0xf1, 0x81, 0xb6, 0x85, 0xa3, 0x68, 0x13, - 0x3d, 0x82, 0x05, 0x7f, 0x38, 0xda, 0xf7, 0x42, 0x75, 0xf3, 0x5c, 0xdd, 0xf7, 0xae, 0x30, 0x18, - 0x83, 0x07, 0xda, 0x8a, 0x7e, 0xa4, 0x55, 0xfa, 0xf5, 0x14, 0x14, 0x22, 0x23, 0x47, 0x3d, 0x28, - 0x8c, 0x5c, 0x3a, 0xd2, 0x07, 0xfc, 0xa0, 0x92, 0x6b, 0x71, 0xef, 0x85, 0x66, 0x5d, 0xe9, 0x4e, - 0x05, 0x71, 0x54, 0x8b, 0x7a, 0x9a, 0x84, 0x42, 0x84, 0x89, 0xde, 0x81, 0x1c, 0xee, 0xe2, 0xd6, - 0xe3, 0x6a, 0xbf, 0xa9, 0xcc, 0x95, 0x6e, 0x9f, 0x9c, 0x96, 0x57, 0xb9, 0xb6, 0xa8, 0x82, 0xae, - 0x6b, 0x1d, 0x31, 0xd7, 0x7b, 0x0b, 0xe6, 0x03, 0x68, 0xa2, 0xf4, 0xca, 0xc9, 0x69, 0xf9, 0xe5, - 0x8b, 0xd0, 0x08, 0x12, 0xf7, 0xb6, 0xaa, 0xb8, 0xd9, 0x50, 0x92, 0xf1, 0x48, 0xdc, 0x3b, 0xd0, - 0x5d, 0x62, 0xa2, 0xef, 0x41, 0x56, 0x02, 0x53, 0xa5, 0xd2, 0xc9, 0x69, 0xf9, 0xe6, 0x45, 0xe0, - 0x14, 0x87, 0x7b, 0xdb, 0xd5, 0xc7, 0x4d, 0x25, 0x1d, 0x8f, 0xc3, 0x3d, 0x5b, 0x3f, 0x22, 0xe8, - 0x0d, 0xc8, 0x08, 0x58, 0xa6, 0x74, 0xeb, 0xe4, 0xb4, 0xfc, 0xd2, 0x73, 0xea, 0x18, 0xaa, 0xb4, - 0xfa, 0x5b, 0x7f, 0xb0, 0x36, 0xf7, 0x97, 0x7f, 0xb8, 0xa6, 0x5c, 0x64, 0x97, 0xfe, 0x3b, 0x01, - 0x0b, 0x33, 0x4b, 0x8e, 0x54, 0xc8, 0x3a, 0xd4, 0xa0, 0x23, 0x71, 0x7e, 0xe5, 0x6a, 0x70, 0x7e, - 0xb6, 0x9e, 0x6d, 0xd3, 0x3a, 0x1d, 0x4d, 0xb0, 0xe4, 0xa0, 0x47, 0x17, 0x4e, 0xe0, 0xfb, 0x2f, - 0xe8, 0x4f, 0xb1, 0x67, 0xf0, 0x67, 0xb0, 0x60, 0xba, 0xd6, 0x11, 0x71, 0x35, 0x83, 0x3a, 0xfb, - 0xd6, 0x40, 0x9e, 0x4d, 0xa5, 0x38, 0x9d, 0x0d, 0x0e, 0xc4, 0x45, 0x21, 0x50, 0xe7, 0xf8, 0xef, - 0x70, 0xfa, 0x96, 0x1e, 0x43, 0x31, 0xea, 0xa1, 0xec, 0x38, 0xf1, 0xac, 0x5f, 0x26, 0x32, 0xa1, - 0xe3, 0xe9, 0x1f, 0xce, 0x33, 0x0a, 0x4f, 0xe7, 0xd0, 0x9b, 0x90, 0x1e, 0x52, 0x53, 0xe8, 0x59, - 0xa8, 0xdd, 0x60, 0x49, 0xc0, 0x3f, 0x9d, 0xad, 0x17, 0xa8, 0x57, 0xd9, 0xb4, 0x6c, 0xb2, 0x43, - 0x4d, 0x82, 0x39, 0x40, 0x3d, 0x82, 0x34, 0x0b, 0x15, 0xe8, 0x15, 0x48, 0xd7, 0x5a, 0xed, 0x86, - 0x32, 0x57, 0x5a, 0x3e, 0x39, 0x2d, 0x2f, 0x70, 0x93, 0x30, 0x06, 0xf3, 0x5d, 0xb4, 0x0e, 0xd9, - 0xc7, 0x9d, 0xed, 0xdd, 0x1d, 0xe6, 0x5e, 0x37, 0x4e, 0x4e, 0xcb, 0x4b, 0x21, 0x5b, 0x18, 0x0d, - 0xbd, 0x0a, 0x99, 0xfe, 0x4e, 0x77, 0xb3, 0xa7, 0x24, 0x4b, 0xe8, 0xe4, 0xb4, 0xbc, 0x18, 0xf2, - 0xf9, 0x98, 0x4b, 0xcb, 0x72, 0x55, 0xf3, 0x21, 0x5d, 0xfd, 0x59, 0x12, 0x16, 0x30, 0xab, 0x24, - 0x5c, 0xbf, 0x4b, 0x6d, 0xcb, 0x98, 0xa0, 0x2e, 0xe4, 0x0d, 0xea, 0x98, 0x56, 0x64, 0x4f, 0x6d, - 0x5c, 0x72, 0xea, 0x4f, 0xa5, 0x82, 0x56, 0x3d, 0x90, 0xc4, 0x53, 0x25, 0xe8, 0x3d, 0xc8, 0x98, - 0xc4, 0xd6, 0x27, 0x32, 0xfd, 0xb8, 0x55, 0x11, 0xb5, 0x4a, 0x25, 0xa8, 0x55, 0x2a, 0x0d, 0x59, - 0xab, 0x60, 0x81, 0xe3, 0x79, 0xb2, 0xfe, 0x54, 0xd3, 0x7d, 0x9f, 0x0c, 0x47, 0xbe, 0xc8, 0x3d, - 0xd2, 0xb8, 0x30, 0xd4, 0x9f, 0x56, 0x25, 0x09, 0xdd, 0x83, 0xec, 0xb1, 0xe5, 0x98, 0xf4, 0x58, - 0xa6, 0x17, 0x57, 0x28, 0x95, 0x40, 0xf5, 0x84, 0x9d, 0xba, 0x17, 0x86, 0xc9, 0xec, 0xdd, 0xee, - 0xb4, 0x9b, 0x81, 0xbd, 0x25, 0xbf, 0xe3, 0xb4, 0xa9, 0xc3, 0xf6, 0x0a, 0x74, 0xda, 0xda, 0x66, - 0xb5, 0xb5, 0xbd, 0x8b, 0x99, 0xcd, 0x57, 0x4e, 0x4e, 0xcb, 0x4a, 0x08, 0xd9, 0xd4, 0x2d, 0x9b, - 0xe5, 0xbb, 0xb7, 0x20, 0x55, 0x6d, 0x7f, 0xa1, 0x24, 0x4b, 0xca, 0xc9, 0x69, 0xb9, 0x18, 0xb2, - 0xab, 0xce, 0x64, 0xba, 0x8d, 0x2e, 0xf6, 0xab, 0xfe, 0x6d, 0x0a, 0x8a, 0xbb, 0x23, 0x53, 0xf7, - 0x89, 0xf0, 0x49, 0x54, 0x86, 0xc2, 0x48, 0x77, 0x75, 0xdb, 0x26, 0xb6, 0xe5, 0x0d, 0x65, 0x15, - 0x16, 0x25, 0xa1, 0x8f, 0x5e, 0xd4, 0x8c, 0xb5, 0x1c, 0xf3, 0xb3, 0xdf, 0xfd, 0x97, 0xf5, 0x44, - 0x60, 0xd0, 0x5d, 0x58, 0xdc, 0x17, 0xa3, 0xd5, 0x74, 0x83, 0x2f, 0x6c, 0x8a, 0x2f, 0x6c, 0x25, - 0x6e, 0x61, 0xa3, 0xc3, 0xaa, 0xc8, 0x49, 0x56, 0xb9, 0x14, 0x5e, 0xd8, 0x8f, 0x36, 0xd1, 0x7d, - 0x98, 0x1f, 0x52, 0xc7, 0xf2, 0xa9, 0x7b, 0xfd, 0x2a, 0x04, 0x48, 0xf4, 0x0e, 0x2c, 0xb3, 0xc5, - 0x0d, 0xc6, 0xc3, 0xd9, 0xfc, 0xc4, 0x4a, 0xe2, 0xa5, 0xa1, 0xfe, 0x54, 0x76, 0x88, 0x19, 0x19, - 0xd5, 0x20, 0x43, 0x5d, 0x96, 0x12, 0x65, 0xf9, 0x70, 0xdf, 0xbd, 0x76, 0xb8, 0xa2, 0xd1, 0x61, - 0x32, 0x58, 0x88, 0xaa, 0x1f, 0xc2, 0xc2, 0xcc, 0x24, 0x58, 0x26, 0xd0, 0xad, 0xee, 0xf6, 0x9a, - 0xca, 0x1c, 0x2a, 0x42, 0xae, 0xde, 0x69, 0xf7, 0x5b, 0xed, 0x5d, 0x96, 0xca, 0x14, 0x21, 0x87, - 0x3b, 0xdb, 0xdb, 0xb5, 0x6a, 0xfd, 0x91, 0x92, 0x54, 0x2b, 0x50, 0x88, 0x68, 0x43, 0x8b, 0x00, - 0xbd, 0x7e, 0xa7, 0xab, 0x6d, 0xb6, 0x70, 0xaf, 0x2f, 0x12, 0xa1, 0x5e, 0xbf, 0x8a, 0xfb, 0x92, - 0x90, 0x50, 0xff, 0x23, 0x19, 0xac, 0xa8, 0xcc, 0x7d, 0x6a, 0xb3, 0xb9, 0xcf, 0x15, 0x83, 0x97, - 0xd9, 0xcf, 0xb4, 0x11, 0xe6, 0x40, 0x1f, 0x01, 0x70, 0xc7, 0x21, 0xa6, 0xa6, 0xfb, 0x72, 0xe1, - 0x4b, 0xcf, 0x19, 0xb9, 0x1f, 0x5c, 0x06, 0xe0, 0xbc, 0x44, 0x57, 0x7d, 0xf4, 0x03, 0x28, 0x1a, - 0x74, 0x38, 0xb2, 0x89, 0x14, 0x4e, 0x5d, 0x2b, 0x5c, 0x08, 0xf1, 0x55, 0x3f, 0x9a, 0x7d, 0xa5, - 0x67, 0xf3, 0xc3, 0xdf, 0x48, 0x04, 0x96, 0x89, 0x49, 0xb8, 0x8a, 0x90, 0xdb, 0xed, 0x36, 0xaa, - 0xfd, 0x56, 0xfb, 0xa1, 0x92, 0x40, 0x00, 0x59, 0x6e, 0xea, 0x86, 0x92, 0x64, 0x89, 0x62, 0xbd, - 0xb3, 0xd3, 0xdd, 0x6e, 0xf2, 0x94, 0x0b, 0xad, 0x80, 0x12, 0x18, 0x5b, 0xe3, 0x86, 0x6c, 0x36, - 0x94, 0x34, 0xba, 0x01, 0x4b, 0x21, 0x55, 0x4a, 0x66, 0xd0, 0x4d, 0x40, 0x21, 0x71, 0xaa, 0x22, - 0xab, 0xfe, 0x2a, 0x2c, 0xd5, 0xa9, 0xe3, 0xeb, 0x96, 0x13, 0x26, 0xd1, 0x1b, 0x6c, 0xd2, 0x92, - 0xa4, 0x59, 0xa6, 0x88, 0xe9, 0xb5, 0xa5, 0xf3, 0xb3, 0xf5, 0x42, 0x08, 0x6d, 0x35, 0xd8, 0x4c, - 0x83, 0x86, 0xc9, 0xf6, 0xef, 0xc8, 0x32, 0xb9, 0x71, 0x33, 0xb5, 0xf9, 0xf3, 0xb3, 0xf5, 0x54, - 0xb7, 0xd5, 0xc0, 0x8c, 0x86, 0x5e, 0x81, 0x3c, 0x79, 0x6a, 0xf9, 0x9a, 0xc1, 0x62, 0x38, 0x33, - 0x60, 0x06, 0xe7, 0x18, 0xa1, 0xce, 0x42, 0x76, 0x0d, 0xa0, 0x4b, 0x5d, 0x5f, 0xf6, 0xfc, 0x3e, - 0x64, 0x46, 0xd4, 0xe5, 0xe5, 0xf9, 0xa5, 0x97, 0x11, 0x0c, 0x2e, 0x1c, 0x15, 0x0b, 0xb0, 0xfa, - 0x57, 0x49, 0x80, 0xbe, 0xee, 0x1d, 0x4a, 0x25, 0x0f, 0x20, 0x1f, 0x5e, 0xec, 0xc8, 0x3a, 0xff, - 0xca, 0xd5, 0x0e, 0xc1, 0xe8, 0x7e, 0xe0, 0x6c, 0xa2, 0x3c, 0x88, 0xad, 0xd3, 0x82, 0x8e, 0xe2, - 0x32, 0xec, 0xd9, 0x1a, 0x80, 0x1d, 0x89, 0xc4, 0x75, 0xe5, 0xca, 0xb3, 0x4f, 0x54, 0xe7, 0xc7, - 0x82, 0x30, 0x9a, 0x4c, 0x30, 0x5f, 0x8f, 0xeb, 0xe4, 0xc2, 0x8a, 0x6c, 0xcd, 0xe1, 0xa9, 0x1c, - 0xfa, 0x0c, 0x0a, 0x6c, 0xde, 0x9a, 0xc7, 0x79, 0x32, 0xb7, 0xbc, 0xd4, 0x54, 0x42, 0x03, 0x86, - 0x51, 0xf8, 0x5d, 0x53, 0x60, 0xd1, 0x1d, 0x3b, 0x6c, 0xda, 0x52, 0x87, 0xfa, 0x27, 0x49, 0x78, - 0xb9, 0x4d, 0xfc, 0x63, 0xea, 0x1e, 0x56, 0x7d, 0x5f, 0x37, 0x0e, 0x86, 0xc4, 0x91, 0x46, 0x8e, - 0x64, 0xd6, 0x89, 0x99, 0xcc, 0x7a, 0x15, 0xe6, 0x75, 0xdb, 0xd2, 0x3d, 0x22, 0xd2, 0x91, 0x3c, - 0x0e, 0x9a, 0x2c, 0xff, 0x67, 0xd5, 0x04, 0xf1, 0x3c, 0x22, 0x0a, 0xfc, 0x3c, 0x9e, 0x12, 0xd0, - 0x8f, 0xe1, 0xa6, 0x4c, 0x3c, 0xf4, 0xb0, 0x2b, 0x96, 0xd9, 0x06, 0x37, 0x50, 0xcd, 0xd8, 0xf2, - 0x26, 0x7e, 0x70, 0x32, 0x33, 0x99, 0x92, 0x3b, 0x23, 0x5f, 0xe6, 0x39, 0x2b, 0x66, 0x0c, 0xab, - 0xf4, 0x10, 0x6e, 0x5d, 0x2a, 0xf2, 0xad, 0x2e, 0x10, 0xfe, 0x21, 0x09, 0xd0, 0xea, 0x56, 0x77, - 0xa4, 0x91, 0x1a, 0x90, 0xdd, 0xd7, 0x87, 0x96, 0x3d, 0xb9, 0x2a, 0x4e, 0x4d, 0xf1, 0x95, 0xaa, - 0x30, 0xc7, 0x26, 0x97, 0xc1, 0x52, 0x96, 0x17, 0x37, 0xe3, 0x3d, 0x87, 0xf8, 0x61, 0x71, 0xc3, - 0x5b, 0x6c, 0x18, 0xae, 0xee, 0x84, 0x0e, 0x26, 0x1a, 0x6c, 0x01, 0x06, 0xba, 0x4f, 0x8e, 0xf5, - 0x49, 0x10, 0x5c, 0x64, 0x13, 0x6d, 0xb1, 0xa2, 0xc7, 0x23, 0xee, 0x11, 0x31, 0x57, 0x33, 0xdc, - 0xa8, 0xd7, 0x8d, 0x07, 0x4b, 0xb8, 0xb0, 0x5d, 0x28, 0x5d, 0xfa, 0x84, 0x27, 0x36, 0x53, 0xd6, - 0xb7, 0xb2, 0xd1, 0x5d, 0x58, 0x98, 0x99, 0xe7, 0x73, 0x55, 0x65, 0xab, 0xfb, 0xf8, 0x7d, 0x25, - 0x2d, 0xbf, 0x3e, 0x54, 0xb2, 0xea, 0x1f, 0xa5, 0x44, 0x38, 0x90, 0x56, 0x8d, 0xbf, 0xf6, 0xcc, - 0xf1, 0x4d, 0x6c, 0x50, 0x5b, 0x6e, 0xd3, 0x37, 0xaf, 0x8e, 0x12, 0xac, 0x4a, 0xe1, 0x70, 0x1c, - 0x0a, 0xa2, 0x75, 0x28, 0x08, 0x2f, 0xd6, 0xd8, 0xb6, 0xe0, 0x66, 0x5d, 0xc0, 0x20, 0x48, 0x4c, - 0x12, 0xdd, 0x81, 0x45, 0x7e, 0x0b, 0xe1, 0x1d, 0x10, 0x53, 0x60, 0xd2, 0x1c, 0xb3, 0x10, 0x52, - 0x39, 0x6c, 0x07, 0x8a, 0x92, 0xa0, 0xf1, 0x0c, 0x35, 0xc3, 0x07, 0xf4, 0xce, 0x75, 0x03, 0x12, - 0x22, 0x3c, 0x71, 0x2d, 0x8c, 0xa6, 0x0d, 0xb5, 0x01, 0xb9, 0x60, 0xb0, 0x68, 0x15, 0x52, 0xfd, - 0x7a, 0x57, 0x99, 0x2b, 0x2d, 0x9d, 0x9c, 0x96, 0x0b, 0x01, 0xb9, 0x5f, 0xef, 0x32, 0xce, 0x6e, - 0xa3, 0xab, 0x24, 0x66, 0x39, 0xbb, 0x8d, 0x6e, 0x29, 0xcd, 0x32, 0x25, 0x75, 0x1f, 0x0a, 0x91, - 0x1e, 0xd0, 0xeb, 0x30, 0xdf, 0x6a, 0x3f, 0xc4, 0xcd, 0x5e, 0x4f, 0x99, 0x2b, 0xdd, 0x3c, 0x39, - 0x2d, 0xa3, 0x08, 0xb7, 0xe5, 0x0c, 0xd8, 0xfa, 0xa0, 0x57, 0x21, 0xbd, 0xd5, 0x61, 0x27, 0xb0, - 0x48, 0x89, 0x23, 0x88, 0x2d, 0xea, 0xf9, 0xa5, 0x1b, 0x32, 0x05, 0x8b, 0x2a, 0x56, 0x7f, 0x2f, - 0x01, 0x59, 0xb1, 0x99, 0x62, 0x17, 0xaa, 0x0a, 0xf3, 0x41, 0xbd, 0x2a, 0xca, 0x95, 0x37, 0x2f, - 0x2f, 0x2d, 0x2a, 0xb2, 0x12, 0x10, 0xee, 0x17, 0xc8, 0x95, 0x3e, 0x86, 0x62, 0x94, 0xf1, 0xad, - 0x9c, 0xef, 0xc7, 0x50, 0x60, 0xfe, 0x1d, 0x94, 0x18, 0x1b, 0x90, 0x15, 0x01, 0x21, 0x3c, 0x11, - 0x2e, 0xaf, 0x73, 0x24, 0x12, 0x3d, 0x80, 0x79, 0x51, 0x1b, 0x05, 0xd7, 0x94, 0x6b, 0x57, 0xef, - 0x22, 0x1c, 0xc0, 0xd5, 0xcf, 0x20, 0xdd, 0x25, 0xc4, 0x65, 0xb6, 0x77, 0xa8, 0x49, 0xa6, 0x87, - 0xa8, 0x2c, 0xeb, 0x4c, 0xd2, 0x6a, 0xb0, 0xb2, 0xce, 0x24, 0x2d, 0x33, 0xbc, 0x88, 0x49, 0x46, - 0x2e, 0x62, 0xfa, 0x50, 0x7c, 0x42, 0xac, 0xc1, 0x81, 0x4f, 0x4c, 0xae, 0xe8, 0x5d, 0x48, 0x8f, - 0x48, 0x38, 0xf8, 0xd5, 0x58, 0x07, 0x23, 0xc4, 0xc5, 0x1c, 0xc5, 0xe2, 0xc8, 0x31, 0x97, 0x96, - 0x97, 0xe3, 0xb2, 0xa5, 0xfe, 0x7d, 0x12, 0x16, 0x5b, 0x9e, 0x37, 0xd6, 0x1d, 0x23, 0xc8, 0xaf, - 0x3e, 0x9d, 0xcd, 0xaf, 0xde, 0x8a, 0x9d, 0xe1, 0x8c, 0xc8, 0xec, 0xfd, 0x92, 0x3c, 0xe3, 0x92, - 0xe1, 0x19, 0xa7, 0xfe, 0x7b, 0x22, 0xb8, 0x44, 0xba, 0x13, 0xd9, 0xee, 0xa5, 0xd5, 0x93, 0xd3, - 0xf2, 0x4a, 0x54, 0x13, 0xd9, 0x75, 0x0e, 0x1d, 0x7a, 0xec, 0xa0, 0xd7, 0x20, 0x83, 0x9b, 0xed, - 0xe6, 0x13, 0x25, 0x21, 0xdc, 0x73, 0x06, 0x84, 0x89, 0x43, 0x8e, 0x99, 0xa6, 0x6e, 0xb3, 0xdd, - 0x60, 0xf9, 0x50, 0x32, 0x46, 0x53, 0x97, 0x38, 0xa6, 0xe5, 0x0c, 0xd0, 0xeb, 0x90, 0x6d, 0xf5, - 0x7a, 0xbb, 0xbc, 0xcc, 0x7f, 0xf9, 0xe4, 0xb4, 0x7c, 0x63, 0x06, 0xc5, 0x2f, 0x10, 0x4d, 0x06, - 0x62, 0xc5, 0x08, 0xcb, 0x94, 0x62, 0x40, 0x2c, 0xcb, 0x15, 0x20, 0xdc, 0xe9, 0x57, 0xfb, 0xac, - 0xc2, 0x7f, 0x1e, 0x84, 0x29, 0xfb, 0x2b, 0xb7, 0xdb, 0x3f, 0x27, 0x41, 0xa9, 0x1a, 0x06, 0x19, - 0xf9, 0x8c, 0x2f, 0xeb, 0xbf, 0x3e, 0xe4, 0x46, 0xec, 0xcb, 0x22, 0x41, 0x2e, 0xf3, 0x20, 0xf6, - 0x79, 0xe6, 0x82, 0x5c, 0x05, 0x53, 0x9b, 0x54, 0xcd, 0xa1, 0xe5, 0x79, 0x16, 0x75, 0x04, 0x0d, - 0x87, 0x9a, 0x4a, 0xff, 0x99, 0x80, 0x1b, 0x31, 0x08, 0x74, 0x17, 0xd2, 0x2e, 0xb5, 0x83, 0x35, - 0xbc, 0x7d, 0xd9, 0xfd, 0x20, 0x13, 0xc5, 0x1c, 0x89, 0xd6, 0x00, 0xf4, 0xb1, 0x4f, 0x75, 0xde, - 0x3f, 0x5f, 0xbd, 0x1c, 0x8e, 0x50, 0xd0, 0x13, 0xc8, 0x7a, 0xc4, 0x70, 0x49, 0x90, 0xf1, 0x7e, - 0xf6, 0x7f, 0x1d, 0x7d, 0xa5, 0xc7, 0xd5, 0x60, 0xa9, 0xae, 0x54, 0x81, 0xac, 0xa0, 0x30, 0xb7, - 0x37, 0x75, 0x5f, 0x97, 0xb7, 0xc7, 0xfc, 0x9b, 0x79, 0x93, 0x6e, 0x0f, 0x02, 0x6f, 0xd2, 0xed, - 0x81, 0xfa, 0x37, 0x49, 0x80, 0xe6, 0x53, 0x9f, 0xb8, 0x8e, 0x6e, 0xd7, 0xab, 0xa8, 0x19, 0x89, - 0xfe, 0x62, 0xb6, 0x6f, 0xc7, 0x5e, 0x89, 0x87, 0x12, 0x95, 0x7a, 0x35, 0x26, 0xfe, 0xdf, 0x82, - 0xd4, 0xd8, 0x95, 0x2f, 0x6e, 0x22, 0x5b, 0xdd, 0xc5, 0xdb, 0x98, 0xd1, 0x50, 0x73, 0x1a, 0xb6, - 0x52, 0x97, 0xbf, 0xab, 0x45, 0x3a, 0x88, 0x0d, 0x5d, 0x6c, 0xe7, 0x1b, 0xba, 0x66, 0x10, 0x79, - 0x72, 0x14, 0xc5, 0xce, 0xaf, 0x57, 0xeb, 0xc4, 0xf5, 0x71, 0xd6, 0xd0, 0xd9, 0xff, 0xef, 0x14, - 0xdf, 0xde, 0x05, 0x98, 0x4e, 0x0d, 0xad, 0x41, 0xa6, 0xbe, 0xd9, 0xeb, 0x6d, 0x2b, 0x73, 0x22, - 0x80, 0x4f, 0x59, 0x9c, 0xac, 0xfe, 0x45, 0x12, 0x72, 0xf5, 0xaa, 0x3c, 0x56, 0xeb, 0xa0, 0xf0, - 0xa8, 0xc4, 0xef, 0xdc, 0xc9, 0xd3, 0x91, 0xe5, 0x4e, 0x64, 0x60, 0xb9, 0xa2, 0xf4, 0x5c, 0x64, - 0x22, 0x6c, 0xd4, 0x4d, 0x2e, 0x80, 0x30, 0x14, 0x89, 0x34, 0x82, 0x66, 0xe8, 0x41, 0x8c, 0x5f, - 0xbb, 0xda, 0x58, 0xa2, 0x88, 0x98, 0xb6, 0x3d, 0x5c, 0x08, 0x94, 0xd4, 0x75, 0x0f, 0x7d, 0x04, - 0x4b, 0x9e, 0x35, 0x70, 0x2c, 0x67, 0xa0, 0x05, 0xc6, 0xe3, 0x0f, 0x00, 0xb5, 0xe5, 0xf3, 0xb3, - 0xf5, 0x85, 0x9e, 0x60, 0x49, 0x1b, 0x2e, 0x48, 0x64, 0x9d, 0x9b, 0x12, 0x7d, 0x08, 0x8b, 0x11, - 0x51, 0x66, 0x45, 0x61, 0x76, 0xe5, 0xfc, 0x6c, 0xbd, 0x18, 0x4a, 0x3e, 0x22, 0x13, 0x5c, 0x0c, - 0x05, 0x1f, 0x11, 0x7e, 0x4b, 0xb2, 0x4f, 0x5d, 0x83, 0x68, 0x2e, 0xdf, 0xd3, 0xfc, 0x04, 0x4f, - 0xe3, 0x02, 0xa7, 0x89, 0x6d, 0xae, 0x3e, 0x86, 0x1b, 0x1d, 0xd7, 0x38, 0x20, 0x9e, 0x2f, 0x4c, - 0x21, 0xad, 0xf8, 0x19, 0xdc, 0xf6, 0x75, 0xef, 0x50, 0x3b, 0xb0, 0x3c, 0x9f, 0xba, 0x13, 0xcd, - 0x25, 0x3e, 0x71, 0x18, 0x5f, 0xe3, 0xaf, 0x86, 0xf2, 0x1a, 0xeb, 0x16, 0xc3, 0x6c, 0x09, 0x08, - 0x0e, 0x10, 0xdb, 0x0c, 0xa0, 0xb6, 0xa0, 0xc8, 0x8a, 0x89, 0x06, 0xd9, 0xd7, 0xc7, 0xb6, 0xcf, - 0x66, 0x0f, 0x36, 0x1d, 0x68, 0x2f, 0x7c, 0x4c, 0xe5, 0x6d, 0x3a, 0x10, 0x9f, 0xea, 0x8f, 0x40, - 0x69, 0x58, 0xde, 0x48, 0xf7, 0x8d, 0x83, 0xe0, 0x7e, 0x0e, 0x35, 0x40, 0x39, 0x20, 0xba, 0xeb, - 0xef, 0x11, 0xdd, 0xd7, 0x46, 0xc4, 0xb5, 0xa8, 0x79, 0xfd, 0x2a, 0x2f, 0x85, 0x22, 0x5d, 0x2e, - 0xa1, 0xfe, 0x57, 0x02, 0x00, 0xeb, 0xfb, 0x41, 0x46, 0xf6, 0x7d, 0x58, 0xf6, 0x1c, 0x7d, 0xe4, - 0x1d, 0x50, 0x5f, 0xb3, 0x1c, 0x9f, 0xb8, 0x47, 0xba, 0x2d, 0xaf, 0x59, 0x94, 0x80, 0xd1, 0x92, - 0x74, 0xf4, 0x2e, 0xa0, 0x43, 0x42, 0x46, 0x1a, 0xb5, 0x4d, 0x2d, 0x60, 0x8a, 0x37, 0xcd, 0x34, - 0x56, 0x18, 0xa7, 0x63, 0x9b, 0xbd, 0x80, 0x8e, 0x6a, 0xb0, 0xc6, 0xa6, 0x4f, 0x1c, 0xdf, 0xb5, - 0x88, 0xa7, 0xed, 0x53, 0x57, 0xf3, 0x6c, 0x7a, 0xac, 0xed, 0x53, 0xdb, 0xa6, 0xc7, 0xc4, 0x0d, - 0x6e, 0xb0, 0x4a, 0x36, 0x1d, 0x34, 0x05, 0x68, 0x93, 0xba, 0x3d, 0x9b, 0x1e, 0x6f, 0x06, 0x08, - 0x96, 0xb6, 0x4d, 0xe7, 0xec, 0x5b, 0xc6, 0x61, 0x90, 0xb6, 0x85, 0xd4, 0xbe, 0x65, 0x1c, 0xa2, - 0xd7, 0x61, 0x81, 0xd8, 0x84, 0x5f, 0x64, 0x08, 0x54, 0x86, 0xa3, 0x8a, 0x01, 0x91, 0x81, 0xd4, - 0xcf, 0x41, 0x69, 0x3a, 0x86, 0x3b, 0x19, 0x45, 0xd6, 0xfc, 0x5d, 0x40, 0x2c, 0x48, 0x6a, 0x36, - 0x35, 0x0e, 0xb5, 0xa1, 0xee, 0xe8, 0x03, 0x36, 0x2e, 0xf1, 0xd4, 0xa4, 0x30, 0xce, 0x36, 0x35, - 0x0e, 0x77, 0x24, 0x5d, 0xfd, 0x08, 0xa0, 0x37, 0x72, 0x89, 0x6e, 0x76, 0x58, 0x36, 0xc1, 0x4c, - 0xc7, 0x5b, 0x9a, 0x29, 0x9f, 0xea, 0xa8, 0x2b, 0xb7, 0xba, 0x22, 0x18, 0x8d, 0x90, 0xae, 0xfe, - 0x02, 0xdc, 0xe8, 0xda, 0xba, 0xc1, 0x9f, 0xad, 0xbb, 0xe1, 0xdb, 0x09, 0x7a, 0x00, 0x59, 0x01, - 0x95, 0x2b, 0x19, 0xbb, 0xdd, 0xa6, 0x7d, 0x6e, 0xcd, 0x61, 0x89, 0xaf, 0x15, 0x01, 0xa6, 0x7a, - 0xd4, 0x3f, 0x4b, 0x40, 0x3e, 0xd4, 0x8f, 0xca, 0xc0, 0x4a, 0x79, 0xe6, 0xde, 0x96, 0x23, 0x6b, - 0xef, 0x3c, 0x8e, 0x92, 0x50, 0x0b, 0x0a, 0xa3, 0x50, 0xfa, 0xca, 0x7c, 0x2e, 0x66, 0xd4, 0x38, - 0x2a, 0x8b, 0x3e, 0x86, 0x7c, 0xf0, 0x36, 0x1a, 0x44, 0xd8, 0xab, 0x9f, 0x52, 0xa7, 0x70, 0xf5, - 0x53, 0x80, 0x1f, 0x52, 0xcb, 0xe9, 0xd3, 0x43, 0xe2, 0xf0, 0xb7, 0x3e, 0x56, 0x13, 0x92, 0xc0, - 0x8a, 0xb2, 0xc5, 0x0b, 0x72, 0xb1, 0x04, 0xe1, 0x93, 0x97, 0x68, 0xaa, 0x7f, 0x9d, 0x84, 0x2c, - 0xa6, 0xd4, 0xaf, 0x57, 0x51, 0x19, 0xb2, 0x32, 0x4e, 0xf0, 0xf3, 0xa7, 0x96, 0x3f, 0x3f, 0x5b, - 0xcf, 0x88, 0x00, 0x91, 0x31, 0x78, 0x64, 0x88, 0x44, 0xf0, 0xe4, 0x65, 0x11, 0x1c, 0xdd, 0x85, - 0xa2, 0x04, 0x69, 0x07, 0xba, 0x77, 0x20, 0x0a, 0xb4, 0xda, 0xe2, 0xf9, 0xd9, 0x3a, 0x08, 0xe4, - 0x96, 0xee, 0x1d, 0x60, 0x10, 0x68, 0xf6, 0x8d, 0x9a, 0x50, 0xf8, 0x92, 0x5a, 0x8e, 0xe6, 0xf3, - 0x49, 0xc8, 0x2b, 0xbf, 0xd8, 0x75, 0x9c, 0x4e, 0x55, 0x3e, 0x7c, 0xc3, 0x97, 0xd3, 0xc9, 0x37, - 0x61, 0xc1, 0xa5, 0xd4, 0x17, 0x61, 0xcb, 0xa2, 0x8e, 0xbc, 0x4d, 0x28, 0xc7, 0x5e, 0x32, 0x53, - 0xea, 0x63, 0x89, 0xc3, 0x45, 0x37, 0xd2, 0x42, 0x77, 0x61, 0xc5, 0xd6, 0x3d, 0x5f, 0xe3, 0xf1, - 0xce, 0x9c, 0x6a, 0xcb, 0xf2, 0xad, 0x86, 0x18, 0x6f, 0x93, 0xb3, 0x02, 0x09, 0xf5, 0x1f, 0x13, - 0x50, 0x60, 0x93, 0xb1, 0xf6, 0x2d, 0x83, 0x25, 0x79, 0xdf, 0x3e, 0xf7, 0xb8, 0x05, 0x29, 0xc3, - 0x73, 0xa5, 0x51, 0xf9, 0xe1, 0x5b, 0xef, 0x61, 0xcc, 0x68, 0xe8, 0x73, 0xc8, 0xca, 0x5b, 0x0d, - 0x91, 0x76, 0xa8, 0xd7, 0xa7, 0xa3, 0xd2, 0x36, 0x52, 0x8e, 0xfb, 0xf2, 0x74, 0x74, 0xe2, 0x10, - 0xc0, 0x51, 0x12, 0xba, 0x09, 0x49, 0x43, 0x98, 0x4b, 0xfe, 0xb2, 0xa2, 0xde, 0xc6, 0x49, 0xc3, - 0x51, 0xff, 0x2e, 0x01, 0x0b, 0xd3, 0x0d, 0xcf, 0x3c, 0xe0, 0x36, 0xe4, 0xbd, 0xf1, 0x9e, 0x37, - 0xf1, 0x7c, 0x32, 0x0c, 0xde, 0x31, 0x43, 0x02, 0x6a, 0x41, 0x5e, 0xb7, 0x07, 0xd4, 0xb5, 0xfc, - 0x83, 0xa1, 0xac, 0x44, 0xe3, 0x53, 0x85, 0xa8, 0xce, 0x4a, 0x35, 0x10, 0xc1, 0x53, 0xe9, 0xe0, - 0xdc, 0x17, 0x8f, 0xdd, 0xfc, 0xdc, 0x7f, 0x0d, 0x8a, 0xb6, 0x3e, 0xe4, 0xd7, 0x3c, 0xbe, 0x35, - 0x14, 0xf3, 0x48, 0xe3, 0x82, 0xa4, 0xf5, 0xad, 0x21, 0x51, 0x55, 0xc8, 0x87, 0xca, 0xd0, 0x12, - 0x14, 0xaa, 0xcd, 0x9e, 0x76, 0x6f, 0xe3, 0x81, 0xf6, 0xb0, 0xbe, 0xa3, 0xcc, 0xc9, 0xdc, 0xf4, - 0xcf, 0x13, 0xb0, 0x20, 0xc3, 0x91, 0xcc, 0xf7, 0x5f, 0x87, 0x79, 0x57, 0xdf, 0xf7, 0x83, 0x8a, - 0x24, 0x2d, 0xbc, 0x9a, 0x45, 0x78, 0x56, 0x91, 0x30, 0x56, 0x7c, 0x45, 0x12, 0x79, 0x59, 0x4f, - 0x5d, 0xf9, 0xb2, 0x9e, 0xfe, 0xb9, 0xbc, 0xac, 0xab, 0xbf, 0x06, 0xb0, 0x69, 0xd9, 0xa4, 0x2f, - 0xee, 0x9a, 0xe2, 0xea, 0x4b, 0x96, 0xc3, 0xc9, 0x1b, 0xc7, 0x20, 0x87, 0x6b, 0x35, 0x30, 0xa3, - 0x31, 0xd6, 0xc0, 0x32, 0xe5, 0x66, 0xe4, 0xac, 0x87, 0x8c, 0x35, 0xb0, 0xcc, 0xf0, 0x2d, 0x29, - 0x7d, 0xdd, 0x5b, 0xd2, 0x69, 0x02, 0x96, 0x64, 0xee, 0x1a, 0x86, 0xdf, 0xb7, 0x21, 0x2f, 0xd2, - 0xd8, 0x69, 0x41, 0xc7, 0x5f, 0x93, 0x05, 0xae, 0xd5, 0xc0, 0x39, 0xc1, 0x6e, 0x99, 0x68, 0x1d, - 0x0a, 0x12, 0x1a, 0xf9, 0x15, 0x0e, 0x08, 0x52, 0x9b, 0x0d, 0xff, 0x7d, 0x48, 0xef, 0x5b, 0x36, - 0x91, 0x8e, 0x1e, 0x1b, 0x00, 0xa6, 0x06, 0xd8, 0x9a, 0xc3, 0x1c, 0x5d, 0xcb, 0x05, 0x97, 0x71, - 0x7c, 0x7c, 0xb2, 0xec, 0x8c, 0x8e, 0x4f, 0x54, 0xa0, 0x17, 0xc6, 0x27, 0x70, 0x6c, 0x7c, 0x82, - 0x2d, 0xc6, 0x27, 0xa1, 0xd1, 0xf1, 0x09, 0xd2, 0xcf, 0x65, 0x7c, 0xdb, 0x70, 0xb3, 0x66, 0xeb, - 0xc6, 0xa1, 0x6d, 0x79, 0x3e, 0x31, 0xa3, 0x11, 0x63, 0x03, 0xb2, 0x33, 0x49, 0xe7, 0x55, 0x97, - 0xb3, 0x12, 0xa9, 0xfe, 0x5b, 0x02, 0x8a, 0x5b, 0x44, 0xb7, 0xfd, 0x83, 0xe9, 0xd5, 0x90, 0x4f, - 0x3c, 0x5f, 0x1e, 0x56, 0xfc, 0x1b, 0x7d, 0x00, 0xb9, 0x30, 0x27, 0xb9, 0xf6, 0x95, 0x2c, 0x84, - 0xa2, 0xfb, 0x30, 0xcf, 0xf6, 0x18, 0x1d, 0x07, 0xc5, 0xce, 0x55, 0x0f, 0x30, 0x12, 0xc9, 0x0e, - 0x19, 0x97, 0xf0, 0x24, 0x84, 0xbb, 0x52, 0x06, 0x07, 0x4d, 0xf4, 0xff, 0xa1, 0xc8, 0xdf, 0x0f, - 0x82, 0x9c, 0x2b, 0x73, 0x9d, 0xce, 0x82, 0x78, 0x02, 0x14, 0xf9, 0xd6, 0xff, 0x24, 0x60, 0x65, - 0x47, 0x9f, 0xec, 0x11, 0x19, 0x36, 0x88, 0x89, 0x89, 0x41, 0x5d, 0x13, 0x75, 0xa3, 0xe1, 0xe6, - 0x8a, 0x17, 0xc5, 0x38, 0xe1, 0xf8, 0xa8, 0x13, 0x14, 0x60, 0xc9, 0x48, 0x01, 0xb6, 0x02, 0x19, - 0x87, 0x3a, 0x06, 0x91, 0xb1, 0x48, 0x34, 0x54, 0x2b, 0x1a, 0x6a, 0x4a, 0xe1, 0x63, 0x1f, 0x7f, - 0xaa, 0x6b, 0x53, 0x3f, 0xec, 0x0d, 0x7d, 0x0e, 0xa5, 0x5e, 0xb3, 0x8e, 0x9b, 0xfd, 0x5a, 0xe7, - 0x47, 0x5a, 0xaf, 0xba, 0xdd, 0xab, 0x6e, 0xdc, 0xd5, 0xba, 0x9d, 0xed, 0x2f, 0xee, 0xdd, 0xbf, - 0xfb, 0x81, 0x92, 0x28, 0x95, 0x4f, 0x4e, 0xcb, 0xb7, 0xdb, 0xd5, 0xfa, 0xb6, 0xd8, 0x31, 0x7b, - 0xf4, 0x69, 0x4f, 0xb7, 0x3d, 0x7d, 0xe3, 0x6e, 0x97, 0xda, 0x13, 0x86, 0x61, 0x6e, 0x5d, 0x8c, - 0x9e, 0x57, 0xd1, 0x63, 0x38, 0x71, 0xe9, 0x31, 0x3c, 0x3d, 0xcd, 0x93, 0x97, 0x9c, 0xe6, 0x9b, - 0xb0, 0x62, 0xb8, 0xd4, 0xf3, 0x34, 0x96, 0xfd, 0x13, 0xf3, 0x42, 0x7d, 0xf1, 0xd2, 0xf9, 0xd9, - 0xfa, 0x72, 0x9d, 0xf1, 0x7b, 0x9c, 0x2d, 0xd5, 0x2f, 0x1b, 0x11, 0x12, 0xef, 0x49, 0xfd, 0xfd, - 0x14, 0x4b, 0xa4, 0xac, 0x23, 0xcb, 0x26, 0x03, 0xe2, 0xa1, 0xc7, 0xb0, 0x64, 0xb8, 0xc4, 0x64, - 0x69, 0xbd, 0x6e, 0x6b, 0xde, 0x88, 0x18, 0xd2, 0xa9, 0xff, 0x5f, 0x6c, 0x4e, 0x13, 0x0a, 0x56, - 0xea, 0xa1, 0x54, 0x6f, 0x44, 0x0c, 0xbc, 0x68, 0xcc, 0xb4, 0xd1, 0x97, 0xb0, 0xe4, 0x11, 0xdb, - 0x72, 0xc6, 0x4f, 0x35, 0x83, 0x3a, 0x3e, 0x79, 0x1a, 0xbc, 0x5b, 0x5d, 0xa7, 0xb7, 0xd7, 0xdc, - 0x66, 0x52, 0x75, 0x21, 0x54, 0x43, 0xe7, 0x67, 0xeb, 0x8b, 0xb3, 0x34, 0xbc, 0x28, 0x35, 0xcb, - 0x76, 0xa9, 0x0d, 0x8b, 0xb3, 0xa3, 0x41, 0x2b, 0x72, 0xef, 0xf3, 0x10, 0x12, 0xec, 0x6d, 0x74, - 0x1b, 0x72, 0x2e, 0x19, 0x58, 0x9e, 0xef, 0x0a, 0x33, 0x33, 0x4e, 0x48, 0x61, 0x3b, 0x5f, 0xfc, - 0x14, 0xa7, 0xf4, 0x2b, 0x70, 0xa1, 0x47, 0xb6, 0x59, 0x4c, 0xcb, 0xd3, 0xf7, 0xa4, 0xca, 0x1c, - 0x0e, 0x9a, 0xcc, 0x07, 0xc7, 0x5e, 0x98, 0xa8, 0xf1, 0x6f, 0x46, 0xe3, 0x19, 0x85, 0xfc, 0x61, - 0x12, 0xcf, 0x19, 0x82, 0x5f, 0x38, 0xa6, 0x23, 0xbf, 0x70, 0x5c, 0x81, 0x8c, 0x4d, 0x8e, 0x88, - 0x2d, 0xce, 0x72, 0x2c, 0x1a, 0xef, 0xfc, 0x2c, 0x05, 0xf9, 0xf0, 0x8d, 0x86, 0x9d, 0x04, 0xed, - 0xe6, 0x93, 0xc0, 0x57, 0x43, 0x7a, 0x9b, 0x1c, 0xa3, 0xd7, 0xa6, 0x77, 0x4a, 0x9f, 0x8b, 0x47, - 0xe9, 0x90, 0x1d, 0xdc, 0x27, 0xbd, 0x01, 0xb9, 0x6a, 0xaf, 0xd7, 0x7a, 0xd8, 0x6e, 0x36, 0x94, - 0xaf, 0x12, 0xa5, 0x97, 0x4e, 0x4e, 0xcb, 0xcb, 0x21, 0xa8, 0xea, 0x09, 0x57, 0xe2, 0xa8, 0x7a, - 0xbd, 0xd9, 0xed, 0x37, 0x1b, 0xca, 0xb3, 0xe4, 0x45, 0x14, 0xbf, 0x23, 0xe1, 0x3f, 0x2d, 0xc9, - 0x77, 0x71, 0xb3, 0x5b, 0xc5, 0xac, 0xc3, 0xaf, 0x92, 0xe2, 0xaa, 0x6b, 0xda, 0xa3, 0x4b, 0x46, - 0xba, 0xcb, 0xfa, 0x5c, 0x0b, 0x7e, 0x62, 0xf5, 0x2c, 0x25, 0x7e, 0x7e, 0x30, 0x7d, 0x70, 0x22, - 0xba, 0x39, 0x61, 0xbd, 0xf1, 0x97, 0x3e, 0xae, 0x26, 0x75, 0xa1, 0xb7, 0x1e, 0x8b, 0x24, 0x4c, - 0x8b, 0x0a, 0xf3, 0x78, 0xb7, 0xdd, 0x66, 0xa0, 0x67, 0xe9, 0x0b, 0xb3, 0xc3, 0x63, 0x87, 0xd5, - 0xbf, 0xe8, 0x0e, 0xe4, 0x82, 0x87, 0x40, 0xe5, 0xab, 0xf4, 0x85, 0x01, 0xd5, 0x83, 0x57, 0x4c, - 0xde, 0xe1, 0xd6, 0x6e, 0x9f, 0xff, 0x02, 0xec, 0x59, 0xe6, 0x62, 0x87, 0x07, 0x63, 0xdf, 0xa4, - 0xc7, 0x0e, 0xdb, 0x81, 0xf2, 0x56, 0xed, 0xab, 0x8c, 0xb8, 0x82, 0x08, 0x31, 0xf2, 0x4a, 0xed, - 0x0d, 0xc8, 0xe1, 0xe6, 0x0f, 0xc5, 0x8f, 0xc5, 0x9e, 0x65, 0x2f, 0xe8, 0xc1, 0xe4, 0x4b, 0x62, - 0xc8, 0xde, 0x3a, 0xb8, 0xbb, 0x55, 0xe5, 0x26, 0xbf, 0x88, 0xea, 0xb8, 0xa3, 0x03, 0xdd, 0x21, - 0xe6, 0xf4, 0x37, 0x18, 0x21, 0xeb, 0x9d, 0x5f, 0x84, 0x5c, 0x90, 0x67, 0xa2, 0x35, 0xc8, 0x3e, - 0xe9, 0xe0, 0x47, 0x4d, 0xac, 0xcc, 0x09, 0x1b, 0x06, 0x9c, 0x27, 0xa2, 0x42, 0x28, 0xc3, 0xfc, - 0x4e, 0xb5, 0x5d, 0x7d, 0xd8, 0xc4, 0xc1, 0x85, 0x77, 0x00, 0x90, 0xc9, 0x52, 0x49, 0x91, 0x1d, - 0x84, 0x3a, 0x6b, 0xab, 0x5f, 0x7f, 0xb3, 0x36, 0xf7, 0xd3, 0x6f, 0xd6, 0xe6, 0x9e, 0x9d, 0xaf, - 0x25, 0xbe, 0x3e, 0x5f, 0x4b, 0xfc, 0xe4, 0x7c, 0x2d, 0xf1, 0xaf, 0xe7, 0x6b, 0x89, 0xbd, 0x2c, - 0x0f, 0xe9, 0xf7, 0xff, 0x37, 0x00, 0x00, 0xff, 0xff, 0x62, 0x46, 0x73, 0x55, 0x80, 0x2e, 0x00, - 0x00, + // 4808 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x7a, 0x4d, 0x6c, 0x24, 0x49, + 0x56, 0xbf, 0xeb, 0xd3, 0x55, 0xaf, 0xca, 0x76, 0x76, 0xb4, 0xb7, 0xd7, 0x5d, 0xd3, 0x63, 0xd7, + 0xe4, 0x4c, 0xef, 0x7c, 0xec, 0xfc, 0x6b, 0xba, 0xdd, 0x33, 0xa3, 0xee, 0xe9, 0xff, 0x7c, 0xd4, + 0x97, 0xdb, 0xb5, 0x6d, 0x57, 0x95, 0xa2, 0xca, 0xdd, 0x3b, 0x07, 0x48, 0xa5, 0x33, 0xc3, 0xe5, + 0x1c, 0x67, 0x65, 0x14, 0x99, 0x59, 0x76, 0x17, 0x0b, 0xa2, 0xc5, 0x01, 0x90, 0x4f, 0x70, 0x62, + 0x25, 0x64, 0x2e, 0x70, 0x42, 0x48, 0x1c, 0x40, 0x42, 0x70, 0x61, 0x90, 0x38, 0xcc, 0x8d, 0x05, + 0x24, 0xb4, 0x02, 0xc9, 0x30, 0x3e, 0x70, 0x43, 0x70, 0x59, 0x71, 0x01, 0x09, 0xc5, 0x47, 0x66, + 0x65, 0xb9, 0xd3, 0x76, 0x0f, 0xb3, 0x17, 0x3b, 0xe3, 0xbd, 0xdf, 0x7b, 0xf1, 0xe2, 0x45, 0xc4, + 0x8b, 0xf7, 0x22, 0x0a, 0x0a, 0xfe, 0x64, 0x44, 0xbc, 0xca, 0xc8, 0xa5, 0x3e, 0x45, 0xc8, 0xa4, + 0xc6, 0x01, 0x71, 0x2b, 0xde, 0x91, 0xee, 0x0e, 0x0f, 0x2c, 0xbf, 0x72, 0x78, 0xb7, 0xb4, 0x36, + 0xa0, 0x74, 0x60, 0x93, 0xf7, 0x38, 0x62, 0x77, 0xbc, 0xf7, 0x9e, 0x6f, 0x0d, 0x89, 0xe7, 0xeb, + 0xc3, 0x91, 0x10, 0x2a, 0xad, 0x9e, 0x07, 0x98, 0x63, 0x57, 0xf7, 0x2d, 0xea, 0x48, 0xfe, 0xf2, + 0x80, 0x0e, 0x28, 0xff, 0x7c, 0x8f, 0x7d, 0x09, 0xaa, 0xba, 0x06, 0xf3, 0x4f, 0x88, 0xeb, 0x59, + 0xd4, 0x41, 0xcb, 0x90, 0xb1, 0x1c, 0x93, 0x3c, 0x5b, 0x49, 0x94, 0x13, 0x6f, 0xa5, 0xb1, 0x68, + 0xa8, 0x77, 0x00, 0x5a, 0xec, 0xa3, 0xe9, 0xf8, 0xee, 0x04, 0x29, 0x90, 0x3a, 0x20, 0x13, 0x8e, + 0xc8, 0x63, 0xf6, 0xc9, 0x28, 0x87, 0xba, 0xbd, 0x92, 0x14, 0x94, 0x43, 0xdd, 0x56, 0xbf, 0x4e, + 0x40, 0xa1, 0xea, 0x38, 0xd4, 0xe7, 0xbd, 0x7b, 0x08, 0x41, 0xda, 0xd1, 0x87, 0x44, 0x0a, 0xf1, + 0x6f, 0x54, 0x87, 0xac, 0xad, 0xef, 0x12, 0xdb, 0x5b, 0x49, 0x96, 0x53, 0x6f, 0x15, 0xd6, 0xbf, + 0x5f, 0x79, 0x71, 0xc8, 0x95, 0x88, 0x92, 0xca, 0x16, 0x47, 0x73, 0x23, 0xb0, 0x14, 0x45, 0x9f, + 0xc0, 0xbc, 0xe5, 0x98, 0x96, 0x41, 0xbc, 0x95, 0x34, 0xd7, 0xb2, 0x1a, 0xa7, 0x65, 0x6a, 0x7d, + 0x2d, 0xfd, 0xd5, 0xe9, 0xda, 0x1c, 0x0e, 0x84, 0x4a, 0x0f, 0xa0, 0x10, 0x51, 0x1b, 0x33, 0xb6, + 0x65, 0xc8, 0x1c, 0xea, 0xf6, 0x98, 0xc8, 0xd1, 0x89, 0xc6, 0x47, 0xc9, 0xfb, 0x09, 0xf5, 0x01, + 0x2c, 0x3c, 0x22, 0x0e, 0x71, 0x2d, 0xa3, 0xe7, 0xbb, 0x96, 0x33, 0x60, 0x83, 0x3c, 0xb0, 0x1c, + 0x33, 0x18, 0x24, 0xfb, 0x8e, 0x17, 0x57, 0x1f, 0xc2, 0x92, 0x14, 0x6d, 0x58, 0x9e, 0xe1, 0x12, + 0x9f, 0x5c, 0x2d, 0x9c, 0x0a, 0x84, 0x7f, 0x37, 0x11, 0x4a, 0x63, 0xe2, 0xd1, 0xb1, 0x6b, 0x10, + 0xf4, 0x01, 0xa4, 0x3c, 0xdf, 0xe5, 0xc2, 0x85, 0xf5, 0xd7, 0xe2, 0x5c, 0x30, 0x63, 0xea, 0xe6, + 0x1c, 0x66, 0x78, 0x54, 0x85, 0x9c, 0x29, 0x0d, 0xe0, 0x7d, 0x14, 0xd6, 0x5f, 0xbf, 0x44, 0x36, + 0xb0, 0x75, 0x73, 0x0e, 0x87, 0x62, 0x35, 0x80, 0x9c, 0x2b, 0xad, 0x50, 0x7f, 0x9c, 0x80, 0x7c, + 0x60, 0x92, 0x87, 0xde, 0x86, 0xbc, 0xa3, 0x3b, 0x54, 0x33, 0x46, 0x63, 0x8f, 0x5b, 0x96, 0xaa, + 0x15, 0xcf, 0x4e, 0xd7, 0x72, 0x6d, 0xdd, 0xa1, 0xf5, 0xee, 0x8e, 0x87, 0x73, 0x8c, 0x5d, 0x1f, + 0x8d, 0x3d, 0xf4, 0x1a, 0x14, 0x87, 0x64, 0x48, 0xdd, 0x89, 0xb6, 0x3b, 0xf1, 0x89, 0x27, 0xc7, + 0x5b, 0x10, 0xb4, 0x1a, 0x23, 0xa1, 0x8f, 0x61, 0x7e, 0x20, 0xcc, 0x58, 0x49, 0xf1, 0x89, 0xbe, + 0xcc, 0xd2, 0xc0, 0x08, 0x1c, 0xc8, 0xa8, 0xbf, 0x9d, 0x80, 0xe5, 0x90, 0x4a, 0x7e, 0x69, 0x6c, + 0xb9, 0x64, 0x48, 0x1c, 0xdf, 0x43, 0x1f, 0x40, 0xd6, 0xb6, 0x86, 0x96, 0xef, 0x49, 0xe7, 0xbd, + 0x1a, 0xa7, 0x36, 0x1c, 0x14, 0x96, 0x60, 0x54, 0x85, 0xa2, 0x4b, 0x3c, 0xe2, 0x1e, 0x8a, 0xb5, + 0x29, 0xbd, 0x77, 0x85, 0xf0, 0x8c, 0x88, 0xba, 0x01, 0xb9, 0xae, 0xad, 0xfb, 0x7b, 0xd4, 0x1d, + 0x22, 0x15, 0x8a, 0xba, 0x6b, 0xec, 0x5b, 0x3e, 0x31, 0xfc, 0xb1, 0x1b, 0xec, 0x93, 0x19, 0x1a, + 0xba, 0x01, 0x49, 0x2a, 0x3a, 0xca, 0xd7, 0xb2, 0x67, 0xa7, 0x6b, 0xc9, 0x4e, 0x0f, 0x27, 0xa9, + 0xa7, 0x3e, 0x84, 0x6b, 0x5d, 0x7b, 0x3c, 0xb0, 0x9c, 0x06, 0xf1, 0x0c, 0xd7, 0x1a, 0x31, 0xed, + 0x6c, 0x39, 0xb1, 0x68, 0x12, 0x2c, 0x27, 0xf6, 0x1d, 0x6e, 0xc2, 0xe4, 0x74, 0x13, 0xaa, 0xbf, + 0x99, 0x84, 0x6b, 0x4d, 0x67, 0x60, 0x39, 0x24, 0x2a, 0x7d, 0x1b, 0x16, 0x09, 0x27, 0x6a, 0x87, + 0x22, 0x30, 0x48, 0x3d, 0x0b, 0x82, 0x1a, 0x44, 0x8b, 0xd6, 0xb9, 0x1d, 0x7c, 0x37, 0x6e, 0xf8, + 0x2f, 0x68, 0x8f, 0xdd, 0xc7, 0x4d, 0x98, 0x1f, 0xf1, 0x41, 0x78, 0x72, 0x7a, 0x6f, 0xc7, 0xe9, + 0x7a, 0x61, 0x9c, 0xc1, 0x76, 0x96, 0xb2, 0xdf, 0x66, 0x3b, 0xff, 0x71, 0x12, 0x96, 0xda, 0xd4, + 0x9c, 0xf1, 0x43, 0x09, 0x72, 0xfb, 0xd4, 0xf3, 0x23, 0xa1, 0x2b, 0x6c, 0xa3, 0xfb, 0x90, 0x1b, + 0xc9, 0xe9, 0x93, 0xb3, 0x7f, 0x2b, 0xde, 0x64, 0x81, 0xc1, 0x21, 0x1a, 0x3d, 0x84, 0x7c, 0xb0, + 0x65, 0xd8, 0x68, 0x5f, 0x62, 0xe1, 0x4c, 0xf1, 0xe8, 0x63, 0xc8, 0x8a, 0x49, 0x58, 0x49, 0x73, + 0xc9, 0xdb, 0x2f, 0xe5, 0x73, 0x2c, 0x85, 0xd0, 0x23, 0xc8, 0xf9, 0xb6, 0xa7, 0x59, 0xce, 0x1e, + 0x5d, 0xc9, 0x70, 0x05, 0x6b, 0x71, 0x0a, 0x98, 0x23, 0xfa, 0x5b, 0xbd, 0x96, 0xb3, 0x47, 0x6b, + 0x85, 0xb3, 0xd3, 0xb5, 0x79, 0xd9, 0xc0, 0xf3, 0xbe, 0xed, 0xb1, 0x0f, 0xf5, 0x77, 0x12, 0x50, + 0x88, 0xa0, 0xd0, 0xab, 0x00, 0xbe, 0x3b, 0xf6, 0x7c, 0xcd, 0xa5, 0xd4, 0xe7, 0xce, 0x2a, 0xe2, + 0x3c, 0xa7, 0x60, 0x4a, 0x7d, 0x54, 0x81, 0xeb, 0x06, 0x71, 0x7d, 0xcd, 0xf2, 0xbc, 0x31, 0x71, + 0x35, 0x6f, 0xbc, 0xfb, 0x05, 0x31, 0x7c, 0xee, 0xb8, 0x22, 0xbe, 0xc6, 0x58, 0x2d, 0xce, 0xe9, + 0x09, 0x06, 0xba, 0x07, 0x37, 0xa2, 0xf8, 0xd1, 0x78, 0xd7, 0xb6, 0x0c, 0x8d, 0x4d, 0x66, 0x8a, + 0x8b, 0x5c, 0x9f, 0x8a, 0x74, 0x39, 0xef, 0x31, 0x99, 0xa8, 0x3f, 0x4d, 0x80, 0x82, 0xf5, 0x3d, + 0x7f, 0x9b, 0x0c, 0x77, 0x89, 0xdb, 0xf3, 0x75, 0x7f, 0xec, 0xa1, 0x1b, 0x90, 0xb5, 0x89, 0x6e, + 0x12, 0x11, 0x1d, 0x73, 0x58, 0xb6, 0xd0, 0x0e, 0xdb, 0xc1, 0xba, 0xb1, 0xaf, 0xef, 0x5a, 0xb6, + 0xe5, 0x4f, 0xb8, 0x29, 0x8b, 0xf1, 0x4b, 0xf8, 0xbc, 0xce, 0x0a, 0x8e, 0x08, 0xe2, 0x19, 0x35, + 0x68, 0x05, 0xe6, 0x87, 0xc4, 0xf3, 0xf4, 0x01, 0xe1, 0x96, 0xe6, 0x71, 0xd0, 0x54, 0x1f, 0x42, + 0x31, 0x2a, 0x87, 0x0a, 0x30, 0xbf, 0xd3, 0x7e, 0xdc, 0xee, 0x3c, 0x6d, 0x2b, 0x73, 0x68, 0x09, + 0x0a, 0x3b, 0x6d, 0xdc, 0xac, 0xd6, 0x37, 0xab, 0xb5, 0xad, 0xa6, 0x92, 0x40, 0x0b, 0x90, 0x9f, + 0x36, 0x93, 0xea, 0x9f, 0x26, 0x00, 0x98, 0xbb, 0xe5, 0xa0, 0x3e, 0x82, 0x8c, 0xe7, 0xeb, 0xbe, + 0x58, 0x95, 0x8b, 0xeb, 0x6f, 0x5c, 0x34, 0x87, 0xd2, 0x5e, 0xf6, 0x8f, 0x60, 0x21, 0x12, 0xb5, + 0x30, 0x39, 0x63, 0x21, 0x0b, 0x10, 0xba, 0x69, 0xba, 0xd2, 0x70, 0xfe, 0xad, 0x3e, 0x84, 0x0c, + 0x97, 0x9e, 0x35, 0x37, 0x07, 0xe9, 0x06, 0xfb, 0x4a, 0xa0, 0x3c, 0x64, 0x70, 0xb3, 0xda, 0xf8, + 0x5c, 0x49, 0x22, 0x05, 0x8a, 0x8d, 0x56, 0xaf, 0xde, 0x69, 0xb7, 0x9b, 0xf5, 0x7e, 0xb3, 0xa1, + 0xa4, 0xd4, 0xdb, 0x90, 0x69, 0x0d, 0x99, 0xe6, 0x5b, 0x6c, 0xc9, 0xef, 0x11, 0x97, 0x38, 0x46, + 0xb0, 0x93, 0xa6, 0x04, 0xf5, 0x27, 0x79, 0xc8, 0x6c, 0xd3, 0xb1, 0xe3, 0xa3, 0xf5, 0x48, 0xd8, + 0x5a, 0x8c, 0x3f, 0xcb, 0x39, 0xb0, 0xd2, 0x9f, 0x8c, 0x88, 0x0c, 0x6b, 0x37, 0x20, 0x2b, 0x36, + 0x87, 0x1c, 0x8e, 0x6c, 0x31, 0xba, 0xaf, 0xbb, 0x03, 0xe2, 0xcb, 0xf1, 0xc8, 0x16, 0x7a, 0x8b, + 0x9d, 0x58, 0xba, 0x49, 0x1d, 0x7b, 0xc2, 0xf7, 0x50, 0x4e, 0x1c, 0x4b, 0x98, 0xe8, 0x66, 0xc7, + 0xb1, 0x27, 0x38, 0xe4, 0xa2, 0x4d, 0x28, 0xee, 0x5a, 0x8e, 0xa9, 0xd1, 0x91, 0x08, 0xf2, 0x99, + 0x8b, 0x77, 0x9c, 0xb0, 0xaa, 0x66, 0x39, 0x66, 0x47, 0x80, 0x71, 0x61, 0x77, 0xda, 0x40, 0x6d, + 0x58, 0x3c, 0xa4, 0xf6, 0x78, 0x48, 0x42, 0x5d, 0x59, 0xae, 0xeb, 0xcd, 0x8b, 0x75, 0x3d, 0xe1, + 0xf8, 0x40, 0xdb, 0xc2, 0x61, 0xb4, 0x89, 0x1e, 0xc3, 0x82, 0x3f, 0x1c, 0xed, 0x79, 0xa1, 0xba, + 0x79, 0xae, 0xee, 0x7b, 0x97, 0x38, 0x8c, 0xc1, 0x03, 0x6d, 0x45, 0x3f, 0xd2, 0x2a, 0xfd, 0x7a, + 0x0a, 0x0a, 0x11, 0xcb, 0x51, 0x0f, 0x0a, 0x23, 0x97, 0x8e, 0xf4, 0x01, 0x3f, 0xa8, 0xe4, 0x5c, + 0xdc, 0x7d, 0xa9, 0x51, 0x57, 0xba, 0x53, 0x41, 0x1c, 0xd5, 0xa2, 0x9e, 0x24, 0xa1, 0x10, 0x61, + 0xa2, 0x77, 0x20, 0x87, 0xbb, 0xb8, 0xf5, 0xa4, 0xda, 0x6f, 0x2a, 0x73, 0xa5, 0x5b, 0xc7, 0x27, + 0xe5, 0x15, 0xae, 0x2d, 0xaa, 0xa0, 0xeb, 0x5a, 0x87, 0x6c, 0xe9, 0xbd, 0x05, 0xf3, 0x01, 0x34, + 0x51, 0x7a, 0xe5, 0xf8, 0xa4, 0xfc, 0xdd, 0xf3, 0xd0, 0x08, 0x12, 0xf7, 0x36, 0xab, 0xb8, 0xd9, + 0x50, 0x92, 0xf1, 0x48, 0xdc, 0xdb, 0xd7, 0x5d, 0x62, 0xa2, 0xef, 0x41, 0x56, 0x02, 0x53, 0xa5, + 0xd2, 0xf1, 0x49, 0xf9, 0xc6, 0x79, 0xe0, 0x14, 0x87, 0x7b, 0x5b, 0xd5, 0x27, 0x4d, 0x25, 0x1d, + 0x8f, 0xc3, 0x3d, 0x5b, 0x3f, 0x24, 0xe8, 0x0d, 0xc8, 0x08, 0x58, 0xa6, 0x74, 0xf3, 0xf8, 0xa4, + 0xfc, 0x9d, 0x17, 0xd4, 0x31, 0x54, 0x69, 0xe5, 0xb7, 0xfe, 0x60, 0x75, 0xee, 0x2f, 0xff, 0x70, + 0x55, 0x39, 0xcf, 0x2e, 0xfd, 0x77, 0x02, 0x16, 0x66, 0xa6, 0x1c, 0xa9, 0x90, 0x75, 0xa8, 0x41, + 0x47, 0xe2, 0xfc, 0xca, 0xd5, 0xe0, 0xec, 0x74, 0x2d, 0xdb, 0xa6, 0x75, 0x3a, 0x9a, 0x60, 0xc9, + 0x41, 0x8f, 0xcf, 0x9d, 0xc0, 0xf7, 0x5e, 0x72, 0x3d, 0xc5, 0x9e, 0xc1, 0x9f, 0xc2, 0x82, 0xe9, + 0x5a, 0x87, 0xc4, 0xd5, 0x0c, 0xea, 0xec, 0x59, 0x03, 0x79, 0x36, 0x95, 0xe2, 0x74, 0x36, 0x38, + 0x10, 0x17, 0x85, 0x40, 0x9d, 0xe3, 0xbf, 0xc5, 0xe9, 0x5b, 0x7a, 0x02, 0xc5, 0xe8, 0x0a, 0x65, + 0xc7, 0x89, 0x67, 0xfd, 0x32, 0x91, 0xf9, 0x20, 0xcf, 0x1e, 0x71, 0x9e, 0x51, 0x44, 0x36, 0xf8, + 0x26, 0xa4, 0x87, 0xd4, 0x14, 0x7a, 0x16, 0x6a, 0xd7, 0x59, 0x12, 0xf0, 0x4f, 0xa7, 0x6b, 0x05, + 0xea, 0x55, 0x36, 0x2c, 0x9b, 0x6c, 0x53, 0x93, 0x60, 0x0e, 0x50, 0x0f, 0x21, 0xcd, 0x42, 0x05, + 0x7a, 0x05, 0xd2, 0xb5, 0x56, 0xbb, 0xa1, 0xcc, 0x95, 0xae, 0x1d, 0x9f, 0x94, 0x17, 0xb8, 0x4b, + 0x18, 0x83, 0xad, 0x5d, 0xb4, 0x06, 0xd9, 0x27, 0x9d, 0xad, 0x9d, 0x6d, 0xb6, 0xbc, 0xae, 0x1f, + 0x9f, 0x94, 0x97, 0x42, 0xb6, 0x70, 0x1a, 0x7a, 0x15, 0x32, 0xfd, 0xed, 0xee, 0x46, 0x4f, 0x49, + 0x96, 0xd0, 0xf1, 0x49, 0x79, 0x31, 0xe4, 0x73, 0x9b, 0x4b, 0xd7, 0xe4, 0xac, 0xe6, 0x43, 0xba, + 0xfa, 0xb3, 0x24, 0x2c, 0x60, 0x56, 0x9b, 0xb9, 0x7e, 0x97, 0xda, 0x96, 0x31, 0x41, 0x5d, 0xc8, + 0x1b, 0xd4, 0x31, 0xad, 0xc8, 0x9e, 0x5a, 0xbf, 0xe0, 0xd4, 0x9f, 0x4a, 0x05, 0xad, 0x7a, 0x20, + 0x89, 0xa7, 0x4a, 0xd0, 0x7b, 0x90, 0x31, 0x89, 0xad, 0x4f, 0x64, 0xfa, 0x71, 0xb3, 0x22, 0xaa, + 0xbf, 0x4a, 0x50, 0xfd, 0x55, 0x1a, 0xb2, 0xfa, 0xc3, 0x02, 0xc7, 0xd3, 0x6c, 0xfd, 0x99, 0xa6, + 0xfb, 0x3e, 0x19, 0x8e, 0x7c, 0x91, 0x7b, 0xa4, 0x71, 0x61, 0xa8, 0x3f, 0xab, 0x4a, 0x12, 0xba, + 0x0b, 0xd9, 0x23, 0xcb, 0x31, 0xe9, 0x91, 0x4c, 0x2f, 0x2e, 0x51, 0x2a, 0x81, 0xea, 0x31, 0x3b, + 0x75, 0xcf, 0x99, 0xc9, 0xfc, 0xdd, 0xee, 0xb4, 0x9b, 0x81, 0xbf, 0x25, 0xbf, 0xe3, 0xb4, 0xa9, + 0xc3, 0xf6, 0x0a, 0x74, 0xda, 0xda, 0x46, 0xb5, 0xb5, 0xb5, 0x83, 0x99, 0xcf, 0x97, 0x8f, 0x4f, + 0xca, 0x4a, 0x08, 0xd9, 0xd0, 0x2d, 0x9b, 0xe5, 0xbb, 0x37, 0x21, 0x55, 0x6d, 0x7f, 0xae, 0x24, + 0x4b, 0xca, 0xf1, 0x49, 0xb9, 0x18, 0xb2, 0xab, 0xce, 0x64, 0xba, 0x8d, 0xce, 0xf7, 0xab, 0xfe, + 0x6d, 0x0a, 0x8a, 0x3b, 0x23, 0x53, 0xf7, 0x89, 0x58, 0x93, 0xa8, 0x0c, 0x85, 0x91, 0xee, 0xea, + 0xb6, 0x4d, 0x6c, 0xcb, 0x1b, 0xca, 0xba, 0x36, 0x4a, 0x42, 0x0f, 0x5e, 0xd6, 0x8d, 0xb5, 0x1c, + 0x5b, 0x67, 0x3f, 0xfe, 0x97, 0xb5, 0x44, 0xe0, 0xd0, 0x1d, 0x58, 0xdc, 0x13, 0xd6, 0x6a, 0xba, + 0xc1, 0x27, 0x36, 0xc5, 0x27, 0xb6, 0x12, 0x37, 0xb1, 0x51, 0xb3, 0x2a, 0x72, 0x90, 0x55, 0x2e, + 0x85, 0x17, 0xf6, 0xa2, 0x4d, 0x74, 0x0f, 0xe6, 0x87, 0xd4, 0xb1, 0x7c, 0xea, 0x5e, 0x3d, 0x0b, + 0x01, 0x12, 0xbd, 0x03, 0xd7, 0xd8, 0xe4, 0x06, 0xf6, 0x70, 0x36, 0x3f, 0xb1, 0x92, 0x78, 0x69, + 0xa8, 0x3f, 0x93, 0x1d, 0x62, 0x46, 0x46, 0x35, 0xc8, 0x50, 0x97, 0xa5, 0x44, 0x59, 0x6e, 0xee, + 0xbb, 0x57, 0x9a, 0x2b, 0x1a, 0x1d, 0x26, 0x83, 0x85, 0xa8, 0xfa, 0x21, 0x2c, 0xcc, 0x0c, 0x82, + 0x65, 0x02, 0xdd, 0xea, 0x4e, 0xaf, 0xa9, 0xcc, 0xa1, 0x22, 0xe4, 0xea, 0x9d, 0x76, 0xbf, 0xd5, + 0xde, 0x61, 0xa9, 0x4c, 0x11, 0x72, 0xb8, 0xb3, 0xb5, 0x55, 0xab, 0xd6, 0x1f, 0x2b, 0x49, 0xb5, + 0x02, 0x85, 0x88, 0x36, 0xb4, 0x08, 0xd0, 0xeb, 0x77, 0xba, 0xda, 0x46, 0x0b, 0xf7, 0xfa, 0x22, + 0x11, 0xea, 0xf5, 0xab, 0xb8, 0x2f, 0x09, 0x09, 0xf5, 0x3f, 0x92, 0xc1, 0x8c, 0xca, 0xdc, 0xa7, + 0x36, 0x9b, 0xfb, 0x5c, 0x62, 0xbc, 0xcc, 0x7e, 0xa6, 0x8d, 0x30, 0x07, 0x7a, 0x00, 0xc0, 0x17, + 0x0e, 0x31, 0x35, 0xdd, 0x97, 0x13, 0x5f, 0x7a, 0xc1, 0xc9, 0xfd, 0xe0, 0x7a, 0x05, 0xe7, 0x25, + 0xba, 0xea, 0xa3, 0x8f, 0xa1, 0x68, 0xd0, 0xe1, 0xc8, 0x26, 0x52, 0x38, 0x75, 0xa5, 0x70, 0x21, + 0xc4, 0x57, 0xfd, 0x68, 0xf6, 0x95, 0x9e, 0xcd, 0x0f, 0x7f, 0x23, 0x11, 0x78, 0x26, 0x26, 0xe1, + 0x2a, 0x42, 0x6e, 0xa7, 0xdb, 0xa8, 0xf6, 0x5b, 0xed, 0x47, 0x4a, 0x02, 0x01, 0x64, 0xb9, 0xab, + 0x1b, 0x4a, 0x92, 0x25, 0x8a, 0xf5, 0xce, 0x76, 0x77, 0xab, 0xc9, 0x53, 0x2e, 0xb4, 0x0c, 0x4a, + 0xe0, 0x6c, 0x8d, 0x3b, 0xb2, 0xd9, 0x50, 0xd2, 0xe8, 0x3a, 0x2c, 0x85, 0x54, 0x29, 0x99, 0x41, + 0x37, 0x00, 0x85, 0xc4, 0xa9, 0x8a, 0xac, 0xfa, 0xab, 0xb0, 0x54, 0xa7, 0x8e, 0xaf, 0x5b, 0x4e, + 0x98, 0x44, 0xaf, 0xb3, 0x41, 0x4b, 0x92, 0x66, 0xc9, 0x5b, 0x8a, 0xda, 0xd2, 0xd9, 0xe9, 0x5a, + 0x21, 0x84, 0xb6, 0x1a, 0x6c, 0xa4, 0x41, 0xc3, 0x64, 0xfb, 0x77, 0x64, 0x99, 0xdc, 0xb9, 0x99, + 0xda, 0xfc, 0xd9, 0xe9, 0x5a, 0xaa, 0xdb, 0x6a, 0x60, 0x46, 0x43, 0xaf, 0x40, 0x9e, 0x3c, 0xb3, + 0x7c, 0xcd, 0x60, 0x31, 0x9c, 0x39, 0x30, 0x83, 0x73, 0x8c, 0x50, 0x67, 0x21, 0xbb, 0x06, 0xd0, + 0xa5, 0xae, 0x2f, 0x7b, 0x7e, 0x1f, 0x32, 0x23, 0xea, 0xf2, 0xf2, 0xfc, 0xc2, 0xeb, 0x1d, 0x06, + 0x17, 0x0b, 0x15, 0x0b, 0xb0, 0xfa, 0x57, 0x49, 0x80, 0xbe, 0xee, 0x1d, 0x48, 0x25, 0xf7, 0x21, + 0x1f, 0x5e, 0x95, 0xc9, 0x3a, 0xff, 0xd2, 0xd9, 0x0e, 0xc1, 0xe8, 0x5e, 0xb0, 0xd8, 0x44, 0x79, + 0x10, 0x5b, 0xa7, 0x05, 0x1d, 0xc5, 0x65, 0xd8, 0xb3, 0x35, 0x00, 0x3b, 0x12, 0x89, 0xeb, 0xca, + 0x99, 0x67, 0x9f, 0xa8, 0xce, 0x8f, 0x05, 0xe1, 0x34, 0x99, 0x60, 0xc6, 0xde, 0x6c, 0x9c, 0x9b, + 0x91, 0xcd, 0x39, 0x3c, 0x95, 0x43, 0x9f, 0x42, 0x81, 0x8d, 0x5b, 0xf3, 0x38, 0x4f, 0xe6, 0x96, + 0x17, 0xba, 0x4a, 0x68, 0xc0, 0x30, 0x0a, 0xbf, 0x6b, 0x0a, 0x2c, 0xba, 0x63, 0x87, 0x0d, 0x5b, + 0xea, 0x50, 0xff, 0x24, 0x09, 0xdf, 0x6d, 0x13, 0xff, 0x88, 0xba, 0x07, 0x55, 0xdf, 0xd7, 0x8d, + 0xfd, 0x21, 0x71, 0xa4, 0x93, 0x23, 0x99, 0x75, 0x62, 0x26, 0xb3, 0x5e, 0x81, 0x79, 0xdd, 0xb6, + 0x74, 0x8f, 0x88, 0x74, 0x24, 0x8f, 0x83, 0x26, 0xcb, 0xff, 0x59, 0x35, 0x41, 0x3c, 0x8f, 0x88, + 0x02, 0x3f, 0x8f, 0xa7, 0x04, 0xf4, 0x23, 0xb8, 0x21, 0x13, 0x0f, 0x3d, 0xec, 0x8a, 0x65, 0xb6, + 0xc1, 0x9d, 0x5e, 0x33, 0xb6, 0xbc, 0x89, 0x37, 0x4e, 0x66, 0x26, 0x53, 0x72, 0x67, 0xe4, 0xcb, + 0x3c, 0x67, 0xd9, 0x8c, 0x61, 0x95, 0x1e, 0xc1, 0xcd, 0x0b, 0x45, 0xbe, 0xd1, 0x05, 0xc2, 0x3f, + 0x24, 0x01, 0x5a, 0xdd, 0xea, 0xb6, 0x74, 0x52, 0x03, 0xb2, 0x7b, 0xfa, 0xd0, 0xb2, 0x27, 0x97, + 0xc5, 0xa9, 0x29, 0xbe, 0x52, 0x15, 0xee, 0xd8, 0xe0, 0x32, 0x58, 0xca, 0xf2, 0xe2, 0x66, 0xbc, + 0xeb, 0x10, 0x3f, 0x2c, 0x6e, 0x78, 0x8b, 0x99, 0xe1, 0xea, 0x4e, 0xb8, 0xc0, 0x44, 0x83, 0x4d, + 0xc0, 0x40, 0xf7, 0xc9, 0x91, 0x3e, 0x09, 0x82, 0x8b, 0x6c, 0xa2, 0x4d, 0x7e, 0x4d, 0x47, 0xdc, + 0x43, 0x62, 0xae, 0x64, 0xb8, 0x53, 0xaf, 0xb2, 0x07, 0x4b, 0xb8, 0xf0, 0x5d, 0x28, 0x5d, 0x7a, + 0xc8, 0x13, 0x9b, 0x29, 0xeb, 0x1b, 0xf9, 0xe8, 0x0e, 0x2c, 0xcc, 0x8c, 0xf3, 0x85, 0xaa, 0xb2, + 0xd5, 0x7d, 0xf2, 0xbe, 0x92, 0x96, 0x5f, 0x1f, 0x2a, 0x59, 0xf5, 0x8f, 0x52, 0x22, 0x1c, 0x48, + 0xaf, 0xc6, 0x5f, 0x24, 0xe7, 0xf8, 0x26, 0x36, 0xa8, 0x2d, 0xb7, 0xe9, 0x9b, 0x97, 0x47, 0x09, + 0x56, 0xa5, 0x70, 0x38, 0x0e, 0x05, 0xd1, 0x1a, 0x14, 0xc4, 0x2a, 0xd6, 0xd8, 0xb6, 0xe0, 0x6e, + 0x5d, 0xc0, 0x20, 0x48, 0x4c, 0x12, 0xdd, 0x86, 0x45, 0x7e, 0x0b, 0xe1, 0xed, 0x13, 0x53, 0x60, + 0xd2, 0x1c, 0xb3, 0x10, 0x52, 0x39, 0x6c, 0x1b, 0x8a, 0x92, 0xa0, 0xf1, 0x0c, 0x35, 0xc3, 0x0d, + 0x7a, 0xe7, 0x2a, 0x83, 0x84, 0x08, 0x4f, 0x5c, 0x0b, 0xa3, 0x69, 0x43, 0x6d, 0x40, 0x2e, 0x30, + 0x16, 0xad, 0x40, 0xaa, 0x5f, 0xef, 0x2a, 0x73, 0xa5, 0xa5, 0xe3, 0x93, 0x72, 0x21, 0x20, 0xf7, + 0xeb, 0x5d, 0xc6, 0xd9, 0x69, 0x74, 0x95, 0xc4, 0x2c, 0x67, 0xa7, 0xd1, 0x2d, 0xa5, 0x59, 0xa6, + 0xa4, 0xee, 0x41, 0x21, 0xd2, 0x03, 0x7a, 0x1d, 0xe6, 0x5b, 0xed, 0x47, 0xb8, 0xd9, 0xeb, 0x29, + 0x73, 0xa5, 0x1b, 0xc7, 0x27, 0x65, 0x14, 0xe1, 0xb6, 0x9c, 0x01, 0x9b, 0x1f, 0xf4, 0x2a, 0xa4, + 0x37, 0x3b, 0xec, 0x04, 0x16, 0x29, 0x71, 0x04, 0xb1, 0x49, 0x3d, 0xbf, 0x74, 0x5d, 0xa6, 0x60, + 0x51, 0xc5, 0xea, 0xef, 0x25, 0x20, 0x2b, 0x36, 0x53, 0xec, 0x44, 0x55, 0x61, 0x3e, 0xa8, 0x57, + 0x45, 0xb9, 0xf2, 0xe6, 0xc5, 0xa5, 0x45, 0x45, 0x56, 0x02, 0x62, 0xf9, 0x05, 0x72, 0xa5, 0x8f, + 0xa0, 0x18, 0x65, 0x7c, 0xa3, 0xc5, 0xf7, 0x23, 0x28, 0xb0, 0xf5, 0x1d, 0x94, 0x18, 0xeb, 0x90, + 0x15, 0x01, 0x21, 0x3c, 0x11, 0x2e, 0xae, 0x73, 0x24, 0x12, 0xdd, 0x87, 0x79, 0x51, 0x1b, 0x05, + 0xd7, 0x94, 0xab, 0x97, 0xef, 0x22, 0x1c, 0xc0, 0xd5, 0x4f, 0x21, 0xdd, 0x25, 0xc4, 0x65, 0xbe, + 0x77, 0xa8, 0x49, 0xa6, 0x87, 0xa8, 0x2c, 0xeb, 0x4c, 0xd2, 0x6a, 0xb0, 0xb2, 0xce, 0x24, 0x2d, + 0x33, 0xbc, 0x88, 0x49, 0x46, 0x2e, 0x62, 0xfa, 0x50, 0x7c, 0x4a, 0xac, 0xc1, 0xbe, 0x4f, 0x4c, + 0xae, 0xe8, 0x5d, 0x48, 0x8f, 0x48, 0x68, 0xfc, 0x4a, 0xec, 0x02, 0x23, 0xc4, 0xc5, 0x1c, 0xc5, + 0xe2, 0xc8, 0x11, 0x97, 0x96, 0x77, 0xeb, 0xb2, 0xa5, 0xfe, 0x7d, 0x12, 0x16, 0x5b, 0x9e, 0x37, + 0xd6, 0x1d, 0x23, 0xc8, 0xaf, 0x3e, 0x99, 0xcd, 0xaf, 0xde, 0x8a, 0x1d, 0xe1, 0x8c, 0xc8, 0xec, + 0xfd, 0x92, 0x3c, 0xe3, 0x92, 0xe1, 0x19, 0xa7, 0xfe, 0x7b, 0x22, 0xb8, 0x44, 0xba, 0x1d, 0xd9, + 0xee, 0xa5, 0x95, 0xe3, 0x93, 0xf2, 0x72, 0x54, 0x13, 0xd9, 0x71, 0x0e, 0x1c, 0x7a, 0xe4, 0xa0, + 0xd7, 0x20, 0x83, 0x9b, 0xed, 0xe6, 0x53, 0x25, 0x21, 0x96, 0xe7, 0x0c, 0x08, 0x13, 0x87, 0x1c, + 0x31, 0x4d, 0xdd, 0x66, 0xbb, 0xc1, 0xf2, 0xa1, 0x64, 0x8c, 0xa6, 0x2e, 0x71, 0x4c, 0xcb, 0x19, + 0xa0, 0xd7, 0x21, 0xdb, 0xea, 0xf5, 0x76, 0x78, 0x99, 0xff, 0xdd, 0xe3, 0x93, 0xf2, 0xf5, 0x19, + 0x14, 0xbf, 0x40, 0x34, 0x19, 0x88, 0x15, 0x23, 0x2c, 0x53, 0x8a, 0x01, 0xb1, 0x2c, 0x57, 0x80, + 0x70, 0xa7, 0x5f, 0xed, 0xb3, 0x0a, 0xff, 0x45, 0x10, 0xa6, 0xec, 0xaf, 0xdc, 0x6e, 0xff, 0x9c, + 0x04, 0xa5, 0x6a, 0x18, 0x64, 0xe4, 0x33, 0xbe, 0xac, 0xff, 0xfa, 0x90, 0x1b, 0xb1, 0x2f, 0x8b, + 0x04, 0xb9, 0xcc, 0xfd, 0xd8, 0x07, 0xaf, 0x73, 0x72, 0x15, 0x4c, 0x6d, 0x52, 0x35, 0x87, 0x96, + 0xe7, 0x59, 0xd4, 0x11, 0x34, 0x1c, 0x6a, 0x2a, 0xfd, 0x67, 0x02, 0xae, 0xc7, 0x20, 0xd0, 0x1d, + 0x48, 0xbb, 0xd4, 0x0e, 0xe6, 0xf0, 0xd6, 0x45, 0xf7, 0x83, 0x4c, 0x14, 0x73, 0x24, 0x5a, 0x05, + 0xd0, 0xc7, 0x3e, 0xd5, 0x79, 0xff, 0x7c, 0xf6, 0x72, 0x38, 0x42, 0x41, 0x4f, 0x21, 0xeb, 0x11, + 0xc3, 0x25, 0x41, 0xc6, 0xfb, 0xe9, 0xff, 0xd5, 0xfa, 0x4a, 0x8f, 0xab, 0xc1, 0x52, 0x5d, 0xa9, + 0x02, 0x59, 0x41, 0x61, 0xcb, 0xde, 0xd4, 0x7d, 0x5d, 0xde, 0x1e, 0xf3, 0x6f, 0xb6, 0x9a, 0x74, + 0x7b, 0x10, 0xac, 0x26, 0xdd, 0x1e, 0xa8, 0x7f, 0x93, 0x04, 0x68, 0x3e, 0xf3, 0x89, 0xeb, 0xe8, + 0x76, 0xbd, 0x8a, 0x9a, 0x91, 0xe8, 0x2f, 0x46, 0xfb, 0x76, 0xec, 0x95, 0x78, 0x28, 0x51, 0xa9, + 0x57, 0x63, 0xe2, 0xff, 0x4d, 0x48, 0x8d, 0x5d, 0xf9, 0x86, 0x29, 0xb2, 0xd5, 0x1d, 0xbc, 0x85, + 0x19, 0x0d, 0x35, 0xa7, 0x61, 0x2b, 0x75, 0xf1, 0x4b, 0x65, 0xa4, 0x83, 0xd8, 0xd0, 0xc5, 0x76, + 0xbe, 0xa1, 0x6b, 0x06, 0x91, 0x27, 0x47, 0x51, 0xec, 0xfc, 0x7a, 0xb5, 0x4e, 0x5c, 0x1f, 0x67, + 0x0d, 0x9d, 0xfd, 0xff, 0x56, 0xf1, 0xed, 0x5d, 0x80, 0xe9, 0xd0, 0xd0, 0x2a, 0x64, 0xea, 0x1b, + 0xbd, 0xde, 0x96, 0x32, 0x27, 0x02, 0xf8, 0x94, 0xc5, 0xc9, 0xea, 0x5f, 0x24, 0x21, 0x57, 0xaf, + 0xca, 0x63, 0xb5, 0x0e, 0x0a, 0x8f, 0x4a, 0xfc, 0xce, 0x9d, 0x3c, 0x1b, 0x59, 0xee, 0x44, 0x06, + 0x96, 0x4b, 0x4a, 0xcf, 0x45, 0x26, 0xc2, 0xac, 0x6e, 0x72, 0x01, 0x84, 0xa1, 0x48, 0xa4, 0x13, + 0x34, 0x43, 0x0f, 0x62, 0xfc, 0xea, 0xe5, 0xce, 0x12, 0x45, 0xc4, 0xb4, 0xed, 0xe1, 0x42, 0xa0, + 0xa4, 0xae, 0x7b, 0xe8, 0x01, 0x2c, 0x79, 0xd6, 0xc0, 0xb1, 0x9c, 0x81, 0x16, 0x38, 0x8f, 0x3f, + 0x00, 0xd4, 0xae, 0x9d, 0x9d, 0xae, 0x2d, 0xf4, 0x04, 0x4b, 0xfa, 0x70, 0x41, 0x22, 0xeb, 0xdc, + 0x95, 0xe8, 0x43, 0x58, 0x8c, 0x88, 0x32, 0x2f, 0x0a, 0xb7, 0x2b, 0x67, 0xa7, 0x6b, 0xc5, 0x50, + 0xf2, 0x31, 0x99, 0xe0, 0x62, 0x28, 0xf8, 0x98, 0xf0, 0x5b, 0x92, 0x3d, 0xea, 0x1a, 0x44, 0x73, + 0xf9, 0x9e, 0xe6, 0x27, 0x78, 0x1a, 0x17, 0x38, 0x4d, 0x6c, 0x73, 0xf5, 0x09, 0x5c, 0xef, 0xb8, + 0xc6, 0x3e, 0xf1, 0x7c, 0xe1, 0x0a, 0xe9, 0xc5, 0x4f, 0xe1, 0x96, 0xaf, 0x7b, 0x07, 0xda, 0xbe, + 0xe5, 0xf9, 0xd4, 0x9d, 0x68, 0x2e, 0xf1, 0x89, 0xc3, 0xf8, 0x1a, 0x7f, 0x35, 0x94, 0xd7, 0x58, + 0x37, 0x19, 0x66, 0x53, 0x40, 0x70, 0x80, 0xd8, 0x62, 0x00, 0xb5, 0x05, 0x45, 0x56, 0x4c, 0x34, + 0xc8, 0x9e, 0x3e, 0xb6, 0x7d, 0x36, 0x7a, 0xb0, 0xe9, 0x40, 0x7b, 0xe9, 0x63, 0x2a, 0x6f, 0xd3, + 0x81, 0xf8, 0x54, 0x7f, 0x08, 0x4a, 0xc3, 0xf2, 0x46, 0xba, 0x6f, 0xec, 0x07, 0xf7, 0x73, 0xa8, + 0x01, 0xca, 0x3e, 0xd1, 0x5d, 0x7f, 0x97, 0xe8, 0xbe, 0x36, 0x22, 0xae, 0x45, 0xcd, 0xab, 0x67, + 0x79, 0x29, 0x14, 0xe9, 0x72, 0x09, 0xf5, 0xbf, 0x12, 0x00, 0x58, 0xdf, 0x0b, 0x32, 0xb2, 0xef, + 0xc3, 0x35, 0xcf, 0xd1, 0x47, 0xde, 0x3e, 0xf5, 0x35, 0xcb, 0xf1, 0x89, 0x7b, 0xa8, 0xdb, 0xf2, + 0x9a, 0x45, 0x09, 0x18, 0x2d, 0x49, 0x47, 0xef, 0x02, 0x3a, 0x20, 0x64, 0xa4, 0x51, 0xdb, 0xd4, + 0x02, 0xa6, 0x78, 0xd3, 0x4c, 0x63, 0x85, 0x71, 0x3a, 0xb6, 0xd9, 0x0b, 0xe8, 0xa8, 0x06, 0xab, + 0x6c, 0xf8, 0xc4, 0xf1, 0x5d, 0x8b, 0x78, 0xda, 0x1e, 0x75, 0x35, 0xcf, 0xa6, 0x47, 0xda, 0x1e, + 0xb5, 0x6d, 0x7a, 0x44, 0xdc, 0xe0, 0x06, 0xab, 0x64, 0xd3, 0x41, 0x53, 0x80, 0x36, 0xa8, 0xdb, + 0xb3, 0xe9, 0xd1, 0x46, 0x80, 0x60, 0x69, 0xdb, 0x74, 0xcc, 0xbe, 0x65, 0x1c, 0x04, 0x69, 0x5b, + 0x48, 0xed, 0x5b, 0xc6, 0x01, 0x7a, 0x1d, 0x16, 0x88, 0x4d, 0xf8, 0x45, 0x86, 0x40, 0x65, 0x38, + 0xaa, 0x18, 0x10, 0x19, 0x48, 0xfd, 0x0c, 0x94, 0xa6, 0x63, 0xb8, 0x93, 0x51, 0x64, 0xce, 0xdf, + 0x05, 0xc4, 0x82, 0xa4, 0x66, 0x53, 0xe3, 0x40, 0x1b, 0xea, 0x8e, 0x3e, 0x60, 0x76, 0x89, 0xa7, + 0x26, 0x85, 0x71, 0xb6, 0xa8, 0x71, 0xb0, 0x2d, 0xe9, 0xea, 0x03, 0x80, 0xde, 0xc8, 0x25, 0xba, + 0xd9, 0x61, 0xd9, 0x04, 0x73, 0x1d, 0x6f, 0x69, 0xa6, 0x7c, 0xaa, 0xa3, 0xae, 0xdc, 0xea, 0x8a, + 0x60, 0x34, 0x42, 0xba, 0xfa, 0x0b, 0x70, 0xbd, 0x6b, 0xeb, 0x06, 0x7f, 0xb6, 0xee, 0x86, 0x6f, + 0x27, 0xe8, 0x3e, 0x64, 0x05, 0x54, 0xce, 0x64, 0xec, 0x76, 0x9b, 0xf6, 0xb9, 0x39, 0x87, 0x25, + 0xbe, 0x56, 0x04, 0x98, 0xea, 0x51, 0xff, 0x2c, 0x01, 0xf9, 0x50, 0x3f, 0x2a, 0x03, 0x2b, 0xe5, + 0xd9, 0xf2, 0xb6, 0x1c, 0x59, 0x7b, 0xe7, 0x71, 0x94, 0x84, 0x5a, 0x50, 0x18, 0x85, 0xd2, 0x97, + 0xe6, 0x73, 0x31, 0x56, 0xe3, 0xa8, 0x2c, 0xfa, 0x08, 0xf2, 0xc1, 0xdb, 0x68, 0x10, 0x61, 0x2f, + 0x7f, 0x4a, 0x9d, 0xc2, 0xd5, 0x4f, 0x00, 0x7e, 0x40, 0x2d, 0xa7, 0x4f, 0x0f, 0x88, 0xc3, 0xdf, + 0xfa, 0x58, 0x4d, 0x48, 0x02, 0x2f, 0xca, 0x16, 0x2f, 0xc8, 0xc5, 0x14, 0x84, 0x4f, 0x5e, 0xa2, + 0xa9, 0xfe, 0x75, 0x12, 0xb2, 0x98, 0x52, 0xbf, 0x5e, 0x45, 0x65, 0xc8, 0xca, 0x38, 0xc1, 0xcf, + 0x9f, 0x5a, 0xfe, 0xec, 0x74, 0x2d, 0x23, 0x02, 0x44, 0xc6, 0xe0, 0x91, 0x21, 0x12, 0xc1, 0x93, + 0x17, 0x45, 0x70, 0x74, 0x07, 0x8a, 0x12, 0xa4, 0xed, 0xeb, 0xde, 0xbe, 0x28, 0xd0, 0x6a, 0x8b, + 0x67, 0xa7, 0x6b, 0x20, 0x90, 0x9b, 0xba, 0xb7, 0x8f, 0x41, 0xa0, 0xd9, 0x37, 0x6a, 0x42, 0xe1, + 0x0b, 0x6a, 0x39, 0x9a, 0xcf, 0x07, 0x21, 0xaf, 0xfc, 0x62, 0xe7, 0x71, 0x3a, 0x54, 0xf9, 0xf0, + 0x0d, 0x5f, 0x4c, 0x07, 0xdf, 0x84, 0x05, 0x97, 0x52, 0x5f, 0x84, 0x2d, 0x8b, 0x3a, 0xf2, 0x36, + 0xa1, 0x1c, 0x7b, 0xc9, 0x4c, 0xa9, 0x8f, 0x25, 0x0e, 0x17, 0xdd, 0x48, 0x0b, 0xdd, 0x81, 0x65, + 0x5b, 0xf7, 0x7c, 0x8d, 0xc7, 0x3b, 0x73, 0xaa, 0x2d, 0xcb, 0xb7, 0x1a, 0x62, 0xbc, 0x0d, 0xce, + 0x0a, 0x24, 0xd4, 0x7f, 0x4c, 0x40, 0x81, 0x0d, 0xc6, 0xda, 0xb3, 0x0c, 0x96, 0xe4, 0x7d, 0xf3, + 0xdc, 0xe3, 0x26, 0xa4, 0x0c, 0xcf, 0x95, 0x4e, 0xe5, 0x87, 0x6f, 0xbd, 0x87, 0x31, 0xa3, 0xa1, + 0xcf, 0x20, 0x2b, 0x6f, 0x35, 0x44, 0xda, 0xa1, 0x5e, 0x9d, 0x8e, 0x4a, 0xdf, 0x48, 0x39, 0xbe, + 0x96, 0xa7, 0xd6, 0x89, 0x43, 0x00, 0x47, 0x49, 0xe8, 0x06, 0x24, 0x0d, 0xe1, 0x2e, 0xf9, 0xcb, + 0x8a, 0x7a, 0x1b, 0x27, 0x0d, 0x47, 0xfd, 0xbb, 0x04, 0x2c, 0x4c, 0x37, 0x3c, 0x5b, 0x01, 0xb7, + 0x20, 0xef, 0x8d, 0x77, 0xbd, 0x89, 0xe7, 0x93, 0x61, 0xf0, 0x8e, 0x19, 0x12, 0x50, 0x0b, 0xf2, + 0xba, 0x3d, 0xa0, 0xae, 0xe5, 0xef, 0x0f, 0x65, 0x25, 0x1a, 0x9f, 0x2a, 0x44, 0x75, 0x56, 0xaa, + 0x81, 0x08, 0x9e, 0x4a, 0x07, 0xe7, 0xbe, 0x78, 0xec, 0xe6, 0xe7, 0xfe, 0x6b, 0x50, 0xb4, 0xf5, + 0x21, 0xbf, 0xe6, 0xf1, 0xad, 0xa1, 0x18, 0x47, 0x1a, 0x17, 0x24, 0xad, 0x6f, 0x0d, 0x89, 0xaa, + 0x42, 0x3e, 0x54, 0x86, 0x96, 0xa0, 0x50, 0x6d, 0xf6, 0xb4, 0xbb, 0xeb, 0xf7, 0xb5, 0x47, 0xf5, + 0x6d, 0x65, 0x4e, 0xe6, 0xa6, 0x7f, 0x9e, 0x80, 0x05, 0x19, 0x8e, 0x64, 0xbe, 0xff, 0x3a, 0xcc, + 0xbb, 0xfa, 0x9e, 0x1f, 0x54, 0x24, 0x69, 0xb1, 0xaa, 0x59, 0x84, 0x67, 0x15, 0x09, 0x63, 0xc5, + 0x57, 0x24, 0x91, 0x97, 0xf5, 0xd4, 0xa5, 0x2f, 0xeb, 0xe9, 0x9f, 0xcb, 0xcb, 0xba, 0xfa, 0x6b, + 0x00, 0x1b, 0x96, 0x4d, 0xfa, 0xe2, 0xae, 0x29, 0xae, 0xbe, 0x64, 0x39, 0x9c, 0xbc, 0x71, 0x0c, + 0x72, 0xb8, 0x56, 0x03, 0x33, 0x1a, 0x63, 0x0d, 0x2c, 0x53, 0x6e, 0x46, 0xce, 0x7a, 0xc4, 0x58, + 0x03, 0xcb, 0x0c, 0xdf, 0x92, 0xd2, 0x57, 0xbd, 0x25, 0x9d, 0x24, 0x60, 0x49, 0xe6, 0xae, 0x61, + 0xf8, 0x7d, 0x1b, 0xf2, 0x22, 0x8d, 0x9d, 0x16, 0x74, 0xfc, 0x35, 0x59, 0xe0, 0x5a, 0x0d, 0x9c, + 0x13, 0xec, 0x96, 0x89, 0xd6, 0xa0, 0x20, 0xa1, 0x91, 0x5f, 0xe1, 0x80, 0x20, 0xb5, 0x99, 0xf9, + 0xef, 0x43, 0x7a, 0xcf, 0xb2, 0x89, 0x5c, 0xe8, 0xb1, 0x01, 0x60, 0xea, 0x80, 0xcd, 0x39, 0xcc, + 0xd1, 0xb5, 0x5c, 0x70, 0x19, 0xc7, 0xed, 0x93, 0x65, 0x67, 0xd4, 0x3e, 0x51, 0x81, 0x9e, 0xb3, + 0x4f, 0xe0, 0x98, 0x7d, 0x82, 0x2d, 0xec, 0x93, 0xd0, 0xa8, 0x7d, 0x82, 0xf4, 0x73, 0xb1, 0x6f, + 0x0b, 0x6e, 0xd4, 0x6c, 0xdd, 0x38, 0xb0, 0x2d, 0xcf, 0x27, 0x66, 0x34, 0x62, 0xac, 0x43, 0x76, + 0x26, 0xe9, 0xbc, 0xec, 0x72, 0x56, 0x22, 0xd5, 0x7f, 0x4b, 0x40, 0x71, 0x93, 0xe8, 0xb6, 0xbf, + 0x3f, 0xbd, 0x1a, 0xf2, 0x89, 0xe7, 0xcb, 0xc3, 0x8a, 0x7f, 0xa3, 0x0f, 0x20, 0x17, 0xe6, 0x24, + 0x57, 0xbe, 0x92, 0x85, 0x50, 0x74, 0x0f, 0xe6, 0xd9, 0x1e, 0xa3, 0xe3, 0xa0, 0xd8, 0xb9, 0xec, + 0x01, 0x46, 0x22, 0xd9, 0x21, 0xe3, 0x12, 0x9e, 0x84, 0xf0, 0xa5, 0x94, 0xc1, 0x41, 0x13, 0xfd, + 0x7f, 0x28, 0xf2, 0xf7, 0x83, 0x20, 0xe7, 0xca, 0x5c, 0xa5, 0xb3, 0x20, 0x9e, 0x00, 0x45, 0xbe, + 0xf5, 0x3f, 0x09, 0x58, 0xde, 0xd6, 0x27, 0xbb, 0x44, 0x86, 0x0d, 0x62, 0x62, 0x62, 0x50, 0xd7, + 0x44, 0xdd, 0x68, 0xb8, 0xb9, 0xe4, 0x45, 0x31, 0x4e, 0x38, 0x3e, 0xea, 0x04, 0x05, 0x58, 0x32, + 0x52, 0x80, 0x2d, 0x43, 0xc6, 0xa1, 0x8e, 0x41, 0x64, 0x2c, 0x12, 0x0d, 0xd5, 0x8a, 0x86, 0x9a, + 0x52, 0xf8, 0xd8, 0xc7, 0x9f, 0xea, 0xda, 0xd4, 0x0f, 0x7b, 0x43, 0x9f, 0x41, 0xa9, 0xd7, 0xac, + 0xe3, 0x66, 0xbf, 0xd6, 0xf9, 0xa1, 0xd6, 0xab, 0x6e, 0xf5, 0xaa, 0xeb, 0x77, 0xb4, 0x6e, 0x67, + 0xeb, 0xf3, 0xbb, 0xf7, 0xee, 0x7c, 0xa0, 0x24, 0x4a, 0xe5, 0xe3, 0x93, 0xf2, 0xad, 0x76, 0xb5, + 0xbe, 0x25, 0x76, 0xcc, 0x2e, 0x7d, 0xd6, 0xd3, 0x6d, 0x4f, 0x5f, 0xbf, 0xd3, 0xa5, 0xf6, 0x84, + 0x61, 0xd8, 0xb2, 0x2e, 0x46, 0xcf, 0xab, 0xe8, 0x31, 0x9c, 0xb8, 0xf0, 0x18, 0x9e, 0x9e, 0xe6, + 0xc9, 0x0b, 0x4e, 0xf3, 0x0d, 0x58, 0x36, 0x5c, 0xea, 0x79, 0x1a, 0xcb, 0xfe, 0x89, 0x79, 0xae, + 0xbe, 0xf8, 0xce, 0xd9, 0xe9, 0xda, 0xb5, 0x3a, 0xe3, 0xf7, 0x38, 0x5b, 0xaa, 0xbf, 0x66, 0x44, + 0x48, 0xbc, 0x27, 0xf5, 0xf7, 0x53, 0x2c, 0x91, 0xb2, 0x0e, 0x2d, 0x9b, 0x0c, 0x88, 0x87, 0x9e, + 0xc0, 0x92, 0xe1, 0x12, 0x93, 0xa5, 0xf5, 0xba, 0xad, 0x79, 0x23, 0x62, 0xc8, 0x45, 0xfd, 0xff, + 0x62, 0x73, 0x9a, 0x50, 0xb0, 0x52, 0x0f, 0xa5, 0x7a, 0x23, 0x62, 0xe0, 0x45, 0x63, 0xa6, 0x8d, + 0xbe, 0x80, 0x25, 0x8f, 0xd8, 0x96, 0x33, 0x7e, 0xa6, 0x19, 0xd4, 0xf1, 0xc9, 0xb3, 0xe0, 0xdd, + 0xea, 0x2a, 0xbd, 0xbd, 0xe6, 0x16, 0x93, 0xaa, 0x0b, 0xa1, 0x1a, 0x3a, 0x3b, 0x5d, 0x5b, 0x9c, + 0xa5, 0xe1, 0x45, 0xa9, 0x59, 0xb6, 0x4b, 0x6d, 0x58, 0x9c, 0xb5, 0x06, 0x2d, 0xcb, 0xbd, 0xcf, + 0x43, 0x48, 0xb0, 0xb7, 0xd1, 0x2d, 0xc8, 0xb9, 0x64, 0x60, 0x79, 0xbe, 0x2b, 0xdc, 0xcc, 0x38, + 0x21, 0x85, 0xed, 0x7c, 0xf1, 0x53, 0x9c, 0xd2, 0xaf, 0xc0, 0xb9, 0x1e, 0xd9, 0x66, 0x31, 0x2d, + 0x4f, 0xdf, 0x95, 0x2a, 0x73, 0x38, 0x68, 0xb2, 0x35, 0x38, 0xf6, 0xc2, 0x44, 0x8d, 0x7f, 0x33, + 0x1a, 0xcf, 0x28, 0xe4, 0x0f, 0x93, 0x78, 0xce, 0x10, 0xfc, 0xc2, 0x31, 0x1d, 0xf9, 0x85, 0xe3, + 0x32, 0x64, 0x6c, 0x72, 0x48, 0x6c, 0x71, 0x96, 0x63, 0xd1, 0x78, 0xe7, 0x67, 0x29, 0xc8, 0x87, + 0x6f, 0x34, 0xec, 0x24, 0x68, 0x37, 0x9f, 0x06, 0x6b, 0x35, 0xa4, 0xb7, 0xc9, 0x11, 0x7a, 0x6d, + 0x7a, 0xa7, 0xf4, 0x99, 0x78, 0x94, 0x0e, 0xd9, 0xc1, 0x7d, 0xd2, 0x1b, 0x90, 0xab, 0xf6, 0x7a, + 0xad, 0x47, 0xed, 0x66, 0x43, 0xf9, 0x32, 0x51, 0xfa, 0xce, 0xf1, 0x49, 0xf9, 0x5a, 0x08, 0xaa, + 0x7a, 0x62, 0x29, 0x71, 0x54, 0xbd, 0xde, 0xec, 0xf6, 0x9b, 0x0d, 0xe5, 0x79, 0xf2, 0x3c, 0x8a, + 0xdf, 0x91, 0xf0, 0x9f, 0x96, 0xe4, 0xbb, 0xb8, 0xd9, 0xad, 0x62, 0xd6, 0xe1, 0x97, 0x49, 0x71, + 0xd5, 0x35, 0xed, 0xd1, 0x25, 0x23, 0x9d, 0xff, 0xae, 0x78, 0x35, 0xf8, 0x89, 0xd5, 0xf3, 0x94, + 0xf8, 0xf9, 0xc1, 0xf4, 0xc1, 0x89, 0xe8, 0xe6, 0x84, 0xf5, 0xc6, 0x5f, 0xfa, 0xb8, 0x9a, 0xd4, + 0xb9, 0xde, 0x7a, 0x2c, 0x92, 0x30, 0x2d, 0x2a, 0xcc, 0xe3, 0x9d, 0x76, 0x9b, 0x81, 0x9e, 0xa7, + 0xcf, 0x8d, 0x0e, 0x8f, 0x1d, 0x56, 0xff, 0xa2, 0xdb, 0x90, 0x0b, 0x1e, 0x02, 0x95, 0x2f, 0xd3, + 0xe7, 0x0c, 0xaa, 0x07, 0xaf, 0x98, 0xbc, 0xc3, 0xcd, 0x9d, 0x3e, 0xff, 0x05, 0xd8, 0xf3, 0xcc, + 0xf9, 0x0e, 0xf7, 0xc7, 0xbe, 0x49, 0x8f, 0x1c, 0xb6, 0x03, 0xe5, 0xad, 0xda, 0x97, 0x19, 0x71, + 0x05, 0x11, 0x62, 0xe4, 0x95, 0xda, 0x1b, 0x90, 0xc3, 0xcd, 0x1f, 0x88, 0x1f, 0x8b, 0x3d, 0xcf, + 0x9e, 0xd3, 0x83, 0xc9, 0x17, 0xc4, 0x90, 0xbd, 0x75, 0x70, 0x77, 0xb3, 0xca, 0x5d, 0x7e, 0x1e, + 0xd5, 0x71, 0x47, 0xfb, 0xba, 0x43, 0xcc, 0xe9, 0x6f, 0x30, 0x42, 0xd6, 0x3b, 0xbf, 0x08, 0xb9, + 0x20, 0xcf, 0x44, 0xab, 0x90, 0x7d, 0xda, 0xc1, 0x8f, 0x9b, 0x58, 0x99, 0x13, 0x3e, 0x0c, 0x38, + 0x4f, 0x45, 0x85, 0x50, 0x86, 0xf9, 0xed, 0x6a, 0xbb, 0xfa, 0xa8, 0x89, 0x83, 0x0b, 0xef, 0x00, + 0x20, 0x93, 0xa5, 0x92, 0x22, 0x3b, 0x08, 0x75, 0xd6, 0x56, 0xbe, 0xfa, 0x7a, 0x75, 0xee, 0xa7, + 0x5f, 0xaf, 0xce, 0x3d, 0x3f, 0x5b, 0x4d, 0x7c, 0x75, 0xb6, 0x9a, 0xf8, 0xc9, 0xd9, 0x6a, 0xe2, + 0x5f, 0xcf, 0x56, 0x13, 0xbb, 0x59, 0x1e, 0xd2, 0xef, 0xfd, 0x6f, 0x00, 0x00, 0x00, 0xff, 0xff, + 0xdb, 0x9d, 0xe2, 0x3d, 0xd2, 0x2f, 0x00, 0x00, } diff --git a/components/engine/vendor/github.com/docker/swarmkit/api/types.proto b/components/engine/vendor/github.com/docker/swarmkit/api/types.proto index 719b88a9c6..201bc3587f 100644 --- a/components/engine/vendor/github.com/docker/swarmkit/api/types.proto +++ b/components/engine/vendor/github.com/docker/swarmkit/api/types.proto @@ -30,12 +30,32 @@ message Annotations { repeated IndexEntry indices = 4 [(gogoproto.nullable) = false]; } +message GenericString { + string kind = 1; + string value = 2; +} + +message GenericDiscrete { + string kind = 1; + int64 value = 2; +} + +message GenericResource { + oneof resource { + GenericString str = 1; + GenericDiscrete discrete = 2; + } +} + message Resources { // Amount of CPUs (e.g. 2000000000 = 2 CPU cores) int64 nano_cpus = 1 [(gogoproto.customname) = "NanoCPUs"]; // Amount of memory in bytes. int64 memory_bytes = 2; + + // User specified resource (e.g: bananas=2;apple={red,yellow,green}) + repeated GenericResource generic = 3; } message ResourceRequirements { diff --git a/components/engine/vendor/github.com/docker/swarmkit/ca/certificates.go b/components/engine/vendor/github.com/docker/swarmkit/ca/certificates.go index 37c8a172de..642c07772b 100644 --- a/components/engine/vendor/github.com/docker/swarmkit/ca/certificates.go +++ b/components/engine/vendor/github.com/docker/swarmkit/ca/certificates.go @@ -871,7 +871,7 @@ func GetRemoteSignedCertificate(ctx context.Context, csr []byte, rootCAPool *x50 caClient = api.NewNodeCAClient(conn.ClientConn) // If there was no deadline exceeded error, and the certificate was issued, return - case err == nil && statusResponse.Status.State == api.IssuanceStateIssued: + case err == nil && (statusResponse.Status.State == api.IssuanceStateIssued || statusResponse.Status.State == api.IssuanceStateRotate): if statusResponse.Certificate == nil { conn.Close(false) return nil, errors.New("no certificate in CertificateStatus response") diff --git a/components/engine/vendor/github.com/docker/swarmkit/ca/config.go b/components/engine/vendor/github.com/docker/swarmkit/ca/config.go index 2aaaf78aba..8f16cc22b5 100644 --- a/components/engine/vendor/github.com/docker/swarmkit/ca/config.go +++ b/components/engine/vendor/github.com/docker/swarmkit/ca/config.go @@ -89,6 +89,39 @@ type CertificateUpdate struct { Err error } +func validateRootCAAndTLSCert(rootCA *RootCA, externalCARootPool *x509.CertPool, tlsKeyPair *tls.Certificate) error { + var ( + leafCert *x509.Certificate + intermediatePool *x509.CertPool + ) + for i, derBytes := range tlsKeyPair.Certificate { + parsed, err := x509.ParseCertificate(derBytes) + if err != nil { + return errors.Wrap(err, "could not validate new root certificates due to parse error") + } + if i == 0 { + leafCert = parsed + } else { + if intermediatePool == nil { + intermediatePool = x509.NewCertPool() + } + intermediatePool.AddCert(parsed) + } + } + opts := x509.VerifyOptions{ + Roots: rootCA.Pool, + Intermediates: intermediatePool, + } + if _, err := leafCert.Verify(opts); err != nil { + return errors.Wrap(err, "new root CA does not match existing TLS credentials") + } + opts.Roots = externalCARootPool + if _, err := leafCert.Verify(opts); err != nil { + return errors.Wrap(err, "new external root pool does not match existing TLS credentials") + } + return nil +} + // NewSecurityConfig initializes and returns a new SecurityConfig. func NewSecurityConfig(rootCA *RootCA, krw *KeyReadWriter, tlsKeyPair *tls.Certificate, issuerInfo *IssuerInfo) (*SecurityConfig, error) { // Create the Server TLS Credentials for this node. These will not be used by workers. @@ -155,8 +188,15 @@ func (s *SecurityConfig) UpdateRootCA(rootCA *RootCA, externalCARootPool *x509.C s.mu.Lock() defer s.mu.Unlock() + // refuse to update the root CA if the current TLS credentials do not validate against it + if err := validateRootCAAndTLSCert(rootCA, externalCARootPool, s.certificate); err != nil { + return err + } + s.rootCA = rootCA s.externalCAClientRootPool = externalCARootPool + s.externalCA.UpdateRootCA(rootCA) + return s.updateTLSCredentials(s.certificate, s.issuerInfo) } @@ -215,6 +255,13 @@ func (s *SecurityConfig) updateTLSCredentials(certificate *tls.Certificate, issu return nil } +// UpdateTLSCredentials updates the security config with an updated TLS certificate and issuer info +func (s *SecurityConfig) UpdateTLSCredentials(certificate *tls.Certificate, issuerInfo *IssuerInfo) error { + s.mu.Lock() + defer s.mu.Unlock() + return s.updateTLSCredentials(certificate, issuerInfo) +} + // SigningPolicy creates a policy used by the signer to ensure that the only fields // from the remote CSRs we trust are: PublicKey, PublicKeyAlgorithm and SignatureAlgorithm. // It receives the duration a certificate will be valid for @@ -470,9 +517,7 @@ func RenewTLSConfigNow(ctx context.Context, s *SecurityConfig, connBroker *conne return err } - s.mu.Lock() - defer s.mu.Unlock() - return s.updateTLSCredentials(tlsKeyPair, issuerInfo) + return s.UpdateTLSCredentials(tlsKeyPair, issuerInfo) } // calculateRandomExpiry returns a random duration between 50% and 80% of the diff --git a/components/engine/vendor/github.com/docker/swarmkit/ca/external.go b/components/engine/vendor/github.com/docker/swarmkit/ca/external.go index 6f23ff1fbf..d6a9421e0d 100644 --- a/components/engine/vendor/github.com/docker/swarmkit/ca/external.go +++ b/components/engine/vendor/github.com/docker/swarmkit/ca/external.go @@ -18,11 +18,15 @@ import ( "github.com/cloudflare/cfssl/config" "github.com/cloudflare/cfssl/csr" "github.com/cloudflare/cfssl/signer" + "github.com/docker/swarmkit/log" "github.com/pkg/errors" "golang.org/x/net/context" "golang.org/x/net/context/ctxhttp" ) +// ExternalCrossSignProfile is the profile that we will be sending cross-signing CSR sign requests with +const ExternalCrossSignProfile = "CA" + // ErrNoExternalCAURLs is an error used it indicate that an ExternalCA is // configured with no URLs to which it can proxy certificate signing requests. var ErrNoExternalCAURLs = errors.New("no external CA URLs") @@ -79,8 +83,7 @@ func (eca *ExternalCA) UpdateTLSConfig(tlsConfig *tls.Config) { } } -// UpdateURLs updates the list of CSR API endpoints by setting it to the given -// urls. +// UpdateURLs updates the list of CSR API endpoints by setting it to the given urls. func (eca *ExternalCA) UpdateURLs(urls ...string) { eca.mu.Lock() defer eca.mu.Unlock() @@ -88,6 +91,13 @@ func (eca *ExternalCA) UpdateURLs(urls ...string) { eca.urls = urls } +// UpdateRootCA changes the root CA used to append intermediates +func (eca *ExternalCA) UpdateRootCA(rca *RootCA) { + eca.mu.Lock() + eca.rootCA = rca + eca.mu.Unlock() +} + // Sign signs a new certificate by proxying the given certificate signing // request to an external CFSSL API server. func (eca *ExternalCA) Sign(ctx context.Context, req signer.SignRequest) (cert []byte, err error) { @@ -96,6 +106,7 @@ func (eca *ExternalCA) Sign(ctx context.Context, req signer.SignRequest) (cert [ eca.mu.Lock() urls := eca.urls client := eca.client + intermediates := eca.rootCA.Intermediates eca.mu.Unlock() if len(urls) == 0 { @@ -114,9 +125,9 @@ func (eca *ExternalCA) Sign(ctx context.Context, req signer.SignRequest) (cert [ cert, err = makeExternalSignRequest(requestCtx, client, url, csrJSON) cancel() if err == nil { - return append(cert, eca.rootCA.Intermediates...), err + return append(cert, intermediates...), err } - logrus.Debugf("unable to proxy certificate signing request to %s: %s", url, err) + log.G(ctx).Debugf("unable to proxy certificate signing request to %s: %s", url, err) } return nil, err @@ -157,6 +168,7 @@ func (eca *ExternalCA) CrossSignRootCA(ctx context.Context, rca RootCA) ([]byte, CN: rootCert.Subject.CommonName, Names: cfCSRObj.Names, }, + Profile: ExternalCrossSignProfile, } // cfssl actually ignores non subject alt name extensions in the CSR, so we have to add the CA extension in the signing // request as well diff --git a/components/engine/vendor/github.com/docker/swarmkit/ca/reconciler.go b/components/engine/vendor/github.com/docker/swarmkit/ca/reconciler.go index 6651393b50..6daec76d39 100644 --- a/components/engine/vendor/github.com/docker/swarmkit/ca/reconciler.go +++ b/components/engine/vendor/github.com/docker/swarmkit/ca/reconciler.go @@ -99,7 +99,7 @@ func (r *rootRotationReconciler) UpdateRootCA(newRootCA *api.RootCA) { if newRootCA.RootRotation != nil { var nodes []*api.Node r.store.View(func(tx store.ReadTx) { - nodes, err = store.FindNodes(tx, store.ByMembership(api.NodeMembershipAccepted)) + nodes, err = store.FindNodes(tx, store.All) }) if err != nil { log.G(r.ctx).WithError(err).Error("unable to list nodes, so unable to process the current root CA") @@ -132,8 +132,8 @@ func (r *rootRotationReconciler) UpdateRootCA(newRootCA *api.RootCA) { func (r *rootRotationReconciler) UpdateNode(node *api.Node) { r.mu.Lock() defer r.mu.Unlock() - // if we're not in the middle of a root rotation, or if this node does not have membership, ignore it - if r.currentRootCA == nil || r.currentRootCA.RootRotation == nil || node.Spec.Membership != api.NodeMembershipAccepted { + // if we're not in the middle of a root rotation ignore the update + if r.currentRootCA == nil || r.currentRootCA.RootRotation == nil { return } if hasIssuer(node, &r.currentIssuer) { diff --git a/components/engine/vendor/github.com/docker/swarmkit/manager/allocator/allocator.go b/components/engine/vendor/github.com/docker/swarmkit/manager/allocator/allocator.go index 95528e750e..5ca50623bb 100644 --- a/components/engine/vendor/github.com/docker/swarmkit/manager/allocator/allocator.go +++ b/components/engine/vendor/github.com/docker/swarmkit/manager/allocator/allocator.go @@ -51,13 +51,6 @@ type taskBallot struct { // allocActor controls the various phases in the lifecycle of one kind of allocator. type allocActor struct { - // Channel through which the allocator gets all the events - // that it is interested in. - ch chan events.Event - - // cancel unregisters the watcher. - cancel func() - // Task voter identity of the allocator. taskVoter string @@ -90,7 +83,10 @@ func New(store *store.MemoryStore, pg plugingetter.PluginGetter) (*Allocator, er func (a *Allocator) Run(ctx context.Context) error { // Setup cancel context for all goroutines to use. ctx, cancel := context.WithCancel(ctx) - var wg sync.WaitGroup + var ( + wg sync.WaitGroup + actors []func() error + ) defer func() { cancel() @@ -98,26 +94,8 @@ func (a *Allocator) Run(ctx context.Context) error { close(a.doneChan) }() - var actors []func() error - watch, watchCancel := state.Watch(a.store.WatchQueue(), - api.EventCreateNetwork{}, - api.EventDeleteNetwork{}, - api.EventCreateService{}, - api.EventUpdateService{}, - api.EventDeleteService{}, - api.EventCreateTask{}, - api.EventUpdateTask{}, - api.EventDeleteTask{}, - api.EventCreateNode{}, - api.EventUpdateNode{}, - api.EventDeleteNode{}, - state.EventCommit{}, - ) - for _, aa := range []allocActor{ { - ch: watch, - cancel: watchCancel, taskVoter: networkVoter, init: a.doNetworkInit, action: a.doNetworkAlloc, @@ -127,8 +105,8 @@ func (a *Allocator) Run(ctx context.Context) error { a.registerToVote(aa.taskVoter) } - // Copy the iterated value for variable capture. - aaCopy := aa + // Assign a pointer for variable capture + aaPtr := &aa actor := func() error { wg.Add(1) defer wg.Done() @@ -136,19 +114,19 @@ func (a *Allocator) Run(ctx context.Context) error { // init might return an allocator specific context // which is a child of the passed in context to hold // allocator specific state - if err := aaCopy.init(ctx); err != nil { - // Stop the watches for this allocator - // if we are failing in the init of - // this allocator. - aa.cancel() + watch, watchCancel, err := a.init(ctx, aaPtr) + if err != nil { return err } wg.Add(1) - go func() { - defer wg.Done() - a.run(ctx, aaCopy) - }() + go func(watch <-chan events.Event, watchCancel func()) { + defer func() { + wg.Done() + watchCancel() + }() + a.run(ctx, *aaPtr, watch) + }(watch, watchCancel) return nil } @@ -172,10 +150,34 @@ func (a *Allocator) Stop() { <-a.doneChan } -func (a *Allocator) run(ctx context.Context, aa allocActor) { +func (a *Allocator) init(ctx context.Context, aa *allocActor) (<-chan events.Event, func(), error) { + watch, watchCancel := state.Watch(a.store.WatchQueue(), + api.EventCreateNetwork{}, + api.EventDeleteNetwork{}, + api.EventCreateService{}, + api.EventUpdateService{}, + api.EventDeleteService{}, + api.EventCreateTask{}, + api.EventUpdateTask{}, + api.EventDeleteTask{}, + api.EventCreateNode{}, + api.EventUpdateNode{}, + api.EventDeleteNode{}, + state.EventCommit{}, + ) + + if err := aa.init(ctx); err != nil { + watchCancel() + return nil, nil, err + } + + return watch, watchCancel, nil +} + +func (a *Allocator) run(ctx context.Context, aa allocActor, watch <-chan events.Event) { for { select { - case ev, ok := <-aa.ch: + case ev, ok := <-watch: if !ok { return } diff --git a/components/engine/vendor/github.com/docker/swarmkit/manager/allocator/networkallocator/drivers_darwin.go b/components/engine/vendor/github.com/docker/swarmkit/manager/allocator/cnmallocator/drivers_darwin.go similarity index 65% rename from components/engine/vendor/github.com/docker/swarmkit/manager/allocator/networkallocator/drivers_darwin.go rename to components/engine/vendor/github.com/docker/swarmkit/manager/allocator/cnmallocator/drivers_darwin.go index 9b56f7be36..8cbedbd6b8 100644 --- a/components/engine/vendor/github.com/docker/swarmkit/manager/allocator/networkallocator/drivers_darwin.go +++ b/components/engine/vendor/github.com/docker/swarmkit/manager/allocator/cnmallocator/drivers_darwin.go @@ -1,8 +1,9 @@ -package networkallocator +package cnmallocator import ( "github.com/docker/libnetwork/drivers/overlay/ovmanager" "github.com/docker/libnetwork/drivers/remote" + "github.com/docker/swarmkit/manager/allocator/networkallocator" ) var initializers = []initializer{ @@ -11,6 +12,6 @@ var initializers = []initializer{ } // PredefinedNetworks returns the list of predefined network structures -func PredefinedNetworks() []PredefinedNetworkData { +func PredefinedNetworks() []networkallocator.PredefinedNetworkData { return nil } diff --git a/components/engine/vendor/github.com/docker/swarmkit/manager/allocator/networkallocator/drivers_ipam.go b/components/engine/vendor/github.com/docker/swarmkit/manager/allocator/cnmallocator/drivers_ipam.go similarity index 95% rename from components/engine/vendor/github.com/docker/swarmkit/manager/allocator/networkallocator/drivers_ipam.go rename to components/engine/vendor/github.com/docker/swarmkit/manager/allocator/cnmallocator/drivers_ipam.go index 56b944a1a7..eb854c56bf 100644 --- a/components/engine/vendor/github.com/docker/swarmkit/manager/allocator/networkallocator/drivers_ipam.go +++ b/components/engine/vendor/github.com/docker/swarmkit/manager/allocator/cnmallocator/drivers_ipam.go @@ -1,4 +1,4 @@ -package networkallocator +package cnmallocator import ( "github.com/docker/libnetwork/drvregistry" diff --git a/components/engine/vendor/github.com/docker/swarmkit/manager/allocator/networkallocator/drivers_network_linux.go b/components/engine/vendor/github.com/docker/swarmkit/manager/allocator/cnmallocator/drivers_network_linux.go similarity index 68% rename from components/engine/vendor/github.com/docker/swarmkit/manager/allocator/networkallocator/drivers_network_linux.go rename to components/engine/vendor/github.com/docker/swarmkit/manager/allocator/cnmallocator/drivers_network_linux.go index 035a904b18..5d6a0e74bf 100644 --- a/components/engine/vendor/github.com/docker/swarmkit/manager/allocator/networkallocator/drivers_network_linux.go +++ b/components/engine/vendor/github.com/docker/swarmkit/manager/allocator/cnmallocator/drivers_network_linux.go @@ -1,4 +1,4 @@ -package networkallocator +package cnmallocator import ( "github.com/docker/libnetwork/drivers/bridge/brmanager" @@ -7,6 +7,7 @@ import ( "github.com/docker/libnetwork/drivers/macvlan/mvmanager" "github.com/docker/libnetwork/drivers/overlay/ovmanager" "github.com/docker/libnetwork/drivers/remote" + "github.com/docker/swarmkit/manager/allocator/networkallocator" ) var initializers = []initializer{ @@ -19,9 +20,9 @@ var initializers = []initializer{ } // PredefinedNetworks returns the list of predefined network structures -func PredefinedNetworks() []PredefinedNetworkData { - return []PredefinedNetworkData{ - {"bridge", "bridge"}, - {"host", "host"}, +func PredefinedNetworks() []networkallocator.PredefinedNetworkData { + return []networkallocator.PredefinedNetworkData{ + {Name: "bridge", Driver: "bridge"}, + {Name: "host", Driver: "host"}, } } diff --git a/components/engine/vendor/github.com/docker/swarmkit/manager/allocator/networkallocator/drivers_network_windows.go b/components/engine/vendor/github.com/docker/swarmkit/manager/allocator/cnmallocator/drivers_network_windows.go similarity index 65% rename from components/engine/vendor/github.com/docker/swarmkit/manager/allocator/networkallocator/drivers_network_windows.go rename to components/engine/vendor/github.com/docker/swarmkit/manager/allocator/cnmallocator/drivers_network_windows.go index 9b56f7be36..8cbedbd6b8 100644 --- a/components/engine/vendor/github.com/docker/swarmkit/manager/allocator/networkallocator/drivers_network_windows.go +++ b/components/engine/vendor/github.com/docker/swarmkit/manager/allocator/cnmallocator/drivers_network_windows.go @@ -1,8 +1,9 @@ -package networkallocator +package cnmallocator import ( "github.com/docker/libnetwork/drivers/overlay/ovmanager" "github.com/docker/libnetwork/drivers/remote" + "github.com/docker/swarmkit/manager/allocator/networkallocator" ) var initializers = []initializer{ @@ -11,6 +12,6 @@ var initializers = []initializer{ } // PredefinedNetworks returns the list of predefined network structures -func PredefinedNetworks() []PredefinedNetworkData { +func PredefinedNetworks() []networkallocator.PredefinedNetworkData { return nil } diff --git a/components/engine/vendor/github.com/docker/swarmkit/manager/allocator/cnmallocator/drivers_unsupported.go b/components/engine/vendor/github.com/docker/swarmkit/manager/allocator/cnmallocator/drivers_unsupported.go new file mode 100644 index 0000000000..f9de277e38 --- /dev/null +++ b/components/engine/vendor/github.com/docker/swarmkit/manager/allocator/cnmallocator/drivers_unsupported.go @@ -0,0 +1,14 @@ +// +build !linux,!darwin,!windows + +package cnmallocator + +import ( + "github.com/docker/swarmkit/manager/allocator/networkallocator" +) + +const initializers = nil + +// PredefinedNetworks returns the list of predefined network structures +func PredefinedNetworks() []networkallocator.PredefinedNetworkData { + return nil +} diff --git a/components/engine/vendor/github.com/docker/swarmkit/manager/allocator/cnmallocator/networkallocator.go b/components/engine/vendor/github.com/docker/swarmkit/manager/allocator/cnmallocator/networkallocator.go new file mode 100644 index 0000000000..6d9193b308 --- /dev/null +++ b/components/engine/vendor/github.com/docker/swarmkit/manager/allocator/cnmallocator/networkallocator.go @@ -0,0 +1,957 @@ +package cnmallocator + +import ( + "fmt" + "net" + "strings" + + "github.com/docker/docker/pkg/plugingetter" + "github.com/docker/libnetwork/datastore" + "github.com/docker/libnetwork/driverapi" + "github.com/docker/libnetwork/drvregistry" + "github.com/docker/libnetwork/ipamapi" + "github.com/docker/libnetwork/netlabel" + "github.com/docker/swarmkit/api" + "github.com/docker/swarmkit/log" + "github.com/docker/swarmkit/manager/allocator/networkallocator" + "github.com/pkg/errors" + "golang.org/x/net/context" +) + +const ( + // DefaultDriver defines the name of the driver to be used by + // default if a network without any driver name specified is + // created. + DefaultDriver = "overlay" +) + +// cnmNetworkAllocator acts as the controller for all network related operations +// like managing network and IPAM drivers and also creating and +// deleting networks and the associated resources. +type cnmNetworkAllocator struct { + // The driver register which manages all internal and external + // IPAM and network drivers. + drvRegistry *drvregistry.DrvRegistry + + // The port allocator instance for allocating node ports + portAllocator *portAllocator + + // Local network state used by cnmNetworkAllocator to do network management. + networks map[string]*network + + // Allocator state to indicate if allocation has been + // successfully completed for this service. + services map[string]struct{} + + // Allocator state to indicate if allocation has been + // successfully completed for this task. + tasks map[string]struct{} + + // Allocator state to indicate if allocation has been + // successfully completed for this node. + nodes map[string]struct{} +} + +// Local in-memory state related to network that need to be tracked by cnmNetworkAllocator +type network struct { + // A local cache of the store object. + nw *api.Network + + // pools is used to save the internal poolIDs needed when + // releasing the pool. + pools map[string]string + + // endpoints is a map of endpoint IP to the poolID from which it + // was allocated. + endpoints map[string]string + + // isNodeLocal indicates whether the scope of the network's resources + // is local to the node. If true, it means the resources can only be + // allocated locally by the node where the network will be deployed. + // In this the swarm manager will skip the allocations. + isNodeLocal bool +} + +type networkDriver struct { + driver driverapi.Driver + name string + capability *driverapi.Capability +} + +type initializer struct { + fn drvregistry.InitFunc + ntype string +} + +// New returns a new NetworkAllocator handle +func New(pg plugingetter.PluginGetter) (networkallocator.NetworkAllocator, error) { + na := &cnmNetworkAllocator{ + networks: make(map[string]*network), + services: make(map[string]struct{}), + tasks: make(map[string]struct{}), + nodes: make(map[string]struct{}), + } + + // There are no driver configurations and notification + // functions as of now. + reg, err := drvregistry.New(nil, nil, nil, nil, pg) + if err != nil { + return nil, err + } + + if err := initializeDrivers(reg); err != nil { + return nil, err + } + + if err = initIPAMDrivers(reg); err != nil { + return nil, err + } + + pa, err := newPortAllocator() + if err != nil { + return nil, err + } + + na.portAllocator = pa + na.drvRegistry = reg + return na, nil +} + +// Allocate allocates all the necessary resources both general +// and driver-specific which may be specified in the NetworkSpec +func (na *cnmNetworkAllocator) Allocate(n *api.Network) error { + if _, ok := na.networks[n.ID]; ok { + return fmt.Errorf("network %s already allocated", n.ID) + } + + d, err := na.resolveDriver(n) + if err != nil { + return err + } + + nw := &network{ + nw: n, + endpoints: make(map[string]string), + isNodeLocal: d.capability.DataScope == datastore.LocalScope, + } + + // No swarm-level allocation can be provided by the network driver for + // node-local networks. Only thing needed is populating the driver's name + // in the driver's state. + if nw.isNodeLocal { + n.DriverState = &api.Driver{ + Name: d.name, + } + } else { + nw.pools, err = na.allocatePools(n) + if err != nil { + return errors.Wrapf(err, "failed allocating pools and gateway IP for network %s", n.ID) + } + + if err := na.allocateDriverState(n); err != nil { + na.freePools(n, nw.pools) + return errors.Wrapf(err, "failed while allocating driver state for network %s", n.ID) + } + } + + na.networks[n.ID] = nw + + return nil +} + +func (na *cnmNetworkAllocator) getNetwork(id string) *network { + return na.networks[id] +} + +// Deallocate frees all the general and driver specific resources +// which were assigned to the passed network. +func (na *cnmNetworkAllocator) Deallocate(n *api.Network) error { + localNet := na.getNetwork(n.ID) + if localNet == nil { + return fmt.Errorf("could not get networker state for network %s", n.ID) + } + + // No swarm-level resource deallocation needed for node-local networks + if localNet.isNodeLocal { + delete(na.networks, n.ID) + return nil + } + + if err := na.freeDriverState(n); err != nil { + return errors.Wrapf(err, "failed to free driver state for network %s", n.ID) + } + + delete(na.networks, n.ID) + + return na.freePools(n, localNet.pools) +} + +// AllocateService allocates all the network resources such as virtual +// IP and ports needed by the service. +func (na *cnmNetworkAllocator) AllocateService(s *api.Service) (err error) { + if err = na.portAllocator.serviceAllocatePorts(s); err != nil { + return err + } + defer func() { + if err != nil { + na.DeallocateService(s) + } + }() + + if s.Endpoint == nil { + s.Endpoint = &api.Endpoint{} + } + s.Endpoint.Spec = s.Spec.Endpoint.Copy() + + // If ResolutionMode is DNSRR do not try allocating VIPs, but + // free any VIP from previous state. + if s.Spec.Endpoint != nil && s.Spec.Endpoint.Mode == api.ResolutionModeDNSRoundRobin { + for _, vip := range s.Endpoint.VirtualIPs { + if err := na.deallocateVIP(vip); err != nil { + // don't bail here, deallocate as many as possible. + log.L.WithError(err). + WithField("vip.network", vip.NetworkID). + WithField("vip.addr", vip.Addr).Error("error deallocating vip") + } + } + + s.Endpoint.VirtualIPs = nil + + delete(na.services, s.ID) + return nil + } + + specNetworks := serviceNetworks(s) + + // Allocate VIPs for all the pre-populated endpoint attachments + eVIPs := s.Endpoint.VirtualIPs[:0] + +vipLoop: + for _, eAttach := range s.Endpoint.VirtualIPs { + if na.IsVIPOnIngressNetwork(eAttach) && networkallocator.IsIngressNetworkNeeded(s) { + if err = na.allocateVIP(eAttach); err != nil { + return err + } + eVIPs = append(eVIPs, eAttach) + continue vipLoop + + } + for _, nAttach := range specNetworks { + if nAttach.Target == eAttach.NetworkID { + if err = na.allocateVIP(eAttach); err != nil { + return err + } + eVIPs = append(eVIPs, eAttach) + continue vipLoop + } + } + // If the network of the VIP is not part of the service spec, + // deallocate the vip + na.deallocateVIP(eAttach) + } + +networkLoop: + for _, nAttach := range specNetworks { + for _, vip := range s.Endpoint.VirtualIPs { + if vip.NetworkID == nAttach.Target { + continue networkLoop + } + } + + vip := &api.Endpoint_VirtualIP{NetworkID: nAttach.Target} + if err = na.allocateVIP(vip); err != nil { + return err + } + + eVIPs = append(eVIPs, vip) + } + + if len(eVIPs) > 0 { + na.services[s.ID] = struct{}{} + } else { + delete(na.services, s.ID) + } + + s.Endpoint.VirtualIPs = eVIPs + return nil +} + +// DeallocateService de-allocates all the network resources such as +// virtual IP and ports associated with the service. +func (na *cnmNetworkAllocator) DeallocateService(s *api.Service) error { + if s.Endpoint == nil { + return nil + } + + for _, vip := range s.Endpoint.VirtualIPs { + if err := na.deallocateVIP(vip); err != nil { + // don't bail here, deallocate as many as possible. + log.L.WithError(err). + WithField("vip.network", vip.NetworkID). + WithField("vip.addr", vip.Addr).Error("error deallocating vip") + } + } + s.Endpoint.VirtualIPs = nil + + na.portAllocator.serviceDeallocatePorts(s) + delete(na.services, s.ID) + + return nil +} + +// IsAllocated returns if the passed network has been allocated or not. +func (na *cnmNetworkAllocator) IsAllocated(n *api.Network) bool { + _, ok := na.networks[n.ID] + return ok +} + +// IsTaskAllocated returns if the passed task has its network resources allocated or not. +func (na *cnmNetworkAllocator) IsTaskAllocated(t *api.Task) bool { + // If the task is not found in the allocated set, then it is + // not allocated. + if _, ok := na.tasks[t.ID]; !ok { + return false + } + + // If Networks is empty there is no way this Task is allocated. + if len(t.Networks) == 0 { + return false + } + + // To determine whether the task has its resources allocated, + // we just need to look at one global scope network (in case of + // multi-network attachment). This is because we make sure we + // allocate for every network or we allocate for none. + + // Find the first global scope network + for _, nAttach := range t.Networks { + // If the network is not allocated, the task cannot be allocated. + localNet, ok := na.networks[nAttach.Network.ID] + if !ok { + return false + } + + // Nothing else to check for local scope network + if localNet.isNodeLocal { + continue + } + + // Addresses empty. Task is not allocated. + if len(nAttach.Addresses) == 0 { + return false + } + + // The allocated IP address not found in local endpoint state. Not allocated. + if _, ok := localNet.endpoints[nAttach.Addresses[0]]; !ok { + return false + } + } + + return true +} + +// HostPublishPortsNeedUpdate returns true if the passed service needs +// allocations for its published ports in host (non ingress) mode +func (na *cnmNetworkAllocator) HostPublishPortsNeedUpdate(s *api.Service) bool { + return na.portAllocator.hostPublishPortsNeedUpdate(s) +} + +// IsServiceAllocated returns false if the passed service needs to have network resources allocated/updated. +func (na *cnmNetworkAllocator) IsServiceAllocated(s *api.Service, flags ...func(*networkallocator.ServiceAllocationOpts)) bool { + var options networkallocator.ServiceAllocationOpts + for _, flag := range flags { + flag(&options) + } + + specNetworks := serviceNetworks(s) + + // If endpoint mode is VIP and allocator does not have the + // service in VIP allocated set then it needs to be allocated. + if len(specNetworks) != 0 && + (s.Spec.Endpoint == nil || + s.Spec.Endpoint.Mode == api.ResolutionModeVirtualIP) { + + if _, ok := na.services[s.ID]; !ok { + return false + } + + if s.Endpoint == nil || len(s.Endpoint.VirtualIPs) == 0 { + return false + } + + // If the spec has networks which don't have a corresponding VIP, + // the service needs to be allocated. + networkLoop: + for _, net := range specNetworks { + for _, vip := range s.Endpoint.VirtualIPs { + if vip.NetworkID == net.Target { + continue networkLoop + } + } + return false + } + } + + // If the spec no longer has networks attached and has a vip allocated + // from previous spec the service needs to allocated. + if s.Endpoint != nil { + vipLoop: + for _, vip := range s.Endpoint.VirtualIPs { + if na.IsVIPOnIngressNetwork(vip) && networkallocator.IsIngressNetworkNeeded(s) { + continue vipLoop + } + for _, net := range specNetworks { + if vip.NetworkID == net.Target { + continue vipLoop + } + } + return false + } + } + + // If the endpoint mode is DNSRR and allocator has the service + // in VIP allocated set then we return to be allocated to make + // sure the allocator triggers networkallocator to free up the + // resources if any. + if s.Spec.Endpoint != nil && s.Spec.Endpoint.Mode == api.ResolutionModeDNSRoundRobin { + if _, ok := na.services[s.ID]; ok { + return false + } + } + + if (s.Spec.Endpoint != nil && len(s.Spec.Endpoint.Ports) != 0) || + (s.Endpoint != nil && len(s.Endpoint.Ports) != 0) { + return na.portAllocator.isPortsAllocatedOnInit(s, options.OnInit) + } + return true +} + +// IsNodeAllocated returns if the passed node has its network resources allocated or not. +func (na *cnmNetworkAllocator) IsNodeAllocated(node *api.Node) bool { + // If the node is not found in the allocated set, then it is + // not allocated. + if _, ok := na.nodes[node.ID]; !ok { + return false + } + + // If no attachment, not allocated. + if node.Attachment == nil { + return false + } + + // If the network is not allocated, the node cannot be allocated. + localNet, ok := na.networks[node.Attachment.Network.ID] + if !ok { + return false + } + + // Addresses empty, not allocated. + if len(node.Attachment.Addresses) == 0 { + return false + } + + // The allocated IP address not found in local endpoint state. Not allocated. + if _, ok := localNet.endpoints[node.Attachment.Addresses[0]]; !ok { + return false + } + + return true +} + +// AllocateNode allocates the IP addresses for the network to which +// the node is attached. +func (na *cnmNetworkAllocator) AllocateNode(node *api.Node) error { + if err := na.allocateNetworkIPs(node.Attachment); err != nil { + return err + } + + na.nodes[node.ID] = struct{}{} + return nil +} + +// DeallocateNode deallocates the IP addresses for the network to +// which the node is attached. +func (na *cnmNetworkAllocator) DeallocateNode(node *api.Node) error { + delete(na.nodes, node.ID) + return na.releaseEndpoints([]*api.NetworkAttachment{node.Attachment}) +} + +// AllocateTask allocates all the endpoint resources for all the +// networks that a task is attached to. +func (na *cnmNetworkAllocator) AllocateTask(t *api.Task) error { + for i, nAttach := range t.Networks { + if localNet := na.getNetwork(nAttach.Network.ID); localNet != nil && localNet.isNodeLocal { + continue + } + if err := na.allocateNetworkIPs(nAttach); err != nil { + if err := na.releaseEndpoints(t.Networks[:i]); err != nil { + log.G(context.TODO()).WithError(err).Errorf("Failed to release IP addresses while rolling back allocation for task %s network %s", t.ID, nAttach.Network.ID) + } + return errors.Wrapf(err, "failed to allocate network IP for task %s network %s", t.ID, nAttach.Network.ID) + } + } + + na.tasks[t.ID] = struct{}{} + + return nil +} + +// DeallocateTask releases all the endpoint resources for all the +// networks that a task is attached to. +func (na *cnmNetworkAllocator) DeallocateTask(t *api.Task) error { + delete(na.tasks, t.ID) + return na.releaseEndpoints(t.Networks) +} + +func (na *cnmNetworkAllocator) releaseEndpoints(networks []*api.NetworkAttachment) error { + for _, nAttach := range networks { + localNet := na.getNetwork(nAttach.Network.ID) + if localNet == nil { + return fmt.Errorf("could not find network allocator state for network %s", nAttach.Network.ID) + } + + if localNet.isNodeLocal { + continue + } + + ipam, _, _, err := na.resolveIPAM(nAttach.Network) + if err != nil { + return errors.Wrap(err, "failed to resolve IPAM while releasing") + } + + // Do not fail and bail out if we fail to release IP + // address here. Keep going and try releasing as many + // addresses as possible. + for _, addr := range nAttach.Addresses { + // Retrieve the poolID and immediately nuke + // out the mapping. + poolID := localNet.endpoints[addr] + delete(localNet.endpoints, addr) + + ip, _, err := net.ParseCIDR(addr) + if err != nil { + log.G(context.TODO()).Errorf("Could not parse IP address %s while releasing", addr) + continue + } + + if err := ipam.ReleaseAddress(poolID, ip); err != nil { + log.G(context.TODO()).WithError(err).Errorf("IPAM failure while releasing IP address %s", addr) + } + } + + // Clear out the address list when we are done with + // this network. + nAttach.Addresses = nil + } + + return nil +} + +// allocate virtual IP for a single endpoint attachment of the service. +func (na *cnmNetworkAllocator) allocateVIP(vip *api.Endpoint_VirtualIP) error { + localNet := na.getNetwork(vip.NetworkID) + if localNet == nil { + return errors.New("networkallocator: could not find local network state") + } + + if localNet.isNodeLocal { + return nil + } + + // If this IP is already allocated in memory we don't need to + // do anything. + if _, ok := localNet.endpoints[vip.Addr]; ok { + return nil + } + + ipam, _, _, err := na.resolveIPAM(localNet.nw) + if err != nil { + return errors.Wrap(err, "failed to resolve IPAM while allocating") + } + + var addr net.IP + if vip.Addr != "" { + var err error + + addr, _, err = net.ParseCIDR(vip.Addr) + if err != nil { + return err + } + } + + for _, poolID := range localNet.pools { + ip, _, err := ipam.RequestAddress(poolID, addr, nil) + if err != nil && err != ipamapi.ErrNoAvailableIPs && err != ipamapi.ErrIPOutOfRange { + return errors.Wrap(err, "could not allocate VIP from IPAM") + } + + // If we got an address then we are done. + if err == nil { + ipStr := ip.String() + localNet.endpoints[ipStr] = poolID + vip.Addr = ipStr + return nil + } + } + + return errors.New("could not find an available IP while allocating VIP") +} + +func (na *cnmNetworkAllocator) deallocateVIP(vip *api.Endpoint_VirtualIP) error { + localNet := na.getNetwork(vip.NetworkID) + if localNet == nil { + return errors.New("networkallocator: could not find local network state") + } + if localNet.isNodeLocal { + return nil + } + ipam, _, _, err := na.resolveIPAM(localNet.nw) + if err != nil { + return errors.Wrap(err, "failed to resolve IPAM while allocating") + } + + // Retrieve the poolID and immediately nuke + // out the mapping. + poolID := localNet.endpoints[vip.Addr] + delete(localNet.endpoints, vip.Addr) + + ip, _, err := net.ParseCIDR(vip.Addr) + if err != nil { + log.G(context.TODO()).Errorf("Could not parse VIP address %s while releasing", vip.Addr) + return err + } + + if err := ipam.ReleaseAddress(poolID, ip); err != nil { + log.G(context.TODO()).WithError(err).Errorf("IPAM failure while releasing VIP address %s", vip.Addr) + return err + } + + return nil +} + +// allocate the IP addresses for a single network attachment of the task. +func (na *cnmNetworkAllocator) allocateNetworkIPs(nAttach *api.NetworkAttachment) error { + var ip *net.IPNet + + ipam, _, _, err := na.resolveIPAM(nAttach.Network) + if err != nil { + return errors.Wrap(err, "failed to resolve IPAM while allocating") + } + + localNet := na.getNetwork(nAttach.Network.ID) + if localNet == nil { + return fmt.Errorf("could not find network allocator state for network %s", nAttach.Network.ID) + } + + addresses := nAttach.Addresses + if len(addresses) == 0 { + addresses = []string{""} + } + + for i, rawAddr := range addresses { + var addr net.IP + if rawAddr != "" { + var err error + addr, _, err = net.ParseCIDR(rawAddr) + if err != nil { + addr = net.ParseIP(rawAddr) + + if addr == nil { + return errors.Wrapf(err, "could not parse address string %s", rawAddr) + } + } + } + + for _, poolID := range localNet.pools { + var err error + + ip, _, err = ipam.RequestAddress(poolID, addr, nil) + if err != nil && err != ipamapi.ErrNoAvailableIPs && err != ipamapi.ErrIPOutOfRange { + return errors.Wrap(err, "could not allocate IP from IPAM") + } + + // If we got an address then we are done. + if err == nil { + ipStr := ip.String() + localNet.endpoints[ipStr] = poolID + addresses[i] = ipStr + nAttach.Addresses = addresses + return nil + } + } + } + + return errors.New("could not find an available IP") +} + +func (na *cnmNetworkAllocator) freeDriverState(n *api.Network) error { + d, err := na.resolveDriver(n) + if err != nil { + return err + } + + return d.driver.NetworkFree(n.ID) +} + +func (na *cnmNetworkAllocator) allocateDriverState(n *api.Network) error { + d, err := na.resolveDriver(n) + if err != nil { + return err + } + + options := make(map[string]string) + // reconcile the driver specific options from the network spec + // and from the operational state retrieved from the store + if n.Spec.DriverConfig != nil { + for k, v := range n.Spec.DriverConfig.Options { + options[k] = v + } + } + if n.DriverState != nil { + for k, v := range n.DriverState.Options { + options[k] = v + } + } + + // Construct IPAM data for driver consumption. + ipv4Data := make([]driverapi.IPAMData, 0, len(n.IPAM.Configs)) + for _, ic := range n.IPAM.Configs { + if ic.Family == api.IPAMConfig_IPV6 { + continue + } + + _, subnet, err := net.ParseCIDR(ic.Subnet) + if err != nil { + return errors.Wrapf(err, "error parsing subnet %s while allocating driver state", ic.Subnet) + } + + gwIP := net.ParseIP(ic.Gateway) + gwNet := &net.IPNet{ + IP: gwIP, + Mask: subnet.Mask, + } + + data := driverapi.IPAMData{ + Pool: subnet, + Gateway: gwNet, + } + + ipv4Data = append(ipv4Data, data) + } + + ds, err := d.driver.NetworkAllocate(n.ID, options, ipv4Data, nil) + if err != nil { + return err + } + + // Update network object with the obtained driver state. + n.DriverState = &api.Driver{ + Name: d.name, + Options: ds, + } + + return nil +} + +// Resolve network driver +func (na *cnmNetworkAllocator) resolveDriver(n *api.Network) (*networkDriver, error) { + dName := DefaultDriver + if n.Spec.DriverConfig != nil && n.Spec.DriverConfig.Name != "" { + dName = n.Spec.DriverConfig.Name + } + + d, drvcap := na.drvRegistry.Driver(dName) + if d == nil { + var err error + err = na.loadDriver(dName) + if err != nil { + return nil, err + } + + d, drvcap = na.drvRegistry.Driver(dName) + if d == nil { + return nil, fmt.Errorf("could not resolve network driver %s", dName) + } + } + + return &networkDriver{driver: d, capability: drvcap, name: dName}, nil +} + +func (na *cnmNetworkAllocator) loadDriver(name string) error { + pg := na.drvRegistry.GetPluginGetter() + if pg == nil { + return errors.New("plugin store is uninitialized") + } + _, err := pg.Get(name, driverapi.NetworkPluginEndpointType, plugingetter.Lookup) + return err +} + +// Resolve the IPAM driver +func (na *cnmNetworkAllocator) resolveIPAM(n *api.Network) (ipamapi.Ipam, string, map[string]string, error) { + dName := ipamapi.DefaultIPAM + if n.Spec.IPAM != nil && n.Spec.IPAM.Driver != nil && n.Spec.IPAM.Driver.Name != "" { + dName = n.Spec.IPAM.Driver.Name + } + + var dOptions map[string]string + if n.Spec.IPAM != nil && n.Spec.IPAM.Driver != nil && len(n.Spec.IPAM.Driver.Options) != 0 { + dOptions = n.Spec.IPAM.Driver.Options + } + + ipam, _ := na.drvRegistry.IPAM(dName) + if ipam == nil { + return nil, "", nil, fmt.Errorf("could not resolve IPAM driver %s", dName) + } + + return ipam, dName, dOptions, nil +} + +func (na *cnmNetworkAllocator) freePools(n *api.Network, pools map[string]string) error { + ipam, _, _, err := na.resolveIPAM(n) + if err != nil { + return errors.Wrapf(err, "failed to resolve IPAM while freeing pools for network %s", n.ID) + } + + releasePools(ipam, n.IPAM.Configs, pools) + return nil +} + +func releasePools(ipam ipamapi.Ipam, icList []*api.IPAMConfig, pools map[string]string) { + for _, ic := range icList { + if err := ipam.ReleaseAddress(pools[ic.Subnet], net.ParseIP(ic.Gateway)); err != nil { + log.G(context.TODO()).WithError(err).Errorf("Failed to release address %s", ic.Subnet) + } + } + + for k, p := range pools { + if err := ipam.ReleasePool(p); err != nil { + log.G(context.TODO()).WithError(err).Errorf("Failed to release pool %s", k) + } + } +} + +func (na *cnmNetworkAllocator) allocatePools(n *api.Network) (map[string]string, error) { + ipam, dName, dOptions, err := na.resolveIPAM(n) + if err != nil { + return nil, err + } + + // We don't support user defined address spaces yet so just + // retrieve default address space names for the driver. + _, asName, err := na.drvRegistry.IPAMDefaultAddressSpaces(dName) + if err != nil { + return nil, err + } + + pools := make(map[string]string) + + var ipamConfigs []*api.IPAMConfig + + // If there is non-nil IPAM state always prefer those subnet + // configs over Spec configs. + if n.IPAM != nil { + ipamConfigs = n.IPAM.Configs + } else if n.Spec.IPAM != nil { + ipamConfigs = make([]*api.IPAMConfig, len(n.Spec.IPAM.Configs)) + copy(ipamConfigs, n.Spec.IPAM.Configs) + } + + // Append an empty slot for subnet allocation if there are no + // IPAM configs from either spec or state. + if len(ipamConfigs) == 0 { + ipamConfigs = append(ipamConfigs, &api.IPAMConfig{Family: api.IPAMConfig_IPV4}) + } + + // Update the runtime IPAM configurations with initial state + n.IPAM = &api.IPAMOptions{ + Driver: &api.Driver{Name: dName, Options: dOptions}, + Configs: ipamConfigs, + } + + for i, ic := range ipamConfigs { + poolID, poolIP, meta, err := ipam.RequestPool(asName, ic.Subnet, ic.Range, dOptions, false) + if err != nil { + // Rollback by releasing all the resources allocated so far. + releasePools(ipam, ipamConfigs[:i], pools) + return nil, err + } + pools[poolIP.String()] = poolID + + // The IPAM contract allows the IPAM driver to autonomously + // provide a network gateway in response to the pool request. + // But if the network spec contains a gateway, we will allocate + // it irrespective of whether the ipam driver returned one already. + // If none of the above is true, we need to allocate one now, and + // let the driver know this request is for the network gateway. + var ( + gwIP *net.IPNet + ip net.IP + ) + if gws, ok := meta[netlabel.Gateway]; ok { + if ip, gwIP, err = net.ParseCIDR(gws); err != nil { + return nil, fmt.Errorf("failed to parse gateway address (%v) returned by ipam driver: %v", gws, err) + } + gwIP.IP = ip + } + if ic.Gateway != "" || gwIP == nil { + gwIP, _, err = ipam.RequestAddress(poolID, net.ParseIP(ic.Gateway), map[string]string{ipamapi.RequestAddressType: netlabel.Gateway}) + if err != nil { + // Rollback by releasing all the resources allocated so far. + releasePools(ipam, ipamConfigs[:i], pools) + return nil, err + } + } + + if ic.Subnet == "" { + ic.Subnet = poolIP.String() + } + + if ic.Gateway == "" { + ic.Gateway = gwIP.IP.String() + } + + } + + return pools, nil +} + +func initializeDrivers(reg *drvregistry.DrvRegistry) error { + for _, i := range initializers { + if err := reg.AddDriver(i.ntype, i.fn, nil); err != nil { + return err + } + } + return nil +} + +func serviceNetworks(s *api.Service) []*api.NetworkAttachmentConfig { + // Always prefer NetworkAttachmentConfig in the TaskSpec + if len(s.Spec.Task.Networks) == 0 && len(s.Spec.Networks) != 0 { + return s.Spec.Networks + } + return s.Spec.Task.Networks +} + +// IsVIPOnIngressNetwork check if the vip is in ingress network +func (na *cnmNetworkAllocator) IsVIPOnIngressNetwork(vip *api.Endpoint_VirtualIP) bool { + if vip == nil { + return false + } + + localNet := na.getNetwork(vip.NetworkID) + if localNet != nil && localNet.nw != nil { + return networkallocator.IsIngressNetwork(localNet.nw) + } + return false +} + +// IsBuiltInDriver returns whether the passed driver is an internal network driver +func IsBuiltInDriver(name string) bool { + n := strings.ToLower(name) + for _, d := range initializers { + if n == d.ntype { + return true + } + } + return false +} diff --git a/components/engine/vendor/github.com/docker/swarmkit/manager/allocator/networkallocator/portallocator.go b/components/engine/vendor/github.com/docker/swarmkit/manager/allocator/cnmallocator/portallocator.go similarity index 99% rename from components/engine/vendor/github.com/docker/swarmkit/manager/allocator/networkallocator/portallocator.go rename to components/engine/vendor/github.com/docker/swarmkit/manager/allocator/cnmallocator/portallocator.go index af8126ea25..b09ac47c79 100644 --- a/components/engine/vendor/github.com/docker/swarmkit/manager/allocator/networkallocator/portallocator.go +++ b/components/engine/vendor/github.com/docker/swarmkit/manager/allocator/cnmallocator/portallocator.go @@ -1,4 +1,4 @@ -package networkallocator +package cnmallocator import ( "fmt" diff --git a/components/engine/vendor/github.com/docker/swarmkit/manager/allocator/network.go b/components/engine/vendor/github.com/docker/swarmkit/manager/allocator/network.go index 23d3f6f0a1..1675dbe249 100644 --- a/components/engine/vendor/github.com/docker/swarmkit/manager/allocator/network.go +++ b/components/engine/vendor/github.com/docker/swarmkit/manager/allocator/network.go @@ -7,6 +7,7 @@ import ( "github.com/docker/go-events" "github.com/docker/swarmkit/api" "github.com/docker/swarmkit/log" + "github.com/docker/swarmkit/manager/allocator/cnmallocator" "github.com/docker/swarmkit/manager/allocator/networkallocator" "github.com/docker/swarmkit/manager/state" "github.com/docker/swarmkit/manager/state/store" @@ -34,7 +35,7 @@ type networkContext struct { ingressNetwork *api.Network // Instance of the low-level network allocator which performs // the actual network allocation. - nwkAllocator *networkallocator.NetworkAllocator + nwkAllocator networkallocator.NetworkAllocator // A set of tasks which are ready to be allocated as a batch. This is // distinct from "unallocatedTasks" which are tasks that failed to @@ -61,7 +62,7 @@ type networkContext struct { } func (a *Allocator) doNetworkInit(ctx context.Context) (err error) { - na, err := networkallocator.New(a.pluginGetter) + na, err := cnmallocator.New(a.pluginGetter) if err != nil { return err } @@ -145,110 +146,31 @@ func (a *Allocator) doNetworkInit(ctx context.Context) (err error) { log.G(ctx).WithError(err).Error("failed committing allocation of networks during init") } - // Allocate nodes in the store so far before we process watched events, - // if the ingress network is present. + // First, allocate objects that already have addresses associated with + // them, to reserve these IP addresses in internal state. if nc.ingressNetwork != nil { - if err := a.allocateNodes(ctx); err != nil { + if err := a.allocateNodes(ctx, true); err != nil { return err } } - - // Allocate services in the store so far before we process watched events. - var services []*api.Service - a.store.View(func(tx store.ReadTx) { - services, err = store.FindServices(tx, store.All) - }) - if err != nil { - return errors.Wrap(err, "error listing all services in store while trying to allocate during init") + if err := a.allocateServices(ctx, true); err != nil { + return err + } + if err := a.allocateTasks(ctx, true); err != nil { + return err } - var allocatedServices []*api.Service - for _, s := range services { - if !nc.nwkAllocator.ServiceNeedsAllocation(s, networkallocator.OnInit) { - continue - } - - if err := a.allocateService(ctx, s); err != nil { - log.G(ctx).WithError(err).Errorf("failed allocating service %s during init", s.ID) - continue - } - allocatedServices = append(allocatedServices, s) - } - - if err := a.store.Batch(func(batch *store.Batch) error { - for _, s := range allocatedServices { - if err := a.commitAllocatedService(ctx, batch, s); err != nil { - log.G(ctx).WithError(err).Errorf("failed committing allocation of service %s during init", s.ID) - } - } - return nil - }); err != nil { - log.G(ctx).WithError(err).Error("failed committing allocation of services during init") - } - - // Allocate tasks in the store so far before we started watching. - var ( - tasks []*api.Task - allocatedTasks []*api.Task - ) - a.store.View(func(tx store.ReadTx) { - tasks, err = store.FindTasks(tx, store.All) - }) - if err != nil { - return errors.Wrap(err, "error listing all tasks in store while trying to allocate during init") - } - - for _, t := range tasks { - if t.Status.State > api.TaskStateRunning { - continue - } - - var s *api.Service - if t.ServiceID != "" { - a.store.View(func(tx store.ReadTx) { - s = store.GetService(tx, t.ServiceID) - }) - } - - // Populate network attachments in the task - // based on service spec. - a.taskCreateNetworkAttachments(t, s) - - if taskReadyForNetworkVote(t, s, nc) { - if t.Status.State >= api.TaskStatePending { - continue - } - - if a.taskAllocateVote(networkVoter, t.ID) { - // If the task is not attached to any network, network - // allocators job is done. Immediately cast a vote so - // that the task can be moved to the PENDING state as - // soon as possible. - updateTaskStatus(t, api.TaskStatePending, allocatedStatusMessage) - allocatedTasks = append(allocatedTasks, t) - } - continue - } - - err := a.allocateTask(ctx, t) - if err == nil { - allocatedTasks = append(allocatedTasks, t) - } else if err != errNoChanges { - log.G(ctx).WithError(err).Errorf("failed allocating task %s during init", t.ID) - nc.unallocatedTasks[t.ID] = t + // Now allocate objects that don't have addresses yet. + if nc.ingressNetwork != nil { + if err := a.allocateNodes(ctx, false); err != nil { + return err } } - - if err := a.store.Batch(func(batch *store.Batch) error { - for _, t := range allocatedTasks { - if err := a.commitAllocatedTask(ctx, batch, t); err != nil { - log.G(ctx).WithError(err).Errorf("failed committing allocation of task %s during init", t.ID) - } - } - - return nil - }); err != nil { - log.G(ctx).WithError(err).Error("failed committing allocation of tasks during init") + if err := a.allocateServices(ctx, false); err != nil { + return err + } + if err := a.allocateTasks(ctx, false); err != nil { + return err } return nil @@ -283,7 +205,7 @@ func (a *Allocator) doNetworkAlloc(ctx context.Context, ev events.Event) { if IsIngressNetwork(n) { nc.ingressNetwork = n - err := a.allocateNodes(ctx) + err := a.allocateNodes(ctx, false) if err != nil { log.G(ctx).WithError(err).Error(err) } @@ -317,7 +239,7 @@ func (a *Allocator) doNetworkAlloc(ctx context.Context, ev events.Event) { break } - if !nc.nwkAllocator.ServiceNeedsAllocation(s) { + if nc.nwkAllocator.IsServiceAllocated(s) { break } @@ -345,7 +267,7 @@ func (a *Allocator) doNetworkAlloc(ctx context.Context, ev events.Event) { break } - if !nc.nwkAllocator.ServiceNeedsAllocation(s) { + if nc.nwkAllocator.IsServiceAllocated(s) { if !nc.nwkAllocator.HostPublishPortsNeedUpdate(s) { break } @@ -368,7 +290,7 @@ func (a *Allocator) doNetworkAlloc(ctx context.Context, ev events.Event) { case api.EventDeleteService: s := v.Service.Copy() - if err := nc.nwkAllocator.ServiceDeallocate(s); err != nil { + if err := nc.nwkAllocator.DeallocateService(s); err != nil { log.G(ctx).WithError(err).Errorf("Failed deallocation during delete of service %s", s.ID) } @@ -455,7 +377,7 @@ func (a *Allocator) doNodeAlloc(ctx context.Context, ev events.Event) { } } -func (a *Allocator) allocateNodes(ctx context.Context) error { +func (a *Allocator) allocateNodes(ctx context.Context, existingAddressesOnly bool) error { // Allocate nodes in the store so far before we process watched events. var ( allocatedNodes []*api.Node @@ -480,6 +402,10 @@ func (a *Allocator) allocateNodes(ctx context.Context) error { node.Attachment = &api.NetworkAttachment{} } + if existingAddressesOnly && len(node.Attachment.Addresses) == 0 { + continue + } + node.Attachment.Network = nc.ingressNetwork.Copy() if err := a.allocateNode(ctx, node); err != nil { log.G(ctx).WithError(err).Errorf("Failed to allocate network resources for node %s", node.ID) @@ -534,6 +460,138 @@ func (a *Allocator) deallocateNodes(ctx context.Context) error { return nil } +// allocateServices allocates services in the store so far before we process +// watched events. +func (a *Allocator) allocateServices(ctx context.Context, existingAddressesOnly bool) error { + var ( + nc = a.netCtx + services []*api.Service + err error + ) + a.store.View(func(tx store.ReadTx) { + services, err = store.FindServices(tx, store.All) + }) + if err != nil { + return errors.Wrap(err, "error listing all services in store while trying to allocate during init") + } + + var allocatedServices []*api.Service + for _, s := range services { + if nc.nwkAllocator.IsServiceAllocated(s, networkallocator.OnInit) { + continue + } + + if existingAddressesOnly && + (s.Endpoint == nil || + len(s.Endpoint.VirtualIPs) == 0) { + continue + } + + if err := a.allocateService(ctx, s); err != nil { + log.G(ctx).WithError(err).Errorf("failed allocating service %s during init", s.ID) + continue + } + allocatedServices = append(allocatedServices, s) + } + + if err := a.store.Batch(func(batch *store.Batch) error { + for _, s := range allocatedServices { + if err := a.commitAllocatedService(ctx, batch, s); err != nil { + log.G(ctx).WithError(err).Errorf("failed committing allocation of service %s during init", s.ID) + } + } + return nil + }); err != nil { + log.G(ctx).WithError(err).Error("failed committing allocation of services during init") + } + + return nil +} + +// allocateTasks allocates tasks in the store so far before we started watching. +func (a *Allocator) allocateTasks(ctx context.Context, existingAddressesOnly bool) error { + var ( + nc = a.netCtx + tasks []*api.Task + allocatedTasks []*api.Task + err error + ) + a.store.View(func(tx store.ReadTx) { + tasks, err = store.FindTasks(tx, store.All) + }) + if err != nil { + return errors.Wrap(err, "error listing all tasks in store while trying to allocate during init") + } + + for _, t := range tasks { + if t.Status.State > api.TaskStateRunning { + continue + } + + if existingAddressesOnly { + hasAddresses := false + for _, nAttach := range t.Networks { + if len(nAttach.Addresses) != 0 { + hasAddresses = true + break + } + } + if !hasAddresses { + continue + } + } + + var s *api.Service + if t.ServiceID != "" { + a.store.View(func(tx store.ReadTx) { + s = store.GetService(tx, t.ServiceID) + }) + } + + // Populate network attachments in the task + // based on service spec. + a.taskCreateNetworkAttachments(t, s) + + if taskReadyForNetworkVote(t, s, nc) { + if t.Status.State >= api.TaskStatePending { + continue + } + + if a.taskAllocateVote(networkVoter, t.ID) { + // If the task is not attached to any network, network + // allocators job is done. Immediately cast a vote so + // that the task can be moved to the PENDING state as + // soon as possible. + updateTaskStatus(t, api.TaskStatePending, allocatedStatusMessage) + allocatedTasks = append(allocatedTasks, t) + } + continue + } + + err := a.allocateTask(ctx, t) + if err == nil { + allocatedTasks = append(allocatedTasks, t) + } else if err != errNoChanges { + log.G(ctx).WithError(err).Errorf("failed allocating task %s during init", t.ID) + nc.unallocatedTasks[t.ID] = t + } + } + + if err := a.store.Batch(func(batch *store.Batch) error { + for _, t := range allocatedTasks { + if err := a.commitAllocatedTask(ctx, batch, t); err != nil { + log.G(ctx).WithError(err).Errorf("failed committing allocation of task %s during init", t.ID) + } + } + + return nil + }); err != nil { + log.G(ctx).WithError(err).Error("failed committing allocation of tasks during init") + } + + return nil +} + // taskReadyForNetworkVote checks if the task is ready for a network // vote to move it to PENDING state. func taskReadyForNetworkVote(t *api.Task, s *api.Service, nc *networkContext) bool { @@ -544,7 +602,7 @@ func taskReadyForNetworkVote(t *api.Task, s *api.Service, nc *networkContext) bo // network configured or service endpoints have been // allocated. return (len(t.Networks) == 0 || nc.nwkAllocator.IsTaskAllocated(t)) && - (s == nil || !nc.nwkAllocator.ServiceNeedsAllocation(s)) + (s == nil || nc.nwkAllocator.IsServiceAllocated(s)) } func taskUpdateNetworks(t *api.Task, networks []*api.NetworkAttachment) { @@ -774,12 +832,12 @@ func (a *Allocator) allocateService(ctx context.Context, s *api.Service) error { } else if s.Endpoint != nil { // service has no user-defined endpoints while has already allocated network resources, // need deallocated. - if err := nc.nwkAllocator.ServiceDeallocate(s); err != nil { + if err := nc.nwkAllocator.DeallocateService(s); err != nil { return err } } - if err := nc.nwkAllocator.ServiceAllocate(s); err != nil { + if err := nc.nwkAllocator.AllocateService(s); err != nil { nc.unallocatedServices[s.ID] = s return err } @@ -814,7 +872,7 @@ func (a *Allocator) commitAllocatedService(ctx context.Context, batch *store.Bat return errors.Wrapf(err, "failed updating state in store transaction for service %s", s.ID) }); err != nil { - if err := a.netCtx.nwkAllocator.ServiceDeallocate(s); err != nil { + if err := a.netCtx.nwkAllocator.DeallocateService(s); err != nil { log.G(ctx).WithError(err).Errorf("failed rolling back allocation of service %s", s.ID) } @@ -869,7 +927,7 @@ func (a *Allocator) allocateTask(ctx context.Context, t *api.Task) (err error) { return } - if nc.nwkAllocator.ServiceNeedsAllocation(s) { + if !nc.nwkAllocator.IsServiceAllocated(s) { err = fmt.Errorf("service %s to which this task %s belongs has pending allocations", s.ID, t.ID) return } @@ -986,7 +1044,7 @@ func (a *Allocator) procUnallocatedServices(ctx context.Context) { nc := a.netCtx var allocatedServices []*api.Service for _, s := range nc.unallocatedServices { - if nc.nwkAllocator.ServiceNeedsAllocation(s) { + if !nc.nwkAllocator.IsServiceAllocated(s) { if err := a.allocateService(ctx, s); err != nil { log.G(ctx).WithError(err).Debugf("Failed allocation of unallocated service %s", s.ID) continue @@ -1071,6 +1129,16 @@ func (a *Allocator) procTasksNetwork(ctx context.Context, onRetry bool) { } } +// IsBuiltInNetworkDriver returns whether the passed driver is an internal network driver +func IsBuiltInNetworkDriver(name string) bool { + return cnmallocator.IsBuiltInDriver(name) +} + +// PredefinedNetworks returns the list of predefined network structures for a given network model +func PredefinedNetworks() []networkallocator.PredefinedNetworkData { + return cnmallocator.PredefinedNetworks() +} + // updateTaskStatus sets TaskStatus and updates timestamp. func updateTaskStatus(t *api.Task, newStatus api.TaskState, message string) { t.Status.State = newStatus diff --git a/components/engine/vendor/github.com/docker/swarmkit/manager/allocator/networkallocator/drivers_unsupported.go b/components/engine/vendor/github.com/docker/swarmkit/manager/allocator/networkallocator/drivers_unsupported.go deleted file mode 100644 index 5facfdc7f4..0000000000 --- a/components/engine/vendor/github.com/docker/swarmkit/manager/allocator/networkallocator/drivers_unsupported.go +++ /dev/null @@ -1,10 +0,0 @@ -// +build !linux,!darwin,!windows - -package networkallocator - -const initializers = nil - -// PredefinedNetworks returns the list of predefined network structures -func PredefinedNetworks() []PredefinedNetworkData { - return nil -} diff --git a/components/engine/vendor/github.com/docker/swarmkit/manager/allocator/networkallocator/networkallocator.go b/components/engine/vendor/github.com/docker/swarmkit/manager/allocator/networkallocator/networkallocator.go index a2fda20348..04dd168126 100644 --- a/components/engine/vendor/github.com/docker/swarmkit/manager/allocator/networkallocator/networkallocator.go +++ b/components/engine/vendor/github.com/docker/swarmkit/manager/allocator/networkallocator/networkallocator.go @@ -1,91 +1,15 @@ package networkallocator import ( - "fmt" - "net" - "strings" - - "github.com/docker/docker/pkg/plugingetter" - "github.com/docker/libnetwork/datastore" - "github.com/docker/libnetwork/driverapi" - "github.com/docker/libnetwork/drvregistry" - "github.com/docker/libnetwork/ipamapi" - "github.com/docker/libnetwork/netlabel" "github.com/docker/swarmkit/api" - "github.com/docker/swarmkit/log" - "github.com/pkg/errors" - "golang.org/x/net/context" ) const ( - // DefaultDriver defines the name of the driver to be used by - // default if a network without any driver name specified is - // created. - DefaultDriver = "overlay" - // PredefinedLabel identifies internally allocated swarm networks // corresponding to the node-local predefined networks on the host. PredefinedLabel = "com.docker.swarm.predefined" ) -// NetworkAllocator acts as the controller for all network related operations -// like managing network and IPAM drivers and also creating and -// deleting networks and the associated resources. -type NetworkAllocator struct { - // The driver register which manages all internal and external - // IPAM and network drivers. - drvRegistry *drvregistry.DrvRegistry - - // The port allocator instance for allocating node ports - portAllocator *portAllocator - - // Local network state used by NetworkAllocator to do network management. - networks map[string]*network - - // Allocator state to indicate if allocation has been - // successfully completed for this service. - services map[string]struct{} - - // Allocator state to indicate if allocation has been - // successfully completed for this task. - tasks map[string]struct{} - - // Allocator state to indicate if allocation has been - // successfully completed for this node. - nodes map[string]struct{} -} - -// Local in-memory state related to network that need to be tracked by NetworkAllocator -type network struct { - // A local cache of the store object. - nw *api.Network - - // pools is used to save the internal poolIDs needed when - // releasing the pool. - pools map[string]string - - // endpoints is a map of endpoint IP to the poolID from which it - // was allocated. - endpoints map[string]string - - // isNodeLocal indicates whether the scope of the network's resources - // is local to the node. If true, it means the resources can only be - // allocated locally by the node where the network will be deployed. - // In this the swarm manager will skip the allocations. - isNodeLocal bool -} - -type networkDriver struct { - driver driverapi.Driver - name string - capability *driverapi.Capability -} - -type initializer struct { - fn drvregistry.InitFunc - ntype string -} - // PredefinedNetworkData contains the minimum set of data needed // to create the correspondent predefined network object in the store. type PredefinedNetworkData struct { @@ -93,280 +17,8 @@ type PredefinedNetworkData struct { Driver string } -// New returns a new NetworkAllocator handle -func New(pg plugingetter.PluginGetter) (*NetworkAllocator, error) { - na := &NetworkAllocator{ - networks: make(map[string]*network), - services: make(map[string]struct{}), - tasks: make(map[string]struct{}), - nodes: make(map[string]struct{}), - } - - // There are no driver configurations and notification - // functions as of now. - reg, err := drvregistry.New(nil, nil, nil, nil, pg) - if err != nil { - return nil, err - } - - if err := initializeDrivers(reg); err != nil { - return nil, err - } - - if err = initIPAMDrivers(reg); err != nil { - return nil, err - } - - pa, err := newPortAllocator() - if err != nil { - return nil, err - } - - na.portAllocator = pa - na.drvRegistry = reg - return na, nil -} - -// Allocate allocates all the necessary resources both general -// and driver-specific which may be specified in the NetworkSpec -func (na *NetworkAllocator) Allocate(n *api.Network) error { - if _, ok := na.networks[n.ID]; ok { - return fmt.Errorf("network %s already allocated", n.ID) - } - - d, err := na.resolveDriver(n) - if err != nil { - return err - } - - nw := &network{ - nw: n, - endpoints: make(map[string]string), - isNodeLocal: d.capability.DataScope == datastore.LocalScope, - } - - // No swarm-level allocation can be provided by the network driver for - // node-local networks. Only thing needed is populating the driver's name - // in the driver's state. - if nw.isNodeLocal { - n.DriverState = &api.Driver{ - Name: d.name, - } - } else { - nw.pools, err = na.allocatePools(n) - if err != nil { - return errors.Wrapf(err, "failed allocating pools and gateway IP for network %s", n.ID) - } - - if err := na.allocateDriverState(n); err != nil { - na.freePools(n, nw.pools) - return errors.Wrapf(err, "failed while allocating driver state for network %s", n.ID) - } - } - - na.networks[n.ID] = nw - - return nil -} - -func (na *NetworkAllocator) getNetwork(id string) *network { - return na.networks[id] -} - -// Deallocate frees all the general and driver specific resources -// which were assigned to the passed network. -func (na *NetworkAllocator) Deallocate(n *api.Network) error { - localNet := na.getNetwork(n.ID) - if localNet == nil { - return fmt.Errorf("could not get networker state for network %s", n.ID) - } - - // No swarm-level resource deallocation needed for node-local networks - if localNet.isNodeLocal { - delete(na.networks, n.ID) - return nil - } - - if err := na.freeDriverState(n); err != nil { - return errors.Wrapf(err, "failed to free driver state for network %s", n.ID) - } - - delete(na.networks, n.ID) - - return na.freePools(n, localNet.pools) -} - -// ServiceAllocate allocates all the network resources such as virtual -// IP and ports needed by the service. -func (na *NetworkAllocator) ServiceAllocate(s *api.Service) (err error) { - if err = na.portAllocator.serviceAllocatePorts(s); err != nil { - return err - } - defer func() { - if err != nil { - na.ServiceDeallocate(s) - } - }() - - if s.Endpoint == nil { - s.Endpoint = &api.Endpoint{} - } - s.Endpoint.Spec = s.Spec.Endpoint.Copy() - - // If ResolutionMode is DNSRR do not try allocating VIPs, but - // free any VIP from previous state. - if s.Spec.Endpoint != nil && s.Spec.Endpoint.Mode == api.ResolutionModeDNSRoundRobin { - for _, vip := range s.Endpoint.VirtualIPs { - if err := na.deallocateVIP(vip); err != nil { - // don't bail here, deallocate as many as possible. - log.L.WithError(err). - WithField("vip.network", vip.NetworkID). - WithField("vip.addr", vip.Addr).Error("error deallocating vip") - } - } - - s.Endpoint.VirtualIPs = nil - - delete(na.services, s.ID) - return nil - } - - specNetworks := serviceNetworks(s) - - // Allocate VIPs for all the pre-populated endpoint attachments - eVIPs := s.Endpoint.VirtualIPs[:0] - -vipLoop: - for _, eAttach := range s.Endpoint.VirtualIPs { - if na.IsVIPOnIngressNetwork(eAttach) && IsIngressNetworkNeeded(s) { - if err = na.allocateVIP(eAttach); err != nil { - return err - } - eVIPs = append(eVIPs, eAttach) - continue vipLoop - - } - for _, nAttach := range specNetworks { - if nAttach.Target == eAttach.NetworkID { - if err = na.allocateVIP(eAttach); err != nil { - return err - } - eVIPs = append(eVIPs, eAttach) - continue vipLoop - } - } - // If the network of the VIP is not part of the service spec, - // deallocate the vip - na.deallocateVIP(eAttach) - } - -networkLoop: - for _, nAttach := range specNetworks { - for _, vip := range s.Endpoint.VirtualIPs { - if vip.NetworkID == nAttach.Target { - continue networkLoop - } - } - - vip := &api.Endpoint_VirtualIP{NetworkID: nAttach.Target} - if err = na.allocateVIP(vip); err != nil { - return err - } - - eVIPs = append(eVIPs, vip) - } - - if len(eVIPs) > 0 { - na.services[s.ID] = struct{}{} - } else { - delete(na.services, s.ID) - } - - s.Endpoint.VirtualIPs = eVIPs - return nil -} - -// ServiceDeallocate de-allocates all the network resources such as -// virtual IP and ports associated with the service. -func (na *NetworkAllocator) ServiceDeallocate(s *api.Service) error { - if s.Endpoint == nil { - return nil - } - - for _, vip := range s.Endpoint.VirtualIPs { - if err := na.deallocateVIP(vip); err != nil { - // don't bail here, deallocate as many as possible. - log.L.WithError(err). - WithField("vip.network", vip.NetworkID). - WithField("vip.addr", vip.Addr).Error("error deallocating vip") - } - } - s.Endpoint.VirtualIPs = nil - - na.portAllocator.serviceDeallocatePorts(s) - delete(na.services, s.ID) - - return nil -} - -// IsAllocated returns if the passed network has been allocated or not. -func (na *NetworkAllocator) IsAllocated(n *api.Network) bool { - _, ok := na.networks[n.ID] - return ok -} - -// IsTaskAllocated returns if the passed task has its network resources allocated or not. -func (na *NetworkAllocator) IsTaskAllocated(t *api.Task) bool { - // If the task is not found in the allocated set, then it is - // not allocated. - if _, ok := na.tasks[t.ID]; !ok { - return false - } - - // If Networks is empty there is no way this Task is allocated. - if len(t.Networks) == 0 { - return false - } - - // To determine whether the task has its resources allocated, - // we just need to look at one global scope network (in case of - // multi-network attachment). This is because we make sure we - // allocate for every network or we allocate for none. - - // Find the first global scope network - for _, nAttach := range t.Networks { - // If the network is not allocated, the task cannot be allocated. - localNet, ok := na.networks[nAttach.Network.ID] - if !ok { - return false - } - - // Nothing else to check for local scope network - if localNet.isNodeLocal { - continue - } - - // Addresses empty. Task is not allocated. - if len(nAttach.Addresses) == 0 { - return false - } - - // The allocated IP address not found in local endpoint state. Not allocated. - if _, ok := localNet.endpoints[nAttach.Addresses[0]]; !ok { - return false - } - } - - return true -} - -// HostPublishPortsNeedUpdate returns true if the passed service needs -// allocations for its published ports in host (non ingress) mode -func (na *NetworkAllocator) HostPublishPortsNeedUpdate(s *api.Service) bool { - return na.portAllocator.hostPublishPortsNeedUpdate(s) -} - -// ServiceAllocationOpts is struct used for functional options in IsServiceAllocated +// ServiceAllocationOpts is struct used for functional options in +// IsServiceAllocated type ServiceAllocationOpts struct { OnInit bool } @@ -376,593 +28,74 @@ func OnInit(options *ServiceAllocationOpts) { options.OnInit = true } -// ServiceNeedsAllocation returns true if the passed service needs to have network resources allocated/updated. -func (na *NetworkAllocator) ServiceNeedsAllocation(s *api.Service, flags ...func(*ServiceAllocationOpts)) bool { - var options ServiceAllocationOpts - for _, flag := range flags { - flag(&options) - } - - specNetworks := serviceNetworks(s) - - // If endpoint mode is VIP and allocator does not have the - // service in VIP allocated set then it needs to be allocated. - if len(specNetworks) != 0 && - (s.Spec.Endpoint == nil || - s.Spec.Endpoint.Mode == api.ResolutionModeVirtualIP) { - - if _, ok := na.services[s.ID]; !ok { - return true - } - - if s.Endpoint == nil || len(s.Endpoint.VirtualIPs) == 0 { - return true - } - - // If the spec has networks which don't have a corresponding VIP, - // the service needs to be allocated. - networkLoop: - for _, net := range specNetworks { - for _, vip := range s.Endpoint.VirtualIPs { - if vip.NetworkID == net.Target { - continue networkLoop - } - } - return true - } - } - - // If the spec no longer has networks attached and has a vip allocated - // from previous spec the service needs to allocated. - if s.Endpoint != nil { - vipLoop: - for _, vip := range s.Endpoint.VirtualIPs { - if na.IsVIPOnIngressNetwork(vip) && IsIngressNetworkNeeded(s) { - continue vipLoop - } - for _, net := range specNetworks { - if vip.NetworkID == net.Target { - continue vipLoop - } - } - return true - } - } - - // If the endpoint mode is DNSRR and allocator has the service - // in VIP allocated set then we return to be allocated to make - // sure the allocator triggers networkallocator to free up the - // resources if any. - if s.Spec.Endpoint != nil && s.Spec.Endpoint.Mode == api.ResolutionModeDNSRoundRobin { - if _, ok := na.services[s.ID]; ok { - return true - } - } - - if (s.Spec.Endpoint != nil && len(s.Spec.Endpoint.Ports) != 0) || - (s.Endpoint != nil && len(s.Endpoint.Ports) != 0) { - return !na.portAllocator.isPortsAllocatedOnInit(s, options.OnInit) - } - return false -} - -// IsNodeAllocated returns if the passed node has its network resources allocated or not. -func (na *NetworkAllocator) IsNodeAllocated(node *api.Node) bool { - // If the node is not found in the allocated set, then it is - // not allocated. - if _, ok := na.nodes[node.ID]; !ok { - return false - } - - // If no attachment, not allocated. - if node.Attachment == nil { - return false - } - - // If the network is not allocated, the node cannot be allocated. - localNet, ok := na.networks[node.Attachment.Network.ID] - if !ok { - return false - } - - // Addresses empty, not allocated. - if len(node.Attachment.Addresses) == 0 { - return false - } - - // The allocated IP address not found in local endpoint state. Not allocated. - if _, ok := localNet.endpoints[node.Attachment.Addresses[0]]; !ok { - return false - } - - return true -} - -// AllocateNode allocates the IP addresses for the network to which -// the node is attached. -func (na *NetworkAllocator) AllocateNode(node *api.Node) error { - if err := na.allocateNetworkIPs(node.Attachment); err != nil { - return err - } - - na.nodes[node.ID] = struct{}{} - return nil -} - -// DeallocateNode deallocates the IP addresses for the network to -// which the node is attached. -func (na *NetworkAllocator) DeallocateNode(node *api.Node) error { - delete(na.nodes, node.ID) - return na.releaseEndpoints([]*api.NetworkAttachment{node.Attachment}) -} - -// AllocateTask allocates all the endpoint resources for all the -// networks that a task is attached to. -func (na *NetworkAllocator) AllocateTask(t *api.Task) error { - for i, nAttach := range t.Networks { - if localNet := na.getNetwork(nAttach.Network.ID); localNet != nil && localNet.isNodeLocal { - continue - } - if err := na.allocateNetworkIPs(nAttach); err != nil { - if err := na.releaseEndpoints(t.Networks[:i]); err != nil { - log.G(context.TODO()).WithError(err).Errorf("Failed to release IP addresses while rolling back allocation for task %s network %s", t.ID, nAttach.Network.ID) - } - return errors.Wrapf(err, "failed to allocate network IP for task %s network %s", t.ID, nAttach.Network.ID) - } - } - - na.tasks[t.ID] = struct{}{} - - return nil -} - -// DeallocateTask releases all the endpoint resources for all the -// networks that a task is attached to. -func (na *NetworkAllocator) DeallocateTask(t *api.Task) error { - delete(na.tasks, t.ID) - return na.releaseEndpoints(t.Networks) -} - -func (na *NetworkAllocator) releaseEndpoints(networks []*api.NetworkAttachment) error { - for _, nAttach := range networks { - localNet := na.getNetwork(nAttach.Network.ID) - if localNet == nil { - return fmt.Errorf("could not find network allocator state for network %s", nAttach.Network.ID) - } - - if localNet.isNodeLocal { - continue - } - - ipam, _, _, err := na.resolveIPAM(nAttach.Network) - if err != nil { - return errors.Wrap(err, "failed to resolve IPAM while releasing") - } - - // Do not fail and bail out if we fail to release IP - // address here. Keep going and try releasing as many - // addresses as possible. - for _, addr := range nAttach.Addresses { - // Retrieve the poolID and immediately nuke - // out the mapping. - poolID := localNet.endpoints[addr] - delete(localNet.endpoints, addr) - - ip, _, err := net.ParseCIDR(addr) - if err != nil { - log.G(context.TODO()).Errorf("Could not parse IP address %s while releasing", addr) - continue - } - - if err := ipam.ReleaseAddress(poolID, ip); err != nil { - log.G(context.TODO()).WithError(err).Errorf("IPAM failure while releasing IP address %s", addr) - } - } - - // Clear out the address list when we are done with - // this network. - nAttach.Addresses = nil - } - - return nil -} - -// allocate virtual IP for a single endpoint attachment of the service. -func (na *NetworkAllocator) allocateVIP(vip *api.Endpoint_VirtualIP) error { - localNet := na.getNetwork(vip.NetworkID) - if localNet == nil { - return errors.New("networkallocator: could not find local network state") - } - - if localNet.isNodeLocal { - return nil - } - - // If this IP is already allocated in memory we don't need to - // do anything. - if _, ok := localNet.endpoints[vip.Addr]; ok { - return nil - } - - ipam, _, _, err := na.resolveIPAM(localNet.nw) - if err != nil { - return errors.Wrap(err, "failed to resolve IPAM while allocating") - } - - var addr net.IP - if vip.Addr != "" { - var err error - - addr, _, err = net.ParseCIDR(vip.Addr) - if err != nil { - return err - } - } - - for _, poolID := range localNet.pools { - ip, _, err := ipam.RequestAddress(poolID, addr, nil) - if err != nil && err != ipamapi.ErrNoAvailableIPs && err != ipamapi.ErrIPOutOfRange { - return errors.Wrap(err, "could not allocate VIP from IPAM") - } - - // If we got an address then we are done. - if err == nil { - ipStr := ip.String() - localNet.endpoints[ipStr] = poolID - vip.Addr = ipStr - return nil - } - } - - return errors.New("could not find an available IP while allocating VIP") -} - -func (na *NetworkAllocator) deallocateVIP(vip *api.Endpoint_VirtualIP) error { - localNet := na.getNetwork(vip.NetworkID) - if localNet == nil { - return errors.New("networkallocator: could not find local network state") - } - if localNet.isNodeLocal { - return nil - } - ipam, _, _, err := na.resolveIPAM(localNet.nw) - if err != nil { - return errors.Wrap(err, "failed to resolve IPAM while allocating") - } - - // Retrieve the poolID and immediately nuke - // out the mapping. - poolID := localNet.endpoints[vip.Addr] - delete(localNet.endpoints, vip.Addr) - - ip, _, err := net.ParseCIDR(vip.Addr) - if err != nil { - log.G(context.TODO()).Errorf("Could not parse VIP address %s while releasing", vip.Addr) - return err - } - - if err := ipam.ReleaseAddress(poolID, ip); err != nil { - log.G(context.TODO()).WithError(err).Errorf("IPAM failure while releasing VIP address %s", vip.Addr) - return err - } - - return nil -} - -// allocate the IP addresses for a single network attachment of the task. -func (na *NetworkAllocator) allocateNetworkIPs(nAttach *api.NetworkAttachment) error { - var ip *net.IPNet - - ipam, _, _, err := na.resolveIPAM(nAttach.Network) - if err != nil { - return errors.Wrap(err, "failed to resolve IPAM while allocating") - } - - localNet := na.getNetwork(nAttach.Network.ID) - if localNet == nil { - return fmt.Errorf("could not find network allocator state for network %s", nAttach.Network.ID) - } - - addresses := nAttach.Addresses - if len(addresses) == 0 { - addresses = []string{""} - } - - for i, rawAddr := range addresses { - var addr net.IP - if rawAddr != "" { - var err error - addr, _, err = net.ParseCIDR(rawAddr) - if err != nil { - addr = net.ParseIP(rawAddr) - - if addr == nil { - return errors.Wrapf(err, "could not parse address string %s", rawAddr) - } - } - } - - for _, poolID := range localNet.pools { - var err error - - ip, _, err = ipam.RequestAddress(poolID, addr, nil) - if err != nil && err != ipamapi.ErrNoAvailableIPs && err != ipamapi.ErrIPOutOfRange { - return errors.Wrap(err, "could not allocate IP from IPAM") - } - - // If we got an address then we are done. - if err == nil { - ipStr := ip.String() - localNet.endpoints[ipStr] = poolID - addresses[i] = ipStr - nAttach.Addresses = addresses - return nil - } - } - } - - return errors.New("could not find an available IP") -} - -func (na *NetworkAllocator) freeDriverState(n *api.Network) error { - d, err := na.resolveDriver(n) - if err != nil { - return err - } - - return d.driver.NetworkFree(n.ID) -} - -func (na *NetworkAllocator) allocateDriverState(n *api.Network) error { - d, err := na.resolveDriver(n) - if err != nil { - return err - } - - options := make(map[string]string) - // reconcile the driver specific options from the network spec - // and from the operational state retrieved from the store - if n.Spec.DriverConfig != nil { - for k, v := range n.Spec.DriverConfig.Options { - options[k] = v - } - } - if n.DriverState != nil { - for k, v := range n.DriverState.Options { - options[k] = v - } - } - - // Construct IPAM data for driver consumption. - ipv4Data := make([]driverapi.IPAMData, 0, len(n.IPAM.Configs)) - for _, ic := range n.IPAM.Configs { - if ic.Family == api.IPAMConfig_IPV6 { - continue - } - - _, subnet, err := net.ParseCIDR(ic.Subnet) - if err != nil { - return errors.Wrapf(err, "error parsing subnet %s while allocating driver state", ic.Subnet) - } - - gwIP := net.ParseIP(ic.Gateway) - gwNet := &net.IPNet{ - IP: gwIP, - Mask: subnet.Mask, - } - - data := driverapi.IPAMData{ - Pool: subnet, - Gateway: gwNet, - } - - ipv4Data = append(ipv4Data, data) - } - - ds, err := d.driver.NetworkAllocate(n.ID, options, ipv4Data, nil) - if err != nil { - return err - } - - // Update network object with the obtained driver state. - n.DriverState = &api.Driver{ - Name: d.name, - Options: ds, - } - - return nil -} - -// Resolve network driver -func (na *NetworkAllocator) resolveDriver(n *api.Network) (*networkDriver, error) { - dName := DefaultDriver - if n.Spec.DriverConfig != nil && n.Spec.DriverConfig.Name != "" { - dName = n.Spec.DriverConfig.Name - } - - d, drvcap := na.drvRegistry.Driver(dName) - if d == nil { - var err error - err = na.loadDriver(dName) - if err != nil { - return nil, err - } - - d, drvcap = na.drvRegistry.Driver(dName) - if d == nil { - return nil, fmt.Errorf("could not resolve network driver %s", dName) - } - } - - return &networkDriver{driver: d, capability: drvcap, name: dName}, nil -} - -func (na *NetworkAllocator) loadDriver(name string) error { - pg := na.drvRegistry.GetPluginGetter() - if pg == nil { - return errors.New("plugin store is uninitialized") - } - _, err := pg.Get(name, driverapi.NetworkPluginEndpointType, plugingetter.Lookup) - return err -} - -// Resolve the IPAM driver -func (na *NetworkAllocator) resolveIPAM(n *api.Network) (ipamapi.Ipam, string, map[string]string, error) { - dName := ipamapi.DefaultIPAM - if n.Spec.IPAM != nil && n.Spec.IPAM.Driver != nil && n.Spec.IPAM.Driver.Name != "" { - dName = n.Spec.IPAM.Driver.Name - } - - var dOptions map[string]string - if n.Spec.IPAM != nil && n.Spec.IPAM.Driver != nil && len(n.Spec.IPAM.Driver.Options) != 0 { - dOptions = n.Spec.IPAM.Driver.Options - } - - ipam, _ := na.drvRegistry.IPAM(dName) - if ipam == nil { - return nil, "", nil, fmt.Errorf("could not resolve IPAM driver %s", dName) - } - - return ipam, dName, dOptions, nil -} - -func (na *NetworkAllocator) freePools(n *api.Network, pools map[string]string) error { - ipam, _, _, err := na.resolveIPAM(n) - if err != nil { - return errors.Wrapf(err, "failed to resolve IPAM while freeing pools for network %s", n.ID) - } - - releasePools(ipam, n.IPAM.Configs, pools) - return nil -} - -func releasePools(ipam ipamapi.Ipam, icList []*api.IPAMConfig, pools map[string]string) { - for _, ic := range icList { - if err := ipam.ReleaseAddress(pools[ic.Subnet], net.ParseIP(ic.Gateway)); err != nil { - log.G(context.TODO()).WithError(err).Errorf("Failed to release address %s", ic.Subnet) - } - } - - for k, p := range pools { - if err := ipam.ReleasePool(p); err != nil { - log.G(context.TODO()).WithError(err).Errorf("Failed to release pool %s", k) - } - } -} - -func (na *NetworkAllocator) allocatePools(n *api.Network) (map[string]string, error) { - ipam, dName, dOptions, err := na.resolveIPAM(n) - if err != nil { - return nil, err - } - - // We don't support user defined address spaces yet so just - // retrieve default address space names for the driver. - _, asName, err := na.drvRegistry.IPAMDefaultAddressSpaces(dName) - if err != nil { - return nil, err - } - - pools := make(map[string]string) - - var ipamConfigs []*api.IPAMConfig - - // If there is non-nil IPAM state always prefer those subnet - // configs over Spec configs. - if n.IPAM != nil { - ipamConfigs = n.IPAM.Configs - } else if n.Spec.IPAM != nil { - ipamConfigs = make([]*api.IPAMConfig, len(n.Spec.IPAM.Configs)) - copy(ipamConfigs, n.Spec.IPAM.Configs) - } - - // Append an empty slot for subnet allocation if there are no - // IPAM configs from either spec or state. - if len(ipamConfigs) == 0 { - ipamConfigs = append(ipamConfigs, &api.IPAMConfig{Family: api.IPAMConfig_IPV4}) - } - - // Update the runtime IPAM configurations with initial state - n.IPAM = &api.IPAMOptions{ - Driver: &api.Driver{Name: dName, Options: dOptions}, - Configs: ipamConfigs, - } - - for i, ic := range ipamConfigs { - poolID, poolIP, meta, err := ipam.RequestPool(asName, ic.Subnet, ic.Range, dOptions, false) - if err != nil { - // Rollback by releasing all the resources allocated so far. - releasePools(ipam, ipamConfigs[:i], pools) - return nil, err - } - pools[poolIP.String()] = poolID - - // The IPAM contract allows the IPAM driver to autonomously - // provide a network gateway in response to the pool request. - // But if the network spec contains a gateway, we will allocate - // it irrespective of whether the ipam driver returned one already. - // If none of the above is true, we need to allocate one now, and - // let the driver know this request is for the network gateway. - var ( - gwIP *net.IPNet - ip net.IP - ) - if gws, ok := meta[netlabel.Gateway]; ok { - if ip, gwIP, err = net.ParseCIDR(gws); err != nil { - return nil, fmt.Errorf("failed to parse gateway address (%v) returned by ipam driver: %v", gws, err) - } - gwIP.IP = ip - } - if ic.Gateway != "" || gwIP == nil { - gwIP, _, err = ipam.RequestAddress(poolID, net.ParseIP(ic.Gateway), map[string]string{ipamapi.RequestAddressType: netlabel.Gateway}) - if err != nil { - // Rollback by releasing all the resources allocated so far. - releasePools(ipam, ipamConfigs[:i], pools) - return nil, err - } - } - - if ic.Subnet == "" { - ic.Subnet = poolIP.String() - } - - if ic.Gateway == "" { - ic.Gateway = gwIP.IP.String() - } - - } - - return pools, nil -} - -func initializeDrivers(reg *drvregistry.DrvRegistry) error { - for _, i := range initializers { - if err := reg.AddDriver(i.ntype, i.fn, nil); err != nil { - return err - } - } - return nil -} - -func serviceNetworks(s *api.Service) []*api.NetworkAttachmentConfig { - // Always prefer NetworkAttachmentConfig in the TaskSpec - if len(s.Spec.Task.Networks) == 0 && len(s.Spec.Networks) != 0 { - return s.Spec.Networks - } - return s.Spec.Task.Networks -} - -// IsVIPOnIngressNetwork check if the vip is in ingress network -func (na *NetworkAllocator) IsVIPOnIngressNetwork(vip *api.Endpoint_VirtualIP) bool { - if vip == nil { - return false - } - - localNet := na.getNetwork(vip.NetworkID) - if localNet != nil && localNet.nw != nil { - return IsIngressNetwork(localNet.nw) - } - return false +// NetworkAllocator provides network model specific allocation functionality. +type NetworkAllocator interface { + // + // Network Allocation + // + + // IsAllocated returns if the passed network has been allocated or not. + IsAllocated(n *api.Network) bool + + // Allocate allocates all the necessary resources both general + // and driver-specific which may be specified in the NetworkSpec + Allocate(n *api.Network) error + + // Deallocate frees all the general and driver specific resources + // which were assigned to the passed network. + Deallocate(n *api.Network) error + + // + // Service Allocation + // + + // IsServiceAllocated returns false if the passed service + // needs to have network resources allocated/updated. + IsServiceAllocated(s *api.Service, flags ...func(*ServiceAllocationOpts)) bool + + // AllocateService allocates all the network resources such as virtual + // IP and ports needed by the service. + AllocateService(s *api.Service) (err error) + + // DeallocateService de-allocates all the network resources such as + // virtual IP and ports associated with the service. + DeallocateService(s *api.Service) error + + // HostPublishPortsNeedUpdate returns true if the passed service needs + // allocations for its published ports in host (non ingress) mode + HostPublishPortsNeedUpdate(s *api.Service) bool + + // + // Node Allocation + // + + // IsNodeAllocated returns if the passed node has its network + // resources allocated or not. + IsNodeAllocated(node *api.Node) bool + + // AllocateNode allocates the IP addresses for the network to which + // the node is attached. + AllocateNode(node *api.Node) error + + // DeallocateNode deallocates the IP addresses for the network to + // which the node is attached. + DeallocateNode(node *api.Node) error + + // + // Task Allocation + // + + // IsTaskAllocated returns if the passed task has its network + // resources allocated or not. + IsTaskAllocated(t *api.Task) bool + + // AllocateTask allocates all the endpoint resources for all the + // networks that a task is attached to. + AllocateTask(t *api.Task) error + + // DeallocateTask releases all the endpoint resources for all the + // networks that a task is attached to. + DeallocateTask(t *api.Task) error } // IsIngressNetwork check if the network is an ingress network @@ -997,14 +130,3 @@ func IsIngressNetworkNeeded(s *api.Service) bool { return false } - -// IsBuiltInDriver returns whether the passed driver is an internal network driver -func IsBuiltInDriver(name string) bool { - n := strings.ToLower(name) - for _, d := range initializers { - if n == d.ntype { - return true - } - } - return false -} diff --git a/components/engine/vendor/github.com/docker/swarmkit/manager/controlapi/common.go b/components/engine/vendor/github.com/docker/swarmkit/manager/controlapi/common.go index 56f0f8a00d..c01662379e 100644 --- a/components/engine/vendor/github.com/docker/swarmkit/manager/controlapi/common.go +++ b/components/engine/vendor/github.com/docker/swarmkit/manager/controlapi/common.go @@ -5,9 +5,10 @@ import ( "strings" "github.com/docker/docker/pkg/plugingetter" + "github.com/docker/libnetwork/driverapi" "github.com/docker/libnetwork/ipamapi" "github.com/docker/swarmkit/api" - "github.com/docker/swarmkit/manager/allocator/networkallocator" + "github.com/docker/swarmkit/manager/allocator" "github.com/docker/swarmkit/manager/state/store" "google.golang.org/grpc" "google.golang.org/grpc/codes" @@ -110,10 +111,11 @@ func validateDriver(driver *api.Driver, pg plugingetter.PluginGetter, pluginType if strings.ToLower(driver.Name) == ipamapi.DefaultIPAM { return nil } - default: - if networkallocator.IsBuiltInDriver(driver.Name) { + case driverapi.NetworkPluginEndpointType: + if allocator.IsBuiltInNetworkDriver(driver.Name) { return nil } + default: } if pg == nil { diff --git a/components/engine/vendor/github.com/docker/swarmkit/manager/controlapi/service.go b/components/engine/vendor/github.com/docker/swarmkit/manager/controlapi/service.go index ecf79579c6..d556b6c0e7 100644 --- a/components/engine/vendor/github.com/docker/swarmkit/manager/controlapi/service.go +++ b/components/engine/vendor/github.com/docker/swarmkit/manager/controlapi/service.go @@ -9,6 +9,7 @@ import ( "github.com/docker/distribution/reference" "github.com/docker/swarmkit/api" "github.com/docker/swarmkit/api/defaults" + "github.com/docker/swarmkit/api/genericresource" "github.com/docker/swarmkit/api/naming" "github.com/docker/swarmkit/identity" "github.com/docker/swarmkit/manager/allocator" @@ -42,6 +43,9 @@ func validateResources(r *api.Resources) error { if r.MemoryBytes != 0 && r.MemoryBytes < 4*1024*1024 { return grpc.Errorf(codes.InvalidArgument, "invalid memory value %d: Must be at least 4MiB", r.MemoryBytes) } + if err := genericresource.ValidateTask(r); err != nil { + return nil + } return nil } diff --git a/components/engine/vendor/github.com/docker/swarmkit/manager/manager.go b/components/engine/vendor/github.com/docker/swarmkit/manager/manager.go index 005a56c33d..c29e9050b7 100644 --- a/components/engine/vendor/github.com/docker/swarmkit/manager/manager.go +++ b/components/engine/vendor/github.com/docker/swarmkit/manager/manager.go @@ -217,7 +217,6 @@ func New(config *Config) (*Manager, error) { m := &Manager{ config: *config, - collector: metrics.NewCollector(raftNode.MemoryStore()), caserver: ca.NewServer(raftNode.MemoryStore(), config.SecurityConfig, config.RootCAPaths), dispatcher: dispatcher.New(raftNode, dispatcher.DefaultConfig()), logbroker: logbroker.New(raftNode.MemoryStore()), @@ -502,12 +501,16 @@ func (m *Manager) Run(parent context.Context) error { healthServer.SetServingStatus("Raft", api.HealthCheckResponse_SERVING) if err := m.raftNode.JoinAndStart(ctx); err != nil { + // Don't block future calls to Stop. + close(m.started) return errors.Wrap(err, "can't initialize raft node") } localHealthServer.SetServingStatus("ControlAPI", api.HealthCheckResponse_SERVING) // Start metrics collection. + + m.collector = metrics.NewCollector(m.raftNode.MemoryStore()) go func(collector *metrics.Collector) { if err := collector.Run(ctx); err != nil { log.G(ctx).WithError(err).Error("collector failed with an error") @@ -590,7 +593,10 @@ func (m *Manager) Stop(ctx context.Context, clearData bool) { m.raftNode.Cancel() - m.collector.Stop() + if m.collector != nil { + m.collector.Stop() + } + m.dispatcher.Stop() m.logbroker.Stop() m.caserver.Stop() @@ -944,7 +950,7 @@ func (m *Manager) becomeLeader(ctx context.Context) { // in order to allow running services on the predefined docker // networks like `bridge` and `host`. log.G(ctx).Info("Creating node-local predefined networks") - for _, p := range networkallocator.PredefinedNetworks() { + for _, p := range allocator.PredefinedNetworks() { if err := store.CreateNetwork(tx, newPredefinedNetwork(p.Name, p.Driver)); err != nil { log.G(ctx).WithError(err).Error("failed to create predefined network " + p.Name) } diff --git a/components/engine/vendor/github.com/docker/swarmkit/manager/orchestrator/constraintenforcer/constraint_enforcer.go b/components/engine/vendor/github.com/docker/swarmkit/manager/orchestrator/constraintenforcer/constraint_enforcer.go index 06c34d9a21..2978898ccb 100644 --- a/components/engine/vendor/github.com/docker/swarmkit/manager/orchestrator/constraintenforcer/constraint_enforcer.go +++ b/components/engine/vendor/github.com/docker/swarmkit/manager/orchestrator/constraintenforcer/constraint_enforcer.go @@ -4,6 +4,7 @@ import ( "time" "github.com/docker/swarmkit/api" + "github.com/docker/swarmkit/api/genericresource" "github.com/docker/swarmkit/log" "github.com/docker/swarmkit/manager/constraint" "github.com/docker/swarmkit/manager/state" @@ -83,10 +84,11 @@ func (ce *ConstraintEnforcer) rejectNoncompliantTasks(node *api.Node) { log.L.WithError(err).Errorf("failed to list tasks for node ID %s", node.ID) } - var availableMemoryBytes, availableNanoCPUs int64 + available := &api.Resources{} + var fakeStore []*api.GenericResource + if node.Description != nil && node.Description.Resources != nil { - availableMemoryBytes = node.Description.Resources.MemoryBytes - availableNanoCPUs = node.Description.Resources.NanoCPUs + available = node.Description.Resources.Copy() } removeTasks := make(map[string]*api.Task) @@ -97,6 +99,7 @@ func (ce *ConstraintEnforcer) rejectNoncompliantTasks(node *api.Node) { // a separate pass over the tasks for each type of // resource, and sort by the size of the reservation // to remove the most resource-intensive tasks. +loop: for _, t := range tasks { if t.DesiredState < api.TaskStateAssigned || t.DesiredState > api.TaskStateRunning { continue @@ -115,16 +118,27 @@ func (ce *ConstraintEnforcer) rejectNoncompliantTasks(node *api.Node) { // Ensure that the task assigned to the node // still satisfies the resource limits. if t.Spec.Resources != nil && t.Spec.Resources.Reservations != nil { - if t.Spec.Resources.Reservations.MemoryBytes > availableMemoryBytes { + if t.Spec.Resources.Reservations.MemoryBytes > available.MemoryBytes { removeTasks[t.ID] = t continue } - if t.Spec.Resources.Reservations.NanoCPUs > availableNanoCPUs { + if t.Spec.Resources.Reservations.NanoCPUs > available.NanoCPUs { removeTasks[t.ID] = t continue } - availableMemoryBytes -= t.Spec.Resources.Reservations.MemoryBytes - availableNanoCPUs -= t.Spec.Resources.Reservations.NanoCPUs + for _, ta := range t.AssignedGenericResources { + // Type change or no longer available + if genericresource.HasResource(ta, available.Generic) { + removeTasks[t.ID] = t + break loop + } + } + + available.MemoryBytes -= t.Spec.Resources.Reservations.MemoryBytes + available.NanoCPUs -= t.Spec.Resources.Reservations.NanoCPUs + + genericresource.ClaimResources(&available.Generic, + &fakeStore, t.AssignedGenericResources) } } diff --git a/components/engine/vendor/github.com/docker/swarmkit/manager/orchestrator/task.go b/components/engine/vendor/github.com/docker/swarmkit/manager/orchestrator/task.go index 54a069e199..32a22d5f5a 100644 --- a/components/engine/vendor/github.com/docker/swarmkit/manager/orchestrator/task.go +++ b/components/engine/vendor/github.com/docker/swarmkit/manager/orchestrator/task.go @@ -63,7 +63,7 @@ func IsTaskDirty(s *api.Service, t *api.Task) bool { // If the spec version matches, we know the task is not dirty. However, // if it does not match, that doesn't mean the task is dirty, since // only a portion of the spec is included in the comparison. - if t.SpecVersion != nil && *s.SpecVersion == *t.SpecVersion { + if t.SpecVersion != nil && s.SpecVersion != nil && *s.SpecVersion == *t.SpecVersion { return false } diff --git a/components/engine/vendor/github.com/docker/swarmkit/manager/scheduler/filter.go b/components/engine/vendor/github.com/docker/swarmkit/manager/scheduler/filter.go index 2909a648d7..6ce3f2c8b8 100644 --- a/components/engine/vendor/github.com/docker/swarmkit/manager/scheduler/filter.go +++ b/components/engine/vendor/github.com/docker/swarmkit/manager/scheduler/filter.go @@ -5,6 +5,7 @@ import ( "strings" "github.com/docker/swarmkit/api" + "github.com/docker/swarmkit/api/genericresource" "github.com/docker/swarmkit/manager/constraint" ) @@ -61,9 +62,12 @@ func (f *ResourceFilter) SetTask(t *api.Task) bool { if r == nil || r.Reservations == nil { return false } - if r.Reservations.NanoCPUs == 0 && r.Reservations.MemoryBytes == 0 { + + res := r.Reservations + if res.NanoCPUs == 0 && res.MemoryBytes == 0 && len(res.Generic) == 0 { return false } + f.reservations = r.Reservations return true } @@ -78,6 +82,13 @@ func (f *ResourceFilter) Check(n *NodeInfo) bool { return false } + for _, v := range f.reservations.Generic { + enough, err := genericresource.HasEnough(n.AvailableResources.Generic, v) + if err != nil || !enough { + return false + } + } + return true } @@ -128,6 +139,12 @@ func (f *PluginFilter) SetTask(t *api.Task) bool { // Check returns true if the task can be scheduled into the given node. // TODO(amitshukla): investigate storing Plugins as a map so it can be easily probed func (f *PluginFilter) Check(n *NodeInfo) bool { + if n.Description == nil || n.Description.Engine == nil { + // If the node is not running Engine, plugins are not + // supported. + return true + } + // Get list of plugins on the node nodePlugins := n.Description.Engine.Plugins diff --git a/components/engine/vendor/github.com/docker/swarmkit/manager/scheduler/nodeinfo.go b/components/engine/vendor/github.com/docker/swarmkit/manager/scheduler/nodeinfo.go index 25b22d7b15..51322a054d 100644 --- a/components/engine/vendor/github.com/docker/swarmkit/manager/scheduler/nodeinfo.go +++ b/components/engine/vendor/github.com/docker/swarmkit/manager/scheduler/nodeinfo.go @@ -4,6 +4,7 @@ import ( "time" "github.com/docker/swarmkit/api" + "github.com/docker/swarmkit/api/genericresource" "github.com/docker/swarmkit/log" "golang.org/x/net/context" ) @@ -20,7 +21,7 @@ type NodeInfo struct { Tasks map[string]*api.Task ActiveTasksCount int ActiveTasksCountByService map[string]int - AvailableResources api.Resources + AvailableResources *api.Resources usedHostPorts map[hostPortSpec]struct{} // recentFailures is a map from service ID to the timestamps of the @@ -36,7 +37,7 @@ func newNodeInfo(n *api.Node, tasks map[string]*api.Task, availableResources api Node: n, Tasks: make(map[string]*api.Task), ActiveTasksCountByService: make(map[string]int), - AvailableResources: availableResources, + AvailableResources: availableResources.Copy(), usedHostPorts: make(map[hostPortSpec]struct{}), recentFailures: make(map[string][]time.Time), } @@ -44,6 +45,7 @@ func newNodeInfo(n *api.Node, tasks map[string]*api.Task, availableResources api for _, t := range tasks { nodeInfo.addTask(t) } + return nodeInfo } @@ -62,8 +64,20 @@ func (nodeInfo *NodeInfo) removeTask(t *api.Task) bool { } reservations := taskReservations(t.Spec) - nodeInfo.AvailableResources.MemoryBytes += reservations.MemoryBytes - nodeInfo.AvailableResources.NanoCPUs += reservations.NanoCPUs + resources := nodeInfo.AvailableResources + + resources.MemoryBytes += reservations.MemoryBytes + resources.NanoCPUs += reservations.NanoCPUs + + if nodeInfo.Description == nil || nodeInfo.Description.Resources == nil || + nodeInfo.Description.Resources.Generic == nil { + return true + } + + taskAssigned := t.AssignedGenericResources + nodeAvailableResources := &resources.Generic + nodeRes := nodeInfo.Description.Resources.Generic + genericresource.Reclaim(nodeAvailableResources, taskAssigned, nodeRes) if t.Endpoint != nil { for _, port := range t.Endpoint.Ports { @@ -97,9 +111,18 @@ func (nodeInfo *NodeInfo) addTask(t *api.Task) bool { } nodeInfo.Tasks[t.ID] = t + reservations := taskReservations(t.Spec) - nodeInfo.AvailableResources.MemoryBytes -= reservations.MemoryBytes - nodeInfo.AvailableResources.NanoCPUs -= reservations.NanoCPUs + resources := nodeInfo.AvailableResources + + resources.MemoryBytes -= reservations.MemoryBytes + resources.NanoCPUs -= reservations.NanoCPUs + + // minimum size required + t.AssignedGenericResources = make([]*api.GenericResource, 0, len(resources.Generic)) + taskAssigned := &t.AssignedGenericResources + + genericresource.Claim(&resources.Generic, taskAssigned, reservations.Generic) if t.Endpoint != nil { for _, port := range t.Endpoint.Ports { diff --git a/components/engine/vendor/github.com/docker/swarmkit/manager/scheduler/scheduler.go b/components/engine/vendor/github.com/docker/swarmkit/manager/scheduler/scheduler.go index a6479b8834..3e5bbd0870 100644 --- a/components/engine/vendor/github.com/docker/swarmkit/manager/scheduler/scheduler.go +++ b/components/engine/vendor/github.com/docker/swarmkit/manager/scheduler/scheduler.go @@ -4,6 +4,7 @@ import ( "time" "github.com/docker/swarmkit/api" + "github.com/docker/swarmkit/api/genericresource" "github.com/docker/swarmkit/log" "github.com/docker/swarmkit/manager/state" "github.com/docker/swarmkit/manager/state/store" @@ -297,15 +298,21 @@ func (s *Scheduler) deleteTask(ctx context.Context, t *api.Task) bool { func (s *Scheduler) createOrUpdateNode(n *api.Node) { nodeInfo, _ := s.nodeSet.nodeInfo(n.ID) - var resources api.Resources + var resources *api.Resources if n.Description != nil && n.Description.Resources != nil { - resources = *n.Description.Resources + resources = n.Description.Resources.Copy() // reconcile resources by looping over all tasks in this node for _, task := range nodeInfo.Tasks { reservations := taskReservations(task.Spec) + resources.MemoryBytes -= reservations.MemoryBytes resources.NanoCPUs -= reservations.NanoCPUs + + genericresource.ConsumeNodeResources(&resources.Generic, + task.AssignedGenericResources) } + } else { + resources = &api.Resources{} } nodeInfo.Node = n nodeInfo.AvailableResources = resources diff --git a/components/engine/vendor/github.com/docker/swarmkit/manager/state/raft/raft.go b/components/engine/vendor/github.com/docker/swarmkit/manager/state/raft/raft.go index 82a550d0f6..b793374095 100644 --- a/components/engine/vendor/github.com/docker/swarmkit/manager/state/raft/raft.go +++ b/components/engine/vendor/github.com/docker/swarmkit/manager/state/raft/raft.go @@ -361,7 +361,7 @@ func (n *Node) JoinAndStart(ctx context.Context) (err error) { if err != nil { n.stopMu.Lock() // to shutdown transport - close(n.stopped) + n.cancelFunc() n.stopMu.Unlock() n.done() } else { diff --git a/components/engine/vendor/github.com/docker/swarmkit/node/node.go b/components/engine/vendor/github.com/docker/swarmkit/node/node.go index 6a40a06e16..ab8504c232 100644 --- a/components/engine/vendor/github.com/docker/swarmkit/node/node.go +++ b/components/engine/vendor/github.com/docker/swarmkit/node/node.go @@ -10,6 +10,7 @@ import ( "path/filepath" "reflect" "sort" + "strings" "sync" "time" @@ -33,6 +34,7 @@ import ( "github.com/pkg/errors" "golang.org/x/net/context" "google.golang.org/grpc" + "google.golang.org/grpc/codes" "google.golang.org/grpc/credentials" ) @@ -344,14 +346,14 @@ func (n *Node) run(ctx context.Context) (err error) { log.G(ctx).WithError(err).Error("invalid new root certificate from the dispatcher") continue } - if err := ca.SaveRootCA(newRootCA, paths.RootCA); err != nil { - log.G(ctx).WithError(err).Error("could not save new root certificate from the dispatcher") - continue - } if err := securityConfig.UpdateRootCA(&newRootCA, newRootCA.Pool); err != nil { log.G(ctx).WithError(err).Error("could not use new root CA from dispatcher") continue } + if err := ca.SaveRootCA(newRootCA, paths.RootCA); err != nil { + log.G(ctx).WithError(err).Error("could not save new root certificate from the dispatcher") + continue + } } } } @@ -432,10 +434,10 @@ func (n *Node) run(ctx context.Context) (err error) { }() wg.Wait() - if managerErr != nil && managerErr != context.Canceled { + if managerErr != nil && errors.Cause(managerErr) != context.Canceled { return managerErr } - if agentErr != nil && agentErr != context.Canceled { + if agentErr != nil && errors.Cause(agentErr) != context.Canceled { return agentErr } return err @@ -516,7 +518,7 @@ waitPeer: rootCA := securityConfig.RootCA() issuer := securityConfig.IssuerInfo() - a, err := agent.New(&agent.Config{ + agentConfig := &agent.Config{ Hostname: n.config.Hostname, ConnBroker: n.connBroker, Executor: n.config.Executor, @@ -529,7 +531,14 @@ waitPeer: CertIssuerPublicKey: issuer.PublicKey, CertIssuerSubject: issuer.Subject, }, - }) + } + // if a join address has been specified, then if the agent fails to connect due to a TLS error, fail fast - don't + // keep re-trying to join + if n.config.JoinAddr != "" { + agentConfig.SessionTracker = &firstSessionErrorTracker{} + } + + a, err := agent.New(agentConfig) if err != nil { return err } @@ -1055,3 +1064,37 @@ func (sp sortablePeers) Less(i, j int) bool { return sp[i].NodeID < sp[j].NodeID func (sp sortablePeers) Len() int { return len(sp) } func (sp sortablePeers) Swap(i, j int) { sp[i], sp[j] = sp[j], sp[i] } + +// firstSessionErrorTracker is a utility that helps determine whether the agent should exit after +// a TLS failure on establishing the first session. This should only happen if a join address +// is specified. If establishing the first session succeeds, but later on some session fails +// because of a TLS error, we don't want to exit the agent because a previously successful +// session indicates that the TLS error may be a transient issue. +type firstSessionErrorTracker struct { + mu sync.Mutex + pastFirstSession bool + err error +} + +func (fs *firstSessionErrorTracker) SessionEstablished() { + fs.mu.Lock() + fs.pastFirstSession = true + fs.mu.Unlock() +} + +func (fs *firstSessionErrorTracker) SessionError(err error) { + fs.mu.Lock() + fs.err = err + fs.mu.Unlock() +} + +func (fs *firstSessionErrorTracker) SessionClosed() error { + fs.mu.Lock() + defer fs.mu.Unlock() + // unfortunately grpc connection errors are type grpc.rpcError, which are not exposed, and we can't get at the underlying error type + if !fs.pastFirstSession && grpc.Code(fs.err) == codes.Internal && + strings.HasPrefix(grpc.ErrorDesc(fs.err), "connection error") && strings.Contains(grpc.ErrorDesc(fs.err), "transport: x509:") { + return fs.err + } + return nil +} diff --git a/components/engine/vendor/github.com/docker/swarmkit/vendor.conf b/components/engine/vendor/github.com/docker/swarmkit/vendor.conf index 0fdffeb0d5..6e86d96796 100644 --- a/components/engine/vendor/github.com/docker/swarmkit/vendor.conf +++ b/components/engine/vendor/github.com/docker/swarmkit/vendor.conf @@ -1,8 +1,9 @@ # grpc and protobuf -google.golang.org/grpc v1.0.4 +google.golang.org/grpc v1.3.0 github.com/gogo/protobuf v0.4 -github.com/golang/protobuf 8ee79997227bf9b34611aee7946ae64735e6fd93 +github.com/golang/protobuf 7a211bcf3bce0e3f1d74f9894916e6f116ae83b4 github.com/matttproud/golang_protobuf_extensions v1.0.0 +google.golang.org/genproto d80a6e20e776b0b17a324d0ba1ab50a39c8e8944 # metrics github.com/grpc-ecosystem/go-grpc-prometheus 6b7015e65d366bf3f19b2b2a000a831940f0f7e0 @@ -50,7 +51,7 @@ github.com/spf13/cobra 8e91712f174ced10270cf66615e0a9127e7c4de5 github.com/spf13/pflag 7f60f83a2c81bc3c3c0d5297f61ddfa68da9d3b7 github.com/stretchr/testify v1.1.4 golang.org/x/crypto 3fbbcd23f1cb824e69491a5930cfeff09b12f4d2 -golang.org/x/net c427ad74c6d7a814201695e9ffde0c5d400a7674 +golang.org/x/net 7dcfb8076726a3fdd9353b6b8a1f1b6be6811bd6 golang.org/x/sys 5eaf0df67e70d6997a9fe0ed24383fa1b01638d3 golang.org/x/text f72d8390a633d5dfb0cc84043294db9f6c935756 golang.org/x/time a4bde12657593d5e90d0533a3e4fd95e635124cb