Ver Fonte

Merge pull request #31535 from aaronlehmann/vendor-swarmkit-7fc7503

Vendor swarmkit d60ccf3
Tõnis Tiigi há 8 anos atrás
pai
commit
3fe2730ab3
29 ficheiros alterados com 793 adições e 807 exclusões
  1. 20 0
      integration-cli/docker_api_swarm_test.go
  2. 2 1
      integration-cli/docker_cli_service_logs_experimental_test.go
  3. 1 1
      vendor.conf
  4. 14 2
      vendor/github.com/docker/swarmkit/agent/agent.go
  5. 157 116
      vendor/github.com/docker/swarmkit/api/control.pb.go
  6. 5 0
      vendor/github.com/docker/swarmkit/api/control.proto
  7. 82 43
      vendor/github.com/docker/swarmkit/api/logbroker.pb.go
  8. 6 0
      vendor/github.com/docker/swarmkit/api/logbroker.proto
  9. 142 397
      vendor/github.com/docker/swarmkit/api/specs.pb.go
  10. 0 9
      vendor/github.com/docker/swarmkit/api/specs.proto
  11. 0 1
      vendor/github.com/docker/swarmkit/api/types.pb.go
  12. 122 49
      vendor/github.com/docker/swarmkit/ca/certificates.go
  13. 52 59
      vendor/github.com/docker/swarmkit/ca/config.go
  14. 2 2
      vendor/github.com/docker/swarmkit/ca/keyreadwriter.go
  15. 11 8
      vendor/github.com/docker/swarmkit/ca/server.go
  16. 2 2
      vendor/github.com/docker/swarmkit/ca/transport.go
  17. 2 2
      vendor/github.com/docker/swarmkit/identity/randomid.go
  18. 3 3
      vendor/github.com/docker/swarmkit/manager/allocator/networkallocator/networkallocator.go
  19. 4 0
      vendor/github.com/docker/swarmkit/manager/controlapi/common.go
  20. 29 45
      vendor/github.com/docker/swarmkit/manager/controlapi/service.go
  21. 21 5
      vendor/github.com/docker/swarmkit/manager/controlapi/task.go
  22. 2 2
      vendor/github.com/docker/swarmkit/manager/encryption/encryption.go
  23. 2 2
      vendor/github.com/docker/swarmkit/manager/encryption/nacl.go
  24. 3 3
      vendor/github.com/docker/swarmkit/manager/keymanager/keymanager.go
  25. 15 6
      vendor/github.com/docker/swarmkit/manager/logbroker/broker.go
  26. 4 0
      vendor/github.com/docker/swarmkit/manager/logbroker/subscription.go
  27. 9 3
      vendor/github.com/docker/swarmkit/manager/manager.go
  28. 1 9
      vendor/github.com/docker/swarmkit/manager/state/raft/transport/peer.go
  29. 80 37
      vendor/github.com/docker/swarmkit/node/node.go

+ 20 - 0
integration-cli/docker_api_swarm_test.go

@@ -5,6 +5,7 @@ package main
 import (
 import (
 	"encoding/json"
 	"encoding/json"
 	"fmt"
 	"fmt"
+	"io/ioutil"
 	"net"
 	"net"
 	"net/http"
 	"net/http"
 	"os"
 	"os"
@@ -13,6 +14,7 @@ import (
 	"sync"
 	"sync"
 	"time"
 	"time"
 
 
+	"github.com/cloudflare/cfssl/helpers"
 	"github.com/docker/docker/api/types"
 	"github.com/docker/docker/api/types"
 	"github.com/docker/docker/api/types/container"
 	"github.com/docker/docker/api/types/container"
 	"github.com/docker/docker/api/types/swarm"
 	"github.com/docker/docker/api/types/swarm"
@@ -176,6 +178,24 @@ func (s *DockerSwarmSuite) TestAPISwarmPromoteDemote(c *check.C) {
 
 
 	waitAndAssert(c, defaultReconciliationTimeout, d2.CheckControlAvailable, checker.False)
 	waitAndAssert(c, defaultReconciliationTimeout, d2.CheckControlAvailable, checker.False)
 
 
+	// Wait for the role to change to worker in the cert. This is partially
+	// done because it's something worth testing in its own right, and
+	// partially because changing the role from manager to worker and then
+	// back to manager quickly might cause the node to pause for awhile
+	// while waiting for the role to change to worker, and the test can
+	// time out during this interval.
+	waitAndAssert(c, defaultReconciliationTimeout, func(c *check.C) (interface{}, check.CommentInterface) {
+		certBytes, err := ioutil.ReadFile(filepath.Join(d2.Folder, "root", "swarm", "certificates", "swarm-node.crt"))
+		if err != nil {
+			return "", check.Commentf("error: %v", err)
+		}
+		certs, err := helpers.ParseCertificatesPEM(certBytes)
+		if err == nil && len(certs) > 0 && len(certs[0].Subject.OrganizationalUnit) > 0 {
+			return certs[0].Subject.OrganizationalUnit[0], nil
+		}
+		return "", check.Commentf("could not get organizational unit from certificate")
+	}, checker.Equals, "swarm-worker")
+
 	// Demoting last node should fail
 	// Demoting last node should fail
 	node := d1.GetNode(c, d1.NodeID)
 	node := d1.GetNode(c, d1.NodeID)
 	node.Spec.Role = swarm.NodeRoleWorker
 	node.Spec.Role = swarm.NodeRoleWorker

+ 2 - 1
integration-cli/docker_cli_service_logs_experimental_test.go

@@ -38,7 +38,8 @@ func (s *DockerSwarmSuite) TestServiceLogs(c *check.C) {
 
 
 	// make sure task has been deployed.
 	// make sure task has been deployed.
 	waitAndAssert(c, defaultReconciliationTimeout,
 	waitAndAssert(c, defaultReconciliationTimeout,
-		d.CheckActiveContainerCount, checker.Equals, len(services))
+		d.CheckRunningTaskImages, checker.DeepEquals,
+		map[string]int{"busybox": len(services)})
 
 
 	for name, message := range services {
 	for name, message := range services {
 		out, err := d.Cmd("service", "logs", name)
 		out, err := d.Cmd("service", "logs", name)

+ 1 - 1
vendor.conf

@@ -104,7 +104,7 @@ github.com/docker/containerd 665e84e6c28653a9c29a6db601636a92d46896f3
 github.com/tonistiigi/fifo 1405643975692217d6720f8b54aeee1bf2cd5cf4
 github.com/tonistiigi/fifo 1405643975692217d6720f8b54aeee1bf2cd5cf4
 
 
 # cluster
 # cluster
-github.com/docker/swarmkit 46bbd41a00b996a13840607772f661a7f5096ca0
+github.com/docker/swarmkit d60ccf366a6758c7857db968857b72202cb2f902
 github.com/golang/mock bd3c8e81be01eef76d4b503f5e687d2d1354d2d9
 github.com/golang/mock bd3c8e81be01eef76d4b503f5e687d2d1354d2d9
 github.com/gogo/protobuf 8d70fb3182befc465c4a1eac8ad4d38ff49778e2
 github.com/gogo/protobuf 8d70fb3182befc465c4a1eac8ad4d38ff49778e2
 github.com/cloudflare/cfssl 7fb22c8cba7ecaf98e4082d22d65800cf45e042a
 github.com/cloudflare/cfssl 7fb22c8cba7ecaf98e4082d22d65800cf45e042a

+ 14 - 2
vendor/github.com/docker/swarmkit/agent/agent.go

@@ -266,6 +266,7 @@ func (a *Agent) run(ctx context.Context) {
 
 
 			subCtx, subCancel := context.WithCancel(ctx)
 			subCtx, subCancel := context.WithCancel(ctx)
 			subscriptions[sub.ID] = subCancel
 			subscriptions[sub.ID] = subCancel
+			// TODO(dperny) we're tossing the error here, that seems wrong
 			go a.worker.Subscribe(subCtx, sub)
 			go a.worker.Subscribe(subCtx, sub)
 		case <-registered:
 		case <-registered:
 			log.G(ctx).Debugln("agent: registered")
 			log.G(ctx).Debugln("agent: registered")
@@ -487,10 +488,21 @@ func (a *Agent) Publisher(ctx context.Context, subscriptionID string) (exec.LogP
 		return nil, nil, err
 		return nil, nil, err
 	}
 	}
 
 
+	// make little closure for ending the log stream
+	sendCloseMsg := func() {
+		// send a close message, to tell the manager our logs are done
+		publisher.Send(&api.PublishLogsMessage{
+			SubscriptionID: subscriptionID,
+			Close:          true,
+		})
+		// close the stream forreal
+		publisher.CloseSend()
+	}
+
 	return exec.LogPublisherFunc(func(ctx context.Context, message api.LogMessage) error {
 	return exec.LogPublisherFunc(func(ctx context.Context, message api.LogMessage) error {
 			select {
 			select {
 			case <-ctx.Done():
 			case <-ctx.Done():
-				publisher.CloseSend()
+				sendCloseMsg()
 				return ctx.Err()
 				return ctx.Err()
 			default:
 			default:
 			}
 			}
@@ -500,7 +512,7 @@ func (a *Agent) Publisher(ctx context.Context, subscriptionID string) (exec.LogP
 				Messages:       []api.LogMessage{message},
 				Messages:       []api.LogMessage{message},
 			})
 			})
 		}), func() {
 		}), func() {
-			publisher.CloseSend()
+			sendCloseMsg()
 		}, nil
 		}, nil
 }
 }
 
 

+ 157 - 116
vendor/github.com/docker/swarmkit/api/control.pb.go

@@ -195,6 +195,11 @@ type ListTasksRequest_Filters struct {
 	DesiredStates []TaskState       `protobuf:"varint,6,rep,packed,name=desired_states,json=desiredStates,enum=docker.swarmkit.v1.TaskState" json:"desired_states,omitempty"`
 	DesiredStates []TaskState       `protobuf:"varint,6,rep,packed,name=desired_states,json=desiredStates,enum=docker.swarmkit.v1.TaskState" json:"desired_states,omitempty"`
 	// NamePrefixes matches all objects with the given prefixes
 	// NamePrefixes matches all objects with the given prefixes
 	NamePrefixes []string `protobuf:"bytes,7,rep,name=name_prefixes,json=namePrefixes" json:"name_prefixes,omitempty"`
 	NamePrefixes []string `protobuf:"bytes,7,rep,name=name_prefixes,json=namePrefixes" json:"name_prefixes,omitempty"`
+	// UpToDate matches tasks that are consistent with the current
+	// service definition.
+	// Note: this is intended for internal status reporting rather
+	// than being exposed to users. It may be removed in the future.
+	UpToDate bool `protobuf:"varint,8,opt,name=up_to_date,json=upToDate,proto3" json:"up_to_date,omitempty"`
 }
 }
 
 
 func (m *ListTasksRequest_Filters) Reset()      { *m = ListTasksRequest_Filters{} }
 func (m *ListTasksRequest_Filters) Reset()      { *m = ListTasksRequest_Filters{} }
@@ -3452,6 +3457,16 @@ func (m *ListTasksRequest_Filters) MarshalTo(dAtA []byte) (int, error) {
 			i += copy(dAtA[i:], s)
 			i += copy(dAtA[i:], s)
 		}
 		}
 	}
 	}
+	if m.UpToDate {
+		dAtA[i] = 0x40
+		i++
+		if m.UpToDate {
+			dAtA[i] = 1
+		} else {
+			dAtA[i] = 0
+		}
+		i++
+	}
 	return i, nil
 	return i, nil
 }
 }
 
 
@@ -5997,6 +6012,9 @@ func (m *ListTasksRequest_Filters) Size() (n int) {
 			n += 1 + l + sovControl(uint64(l))
 			n += 1 + l + sovControl(uint64(l))
 		}
 		}
 	}
 	}
+	if m.UpToDate {
+		n += 2
+	}
 	return n
 	return n
 }
 }
 
 
@@ -6719,6 +6737,7 @@ func (this *ListTasksRequest_Filters) String() string {
 		`NodeIDs:` + fmt.Sprintf("%v", this.NodeIDs) + `,`,
 		`NodeIDs:` + fmt.Sprintf("%v", this.NodeIDs) + `,`,
 		`DesiredStates:` + fmt.Sprintf("%v", this.DesiredStates) + `,`,
 		`DesiredStates:` + fmt.Sprintf("%v", this.DesiredStates) + `,`,
 		`NamePrefixes:` + fmt.Sprintf("%v", this.NamePrefixes) + `,`,
 		`NamePrefixes:` + fmt.Sprintf("%v", this.NamePrefixes) + `,`,
+		`UpToDate:` + fmt.Sprintf("%v", this.UpToDate) + `,`,
 		`}`,
 		`}`,
 	}, "")
 	}, "")
 	return s
 	return s
@@ -8998,6 +9017,26 @@ func (m *ListTasksRequest_Filters) Unmarshal(dAtA []byte) error {
 			}
 			}
 			m.NamePrefixes = append(m.NamePrefixes, string(dAtA[iNdEx:postIndex]))
 			m.NamePrefixes = append(m.NamePrefixes, string(dAtA[iNdEx:postIndex]))
 			iNdEx = postIndex
 			iNdEx = postIndex
+		case 8:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field UpToDate", wireType)
+			}
+			var v int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowControl
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				v |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			m.UpToDate = bool(v != 0)
 		default:
 		default:
 			iNdEx = preIndex
 			iNdEx = preIndex
 			skippy, err := skipControl(dAtA[iNdEx:])
 			skippy, err := skipControl(dAtA[iNdEx:])
@@ -13310,120 +13349,122 @@ var (
 func init() { proto.RegisterFile("control.proto", fileDescriptorControl) }
 func init() { proto.RegisterFile("control.proto", fileDescriptorControl) }
 
 
 var fileDescriptorControl = []byte{
 var fileDescriptorControl = []byte{
-	// 1838 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xcc, 0x5a, 0x4d, 0x4f, 0x1b, 0x57,
-	0x17, 0xc6, 0x1f, 0x60, 0x73, 0x8c, 0x0d, 0x5c, 0x9c, 0xbc, 0x96, 0x93, 0x17, 0xd0, 0xe4, 0x0d,
-	0x31, 0xaf, 0xa8, 0x69, 0x9c, 0x46, 0x4d, 0x53, 0xf5, 0x23, 0x40, 0x92, 0x3a, 0x24, 0x24, 0x1a,
-	0x42, 0xd4, 0x1d, 0x1a, 0xec, 0x1b, 0x3a, 0xb1, 0xf1, 0xb8, 0x33, 0x03, 0x09, 0xea, 0xa6, 0xad,
-	0xda, 0x9f, 0x50, 0xa9, 0xdb, 0x6e, 0x5b, 0xa9, 0x8b, 0xae, 0xfa, 0x13, 0xa2, 0xae, 0xba, 0xec,
-	0x0a, 0x35, 0x96, 0x2a, 0x75, 0xd5, 0x9f, 0x50, 0x55, 0xf7, 0x6b, 0xbe, 0x7c, 0x67, 0xc6, 0x06,
-	0x2a, 0xb2, 0xca, 0xcc, 0x9d, 0xe7, 0xdc, 0x73, 0xee, 0x3d, 0xcf, 0x7d, 0x7c, 0xee, 0x09, 0x90,
-	0x6f, 0x18, 0x1d, 0xdb, 0x34, 0xda, 0xd5, 0xae, 0x69, 0xd8, 0x06, 0x42, 0x4d, 0xa3, 0xd1, 0xc2,
-	0x66, 0xd5, 0x7a, 0xae, 0x99, 0x7b, 0x2d, 0xdd, 0xae, 0x1e, 0x5c, 0x2d, 0xe7, 0xac, 0x2e, 0x6e,
-	0x58, 0x0c, 0x50, 0xce, 0x1b, 0x3b, 0xcf, 0x70, 0xc3, 0x16, 0xaf, 0x39, 0xfb, 0xb0, 0x8b, 0xc5,
-	0x4b, 0x71, 0xd7, 0xd8, 0x35, 0xe8, 0xe3, 0x32, 0x79, 0xe2, 0xa3, 0x33, 0xdd, 0xf6, 0xfe, 0xae,
-	0xde, 0x59, 0x66, 0xff, 0xb0, 0x41, 0xe5, 0x3a, 0x14, 0xee, 0x62, 0x7b, 0xc3, 0x68, 0x62, 0x15,
-	0x7f, 0xba, 0x8f, 0x2d, 0x1b, 0x5d, 0x82, 0x4c, 0xc7, 0x68, 0xe2, 0x6d, 0xbd, 0x59, 0x4a, 0xcc,
-	0x27, 0x2a, 0xe3, 0x2b, 0xd0, 0x3b, 0x9a, 0x1b, 0x23, 0x88, 0xfa, 0x9a, 0x3a, 0x46, 0x3e, 0xd5,
-	0x9b, 0xca, 0x07, 0x30, 0xe9, 0x98, 0x59, 0x5d, 0xa3, 0x63, 0x61, 0xb4, 0x04, 0x69, 0xf2, 0x91,
-	0x1a, 0xe5, 0x6a, 0xa5, 0x6a, 0xff, 0x02, 0xaa, 0x14, 0x4f, 0x51, 0xca, 0x51, 0x0a, 0xa6, 0xee,
-	0xeb, 0x16, 0x9d, 0xc2, 0x12, 0xae, 0xef, 0x40, 0xe6, 0xa9, 0xde, 0xb6, 0xb1, 0x69, 0xf1, 0x59,
-	0x96, 0x64, 0xb3, 0x04, 0xcd, 0xaa, 0x77, 0x98, 0x8d, 0x2a, 0x8c, 0xcb, 0x5f, 0xa4, 0x20, 0xc3,
-	0x07, 0x51, 0x11, 0x46, 0x3b, 0xda, 0x1e, 0x26, 0x33, 0xa6, 0x2a, 0xe3, 0x2a, 0x7b, 0x41, 0xcb,
-	0x90, 0xd3, 0x9b, 0xdb, 0x5d, 0x13, 0x3f, 0xd5, 0x5f, 0x60, 0xab, 0x94, 0x24, 0xdf, 0x56, 0x0a,
-	0xbd, 0xa3, 0x39, 0xa8, 0xaf, 0x3d, 0xe2, 0xa3, 0x2a, 0xe8, 0x4d, 0xf1, 0x8c, 0x1e, 0xc1, 0x58,
-	0x5b, 0xdb, 0xc1, 0x6d, 0xab, 0x94, 0x9a, 0x4f, 0x55, 0x72, 0xb5, 0x1b, 0xc3, 0x44, 0x56, 0xbd,
-	0x4f, 0x4d, 0x6f, 0x77, 0x6c, 0xf3, 0x50, 0xe5, 0xf3, 0xa0, 0x3a, 0xe4, 0xf6, 0xf0, 0xde, 0x0e,
-	0x36, 0xad, 0x4f, 0xf4, 0xae, 0x55, 0x4a, 0xcf, 0xa7, 0x2a, 0x85, 0xda, 0x95, 0xb0, 0x6d, 0xdb,
-	0xec, 0xe2, 0x46, 0xf5, 0x81, 0x83, 0x57, 0xbd, 0xb6, 0xa8, 0x06, 0xa3, 0xa6, 0xd1, 0xc6, 0x56,
-	0x69, 0x94, 0x4e, 0x72, 0x31, 0x74, 0xef, 0x8d, 0x36, 0x56, 0x19, 0x14, 0x5d, 0x82, 0x3c, 0xd9,
-	0x0a, 0x77, 0x0f, 0xc6, 0xe8, 0xfe, 0x4c, 0x90, 0x41, 0xb1, 0xea, 0xf2, 0x3b, 0x90, 0xf3, 0x84,
-	0x8e, 0xa6, 0x20, 0xd5, 0xc2, 0x87, 0x8c, 0x16, 0x2a, 0x79, 0x24, 0xbb, 0x7b, 0xa0, 0xb5, 0xf7,
-	0x71, 0x29, 0x49, 0xc7, 0xd8, 0xcb, 0xcd, 0xe4, 0x8d, 0x84, 0xb2, 0x0a, 0xd3, 0x9e, 0xed, 0xe0,
-	0x1c, 0xa9, 0xc2, 0x28, 0xc9, 0x3e, 0x4b, 0x46, 0x14, 0x49, 0x18, 0x4c, 0xf9, 0x3e, 0x01, 0xd3,
-	0x5b, 0xdd, 0xa6, 0x66, 0xe3, 0x61, 0x19, 0x8a, 0xde, 0x87, 0x09, 0x0a, 0x3a, 0xc0, 0xa6, 0xa5,
-	0x1b, 0x1d, 0x1a, 0x60, 0xae, 0x76, 0x41, 0xe6, 0xf1, 0x09, 0x83, 0xa8, 0x39, 0x62, 0xc0, 0x5f,
-	0xd0, 0x9b, 0x90, 0x26, 0xc7, 0xad, 0x94, 0xa2, 0x76, 0x17, 0xa3, 0xf2, 0xa2, 0x52, 0xa4, 0xb2,
-	0x02, 0xc8, 0x1b, 0xeb, 0xb1, 0x8e, 0xc5, 0x06, 0x4c, 0xab, 0x78, 0xcf, 0x38, 0x18, 0x7e, 0xbd,
-	0x45, 0x18, 0x7d, 0x6a, 0x98, 0x0d, 0x96, 0x89, 0xac, 0xca, 0x5e, 0x94, 0x22, 0x20, 0xef, 0x7c,
-	0x2c, 0x26, 0x7e, 0xe8, 0x1f, 0x6b, 0x56, 0xcb, 0xe3, 0xc2, 0xd6, 0xac, 0x56, 0xc0, 0x05, 0x41,
-	0x10, 0x17, 0xe4, 0x93, 0x73, 0xe8, 0x99, 0x99, 0xbb, 0x3a, 0xf2, 0x31, 0x6a, 0x75, 0x14, 0x4f,
-	0x51, 0xca, 0x0d, 0xb1, 0xba, 0xa1, 0x5d, 0x3b, 0xeb, 0xf0, 0x7a, 0x57, 0xfe, 0xe6, 0x22, 0x42,
-	0x06, 0x8f, 0x21, 0x22, 0x5e, 0xb3, 0x7e, 0x11, 0xf9, 0xee, 0x0c, 0x45, 0x44, 0x16, 0x99, 0x54,
-	0x44, 0x96, 0x21, 0x67, 0x61, 0xf3, 0x40, 0x6f, 0x10, 0x76, 0x30, 0x11, 0xe1, 0x21, 0x6c, 0xb2,
-	0xe1, 0xfa, 0x9a, 0xa5, 0x02, 0x87, 0xd4, 0x9b, 0x16, 0x5a, 0x80, 0x2c, 0xe7, 0x12, 0x53, 0x8b,
-	0xf1, 0x95, 0x5c, 0xef, 0x68, 0x2e, 0xc3, 0xc8, 0x64, 0xa9, 0x19, 0xc6, 0x26, 0x0b, 0xad, 0x41,
-	0xa1, 0x89, 0x2d, 0xdd, 0xc4, 0xcd, 0x6d, 0xcb, 0xd6, 0x6c, 0xae, 0x0f, 0x85, 0xda, 0x7f, 0xc3,
-	0x52, 0xbc, 0x49, 0x50, 0x6a, 0x9e, 0x1b, 0xd1, 0x37, 0x89, 0xc8, 0x64, 0xfe, 0x15, 0x91, 0xe1,
-	0xdb, 0xe5, 0x8a, 0x0c, 0x61, 0x4d, 0xa4, 0xc8, 0x50, 0x1a, 0x31, 0x98, 0xb2, 0x0e, 0xc5, 0x55,
-	0x13, 0x6b, 0x36, 0xe6, 0x5b, 0x26, 0x88, 0x74, 0x8d, 0x2b, 0x00, 0x63, 0xd1, 0x9c, 0x6c, 0x1a,
-	0x6e, 0xe1, 0x11, 0x81, 0x0d, 0x38, 0x17, 0x98, 0x8c, 0x47, 0x75, 0x1d, 0x32, 0x3c, 0x0d, 0x7c,
-	0xc2, 0x0b, 0x11, 0x13, 0xaa, 0x02, 0xab, 0xdc, 0x82, 0xe9, 0xbb, 0xd8, 0x0e, 0x44, 0xb6, 0x04,
-	0xe0, 0x66, 0x9d, 0x9f, 0x9a, 0x7c, 0xef, 0x68, 0x6e, 0xdc, 0x49, 0xba, 0x3a, 0xee, 0xe4, 0x5c,
-	0x59, 0x07, 0xe4, 0x9d, 0xe2, 0x64, 0xf1, 0xfc, 0x94, 0x84, 0x22, 0x53, 0xb9, 0x93, 0xc4, 0x84,
-	0xd6, 0x60, 0x52, 0xa0, 0x87, 0x10, 0xe8, 0x02, 0xb7, 0x11, 0x1a, 0x7d, 0xcd, 0xa7, 0xd1, 0x83,
-	0x65, 0x08, 0x3d, 0x80, 0xac, 0x69, 0xb4, 0xdb, 0x3b, 0x5a, 0xa3, 0x55, 0x4a, 0xcf, 0x27, 0x2a,
-	0x85, 0xda, 0x55, 0x99, 0xa1, 0x6c, 0x91, 0x55, 0x95, 0x1b, 0xaa, 0xce, 0x14, 0x8a, 0x02, 0x59,
-	0x31, 0x8a, 0xb2, 0x90, 0xde, 0x78, 0xb8, 0x71, 0x7b, 0x6a, 0x04, 0x4d, 0x40, 0xf6, 0x91, 0x7a,
-	0xfb, 0x49, 0xfd, 0xe1, 0xd6, 0xe6, 0x54, 0x82, 0x90, 0x22, 0x30, 0xdd, 0xc9, 0x92, 0xb0, 0x06,
-	0x45, 0xa6, 0x86, 0x27, 0xe2, 0xc5, 0x7f, 0xe0, 0x5c, 0x60, 0x16, 0x2e, 0xab, 0x7f, 0x26, 0x61,
-	0x86, 0x1c, 0x2b, 0x3e, 0xee, 0x28, 0x6b, 0x3d, 0xa8, 0xac, 0xcb, 0x61, 0xfa, 0x15, 0xb0, 0xec,
-	0x17, 0xd7, 0xaf, 0x93, 0xa7, 0x2e, 0xae, 0x9b, 0x01, 0x71, 0x7d, 0x77, 0xc8, 0xe0, 0xa4, 0xfa,
-	0xda, 0x27, 0x60, 0xe9, 0xd3, 0x15, 0xb0, 0x87, 0x50, 0xf4, 0x87, 0xc4, 0x89, 0xf1, 0x36, 0x64,
-	0x79, 0xa2, 0x84, 0x8c, 0x45, 0x32, 0xc3, 0x01, 0xbb, 0x62, 0xb6, 0x81, 0xed, 0xe7, 0x86, 0xd9,
-	0x1a, 0x42, 0xcc, 0xb8, 0x85, 0x4c, 0xcc, 0x9c, 0xc9, 0x5c, 0xde, 0x76, 0xd8, 0x50, 0x14, 0x6f,
-	0x85, 0x95, 0xc0, 0x2a, 0x5b, 0x54, 0xcc, 0x02, 0x91, 0x21, 0x48, 0x93, 0xdd, 0xe4, 0xfb, 0x45,
-	0x9f, 0x09, 0x91, 0xb9, 0x0d, 0x21, 0x72, 0xd2, 0x25, 0x32, 0xb7, 0x25, 0x44, 0xe6, 0x00, 0x47,
-	0xe0, 0x4e, 0x29, 0xc6, 0x8f, 0xc5, 0xd9, 0x3a, 0xf5, 0x30, 0x9d, 0xf3, 0x16, 0x88, 0xd4, 0x39,
-	0x6f, 0x7c, 0xfc, 0x18, 0xe7, 0x2d, 0x60, 0xf9, 0x7a, 0x9d, 0xb7, 0x90, 0xe0, 0xce, 0xf2, 0xbc,
-	0xb9, 0x21, 0xb9, 0xe7, 0x8d, 0x27, 0x2a, 0xf2, 0xbc, 0x89, 0xcc, 0x39, 0x60, 0xfe, 0xfb, 0xbc,
-	0xda, 0xde, 0xb7, 0x6c, 0x6c, 0x7a, 0x74, 0xb8, 0xc1, 0x46, 0x02, 0x3a, 0xcc, 0x71, 0x84, 0x17,
-	0x1c, 0xe0, 0xd0, 0xd7, 0x99, 0xc2, 0xa5, 0x2f, 0x87, 0x44, 0xd1, 0x57, 0x58, 0x09, 0xac, 0xc3,
-	0x25, 0xfe, 0xe1, 0x18, 0x5c, 0x0a, 0x58, 0xbe, 0x5e, 0x5c, 0x0a, 0x09, 0xee, 0x2c, 0xb9, 0xe4,
-	0x86, 0xe4, 0x72, 0x89, 0x67, 0x23, 0x92, 0x4b, 0x22, 0x75, 0x0e, 0x58, 0xf9, 0x26, 0x01, 0xb9,
-	0x75, 0x7c, 0xa8, 0x1a, 0xb6, 0x66, 0x93, 0xf2, 0xe6, 0xff, 0x30, 0x4d, 0x48, 0x86, 0xcd, 0xed,
-	0x67, 0x86, 0xde, 0xd9, 0xb6, 0x8d, 0x16, 0xee, 0xd0, 0xd0, 0xb2, 0xea, 0x24, 0xfb, 0x70, 0xcf,
-	0xd0, 0x3b, 0x8f, 0xc9, 0x30, 0x5a, 0x02, 0xb4, 0xa7, 0x75, 0xb4, 0x5d, 0x3f, 0x98, 0xdd, 0x05,
-	0xa7, 0xf8, 0x17, 0x29, 0x7a, 0xbf, 0xd3, 0x36, 0x1a, 0xad, 0x6d, 0xb2, 0xea, 0x94, 0x0f, 0xbd,
-	0x45, 0x3f, 0xac, 0xe3, 0x43, 0xe5, 0x4b, 0xa7, 0xe6, 0x3b, 0x09, 0xcf, 0x49, 0xcd, 0x27, 0xd0,
-	0xc3, 0xd4, 0x7c, 0xdc, 0x66, 0x88, 0x9a, 0x8f, 0x7b, 0xf7, 0xd4, 0x7c, 0xb7, 0x48, 0xcd, 0xc7,
-	0x76, 0x95, 0xd6, 0x7c, 0x21, 0x86, 0x9e, 0xcd, 0x5f, 0x49, 0xbf, 0x3c, 0x9a, 0x1b, 0x51, 0x1d,
-	0x33, 0xb7, 0x86, 0x3b, 0xa5, 0x83, 0xfa, 0x1e, 0x4c, 0xd1, 0xaa, 0xbc, 0x61, 0x62, 0x5b, 0xec,
-	0xe7, 0x22, 0x8c, 0x5b, 0x74, 0xc0, 0xdd, 0xce, 0x89, 0xde, 0xd1, 0x5c, 0x96, 0xa1, 0xea, 0x6b,
-	0xe4, 0x77, 0x9e, 0x3e, 0x35, 0x95, 0xbb, 0xfc, 0x5e, 0xc0, 0xcc, 0x79, 0x28, 0x35, 0x18, 0x63,
-	0x00, 0x1e, 0x49, 0x59, 0x5e, 0x33, 0x50, 0x1b, 0x8e, 0x54, 0x7e, 0x4e, 0xc0, 0x8c, 0x28, 0x4e,
-	0x8f, 0x17, 0x0b, 0x5a, 0x81, 0x02, 0x87, 0x0e, 0x91, 0xd7, 0x3c, 0x33, 0x11, 0x69, 0xad, 0xf9,
-	0xd2, 0x3a, 0x1b, 0x1e, 0xb8, 0xa7, 0x3c, 0xb9, 0xe7, 0x5e, 0x45, 0x4e, 0xbc, 0x0d, 0x7f, 0x24,
-	0x01, 0xb1, 0x4a, 0x8c, 0xbc, 0x3a, 0xb2, 0xf9, 0x51, 0x50, 0x36, 0xab, 0xe1, 0x55, 0xa5, 0xd7,
-	0xb0, 0x5f, 0x35, 0xbf, 0x3a, 0x7d, 0xd5, 0x54, 0x03, 0xaa, 0x79, 0x73, 0xb8, 0xd8, 0xce, 0x44,
-	0x34, 0xd7, 0xc5, 0xd5, 0x82, 0x47, 0xc4, 0x53, 0xf6, 0x16, 0xb9, 0x08, 0xd1, 0x21, 0x2e, 0x99,
-	0x51, 0x39, 0x13, 0x50, 0xa5, 0x0e, 0x33, 0xe2, 0xb2, 0xed, 0xa5, 0x6e, 0xcd, 0x57, 0xeb, 0x0e,
-	0xcc, 0x25, 0xff, 0x54, 0x27, 0xe0, 0xd2, 0x87, 0x30, 0x23, 0x2e, 0x56, 0xc7, 0x3c, 0xdd, 0xe7,
-	0xdd, 0x0b, 0x9e, 0x37, 0x9a, 0xda, 0x0f, 0xe7, 0x21, 0xb3, 0xca, 0xfe, 0x9f, 0x00, 0xe9, 0x90,
-	0xe1, 0x2d, 0x78, 0xa4, 0xc8, 0x82, 0xf2, 0xb7, 0xf5, 0xcb, 0x97, 0x22, 0x31, 0xbc, 0x12, 0x3d,
-	0xf7, 0xcb, 0x8f, 0x7f, 0x7d, 0x9b, 0x9c, 0x84, 0x3c, 0x05, 0xbd, 0xc1, 0x7f, 0x09, 0x90, 0x01,
-	0xe3, 0x4e, 0x2f, 0x17, 0xfd, 0x6f, 0x90, 0xce, 0x77, 0xf9, 0x72, 0x0c, 0x2a, 0xda, 0xa1, 0x09,
-	0xe0, 0xb6, 0x52, 0xd1, 0xe5, 0xf0, 0xfb, 0xb9, 0x77, 0x85, 0x0b, 0x71, 0xb0, 0x58, 0x9f, 0x6e,
-	0xab, 0x54, 0xee, 0xb3, 0xaf, 0x35, 0x2b, 0xf7, 0x29, 0xe9, 0xb8, 0x86, 0xf8, 0x64, 0x39, 0x7c,
-	0xac, 0x59, 0xad, 0xd0, 0x1c, 0x7a, 0x5a, 0xa5, 0xa1, 0x39, 0xf4, 0x35, 0x45, 0xa3, 0x73, 0x48,
-	0x5b, 0x65, 0xe1, 0x39, 0xf4, 0x36, 0x1e, 0xc3, 0x73, 0xe8, 0xeb, 0xb7, 0xc5, 0xee, 0x27, 0x5d,
-	0x5e, 0xc4, 0x7e, 0x7a, 0x57, 0xb8, 0x10, 0x07, 0x8b, 0xf5, 0xe9, 0xb6, 0xba, 0xe4, 0x3e, 0xfb,
-	0xba, 0x69, 0x72, 0x9f, 0xfd, 0x1d, 0xb3, 0x30, 0x9f, 0x2f, 0x60, 0xc2, 0x7b, 0x85, 0x47, 0x57,
-	0x06, 0xec, 0x3b, 0x94, 0x2b, 0xf1, 0xc0, 0x68, 0xcf, 0x9f, 0x41, 0xde, 0xd7, 0x6b, 0x44, 0xd2,
-	0x19, 0x65, 0xbd, 0xcd, 0xf2, 0xe2, 0x00, 0xc8, 0x58, 0xe7, 0xbe, 0x9e, 0x96, 0xdc, 0xb9, 0xac,
-	0x8b, 0x26, 0x77, 0x2e, 0x6d, 0x90, 0x45, 0x38, 0xf7, 0xb5, 0xae, 0xe4, 0xce, 0x65, 0x3d, 0x32,
-	0xb9, 0x73, 0x79, 0x1f, 0x2c, 0x92, 0x64, 0xfc, 0x2a, 0x18, 0x4a, 0x32, 0x7f, 0xfb, 0x20, 0x94,
-	0x64, 0xc1, 0x5e, 0x40, 0x34, 0xc9, 0xc4, 0xbd, 0x35, 0x9c, 0x64, 0x81, 0xcb, 0x76, 0x38, 0xc9,
-	0x82, 0x57, 0xe0, 0x58, 0x92, 0x89, 0x05, 0x47, 0x90, 0x2c, 0xb0, 0xe6, 0xc5, 0x01, 0x90, 0x03,
-	0xe6, 0x39, 0xd2, 0xb9, 0xac, 0x5f, 0x13, 0x95, 0xe7, 0x01, 0x9d, 0xb3, 0x3c, 0xf3, 0xc2, 0x3d,
-	0x34, 0xcf, 0xfe, 0x2b, 0x51, 0x68, 0x9e, 0x03, 0xb7, 0x86, 0x98, 0x3c, 0x8b, 0x3b, 0x65, 0x78,
-	0x9e, 0x03, 0x17, 0xe1, 0xf0, 0x3c, 0x07, 0xaf, 0xa7, 0xb1, 0xe7, 0x59, 0x2c, 0x38, 0xe2, 0x3c,
-	0x07, 0xd6, 0xbc, 0x38, 0x00, 0x32, 0xf6, 0xc7, 0xc9, 0xb9, 0xcd, 0xc8, 0x7f, 0x9c, 0x82, 0x77,
-	0xa5, 0xf2, 0xe5, 0x18, 0x54, 0xec, 0x3e, 0x7b, 0xaf, 0x0e, 0xf2, 0x7d, 0x96, 0x5c, 0x8b, 0xca,
-	0x95, 0x78, 0x60, 0xb4, 0xe7, 0x7d, 0xc8, 0x79, 0x0a, 0x60, 0xb4, 0x30, 0x58, 0xcd, 0x5e, 0xbe,
-	0x12, 0x8b, 0x8b, 0x5d, 0xb0, 0xb7, 0xbe, 0x95, 0x2f, 0x58, 0x52, 0x4c, 0x97, 0x2b, 0xf1, 0xc0,
-	0x58, 0xcf, 0xde, 0x5a, 0x56, 0xee, 0x59, 0x52, 0x2f, 0x97, 0x2b, 0xf1, 0xc0, 0x48, 0xcf, 0x2b,
-	0xa5, 0x97, 0xaf, 0x66, 0x47, 0x7e, 0x7b, 0x35, 0x3b, 0xf2, 0x79, 0x6f, 0x36, 0xf1, 0xb2, 0x37,
-	0x9b, 0xf8, 0xb5, 0x37, 0x9b, 0xf8, 0xbd, 0x37, 0x9b, 0xd8, 0x19, 0xa3, 0x7f, 0xfc, 0x72, 0xed,
-	0x9f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xf7, 0xd5, 0x67, 0xd5, 0x75, 0x23, 0x00, 0x00,
+	// 1865 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xcc, 0x5a, 0x4b, 0x6f, 0x1b, 0x47,
+	0x12, 0x16, 0x1f, 0x12, 0xa9, 0xa2, 0x48, 0x49, 0x2d, 0xda, 0x4b, 0xd0, 0x5e, 0x49, 0x18, 0xaf,
+	0x65, 0x6a, 0xa1, 0xa5, 0xd6, 0xf4, 0x1a, 0xeb, 0xf5, 0x62, 0x1f, 0x96, 0x68, 0x3b, 0xb4, 0x6c,
+	0xd9, 0x18, 0x49, 0x46, 0x6e, 0x04, 0x45, 0xb6, 0x95, 0x31, 0x29, 0x0e, 0x33, 0x33, 0x94, 0x2d,
+	0xe4, 0x92, 0x04, 0xc9, 0x4f, 0x08, 0x90, 0x43, 0x7e, 0x41, 0x02, 0xe4, 0x90, 0x53, 0x6e, 0xb9,
+	0x1a, 0x39, 0xe5, 0x98, 0x93, 0x10, 0x13, 0x08, 0x90, 0x53, 0x7e, 0x43, 0xd0, 0xaf, 0x79, 0xb1,
+	0x67, 0x86, 0x94, 0x04, 0xc8, 0x27, 0xcf, 0xf4, 0x7c, 0xd5, 0x55, 0xdd, 0xf5, 0xf5, 0xc7, 0xea,
+	0xb2, 0x20, 0xdb, 0xd4, 0xbb, 0x96, 0xa1, 0x77, 0xca, 0x3d, 0x43, 0xb7, 0x74, 0x84, 0x5a, 0x7a,
+	0xb3, 0x8d, 0x8d, 0xb2, 0xf9, 0xaa, 0x61, 0x1c, 0xb6, 0x35, 0xab, 0x7c, 0x74, 0xb3, 0x98, 0x31,
+	0x7b, 0xb8, 0x69, 0x32, 0x40, 0x31, 0xab, 0xef, 0xbf, 0xc4, 0x4d, 0x4b, 0xbc, 0x66, 0xac, 0xe3,
+	0x1e, 0x16, 0x2f, 0xf9, 0x03, 0xfd, 0x40, 0xa7, 0x8f, 0xeb, 0xe4, 0x89, 0x8f, 0x2e, 0xf4, 0x3a,
+	0xfd, 0x03, 0xad, 0xbb, 0xce, 0xfe, 0x61, 0x83, 0xca, 0x6d, 0xc8, 0x3d, 0xc4, 0xd6, 0xb6, 0xde,
+	0xc2, 0x2a, 0xfe, 0xb0, 0x8f, 0x4d, 0x0b, 0x5d, 0x83, 0x54, 0x57, 0x6f, 0xe1, 0xba, 0xd6, 0x2a,
+	0xc4, 0x96, 0x63, 0xa5, 0xe9, 0x0d, 0x18, 0x9c, 0x2c, 0x4d, 0x11, 0x44, 0xad, 0xaa, 0x4e, 0x91,
+	0x4f, 0xb5, 0x96, 0xf2, 0x3f, 0x98, 0xb5, 0xcd, 0xcc, 0x9e, 0xde, 0x35, 0x31, 0x5a, 0x83, 0x24,
+	0xf9, 0x48, 0x8d, 0x32, 0x95, 0x42, 0x79, 0x78, 0x01, 0x65, 0x8a, 0xa7, 0x28, 0xe5, 0x24, 0x01,
+	0x73, 0x8f, 0x35, 0x93, 0x4e, 0x61, 0x0a, 0xd7, 0x0f, 0x20, 0xf5, 0x42, 0xeb, 0x58, 0xd8, 0x30,
+	0xf9, 0x2c, 0x6b, 0xb2, 0x59, 0xfc, 0x66, 0xe5, 0x07, 0xcc, 0x46, 0x15, 0xc6, 0xc5, 0x4f, 0x12,
+	0x90, 0xe2, 0x83, 0x28, 0x0f, 0x93, 0xdd, 0xc6, 0x21, 0x26, 0x33, 0x26, 0x4a, 0xd3, 0x2a, 0x7b,
+	0x41, 0xeb, 0x90, 0xd1, 0x5a, 0xf5, 0x9e, 0x81, 0x5f, 0x68, 0xaf, 0xb1, 0x59, 0x88, 0x93, 0x6f,
+	0x1b, 0xb9, 0xc1, 0xc9, 0x12, 0xd4, 0xaa, 0xcf, 0xf8, 0xa8, 0x0a, 0x5a, 0x4b, 0x3c, 0xa3, 0x67,
+	0x30, 0xd5, 0x69, 0xec, 0xe3, 0x8e, 0x59, 0x48, 0x2c, 0x27, 0x4a, 0x99, 0xca, 0x9d, 0x71, 0x22,
+	0x2b, 0x3f, 0xa6, 0xa6, 0xf7, 0xbb, 0x96, 0x71, 0xac, 0xf2, 0x79, 0x50, 0x0d, 0x32, 0x87, 0xf8,
+	0x70, 0x1f, 0x1b, 0xe6, 0x07, 0x5a, 0xcf, 0x2c, 0x24, 0x97, 0x13, 0xa5, 0x5c, 0xe5, 0x46, 0xd0,
+	0xb6, 0xed, 0xf4, 0x70, 0xb3, 0xfc, 0xc4, 0xc6, 0xab, 0x6e, 0x5b, 0x54, 0x81, 0x49, 0x43, 0xef,
+	0x60, 0xb3, 0x30, 0x49, 0x27, 0xb9, 0x1a, 0xb8, 0xf7, 0x7a, 0x07, 0xab, 0x0c, 0x8a, 0xae, 0x41,
+	0x96, 0x6c, 0x85, 0xb3, 0x07, 0x53, 0x74, 0x7f, 0x66, 0xc8, 0xa0, 0x58, 0x75, 0xf1, 0x5f, 0x90,
+	0x71, 0x85, 0x8e, 0xe6, 0x20, 0xd1, 0xc6, 0xc7, 0x8c, 0x16, 0x2a, 0x79, 0x24, 0xbb, 0x7b, 0xd4,
+	0xe8, 0xf4, 0x71, 0x21, 0x4e, 0xc7, 0xd8, 0xcb, 0xdd, 0xf8, 0x9d, 0x98, 0xb2, 0x09, 0xf3, 0xae,
+	0xed, 0xe0, 0x1c, 0x29, 0xc3, 0x24, 0xc9, 0x3e, 0x4b, 0x46, 0x18, 0x49, 0x18, 0x4c, 0xf9, 0x3a,
+	0x06, 0xf3, 0x7b, 0xbd, 0x56, 0xc3, 0xc2, 0xe3, 0x32, 0x14, 0xfd, 0x17, 0x66, 0x28, 0xe8, 0x08,
+	0x1b, 0xa6, 0xa6, 0x77, 0x69, 0x80, 0x99, 0xca, 0x15, 0x99, 0xc7, 0xe7, 0x0c, 0xa2, 0x66, 0x88,
+	0x01, 0x7f, 0x41, 0x7f, 0x87, 0x24, 0x39, 0x6e, 0x85, 0x04, 0xb5, 0xbb, 0x1a, 0x96, 0x17, 0x95,
+	0x22, 0x95, 0x0d, 0x40, 0xee, 0x58, 0x4f, 0x75, 0x2c, 0xb6, 0x61, 0x5e, 0xc5, 0x87, 0xfa, 0xd1,
+	0xf8, 0xeb, 0xcd, 0xc3, 0xe4, 0x0b, 0xdd, 0x68, 0xb2, 0x4c, 0xa4, 0x55, 0xf6, 0xa2, 0xe4, 0x01,
+	0xb9, 0xe7, 0x63, 0x31, 0xf1, 0x43, 0xbf, 0xdb, 0x30, 0xdb, 0x2e, 0x17, 0x56, 0xc3, 0x6c, 0xfb,
+	0x5c, 0x10, 0x04, 0x71, 0x41, 0x3e, 0xd9, 0x87, 0x9e, 0x99, 0x39, 0xab, 0x23, 0x1f, 0xc3, 0x56,
+	0x47, 0xf1, 0x14, 0xa5, 0xdc, 0x11, 0xab, 0x1b, 0xdb, 0xb5, 0xbd, 0x0e, 0xb7, 0x77, 0xe5, 0xab,
+	0x24, 0x13, 0x11, 0x32, 0x78, 0x0a, 0x11, 0x71, 0x9b, 0x0d, 0x8b, 0xc8, 0x0f, 0x17, 0x28, 0x22,
+	0xb2, 0xc8, 0xa4, 0x22, 0xb2, 0x0e, 0x19, 0x13, 0x1b, 0x47, 0x5a, 0x93, 0xb0, 0x83, 0x89, 0x08,
+	0x0f, 0x61, 0x87, 0x0d, 0xd7, 0xaa, 0xa6, 0x0a, 0x1c, 0x52, 0x6b, 0x99, 0x68, 0x05, 0xd2, 0x9c,
+	0x4b, 0x4c, 0x2d, 0xa6, 0x37, 0x32, 0x83, 0x93, 0xa5, 0x14, 0x23, 0x93, 0xa9, 0xa6, 0x18, 0x9b,
+	0x4c, 0x54, 0x85, 0x5c, 0x0b, 0x9b, 0x9a, 0x81, 0x5b, 0x75, 0xd3, 0x6a, 0x58, 0x5c, 0x1f, 0x72,
+	0x95, 0x3f, 0x07, 0xa5, 0x78, 0x87, 0xa0, 0xd4, 0x2c, 0x37, 0xa2, 0x6f, 0x12, 0x91, 0x49, 0x0d,
+	0x8b, 0x0c, 0xba, 0x0a, 0xd0, 0xef, 0xd5, 0x2d, 0xbd, 0x4e, 0xce, 0x4e, 0x21, 0x4d, 0xe9, 0x9b,
+	0xee, 0xf7, 0x76, 0xf5, 0x6a, 0xc3, 0xc2, 0xe7, 0x20, 0x41, 0x7c, 0x33, 0x1d, 0x09, 0x22, 0x9c,
+	0x0a, 0x95, 0x20, 0x4a, 0x32, 0x06, 0x53, 0xb6, 0x20, 0xbf, 0x69, 0xe0, 0x86, 0x85, 0xf9, 0x86,
+	0x0a, 0x9a, 0xdd, 0xe2, 0xfa, 0xc0, 0x38, 0xb6, 0x24, 0x9b, 0x86, 0x5b, 0xb8, 0x24, 0x62, 0x1b,
+	0x2e, 0xf9, 0x26, 0xe3, 0x51, 0xdd, 0x86, 0x14, 0x4f, 0x12, 0x9f, 0xf0, 0x4a, 0xc8, 0x84, 0xaa,
+	0xc0, 0x2a, 0xf7, 0x60, 0xfe, 0x21, 0xb6, 0x7c, 0x91, 0xad, 0x01, 0x38, 0x9c, 0xe0, 0x67, 0x2a,
+	0x3b, 0x38, 0x59, 0x9a, 0xb6, 0x29, 0xa1, 0x4e, 0xdb, 0x8c, 0x50, 0xb6, 0x00, 0xb9, 0xa7, 0x38,
+	0x5b, 0x3c, 0xdf, 0xc5, 0x21, 0xcf, 0x34, 0xf0, 0x2c, 0x31, 0xa1, 0x2a, 0xcc, 0x0a, 0xf4, 0x18,
+	0xf2, 0x9d, 0xe3, 0x36, 0x42, 0xc1, 0x6f, 0x79, 0x14, 0x7c, 0xb4, 0x0c, 0xa1, 0x27, 0x90, 0x36,
+	0xf4, 0x4e, 0x67, 0xbf, 0xd1, 0x6c, 0x17, 0x92, 0xcb, 0xb1, 0x52, 0xae, 0x72, 0x53, 0x66, 0x28,
+	0x5b, 0x64, 0x59, 0xe5, 0x86, 0xaa, 0x3d, 0x85, 0xa2, 0x40, 0x5a, 0x8c, 0xa2, 0x34, 0x24, 0xb7,
+	0x9f, 0x6e, 0xdf, 0x9f, 0x9b, 0x40, 0x33, 0x90, 0x7e, 0xa6, 0xde, 0x7f, 0x5e, 0x7b, 0xba, 0xb7,
+	0x33, 0x17, 0x23, 0xa4, 0xf0, 0x4d, 0x77, 0xb6, 0x24, 0x54, 0x21, 0xcf, 0xb4, 0xf2, 0x4c, 0xbc,
+	0xf8, 0x13, 0x5c, 0xf2, 0xcd, 0xc2, 0x45, 0xf7, 0xb7, 0x38, 0x2c, 0x90, 0x63, 0xc5, 0xc7, 0x6d,
+	0xdd, 0xad, 0xf9, 0x75, 0x77, 0x3d, 0x48, 0xdd, 0x7c, 0x96, 0xc3, 0xd2, 0xfb, 0x79, 0xfc, 0xdc,
+	0xa5, 0x77, 0xc7, 0x27, 0xbd, 0xff, 0x1e, 0x33, 0x38, 0xa9, 0xfa, 0x0e, 0xc9, 0x5b, 0xf2, 0x7c,
+	0x6b, 0xa8, 0xa7, 0x90, 0xf7, 0x86, 0xc4, 0x89, 0xf1, 0x4f, 0x48, 0xf3, 0x44, 0x09, 0x19, 0x0b,
+	0x65, 0x86, 0x0d, 0x76, 0xc4, 0x6c, 0x1b, 0x5b, 0xaf, 0x74, 0xa3, 0x3d, 0x86, 0x98, 0x71, 0x0b,
+	0x99, 0x98, 0xd9, 0x93, 0x39, 0xbc, 0xed, 0xb2, 0xa1, 0x30, 0xde, 0x0a, 0x2b, 0x81, 0x55, 0xf6,
+	0xa8, 0x98, 0xf9, 0x22, 0x43, 0x90, 0x24, 0xbb, 0xc9, 0xf7, 0x8b, 0x3e, 0x13, 0x22, 0x73, 0x1b,
+	0x42, 0xe4, 0xb8, 0x43, 0x64, 0x6e, 0x4b, 0x88, 0xcc, 0x01, 0xb6, 0xc0, 0x9d, 0x53, 0x8c, 0xef,
+	0x8b, 0xb3, 0x75, 0xee, 0x61, 0xda, 0xe7, 0xcd, 0x17, 0xa9, 0x7d, 0xde, 0xf8, 0xf8, 0x29, 0xce,
+	0x9b, 0xcf, 0xf2, 0xdd, 0x3a, 0x6f, 0x01, 0xc1, 0x5d, 0xe4, 0x79, 0x73, 0x42, 0x72, 0xce, 0x1b,
+	0x4f, 0x54, 0xe8, 0x79, 0x13, 0x99, 0xb3, 0xc1, 0xfc, 0xf7, 0x79, 0xb3, 0xd3, 0x37, 0x2d, 0x6c,
+	0xb8, 0x74, 0xb8, 0xc9, 0x46, 0x7c, 0x3a, 0xcc, 0x71, 0x84, 0x17, 0x1c, 0x60, 0xd3, 0xd7, 0x9e,
+	0xc2, 0xa1, 0x2f, 0x87, 0x84, 0xd1, 0x57, 0x58, 0x09, 0xac, 0xcd, 0x25, 0xfe, 0xe1, 0x14, 0x5c,
+	0xf2, 0x59, 0xbe, 0x5b, 0x5c, 0x0a, 0x08, 0xee, 0x22, 0xb9, 0xe4, 0x84, 0xe4, 0x70, 0x89, 0x67,
+	0x23, 0x94, 0x4b, 0x22, 0x75, 0x36, 0x58, 0xf9, 0x22, 0x06, 0x99, 0x2d, 0x7c, 0xac, 0xea, 0x56,
+	0xc3, 0x22, 0xe5, 0xcd, 0x5f, 0x61, 0x9e, 0x90, 0x0c, 0x1b, 0xf5, 0x97, 0xba, 0xd6, 0xad, 0x5b,
+	0x7a, 0x1b, 0x77, 0x69, 0x68, 0x69, 0x75, 0x96, 0x7d, 0x78, 0xa4, 0x6b, 0xdd, 0x5d, 0x32, 0x8c,
+	0xd6, 0x00, 0x1d, 0x36, 0xba, 0x8d, 0x03, 0x2f, 0x98, 0xdd, 0x14, 0xe7, 0xf8, 0x17, 0x29, 0xba,
+	0xdf, 0xed, 0xe8, 0xcd, 0x76, 0x9d, 0xac, 0x3a, 0xe1, 0x41, 0xef, 0xd1, 0x0f, 0x5b, 0xf8, 0x58,
+	0xf9, 0xd4, 0xae, 0xf9, 0xce, 0xc2, 0x73, 0x52, 0xf3, 0x09, 0xf4, 0x38, 0x35, 0x1f, 0xb7, 0x19,
+	0xa3, 0xe6, 0xe3, 0xde, 0x5d, 0x35, 0xdf, 0x3d, 0x52, 0xf3, 0xb1, 0x5d, 0xa5, 0x35, 0x5f, 0x80,
+	0xa1, 0x6b, 0xf3, 0x37, 0x92, 0x6f, 0x4e, 0x96, 0x26, 0x54, 0xdb, 0xcc, 0xa9, 0xe1, 0xce, 0xe9,
+	0xa0, 0xfe, 0x07, 0xe6, 0x68, 0x55, 0xde, 0x34, 0xb0, 0x25, 0xf6, 0x73, 0x15, 0xa6, 0x4d, 0x3a,
+	0xe0, 0x6c, 0xe7, 0xcc, 0xe0, 0x64, 0x29, 0xcd, 0x50, 0xb5, 0x2a, 0xf9, 0x9d, 0xa7, 0x4f, 0x2d,
+	0xe5, 0x21, 0xbf, 0x17, 0x30, 0x73, 0x1e, 0x4a, 0x05, 0xa6, 0x18, 0x80, 0x47, 0x52, 0x94, 0xd7,
+	0x0c, 0xd4, 0x86, 0x23, 0x95, 0xef, 0x63, 0xb0, 0x20, 0x8a, 0xd3, 0xd3, 0xc5, 0x82, 0x36, 0x20,
+	0xc7, 0xa1, 0x63, 0xe4, 0x35, 0xcb, 0x4c, 0x44, 0x5a, 0x2b, 0x9e, 0xb4, 0x2e, 0x06, 0x07, 0xee,
+	0x2a, 0x4f, 0x1e, 0x39, 0x57, 0x91, 0x33, 0x6f, 0xc3, 0xaf, 0x71, 0x40, 0xac, 0x12, 0x23, 0xaf,
+	0xb6, 0x6c, 0xbe, 0xe7, 0x97, 0xcd, 0x72, 0x70, 0x55, 0xe9, 0x36, 0x1c, 0x56, 0xcd, 0xcf, 0xce,
+	0x5f, 0x35, 0x55, 0x9f, 0x6a, 0xde, 0x1d, 0x2f, 0xb6, 0x0b, 0x11, 0xcd, 0x2d, 0x71, 0xb5, 0xe0,
+	0x11, 0xf1, 0x94, 0xfd, 0x83, 0x5c, 0x84, 0xe8, 0x10, 0x97, 0xcc, 0xb0, 0x9c, 0x09, 0xa8, 0x52,
+	0x83, 0x05, 0x71, 0xd9, 0x76, 0x53, 0xb7, 0xe2, 0xa9, 0x75, 0x47, 0xe6, 0x92, 0x77, 0xaa, 0x33,
+	0x70, 0xe9, 0xff, 0xb0, 0x20, 0x2e, 0x56, 0xa7, 0x3c, 0xdd, 0x97, 0x9d, 0x0b, 0x9e, 0x3b, 0x9a,
+	0xca, 0x37, 0x97, 0x21, 0xb5, 0xc9, 0xfe, 0x17, 0x01, 0x69, 0x90, 0xe2, 0x0d, 0x7a, 0xa4, 0xc8,
+	0x82, 0xf2, 0x36, 0xfd, 0x8b, 0xd7, 0x42, 0x31, 0xbc, 0x12, 0xbd, 0xf4, 0xe3, 0xb7, 0xbf, 0x7f,
+	0x19, 0x9f, 0x85, 0x2c, 0x05, 0xfd, 0x8d, 0xff, 0x12, 0x20, 0x1d, 0xa6, 0xed, 0x4e, 0x2f, 0xfa,
+	0xcb, 0x28, 0x7d, 0xf1, 0xe2, 0xf5, 0x08, 0x54, 0xb8, 0x43, 0x03, 0xc0, 0x69, 0xb4, 0xa2, 0xeb,
+	0xc1, 0xf7, 0x73, 0xf7, 0x0a, 0x57, 0xa2, 0x60, 0x91, 0x3e, 0x9d, 0x46, 0xaa, 0xdc, 0xe7, 0x50,
+	0xe3, 0x56, 0xee, 0x53, 0xd2, 0x8f, 0x0d, 0xf0, 0xc9, 0x72, 0xb8, 0xdb, 0x30, 0xdb, 0x81, 0x39,
+	0x74, 0x35, 0x52, 0x03, 0x73, 0xe8, 0x69, 0x99, 0x86, 0xe7, 0x90, 0xb6, 0xca, 0x82, 0x73, 0xe8,
+	0x6e, 0x4b, 0x06, 0xe7, 0xd0, 0xd3, 0x6f, 0x8b, 0xdc, 0x4f, 0xba, 0xbc, 0x90, 0xfd, 0x74, 0xaf,
+	0x70, 0x25, 0x0a, 0x16, 0xe9, 0xd3, 0x69, 0x75, 0xc9, 0x7d, 0x0e, 0x75, 0xd3, 0xe4, 0x3e, 0x87,
+	0x3b, 0x66, 0x41, 0x3e, 0x5f, 0xc3, 0x8c, 0xfb, 0x0a, 0x8f, 0x6e, 0x8c, 0xd8, 0x77, 0x28, 0x96,
+	0xa2, 0x81, 0xe1, 0x9e, 0x3f, 0x82, 0xac, 0xa7, 0xd7, 0x88, 0xa4, 0x33, 0xca, 0x7a, 0x9b, 0xc5,
+	0xd5, 0x11, 0x90, 0x91, 0xce, 0x3d, 0x3d, 0x2d, 0xb9, 0x73, 0x59, 0x17, 0x4d, 0xee, 0x5c, 0xda,
+	0x20, 0x0b, 0x71, 0xee, 0x69, 0x5d, 0xc9, 0x9d, 0xcb, 0x7a, 0x64, 0x72, 0xe7, 0xf2, 0x3e, 0x58,
+	0x28, 0xc9, 0xf8, 0x55, 0x30, 0x90, 0x64, 0xde, 0xf6, 0x41, 0x20, 0xc9, 0xfc, 0xbd, 0x80, 0x70,
+	0x92, 0x89, 0x7b, 0x6b, 0x30, 0xc9, 0x7c, 0x97, 0xed, 0x60, 0x92, 0xf9, 0xaf, 0xc0, 0x91, 0x24,
+	0x13, 0x0b, 0x0e, 0x21, 0x99, 0x6f, 0xcd, 0xab, 0x23, 0x20, 0x47, 0xcc, 0x73, 0xa8, 0x73, 0x59,
+	0xbf, 0x26, 0x2c, 0xcf, 0x23, 0x3a, 0x67, 0x79, 0xe6, 0x85, 0x7b, 0x60, 0x9e, 0xbd, 0x57, 0xa2,
+	0xc0, 0x3c, 0xfb, 0x6e, 0x0d, 0x11, 0x79, 0x16, 0x77, 0xca, 0xe0, 0x3c, 0xfb, 0x2e, 0xc2, 0xc1,
+	0x79, 0xf6, 0x5f, 0x4f, 0x23, 0xcf, 0xb3, 0x58, 0x70, 0xc8, 0x79, 0xf6, 0xad, 0x79, 0x75, 0x04,
+	0x64, 0xe4, 0x8f, 0x93, 0x7d, 0x9b, 0x91, 0xff, 0x38, 0xf9, 0xef, 0x4a, 0xc5, 0xeb, 0x11, 0xa8,
+	0xc8, 0x7d, 0x76, 0x5f, 0x1d, 0xe4, 0xfb, 0x2c, 0xb9, 0x16, 0x15, 0x4b, 0xd1, 0xc0, 0x70, 0xcf,
+	0x7d, 0xc8, 0xb8, 0x0a, 0x60, 0xb4, 0x32, 0x5a, 0xcd, 0x5e, 0xbc, 0x11, 0x89, 0x8b, 0x5c, 0xb0,
+	0xbb, 0xbe, 0x95, 0x2f, 0x58, 0x52, 0x4c, 0x17, 0x4b, 0xd1, 0xc0, 0x48, 0xcf, 0xee, 0x5a, 0x56,
+	0xee, 0x59, 0x52, 0x2f, 0x17, 0x4b, 0xd1, 0xc0, 0x50, 0xcf, 0x1b, 0x85, 0x37, 0x6f, 0x17, 0x27,
+	0x7e, 0x7e, 0xbb, 0x38, 0xf1, 0xf1, 0x60, 0x31, 0xf6, 0x66, 0xb0, 0x18, 0xfb, 0x69, 0xb0, 0x18,
+	0xfb, 0x65, 0xb0, 0x18, 0xdb, 0x9f, 0xa2, 0x7f, 0x1a, 0x73, 0xeb, 0x8f, 0x00, 0x00, 0x00, 0xff,
+	0xff, 0xcc, 0x5c, 0xf3, 0xfa, 0x93, 0x23, 0x00, 0x00,
 }
 }

+ 5 - 0
vendor/github.com/docker/swarmkit/api/control.proto

@@ -191,6 +191,11 @@ message ListTasksRequest {
 		repeated docker.swarmkit.v1.TaskState desired_states = 6;
 		repeated docker.swarmkit.v1.TaskState desired_states = 6;
 		// NamePrefixes matches all objects with the given prefixes
 		// NamePrefixes matches all objects with the given prefixes
 		repeated string name_prefixes = 7;
 		repeated string name_prefixes = 7;
+		// UpToDate matches tasks that are consistent with the current
+		// service definition.
+		// Note: this is intended for internal status reporting rather
+		// than being exposed to users. It may be removed in the future.
+		bool up_to_date = 8;
 	}
 	}
 
 
 	Filters filters = 1;
 	Filters filters = 1;

+ 82 - 43
vendor/github.com/docker/swarmkit/api/logbroker.pb.go

@@ -190,6 +190,11 @@ type PublishLogsMessage struct {
 	SubscriptionID string `protobuf:"bytes,1,opt,name=subscription_id,json=subscriptionId,proto3" json:"subscription_id,omitempty"`
 	SubscriptionID string `protobuf:"bytes,1,opt,name=subscription_id,json=subscriptionId,proto3" json:"subscription_id,omitempty"`
 	// Messages is the log message for publishing.
 	// Messages is the log message for publishing.
 	Messages []LogMessage `protobuf:"bytes,2,rep,name=messages" json:"messages"`
 	Messages []LogMessage `protobuf:"bytes,2,rep,name=messages" json:"messages"`
+	// Close is a boolean for whether or not the client has completed its log
+	// stream. When close is called, the manager can hang up the subscription.
+	// Any further logs from this subscription are an error condition. Any
+	// messages included when close is set can be discarded
+	Close bool `protobuf:"varint,3,opt,name=close,proto3" json:"close,omitempty"`
 }
 }
 
 
 func (m *PublishLogsMessage) Reset()                    { *m = PublishLogsMessage{} }
 func (m *PublishLogsMessage) Reset()                    { *m = PublishLogsMessage{} }
@@ -1127,6 +1132,16 @@ func (m *PublishLogsMessage) MarshalTo(dAtA []byte) (int, error) {
 			i += n
 			i += n
 		}
 		}
 	}
 	}
+	if m.Close {
+		dAtA[i] = 0x18
+		i++
+		if m.Close {
+			dAtA[i] = 1
+		} else {
+			dAtA[i] = 0
+		}
+		i++
+	}
 	return i, nil
 	return i, nil
 }
 }
 
 
@@ -1629,6 +1644,9 @@ func (m *PublishLogsMessage) Size() (n int) {
 			n += 1 + l + sovLogbroker(uint64(l))
 			n += 1 + l + sovLogbroker(uint64(l))
 		}
 		}
 	}
 	}
+	if m.Close {
+		n += 2
+	}
 	return n
 	return n
 }
 }
 
 
@@ -1751,6 +1769,7 @@ func (this *PublishLogsMessage) String() string {
 	s := strings.Join([]string{`&PublishLogsMessage{`,
 	s := strings.Join([]string{`&PublishLogsMessage{`,
 		`SubscriptionID:` + fmt.Sprintf("%v", this.SubscriptionID) + `,`,
 		`SubscriptionID:` + fmt.Sprintf("%v", this.SubscriptionID) + `,`,
 		`Messages:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.Messages), "LogMessage", "LogMessage", 1), `&`, ``, 1) + `,`,
 		`Messages:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.Messages), "LogMessage", "LogMessage", 1), `&`, ``, 1) + `,`,
+		`Close:` + fmt.Sprintf("%v", this.Close) + `,`,
 		`}`,
 		`}`,
 	}, "")
 	}, "")
 	return s
 	return s
@@ -2894,6 +2913,26 @@ func (m *PublishLogsMessage) Unmarshal(dAtA []byte) error {
 				return err
 				return err
 			}
 			}
 			iNdEx = postIndex
 			iNdEx = postIndex
+		case 3:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Close", wireType)
+			}
+			var v int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowLogbroker
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				v |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			m.Close = bool(v != 0)
 		default:
 		default:
 			iNdEx = preIndex
 			iNdEx = preIndex
 			skippy, err := skipLogbroker(dAtA[iNdEx:])
 			skippy, err := skipLogbroker(dAtA[iNdEx:])
@@ -3073,14 +3112,14 @@ var (
 func init() { proto.RegisterFile("logbroker.proto", fileDescriptorLogbroker) }
 func init() { proto.RegisterFile("logbroker.proto", fileDescriptorLogbroker) }
 
 
 var fileDescriptorLogbroker = []byte{
 var fileDescriptorLogbroker = []byte{
-	// 881 bytes of a gzipped FileDescriptorProto
+	// 886 bytes of a gzipped FileDescriptorProto
 	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xa4, 0x95, 0x4f, 0x8f, 0xdb, 0x44,
 	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xa4, 0x95, 0x4f, 0x8f, 0xdb, 0x44,
 	0x18, 0xc6, 0x33, 0xce, 0x36, 0x7f, 0xde, 0x74, 0xff, 0x74, 0xb2, 0x5d, 0x45, 0x11, 0xb5, 0x23,
 	0x18, 0xc6, 0x33, 0xce, 0x36, 0x7f, 0xde, 0x74, 0xff, 0x74, 0xb2, 0x5d, 0x45, 0x11, 0xb5, 0x23,
 	0x57, 0x2a, 0xd1, 0xaa, 0x24, 0x25, 0x08, 0x81, 0x54, 0x09, 0x41, 0x48, 0x85, 0x22, 0xd2, 0x5d,
 	0x57, 0x2a, 0xd1, 0xaa, 0x24, 0x25, 0x08, 0x81, 0x54, 0x09, 0x41, 0x48, 0x85, 0x22, 0xd2, 0x5d,
 	0x34, 0xc9, 0x0a, 0x6e, 0x2b, 0x27, 0x9e, 0x1a, 0x2b, 0x8e, 0x27, 0x78, 0x9c, 0x2e, 0x07, 0x0e,
 	0x34, 0xc9, 0x0a, 0x6e, 0x2b, 0x27, 0x9e, 0x1a, 0x2b, 0x8e, 0x27, 0x78, 0x9c, 0x2e, 0x07, 0x0e,
-	0x1c, 0x8a, 0x84, 0x7a, 0xe0, 0x82, 0x90, 0xe0, 0xd0, 0x13, 0xbd, 0x21, 0xc1, 0x9d, 0x0f, 0x80,
+	0x1c, 0x8a, 0x84, 0x7a, 0xe0, 0x86, 0x04, 0x87, 0x9e, 0xe8, 0x05, 0x21, 0xc1, 0x9d, 0x0f, 0x80,
 	0x56, 0x9c, 0xe0, 0xc6, 0x29, 0xa2, 0xfe, 0x00, 0x7c, 0x06, 0xe4, 0x99, 0x89, 0xe3, 0x25, 0x49,
 	0x56, 0x9c, 0xe0, 0xc6, 0x29, 0xa2, 0xfe, 0x00, 0x7c, 0x06, 0xe4, 0x99, 0x89, 0xe3, 0x25, 0x49,
-	0x8b, 0xb6, 0x97, 0x64, 0xc6, 0xf3, 0xbc, 0x9e, 0xdf, 0xfb, 0xcc, 0x33, 0x09, 0xec, 0x7a, 0xcc,
+	0x8b, 0xb6, 0x97, 0x64, 0xc6, 0xf3, 0xbc, 0x9e, 0xdf, 0x3c, 0xf3, 0xbc, 0x09, 0xec, 0x7a, 0xcc,
 	0x19, 0x06, 0x6c, 0x4c, 0x83, 0xc6, 0x34, 0x60, 0x21, 0xc3, 0xd8, 0x66, 0xa3, 0x78, 0xc6, 0xcf,
 	0x19, 0x06, 0x6c, 0x4c, 0x83, 0xc6, 0x34, 0x60, 0x21, 0xc3, 0xd8, 0x66, 0xa3, 0x78, 0xc6, 0xcf,
 	0xac, 0x60, 0x32, 0x76, 0xc3, 0xc6, 0xc3, 0xd7, 0xab, 0xfb, 0x0e, 0x73, 0x98, 0x58, 0x6e, 0xc6,
 	0xac, 0x60, 0x32, 0x76, 0xc3, 0xc6, 0xc3, 0xd7, 0xab, 0xfb, 0x0e, 0x73, 0x98, 0x58, 0x6e, 0xc6,
 	0x23, 0xa9, 0xac, 0x1a, 0x0e, 0x63, 0x8e, 0x47, 0x9b, 0x62, 0x36, 0x9c, 0x3d, 0x68, 0x86, 0xee,
 	0x23, 0xa9, 0xac, 0x1a, 0x0e, 0x63, 0x8e, 0x47, 0x9b, 0x62, 0x36, 0x9c, 0x3d, 0x68, 0x86, 0xee,
@@ -3090,44 +3129,44 @@ var fileDescriptorLogbroker = []byte{
 	0x9d, 0xd6, 0x8d, 0xc6, 0x2a, 0x4c, 0x23, 0x2e, 0x16, 0x2a, 0xb2, 0x50, 0xe3, 0x03, 0xc8, 0x3d,
 	0x9d, 0xd6, 0x8d, 0xc6, 0x2a, 0x4c, 0x23, 0x2e, 0x16, 0x2a, 0xb2, 0x50, 0xe3, 0x03, 0xc8, 0x3d,
 	0x60, 0x9e, 0xc7, 0xce, 0x2a, 0x5a, 0x0d, 0xd5, 0x0b, 0x44, 0xcd, 0x30, 0x86, 0xad, 0xd0, 0x72,
 	0x60, 0x9e, 0xc7, 0xce, 0x2a, 0x5a, 0x0d, 0xd5, 0x0b, 0x44, 0xcd, 0x30, 0x86, 0xad, 0xd0, 0x72,
 	0xbd, 0x4a, 0xb6, 0x86, 0xea, 0x59, 0x22, 0xc6, 0xf8, 0x0e, 0x5c, 0xe1, 0xae, 0x3f, 0xa2, 0x95,
 	0xbd, 0x4a, 0xb6, 0x86, 0xea, 0x59, 0x22, 0xc6, 0xf8, 0x0e, 0x5c, 0xe1, 0xae, 0x3f, 0xa2, 0x95,
-	0xad, 0x1a, 0xaa, 0x97, 0x5a, 0xd5, 0x86, 0xec, 0xa2, 0xb1, 0xe8, 0xa2, 0x31, 0x58, 0x74, 0x41,
-	0xa4, 0xd0, 0xfc, 0x06, 0x41, 0x29, 0xde, 0x94, 0x7a, 0x74, 0x14, 0xb2, 0x00, 0x37, 0xa1, 0xc4,
-	0x69, 0xf0, 0xd0, 0x1d, 0xd1, 0x53, 0xd7, 0x96, 0xa8, 0xc5, 0xf6, 0x4e, 0x34, 0x37, 0xa0, 0x2f,
-	0x1f, 0x77, 0x3b, 0x9c, 0x80, 0x92, 0x74, 0x6d, 0x8e, 0x6f, 0x41, 0xc1, 0x67, 0xb6, 0x54, 0x6b,
-	0x42, 0x5d, 0x8a, 0xe6, 0x46, 0xfe, 0x88, 0xd9, 0x42, 0x9a, 0x8f, 0x17, 0x95, 0x2e, 0xb4, 0xf8,
-	0x58, 0xe8, 0xb2, 0x4b, 0xdd, 0xc0, 0xe2, 0x63, 0xa1, 0x8b, 0x17, 0xbb, 0x36, 0x37, 0x1f, 0x21,
-	0x80, 0x1e, 0x73, 0xde, 0x67, 0x7e, 0x48, 0x3f, 0x0f, 0xf1, 0x6d, 0x80, 0x25, 0x4f, 0x05, 0xd5,
-	0x50, 0xbd, 0xd8, 0xde, 0x8e, 0xe6, 0x46, 0x31, 0xc1, 0x21, 0xc5, 0x84, 0x06, 0xdf, 0x84, 0xbc,
-	0x82, 0x11, 0x66, 0x15, 0xdb, 0x10, 0xcd, 0x8d, 0x9c, 0x64, 0x21, 0x39, 0x89, 0x12, 0x8b, 0x14,
-	0x89, 0xf0, 0x4e, 0x89, 0x24, 0x08, 0xc9, 0x49, 0x0e, 0xf3, 0x4f, 0x89, 0x71, 0x9f, 0x72, 0x6e,
-	0x39, 0x14, 0xbf, 0x03, 0xf9, 0x91, 0x24, 0x12, 0x0c, 0xa5, 0x96, 0xbe, 0xe1, 0xf4, 0x14, 0x77,
-	0x7b, 0xeb, 0x7c, 0x6e, 0x64, 0xc8, 0xa2, 0x08, 0xbf, 0x0d, 0xc5, 0x24, 0x40, 0x02, 0xed, 0xf9,
-	0x87, 0xb3, 0x14, 0xe3, 0x37, 0x21, 0x27, 0x93, 0x20, 0x60, 0x5f, 0x18, 0x1b, 0x25, 0x8e, 0xd3,
-	0x61, 0x5b, 0xa1, 0x25, 0x82, 0x70, 0x95, 0x88, 0xb1, 0xf9, 0x03, 0x82, 0x7d, 0x15, 0xcd, 0x21,
-	0xed, 0x31, 0x87, 0x13, 0xfa, 0xd9, 0x8c, 0xf2, 0x10, 0xdf, 0x85, 0x02, 0x57, 0x01, 0x50, 0xed,
-	0x19, 0x9b, 0x76, 0x51, 0x32, 0x92, 0x14, 0xe0, 0x0e, 0xe4, 0x99, 0xcc, 0xb8, 0x6a, 0xec, 0x70,
-	0x53, 0xed, 0xea, 0xad, 0x20, 0x8b, 0x52, 0xf3, 0x93, 0xff, 0xa0, 0x2d, 0x8c, 0x7f, 0x17, 0x0a,
-	0x13, 0x39, 0x94, 0x61, 0xdc, 0xec, 0xbc, 0xaa, 0x50, 0xce, 0x27, 0x55, 0xe6, 0x2b, 0x50, 0xed,
-	0xb9, 0x3c, 0xa4, 0x7e, 0x7a, 0xff, 0x45, 0xeb, 0xe6, 0x6f, 0x08, 0xca, 0xe9, 0x85, 0xc5, 0xbe,
-	0x07, 0xa0, 0x25, 0x79, 0xcb, 0x45, 0x73, 0x43, 0xeb, 0x76, 0x88, 0xe6, 0xda, 0x17, 0xac, 0xd2,
-	0x5e, 0xc2, 0xaa, 0xec, 0xa5, 0xad, 0xc2, 0xfb, 0x70, 0x65, 0xe4, 0x31, 0x2e, 0x2f, 0x79, 0x81,
-	0xc8, 0x89, 0xf9, 0x2d, 0x02, 0xfc, 0xd1, 0x6c, 0xe8, 0xb9, 0xfc, 0xd3, 0xb4, 0x7f, 0x77, 0x61,
-	0x97, 0xa7, 0x5e, 0xb6, 0xbc, 0x44, 0x38, 0x9a, 0x1b, 0x3b, 0xe9, 0x7d, 0xba, 0x1d, 0xb2, 0x93,
-	0x96, 0x76, 0xed, 0x0b, 0xe6, 0x6b, 0x97, 0x32, 0xff, 0x3a, 0x94, 0x53, 0x50, 0x84, 0xf2, 0x29,
-	0xf3, 0x39, 0x3d, 0x7c, 0x8a, 0xa0, 0x98, 0x64, 0x16, 0xdf, 0x06, 0xdc, 0x3b, 0xfe, 0xe0, 0xb4,
-	0x3f, 0x20, 0xf7, 0xde, 0xbb, 0x7f, 0x7a, 0x72, 0xf4, 0xe1, 0xd1, 0xf1, 0xc7, 0x47, 0x7b, 0x99,
-	0xea, 0xfe, 0xe3, 0x27, 0xb5, 0xbd, 0x44, 0x76, 0xe2, 0x8f, 0x7d, 0x76, 0xe6, 0xe3, 0x43, 0xb8,
-	0x96, 0x52, 0xf7, 0x07, 0x9d, 0xe3, 0x93, 0xc1, 0x1e, 0xaa, 0x96, 0x1f, 0x3f, 0xa9, 0xed, 0x26,
-	0xe2, 0x7e, 0x68, 0xb3, 0x59, 0xb8, 0xaa, 0xbd, 0x47, 0xc8, 0x9e, 0xb6, 0xaa, 0xa5, 0x41, 0x50,
-	0xbd, 0xf6, 0xf5, 0x8f, 0x7a, 0xe6, 0xd7, 0xa7, 0xfa, 0x12, 0xac, 0xf5, 0x08, 0xc1, 0x56, 0xcc,
-	0x8d, 0xbf, 0x80, 0xed, 0x0b, 0xe9, 0xc4, 0xf5, 0x75, 0x3e, 0xac, 0xbb, 0x5b, 0xd5, 0x17, 0x2b,
-	0x95, 0x77, 0xe6, 0xf5, 0xdf, 0x7f, 0xfe, 0xe7, 0x7b, 0x6d, 0x17, 0xb6, 0x85, 0xf2, 0xb5, 0x89,
-	0xe5, 0x5b, 0x0e, 0x0d, 0xee, 0xa0, 0xd6, 0x4f, 0x9a, 0x70, 0xab, 0x2d, 0xfe, 0xc9, 0xf0, 0x77,
-	0x08, 0xca, 0x6b, 0x02, 0x8d, 0x1b, 0x6b, 0x8f, 0x66, 0x63, 0xf2, 0xab, 0xaf, 0x3e, 0x07, 0x2c,
-	0x7d, 0x15, 0xcc, 0x9b, 0x82, 0xeb, 0x06, 0x5c, 0x95, 0x5c, 0x67, 0x2c, 0x18, 0xd3, 0x60, 0x85,
-	0x12, 0x7f, 0x85, 0xa0, 0x94, 0x3a, 0x6b, 0x7c, 0x6b, 0xdd, 0xfb, 0x57, 0x13, 0xba, 0x9e, 0x63,
-	0x4d, 0x68, 0xfe, 0x17, 0x47, 0x1d, 0xb5, 0x2b, 0xe7, 0xcf, 0xf4, 0xcc, 0x5f, 0xcf, 0xf4, 0xcc,
-	0x97, 0x91, 0x8e, 0xce, 0x23, 0x1d, 0xfd, 0x11, 0xe9, 0xe8, 0xef, 0x48, 0x47, 0xc3, 0x9c, 0xf8,
-	0xa5, 0x7d, 0xe3, 0xdf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x11, 0x82, 0x16, 0xad, 0x17, 0x08, 0x00,
-	0x00,
+	0xad, 0x1a, 0xaa, 0x97, 0x5a, 0xd5, 0x86, 0x3c, 0x45, 0x63, 0x71, 0x8a, 0xc6, 0x60, 0x71, 0x0a,
+	0x22, 0x85, 0xe6, 0x37, 0x08, 0x4a, 0xf1, 0xa6, 0xd4, 0xa3, 0xa3, 0x90, 0x05, 0xb8, 0x09, 0x25,
+	0x4e, 0x83, 0x87, 0xee, 0x88, 0x9e, 0xba, 0xb6, 0x44, 0x2d, 0xb6, 0x77, 0xa2, 0xb9, 0x01, 0x7d,
+	0xf9, 0xb8, 0xdb, 0xe1, 0x04, 0x94, 0xa4, 0x6b, 0x73, 0x7c, 0x0b, 0x0a, 0x3e, 0xb3, 0xa5, 0x5a,
+	0x13, 0xea, 0x52, 0x34, 0x37, 0xf2, 0x47, 0xcc, 0x16, 0xd2, 0x7c, 0xbc, 0xa8, 0x74, 0xa1, 0xc5,
+	0xc7, 0x42, 0x97, 0x5d, 0xea, 0x06, 0x16, 0x1f, 0x0b, 0x5d, 0xbc, 0xd8, 0xb5, 0xb9, 0xf9, 0x08,
+	0x01, 0xf4, 0x98, 0xf3, 0x3e, 0xf3, 0x43, 0xfa, 0x79, 0x88, 0x6f, 0x03, 0x2c, 0x79, 0x2a, 0xa8,
+	0x86, 0xea, 0xc5, 0xf6, 0x76, 0x34, 0x37, 0x8a, 0x09, 0x0e, 0x29, 0x26, 0x34, 0xf8, 0x26, 0xe4,
+	0x15, 0x8c, 0x30, 0xab, 0xd8, 0x86, 0x68, 0x6e, 0xe4, 0x24, 0x0b, 0xc9, 0x49, 0x94, 0x58, 0xa4,
+	0x48, 0x84, 0x77, 0x4a, 0x24, 0x41, 0x48, 0x4e, 0x72, 0x98, 0x7f, 0x4a, 0x8c, 0xfb, 0x94, 0x73,
+	0xcb, 0xa1, 0xf8, 0x1d, 0xc8, 0x8f, 0x24, 0x91, 0x60, 0x28, 0xb5, 0xf4, 0x0d, 0xb7, 0xa7, 0xb8,
+	0xdb, 0x5b, 0xe7, 0x73, 0x23, 0x43, 0x16, 0x45, 0xf8, 0x6d, 0x28, 0x26, 0x01, 0x12, 0x68, 0xcf,
+	0xbf, 0x9c, 0xa5, 0x18, 0xbf, 0x09, 0x39, 0x99, 0x04, 0x01, 0xfb, 0xc2, 0xd8, 0x28, 0x71, 0x9c,
+	0x0e, 0xdb, 0x0a, 0x2d, 0x11, 0x84, 0xab, 0x44, 0x8c, 0xcd, 0xef, 0x11, 0xec, 0xab, 0x68, 0x0e,
+	0x69, 0x8f, 0x39, 0x9c, 0xd0, 0xcf, 0x66, 0x94, 0x87, 0xf8, 0x2e, 0x14, 0xb8, 0x0a, 0x80, 0x3a,
+	0x9e, 0xb1, 0x69, 0x17, 0x25, 0x23, 0x49, 0x01, 0xee, 0x40, 0x9e, 0xc9, 0x8c, 0xab, 0x83, 0x1d,
+	0x6e, 0xaa, 0x5d, 0xed, 0x0a, 0xb2, 0x28, 0x35, 0x3f, 0xf9, 0x0f, 0xda, 0xc2, 0xf8, 0x77, 0xa1,
+	0x30, 0x91, 0x43, 0x19, 0xc6, 0xcd, 0xce, 0xab, 0x0a, 0xe5, 0x7c, 0x52, 0x65, 0xbe, 0x02, 0xd5,
+	0x9e, 0xcb, 0x43, 0xea, 0xa7, 0xf7, 0x5f, 0x1c, 0xdd, 0xfc, 0x0d, 0x41, 0x39, 0xbd, 0xb0, 0xd8,
+	0xf7, 0x00, 0xb4, 0x24, 0x6f, 0xb9, 0x68, 0x6e, 0x68, 0xdd, 0x0e, 0xd1, 0x5c, 0xfb, 0x82, 0x55,
+	0xda, 0x4b, 0x58, 0x95, 0xbd, 0xb4, 0x55, 0x78, 0x1f, 0xae, 0x8c, 0x3c, 0xc6, 0x65, 0x93, 0x17,
+	0x88, 0x9c, 0x98, 0x3f, 0x22, 0xc0, 0x1f, 0xcd, 0x86, 0x9e, 0xcb, 0x3f, 0x4d, 0xfb, 0x77, 0x17,
+	0x76, 0x79, 0xea, 0x65, 0xcb, 0x26, 0xc2, 0xd1, 0xdc, 0xd8, 0x49, 0xef, 0xd3, 0xed, 0x90, 0x9d,
+	0xb4, 0xb4, 0x6b, 0x5f, 0x30, 0x5f, 0xbb, 0x8c, 0xf9, 0x4b, 0xd6, 0x6c, 0x9a, 0xf5, 0x3a, 0x94,
+	0x53, 0xa8, 0x84, 0xf2, 0x29, 0xf3, 0x39, 0x3d, 0x7c, 0x8a, 0xa0, 0x98, 0x24, 0x19, 0xdf, 0x06,
+	0xdc, 0x3b, 0xfe, 0xe0, 0xb4, 0x3f, 0x20, 0xf7, 0xde, 0xbb, 0x7f, 0x7a, 0x72, 0xf4, 0xe1, 0xd1,
+	0xf1, 0xc7, 0x47, 0x7b, 0x99, 0xea, 0xfe, 0xe3, 0x27, 0xb5, 0xbd, 0x44, 0x76, 0xe2, 0x8f, 0x7d,
+	0x76, 0xe6, 0xe3, 0x43, 0xb8, 0x96, 0x52, 0xf7, 0x07, 0x9d, 0xe3, 0x93, 0xc1, 0x1e, 0xaa, 0x96,
+	0x1f, 0x3f, 0xa9, 0xed, 0x26, 0xe2, 0x7e, 0x68, 0xb3, 0x59, 0xb8, 0xaa, 0xbd, 0x47, 0xc8, 0x9e,
+	0xb6, 0xaa, 0xa5, 0x41, 0x50, 0xbd, 0xf6, 0xf5, 0x0f, 0x7a, 0xe6, 0xd7, 0xa7, 0xfa, 0x12, 0xac,
+	0xf5, 0x08, 0xc1, 0x56, 0xcc, 0x8d, 0xbf, 0x80, 0xed, 0x0b, 0x99, 0xc5, 0xf5, 0x75, 0xee, 0xac,
+	0xeb, 0xb8, 0xea, 0x8b, 0x95, 0xca, 0x51, 0xf3, 0xfa, 0xef, 0x3f, 0xff, 0xf3, 0x9d, 0xb6, 0x0b,
+	0xdb, 0x42, 0xf9, 0xda, 0xc4, 0xf2, 0x2d, 0x87, 0x06, 0x77, 0x50, 0xeb, 0x27, 0x4d, 0xb8, 0xd5,
+	0x16, 0xff, 0x6f, 0xf8, 0x5b, 0x04, 0xe5, 0x35, 0x31, 0xc7, 0x8d, 0xb5, 0x17, 0xb6, 0xb1, 0x1f,
+	0xaa, 0xaf, 0x3e, 0x07, 0x2c, 0xdd, 0x20, 0xe6, 0x4d, 0xc1, 0x75, 0x03, 0xae, 0x4a, 0xae, 0x33,
+	0x16, 0x8c, 0x69, 0xb0, 0x42, 0x89, 0xbf, 0x42, 0x50, 0x4a, 0xdd, 0x35, 0xbe, 0xb5, 0xee, 0xfd,
+	0xab, 0xb9, 0x5d, 0xcf, 0xb1, 0x26, 0x34, 0xff, 0x8b, 0xa3, 0x8e, 0xda, 0x95, 0xf3, 0x67, 0x7a,
+	0xe6, 0xaf, 0x67, 0x7a, 0xe6, 0xcb, 0x48, 0x47, 0xe7, 0x91, 0x8e, 0xfe, 0x88, 0x74, 0xf4, 0x77,
+	0xa4, 0xa3, 0x61, 0x4e, 0xfc, 0xfe, 0xbe, 0xf1, 0x6f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xa3, 0x37,
+	0x34, 0x6f, 0x2d, 0x08, 0x00, 0x00,
 }
 }

+ 6 - 0
vendor/github.com/docker/swarmkit/api/logbroker.proto

@@ -167,6 +167,12 @@ message PublishLogsMessage {
 
 
 	// Messages is the log message for publishing.
 	// Messages is the log message for publishing.
 	repeated LogMessage messages = 2 [(gogoproto.nullable) = false];
 	repeated LogMessage messages = 2 [(gogoproto.nullable) = false];
+
+	// Close is a boolean for whether or not the client has completed its log
+	// stream. When close is called, the manager can hang up the subscription.
+	// Any further logs from this subscription are an error condition. Any
+	// messages included when close is set can be discarded
+	bool close = 3;
 }
 }
 
 
 message PublishLogsResponse { }
 message PublishLogsResponse { }

+ 142 - 397
vendor/github.com/docker/swarmkit/api/specs.pb.go

@@ -106,7 +106,7 @@ func (x EndpointSpec_ResolutionMode) String() string {
 	return proto.EnumName(EndpointSpec_ResolutionMode_name, int32(x))
 	return proto.EnumName(EndpointSpec_ResolutionMode_name, int32(x))
 }
 }
 func (EndpointSpec_ResolutionMode) EnumDescriptor() ([]byte, []int) {
 func (EndpointSpec_ResolutionMode) EnumDescriptor() ([]byte, []int) {
-	return fileDescriptorSpecs, []int{8, 0}
+	return fileDescriptorSpecs, []int{7, 0}
 }
 }
 
 
 type NodeSpec struct {
 type NodeSpec struct {
@@ -289,7 +289,6 @@ type TaskSpec struct {
 	// Types that are valid to be assigned to Runtime:
 	// Types that are valid to be assigned to Runtime:
 	//	*TaskSpec_Attachment
 	//	*TaskSpec_Attachment
 	//	*TaskSpec_Container
 	//	*TaskSpec_Container
-	//	*TaskSpec_Plugin
 	Runtime isTaskSpec_Runtime `protobuf_oneof:"runtime"`
 	Runtime isTaskSpec_Runtime `protobuf_oneof:"runtime"`
 	// Resource requirements for the container.
 	// Resource requirements for the container.
 	Resources *ResourceRequirements `protobuf:"bytes,2,opt,name=resources" json:"resources,omitempty"`
 	Resources *ResourceRequirements `protobuf:"bytes,2,opt,name=resources" json:"resources,omitempty"`
@@ -327,13 +326,9 @@ type TaskSpec_Attachment struct {
 type TaskSpec_Container struct {
 type TaskSpec_Container struct {
 	Container *ContainerSpec `protobuf:"bytes,1,opt,name=container,oneof"`
 	Container *ContainerSpec `protobuf:"bytes,1,opt,name=container,oneof"`
 }
 }
-type TaskSpec_Plugin struct {
-	Plugin *PluginSpec `protobuf:"bytes,10,opt,name=plugin,oneof"`
-}
 
 
 func (*TaskSpec_Attachment) isTaskSpec_Runtime() {}
 func (*TaskSpec_Attachment) isTaskSpec_Runtime() {}
 func (*TaskSpec_Container) isTaskSpec_Runtime()  {}
 func (*TaskSpec_Container) isTaskSpec_Runtime()  {}
-func (*TaskSpec_Plugin) isTaskSpec_Runtime()     {}
 
 
 func (m *TaskSpec) GetRuntime() isTaskSpec_Runtime {
 func (m *TaskSpec) GetRuntime() isTaskSpec_Runtime {
 	if m != nil {
 	if m != nil {
@@ -356,19 +351,11 @@ func (m *TaskSpec) GetContainer() *ContainerSpec {
 	return nil
 	return nil
 }
 }
 
 
-func (m *TaskSpec) GetPlugin() *PluginSpec {
-	if x, ok := m.GetRuntime().(*TaskSpec_Plugin); ok {
-		return x.Plugin
-	}
-	return nil
-}
-
 // XXX_OneofFuncs is for the internal use of the proto package.
 // XXX_OneofFuncs is for the internal use of the proto package.
 func (*TaskSpec) 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{}) {
 func (*TaskSpec) 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 _TaskSpec_OneofMarshaler, _TaskSpec_OneofUnmarshaler, _TaskSpec_OneofSizer, []interface{}{
 	return _TaskSpec_OneofMarshaler, _TaskSpec_OneofUnmarshaler, _TaskSpec_OneofSizer, []interface{}{
 		(*TaskSpec_Attachment)(nil),
 		(*TaskSpec_Attachment)(nil),
 		(*TaskSpec_Container)(nil),
 		(*TaskSpec_Container)(nil),
-		(*TaskSpec_Plugin)(nil),
 	}
 	}
 }
 }
 
 
@@ -386,11 +373,6 @@ func _TaskSpec_OneofMarshaler(msg proto.Message, b *proto.Buffer) error {
 		if err := b.EncodeMessage(x.Container); err != nil {
 		if err := b.EncodeMessage(x.Container); err != nil {
 			return err
 			return err
 		}
 		}
-	case *TaskSpec_Plugin:
-		_ = b.EncodeVarint(10<<3 | proto.WireBytes)
-		if err := b.EncodeMessage(x.Plugin); err != nil {
-			return err
-		}
 	case nil:
 	case nil:
 	default:
 	default:
 		return fmt.Errorf("TaskSpec.Runtime has unexpected type %T", x)
 		return fmt.Errorf("TaskSpec.Runtime has unexpected type %T", x)
@@ -417,14 +399,6 @@ func _TaskSpec_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffe
 		err := b.DecodeMessage(msg)
 		err := b.DecodeMessage(msg)
 		m.Runtime = &TaskSpec_Container{msg}
 		m.Runtime = &TaskSpec_Container{msg}
 		return true, err
 		return true, err
-	case 10: // runtime.plugin
-		if wire != proto.WireBytes {
-			return true, proto.ErrInternalBadWireType
-		}
-		msg := new(PluginSpec)
-		err := b.DecodeMessage(msg)
-		m.Runtime = &TaskSpec_Plugin{msg}
-		return true, err
 	default:
 	default:
 		return false, nil
 		return false, nil
 	}
 	}
@@ -444,11 +418,6 @@ func _TaskSpec_OneofSizer(msg proto.Message) (n int) {
 		n += proto.SizeVarint(1<<3 | proto.WireBytes)
 		n += proto.SizeVarint(1<<3 | proto.WireBytes)
 		n += proto.SizeVarint(uint64(s))
 		n += proto.SizeVarint(uint64(s))
 		n += s
 		n += s
-	case *TaskSpec_Plugin:
-		s := proto.Size(x.Plugin)
-		n += proto.SizeVarint(10<<3 | proto.WireBytes)
-		n += proto.SizeVarint(uint64(s))
-		n += s
 	case nil:
 	case nil:
 	default:
 	default:
 		panic(fmt.Sprintf("proto: unexpected type %T in oneof", x))
 		panic(fmt.Sprintf("proto: unexpected type %T in oneof", x))
@@ -590,18 +559,6 @@ func (m *ContainerSpec_DNSConfig) Reset()                    { *m = ContainerSpe
 func (*ContainerSpec_DNSConfig) ProtoMessage()               {}
 func (*ContainerSpec_DNSConfig) ProtoMessage()               {}
 func (*ContainerSpec_DNSConfig) Descriptor() ([]byte, []int) { return fileDescriptorSpecs, []int{6, 2} }
 func (*ContainerSpec_DNSConfig) Descriptor() ([]byte, []int) { return fileDescriptorSpecs, []int{6, 2} }
 
 
-// PluginSpec specifies runtime parameters for a plugin.
-type PluginSpec struct {
-	// image defines the image reference, as specified in the
-	// distribution/reference package. This may include a registry host, name,
-	// tag or digest.
-	Image string `protobuf:"bytes,1,opt,name=image,proto3" json:"image,omitempty"`
-}
-
-func (m *PluginSpec) Reset()                    { *m = PluginSpec{} }
-func (*PluginSpec) ProtoMessage()               {}
-func (*PluginSpec) Descriptor() ([]byte, []int) { return fileDescriptorSpecs, []int{7} }
-
 // EndpointSpec defines the properties that can be configured to
 // EndpointSpec defines the properties that can be configured to
 // access and loadbalance the service.
 // access and loadbalance the service.
 type EndpointSpec struct {
 type EndpointSpec struct {
@@ -613,7 +570,7 @@ type EndpointSpec struct {
 
 
 func (m *EndpointSpec) Reset()                    { *m = EndpointSpec{} }
 func (m *EndpointSpec) Reset()                    { *m = EndpointSpec{} }
 func (*EndpointSpec) ProtoMessage()               {}
 func (*EndpointSpec) ProtoMessage()               {}
-func (*EndpointSpec) Descriptor() ([]byte, []int) { return fileDescriptorSpecs, []int{8} }
+func (*EndpointSpec) Descriptor() ([]byte, []int) { return fileDescriptorSpecs, []int{7} }
 
 
 // NetworkSpec specifies user defined network parameters.
 // NetworkSpec specifies user defined network parameters.
 type NetworkSpec struct {
 type NetworkSpec struct {
@@ -638,7 +595,7 @@ type NetworkSpec struct {
 
 
 func (m *NetworkSpec) Reset()                    { *m = NetworkSpec{} }
 func (m *NetworkSpec) Reset()                    { *m = NetworkSpec{} }
 func (*NetworkSpec) ProtoMessage()               {}
 func (*NetworkSpec) ProtoMessage()               {}
-func (*NetworkSpec) Descriptor() ([]byte, []int) { return fileDescriptorSpecs, []int{9} }
+func (*NetworkSpec) Descriptor() ([]byte, []int) { return fileDescriptorSpecs, []int{8} }
 
 
 // ClusterSpec specifies global cluster settings.
 // ClusterSpec specifies global cluster settings.
 type ClusterSpec struct {
 type ClusterSpec struct {
@@ -663,7 +620,7 @@ type ClusterSpec struct {
 
 
 func (m *ClusterSpec) Reset()                    { *m = ClusterSpec{} }
 func (m *ClusterSpec) Reset()                    { *m = ClusterSpec{} }
 func (*ClusterSpec) ProtoMessage()               {}
 func (*ClusterSpec) ProtoMessage()               {}
-func (*ClusterSpec) Descriptor() ([]byte, []int) { return fileDescriptorSpecs, []int{10} }
+func (*ClusterSpec) Descriptor() ([]byte, []int) { return fileDescriptorSpecs, []int{9} }
 
 
 // SecretSpec specifies a user-provided secret.
 // SecretSpec specifies a user-provided secret.
 type SecretSpec struct {
 type SecretSpec struct {
@@ -674,7 +631,7 @@ type SecretSpec struct {
 
 
 func (m *SecretSpec) Reset()                    { *m = SecretSpec{} }
 func (m *SecretSpec) Reset()                    { *m = SecretSpec{} }
 func (*SecretSpec) ProtoMessage()               {}
 func (*SecretSpec) ProtoMessage()               {}
-func (*SecretSpec) Descriptor() ([]byte, []int) { return fileDescriptorSpecs, []int{11} }
+func (*SecretSpec) Descriptor() ([]byte, []int) { return fileDescriptorSpecs, []int{10} }
 
 
 func init() {
 func init() {
 	proto.RegisterType((*NodeSpec)(nil), "docker.swarmkit.v1.NodeSpec")
 	proto.RegisterType((*NodeSpec)(nil), "docker.swarmkit.v1.NodeSpec")
@@ -686,7 +643,6 @@ func init() {
 	proto.RegisterType((*ContainerSpec)(nil), "docker.swarmkit.v1.ContainerSpec")
 	proto.RegisterType((*ContainerSpec)(nil), "docker.swarmkit.v1.ContainerSpec")
 	proto.RegisterType((*ContainerSpec_PullOptions)(nil), "docker.swarmkit.v1.ContainerSpec.PullOptions")
 	proto.RegisterType((*ContainerSpec_PullOptions)(nil), "docker.swarmkit.v1.ContainerSpec.PullOptions")
 	proto.RegisterType((*ContainerSpec_DNSConfig)(nil), "docker.swarmkit.v1.ContainerSpec.DNSConfig")
 	proto.RegisterType((*ContainerSpec_DNSConfig)(nil), "docker.swarmkit.v1.ContainerSpec.DNSConfig")
-	proto.RegisterType((*PluginSpec)(nil), "docker.swarmkit.v1.PluginSpec")
 	proto.RegisterType((*EndpointSpec)(nil), "docker.swarmkit.v1.EndpointSpec")
 	proto.RegisterType((*EndpointSpec)(nil), "docker.swarmkit.v1.EndpointSpec")
 	proto.RegisterType((*NetworkSpec)(nil), "docker.swarmkit.v1.NetworkSpec")
 	proto.RegisterType((*NetworkSpec)(nil), "docker.swarmkit.v1.NetworkSpec")
 	proto.RegisterType((*ClusterSpec)(nil), "docker.swarmkit.v1.ClusterSpec")
 	proto.RegisterType((*ClusterSpec)(nil), "docker.swarmkit.v1.ClusterSpec")
@@ -842,12 +798,6 @@ func (m *TaskSpec) CopyFrom(src interface{}) {
 			}
 			}
 			github_com_docker_swarmkit_api_deepcopy.Copy(v.Container, o.GetContainer())
 			github_com_docker_swarmkit_api_deepcopy.Copy(v.Container, o.GetContainer())
 			m.Runtime = &v
 			m.Runtime = &v
-		case *TaskSpec_Plugin:
-			v := TaskSpec_Plugin{
-				Plugin: &PluginSpec{},
-			}
-			github_com_docker_swarmkit_api_deepcopy.Copy(v.Plugin, o.GetPlugin())
-			m.Runtime = &v
 		}
 		}
 	}
 	}
 
 
@@ -991,21 +941,6 @@ func (m *ContainerSpec_DNSConfig) CopyFrom(src interface{}) {
 
 
 }
 }
 
 
-func (m *PluginSpec) Copy() *PluginSpec {
-	if m == nil {
-		return nil
-	}
-	o := &PluginSpec{}
-	o.CopyFrom(m)
-	return o
-}
-
-func (m *PluginSpec) CopyFrom(src interface{}) {
-
-	o := src.(*PluginSpec)
-	*m = *o
-}
-
 func (m *EndpointSpec) Copy() *EndpointSpec {
 func (m *EndpointSpec) Copy() *EndpointSpec {
 	if m == nil {
 	if m == nil {
 		return nil
 		return nil
@@ -1395,20 +1330,6 @@ func (m *TaskSpec_Attachment) MarshalTo(dAtA []byte) (int, error) {
 	}
 	}
 	return i, nil
 	return i, nil
 }
 }
-func (m *TaskSpec_Plugin) MarshalTo(dAtA []byte) (int, error) {
-	i := 0
-	if m.Plugin != nil {
-		dAtA[i] = 0x52
-		i++
-		i = encodeVarintSpecs(dAtA, i, uint64(m.Plugin.Size()))
-		n17, err := m.Plugin.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += n17
-	}
-	return i, nil
-}
 func (m *NetworkAttachmentSpec) Marshal() (dAtA []byte, err error) {
 func (m *NetworkAttachmentSpec) Marshal() (dAtA []byte, err error) {
 	size := m.Size()
 	size := m.Size()
 	dAtA = make([]byte, size)
 	dAtA = make([]byte, size)
@@ -1544,21 +1465,21 @@ func (m *ContainerSpec) MarshalTo(dAtA []byte) (int, error) {
 		dAtA[i] = 0x4a
 		dAtA[i] = 0x4a
 		i++
 		i++
 		i = encodeVarintSpecs(dAtA, i, uint64(m.StopGracePeriod.Size()))
 		i = encodeVarintSpecs(dAtA, i, uint64(m.StopGracePeriod.Size()))
-		n18, err := m.StopGracePeriod.MarshalTo(dAtA[i:])
+		n17, err := m.StopGracePeriod.MarshalTo(dAtA[i:])
 		if err != nil {
 		if err != nil {
 			return 0, err
 			return 0, err
 		}
 		}
-		i += n18
+		i += n17
 	}
 	}
 	if m.PullOptions != nil {
 	if m.PullOptions != nil {
 		dAtA[i] = 0x52
 		dAtA[i] = 0x52
 		i++
 		i++
 		i = encodeVarintSpecs(dAtA, i, uint64(m.PullOptions.Size()))
 		i = encodeVarintSpecs(dAtA, i, uint64(m.PullOptions.Size()))
-		n19, err := m.PullOptions.MarshalTo(dAtA[i:])
+		n18, err := m.PullOptions.MarshalTo(dAtA[i:])
 		if err != nil {
 		if err != nil {
 			return 0, err
 			return 0, err
 		}
 		}
-		i += n19
+		i += n18
 	}
 	}
 	if len(m.Groups) > 0 {
 	if len(m.Groups) > 0 {
 		for _, s := range m.Groups {
 		for _, s := range m.Groups {
@@ -1607,11 +1528,11 @@ func (m *ContainerSpec) MarshalTo(dAtA []byte) (int, error) {
 		dAtA[i] = 0x7a
 		dAtA[i] = 0x7a
 		i++
 		i++
 		i = encodeVarintSpecs(dAtA, i, uint64(m.DNSConfig.Size()))
 		i = encodeVarintSpecs(dAtA, i, uint64(m.DNSConfig.Size()))
-		n20, err := m.DNSConfig.MarshalTo(dAtA[i:])
+		n19, err := m.DNSConfig.MarshalTo(dAtA[i:])
 		if err != nil {
 		if err != nil {
 			return 0, err
 			return 0, err
 		}
 		}
-		i += n20
+		i += n19
 	}
 	}
 	if m.Healthcheck != nil {
 	if m.Healthcheck != nil {
 		dAtA[i] = 0x82
 		dAtA[i] = 0x82
@@ -1619,11 +1540,11 @@ func (m *ContainerSpec) MarshalTo(dAtA []byte) (int, error) {
 		dAtA[i] = 0x1
 		dAtA[i] = 0x1
 		i++
 		i++
 		i = encodeVarintSpecs(dAtA, i, uint64(m.Healthcheck.Size()))
 		i = encodeVarintSpecs(dAtA, i, uint64(m.Healthcheck.Size()))
-		n21, err := m.Healthcheck.MarshalTo(dAtA[i:])
+		n20, err := m.Healthcheck.MarshalTo(dAtA[i:])
 		if err != nil {
 		if err != nil {
 			return 0, err
 			return 0, err
 		}
 		}
-		i += n21
+		i += n20
 	}
 	}
 	if len(m.Hosts) > 0 {
 	if len(m.Hosts) > 0 {
 		for _, s := range m.Hosts {
 		for _, s := range m.Hosts {
@@ -1766,30 +1687,6 @@ func (m *ContainerSpec_DNSConfig) MarshalTo(dAtA []byte) (int, error) {
 	return i, nil
 	return i, nil
 }
 }
 
 
-func (m *PluginSpec) 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 *PluginSpec) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if len(m.Image) > 0 {
-		dAtA[i] = 0xa
-		i++
-		i = encodeVarintSpecs(dAtA, i, uint64(len(m.Image)))
-		i += copy(dAtA[i:], m.Image)
-	}
-	return i, nil
-}
-
 func (m *EndpointSpec) Marshal() (dAtA []byte, err error) {
 func (m *EndpointSpec) Marshal() (dAtA []byte, err error) {
 	size := m.Size()
 	size := m.Size()
 	dAtA = make([]byte, size)
 	dAtA = make([]byte, size)
@@ -1843,20 +1740,20 @@ func (m *NetworkSpec) MarshalTo(dAtA []byte) (int, error) {
 	dAtA[i] = 0xa
 	dAtA[i] = 0xa
 	i++
 	i++
 	i = encodeVarintSpecs(dAtA, i, uint64(m.Annotations.Size()))
 	i = encodeVarintSpecs(dAtA, i, uint64(m.Annotations.Size()))
-	n22, err := m.Annotations.MarshalTo(dAtA[i:])
+	n21, err := m.Annotations.MarshalTo(dAtA[i:])
 	if err != nil {
 	if err != nil {
 		return 0, err
 		return 0, err
 	}
 	}
-	i += n22
+	i += n21
 	if m.DriverConfig != nil {
 	if m.DriverConfig != nil {
 		dAtA[i] = 0x12
 		dAtA[i] = 0x12
 		i++
 		i++
 		i = encodeVarintSpecs(dAtA, i, uint64(m.DriverConfig.Size()))
 		i = encodeVarintSpecs(dAtA, i, uint64(m.DriverConfig.Size()))
-		n23, err := m.DriverConfig.MarshalTo(dAtA[i:])
+		n22, err := m.DriverConfig.MarshalTo(dAtA[i:])
 		if err != nil {
 		if err != nil {
 			return 0, err
 			return 0, err
 		}
 		}
-		i += n23
+		i += n22
 	}
 	}
 	if m.Ipv6Enabled {
 	if m.Ipv6Enabled {
 		dAtA[i] = 0x18
 		dAtA[i] = 0x18
@@ -1882,11 +1779,11 @@ func (m *NetworkSpec) MarshalTo(dAtA []byte) (int, error) {
 		dAtA[i] = 0x2a
 		dAtA[i] = 0x2a
 		i++
 		i++
 		i = encodeVarintSpecs(dAtA, i, uint64(m.IPAM.Size()))
 		i = encodeVarintSpecs(dAtA, i, uint64(m.IPAM.Size()))
-		n24, err := m.IPAM.MarshalTo(dAtA[i:])
+		n23, err := m.IPAM.MarshalTo(dAtA[i:])
 		if err != nil {
 		if err != nil {
 			return 0, err
 			return 0, err
 		}
 		}
-		i += n24
+		i += n23
 	}
 	}
 	if m.Attachable {
 	if m.Attachable {
 		dAtA[i] = 0x30
 		dAtA[i] = 0x30
@@ -1919,67 +1816,67 @@ func (m *ClusterSpec) MarshalTo(dAtA []byte) (int, error) {
 	dAtA[i] = 0xa
 	dAtA[i] = 0xa
 	i++
 	i++
 	i = encodeVarintSpecs(dAtA, i, uint64(m.Annotations.Size()))
 	i = encodeVarintSpecs(dAtA, i, uint64(m.Annotations.Size()))
-	n25, err := m.Annotations.MarshalTo(dAtA[i:])
+	n24, err := m.Annotations.MarshalTo(dAtA[i:])
 	if err != nil {
 	if err != nil {
 		return 0, err
 		return 0, err
 	}
 	}
-	i += n25
+	i += n24
 	dAtA[i] = 0x12
 	dAtA[i] = 0x12
 	i++
 	i++
 	i = encodeVarintSpecs(dAtA, i, uint64(m.AcceptancePolicy.Size()))
 	i = encodeVarintSpecs(dAtA, i, uint64(m.AcceptancePolicy.Size()))
-	n26, err := m.AcceptancePolicy.MarshalTo(dAtA[i:])
+	n25, err := m.AcceptancePolicy.MarshalTo(dAtA[i:])
 	if err != nil {
 	if err != nil {
 		return 0, err
 		return 0, err
 	}
 	}
-	i += n26
+	i += n25
 	dAtA[i] = 0x1a
 	dAtA[i] = 0x1a
 	i++
 	i++
 	i = encodeVarintSpecs(dAtA, i, uint64(m.Orchestration.Size()))
 	i = encodeVarintSpecs(dAtA, i, uint64(m.Orchestration.Size()))
-	n27, err := m.Orchestration.MarshalTo(dAtA[i:])
+	n26, err := m.Orchestration.MarshalTo(dAtA[i:])
 	if err != nil {
 	if err != nil {
 		return 0, err
 		return 0, err
 	}
 	}
-	i += n27
+	i += n26
 	dAtA[i] = 0x22
 	dAtA[i] = 0x22
 	i++
 	i++
 	i = encodeVarintSpecs(dAtA, i, uint64(m.Raft.Size()))
 	i = encodeVarintSpecs(dAtA, i, uint64(m.Raft.Size()))
-	n28, err := m.Raft.MarshalTo(dAtA[i:])
+	n27, err := m.Raft.MarshalTo(dAtA[i:])
 	if err != nil {
 	if err != nil {
 		return 0, err
 		return 0, err
 	}
 	}
-	i += n28
+	i += n27
 	dAtA[i] = 0x2a
 	dAtA[i] = 0x2a
 	i++
 	i++
 	i = encodeVarintSpecs(dAtA, i, uint64(m.Dispatcher.Size()))
 	i = encodeVarintSpecs(dAtA, i, uint64(m.Dispatcher.Size()))
-	n29, err := m.Dispatcher.MarshalTo(dAtA[i:])
+	n28, err := m.Dispatcher.MarshalTo(dAtA[i:])
 	if err != nil {
 	if err != nil {
 		return 0, err
 		return 0, err
 	}
 	}
-	i += n29
+	i += n28
 	dAtA[i] = 0x32
 	dAtA[i] = 0x32
 	i++
 	i++
 	i = encodeVarintSpecs(dAtA, i, uint64(m.CAConfig.Size()))
 	i = encodeVarintSpecs(dAtA, i, uint64(m.CAConfig.Size()))
-	n30, err := m.CAConfig.MarshalTo(dAtA[i:])
+	n29, err := m.CAConfig.MarshalTo(dAtA[i:])
 	if err != nil {
 	if err != nil {
 		return 0, err
 		return 0, err
 	}
 	}
-	i += n30
+	i += n29
 	dAtA[i] = 0x3a
 	dAtA[i] = 0x3a
 	i++
 	i++
 	i = encodeVarintSpecs(dAtA, i, uint64(m.TaskDefaults.Size()))
 	i = encodeVarintSpecs(dAtA, i, uint64(m.TaskDefaults.Size()))
-	n31, err := m.TaskDefaults.MarshalTo(dAtA[i:])
+	n30, err := m.TaskDefaults.MarshalTo(dAtA[i:])
 	if err != nil {
 	if err != nil {
 		return 0, err
 		return 0, err
 	}
 	}
-	i += n31
+	i += n30
 	dAtA[i] = 0x42
 	dAtA[i] = 0x42
 	i++
 	i++
 	i = encodeVarintSpecs(dAtA, i, uint64(m.EncryptionConfig.Size()))
 	i = encodeVarintSpecs(dAtA, i, uint64(m.EncryptionConfig.Size()))
-	n32, err := m.EncryptionConfig.MarshalTo(dAtA[i:])
+	n31, err := m.EncryptionConfig.MarshalTo(dAtA[i:])
 	if err != nil {
 	if err != nil {
 		return 0, err
 		return 0, err
 	}
 	}
-	i += n32
+	i += n31
 	return i, nil
 	return i, nil
 }
 }
 
 
@@ -2001,11 +1898,11 @@ func (m *SecretSpec) MarshalTo(dAtA []byte) (int, error) {
 	dAtA[i] = 0xa
 	dAtA[i] = 0xa
 	i++
 	i++
 	i = encodeVarintSpecs(dAtA, i, uint64(m.Annotations.Size()))
 	i = encodeVarintSpecs(dAtA, i, uint64(m.Annotations.Size()))
-	n33, err := m.Annotations.MarshalTo(dAtA[i:])
+	n32, err := m.Annotations.MarshalTo(dAtA[i:])
 	if err != nil {
 	if err != nil {
 		return 0, err
 		return 0, err
 	}
 	}
-	i += n33
+	i += n32
 	if len(m.Data) > 0 {
 	if len(m.Data) > 0 {
 		dAtA[i] = 0x12
 		dAtA[i] = 0x12
 		i++
 		i++
@@ -2176,15 +2073,6 @@ func (m *TaskSpec_Attachment) Size() (n int) {
 	}
 	}
 	return n
 	return n
 }
 }
-func (m *TaskSpec_Plugin) Size() (n int) {
-	var l int
-	_ = l
-	if m.Plugin != nil {
-		l = m.Plugin.Size()
-		n += 1 + l + sovSpecs(uint64(l))
-	}
-	return n
-}
 func (m *NetworkAttachmentSpec) Size() (n int) {
 func (m *NetworkAttachmentSpec) Size() (n int) {
 	var l int
 	var l int
 	_ = l
 	_ = l
@@ -2330,16 +2218,6 @@ func (m *ContainerSpec_DNSConfig) Size() (n int) {
 	return n
 	return n
 }
 }
 
 
-func (m *PluginSpec) Size() (n int) {
-	var l int
-	_ = l
-	l = len(m.Image)
-	if l > 0 {
-		n += 1 + l + sovSpecs(uint64(l))
-	}
-	return n
-}
-
 func (m *EndpointSpec) Size() (n int) {
 func (m *EndpointSpec) Size() (n int) {
 	var l int
 	var l int
 	_ = l
 	_ = l
@@ -2531,16 +2409,6 @@ func (this *TaskSpec_Attachment) String() string {
 	}, "")
 	}, "")
 	return s
 	return s
 }
 }
-func (this *TaskSpec_Plugin) String() string {
-	if this == nil {
-		return "nil"
-	}
-	s := strings.Join([]string{`&TaskSpec_Plugin{`,
-		`Plugin:` + strings.Replace(fmt.Sprintf("%v", this.Plugin), "PluginSpec", "PluginSpec", 1) + `,`,
-		`}`,
-	}, "")
-	return s
-}
 func (this *NetworkAttachmentSpec) String() string {
 func (this *NetworkAttachmentSpec) String() string {
 	if this == nil {
 	if this == nil {
 		return "nil"
 		return "nil"
@@ -2612,16 +2480,6 @@ func (this *ContainerSpec_DNSConfig) String() string {
 	}, "")
 	}, "")
 	return s
 	return s
 }
 }
-func (this *PluginSpec) String() string {
-	if this == nil {
-		return "nil"
-	}
-	s := strings.Join([]string{`&PluginSpec{`,
-		`Image:` + fmt.Sprintf("%v", this.Image) + `,`,
-		`}`,
-	}, "")
-	return s
-}
 func (this *EndpointSpec) String() string {
 func (this *EndpointSpec) String() string {
 	if this == nil {
 	if this == nil {
 		return "nil"
 		return "nil"
@@ -3519,38 +3377,6 @@ func (m *TaskSpec) Unmarshal(dAtA []byte) error {
 					break
 					break
 				}
 				}
 			}
 			}
-		case 10:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Plugin", wireType)
-			}
-			var msglen int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowSpecs
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthSpecs
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			v := &PluginSpec{}
-			if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			m.Runtime = &TaskSpec_Plugin{v}
-			iNdEx = postIndex
 		default:
 		default:
 			iNdEx = preIndex
 			iNdEx = preIndex
 			skippy, err := skipSpecs(dAtA[iNdEx:])
 			skippy, err := skipSpecs(dAtA[iNdEx:])
@@ -4577,85 +4403,6 @@ func (m *ContainerSpec_DNSConfig) Unmarshal(dAtA []byte) error {
 	}
 	}
 	return nil
 	return nil
 }
 }
-func (m *PluginSpec) 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 ErrIntOverflowSpecs
-			}
-			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: PluginSpec: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: PluginSpec: illegal tag %d (wire type %d)", fieldNum, wire)
-		}
-		switch fieldNum {
-		case 1:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Image", wireType)
-			}
-			var stringLen uint64
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowSpecs
-				}
-				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 ErrInvalidLengthSpecs
-			}
-			postIndex := iNdEx + intStringLen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			m.Image = string(dAtA[iNdEx:postIndex])
-			iNdEx = postIndex
-		default:
-			iNdEx = preIndex
-			skippy, err := skipSpecs(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthSpecs
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
 func (m *EndpointSpec) Unmarshal(dAtA []byte) error {
 func (m *EndpointSpec) Unmarshal(dAtA []byte) error {
 	l := len(dAtA)
 	l := len(dAtA)
 	iNdEx := 0
 	iNdEx := 0
@@ -5471,114 +5218,112 @@ var (
 func init() { proto.RegisterFile("specs.proto", fileDescriptorSpecs) }
 func init() { proto.RegisterFile("specs.proto", fileDescriptorSpecs) }
 
 
 var fileDescriptorSpecs = []byte{
 var fileDescriptorSpecs = []byte{
-	// 1730 bytes of a gzipped FileDescriptorProto
+	// 1707 bytes of a gzipped FileDescriptorProto
 	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xac, 0x57, 0x41, 0x73, 0x1b, 0xb7,
 	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xac, 0x57, 0x41, 0x73, 0x1b, 0xb7,
-	0x15, 0x26, 0x25, 0x8a, 0x5a, 0xbe, 0xa5, 0x6c, 0x0a, 0x4d, 0xd2, 0x35, 0xdd, 0x90, 0x34, 0xe3,
+	0x15, 0x26, 0x25, 0x8a, 0x5a, 0xbe, 0xa5, 0x6c, 0x1a, 0x75, 0xd2, 0x35, 0xdd, 0x90, 0x34, 0xe3,
 	0xa6, 0x4a, 0x33, 0xa5, 0xa6, 0x6a, 0x27, 0x75, 0xea, 0x66, 0x5a, 0x52, 0x64, 0x65, 0x55, 0x95,
 	0xa6, 0x4a, 0x33, 0xa5, 0xa6, 0x6a, 0x27, 0x75, 0xea, 0x66, 0x5a, 0x52, 0x64, 0x65, 0x55, 0x95,
 	0xcc, 0x01, 0x15, 0x77, 0x7c, 0xe2, 0x80, 0xbb, 0x10, 0xb9, 0xa3, 0xe5, 0x62, 0x0b, 0x60, 0x99,
 	0xcc, 0x01, 0x15, 0x77, 0x7c, 0xe2, 0x80, 0xbb, 0x10, 0xb9, 0xa3, 0xe5, 0x62, 0x0b, 0x60, 0x99,
-	0xe1, 0xad, 0xc7, 0x8c, 0xcf, 0xbd, 0x6a, 0x7a, 0xe8, 0x6f, 0xe8, 0x7f, 0xf0, 0xb1, 0xc7, 0x9e,
-	0x34, 0x0d, 0xff, 0x42, 0x7f, 0x40, 0x3b, 0xc0, 0x82, 0xe4, 0x32, 0x59, 0xc5, 0x9e, 0xa9, 0x6f,
-	0xc0, 0xdb, 0xef, 0x7b, 0x78, 0x78, 0xf8, 0xf0, 0xf0, 0x16, 0x6c, 0x11, 0x51, 0x57, 0xb4, 0x22,
-	0xce, 0x24, 0x43, 0xc8, 0x63, 0xee, 0x35, 0xe5, 0x2d, 0xf1, 0x15, 0xe1, 0xd3, 0x6b, 0x5f, 0xb6,
-	0x66, 0x3f, 0xaf, 0xda, 0x72, 0x1e, 0x51, 0x03, 0xa8, 0xbe, 0x37, 0x66, 0x63, 0xa6, 0x87, 0x87,
-	0x6a, 0x64, 0xac, 0xb5, 0x31, 0x63, 0xe3, 0x80, 0x1e, 0xea, 0xd9, 0x28, 0xbe, 0x3a, 0xf4, 0x62,
-	0x4e, 0xa4, 0xcf, 0xc2, 0xe4, 0x7b, 0xf3, 0xa6, 0x00, 0xd6, 0x05, 0xf3, 0xe8, 0x20, 0xa2, 0x2e,
-	0x3a, 0x01, 0x9b, 0x84, 0x21, 0x93, 0x1a, 0x20, 0x9c, 0x7c, 0x23, 0x7f, 0x60, 0x1f, 0xd5, 0x5b,
-	0xdf, 0x5d, 0xb9, 0xd5, 0x5e, 0xc3, 0x3a, 0x85, 0xd7, 0xb7, 0xf5, 0x1c, 0x4e, 0x33, 0xd1, 0x6f,
-	0xa1, 0xec, 0x51, 0xe1, 0x73, 0xea, 0x0d, 0x39, 0x0b, 0xa8, 0xb3, 0xd5, 0xc8, 0x1f, 0xdc, 0x3b,
-	0xfa, 0x51, 0x96, 0x27, 0xb5, 0x38, 0x66, 0x01, 0xc5, 0xb6, 0x61, 0xa8, 0x09, 0x3a, 0x01, 0x98,
-	0xd2, 0xe9, 0x88, 0x72, 0x31, 0xf1, 0x23, 0x67, 0x5b, 0xd3, 0x7f, 0x72, 0x17, 0x5d, 0xc5, 0xde,
-	0x3a, 0x5f, 0xc1, 0x71, 0x8a, 0x8a, 0xce, 0xa1, 0x4c, 0x66, 0xc4, 0x0f, 0xc8, 0xc8, 0x0f, 0x7c,
-	0x39, 0x77, 0x0a, 0xda, 0xd5, 0x27, 0xdf, 0xeb, 0xaa, 0x9d, 0x22, 0xe0, 0x0d, 0x7a, 0xd3, 0x03,
-	0x58, 0x2f, 0x84, 0x3e, 0x86, 0xdd, 0x7e, 0xef, 0xa2, 0x7b, 0x7a, 0x71, 0x52, 0xc9, 0x55, 0x1f,
-	0xbc, 0xba, 0x69, 0xbc, 0xaf, 0x7c, 0xac, 0x01, 0x7d, 0x1a, 0x7a, 0x7e, 0x38, 0x46, 0x07, 0x60,
-	0xb5, 0x8f, 0x8f, 0x7b, 0xfd, 0xcb, 0x5e, 0xb7, 0x92, 0xaf, 0x56, 0x5f, 0xdd, 0x34, 0x3e, 0xd8,
-	0x04, 0xb6, 0x5d, 0x97, 0x46, 0x92, 0x7a, 0xd5, 0xc2, 0xd7, 0x7f, 0xaf, 0xe5, 0x9a, 0x5f, 0xe7,
-	0xa1, 0x9c, 0x0e, 0x02, 0x7d, 0x0c, 0xc5, 0xf6, 0xf1, 0xe5, 0xe9, 0x8b, 0x5e, 0x25, 0xb7, 0xa6,
-	0xa7, 0x11, 0x6d, 0x57, 0xfa, 0x33, 0x8a, 0x1e, 0xc3, 0x4e, 0xbf, 0xfd, 0xe5, 0xa0, 0x57, 0xc9,
-	0xaf, 0xc3, 0x49, 0xc3, 0xfa, 0x24, 0x16, 0x1a, 0xd5, 0xc5, 0xed, 0xd3, 0x8b, 0xca, 0x56, 0x36,
-	0xaa, 0xcb, 0x89, 0x1f, 0x9a, 0x50, 0xfe, 0x56, 0x00, 0x7b, 0x40, 0xf9, 0xcc, 0x77, 0xdf, 0xb1,
-	0x44, 0x3e, 0x83, 0x82, 0x24, 0xe2, 0x5a, 0x4b, 0xc3, 0xce, 0x96, 0xc6, 0x25, 0x11, 0xd7, 0x6a,
-	0x51, 0x43, 0xd7, 0x78, 0xa5, 0x0c, 0x4e, 0xa3, 0xc0, 0x77, 0x89, 0xa4, 0x9e, 0x56, 0x86, 0x7d,
-	0xf4, 0xe3, 0x2c, 0x36, 0x5e, 0xa1, 0x4c, 0xfc, 0xcf, 0x72, 0x38, 0x45, 0x45, 0x4f, 0xa1, 0x38,
-	0x0e, 0xd8, 0x88, 0x04, 0x5a, 0x13, 0xf6, 0xd1, 0xa3, 0x2c, 0x27, 0x27, 0x1a, 0xb1, 0x76, 0x60,
-	0x28, 0xe8, 0x09, 0x14, 0xe3, 0xc8, 0x23, 0x92, 0x3a, 0x45, 0x4d, 0x6e, 0x64, 0x91, 0xbf, 0xd4,
-	0x88, 0x63, 0x16, 0x5e, 0xf9, 0x63, 0x6c, 0xf0, 0xe8, 0x0c, 0xac, 0x90, 0xca, 0xaf, 0x18, 0xbf,
-	0x16, 0xce, 0x6e, 0x63, 0xfb, 0xc0, 0x3e, 0xfa, 0x34, 0x53, 0x8c, 0x09, 0xa6, 0x2d, 0x25, 0x71,
-	0x27, 0x53, 0x1a, 0xca, 0xc4, 0x4d, 0x67, 0xcb, 0xc9, 0xe3, 0x95, 0x03, 0xf4, 0x1b, 0xb0, 0x68,
-	0xe8, 0x45, 0xcc, 0x0f, 0xa5, 0x63, 0xdd, 0x1d, 0x48, 0xcf, 0x60, 0x54, 0x32, 0xf1, 0x8a, 0xa1,
-	0xd8, 0x9c, 0x05, 0xc1, 0x88, 0xb8, 0xd7, 0x4e, 0xe9, 0x2d, 0xb7, 0xb1, 0x62, 0x74, 0x8a, 0x50,
-	0x98, 0x32, 0x8f, 0x36, 0x0f, 0x61, 0xff, 0x3b, 0xa9, 0x46, 0x55, 0xb0, 0x4c, 0xaa, 0x13, 0x8d,
-	0x14, 0xf0, 0x6a, 0xde, 0xbc, 0x0f, 0x7b, 0x1b, 0x69, 0x6d, 0xbe, 0x2e, 0x80, 0xb5, 0x3c, 0x6b,
-	0xd4, 0x86, 0x92, 0xcb, 0x42, 0x49, 0xfc, 0x90, 0x72, 0x23, 0xaf, 0xcc, 0x93, 0x39, 0x5e, 0x82,
-	0x14, 0xeb, 0x59, 0x0e, 0xaf, 0x59, 0xe8, 0xf7, 0x50, 0xe2, 0x54, 0xb0, 0x98, 0xbb, 0x54, 0x18,
-	0x7d, 0x1d, 0x64, 0x2b, 0x24, 0x01, 0x61, 0xfa, 0xe7, 0xd8, 0xe7, 0x54, 0x65, 0x59, 0xe0, 0x35,
-	0x15, 0x3d, 0x85, 0x5d, 0x4e, 0x85, 0x24, 0x5c, 0x7e, 0x9f, 0x44, 0x70, 0x02, 0xe9, 0xb3, 0xc0,
-	0x77, 0xe7, 0x78, 0xc9, 0x40, 0x4f, 0xa1, 0x14, 0x05, 0xc4, 0xd5, 0x5e, 0x9d, 0x1d, 0x4d, 0xff,
-	0x30, 0x8b, 0xde, 0x5f, 0x82, 0xf0, 0x1a, 0x8f, 0x3e, 0x07, 0x08, 0xd8, 0x78, 0xe8, 0x71, 0x7f,
-	0x46, 0xb9, 0x91, 0x58, 0x35, 0x8b, 0xdd, 0xd5, 0x08, 0x5c, 0x0a, 0xd8, 0x38, 0x19, 0xa2, 0x93,
-	0xff, 0x4b, 0x5f, 0x29, 0x6d, 0x9d, 0x01, 0x90, 0xd5, 0x57, 0xa3, 0xae, 0x4f, 0xde, 0xca, 0x95,
-	0x39, 0x91, 0x14, 0x1d, 0x3d, 0x82, 0xf2, 0x15, 0xe3, 0x2e, 0x1d, 0x9a, 0x5b, 0x53, 0xd2, 0x9a,
-	0xb0, 0xb5, 0x2d, 0xd1, 0x97, 0xba, 0x52, 0x51, 0x10, 0x8f, 0xfd, 0xd0, 0x01, 0xbd, 0x56, 0x2d,
-	0x3b, 0x5b, 0x0a, 0x61, 0x16, 0x30, 0xf8, 0x4e, 0x09, 0x76, 0x79, 0x1c, 0x4a, 0x7f, 0x4a, 0x9b,
-	0x67, 0xf0, 0x7e, 0x66, 0x38, 0xe8, 0x08, 0xca, 0x2b, 0x81, 0x0c, 0x7d, 0x4f, 0x2b, 0xab, 0xd4,
-	0xb9, 0xbf, 0xb8, 0xad, 0xdb, 0x2b, 0x25, 0x9d, 0x76, 0xb1, 0xbd, 0x02, 0x9d, 0x7a, 0xcd, 0xbf,
-	0x5a, 0xb0, 0xb7, 0x21, 0x33, 0xf4, 0x1e, 0xec, 0xf8, 0x53, 0x32, 0xa6, 0x09, 0x1d, 0x27, 0x13,
-	0xd4, 0x83, 0x62, 0x40, 0x46, 0x34, 0x50, 0x62, 0x53, 0x09, 0xff, 0xd9, 0x1b, 0xf5, 0xda, 0xfa,
-	0xa3, 0xc6, 0xf7, 0x42, 0xc9, 0xe7, 0xd8, 0x90, 0x91, 0x03, 0xbb, 0x2e, 0x9b, 0x4e, 0x49, 0xa8,
-	0xca, 0xda, 0xf6, 0x41, 0x09, 0x2f, 0xa7, 0x08, 0x41, 0x81, 0xf0, 0xb1, 0x70, 0x0a, 0xda, 0xac,
-	0xc7, 0xa8, 0x02, 0xdb, 0x34, 0x9c, 0x39, 0x3b, 0xda, 0xa4, 0x86, 0xca, 0xe2, 0xf9, 0x89, 0x5a,
-	0x4a, 0x58, 0x0d, 0x15, 0x2f, 0x16, 0x94, 0x3b, 0xbb, 0xda, 0xa4, 0xc7, 0xe8, 0x57, 0x50, 0x9c,
-	0xb2, 0x38, 0x94, 0xc2, 0xb1, 0x74, 0xb0, 0x0f, 0xb2, 0x82, 0x3d, 0x57, 0x08, 0x53, 0x76, 0x0d,
-	0x1c, 0xf5, 0x60, 0x5f, 0x48, 0x16, 0x0d, 0xc7, 0x9c, 0xb8, 0x74, 0x18, 0x51, 0xee, 0x33, 0xcf,
-	0x94, 0x8d, 0x07, 0xad, 0xa4, 0xcb, 0x68, 0x2d, 0xbb, 0x8c, 0x56, 0xd7, 0x74, 0x19, 0xf8, 0xbe,
-	0xe2, 0x9c, 0x28, 0x4a, 0x5f, 0x33, 0x50, 0x1f, 0xca, 0x51, 0x1c, 0x04, 0x43, 0x16, 0x25, 0x2f,
-	0x48, 0x72, 0xd8, 0x6f, 0x91, 0xb2, 0x7e, 0x1c, 0x04, 0xcf, 0x13, 0x12, 0xb6, 0xa3, 0xf5, 0x04,
-	0x7d, 0x00, 0xc5, 0x31, 0x67, 0x71, 0x24, 0x1c, 0x5b, 0x27, 0xc3, 0xcc, 0xd0, 0x17, 0xb0, 0x2b,
-	0xa8, 0xcb, 0xa9, 0x14, 0x4e, 0x59, 0x6f, 0xf5, 0xa3, 0xac, 0x45, 0x06, 0x1a, 0x82, 0xe9, 0x15,
-	0xe5, 0x34, 0x74, 0x29, 0x5e, 0x72, 0xd0, 0x03, 0xd8, 0x96, 0x72, 0xee, 0xec, 0x35, 0xf2, 0x07,
-	0x56, 0x67, 0x77, 0x71, 0x5b, 0xdf, 0xbe, 0xbc, 0x7c, 0x89, 0x95, 0x4d, 0x55, 0xb7, 0x09, 0x13,
-	0x32, 0x24, 0x53, 0xea, 0xdc, 0xd3, 0xb9, 0x5d, 0xcd, 0xd1, 0x4b, 0x00, 0x2f, 0x14, 0x43, 0x57,
-	0x5f, 0x27, 0xe7, 0xbe, 0xde, 0xdd, 0xa7, 0x6f, 0xde, 0x5d, 0xf7, 0x62, 0x60, 0x2a, 0xfc, 0xde,
-	0xe2, 0xb6, 0x5e, 0x5a, 0x4d, 0x71, 0xc9, 0x0b, 0x45, 0x32, 0x44, 0x1d, 0xb0, 0x27, 0x94, 0x04,
-	0x72, 0xe2, 0x4e, 0xa8, 0x7b, 0xed, 0x54, 0xee, 0x2e, 0xd9, 0xcf, 0x34, 0xcc, 0x78, 0x48, 0x93,
-	0x94, 0x82, 0x55, 0xa8, 0xc2, 0xd9, 0xd7, 0xb9, 0x4a, 0x26, 0xe8, 0x43, 0x00, 0x16, 0xd1, 0x70,
-	0x28, 0xa4, 0xe7, 0x87, 0x0e, 0x52, 0x5b, 0xc6, 0x25, 0x65, 0x19, 0x28, 0x03, 0x7a, 0xa8, 0x0a,
-	0x2a, 0xf1, 0x86, 0x2c, 0x0c, 0xe6, 0xce, 0x0f, 0xf4, 0x57, 0x4b, 0x19, 0x9e, 0x87, 0xc1, 0x1c,
-	0xd5, 0xc1, 0xd6, 0xba, 0x10, 0xfe, 0x38, 0x24, 0x81, 0xf3, 0x9e, 0xce, 0x07, 0x28, 0xd3, 0x40,
-	0x5b, 0xaa, 0x9f, 0x83, 0x9d, 0x92, 0xbb, 0x92, 0xe9, 0x35, 0x9d, 0x9b, 0x1b, 0xa4, 0x86, 0x2a,
-	0xa6, 0x19, 0x09, 0xe2, 0xa4, 0x4d, 0x2c, 0xe1, 0x64, 0xf2, 0xeb, 0xad, 0x27, 0xf9, 0xea, 0x11,
-	0xd8, 0xa9, 0x63, 0x47, 0x1f, 0xc1, 0x1e, 0xa7, 0x63, 0x5f, 0x48, 0x3e, 0x1f, 0x92, 0x58, 0x4e,
-	0x9c, 0xdf, 0x69, 0x42, 0x79, 0x69, 0x6c, 0xc7, 0x72, 0x52, 0x1d, 0xc2, 0x3a, 0x7b, 0xa8, 0x01,
-	0xb6, 0x3a, 0x15, 0x41, 0xf9, 0x8c, 0x72, 0xf5, 0x14, 0xa9, 0x4d, 0xa7, 0x4d, 0x4a, 0x3d, 0x82,
-	0x12, 0xee, 0x4e, 0xf4, 0xe5, 0x2d, 0x61, 0x33, 0x53, 0xb7, 0x71, 0x29, 0x51, 0x73, 0x1b, 0xcd,
-	0xb4, 0xd9, 0x04, 0x58, 0x97, 0xa1, 0xec, 0x92, 0xd0, 0xfc, 0x4f, 0x1e, 0xca, 0xe9, 0x57, 0x17,
-	0x1d, 0x27, 0xaf, 0xa5, 0x46, 0xdd, 0x3b, 0x3a, 0x7c, 0xd3, 0x2b, 0xad, 0xdf, 0xa6, 0x20, 0x56,
-	0x0b, 0x9e, 0xab, 0x06, 0x59, 0x93, 0xd1, 0x2f, 0x61, 0x27, 0x62, 0x5c, 0x2e, 0xeb, 0x4c, 0x76,
-	0x85, 0x64, 0x7c, 0x59, 0xcb, 0x13, 0x70, 0x73, 0x02, 0xf7, 0x36, 0xbd, 0xa1, 0xc7, 0xb0, 0xfd,
-	0xe2, 0xb4, 0x5f, 0xc9, 0x55, 0x1f, 0xbe, 0xba, 0x69, 0xfc, 0x70, 0xf3, 0xe3, 0x0b, 0x9f, 0xcb,
-	0x98, 0x04, 0xa7, 0x7d, 0xf4, 0x53, 0xd8, 0xe9, 0x5e, 0x0c, 0x30, 0xae, 0xe4, 0xab, 0xf5, 0x57,
-	0x37, 0x8d, 0x87, 0x9b, 0x38, 0xf5, 0x89, 0xc5, 0xa1, 0x87, 0xd9, 0x68, 0xd5, 0x2c, 0xfe, 0x63,
-	0x0b, 0x6c, 0x53, 0x7e, 0xdf, 0xf5, 0xff, 0xc4, 0x5e, 0xf2, 0x16, 0x2e, 0xef, 0xd5, 0xd6, 0x1b,
-	0x9f, 0xc4, 0x72, 0x42, 0x30, 0x3a, 0x78, 0x04, 0x65, 0x3f, 0x9a, 0x7d, 0x36, 0xa4, 0x21, 0x19,
-	0x05, 0xa6, 0x6f, 0xb4, 0xb0, 0xad, 0x6c, 0xbd, 0xc4, 0xa4, 0x2e, 0xb5, 0x1f, 0x4a, 0xca, 0x43,
-	0xd3, 0x11, 0x5a, 0x78, 0x35, 0x47, 0x5f, 0x40, 0xc1, 0x8f, 0xc8, 0xd4, 0xbc, 0xe3, 0x99, 0x3b,
-	0x38, 0xed, 0xb7, 0xcf, 0x8d, 0x4e, 0x3b, 0xd6, 0xe2, 0xb6, 0x5e, 0x50, 0x06, 0xac, 0x69, 0xa8,
-	0xb6, 0x7c, 0x4a, 0xd5, 0x4a, 0xba, 0x40, 0x5b, 0x38, 0x65, 0x69, 0xfe, 0xb7, 0x00, 0xf6, 0x71,
-	0x10, 0x0b, 0x69, 0x9e, 0x99, 0x77, 0x96, 0xb7, 0x97, 0xb0, 0x4f, 0xf4, 0xaf, 0x05, 0x09, 0x55,
-	0xcd, 0xd6, 0x2d, 0x8a, 0xc9, 0xdd, 0xe3, 0x4c, 0x77, 0x2b, 0x70, 0xd2, 0xce, 0x74, 0x8a, 0xca,
-	0xa7, 0x93, 0xc7, 0x15, 0xf2, 0xad, 0x2f, 0x68, 0x00, 0x7b, 0x8c, 0xbb, 0x13, 0x2a, 0x64, 0x52,
-	0xe9, 0x4d, 0x2b, 0x9e, 0xf9, 0x93, 0xf6, 0x3c, 0x0d, 0x34, 0x65, 0x2e, 0x89, 0x76, 0xd3, 0x07,
-	0x7a, 0x02, 0x05, 0x4e, 0xae, 0x96, 0xed, 0x56, 0xa6, 0xbe, 0x31, 0xb9, 0x92, 0x1b, 0x2e, 0x34,
-	0x03, 0xfd, 0x01, 0xc0, 0xf3, 0x45, 0x44, 0xa4, 0x3b, 0xa1, 0xdc, 0x9c, 0x53, 0xe6, 0x16, 0xbb,
-	0x2b, 0xd4, 0x86, 0x97, 0x14, 0x1b, 0x9d, 0x41, 0xc9, 0x25, 0x4b, 0xa5, 0x15, 0xef, 0xfe, 0x3f,
-	0x39, 0x6e, 0x1b, 0x17, 0x15, 0xe5, 0x62, 0x71, 0x5b, 0xb7, 0x96, 0x16, 0x6c, 0xb9, 0xc4, 0x28,
-	0xef, 0x0c, 0xf6, 0xd4, 0x7f, 0xcb, 0xd0, 0xa3, 0x57, 0x24, 0x0e, 0xa4, 0xd0, 0x8f, 0xf1, 0x1d,
-	0x65, 0x5b, 0x35, 0xc1, 0x5d, 0x83, 0x33, 0x71, 0x95, 0x65, 0xca, 0x86, 0xfe, 0x04, 0xfb, 0x34,
-	0x74, 0xf9, 0x5c, 0xeb, 0x6c, 0x19, 0xa1, 0x75, 0xf7, 0x66, 0x7b, 0x2b, 0xf0, 0xc6, 0x66, 0x2b,
-	0xf4, 0x5b, 0xf6, 0xa6, 0x0f, 0x90, 0x3c, 0x84, 0xef, 0x56, 0x7f, 0x08, 0x0a, 0x1e, 0x91, 0x44,
-	0x4b, 0xae, 0x8c, 0xf5, 0xb8, 0xe3, 0xbc, 0xfe, 0xa6, 0x96, 0xfb, 0xd7, 0x37, 0xb5, 0xdc, 0x5f,
-	0x16, 0xb5, 0xfc, 0xeb, 0x45, 0x2d, 0xff, 0xcf, 0x45, 0x2d, 0xff, 0xef, 0x45, 0x2d, 0x3f, 0x2a,
-	0xea, 0xf6, 0xe1, 0x17, 0xff, 0x0b, 0x00, 0x00, 0xff, 0xff, 0x91, 0xbf, 0x5e, 0xca, 0xf8, 0x10,
-	0x00, 0x00,
+	0xe1, 0xad, 0xc7, 0x8c, 0x0f, 0x3d, 0xf5, 0xaa, 0xe9, 0xa1, 0xbf, 0xa1, 0xff, 0xc1, 0xc7, 0x1e,
+	0x7b, 0xd2, 0x34, 0xfc, 0x0b, 0xfd, 0x01, 0xed, 0x00, 0x0b, 0x92, 0xcb, 0x64, 0x15, 0x7b, 0x26,
+	0xbe, 0xe1, 0xbd, 0xfd, 0xbe, 0x07, 0xe0, 0xe1, 0xc3, 0xc3, 0x5b, 0xb0, 0x45, 0x44, 0x5d, 0xd1,
+	0x8a, 0x38, 0x93, 0x0c, 0x21, 0x8f, 0xb9, 0x57, 0x94, 0xb7, 0xc4, 0x97, 0x84, 0x4f, 0xaf, 0x7c,
+	0xd9, 0x9a, 0xfd, 0xbc, 0x6a, 0xcb, 0x79, 0x44, 0x0d, 0xa0, 0x7a, 0x7f, 0xcc, 0xc6, 0x4c, 0x0f,
+	0x0f, 0xd4, 0xc8, 0x78, 0x6b, 0x63, 0xc6, 0xc6, 0x01, 0x3d, 0xd0, 0xd6, 0x28, 0xbe, 0x3c, 0xf0,
+	0x62, 0x4e, 0xa4, 0xcf, 0xc2, 0xe4, 0x7b, 0xf3, 0xba, 0x00, 0xd6, 0x39, 0xf3, 0xe8, 0x20, 0xa2,
+	0x2e, 0x3a, 0x06, 0x9b, 0x84, 0x21, 0x93, 0x1a, 0x20, 0x9c, 0x7c, 0x23, 0xbf, 0x6f, 0x1f, 0xd6,
+	0x5b, 0xdf, 0x9e, 0xb9, 0xd5, 0x5e, 0xc3, 0x3a, 0x85, 0xd7, 0x37, 0xf5, 0x1c, 0x4e, 0x33, 0xd1,
+	0x6f, 0xa1, 0xec, 0x51, 0xe1, 0x73, 0xea, 0x0d, 0x39, 0x0b, 0xa8, 0xb3, 0xd5, 0xc8, 0xef, 0xdf,
+	0x39, 0xfc, 0x51, 0x56, 0x24, 0x35, 0x39, 0x66, 0x01, 0xc5, 0xb6, 0x61, 0x28, 0x03, 0x1d, 0x03,
+	0x4c, 0xe9, 0x74, 0x44, 0xb9, 0x98, 0xf8, 0x91, 0xb3, 0xad, 0xe9, 0x3f, 0xb9, 0x8d, 0xae, 0xd6,
+	0xde, 0x3a, 0x5b, 0xc1, 0x71, 0x8a, 0x8a, 0xce, 0xa0, 0x4c, 0x66, 0xc4, 0x0f, 0xc8, 0xc8, 0x0f,
+	0x7c, 0x39, 0x77, 0x0a, 0x3a, 0xd4, 0xc7, 0xdf, 0x19, 0xaa, 0x9d, 0x22, 0xe0, 0x0d, 0x7a, 0xd3,
+	0x03, 0x58, 0x4f, 0x84, 0x3e, 0x82, 0xdd, 0x7e, 0xef, 0xbc, 0x7b, 0x72, 0x7e, 0x5c, 0xc9, 0x55,
+	0x1f, 0xbc, 0xba, 0x6e, 0xbc, 0xa7, 0x62, 0xac, 0x01, 0x7d, 0x1a, 0x7a, 0x7e, 0x38, 0x46, 0xfb,
+	0x60, 0xb5, 0x8f, 0x8e, 0x7a, 0xfd, 0x8b, 0x5e, 0xb7, 0x92, 0xaf, 0x56, 0x5f, 0x5d, 0x37, 0xde,
+	0xdf, 0x04, 0xb6, 0x5d, 0x97, 0x46, 0x92, 0x7a, 0xd5, 0xc2, 0x57, 0xff, 0xa8, 0xe5, 0x9a, 0x5f,
+	0xe5, 0xa1, 0x9c, 0x5e, 0x04, 0xfa, 0x08, 0x8a, 0xed, 0xa3, 0x8b, 0x93, 0x17, 0xbd, 0x4a, 0x6e,
+	0x4d, 0x4f, 0x23, 0xda, 0xae, 0xf4, 0x67, 0x14, 0x3d, 0x86, 0x9d, 0x7e, 0xfb, 0x8b, 0x41, 0xaf,
+	0x92, 0x5f, 0x2f, 0x27, 0x0d, 0xeb, 0x93, 0x58, 0x68, 0x54, 0x17, 0xb7, 0x4f, 0xce, 0x2b, 0x5b,
+	0xd9, 0xa8, 0x2e, 0x27, 0x7e, 0x68, 0x96, 0xf2, 0xf7, 0x02, 0xd8, 0x03, 0xca, 0x67, 0xbe, 0xfb,
+	0x8e, 0x25, 0xf2, 0x29, 0x14, 0x24, 0x11, 0x57, 0x5a, 0x1a, 0x76, 0xb6, 0x34, 0x2e, 0x88, 0xb8,
+	0x52, 0x93, 0x1a, 0xba, 0xc6, 0x2b, 0x65, 0x70, 0x1a, 0x05, 0xbe, 0x4b, 0x24, 0xf5, 0xb4, 0x32,
+	0xec, 0xc3, 0x1f, 0x67, 0xb1, 0xf1, 0x0a, 0x65, 0xd6, 0xff, 0x2c, 0x87, 0x53, 0x54, 0xf4, 0x14,
+	0x8a, 0xe3, 0x80, 0x8d, 0x48, 0xa0, 0x35, 0x61, 0x1f, 0x3e, 0xca, 0x0a, 0x72, 0xac, 0x11, 0xeb,
+	0x00, 0x86, 0x82, 0x9e, 0x40, 0x31, 0x8e, 0x3c, 0x22, 0xa9, 0x53, 0xd4, 0xe4, 0x46, 0x16, 0xf9,
+	0x0b, 0x8d, 0x38, 0x62, 0xe1, 0xa5, 0x3f, 0xc6, 0x06, 0x8f, 0x4e, 0xc1, 0x0a, 0xa9, 0xfc, 0x92,
+	0xf1, 0x2b, 0xe1, 0xec, 0x36, 0xb6, 0xf7, 0xed, 0xc3, 0x4f, 0x32, 0xc5, 0x98, 0x60, 0xda, 0x52,
+	0x12, 0x77, 0x32, 0xa5, 0xa1, 0x4c, 0xc2, 0x74, 0xb6, 0x9c, 0x3c, 0x5e, 0x05, 0x40, 0xbf, 0x01,
+	0x8b, 0x86, 0x5e, 0xc4, 0xfc, 0x50, 0x3a, 0xd6, 0xed, 0x0b, 0xe9, 0x19, 0x8c, 0x4a, 0x26, 0x5e,
+	0x31, 0x14, 0x9b, 0xb3, 0x20, 0x18, 0x11, 0xf7, 0xca, 0x29, 0xbd, 0xe5, 0x36, 0x56, 0x8c, 0x4e,
+	0x11, 0x0a, 0x53, 0xe6, 0xd1, 0xe6, 0x01, 0xdc, 0xfb, 0x56, 0xaa, 0x51, 0x15, 0x2c, 0x93, 0xea,
+	0x44, 0x23, 0x05, 0xbc, 0xb2, 0x9b, 0x77, 0x61, 0x6f, 0x23, 0xad, 0xcd, 0xbf, 0x16, 0xc0, 0x5a,
+	0x9e, 0x35, 0x6a, 0x43, 0xc9, 0x65, 0xa1, 0x24, 0x7e, 0x48, 0xb9, 0x91, 0x57, 0xe6, 0xc9, 0x1c,
+	0x2d, 0x41, 0x8a, 0xf5, 0x2c, 0x87, 0xd7, 0x2c, 0xf4, 0x7b, 0x28, 0x71, 0x2a, 0x58, 0xcc, 0x5d,
+	0x2a, 0x8c, 0xbe, 0xf6, 0xb3, 0x15, 0x92, 0x80, 0x30, 0xfd, 0x73, 0xec, 0x73, 0xaa, 0xb2, 0x2c,
+	0xf0, 0x9a, 0x8a, 0x9e, 0xc2, 0x2e, 0xa7, 0x42, 0x12, 0x2e, 0xbf, 0x4b, 0x22, 0x38, 0x81, 0xf4,
+	0x59, 0xe0, 0xbb, 0x73, 0xbc, 0x64, 0xa0, 0xa7, 0x50, 0x8a, 0x02, 0xe2, 0xea, 0xa8, 0xce, 0x8e,
+	0xa6, 0x7f, 0x90, 0x45, 0xef, 0x2f, 0x41, 0x78, 0x8d, 0x47, 0x9f, 0x01, 0x04, 0x6c, 0x3c, 0xf4,
+	0xb8, 0x3f, 0xa3, 0xdc, 0x48, 0xac, 0x9a, 0xc5, 0xee, 0x6a, 0x04, 0x2e, 0x05, 0x6c, 0x9c, 0x0c,
+	0xd1, 0xf1, 0xf7, 0xd2, 0x57, 0x4a, 0x5b, 0xa7, 0x00, 0x64, 0xf5, 0xd5, 0xa8, 0xeb, 0xe3, 0xb7,
+	0x0a, 0x65, 0x4e, 0x24, 0x45, 0x47, 0x8f, 0xa0, 0x7c, 0xc9, 0xb8, 0x4b, 0x87, 0xe6, 0xd6, 0x94,
+	0xb4, 0x26, 0x6c, 0xed, 0x4b, 0xf4, 0xd5, 0x29, 0xc1, 0x2e, 0x8f, 0x43, 0xe9, 0x4f, 0x69, 0xf3,
+	0x14, 0xde, 0xcb, 0x0c, 0x8a, 0x0e, 0xa1, 0xbc, 0x3a, 0xe6, 0xa1, 0xef, 0x69, 0x7d, 0x94, 0x3a,
+	0x77, 0x17, 0x37, 0x75, 0x7b, 0xa5, 0x87, 0x93, 0x2e, 0xb6, 0x57, 0xa0, 0x13, 0xaf, 0xf9, 0x37,
+	0x0b, 0xf6, 0x36, 0xc4, 0x82, 0xee, 0xc3, 0x8e, 0x3f, 0x25, 0x63, 0x9a, 0xd0, 0x71, 0x62, 0xa0,
+	0x1e, 0x14, 0x03, 0x32, 0xa2, 0x81, 0x92, 0x8c, 0x4a, 0xdb, 0xcf, 0xde, 0xa8, 0xba, 0xd6, 0x1f,
+	0x35, 0xbe, 0x17, 0x4a, 0x3e, 0xc7, 0x86, 0x8c, 0x1c, 0xd8, 0x75, 0xd9, 0x74, 0x4a, 0x42, 0x55,
+	0x9c, 0xb6, 0xf7, 0x4b, 0x78, 0x69, 0x22, 0x04, 0x05, 0xc2, 0xc7, 0xc2, 0x29, 0x68, 0xb7, 0x1e,
+	0xa3, 0x0a, 0x6c, 0xd3, 0x70, 0xe6, 0xec, 0x68, 0x97, 0x1a, 0x2a, 0x8f, 0xe7, 0x27, 0x67, 0x5e,
+	0xc2, 0x6a, 0xa8, 0x78, 0xb1, 0xa0, 0xdc, 0xd9, 0xd5, 0x2e, 0x3d, 0x46, 0xbf, 0x82, 0xe2, 0x94,
+	0xc5, 0xa1, 0x14, 0x8e, 0xa5, 0x17, 0xfb, 0x20, 0x6b, 0xb1, 0x67, 0x0a, 0x61, 0x8a, 0xa7, 0x81,
+	0xa3, 0x1e, 0xdc, 0x13, 0x92, 0x45, 0xc3, 0x31, 0x27, 0x2e, 0x1d, 0x46, 0x94, 0xfb, 0xcc, 0x33,
+	0x97, 0xff, 0x41, 0x2b, 0xe9, 0x15, 0x5a, 0xcb, 0x5e, 0xa1, 0xd5, 0x35, 0xbd, 0x02, 0xbe, 0xab,
+	0x38, 0xc7, 0x8a, 0xd2, 0xd7, 0x0c, 0xd4, 0x87, 0x72, 0x14, 0x07, 0xc1, 0x90, 0x45, 0xc9, 0x3b,
+	0x00, 0x3a, 0xc2, 0x5b, 0xa4, 0xac, 0x1f, 0x07, 0xc1, 0xf3, 0x84, 0x84, 0xed, 0x68, 0x6d, 0xa0,
+	0xf7, 0xa1, 0x38, 0xe6, 0x2c, 0x8e, 0x84, 0x63, 0xeb, 0x64, 0x18, 0x0b, 0x7d, 0x0e, 0xbb, 0x82,
+	0xba, 0x9c, 0x4a, 0xe1, 0x94, 0xf5, 0x56, 0x3f, 0xcc, 0x9a, 0x64, 0xa0, 0x21, 0x98, 0x5e, 0x52,
+	0x4e, 0x43, 0x97, 0xe2, 0x25, 0x07, 0x3d, 0x80, 0x6d, 0x29, 0xe7, 0xce, 0x5e, 0x23, 0xbf, 0x6f,
+	0x75, 0x76, 0x17, 0x37, 0xf5, 0xed, 0x8b, 0x8b, 0x97, 0x58, 0xf9, 0x54, 0x8d, 0x9a, 0x30, 0x21,
+	0x43, 0x32, 0xa5, 0xce, 0x1d, 0x9d, 0xdb, 0x95, 0x8d, 0x5e, 0x02, 0x78, 0xa1, 0x18, 0xba, 0xfa,
+	0x52, 0x38, 0x77, 0xf5, 0xee, 0x3e, 0x79, 0xf3, 0xee, 0xba, 0xe7, 0x03, 0x53, 0xa7, 0xf7, 0x16,
+	0x37, 0xf5, 0xd2, 0xca, 0xc4, 0x25, 0x2f, 0x14, 0xc9, 0x10, 0x75, 0xc0, 0x9e, 0x50, 0x12, 0xc8,
+	0x89, 0x3b, 0xa1, 0xee, 0x95, 0x53, 0xb9, 0xbd, 0xf0, 0x3e, 0xd3, 0x30, 0x13, 0x21, 0x4d, 0x52,
+	0x0a, 0x56, 0x4b, 0x15, 0xce, 0x3d, 0x9d, 0xab, 0xc4, 0x40, 0x1f, 0x00, 0xb0, 0x88, 0x86, 0x43,
+	0x21, 0x3d, 0x3f, 0x74, 0x90, 0xda, 0x32, 0x2e, 0x29, 0xcf, 0x40, 0x39, 0xd0, 0x43, 0x55, 0x16,
+	0x89, 0x37, 0x64, 0x61, 0x30, 0x77, 0x7e, 0xa0, 0xbf, 0x5a, 0xca, 0xf1, 0x3c, 0x0c, 0xe6, 0xa8,
+	0x0e, 0xb6, 0xd6, 0x85, 0xf0, 0xc7, 0x21, 0x09, 0x9c, 0xfb, 0x3a, 0x1f, 0xa0, 0x5c, 0x03, 0xed,
+	0xa9, 0x7e, 0x06, 0x76, 0x4a, 0xee, 0x4a, 0xa6, 0x57, 0x74, 0x6e, 0x6e, 0x90, 0x1a, 0xaa, 0x35,
+	0xcd, 0x48, 0x10, 0x27, 0xcd, 0x5e, 0x09, 0x27, 0xc6, 0xaf, 0xb7, 0x9e, 0xe4, 0xab, 0x87, 0x60,
+	0xa7, 0x8e, 0x1d, 0x7d, 0x08, 0x7b, 0x9c, 0x8e, 0x7d, 0x21, 0xf9, 0x7c, 0x48, 0x62, 0x39, 0x71,
+	0x7e, 0xa7, 0x09, 0xe5, 0xa5, 0xb3, 0x1d, 0xcb, 0x49, 0x75, 0x08, 0xeb, 0xec, 0xa1, 0x06, 0xd8,
+	0xea, 0x54, 0x04, 0xe5, 0x33, 0xca, 0xd5, 0x83, 0xa2, 0x36, 0x9d, 0x76, 0x29, 0xf5, 0x08, 0x4a,
+	0xb8, 0x3b, 0xd1, 0x97, 0xb7, 0x84, 0x8d, 0xa5, 0x6e, 0xe3, 0x52, 0xa2, 0xe6, 0x36, 0x1a, 0xb3,
+	0xf9, 0xdf, 0x3c, 0x94, 0xd3, 0xef, 0x22, 0x3a, 0x4a, 0xde, 0x33, 0xbd, 0xa5, 0x3b, 0x87, 0x07,
+	0x6f, 0x7a, 0x47, 0xf5, 0xeb, 0x11, 0xc4, 0x2a, 0xd8, 0x99, 0x6a, 0x61, 0x35, 0x19, 0xfd, 0x12,
+	0x76, 0x22, 0xc6, 0xe5, 0xb2, 0x86, 0xd4, 0x32, 0x2b, 0x3e, 0xe3, 0xcb, 0x6a, 0x9b, 0x80, 0x9b,
+	0x13, 0xb8, 0xb3, 0x19, 0x0d, 0x3d, 0x86, 0xed, 0x17, 0x27, 0xfd, 0x4a, 0xae, 0xfa, 0xf0, 0xd5,
+	0x75, 0xe3, 0x87, 0x9b, 0x1f, 0x5f, 0xf8, 0x5c, 0xc6, 0x24, 0x38, 0xe9, 0xa3, 0x9f, 0xc2, 0x4e,
+	0xf7, 0x7c, 0x80, 0x71, 0x25, 0x5f, 0xad, 0xbf, 0xba, 0x6e, 0x3c, 0xdc, 0xc4, 0xa9, 0x4f, 0x2c,
+	0x0e, 0x3d, 0xcc, 0x46, 0xab, 0x76, 0xee, 0x9f, 0x5b, 0x60, 0x9b, 0xd2, 0xfa, 0xae, 0x3b, 0xfe,
+	0xbd, 0xe4, 0xb5, 0x5a, 0xde, 0x99, 0xad, 0x37, 0x3e, 0x5a, 0xe5, 0x84, 0x60, 0xce, 0xf8, 0x11,
+	0x94, 0xfd, 0x68, 0xf6, 0xe9, 0x90, 0x86, 0x64, 0x14, 0x98, 0xce, 0xce, 0xc2, 0xb6, 0xf2, 0xf5,
+	0x12, 0x97, 0xba, 0xb0, 0x7e, 0x28, 0x29, 0x0f, 0x4d, 0xcf, 0x66, 0xe1, 0x95, 0x8d, 0x3e, 0x87,
+	0x82, 0x1f, 0x91, 0xa9, 0x79, 0x69, 0x33, 0x77, 0x70, 0xd2, 0x6f, 0x9f, 0x19, 0x0d, 0x76, 0xac,
+	0xc5, 0x4d, 0xbd, 0xa0, 0x1c, 0x58, 0xd3, 0x50, 0x6d, 0xf9, 0xd8, 0xa9, 0x99, 0x74, 0xf1, 0xb5,
+	0x70, 0xca, 0xd3, 0xfc, 0x5f, 0x01, 0xec, 0xa3, 0x20, 0x16, 0xd2, 0x3c, 0x21, 0xef, 0x2c, 0x6f,
+	0x2f, 0xe1, 0x1e, 0xd1, 0xcd, 0x3f, 0x09, 0x55, 0x3d, 0xd6, 0x4d, 0x84, 0xc9, 0xdd, 0xe3, 0xcc,
+	0x70, 0x2b, 0x70, 0xd2, 0x70, 0x74, 0x8a, 0x2a, 0xa6, 0x93, 0xc7, 0x15, 0xf2, 0x8d, 0x2f, 0x68,
+	0x00, 0x7b, 0x8c, 0xbb, 0x13, 0x2a, 0x64, 0x52, 0xc5, 0x4d, 0xb3, 0x9c, 0xf9, 0x1b, 0xf5, 0x3c,
+	0x0d, 0x34, 0x25, 0x2c, 0x59, 0xed, 0x66, 0x0c, 0xf4, 0x04, 0x0a, 0x9c, 0x5c, 0x2e, 0x1b, 0xa2,
+	0x4c, 0x7d, 0x63, 0x72, 0x29, 0x37, 0x42, 0x68, 0x06, 0xfa, 0x03, 0x80, 0xe7, 0x8b, 0x88, 0x48,
+	0x77, 0x42, 0xb9, 0x39, 0xa7, 0xcc, 0x2d, 0x76, 0x57, 0xa8, 0x8d, 0x28, 0x29, 0x36, 0x3a, 0x85,
+	0x92, 0x4b, 0x96, 0x4a, 0x2b, 0xde, 0xfe, 0x07, 0x71, 0xd4, 0x36, 0x21, 0x2a, 0x2a, 0xc4, 0xe2,
+	0xa6, 0x6e, 0x2d, 0x3d, 0xd8, 0x72, 0x89, 0x51, 0xde, 0x29, 0xec, 0xa9, 0x3f, 0x8b, 0xa1, 0x47,
+	0x2f, 0x49, 0x1c, 0x48, 0xa1, 0x1f, 0xda, 0x5b, 0x4a, 0xb2, 0x6a, 0x53, 0xbb, 0x06, 0x67, 0xd6,
+	0x55, 0x96, 0x29, 0x1f, 0xfa, 0x13, 0xdc, 0xa3, 0xa1, 0xcb, 0xe7, 0x5a, 0x67, 0xcb, 0x15, 0x5a,
+	0xb7, 0x6f, 0xb6, 0xb7, 0x02, 0x6f, 0x6c, 0xb6, 0x42, 0xbf, 0xe1, 0x6f, 0xfa, 0x00, 0xc9, 0x23,
+	0xf7, 0x6e, 0xf5, 0x87, 0xa0, 0xe0, 0x11, 0x49, 0xb4, 0xe4, 0xca, 0x58, 0x8f, 0x3b, 0xce, 0xeb,
+	0xaf, 0x6b, 0xb9, 0x7f, 0x7f, 0x5d, 0xcb, 0xfd, 0x65, 0x51, 0xcb, 0xbf, 0x5e, 0xd4, 0xf2, 0xff,
+	0x5a, 0xd4, 0xf2, 0xff, 0x59, 0xd4, 0xf2, 0xa3, 0xa2, 0x6e, 0x0d, 0x7e, 0xf1, 0xff, 0x00, 0x00,
+	0x00, 0xff, 0xff, 0xed, 0xbe, 0x26, 0xe6, 0x9a, 0x10, 0x00, 0x00,
 }
 }

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

@@ -101,7 +101,6 @@ message TaskSpec {
 	oneof runtime {
 	oneof runtime {
 		NetworkAttachmentSpec attachment = 8;
 		NetworkAttachmentSpec attachment = 8;
 		ContainerSpec container = 1;
 		ContainerSpec container = 1;
-		PluginSpec plugin = 10;
 	}
 	}
 
 
 	// Resource requirements for the container.
 	// Resource requirements for the container.
@@ -267,14 +266,6 @@ message ContainerSpec {
 	HealthConfig healthcheck = 16;
 	HealthConfig healthcheck = 16;
 }
 }
 
 
-// PluginSpec specifies runtime parameters for a plugin.
-message PluginSpec {
-	// image defines the image reference, as specified in the
-	// distribution/reference package. This may include a registry host, name,
-	// tag or digest.
-	string image = 1;
-}
-
 // EndpointSpec defines the properties that can be configured to
 // EndpointSpec defines the properties that can be configured to
 // access and loadbalance the service.
 // access and loadbalance the service.
 message EndpointSpec {
 message EndpointSpec {

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

@@ -72,7 +72,6 @@
 		TaskSpec
 		TaskSpec
 		NetworkAttachmentSpec
 		NetworkAttachmentSpec
 		ContainerSpec
 		ContainerSpec
-		PluginSpec
 		EndpointSpec
 		EndpointSpec
 		NetworkSpec
 		NetworkSpec
 		ClusterSpec
 		ClusterSpec

+ 122 - 49
vendor/github.com/docker/swarmkit/ca/certificates.go

@@ -5,7 +5,7 @@ import (
 	"crypto"
 	"crypto"
 	"crypto/ecdsa"
 	"crypto/ecdsa"
 	"crypto/elliptic"
 	"crypto/elliptic"
-	"crypto/rand"
+	cryptorand "crypto/rand"
 	"crypto/rsa"
 	"crypto/rsa"
 	"crypto/tls"
 	"crypto/tls"
 	"crypto/x509"
 	"crypto/x509"
@@ -100,18 +100,29 @@ type CertPaths struct {
 	Cert, Key string
 	Cert, Key string
 }
 }
 
 
-// RootCA is the representation of everything we need to sign certificates
-type RootCA struct {
+// LocalSigner is a signer that can sign CSRs
+type LocalSigner struct {
+	cfsigner.Signer
+
 	// Key will only be used by the original manager to put the private
 	// Key will only be used by the original manager to put the private
 	// key-material in raft, no signing operations depend on it.
 	// key-material in raft, no signing operations depend on it.
 	Key []byte
 	Key []byte
-	// Cert includes the PEM encoded Certificate for the Root CA
+}
+
+// RootCA is the representation of everything we need to sign certificates
+type RootCA struct {
+	// Cert contains a bundle of PEM encoded Certificate for the Root CA, the first one of which
+	// must correspond to the key in the local signer, if provided
 	Cert []byte
 	Cert []byte
+
+	// Pool is the root pool used to validate TLS certificates
 	Pool *x509.CertPool
 	Pool *x509.CertPool
-	// Digest of the serialized bytes of the certificate
+
+	// Digest of the serialized bytes of the certificate(s)
 	Digest digest.Digest
 	Digest digest.Digest
+
 	// This signer will be nil if the node doesn't have the appropriate key material
 	// This signer will be nil if the node doesn't have the appropriate key material
-	Signer cfsigner.Signer
+	Signer *LocalSigner
 }
 }
 
 
 // CanSign ensures that the signer has all three necessary elements needed to operate
 // CanSign ensures that the signer has all three necessary elements needed to operate
@@ -154,25 +165,6 @@ func (rca *RootCA) IssueAndSaveNewCertificates(kw KeyWriter, cn, ou, org string)
 	return &tlsKeyPair, nil
 	return &tlsKeyPair, nil
 }
 }
 
 
-// Normally we can just call cert.Verify(opts), but since we actually want more information about
-// whether a certificate is not yet valid or expired, we also need to perform the expiry checks ourselves.
-func verifyCertificate(cert *x509.Certificate, opts x509.VerifyOptions, allowExpired bool) error {
-	_, err := cert.Verify(opts)
-	if invalidErr, ok := err.(x509.CertificateInvalidError); ok && invalidErr.Reason == x509.Expired {
-		now := time.Now().UTC()
-		if now.Before(cert.NotBefore) {
-			return errors.Wrapf(err, "certificate not valid before %s, and it is currently %s",
-				cert.NotBefore.UTC().Format(time.RFC1123), now.Format(time.RFC1123))
-		}
-		if allowExpired {
-			return nil
-		}
-		return errors.Wrapf(err, "certificate expires at %s, and it is currently %s",
-			cert.NotAfter.UTC().Format(time.RFC1123), now.Format(time.RFC1123))
-	}
-	return err
-}
-
 // RequestAndSaveNewCertificates gets new certificates issued, either by signing them locally if a signer is
 // RequestAndSaveNewCertificates gets new certificates issued, either by signing them locally if a signer is
 // available, or by requesting them from the remote server at remoteAddr.
 // available, or by requesting them from the remote server at remoteAddr.
 func (rca *RootCA) RequestAndSaveNewCertificates(ctx context.Context, kw KeyWriter, config CertificateRequestConfig) (*tls.Certificate, error) {
 func (rca *RootCA) RequestAndSaveNewCertificates(ctx context.Context, kw KeyWriter, config CertificateRequestConfig) (*tls.Certificate, error) {
@@ -208,20 +200,9 @@ func (rca *RootCA) RequestAndSaveNewCertificates(ctx context.Context, kw KeyWrit
 	// Доверяй, но проверяй.
 	// Доверяй, но проверяй.
 	// Before we overwrite our local key + certificate, let's make sure the server gave us one that is valid
 	// Before we overwrite our local key + certificate, let's make sure the server gave us one that is valid
 	// Create an X509Cert so we can .Verify()
 	// Create an X509Cert so we can .Verify()
-	certBlock, _ := pem.Decode(signedCert)
-	if certBlock == nil {
-		return nil, errors.New("failed to parse certificate PEM")
-	}
-	X509Cert, err := x509.ParseCertificate(certBlock.Bytes)
-	if err != nil {
-		return nil, err
-	}
-	// Include our current root pool
-	opts := x509.VerifyOptions{
-		Roots: rca.Pool,
-	}
 	// Check to see if this certificate was signed by our CA, and isn't expired
 	// Check to see if this certificate was signed by our CA, and isn't expired
-	if err := verifyCertificate(X509Cert, opts, false); err != nil {
+	parsedCerts, err := ValidateCertChain(rca.Pool, signedCert, false)
+	if err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
 
 
@@ -233,7 +214,8 @@ func (rca *RootCA) RequestAndSaveNewCertificates(ctx context.Context, kw KeyWrit
 
 
 	var kekUpdate *KEKData
 	var kekUpdate *KEKData
 	for i := 0; i < 5; i++ {
 	for i := 0; i < 5; i++ {
-		kekUpdate, err = rca.getKEKUpdate(ctx, X509Cert, tlsKeyPair, config.ConnBroker)
+		// ValidateCertChain will always return at least 1 cert, so indexing at 0 is safe
+		kekUpdate, err = rca.getKEKUpdate(ctx, parsedCerts[0], tlsKeyPair, config.ConnBroker)
 		if err == nil {
 		if err == nil {
 			break
 			break
 		}
 		}
@@ -412,7 +394,104 @@ func NewRootCA(certBytes, keyBytes []byte, certExpiry time.Duration) (RootCA, er
 		}
 		}
 	}
 	}
 
 
-	return RootCA{Signer: signer, Key: keyBytes, Digest: digest, Cert: certBytes, Pool: pool}, nil
+	return RootCA{Signer: &LocalSigner{Signer: signer, Key: keyBytes}, Digest: digest, Cert: certBytes, Pool: pool}, nil
+}
+
+// ValidateCertChain checks checks that the certificates provided chain up to the root pool provided.  In addition
+// it also enforces that every cert in the bundle certificates form a chain, each one certifying the one above,
+// as per RFC5246 section 7.4.2, and that every certificate (whether or not it is necessary to form a chain to the root
+// pool) is currently valid and not yet expired (unless allowExpiry is set to true).
+// This is additional validation not required by go's Certificate.Verify (which allows invalid certs in the
+// intermediate pool), because this function is intended to be used when reading certs from untrusted locations such as
+// from disk or over a network when a CSR is signed, so it is extra pedantic.
+// This function always returns all the parsed certificates in the bundle in order, which means there will always be
+// at least 1 certificate if there is no error.
+func ValidateCertChain(rootPool *x509.CertPool, certs []byte, allowExpired bool) ([]*x509.Certificate, error) {
+	// Parse all the certificates in the cert bundle
+	parsedCerts, err := helpers.ParseCertificatesPEM(certs)
+	if err != nil {
+		return nil, err
+	}
+	if len(parsedCerts) == 0 {
+		return nil, errors.New("no certificates to validate")
+	}
+	now := time.Now()
+	// ensure that they form a chain, each one being signed by the one after it
+	var intermediatePool *x509.CertPool
+	for i, cert := range parsedCerts {
+		// Manual expiry validation because we want more information on which certificate in the chain is expired, and
+		// because this is an easier way to allow expired certs.
+		if now.Before(cert.NotBefore) {
+			return nil, errors.Wrapf(
+				x509.CertificateInvalidError{
+					Cert:   cert,
+					Reason: x509.Expired,
+				},
+				"certificate (%d - %s) not valid before %s, and it is currently %s",
+				i+1, cert.Subject.CommonName, cert.NotBefore.UTC().Format(time.RFC1123), now.Format(time.RFC1123))
+		}
+		if !allowExpired && now.After(cert.NotAfter) {
+			return nil, errors.Wrapf(
+				x509.CertificateInvalidError{
+					Cert:   cert,
+					Reason: x509.Expired,
+				},
+				"certificate (%d - %s) not valid after %s, and it is currently %s",
+				i+1, cert.Subject.CommonName, cert.NotAfter.UTC().Format(time.RFC1123), now.Format(time.RFC1123))
+		}
+
+		if i > 0 {
+			// check that the previous cert was signed by this cert
+			prevCert := parsedCerts[i-1]
+			if err := prevCert.CheckSignatureFrom(cert); err != nil {
+				return nil, errors.Wrapf(err, "certificates do not form a chain: (%d - %s) is not signed by (%d - %s)",
+					i, prevCert.Subject.CommonName, i+1, cert.Subject.CommonName)
+			}
+
+			if intermediatePool == nil {
+				intermediatePool = x509.NewCertPool()
+			}
+			intermediatePool.AddCert(cert)
+
+		}
+	}
+
+	verifyOpts := x509.VerifyOptions{
+		Roots:         rootPool,
+		Intermediates: intermediatePool,
+		CurrentTime:   now,
+	}
+
+	// If we accept expired certs, try to build a valid cert chain using some subset of the certs.  We start off using the
+	// first certificate's NotAfter as the current time, thus ensuring that the first cert is not expired. If the chain
+	// still fails to validate due to expiry issues, continue iterating over the rest of the certs.
+	// If any of the other certs has an earlier NotAfter time, use that time as the current time instead. This insures that
+	// particular cert, and any that came before it, are not expired.  Note that the root that the certs chain up to
+	// should also not be expired at that "current" time.
+	if allowExpired {
+		verifyOpts.CurrentTime = parsedCerts[0].NotAfter.Add(time.Hour)
+		for _, cert := range parsedCerts {
+			if !cert.NotAfter.Before(verifyOpts.CurrentTime) {
+				continue
+			}
+			verifyOpts.CurrentTime = cert.NotAfter
+
+			_, err = parsedCerts[0].Verify(verifyOpts)
+			if err == nil {
+				return parsedCerts, nil
+			}
+		}
+		if invalid, ok := err.(x509.CertificateInvalidError); ok && invalid.Reason == x509.Expired {
+			return nil, errors.New("there is no time span for which all of the certificates, including a root, are valid")
+		}
+		return nil, err
+	}
+
+	_, err = parsedCerts[0].Verify(verifyOpts)
+	if err != nil {
+		return nil, err
+	}
+	return parsedCerts, nil
 }
 }
 
 
 func ensureCertKeyMatch(cert *x509.Certificate, key crypto.PublicKey) error {
 func ensureCertKeyMatch(cert *x509.Certificate, key crypto.PublicKey) error {
@@ -666,17 +745,11 @@ func saveRootCA(rootCA RootCA, paths CertPaths) error {
 }
 }
 
 
 // GenerateNewCSR returns a newly generated key and CSR signed with said key
 // GenerateNewCSR returns a newly generated key and CSR signed with said key
-func GenerateNewCSR() (csr, key []byte, err error) {
+func GenerateNewCSR() ([]byte, []byte, error) {
 	req := &cfcsr.CertificateRequest{
 	req := &cfcsr.CertificateRequest{
 		KeyRequest: cfcsr.NewBasicKeyRequest(),
 		KeyRequest: cfcsr.NewBasicKeyRequest(),
 	}
 	}
-
-	csr, key, err = cfcsr.ParseRequest(req)
-	if err != nil {
-		return
-	}
-
-	return
+	return cfcsr.ParseRequest(req)
 }
 }
 
 
 // EncryptECPrivateKey receives a PEM encoded private key and returns an encrypted
 // EncryptECPrivateKey receives a PEM encoded private key and returns an encrypted
@@ -692,7 +765,7 @@ func EncryptECPrivateKey(key []byte, passphraseStr string) ([]byte, error) {
 		return nil, errors.New("error while decoding PEM key")
 		return nil, errors.New("error while decoding PEM key")
 	}
 	}
 
 
-	encryptedPEMBlock, err := x509.EncryptPEMBlock(rand.Reader,
+	encryptedPEMBlock, err := x509.EncryptPEMBlock(cryptorand.Reader,
 		"EC PRIVATE KEY",
 		"EC PRIVATE KEY",
 		keyBlock.Bytes,
 		keyBlock.Bytes,
 		passphrase,
 		passphrase,

+ 52 - 59
vendor/github.com/docker/swarmkit/ca/config.go

@@ -4,7 +4,6 @@ import (
 	cryptorand "crypto/rand"
 	cryptorand "crypto/rand"
 	"crypto/tls"
 	"crypto/tls"
 	"crypto/x509"
 	"crypto/x509"
-	"encoding/pem"
 	"fmt"
 	"fmt"
 	"math/big"
 	"math/big"
 	"math/rand"
 	"math/rand"
@@ -112,6 +111,11 @@ func (s *SecurityConfig) RootCA() *RootCA {
 	return s.rootCA
 	return s.rootCA
 }
 }
 
 
+// ExternalCA returns the external CA.
+func (s *SecurityConfig) ExternalCA() *ExternalCA {
+	return s.externalCA
+}
+
 // KeyWriter returns the object that can write keys to disk
 // KeyWriter returns the object that can write keys to disk
 func (s *SecurityConfig) KeyWriter() KeyWriter {
 func (s *SecurityConfig) KeyWriter() KeyWriter {
 	return s.keyReadWriter
 	return s.keyReadWriter
@@ -129,11 +133,45 @@ func (s *SecurityConfig) UpdateRootCA(cert, key []byte, certExpiry time.Duration
 	defer s.mu.Unlock()
 	defer s.mu.Unlock()
 
 
 	rootCA, err := NewRootCA(cert, key, certExpiry)
 	rootCA, err := NewRootCA(cert, key, certExpiry)
-	if err == nil {
-		s.rootCA = &rootCA
+	if err != nil {
+		return err
+	}
+
+	s.rootCA = &rootCA
+	clientTLSConfig := s.ClientTLSCreds.Config()
+	return s.updateTLSCredentials(clientTLSConfig.Certificates)
+}
+
+// updateTLSCredentials updates the client, server, and TLS credentials on a security config.  This function expects
+// something else to have taken out a lock on the SecurityConfig.
+func (s *SecurityConfig) updateTLSCredentials(certificates []tls.Certificate) error {
+	clientConfig, err := NewClientTLSConfig(certificates, s.rootCA.Pool, ManagerRole)
+	if err != nil {
+		return errors.Wrap(err, "failed to create a new client config using the new root CA")
+	}
+
+	serverConfig, err := NewServerTLSConfig(certificates, s.rootCA.Pool)
+	if err != nil {
+		return errors.Wrap(err, "failed to create a new server config using the new root CA")
+	}
+
+	if err := s.ClientTLSCreds.loadNewTLSConfig(clientConfig); err != nil {
+		return errors.Wrap(err, "failed to update the client credentials")
 	}
 	}
 
 
-	return err
+	// Update the external CA to use the new client TLS
+	// config using a copy without a serverName specified.
+	s.externalCA.UpdateTLSConfig(&tls.Config{
+		Certificates: certificates,
+		RootCAs:      s.rootCA.Pool,
+		MinVersion:   tls.VersionTLS12,
+	})
+
+	if err := s.ServerTLSCreds.loadNewTLSConfig(serverConfig); err != nil {
+		return errors.Wrap(err, "failed to update the server TLS credentials")
+	}
+
+	return nil
 }
 }
 
 
 // SigningPolicy creates a policy used by the signer to ensure that the only fields
 // SigningPolicy creates a policy used by the signer to ensure that the only fields
@@ -263,25 +301,8 @@ func LoadSecurityConfig(ctx context.Context, rootCA RootCA, krw *KeyReadWriter,
 		return nil, err
 		return nil, err
 	}
 	}
 
 
-	// Create an x509 certificate out of the contents on disk
-	certBlock, _ := pem.Decode([]byte(cert))
-	if certBlock == nil {
-		return nil, errors.New("failed to parse certificate PEM")
-	}
-
-	// Create an X509Cert so we can .Verify()
-	X509Cert, err := x509.ParseCertificate(certBlock.Bytes)
-	if err != nil {
-		return nil, err
-	}
-
-	// Include our root pool
-	opts := x509.VerifyOptions{
-		Roots: rootCA.Pool,
-	}
-
 	// Check to see if this certificate was signed by our CA, and isn't expired
 	// Check to see if this certificate was signed by our CA, and isn't expired
-	if err := verifyCertificate(X509Cert, opts, allowExpired); err != nil {
+	if _, err := ValidateCertChain(rootCA.Pool, cert, allowExpired); err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
 
 
@@ -415,37 +436,9 @@ func RenewTLSConfigNow(ctx context.Context, s *SecurityConfig, connBroker *conne
 		log.WithError(err).Errorf("failed to renew the certificate")
 		log.WithError(err).Errorf("failed to renew the certificate")
 		return err
 		return err
 	}
 	}
-
-	clientTLSConfig, err := NewClientTLSConfig(tlsKeyPair, rootCA.Pool, CARole)
-	if err != nil {
-		log.WithError(err).Errorf("failed to create a new client config")
-		return err
-	}
-	serverTLSConfig, err := NewServerTLSConfig(tlsKeyPair, rootCA.Pool)
-	if err != nil {
-		log.WithError(err).Errorf("failed to create a new server config")
-		return err
-	}
-
-	if err = s.ClientTLSCreds.LoadNewTLSConfig(clientTLSConfig); err != nil {
-		log.WithError(err).Errorf("failed to update the client credentials")
-		return err
-	}
-
-	// Update the external CA to use the new client TLS
-	// config using a copy without a serverName specified.
-	s.externalCA.UpdateTLSConfig(&tls.Config{
-		Certificates: clientTLSConfig.Certificates,
-		RootCAs:      clientTLSConfig.RootCAs,
-		MinVersion:   tls.VersionTLS12,
-	})
-
-	if err = s.ServerTLSCreds.LoadNewTLSConfig(serverTLSConfig); err != nil {
-		log.WithError(err).Errorf("failed to update the server TLS credentials")
-		return err
-	}
-
-	return nil
+	s.mu.Lock()
+	defer s.mu.Unlock()
+	return s.updateTLSCredentials([]tls.Certificate{*tlsKeyPair})
 }
 }
 
 
 // RenewTLSConfig will continuously monitor for the necessity of renewing the local certificates, either by
 // RenewTLSConfig will continuously monitor for the necessity of renewing the local certificates, either by
@@ -565,13 +558,13 @@ func calculateRandomExpiry(validFrom, validUntil time.Time) time.Duration {
 
 
 // NewServerTLSConfig returns a tls.Config configured for a TLS Server, given a tls.Certificate
 // NewServerTLSConfig returns a tls.Config configured for a TLS Server, given a tls.Certificate
 // and the PEM-encoded root CA Certificate
 // and the PEM-encoded root CA Certificate
-func NewServerTLSConfig(cert *tls.Certificate, rootCAPool *x509.CertPool) (*tls.Config, error) {
+func NewServerTLSConfig(certs []tls.Certificate, rootCAPool *x509.CertPool) (*tls.Config, error) {
 	if rootCAPool == nil {
 	if rootCAPool == nil {
 		return nil, errors.New("valid root CA pool required")
 		return nil, errors.New("valid root CA pool required")
 	}
 	}
 
 
 	return &tls.Config{
 	return &tls.Config{
-		Certificates: []tls.Certificate{*cert},
+		Certificates: certs,
 		// Since we're using the same CA server to issue Certificates to new nodes, we can't
 		// Since we're using the same CA server to issue Certificates to new nodes, we can't
 		// use tls.RequireAndVerifyClientCert
 		// use tls.RequireAndVerifyClientCert
 		ClientAuth:               tls.VerifyClientCertIfGiven,
 		ClientAuth:               tls.VerifyClientCertIfGiven,
@@ -584,14 +577,14 @@ func NewServerTLSConfig(cert *tls.Certificate, rootCAPool *x509.CertPool) (*tls.
 
 
 // NewClientTLSConfig returns a tls.Config configured for a TLS Client, given a tls.Certificate
 // NewClientTLSConfig returns a tls.Config configured for a TLS Client, given a tls.Certificate
 // the PEM-encoded root CA Certificate, and the name of the remote server the client wants to connect to.
 // the PEM-encoded root CA Certificate, and the name of the remote server the client wants to connect to.
-func NewClientTLSConfig(cert *tls.Certificate, rootCAPool *x509.CertPool, serverName string) (*tls.Config, error) {
+func NewClientTLSConfig(certs []tls.Certificate, rootCAPool *x509.CertPool, serverName string) (*tls.Config, error) {
 	if rootCAPool == nil {
 	if rootCAPool == nil {
 		return nil, errors.New("valid root CA pool required")
 		return nil, errors.New("valid root CA pool required")
 	}
 	}
 
 
 	return &tls.Config{
 	return &tls.Config{
 		ServerName:   serverName,
 		ServerName:   serverName,
-		Certificates: []tls.Certificate{*cert},
+		Certificates: certs,
 		RootCAs:      rootCAPool,
 		RootCAs:      rootCAPool,
 		MinVersion:   tls.VersionTLS12,
 		MinVersion:   tls.VersionTLS12,
 	}, nil
 	}, nil
@@ -600,7 +593,7 @@ func NewClientTLSConfig(cert *tls.Certificate, rootCAPool *x509.CertPool, server
 // NewClientTLSCredentials returns GRPC credentials for a TLS GRPC client, given a tls.Certificate
 // NewClientTLSCredentials returns GRPC credentials for a TLS GRPC client, given a tls.Certificate
 // a PEM-Encoded root CA Certificate, and the name of the remote server the client wants to connect to.
 // a PEM-Encoded root CA Certificate, and the name of the remote server the client wants to connect to.
 func (rootCA *RootCA) NewClientTLSCredentials(cert *tls.Certificate, serverName string) (*MutableTLSCreds, error) {
 func (rootCA *RootCA) NewClientTLSCredentials(cert *tls.Certificate, serverName string) (*MutableTLSCreds, error) {
-	tlsConfig, err := NewClientTLSConfig(cert, rootCA.Pool, serverName)
+	tlsConfig, err := NewClientTLSConfig([]tls.Certificate{*cert}, rootCA.Pool, serverName)
 	if err != nil {
 	if err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
@@ -613,7 +606,7 @@ func (rootCA *RootCA) NewClientTLSCredentials(cert *tls.Certificate, serverName
 // NewServerTLSCredentials returns GRPC credentials for a TLS GRPC client, given a tls.Certificate
 // NewServerTLSCredentials returns GRPC credentials for a TLS GRPC client, given a tls.Certificate
 // a PEM-Encoded root CA Certificate, and the name of the remote server the client wants to connect to.
 // a PEM-Encoded root CA Certificate, and the name of the remote server the client wants to connect to.
 func (rootCA *RootCA) NewServerTLSCredentials(cert *tls.Certificate) (*MutableTLSCreds, error) {
 func (rootCA *RootCA) NewServerTLSCredentials(cert *tls.Certificate) (*MutableTLSCreds, error) {
-	tlsConfig, err := NewServerTLSConfig(cert, rootCA.Pool)
+	tlsConfig, err := NewServerTLSConfig([]tls.Certificate{*cert}, rootCA.Pool)
 	if err != nil {
 	if err != nil {
 		return nil, err
 		return nil, err
 	}
 	}

+ 2 - 2
vendor/github.com/docker/swarmkit/ca/keyreadwriter.go

@@ -1,7 +1,7 @@
 package ca
 package ca
 
 
 import (
 import (
-	"crypto/rand"
+	cryptorand "crypto/rand"
 	"crypto/x509"
 	"crypto/x509"
 	"encoding/pem"
 	"encoding/pem"
 	"io/ioutil"
 	"io/ioutil"
@@ -345,7 +345,7 @@ func (k *KeyReadWriter) readKey() (*pem.Block, error) {
 // writing it to disk.  If the kek is nil, writes it to disk unencrypted.
 // writing it to disk.  If the kek is nil, writes it to disk unencrypted.
 func (k *KeyReadWriter) writeKey(keyBlock *pem.Block, kekData KEKData, pkh PEMKeyHeaders) error {
 func (k *KeyReadWriter) writeKey(keyBlock *pem.Block, kekData KEKData, pkh PEMKeyHeaders) error {
 	if kekData.KEK != nil {
 	if kekData.KEK != nil {
-		encryptedPEMBlock, err := x509.EncryptPEMBlock(rand.Reader,
+		encryptedPEMBlock, err := x509.EncryptPEMBlock(cryptorand.Reader,
 			keyBlock.Type,
 			keyBlock.Type,
 			keyBlock.Bytes,
 			keyBlock.Bytes,
 			kekData.KEK,
 			kekData.KEK,

+ 11 - 8
vendor/github.com/docker/swarmkit/ca/server.go

@@ -392,14 +392,12 @@ func (s *Server) Run(ctx context.Context) error {
 			if len(clusters) != 1 {
 			if len(clusters) != 1 {
 				return errors.New("could not find cluster object")
 				return errors.New("could not find cluster object")
 			}
 			}
-			s.updateCluster(ctx, clusters[0])
-
+			s.UpdateRootCA(ctx, clusters[0]) // call once to ensure that the join tokens are always set
 			nodes, err = store.FindNodes(readTx, store.All)
 			nodes, err = store.FindNodes(readTx, store.All)
 			return err
 			return err
 		},
 		},
 		state.EventCreateNode{},
 		state.EventCreateNode{},
 		state.EventUpdateNode{},
 		state.EventUpdateNode{},
-		state.EventUpdateCluster{},
 	)
 	)
 
 
 	// Do this after updateCluster has been called, so isRunning never
 	// Do this after updateCluster has been called, so isRunning never
@@ -434,6 +432,12 @@ func (s *Server) Run(ctx context.Context) error {
 	// Watch for new nodes being created, new nodes being updated, and changes
 	// Watch for new nodes being created, new nodes being updated, and changes
 	// to the cluster
 	// to the cluster
 	for {
 	for {
+		select {
+		case <-ctx.Done():
+			return nil
+		default:
+		}
+
 		select {
 		select {
 		case event := <-updates:
 		case event := <-updates:
 			switch v := event.(type) {
 			switch v := event.(type) {
@@ -445,8 +449,6 @@ func (s *Server) Run(ctx context.Context) error {
 				if !isFinalState(v.Node.Certificate.Status) {
 				if !isFinalState(v.Node.Certificate.Status) {
 					s.evaluateAndSignNodeCert(ctx, v.Node)
 					s.evaluateAndSignNodeCert(ctx, v.Node)
 				}
 				}
-			case state.EventUpdateCluster:
-				s.updateCluster(ctx, v.Cluster)
 			}
 			}
 		case <-ticker.C:
 		case <-ticker.C:
 			for _, node := range s.pending {
 			for _, node := range s.pending {
@@ -512,9 +514,10 @@ func (s *Server) isRunning() bool {
 	return true
 	return true
 }
 }
 
 
-// updateCluster is called when there are cluster changes, and it ensures that the local RootCA is
-// always aware of changes in clusterExpiry and the Root CA key material
-func (s *Server) updateCluster(ctx context.Context, cluster *api.Cluster) {
+// UpdateRootCA is called when there are cluster changes, and it ensures that the local RootCA is
+// always aware of changes in clusterExpiry and the Root CA key material - this can be called by
+// anything to update the root CA material
+func (s *Server) UpdateRootCA(ctx context.Context, cluster *api.Cluster) {
 	s.mu.Lock()
 	s.mu.Lock()
 	s.joinTokens = cluster.RootCA.JoinTokens.Copy()
 	s.joinTokens = cluster.RootCA.JoinTokens.Copy()
 	s.mu.Unlock()
 	s.mu.Unlock()

+ 2 - 2
vendor/github.com/docker/swarmkit/ca/transport.go

@@ -120,8 +120,8 @@ func (c *MutableTLSCreds) ServerHandshake(rawConn net.Conn) (net.Conn, credentia
 	return conn, credentials.TLSInfo{State: conn.ConnectionState()}, nil
 	return conn, credentials.TLSInfo{State: conn.ConnectionState()}, nil
 }
 }
 
 
-// LoadNewTLSConfig replaces the currently loaded TLS config with a new one
-func (c *MutableTLSCreds) LoadNewTLSConfig(newConfig *tls.Config) error {
+// loadNewTLSConfig replaces the currently loaded TLS config with a new one
+func (c *MutableTLSCreds) loadNewTLSConfig(newConfig *tls.Config) error {
 	newSubject, err := GetAndValidateCertificateSubject(newConfig.Certificates)
 	newSubject, err := GetAndValidateCertificateSubject(newConfig.Certificates)
 	if err != nil {
 	if err != nil {
 		return err
 		return err

+ 2 - 2
vendor/github.com/docker/swarmkit/identity/randomid.go

@@ -1,7 +1,7 @@
 package identity
 package identity
 
 
 import (
 import (
-	"crypto/rand"
+	cryptorand "crypto/rand"
 	"fmt"
 	"fmt"
 	"io"
 	"io"
 	"math/big"
 	"math/big"
@@ -10,7 +10,7 @@ import (
 var (
 var (
 	// idReader is used for random id generation. This declaration allows us to
 	// idReader is used for random id generation. This declaration allows us to
 	// replace it for testing.
 	// replace it for testing.
-	idReader = rand.Reader
+	idReader = cryptorand.Reader
 )
 )
 
 
 // parameters for random identifier generation. We can tweak this when there is
 // parameters for random identifier generation. We can tweak this when there is

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

@@ -454,7 +454,7 @@ func (na *NetworkAllocator) releaseEndpoints(networks []*api.NetworkAttachment)
 func (na *NetworkAllocator) allocateVIP(vip *api.Endpoint_VirtualIP) error {
 func (na *NetworkAllocator) allocateVIP(vip *api.Endpoint_VirtualIP) error {
 	localNet := na.getNetwork(vip.NetworkID)
 	localNet := na.getNetwork(vip.NetworkID)
 	if localNet == nil {
 	if localNet == nil {
-		return fmt.Errorf("networkallocator: could not find local network state")
+		return errors.New("networkallocator: could not find local network state")
 	}
 	}
 
 
 	// If this IP is already allocated in memory we don't need to
 	// If this IP is already allocated in memory we don't need to
@@ -682,7 +682,7 @@ func (na *NetworkAllocator) resolveDriver(n *api.Network) (driverapi.Driver, str
 func (na *NetworkAllocator) loadDriver(name string) error {
 func (na *NetworkAllocator) loadDriver(name string) error {
 	pg := na.drvRegistry.GetPluginGetter()
 	pg := na.drvRegistry.GetPluginGetter()
 	if pg == nil {
 	if pg == nil {
-		return fmt.Errorf("plugin store is uninitialized")
+		return errors.New("plugin store is uninitialized")
 	}
 	}
 	_, err := pg.Get(name, driverapi.NetworkPluginEndpointType, plugingetter.Lookup)
 	_, err := pg.Get(name, driverapi.NetworkPluginEndpointType, plugingetter.Lookup)
 	return err
 	return err
@@ -739,7 +739,7 @@ func (na *NetworkAllocator) allocatePools(n *api.Network) (map[string]string, er
 	}
 	}
 
 
 	// We don't support user defined address spaces yet so just
 	// We don't support user defined address spaces yet so just
-	// retrive default address space names for the driver.
+	// retrieve default address space names for the driver.
 	_, asName, err := na.drvRegistry.IPAMDefaultAddressSpaces(dName)
 	_, asName, err := na.drvRegistry.IPAMDefaultAddressSpaces(dName)
 	if err != nil {
 	if err != nil {
 		return nil, err
 		return nil, err

+ 4 - 0
vendor/github.com/docker/swarmkit/manager/controlapi/common.go

@@ -94,6 +94,10 @@ func validateDriver(driver *api.Driver, pg plugingetter.PluginGetter, pluginType
 		return nil
 		return nil
 	}
 	}
 
 
+	if pg == nil {
+		return grpc.Errorf(codes.InvalidArgument, "plugin %s not supported", driver.Name)
+	}
+
 	p, err := pg.Get(driver.Name, pluginType, plugingetter.Lookup)
 	p, err := pg.Get(driver.Name, pluginType, plugingetter.Lookup)
 	if err != nil {
 	if err != nil {
 		return grpc.Errorf(codes.InvalidArgument, "error during lookup of plugin %s", driver.Name)
 		return grpc.Errorf(codes.InvalidArgument, "error during lookup of plugin %s", driver.Name)

+ 29 - 45
vendor/github.com/docker/swarmkit/manager/controlapi/service.go

@@ -117,29 +117,7 @@ func validateUpdate(uc *api.UpdateConfig) error {
 	return nil
 	return nil
 }
 }
 
 
-func validateContainerSpec(taskSpec api.TaskSpec) error {
-	// Building a empty/dummy Task to validate the templating and
-	// the resulting container spec as well. This is a *best effort*
-	// validation.
-	container, err := template.ExpandContainerSpec(&api.Task{
-		Spec:      taskSpec,
-		ServiceID: "serviceid",
-		Slot:      1,
-		NodeID:    "nodeid",
-		Networks:  []*api.NetworkAttachment{},
-		Annotations: api.Annotations{
-			Name: "taskname",
-		},
-		ServiceAnnotations: api.Annotations{
-			Name: "servicename",
-		},
-		Endpoint:  &api.Endpoint{},
-		LogDriver: taskSpec.LogDriver,
-	})
-	if err != nil {
-		return grpc.Errorf(codes.InvalidArgument, err.Error())
-	}
-
+func validateContainerSpec(container *api.ContainerSpec) error {
 	if container == nil {
 	if container == nil {
 		return grpc.Errorf(codes.InvalidArgument, "ContainerSpec: missing in service spec")
 		return grpc.Errorf(codes.InvalidArgument, "ContainerSpec: missing in service spec")
 	}
 	}
@@ -163,18 +141,6 @@ func validateContainerSpec(taskSpec api.TaskSpec) error {
 	return nil
 	return nil
 }
 }
 
 
-func validatePluginSpec(plugin *api.PluginSpec) error {
-	if plugin.Image == "" {
-		return grpc.Errorf(codes.InvalidArgument, "PluginSpec: image reference must be provided")
-	}
-
-	if _, err := reference.ParseNormalizedNamed(plugin.Image); err != nil {
-		return grpc.Errorf(codes.InvalidArgument, "PluginSpec: %q is not a valid repository/tag", plugin.Image)
-	}
-
-	return nil
-}
-
 func validateTaskSpec(taskSpec api.TaskSpec) error {
 func validateTaskSpec(taskSpec api.TaskSpec) error {
 	if err := validateResourceRequirements(taskSpec.Resources); err != nil {
 	if err := validateResourceRequirements(taskSpec.Resources); err != nil {
 		return err
 		return err
@@ -197,18 +163,36 @@ func validateTaskSpec(taskSpec api.TaskSpec) error {
 		return grpc.Errorf(codes.InvalidArgument, "TaskSpec: missing runtime")
 		return grpc.Errorf(codes.InvalidArgument, "TaskSpec: missing runtime")
 	}
 	}
 
 
-	switch taskSpec.GetRuntime().(type) {
-	case *api.TaskSpec_Container:
-		if err := validateContainerSpec(taskSpec); err != nil {
-			return err
-		}
-	case *api.TaskSpec_Plugin:
-		if err := validatePluginSpec(taskSpec.GetPlugin()); err != nil {
-			return err
-		}
-	default:
+	_, ok := taskSpec.GetRuntime().(*api.TaskSpec_Container)
+	if !ok {
 		return grpc.Errorf(codes.Unimplemented, "RuntimeSpec: unimplemented runtime in service spec")
 		return grpc.Errorf(codes.Unimplemented, "RuntimeSpec: unimplemented runtime in service spec")
 	}
 	}
+
+	// Building a empty/dummy Task to validate the templating and
+	// the resulting container spec as well. This is a *best effort*
+	// validation.
+	preparedSpec, err := template.ExpandContainerSpec(&api.Task{
+		Spec:      taskSpec,
+		ServiceID: "serviceid",
+		Slot:      1,
+		NodeID:    "nodeid",
+		Networks:  []*api.NetworkAttachment{},
+		Annotations: api.Annotations{
+			Name: "taskname",
+		},
+		ServiceAnnotations: api.Annotations{
+			Name: "servicename",
+		},
+		Endpoint:  &api.Endpoint{},
+		LogDriver: taskSpec.LogDriver,
+	})
+	if err != nil {
+		return grpc.Errorf(codes.InvalidArgument, err.Error())
+	}
+	if err := validateContainerSpec(preparedSpec); err != nil {
+		return err
+	}
+
 	return nil
 	return nil
 }
 }
 
 

+ 21 - 5
vendor/github.com/docker/swarmkit/manager/controlapi/task.go

@@ -3,6 +3,7 @@ package controlapi
 import (
 import (
 	"github.com/docker/swarmkit/api"
 	"github.com/docker/swarmkit/api"
 	"github.com/docker/swarmkit/api/naming"
 	"github.com/docker/swarmkit/api/naming"
+	"github.com/docker/swarmkit/manager/orchestrator"
 	"github.com/docker/swarmkit/manager/state/store"
 	"github.com/docker/swarmkit/manager/state/store"
 	"golang.org/x/net/context"
 	"golang.org/x/net/context"
 	"google.golang.org/grpc"
 	"google.golang.org/grpc"
@@ -97,12 +98,11 @@ func (s *Server) ListTasks(ctx context.Context, request *api.ListTasksRequest) (
 		default:
 		default:
 			tasks, err = store.FindTasks(tx, store.All)
 			tasks, err = store.FindTasks(tx, store.All)
 		}
 		}
-	})
-	if err != nil {
-		return nil, err
-	}
 
 
-	if request.Filters != nil {
+		if err != nil || request.Filters == nil {
+			return
+		}
+
 		tasks = filterTasks(tasks,
 		tasks = filterTasks(tasks,
 			func(e *api.Task) bool {
 			func(e *api.Task) bool {
 				return filterContains(naming.Task(e), request.Filters.Names)
 				return filterContains(naming.Task(e), request.Filters.Names)
@@ -133,7 +133,23 @@ func (s *Server) ListTasks(ctx context.Context, request *api.ListTasksRequest) (
 				}
 				}
 				return false
 				return false
 			},
 			},
+			func(e *api.Task) bool {
+				if !request.Filters.UpToDate {
+					return true
+				}
+
+				service := store.GetService(tx, e.ServiceID)
+				if service == nil {
+					return false
+				}
+
+				return !orchestrator.IsTaskDirty(service, e)
+			},
 		)
 		)
+	})
+
+	if err != nil {
+		return nil, err
 	}
 	}
 
 
 	return &api.ListTasksResponse{
 	return &api.ListTasksResponse{

+ 2 - 2
vendor/github.com/docker/swarmkit/manager/encryption/encryption.go

@@ -1,7 +1,7 @@
 package encryption
 package encryption
 
 
 import (
 import (
-	"crypto/rand"
+	cryptorand "crypto/rand"
 	"encoding/base64"
 	"encoding/base64"
 	"fmt"
 	"fmt"
 	"io"
 	"io"
@@ -105,7 +105,7 @@ func Defaults(key []byte) (Encrypter, Decrypter) {
 // using this package
 // using this package
 func GenerateSecretKey() []byte {
 func GenerateSecretKey() []byte {
 	secretData := make([]byte, naclSecretboxKeySize)
 	secretData := make([]byte, naclSecretboxKeySize)
-	if _, err := io.ReadFull(rand.Reader, secretData); err != nil {
+	if _, err := io.ReadFull(cryptorand.Reader, secretData); err != nil {
 		// panic if we can't read random data
 		// panic if we can't read random data
 		panic(errors.Wrap(err, "failed to read random bytes"))
 		panic(errors.Wrap(err, "failed to read random bytes"))
 	}
 	}

+ 2 - 2
vendor/github.com/docker/swarmkit/manager/encryption/nacl.go

@@ -1,7 +1,7 @@
 package encryption
 package encryption
 
 
 import (
 import (
-	"crypto/rand"
+	cryptorand "crypto/rand"
 	"fmt"
 	"fmt"
 	"io"
 	"io"
 
 
@@ -37,7 +37,7 @@ func (n NACLSecretbox) Algorithm() api.MaybeEncryptedRecord_Algorithm {
 // Encrypt encrypts some bytes and returns an encrypted record
 // Encrypt encrypts some bytes and returns an encrypted record
 func (n NACLSecretbox) Encrypt(data []byte) (*api.MaybeEncryptedRecord, error) {
 func (n NACLSecretbox) Encrypt(data []byte) (*api.MaybeEncryptedRecord, error) {
 	var nonce [24]byte
 	var nonce [24]byte
-	if _, err := io.ReadFull(rand.Reader, nonce[:]); err != nil {
+	if _, err := io.ReadFull(cryptorand.Reader, nonce[:]); err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
 
 

+ 3 - 3
vendor/github.com/docker/swarmkit/manager/keymanager/keymanager.go

@@ -6,7 +6,7 @@ package keymanager
 // which is used to exchange service discovery and overlay network control
 // which is used to exchange service discovery and overlay network control
 // plane information. It can also be used to encrypt overlay data traffic.
 // plane information. It can also be used to encrypt overlay data traffic.
 import (
 import (
-	"crypto/rand"
+	cryptorand "crypto/rand"
 	"encoding/binary"
 	"encoding/binary"
 	"sync"
 	"sync"
 	"time"
 	"time"
@@ -95,7 +95,7 @@ func New(store *store.MemoryStore, config *Config) *KeyManager {
 func (k *KeyManager) allocateKey(ctx context.Context, subsys string) *api.EncryptionKey {
 func (k *KeyManager) allocateKey(ctx context.Context, subsys string) *api.EncryptionKey {
 	key := make([]byte, k.config.Keylen)
 	key := make([]byte, k.config.Keylen)
 
 
-	_, err := rand.Read(key)
+	_, err := cryptorand.Read(key)
 	if err != nil {
 	if err != nil {
 		panic(errors.Wrap(err, "key generated failed"))
 		panic(errors.Wrap(err, "key generated failed"))
 	}
 	}
@@ -232,7 +232,7 @@ func (k *KeyManager) Stop() error {
 // genSkew generates a random uint64 number between 0 and 65535
 // genSkew generates a random uint64 number between 0 and 65535
 func genSkew() uint64 {
 func genSkew() uint64 {
 	b := make([]byte, 2)
 	b := make([]byte, 2)
-	if _, err := rand.Read(b); err != nil {
+	if _, err := cryptorand.Read(b); err != nil {
 		panic(err)
 		panic(err)
 	}
 	}
 	return uint64(binary.BigEndian.Uint16(b))
 	return uint64(binary.BigEndian.Uint16(b))

+ 15 - 6
vendor/github.com/docker/swarmkit/manager/logbroker/broker.go

@@ -360,7 +360,7 @@ func (lb *LogBroker) PublishLogs(stream api.LogBroker_PublishLogsServer) (err er
 	}()
 	}()
 
 
 	for {
 	for {
-		log, err := stream.Recv()
+		logMsg, err := stream.Recv()
 		if err == io.EOF {
 		if err == io.EOF {
 			return stream.SendAndClose(&api.PublishLogsResponse{})
 			return stream.SendAndClose(&api.PublishLogsResponse{})
 		}
 		}
@@ -368,28 +368,37 @@ func (lb *LogBroker) PublishLogs(stream api.LogBroker_PublishLogsServer) (err er
 			return err
 			return err
 		}
 		}
 
 
-		if log.SubscriptionID == "" {
+		if logMsg.SubscriptionID == "" {
 			return grpc.Errorf(codes.InvalidArgument, "missing subscription ID")
 			return grpc.Errorf(codes.InvalidArgument, "missing subscription ID")
 		}
 		}
 
 
 		if currentSubscription == nil {
 		if currentSubscription == nil {
-			currentSubscription = lb.getSubscription(log.SubscriptionID)
+			currentSubscription = lb.getSubscription(logMsg.SubscriptionID)
 			if currentSubscription == nil {
 			if currentSubscription == nil {
 				return grpc.Errorf(codes.NotFound, "unknown subscription ID")
 				return grpc.Errorf(codes.NotFound, "unknown subscription ID")
 			}
 			}
 		} else {
 		} else {
-			if log.SubscriptionID != currentSubscription.message.ID {
+			if logMsg.SubscriptionID != currentSubscription.message.ID {
 				return grpc.Errorf(codes.InvalidArgument, "different subscription IDs in the same session")
 				return grpc.Errorf(codes.InvalidArgument, "different subscription IDs in the same session")
 			}
 			}
 		}
 		}
 
 
+		// if we have a close message, close out the subscription
+		if logMsg.Close {
+			// Mark done and then set to nil so if we error after this point,
+			// we don't try to close again in the defer
+			currentSubscription.Done(remote.NodeID, err)
+			currentSubscription = nil
+			return nil
+		}
+
 		// Make sure logs are emitted using the right Node ID to avoid impersonation.
 		// Make sure logs are emitted using the right Node ID to avoid impersonation.
-		for _, msg := range log.Messages {
+		for _, msg := range logMsg.Messages {
 			if msg.Context.NodeID != remote.NodeID {
 			if msg.Context.NodeID != remote.NodeID {
 				return grpc.Errorf(codes.PermissionDenied, "invalid NodeID: expected=%s;received=%s", remote.NodeID, msg.Context.NodeID)
 				return grpc.Errorf(codes.PermissionDenied, "invalid NodeID: expected=%s;received=%s", remote.NodeID, msg.Context.NodeID)
 			}
 			}
 		}
 		}
 
 
-		lb.publish(log)
+		lb.publish(logMsg)
 	}
 	}
 }
 }

+ 4 - 0
vendor/github.com/docker/swarmkit/manager/logbroker/subscription.go

@@ -182,6 +182,10 @@ func (s *subscription) match() {
 				continue
 				continue
 			}
 			}
 			for _, task := range tasks {
 			for _, task := range tasks {
+				// if we're not following, don't add tasks that aren't running yet
+				if !s.follow() && task.Status.State < api.TaskStateRunning {
+					continue
+				}
 				add(task)
 				add(task)
 			}
 			}
 		}
 		}

+ 9 - 3
vendor/github.com/docker/swarmkit/manager/manager.go

@@ -514,7 +514,7 @@ func (m *Manager) Run(parent context.Context) error {
 	}
 	}
 	raftConfig := c.Spec.Raft
 	raftConfig := c.Spec.Raft
 
 
-	if err := m.watchForKEKChanges(ctx); err != nil {
+	if err := m.watchForClusterChanges(ctx); err != nil {
 		return err
 		return err
 	}
 	}
 
 
@@ -679,7 +679,7 @@ func (m *Manager) updateKEK(ctx context.Context, cluster *api.Cluster) error {
 	return nil
 	return nil
 }
 }
 
 
-func (m *Manager) watchForKEKChanges(ctx context.Context) error {
+func (m *Manager) watchForClusterChanges(ctx context.Context) error {
 	clusterID := m.config.SecurityConfig.ClientTLSCreds.Organization()
 	clusterID := m.config.SecurityConfig.ClientTLSCreds.Organization()
 	clusterWatch, clusterWatchCancel, err := store.ViewAndWatch(m.raftNode.MemoryStore(),
 	clusterWatch, clusterWatchCancel, err := store.ViewAndWatch(m.raftNode.MemoryStore(),
 		func(tx store.ReadTx) error {
 		func(tx store.ReadTx) error {
@@ -687,6 +687,7 @@ func (m *Manager) watchForKEKChanges(ctx context.Context) error {
 			if cluster == nil {
 			if cluster == nil {
 				return fmt.Errorf("unable to get current cluster")
 				return fmt.Errorf("unable to get current cluster")
 			}
 			}
+			m.caserver.UpdateRootCA(ctx, cluster)
 			return m.updateKEK(ctx, cluster)
 			return m.updateKEK(ctx, cluster)
 		},
 		},
 		state.EventUpdateCluster{
 		state.EventUpdateCluster{
@@ -702,6 +703,7 @@ func (m *Manager) watchForKEKChanges(ctx context.Context) error {
 			select {
 			select {
 			case event := <-clusterWatch:
 			case event := <-clusterWatch:
 				clusterEvent := event.(state.EventUpdateCluster)
 				clusterEvent := event.(state.EventUpdateCluster)
+				m.caserver.UpdateRootCA(ctx, clusterEvent.Cluster)
 				m.updateKEK(ctx, clusterEvent.Cluster)
 				m.updateKEK(ctx, clusterEvent.Cluster)
 			case <-ctx.Done():
 			case <-ctx.Done():
 				clusterWatchCancel()
 				clusterWatchCancel()
@@ -1030,6 +1032,10 @@ func defaultClusterObject(
 	encryptionConfig api.EncryptionConfig,
 	encryptionConfig api.EncryptionConfig,
 	initialUnlockKeys []*api.EncryptionKey,
 	initialUnlockKeys []*api.EncryptionKey,
 	rootCA *ca.RootCA) *api.Cluster {
 	rootCA *ca.RootCA) *api.Cluster {
+	var caKey []byte
+	if rootCA.Signer != nil {
+		caKey = rootCA.Signer.Key
+	}
 
 
 	return &api.Cluster{
 	return &api.Cluster{
 		ID: clusterID,
 		ID: clusterID,
@@ -1048,7 +1054,7 @@ func defaultClusterObject(
 			EncryptionConfig: encryptionConfig,
 			EncryptionConfig: encryptionConfig,
 		},
 		},
 		RootCA: api.RootCA{
 		RootCA: api.RootCA{
-			CAKey:      rootCA.Key,
+			CAKey:      caKey,
 			CACert:     rootCA.Cert,
 			CACert:     rootCA.Cert,
 			CACertHash: rootCA.Digest.String(),
 			CACertHash: rootCA.Digest.String(),
 			JoinTokens: api.JoinTokens{
 			JoinTokens: api.JoinTokens{

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

@@ -132,14 +132,6 @@ func (p *peer) resolveAddr(ctx context.Context, id uint64) (string, error) {
 	return resp.Addr, nil
 	return resp.Addr, nil
 }
 }
 
 
-func (p *peer) reportSnapshot(failure bool) {
-	if failure {
-		p.tr.config.ReportSnapshot(p.id, raft.SnapshotFailure)
-		return
-	}
-	p.tr.config.ReportSnapshot(p.id, raft.SnapshotFinish)
-}
-
 func (p *peer) sendProcessMessage(ctx context.Context, m raftpb.Message) error {
 func (p *peer) sendProcessMessage(ctx context.Context, m raftpb.Message) error {
 	ctx, cancel := context.WithTimeout(ctx, p.tr.config.SendTimeout)
 	ctx, cancel := context.WithTimeout(ctx, p.tr.config.SendTimeout)
 	defer cancel()
 	defer cancel()
@@ -151,9 +143,9 @@ func (p *peer) sendProcessMessage(ctx context.Context, m raftpb.Message) error {
 		if err != nil {
 		if err != nil {
 			p.tr.config.ReportSnapshot(m.To, raft.SnapshotFailure)
 			p.tr.config.ReportSnapshot(m.To, raft.SnapshotFailure)
 		} else {
 		} else {
+			p.tr.config.ReportSnapshot(m.To, raft.SnapshotFinish)
 		}
 		}
 	}
 	}
-	p.reportSnapshot(err != nil)
 	if err != nil {
 	if err != nil {
 		p.tr.config.ReportUnreachable(m.To)
 		p.tr.config.ReportUnreachable(m.To)
 		return err
 		return err

+ 80 - 37
vendor/github.com/docker/swarmkit/node/node.go

@@ -33,7 +33,10 @@ import (
 	"google.golang.org/grpc/credentials"
 	"google.golang.org/grpc/credentials"
 )
 )
 
 
-const stateFilename = "state.json"
+const (
+	stateFilename     = "state.json"
+	roleChangeTimeout = 16 * time.Second
+)
 
 
 var (
 var (
 	errNodeStarted    = errors.New("node: already started")
 	errNodeStarted    = errors.New("node: already started")
@@ -269,12 +272,11 @@ func (n *Node) run(ctx context.Context) (err error) {
 				}
 				}
 				n.Lock()
 				n.Lock()
 				// If we got a role change, renew
 				// If we got a role change, renew
-				lastRole := n.role
 				role := ca.WorkerRole
 				role := ca.WorkerRole
 				if node.Role == api.NodeRoleManager {
 				if node.Role == api.NodeRoleManager {
 					role = ca.ManagerRole
 					role = ca.ManagerRole
 				}
 				}
-				if lastRole == role {
+				if n.role == role {
 					n.Unlock()
 					n.Unlock()
 					continue
 					continue
 				}
 				}
@@ -284,23 +286,23 @@ func (n *Node) run(ctx context.Context) (err error) {
 		}
 		}
 	}()
 	}()
 
 
+	var wg sync.WaitGroup
+	wg.Add(3)
+
 	updates := ca.RenewTLSConfig(ctx, securityConfig, n.connBroker, forceCertRenewal)
 	updates := ca.RenewTLSConfig(ctx, securityConfig, n.connBroker, forceCertRenewal)
 	go func() {
 	go func() {
-		for {
-			select {
-			case certUpdate := <-updates:
-				if certUpdate.Err != nil {
-					logrus.Warnf("error renewing TLS certificate: %v", certUpdate.Err)
-					continue
-				}
-				n.Lock()
-				n.role = certUpdate.Role
-				n.roleCond.Broadcast()
-				n.Unlock()
-			case <-ctx.Done():
-				return
+		for certUpdate := range updates {
+			if certUpdate.Err != nil {
+				logrus.Warnf("error renewing TLS certificate: %v", certUpdate.Err)
+				continue
 			}
 			}
+			n.Lock()
+			n.role = certUpdate.Role
+			n.roleCond.Broadcast()
+			n.Unlock()
 		}
 		}
+
+		wg.Done()
 	}()
 	}()
 
 
 	role := n.role
 	role := n.role
@@ -309,10 +311,8 @@ func (n *Node) run(ctx context.Context) (err error) {
 	agentReady := make(chan struct{})
 	agentReady := make(chan struct{})
 	var managerErr error
 	var managerErr error
 	var agentErr error
 	var agentErr error
-	var wg sync.WaitGroup
-	wg.Add(2)
 	go func() {
 	go func() {
-		managerErr = n.superviseManager(ctx, securityConfig, managerReady) // store err and loop
+		managerErr = n.superviseManager(ctx, securityConfig, managerReady, forceCertRenewal) // store err and loop
 		wg.Done()
 		wg.Done()
 		cancel()
 		cancel()
 	}()
 	}()
@@ -703,7 +703,7 @@ func (n *Node) waitRole(ctx context.Context, role string) error {
 	return nil
 	return nil
 }
 }
 
 
-func (n *Node) runManager(ctx context.Context, securityConfig *ca.SecurityConfig, ready chan struct{}, workerRole <-chan struct{}) error {
+func (n *Node) runManager(ctx context.Context, securityConfig *ca.SecurityConfig, ready chan struct{}, workerRole <-chan struct{}) (bool, error) {
 	var remoteAPI *manager.RemoteAddrs
 	var remoteAPI *manager.RemoteAddrs
 	if n.config.ListenRemoteAPI != "" {
 	if n.config.ListenRemoteAPI != "" {
 		remoteAPI = &manager.RemoteAddrs{
 		remoteAPI = &manager.RemoteAddrs{
@@ -729,7 +729,7 @@ func (n *Node) runManager(ctx context.Context, securityConfig *ca.SecurityConfig
 		PluginGetter:     n.config.PluginGetter,
 		PluginGetter:     n.config.PluginGetter,
 	})
 	})
 	if err != nil {
 	if err != nil {
-		return err
+		return false, err
 	}
 	}
 	done := make(chan struct{})
 	done := make(chan struct{})
 	var runErr error
 	var runErr error
@@ -762,7 +762,7 @@ func (n *Node) runManager(ctx context.Context, securityConfig *ca.SecurityConfig
 	// wait for manager stop or for role change
 	// wait for manager stop or for role change
 	select {
 	select {
 	case <-done:
 	case <-done:
-		return runErr
+		return false, runErr
 	case <-workerRole:
 	case <-workerRole:
 		log.G(ctx).Info("role changed to worker, stopping manager")
 		log.G(ctx).Info("role changed to worker, stopping manager")
 		clearData = true
 		clearData = true
@@ -770,12 +770,12 @@ func (n *Node) runManager(ctx context.Context, securityConfig *ca.SecurityConfig
 		log.G(ctx).Info("manager removed from raft cluster, stopping manager")
 		log.G(ctx).Info("manager removed from raft cluster, stopping manager")
 		clearData = true
 		clearData = true
 	case <-ctx.Done():
 	case <-ctx.Done():
-		return ctx.Err()
+		return false, ctx.Err()
 	}
 	}
-	return nil
+	return clearData, nil
 }
 }
 
 
-func (n *Node) superviseManager(ctx context.Context, securityConfig *ca.SecurityConfig, ready chan struct{}) error {
+func (n *Node) superviseManager(ctx context.Context, securityConfig *ca.SecurityConfig, ready chan struct{}, forceCertRenewal chan struct{}) error {
 	for {
 	for {
 		if err := n.waitRole(ctx, ca.ManagerRole); err != nil {
 		if err := n.waitRole(ctx, ca.ManagerRole); err != nil {
 			return err
 			return err
@@ -789,7 +789,8 @@ func (n *Node) superviseManager(ctx context.Context, securityConfig *ca.Security
 			}
 			}
 		}()
 		}()
 
 
-		if err := n.runManager(ctx, securityConfig, ready, workerRole); err != nil {
+		wasRemoved, err := n.runManager(ctx, securityConfig, ready, workerRole)
+		if err != nil {
 			waitRoleCancel()
 			waitRoleCancel()
 			return errors.Wrap(err, "manager stopped")
 			return errors.Wrap(err, "manager stopped")
 		}
 		}
@@ -798,18 +799,60 @@ func (n *Node) superviseManager(ctx context.Context, securityConfig *ca.Security
 		// "manager", it's possible that the manager was demoted and
 		// "manager", it's possible that the manager was demoted and
 		// the agent hasn't realized this yet. We should wait for the
 		// the agent hasn't realized this yet. We should wait for the
 		// role to change instead of restarting the manager immediately.
 		// role to change instead of restarting the manager immediately.
-		timer := time.NewTimer(16 * time.Second)
-		select {
-		case <-timer.C:
-			log.G(ctx).Warn("failed to get worker role after manager stop, restarting manager")
-		case <-workerRole:
-		case <-ctx.Done():
-			timer.Stop()
-			waitRoleCancel()
-			return ctx.Err()
+		err = func() error {
+			timer := time.NewTimer(roleChangeTimeout)
+			defer timer.Stop()
+			defer waitRoleCancel()
+
+			select {
+			case <-timer.C:
+			case <-workerRole:
+				return nil
+			case <-ctx.Done():
+				return ctx.Err()
+			}
+
+			if !wasRemoved {
+				log.G(ctx).Warn("failed to get worker role after manager stop, restarting manager")
+				return nil
+			}
+			// We need to be extra careful about restarting the
+			// manager. It may cause the node to wrongly join under
+			// a new Raft ID. Since we didn't see a role change
+			// yet, force a certificate renewal. If the certificate
+			// comes back with a worker role, we know we shouldn't
+			// restart the manager. However, if we don't see
+			// workerRole get closed, it means we didn't switch to
+			// a worker certificate, either because we couldn't
+			// contact a working CA, or because we've been
+			// re-promoted. In this case, we must assume we were
+			// re-promoted, and restart the manager.
+			log.G(ctx).Warn("failed to get worker role after manager stop, forcing certificate renewal")
+			timer.Reset(roleChangeTimeout)
+
+			select {
+			case forceCertRenewal <- struct{}{}:
+			case <-timer.C:
+				log.G(ctx).Warn("failed to trigger certificate renewal after manager stop, restarting manager")
+				return nil
+			case <-ctx.Done():
+				return ctx.Err()
+			}
+
+			// Now that the renewal request has been sent to the
+			// renewal goroutine, wait for a change in role.
+			select {
+			case <-timer.C:
+				log.G(ctx).Warn("failed to get worker role after manager stop, restarting manager")
+			case <-workerRole:
+			case <-ctx.Done():
+				return ctx.Err()
+			}
+			return nil
+		}()
+		if err != nil {
+			return err
 		}
 		}
-		timer.Stop()
-		waitRoleCancel()
 
 
 		ready = nil
 		ready = nil
 	}
 	}