Переглянути джерело

Update SwarmKit to 6bc357e9c5f0ac2cdf801898a43d08c260b4d5d0

This fix tries to update the SwarmKit from
ed384f3b3957f65e3111bd020f9815f3d4296fa2
to
6bc357e9c5f0ac2cdf801898a43d08c260b4d5d0

The following is the list of docker related changes:
1. Took long time for Docker Swarm service turn desired state from Ready to Running (Issue #28291)
2. Native Swarm in 1.12 - panic: runtime error: index out of range (Issue #25608)
3. Global mode target replicas keep increasing (Issue #30854)
4. Creating service with publish mode=host and without published port crashes swarm manager (Issue #30938)
5. Define signals used to stop containers for updates (Issue #25696) (PR #30754)

This fix fixes #28291, #25608, #30854, #30938.
This fix is required by PR #30754.

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
Yong Tang 8 роки тому
батько
коміт
ec860ca252
33 змінених файлів з 879 додано та 519 видалено
  1. 1 1
      vendor.conf
  2. 5 5
      vendor/github.com/docker/swarmkit/agent/agent.go
  3. 2 4
      vendor/github.com/docker/swarmkit/agent/exec/errors.go
  4. 4 4
      vendor/github.com/docker/swarmkit/agent/secrets/secrets.go
  5. 4 1
      vendor/github.com/docker/swarmkit/agent/worker.go
  6. 176 113
      vendor/github.com/docker/swarmkit/api/control.pb.go
  7. 15 0
      vendor/github.com/docker/swarmkit/api/control.proto
  8. 1 1
      vendor/github.com/docker/swarmkit/api/naming/naming.go
  9. 257 157
      vendor/github.com/docker/swarmkit/api/specs.pb.go
  10. 7 1
      vendor/github.com/docker/swarmkit/api/specs.proto
  11. 0 11
      vendor/github.com/docker/swarmkit/api/types.pb.go
  12. 0 11
      vendor/github.com/docker/swarmkit/api/types.proto
  13. 30 28
      vendor/github.com/docker/swarmkit/ca/certificates.go
  14. 1 2
      vendor/github.com/docker/swarmkit/ca/external.go
  15. 1 1
      vendor/github.com/docker/swarmkit/ca/keyreadwriter.go
  16. 3 2
      vendor/github.com/docker/swarmkit/manager/allocator/network.go
  17. 1 1
      vendor/github.com/docker/swarmkit/manager/allocator/networkallocator/networkallocator.go
  18. 2 1
      vendor/github.com/docker/swarmkit/manager/allocator/networkallocator/portallocator.go
  19. 1 1
      vendor/github.com/docker/swarmkit/manager/controlapi/secret.go
  20. 48 13
      vendor/github.com/docker/swarmkit/manager/controlapi/service.go
  21. 1 1
      vendor/github.com/docker/swarmkit/manager/encryption/nacl.go
  22. 0 2
      vendor/github.com/docker/swarmkit/manager/keymanager/keymanager.go
  23. 16 4
      vendor/github.com/docker/swarmkit/manager/orchestrator/constraintenforcer/constraint_enforcer.go
  24. 104 31
      vendor/github.com/docker/swarmkit/manager/orchestrator/global/global.go
  25. 5 0
      vendor/github.com/docker/swarmkit/manager/orchestrator/replicated/services.go
  26. 39 92
      vendor/github.com/docker/swarmkit/manager/orchestrator/replicated/tasks.go
  27. 7 0
      vendor/github.com/docker/swarmkit/manager/orchestrator/task.go
  28. 103 0
      vendor/github.com/docker/swarmkit/manager/orchestrator/taskinit/init.go
  29. 12 5
      vendor/github.com/docker/swarmkit/manager/orchestrator/taskreaper/task_reaper.go
  30. 30 23
      vendor/github.com/docker/swarmkit/manager/orchestrator/update/updater.go
  31. 1 1
      vendor/github.com/docker/swarmkit/manager/state/doc.go
  32. 1 1
      vendor/github.com/docker/swarmkit/manager/state/raft/storage/snapwrap.go
  33. 1 1
      vendor/github.com/docker/swarmkit/manager/state/raft/storage/walwrap.go

+ 1 - 1
vendor.conf

@@ -103,7 +103,7 @@ github.com/docker/containerd 78fb8f45890a601e0fd9051cf9f9f74923e950fd
 github.com/tonistiigi/fifo 1405643975692217d6720f8b54aeee1bf2cd5cf4
 
 # cluster
-github.com/docker/swarmkit ed384f3b3957f65e3111bd020f9815f3d4296fa2
+github.com/docker/swarmkit 6bc357e9c5f0ac2cdf801898a43d08c260b4d5d0
 github.com/golang/mock bd3c8e81be01eef76d4b503f5e687d2d1354d2d9
 github.com/gogo/protobuf 8d70fb3182befc465c4a1eac8ad4d38ff49778e2
 github.com/cloudflare/cfssl 7fb22c8cba7ecaf98e4082d22d65800cf45e042a

+ 5 - 5
vendor/github.com/docker/swarmkit/agent/agent.go

@@ -179,13 +179,13 @@ func (a *Agent) run(ctx context.Context) {
 
 	ctx = log.WithModule(ctx, "agent")
 
-	log.G(ctx).Debugf("(*Agent).run")
-	defer log.G(ctx).Debugf("(*Agent).run exited")
+	log.G(ctx).Debug("(*Agent).run")
+	defer log.G(ctx).Debug("(*Agent).run exited")
 
 	// get the node description
 	nodeDescription, err := a.nodeDescriptionWithHostname(ctx)
 	if err != nil {
-		log.G(ctx).WithError(err).WithField("agent", a.config.Executor).Errorf("agent: node description unavailable")
+		log.G(ctx).WithError(err).WithField("agent", a.config.Executor).Error("agent: node description unavailable")
 	}
 	// nodeUpdateTicker is used to periodically check for updates to node description
 	nodeUpdateTicker := time.NewTicker(nodeUpdatePeriod)
@@ -312,7 +312,7 @@ func (a *Agent) run(ctx context.Context) {
 			// get the current node description
 			newNodeDescription, err := a.nodeDescriptionWithHostname(ctx)
 			if err != nil {
-				log.G(ctx).WithError(err).WithField("agent", a.config.Executor).Errorf("agent: updated node description unavailable")
+				log.G(ctx).WithError(err).WithField("agent", a.config.Executor).Error("agent: updated node description unavailable")
 			}
 
 			// if newNodeDescription is nil, it will cause a panic when
@@ -431,7 +431,7 @@ func (a *Agent) withSession(ctx context.Context, fn func(session *session) error
 //
 // If an error is returned, the operation should be retried.
 func (a *Agent) UpdateTaskStatus(ctx context.Context, taskID string, status *api.TaskStatus) error {
-	log.G(ctx).WithField("task.id", taskID).Debugf("(*Agent).UpdateTaskStatus")
+	log.G(ctx).WithField("task.id", taskID).Debug("(*Agent).UpdateTaskStatus")
 	ctx, cancel := context.WithCancel(ctx)
 	defer cancel()
 

+ 2 - 4
vendor/github.com/docker/swarmkit/agent/exec/errors.go

@@ -66,10 +66,8 @@ func (t temporary) Temporary() bool { return true }
 // temporary.
 func IsTemporary(err error) bool {
 	for err != nil {
-		if tmp, ok := err.(Temporary); ok {
-			if tmp.Temporary() {
-				return true
-			}
+		if tmp, ok := err.(Temporary); ok && tmp.Temporary() {
+			return true
 		}
 
 		cause := errors.Cause(err)

+ 4 - 4
vendor/github.com/docker/swarmkit/agent/secrets/secrets.go

@@ -8,7 +8,7 @@ import (
 )
 
 // secrets is a map that keeps all the currently available secrets to the agent
-// mapped by secret ID
+// mapped by secret ID.
 type secrets struct {
 	mu sync.RWMutex
 	m  map[string]*api.Secret
@@ -31,7 +31,7 @@ func (s *secrets) Get(secretID string) *api.Secret {
 	return nil
 }
 
-// add adds one or more secrets to the secret map
+// Add adds one or more secrets to the secret map.
 func (s *secrets) Add(secrets ...api.Secret) {
 	s.mu.Lock()
 	defer s.mu.Unlock()
@@ -40,7 +40,7 @@ func (s *secrets) Add(secrets ...api.Secret) {
 	}
 }
 
-// remove removes one or more secrets by ID from the secret map.  Succeeds
+// Remove removes one or more secrets by ID from the secret map.  Succeeds
 // whether or not the given IDs are in the map.
 func (s *secrets) Remove(secrets []string) {
 	s.mu.Lock()
@@ -50,7 +50,7 @@ func (s *secrets) Remove(secrets []string) {
 	}
 }
 
-// reset removes all the secrets
+// Reset removes all the secrets.
 func (s *secrets) Reset() {
 	s.mu.Lock()
 	defer s.mu.Unlock()

+ 4 - 1
vendor/github.com/docker/swarmkit/agent/worker.go

@@ -396,7 +396,10 @@ func (w *worker) taskManager(ctx context.Context, tx *bolt.Tx, task *api.Task) (
 }
 
 func (w *worker) newTaskManager(ctx context.Context, tx *bolt.Tx, task *api.Task) (*taskManager, error) {
-	ctx = log.WithLogger(ctx, log.G(ctx).WithField("task.id", task.ID))
+	ctx = log.WithLogger(ctx, log.G(ctx).WithFields(logrus.Fields{
+		"task.id":    task.ID,
+		"service.id": task.ServiceID,
+	}))
 
 	ctlr, status, err := exec.Resolve(ctx, task, w.executor)
 	if err := w.updateTaskStatus(ctx, tx, task.ID, status); err != nil {

+ 176 - 113
vendor/github.com/docker/swarmkit/api/control.pb.go

@@ -34,6 +34,33 @@ var _ = proto.Marshal
 var _ = fmt.Errorf
 var _ = math.Inf
 
+type UpdateServiceRequest_Rollback int32
+
+const (
+	// This is not a rollback. The spec field of the request will
+	// be honored.
+	UpdateServiceRequest_NONE UpdateServiceRequest_Rollback = 0
+	// Roll back the service - get spec from the service's
+	// previous_spec.
+	UpdateServiceRequest_PREVIOUS UpdateServiceRequest_Rollback = 1
+)
+
+var UpdateServiceRequest_Rollback_name = map[int32]string{
+	0: "NONE",
+	1: "PREVIOUS",
+}
+var UpdateServiceRequest_Rollback_value = map[string]int32{
+	"NONE":     0,
+	"PREVIOUS": 1,
+}
+
+func (x UpdateServiceRequest_Rollback) String() string {
+	return proto.EnumName(UpdateServiceRequest_Rollback_name, int32(x))
+}
+func (UpdateServiceRequest_Rollback) EnumDescriptor() ([]byte, []int) {
+	return fileDescriptorControl, []int{18, 0}
+}
+
 type GetNodeRequest struct {
 	NodeID string `protobuf:"bytes,1,opt,name=node_id,json=nodeId,proto3" json:"node_id,omitempty"`
 }
@@ -220,6 +247,10 @@ type UpdateServiceRequest struct {
 	ServiceID      string       `protobuf:"bytes,1,opt,name=service_id,json=serviceId,proto3" json:"service_id,omitempty"`
 	ServiceVersion *Version     `protobuf:"bytes,2,opt,name=service_version,json=serviceVersion" json:"service_version,omitempty"`
 	Spec           *ServiceSpec `protobuf:"bytes,3,opt,name=spec" json:"spec,omitempty"`
+	// Rollback may be set to PREVIOUS to request a rollback (the service's
+	// spec will be set to the value of its previous_spec field). In this
+	// case, the spec field of this request is ignored.
+	Rollback UpdateServiceRequest_Rollback `protobuf:"varint,4,opt,name=rollback,proto3,enum=docker.swarmkit.v1.UpdateServiceRequest_Rollback" json:"rollback,omitempty"`
 }
 
 func (m *UpdateServiceRequest) Reset()                    { *m = UpdateServiceRequest{} }
@@ -614,6 +645,7 @@ func init() {
 	proto.RegisterType((*CreateSecretResponse)(nil), "docker.swarmkit.v1.CreateSecretResponse")
 	proto.RegisterType((*RemoveSecretRequest)(nil), "docker.swarmkit.v1.RemoveSecretRequest")
 	proto.RegisterType((*RemoveSecretResponse)(nil), "docker.swarmkit.v1.RemoveSecretResponse")
+	proto.RegisterEnum("docker.swarmkit.v1.UpdateServiceRequest_Rollback", UpdateServiceRequest_Rollback_name, UpdateServiceRequest_Rollback_value)
 }
 
 type authenticatedWrapperControlServer struct {
@@ -3602,6 +3634,11 @@ func (m *UpdateServiceRequest) MarshalTo(dAtA []byte) (int, error) {
 		}
 		i += n18
 	}
+	if m.Rollback != 0 {
+		dAtA[i] = 0x20
+		i++
+		i = encodeVarintControl(dAtA, i, uint64(m.Rollback))
+	}
 	return i, nil
 }
 
@@ -6030,6 +6067,9 @@ func (m *UpdateServiceRequest) Size() (n int) {
 		l = m.Spec.Size()
 		n += 1 + l + sovControl(uint64(l))
 	}
+	if m.Rollback != 0 {
+		n += 1 + sovControl(uint64(m.Rollback))
+	}
 	return n
 }
 
@@ -6741,6 +6781,7 @@ func (this *UpdateServiceRequest) String() string {
 		`ServiceID:` + fmt.Sprintf("%v", this.ServiceID) + `,`,
 		`ServiceVersion:` + strings.Replace(fmt.Sprintf("%v", this.ServiceVersion), "Version", "Version", 1) + `,`,
 		`Spec:` + strings.Replace(fmt.Sprintf("%v", this.Spec), "ServiceSpec", "ServiceSpec", 1) + `,`,
+		`Rollback:` + fmt.Sprintf("%v", this.Rollback) + `,`,
 		`}`,
 	}, "")
 	return s
@@ -9511,6 +9552,25 @@ func (m *UpdateServiceRequest) Unmarshal(dAtA []byte) error {
 				return err
 			}
 			iNdEx = postIndex
+		case 4:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Rollback", wireType)
+			}
+			m.Rollback = 0
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowControl
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				m.Rollback |= (UpdateServiceRequest_Rollback(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
 		default:
 			iNdEx = preIndex
 			skippy, err := skipControl(dAtA[iNdEx:])
@@ -13250,117 +13310,120 @@ var (
 func init() { proto.RegisterFile("control.proto", fileDescriptorControl) }
 
 var fileDescriptorControl = []byte{
-	// 1781 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xcc, 0x5a, 0xdd, 0x6f, 0x1b, 0xc5,
-	0x16, 0xaf, 0xed, 0x24, 0x4e, 0x8e, 0xe3, 0x7c, 0x4c, 0xdc, 0x5e, 0xcb, 0xed, 0x4d, 0xaa, 0xed,
-	0x6d, 0xea, 0x5c, 0xe5, 0x3a, 0x17, 0x97, 0x8a, 0x52, 0xc4, 0x47, 0x93, 0xd0, 0xe2, 0xa6, 0x84,
-	0x6a, 0xd3, 0x22, 0xde, 0x22, 0xc7, 0x9e, 0x86, 0xad, 0x1d, 0xaf, 0xd9, 0xdd, 0xa4, 0x8d, 0x78,
-	0x01, 0x04, 0x7f, 0x02, 0x12, 0xaf, 0xbc, 0x82, 0xc4, 0x33, 0x6f, 0xbc, 0x56, 0x3c, 0xf1, 0xc8,
-	0x53, 0x44, 0x2d, 0x21, 0xf1, 0xc4, 0x9f, 0x80, 0xd0, 0xcc, 0x9c, 0xd9, 0x2f, 0xcf, 0xee, 0xda,
-	0x49, 0x50, 0xfa, 0x14, 0xef, 0xec, 0xef, 0xcc, 0x39, 0x33, 0xe7, 0x37, 0xbf, 0x3d, 0x73, 0x14,
-	0xc8, 0x37, 0xcc, 0x8e, 0x63, 0x99, 0xed, 0x4a, 0xd7, 0x32, 0x1d, 0x93, 0x90, 0xa6, 0xd9, 0x68,
-	0x51, 0xab, 0x62, 0x3f, 0xad, 0x5b, 0x7b, 0x2d, 0xc3, 0xa9, 0x1c, 0xbc, 0x52, 0xca, 0xd9, 0x5d,
-	0xda, 0xb0, 0x05, 0xa0, 0x94, 0x37, 0x77, 0x9e, 0xd0, 0x86, 0x23, 0x1f, 0x73, 0xce, 0x61, 0x97,
-	0xca, 0x87, 0xc2, 0xae, 0xb9, 0x6b, 0xf2, 0x9f, 0x2b, 0xec, 0x17, 0x8e, 0xce, 0x75, 0xdb, 0xfb,
-	0xbb, 0x46, 0x67, 0x45, 0xfc, 0x11, 0x83, 0xda, 0x0d, 0x98, 0xba, 0x4b, 0x9d, 0x4d, 0xb3, 0x49,
-	0x75, 0xfa, 0xc9, 0x3e, 0xb5, 0x1d, 0x72, 0x05, 0xb2, 0x1d, 0xb3, 0x49, 0xb7, 0x8d, 0x66, 0x31,
-	0x75, 0x39, 0x55, 0x9e, 0x58, 0x85, 0xde, 0xd1, 0xc2, 0x18, 0x43, 0xd4, 0xd6, 0xf5, 0x31, 0xf6,
-	0xaa, 0xd6, 0xd4, 0xde, 0x86, 0x69, 0xd7, 0xcc, 0xee, 0x9a, 0x1d, 0x9b, 0x92, 0x65, 0x18, 0x61,
-	0x2f, 0xb9, 0x51, 0xae, 0x5a, 0xac, 0xf4, 0x2f, 0xa0, 0xc2, 0xf1, 0x1c, 0xa5, 0x1d, 0x65, 0x60,
-	0xe6, 0xbe, 0x61, 0xf3, 0x29, 0x6c, 0xe9, 0xfa, 0x0e, 0x64, 0x1f, 0x1b, 0x6d, 0x87, 0x5a, 0x36,
-	0xce, 0xb2, 0xac, 0x9a, 0x25, 0x6c, 0x56, 0xb9, 0x23, 0x6c, 0x74, 0x69, 0x5c, 0xfa, 0x3c, 0x03,
-	0x59, 0x1c, 0x24, 0x05, 0x18, 0xed, 0xd4, 0xf7, 0x28, 0x9b, 0x31, 0x53, 0x9e, 0xd0, 0xc5, 0x03,
-	0x59, 0x81, 0x9c, 0xd1, 0xdc, 0xee, 0x5a, 0xf4, 0xb1, 0xf1, 0x8c, 0xda, 0xc5, 0x34, 0x7b, 0xb7,
-	0x3a, 0xd5, 0x3b, 0x5a, 0x80, 0xda, 0xfa, 0x03, 0x1c, 0xd5, 0xc1, 0x68, 0xca, 0xdf, 0xe4, 0x01,
-	0x8c, 0xb5, 0xeb, 0x3b, 0xb4, 0x6d, 0x17, 0x33, 0x97, 0x33, 0xe5, 0x5c, 0xf5, 0xe6, 0x30, 0x91,
-	0x55, 0xee, 0x73, 0xd3, 0x77, 0x3b, 0x8e, 0x75, 0xa8, 0xe3, 0x3c, 0xa4, 0x06, 0xb9, 0x3d, 0xba,
-	0xb7, 0x43, 0x2d, 0xfb, 0x63, 0xa3, 0x6b, 0x17, 0x47, 0x2e, 0x67, 0xca, 0x53, 0xd5, 0x6b, 0x51,
-	0xdb, 0xb6, 0xd5, 0xa5, 0x8d, 0xca, 0xfb, 0x2e, 0x5e, 0xf7, 0xdb, 0x92, 0x2a, 0x8c, 0x5a, 0x66,
-	0x9b, 0xda, 0xc5, 0x51, 0x3e, 0xc9, 0xa5, 0xc8, 0xbd, 0x37, 0xdb, 0x54, 0x17, 0x50, 0x72, 0x05,
-	0xf2, 0x6c, 0x2b, 0xbc, 0x3d, 0x18, 0xe3, 0xfb, 0x33, 0xc9, 0x06, 0xe5, 0xaa, 0x4b, 0xaf, 0x43,
-	0xce, 0x17, 0x3a, 0x99, 0x81, 0x4c, 0x8b, 0x1e, 0x0a, 0x5a, 0xe8, 0xec, 0x27, 0xdb, 0xdd, 0x83,
-	0x7a, 0x7b, 0x9f, 0x16, 0xd3, 0x7c, 0x4c, 0x3c, 0xdc, 0x4a, 0xdf, 0x4c, 0x69, 0x6b, 0x30, 0xeb,
-	0xdb, 0x0e, 0xe4, 0x48, 0x05, 0x46, 0x59, 0xf6, 0x45, 0x32, 0xe2, 0x48, 0x22, 0x60, 0xda, 0x77,
-	0x29, 0x98, 0x7d, 0xd4, 0x6d, 0xd6, 0x1d, 0x3a, 0x2c, 0x43, 0xc9, 0x5b, 0x30, 0xc9, 0x41, 0x07,
-	0xd4, 0xb2, 0x0d, 0xb3, 0xc3, 0x03, 0xcc, 0x55, 0x2f, 0xaa, 0x3c, 0x7e, 0x28, 0x20, 0x7a, 0x8e,
-	0x19, 0xe0, 0x03, 0xf9, 0x3f, 0x8c, 0xb0, 0xe3, 0x56, 0xcc, 0x70, 0xbb, 0x4b, 0x71, 0x79, 0xd1,
-	0x39, 0x52, 0x5b, 0x05, 0xe2, 0x8f, 0xf5, 0x58, 0xc7, 0x62, 0x13, 0x66, 0x75, 0xba, 0x67, 0x1e,
-	0x0c, 0xbf, 0xde, 0x02, 0x8c, 0x3e, 0x36, 0xad, 0x86, 0xc8, 0xc4, 0xb8, 0x2e, 0x1e, 0xb4, 0x02,
-	0x10, 0xff, 0x7c, 0x22, 0x26, 0x3c, 0xf4, 0x0f, 0xeb, 0x76, 0xcb, 0xe7, 0xc2, 0xa9, 0xdb, 0xad,
-	0x90, 0x0b, 0x86, 0x60, 0x2e, 0xd8, 0x2b, 0xf7, 0xd0, 0x0b, 0x33, 0x6f, 0x75, 0xec, 0x65, 0xdc,
-	0xea, 0x38, 0x9e, 0xa3, 0xb4, 0x9b, 0x72, 0x75, 0x43, 0xbb, 0x76, 0xd7, 0xe1, 0xf7, 0xae, 0xfd,
-	0x85, 0x22, 0xc2, 0x06, 0x8f, 0x21, 0x22, 0x7e, 0xb3, 0x7e, 0x11, 0xf9, 0xf6, 0x0c, 0x45, 0x44,
-	0x15, 0x99, 0x52, 0x44, 0x56, 0x20, 0x67, 0x53, 0xeb, 0xc0, 0x68, 0x30, 0x76, 0x08, 0x11, 0xc1,
-	0x10, 0xb6, 0xc4, 0x70, 0x6d, 0xdd, 0xd6, 0x01, 0x21, 0xb5, 0xa6, 0x4d, 0x16, 0x61, 0x1c, 0xb9,
-	0x24, 0xd4, 0x62, 0x62, 0x35, 0xd7, 0x3b, 0x5a, 0xc8, 0x0a, 0x32, 0xd9, 0x7a, 0x56, 0xb0, 0xc9,
-	0x26, 0xeb, 0x30, 0xd5, 0xa4, 0xb6, 0x61, 0xd1, 0xe6, 0xb6, 0xed, 0xd4, 0x1d, 0xd4, 0x87, 0xa9,
-	0xea, 0xbf, 0xa3, 0x52, 0xbc, 0xc5, 0x50, 0x7a, 0x1e, 0x8d, 0xf8, 0x93, 0x42, 0x64, 0xb2, 0xff,
-	0x88, 0xc8, 0xe0, 0x76, 0x79, 0x22, 0xc3, 0x58, 0x13, 0x2b, 0x32, 0x9c, 0x46, 0x02, 0xa6, 0x6d,
-	0x40, 0x61, 0xcd, 0xa2, 0x75, 0x87, 0xe2, 0x96, 0x49, 0x22, 0x5d, 0x47, 0x05, 0x10, 0x2c, 0x5a,
-	0x50, 0x4d, 0x83, 0x16, 0x3e, 0x11, 0xd8, 0x84, 0xf3, 0xa1, 0xc9, 0x30, 0xaa, 0x1b, 0x90, 0xc5,
-	0x34, 0xe0, 0x84, 0x17, 0x63, 0x26, 0xd4, 0x25, 0x56, 0xbb, 0x0d, 0xb3, 0x77, 0xa9, 0x13, 0x8a,
-	0x6c, 0x19, 0xc0, 0xcb, 0x3a, 0x9e, 0x9a, 0x7c, 0xef, 0x68, 0x61, 0xc2, 0x4d, 0xba, 0x3e, 0xe1,
-	0xe6, 0x5c, 0xdb, 0x00, 0xe2, 0x9f, 0xe2, 0x64, 0xf1, 0xfc, 0x94, 0x82, 0x82, 0x50, 0xb9, 0x93,
-	0xc4, 0x44, 0xd6, 0x61, 0x5a, 0xa2, 0x87, 0x10, 0xe8, 0x29, 0xb4, 0x91, 0x1a, 0x7d, 0x3d, 0xa0,
-	0xd1, 0x83, 0x67, 0x28, 0xb4, 0x80, 0x93, 0xed, 0xc8, 0x3a, 0x14, 0x84, 0x34, 0x9d, 0x28, 0x49,
-	0xff, 0x82, 0xf3, 0xa1, 0x59, 0x50, 0xe3, 0xfe, 0x48, 0xc3, 0x1c, 0xe3, 0x38, 0x8e, 0xbb, 0x32,
-	0x57, 0x0b, 0xcb, 0xdc, 0x4a, 0x94, 0x98, 0x84, 0x2c, 0xfb, 0x95, 0xee, 0xab, 0xf4, 0xa9, 0x2b,
-	0xdd, 0x56, 0x48, 0xe9, 0xde, 0x18, 0x32, 0x38, 0xa5, 0xd8, 0xf5, 0xa9, 0xc9, 0xc8, 0xe9, 0xaa,
-	0xc9, 0x07, 0x50, 0x08, 0x86, 0x84, 0xc4, 0x78, 0x0d, 0xc6, 0x31, 0x51, 0x52, 0x53, 0x62, 0x99,
-	0xe1, 0x82, 0x3d, 0x65, 0xd9, 0xa4, 0xce, 0x53, 0xd3, 0x6a, 0x0d, 0xa1, 0x2c, 0x68, 0xa1, 0x52,
-	0x16, 0x77, 0x32, 0x8f, 0xb7, 0x1d, 0x31, 0x14, 0xc7, 0x5b, 0x69, 0x25, 0xb1, 0xda, 0x23, 0xae,
-	0x2c, 0xa1, 0xc8, 0x08, 0x8c, 0xb0, 0xdd, 0xc4, 0xfd, 0xe2, 0xbf, 0x19, 0x91, 0xd1, 0x86, 0x11,
-	0x39, 0xed, 0x11, 0x19, 0x6d, 0x19, 0x91, 0x11, 0xe0, 0xaa, 0xcd, 0x29, 0xc5, 0xf8, 0x91, 0x3c,
-	0x5b, 0xa7, 0x1e, 0xa6, 0x7b, 0xde, 0x42, 0x91, 0xba, 0xe7, 0x0d, 0xc7, 0x8f, 0x71, 0xde, 0x42,
-	0x96, 0x2f, 0xd7, 0x79, 0x8b, 0x08, 0xee, 0x2c, 0xcf, 0x9b, 0x17, 0x92, 0x77, 0xde, 0x30, 0x51,
-	0xb1, 0xe7, 0x4d, 0x66, 0xce, 0x05, 0xe3, 0xc7, 0x72, 0xad, 0xbd, 0x6f, 0x3b, 0xd4, 0xf2, 0xe9,
-	0x70, 0x43, 0x8c, 0x84, 0x74, 0x18, 0x71, 0x8c, 0x17, 0x08, 0x70, 0xe9, 0xeb, 0x4e, 0xe1, 0xd1,
-	0x17, 0x21, 0x71, 0xf4, 0x95, 0x56, 0x12, 0xeb, 0x72, 0x09, 0x5f, 0x1c, 0x83, 0x4b, 0x21, 0xcb,
-	0x97, 0x8b, 0x4b, 0x11, 0xc1, 0x9d, 0x25, 0x97, 0xbc, 0x90, 0x3c, 0x2e, 0x61, 0x36, 0x62, 0xb9,
-	0x24, 0x53, 0xe7, 0x82, 0xb5, 0xaf, 0x53, 0x90, 0xdb, 0xa0, 0x87, 0xba, 0xe9, 0xd4, 0x1d, 0x56,
-	0x6b, 0xfc, 0x17, 0x66, 0x19, 0xc9, 0xa8, 0xb5, 0xfd, 0xc4, 0x34, 0x3a, 0xdb, 0x8e, 0xd9, 0xa2,
-	0x1d, 0x1e, 0xda, 0xb8, 0x3e, 0x2d, 0x5e, 0xdc, 0x33, 0x8d, 0xce, 0x43, 0x36, 0x4c, 0x96, 0x81,
-	0xec, 0xd5, 0x3b, 0xf5, 0xdd, 0x20, 0x58, 0x5c, 0xcc, 0x66, 0xf0, 0x8d, 0x12, 0xbd, 0xdf, 0x69,
-	0x9b, 0x8d, 0xd6, 0x36, 0x5b, 0x75, 0x26, 0x80, 0x7e, 0xc4, 0x5f, 0x6c, 0xd0, 0x43, 0xed, 0x8b,
-	0xb4, 0x2c, 0xc0, 0x4e, 0xc2, 0x73, 0x56, 0x80, 0x49, 0xf4, 0x30, 0x05, 0x18, 0xda, 0x0c, 0x51,
-	0x80, 0xa1, 0x77, 0xef, 0x43, 0x46, 0x6e, 0xc3, 0xb8, 0x85, 0xbb, 0x5a, 0x1c, 0x89, 0x36, 0xf4,
-	0x6d, 0xfe, 0xea, 0xc8, 0xf3, 0xa3, 0x85, 0x73, 0xba, 0x6b, 0xe6, 0xd5, 0x70, 0xa7, 0x74, 0x50,
-	0xdf, 0x84, 0x19, 0x5e, 0x22, 0x37, 0x2c, 0xea, 0xc8, 0xfd, 0x5c, 0x82, 0x09, 0x9b, 0x0f, 0x78,
-	0xdb, 0x39, 0xd9, 0x3b, 0x5a, 0x18, 0x17, 0xa8, 0xda, 0x3a, 0xfb, 0xce, 0xf3, 0x5f, 0x4d, 0xed,
-	0x2e, 0x16, 0xe9, 0xc2, 0x1c, 0x43, 0xa9, 0xc2, 0x98, 0x00, 0x60, 0x24, 0x25, 0x75, 0xcd, 0xc0,
-	0x6d, 0x10, 0xa9, 0xfd, 0x98, 0x82, 0x39, 0x59, 0x9c, 0x1e, 0x2f, 0x16, 0xb2, 0x0a, 0x53, 0x08,
-	0x1d, 0x22, 0xaf, 0x79, 0x61, 0x22, 0xd3, 0x5a, 0x0d, 0xa4, 0x75, 0x3e, 0x3a, 0x70, 0x5f, 0x79,
-	0x72, 0xcf, 0xbb, 0x17, 0x9c, 0x78, 0x1b, 0x7e, 0x4f, 0x03, 0x11, 0x95, 0x18, 0x7b, 0x74, 0x65,
-	0xf3, 0xbd, 0xb0, 0x6c, 0x56, 0xa2, 0xab, 0x4a, 0xbf, 0x61, 0xbf, 0x6a, 0x7e, 0x79, 0xfa, 0xaa,
-	0xa9, 0x87, 0x54, 0xf3, 0xd6, 0x70, 0xb1, 0x9d, 0x89, 0x68, 0x6e, 0xc8, 0xab, 0x05, 0x46, 0x84,
-	0x29, 0x7b, 0x95, 0x5d, 0x84, 0xf8, 0x10, 0x4a, 0x66, 0x5c, 0xce, 0x24, 0x54, 0xab, 0xc1, 0x9c,
-	0xbc, 0xf9, 0xfa, 0xa9, 0x5b, 0x0d, 0xd4, 0xba, 0x03, 0x73, 0x29, 0x38, 0xd5, 0x09, 0xb8, 0xf4,
-	0x0e, 0xcc, 0xc9, 0x8b, 0xd5, 0x31, 0x4f, 0xf7, 0x05, 0xef, 0x82, 0xe7, 0x8f, 0xa6, 0xfa, 0xfd,
-	0x05, 0xc8, 0xae, 0x89, 0xa6, 0x3d, 0x31, 0x20, 0x8b, 0xfd, 0x70, 0xa2, 0xa9, 0x82, 0x0a, 0xf6,
-	0xd8, 0x4b, 0x57, 0x62, 0x31, 0x58, 0x89, 0x9e, 0xff, 0xf9, 0x87, 0x3f, 0xbf, 0x49, 0x4f, 0x43,
-	0x9e, 0x83, 0xfe, 0x87, 0x5f, 0x02, 0x62, 0xc2, 0x84, 0xdb, 0x58, 0x25, 0xff, 0x19, 0xa4, 0x0d,
-	0x5d, 0xba, 0x9a, 0x80, 0x8a, 0x77, 0x68, 0x01, 0x78, 0x7d, 0x4d, 0xa2, 0x9c, 0xab, 0xaf, 0x47,
-	0x5b, 0x5a, 0x4c, 0x82, 0x25, 0xfa, 0xf4, 0xfa, 0x96, 0x6a, 0x9f, 0x7d, 0x7d, 0x52, 0xb5, 0x4f,
-	0x45, 0xfb, 0x33, 0xc2, 0xa7, 0xc8, 0xe1, 0xc3, 0xba, 0xdd, 0x8a, 0xcc, 0xa1, 0xaf, 0x6f, 0x19,
-	0x99, 0xc3, 0x40, 0x87, 0x32, 0x3e, 0x87, 0xbc, 0x6f, 0x15, 0x9d, 0x43, 0x7f, 0x17, 0x30, 0x3a,
-	0x87, 0x81, 0xe6, 0x57, 0xe2, 0x7e, 0xf2, 0xe5, 0xc5, 0xec, 0xa7, 0x7f, 0x85, 0x8b, 0x49, 0xb0,
-	0x44, 0x9f, 0x5e, 0xdf, 0x49, 0xed, 0xb3, 0xaf, 0xb5, 0xa5, 0xf6, 0xd9, 0xdf, 0xbe, 0x8a, 0xf2,
-	0xf9, 0x0c, 0x26, 0xfd, 0x57, 0x78, 0x72, 0x6d, 0xc0, 0xbe, 0x43, 0xa9, 0x9c, 0x0c, 0x8c, 0xf7,
-	0xfc, 0x29, 0xe4, 0x03, 0x8d, 0x3f, 0xa2, 0x9c, 0x51, 0xd5, 0x68, 0x2c, 0x2d, 0x0d, 0x80, 0x4c,
-	0x74, 0x1e, 0xe8, 0x69, 0xa9, 0x9d, 0xab, 0xfa, 0x76, 0x6a, 0xe7, 0xca, 0x06, 0x59, 0x8c, 0xf3,
-	0x40, 0xeb, 0x4a, 0xed, 0x5c, 0xd5, 0x23, 0x53, 0x3b, 0x57, 0xf7, 0xc1, 0x62, 0x49, 0x86, 0x57,
-	0xc1, 0x48, 0x92, 0x05, 0xdb, 0x07, 0x91, 0x24, 0x0b, 0xf7, 0x02, 0xe2, 0x49, 0x26, 0xef, 0xad,
-	0xd1, 0x24, 0x0b, 0x5d, 0xb6, 0xa3, 0x49, 0x16, 0xbe, 0x02, 0x27, 0x92, 0x4c, 0x2e, 0x38, 0x86,
-	0x64, 0xa1, 0x35, 0x2f, 0x0d, 0x80, 0x1c, 0x30, 0xcf, 0xb1, 0xce, 0x55, 0xfd, 0x9a, 0xb8, 0x3c,
-	0x0f, 0xe8, 0x5c, 0xe4, 0x19, 0x0b, 0xf7, 0xc8, 0x3c, 0x07, 0xaf, 0x44, 0x91, 0x79, 0x0e, 0xdd,
-	0x1a, 0x12, 0xf2, 0x2c, 0xef, 0x94, 0xd1, 0x79, 0x0e, 0x5d, 0x84, 0xa3, 0xf3, 0x1c, 0xbe, 0x9e,
-	0x26, 0x9e, 0x67, 0xb9, 0xe0, 0x98, 0xf3, 0x1c, 0x5a, 0xf3, 0xd2, 0x00, 0xc8, 0xc4, 0x8f, 0x93,
-	0x7b, 0x9b, 0x51, 0x7f, 0x9c, 0xc2, 0x77, 0xa5, 0xd2, 0xd5, 0x04, 0x54, 0xe2, 0x3e, 0xfb, 0xaf,
-	0x0e, 0xea, 0x7d, 0x56, 0x5c, 0x8b, 0x4a, 0xe5, 0x64, 0x60, 0xbc, 0xe7, 0x7d, 0xc8, 0xf9, 0x0a,
-	0x60, 0xb2, 0x38, 0x58, 0xcd, 0x5e, 0xba, 0x96, 0x88, 0x4b, 0x5c, 0xb0, 0xbf, 0xbe, 0x55, 0x2f,
-	0x58, 0x51, 0x4c, 0x97, 0xca, 0xc9, 0xc0, 0x44, 0xcf, 0xfe, 0x5a, 0x56, 0xed, 0x59, 0x51, 0x2f,
-	0x97, 0xca, 0xc9, 0xc0, 0x58, 0xcf, 0xab, 0xc5, 0xe7, 0x2f, 0xe6, 0xcf, 0xfd, 0xfa, 0x62, 0xfe,
-	0xdc, 0x67, 0xbd, 0xf9, 0xd4, 0xf3, 0xde, 0x7c, 0xea, 0x97, 0xde, 0x7c, 0xea, 0xb7, 0xde, 0x7c,
-	0x6a, 0x67, 0x8c, 0xff, 0x27, 0xca, 0xf5, 0xbf, 0x03, 0x00, 0x00, 0xff, 0xff, 0xb2, 0xa1, 0x31,
-	0x8d, 0x02, 0x23, 0x00, 0x00,
+	// 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,
 }

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

@@ -220,6 +220,21 @@ message UpdateServiceRequest {
 	string service_id = 1;
 	Version service_version = 2;
 	ServiceSpec spec = 3;
+
+	enum Rollback {
+		// This is not a rollback. The spec field of the request will
+		// be honored.
+		NONE = 0;
+
+		// Roll back the service - get spec from the service's
+		// previous_spec.
+		PREVIOUS = 1;
+	}
+
+	// Rollback may be set to PREVIOUS to request a rollback (the service's
+	// spec will be set to the value of its previous_spec field). In this
+	// case, the spec field of this request is ignored.
+	Rollback rollback = 4;
 }
 
 message UpdateServiceResponse {

+ 1 - 1
vendor/github.com/docker/swarmkit/api/naming/naming.go

@@ -9,7 +9,7 @@ import (
 
 // Task returns the task name from Annotations.Name,
 // and, in case Annotations.Name is missing, fallback
-// to construct the name from othere information.
+// to construct the name from other information.
 func Task(t *api.Task) string {
 	if t.Annotations.Name != "" {
 		// if set, use the container Annotations.Name field, set in the orchestrator.

+ 257 - 157
vendor/github.com/docker/swarmkit/api/specs.pb.go

@@ -138,8 +138,10 @@ type ServiceSpec struct {
 	//	*ServiceSpec_Replicated
 	//	*ServiceSpec_Global
 	Mode isServiceSpec_Mode `protobuf_oneof:"mode"`
-	// UpdateConfig controls the rate and policy of updates.
+	// Update contains settings which affect updates.
 	Update *UpdateConfig `protobuf:"bytes,6,opt,name=update" json:"update,omitempty"`
+	// Rollback contains settings which affect rollbacks of updates.
+	Rollback *UpdateConfig `protobuf:"bytes,9,opt,name=rollback" json:"rollback,omitempty"`
 	// ServiceSpec.Networks has been deprecated and is replaced by
 	// Networks field in Task (TaskSpec.Networks).
 	// This field (ServiceSpec.Networks) is kept for compatibility.
@@ -488,8 +490,10 @@ type ContainerSpec struct {
 	// This only impacts the root filesystem, not additional mounts (including
 	// tmpfs). For additional mounts that are not part of the initial rootfs,
 	// they will be decided by the modes passed in the mount definition.
-	ReadOnly bool    `protobuf:"varint,19,opt,name=read_only,json=readOnly,proto3" json:"read_only,omitempty"`
-	Mounts   []Mount `protobuf:"bytes,8,rep,name=mounts" json:"mounts"`
+	ReadOnly bool `protobuf:"varint,19,opt,name=read_only,json=readOnly,proto3" json:"read_only,omitempty"`
+	// StopSignal defines the signal to stop the container.
+	StopSignal string  `protobuf:"bytes,20,opt,name=stop_signal,json=stopSignal,proto3" json:"stop_signal,omitempty"`
+	Mounts     []Mount `protobuf:"bytes,8,rep,name=mounts" json:"mounts"`
 	// StopGracePeriod the grace period for stopping the container before
 	// forcefully killing the container.
 	// Note: Can't use stdduration here because this needs to be nullable.
@@ -683,6 +687,10 @@ func (m *ServiceSpec) CopyFrom(src interface{}) {
 		m.Update = &UpdateConfig{}
 		github_com_docker_swarmkit_api_deepcopy.Copy(m.Update, o.Update)
 	}
+	if o.Rollback != nil {
+		m.Rollback = &UpdateConfig{}
+		github_com_docker_swarmkit_api_deepcopy.Copy(m.Rollback, o.Rollback)
+	}
 	if o.Networks != nil {
 		m.Networks = make([]*NetworkAttachmentConfig, len(o.Networks))
 		for i := range m.Networks {
@@ -1130,6 +1138,16 @@ func (m *ServiceSpec) MarshalTo(dAtA []byte) (int, error) {
 		}
 		i += n6
 	}
+	if m.Rollback != nil {
+		dAtA[i] = 0x4a
+		i++
+		i = encodeVarintSpecs(dAtA, i, uint64(m.Rollback.Size()))
+		n7, err := m.Rollback.MarshalTo(dAtA[i:])
+		if err != nil {
+			return 0, err
+		}
+		i += n7
+	}
 	return i, nil
 }
 
@@ -1139,11 +1157,11 @@ func (m *ServiceSpec_Replicated) MarshalTo(dAtA []byte) (int, error) {
 		dAtA[i] = 0x1a
 		i++
 		i = encodeVarintSpecs(dAtA, i, uint64(m.Replicated.Size()))
-		n7, err := m.Replicated.MarshalTo(dAtA[i:])
+		n8, err := m.Replicated.MarshalTo(dAtA[i:])
 		if err != nil {
 			return 0, err
 		}
-		i += n7
+		i += n8
 	}
 	return i, nil
 }
@@ -1153,11 +1171,11 @@ func (m *ServiceSpec_Global) MarshalTo(dAtA []byte) (int, error) {
 		dAtA[i] = 0x22
 		i++
 		i = encodeVarintSpecs(dAtA, i, uint64(m.Global.Size()))
-		n8, err := m.Global.MarshalTo(dAtA[i:])
+		n9, err := m.Global.MarshalTo(dAtA[i:])
 		if err != nil {
 			return 0, err
 		}
-		i += n8
+		i += n9
 	}
 	return i, nil
 }
@@ -1218,51 +1236,51 @@ func (m *TaskSpec) MarshalTo(dAtA []byte) (int, error) {
 	var l int
 	_ = l
 	if m.Runtime != nil {
-		nn9, err := m.Runtime.MarshalTo(dAtA[i:])
+		nn10, err := m.Runtime.MarshalTo(dAtA[i:])
 		if err != nil {
 			return 0, err
 		}
-		i += nn9
+		i += nn10
 	}
 	if m.Resources != nil {
 		dAtA[i] = 0x12
 		i++
 		i = encodeVarintSpecs(dAtA, i, uint64(m.Resources.Size()))
-		n10, err := m.Resources.MarshalTo(dAtA[i:])
+		n11, err := m.Resources.MarshalTo(dAtA[i:])
 		if err != nil {
 			return 0, err
 		}
-		i += n10
+		i += n11
 	}
 	if m.Restart != nil {
 		dAtA[i] = 0x22
 		i++
 		i = encodeVarintSpecs(dAtA, i, uint64(m.Restart.Size()))
-		n11, err := m.Restart.MarshalTo(dAtA[i:])
+		n12, err := m.Restart.MarshalTo(dAtA[i:])
 		if err != nil {
 			return 0, err
 		}
-		i += n11
+		i += n12
 	}
 	if m.Placement != nil {
 		dAtA[i] = 0x2a
 		i++
 		i = encodeVarintSpecs(dAtA, i, uint64(m.Placement.Size()))
-		n12, err := m.Placement.MarshalTo(dAtA[i:])
+		n13, err := m.Placement.MarshalTo(dAtA[i:])
 		if err != nil {
 			return 0, err
 		}
-		i += n12
+		i += n13
 	}
 	if m.LogDriver != nil {
 		dAtA[i] = 0x32
 		i++
 		i = encodeVarintSpecs(dAtA, i, uint64(m.LogDriver.Size()))
-		n13, err := m.LogDriver.MarshalTo(dAtA[i:])
+		n14, err := m.LogDriver.MarshalTo(dAtA[i:])
 		if err != nil {
 			return 0, err
 		}
-		i += n13
+		i += n14
 	}
 	if len(m.Networks) > 0 {
 		for _, msg := range m.Networks {
@@ -1290,11 +1308,11 @@ func (m *TaskSpec_Container) MarshalTo(dAtA []byte) (int, error) {
 		dAtA[i] = 0xa
 		i++
 		i = encodeVarintSpecs(dAtA, i, uint64(m.Container.Size()))
-		n14, err := m.Container.MarshalTo(dAtA[i:])
+		n15, err := m.Container.MarshalTo(dAtA[i:])
 		if err != nil {
 			return 0, err
 		}
-		i += n14
+		i += n15
 	}
 	return i, nil
 }
@@ -1304,11 +1322,11 @@ func (m *TaskSpec_Attachment) MarshalTo(dAtA []byte) (int, error) {
 		dAtA[i] = 0x42
 		i++
 		i = encodeVarintSpecs(dAtA, i, uint64(m.Attachment.Size()))
-		n15, err := m.Attachment.MarshalTo(dAtA[i:])
+		n16, err := m.Attachment.MarshalTo(dAtA[i:])
 		if err != nil {
 			return 0, err
 		}
-		i += n15
+		i += n16
 	}
 	return i, nil
 }
@@ -1447,21 +1465,21 @@ func (m *ContainerSpec) MarshalTo(dAtA []byte) (int, error) {
 		dAtA[i] = 0x4a
 		i++
 		i = encodeVarintSpecs(dAtA, i, uint64(m.StopGracePeriod.Size()))
-		n16, err := m.StopGracePeriod.MarshalTo(dAtA[i:])
+		n17, err := m.StopGracePeriod.MarshalTo(dAtA[i:])
 		if err != nil {
 			return 0, err
 		}
-		i += n16
+		i += n17
 	}
 	if m.PullOptions != nil {
 		dAtA[i] = 0x52
 		i++
 		i = encodeVarintSpecs(dAtA, i, uint64(m.PullOptions.Size()))
-		n17, err := m.PullOptions.MarshalTo(dAtA[i:])
+		n18, err := m.PullOptions.MarshalTo(dAtA[i:])
 		if err != nil {
 			return 0, err
 		}
-		i += n17
+		i += n18
 	}
 	if len(m.Groups) > 0 {
 		for _, s := range m.Groups {
@@ -1510,11 +1528,11 @@ func (m *ContainerSpec) MarshalTo(dAtA []byte) (int, error) {
 		dAtA[i] = 0x7a
 		i++
 		i = encodeVarintSpecs(dAtA, i, uint64(m.DNSConfig.Size()))
-		n18, err := m.DNSConfig.MarshalTo(dAtA[i:])
+		n19, err := m.DNSConfig.MarshalTo(dAtA[i:])
 		if err != nil {
 			return 0, err
 		}
-		i += n18
+		i += n19
 	}
 	if m.Healthcheck != nil {
 		dAtA[i] = 0x82
@@ -1522,11 +1540,11 @@ func (m *ContainerSpec) MarshalTo(dAtA []byte) (int, error) {
 		dAtA[i] = 0x1
 		i++
 		i = encodeVarintSpecs(dAtA, i, uint64(m.Healthcheck.Size()))
-		n19, err := m.Healthcheck.MarshalTo(dAtA[i:])
+		n20, err := m.Healthcheck.MarshalTo(dAtA[i:])
 		if err != nil {
 			return 0, err
 		}
-		i += n19
+		i += n20
 	}
 	if len(m.Hosts) > 0 {
 		for _, s := range m.Hosts {
@@ -1569,6 +1587,14 @@ func (m *ContainerSpec) MarshalTo(dAtA []byte) (int, error) {
 		}
 		i++
 	}
+	if len(m.StopSignal) > 0 {
+		dAtA[i] = 0xa2
+		i++
+		dAtA[i] = 0x1
+		i++
+		i = encodeVarintSpecs(dAtA, i, uint64(len(m.StopSignal)))
+		i += copy(dAtA[i:], m.StopSignal)
+	}
 	return i, nil
 }
 
@@ -1714,20 +1740,20 @@ func (m *NetworkSpec) MarshalTo(dAtA []byte) (int, error) {
 	dAtA[i] = 0xa
 	i++
 	i = encodeVarintSpecs(dAtA, i, uint64(m.Annotations.Size()))
-	n20, err := m.Annotations.MarshalTo(dAtA[i:])
+	n21, err := m.Annotations.MarshalTo(dAtA[i:])
 	if err != nil {
 		return 0, err
 	}
-	i += n20
+	i += n21
 	if m.DriverConfig != nil {
 		dAtA[i] = 0x12
 		i++
 		i = encodeVarintSpecs(dAtA, i, uint64(m.DriverConfig.Size()))
-		n21, err := m.DriverConfig.MarshalTo(dAtA[i:])
+		n22, err := m.DriverConfig.MarshalTo(dAtA[i:])
 		if err != nil {
 			return 0, err
 		}
-		i += n21
+		i += n22
 	}
 	if m.Ipv6Enabled {
 		dAtA[i] = 0x18
@@ -1753,11 +1779,11 @@ func (m *NetworkSpec) MarshalTo(dAtA []byte) (int, error) {
 		dAtA[i] = 0x2a
 		i++
 		i = encodeVarintSpecs(dAtA, i, uint64(m.IPAM.Size()))
-		n22, err := m.IPAM.MarshalTo(dAtA[i:])
+		n23, err := m.IPAM.MarshalTo(dAtA[i:])
 		if err != nil {
 			return 0, err
 		}
-		i += n22
+		i += n23
 	}
 	if m.Attachable {
 		dAtA[i] = 0x30
@@ -1790,67 +1816,67 @@ func (m *ClusterSpec) MarshalTo(dAtA []byte) (int, error) {
 	dAtA[i] = 0xa
 	i++
 	i = encodeVarintSpecs(dAtA, i, uint64(m.Annotations.Size()))
-	n23, err := m.Annotations.MarshalTo(dAtA[i:])
+	n24, err := m.Annotations.MarshalTo(dAtA[i:])
 	if err != nil {
 		return 0, err
 	}
-	i += n23
+	i += n24
 	dAtA[i] = 0x12
 	i++
 	i = encodeVarintSpecs(dAtA, i, uint64(m.AcceptancePolicy.Size()))
-	n24, err := m.AcceptancePolicy.MarshalTo(dAtA[i:])
+	n25, err := m.AcceptancePolicy.MarshalTo(dAtA[i:])
 	if err != nil {
 		return 0, err
 	}
-	i += n24
+	i += n25
 	dAtA[i] = 0x1a
 	i++
 	i = encodeVarintSpecs(dAtA, i, uint64(m.Orchestration.Size()))
-	n25, err := m.Orchestration.MarshalTo(dAtA[i:])
+	n26, err := m.Orchestration.MarshalTo(dAtA[i:])
 	if err != nil {
 		return 0, err
 	}
-	i += n25
+	i += n26
 	dAtA[i] = 0x22
 	i++
 	i = encodeVarintSpecs(dAtA, i, uint64(m.Raft.Size()))
-	n26, err := m.Raft.MarshalTo(dAtA[i:])
+	n27, err := m.Raft.MarshalTo(dAtA[i:])
 	if err != nil {
 		return 0, err
 	}
-	i += n26
+	i += n27
 	dAtA[i] = 0x2a
 	i++
 	i = encodeVarintSpecs(dAtA, i, uint64(m.Dispatcher.Size()))
-	n27, err := m.Dispatcher.MarshalTo(dAtA[i:])
+	n28, err := m.Dispatcher.MarshalTo(dAtA[i:])
 	if err != nil {
 		return 0, err
 	}
-	i += n27
+	i += n28
 	dAtA[i] = 0x32
 	i++
 	i = encodeVarintSpecs(dAtA, i, uint64(m.CAConfig.Size()))
-	n28, err := m.CAConfig.MarshalTo(dAtA[i:])
+	n29, err := m.CAConfig.MarshalTo(dAtA[i:])
 	if err != nil {
 		return 0, err
 	}
-	i += n28
+	i += n29
 	dAtA[i] = 0x3a
 	i++
 	i = encodeVarintSpecs(dAtA, i, uint64(m.TaskDefaults.Size()))
-	n29, err := m.TaskDefaults.MarshalTo(dAtA[i:])
+	n30, err := m.TaskDefaults.MarshalTo(dAtA[i:])
 	if err != nil {
 		return 0, err
 	}
-	i += n29
+	i += n30
 	dAtA[i] = 0x42
 	i++
 	i = encodeVarintSpecs(dAtA, i, uint64(m.EncryptionConfig.Size()))
-	n30, err := m.EncryptionConfig.MarshalTo(dAtA[i:])
+	n31, err := m.EncryptionConfig.MarshalTo(dAtA[i:])
 	if err != nil {
 		return 0, err
 	}
-	i += n30
+	i += n31
 	return i, nil
 }
 
@@ -1872,11 +1898,11 @@ func (m *SecretSpec) MarshalTo(dAtA []byte) (int, error) {
 	dAtA[i] = 0xa
 	i++
 	i = encodeVarintSpecs(dAtA, i, uint64(m.Annotations.Size()))
-	n31, err := m.Annotations.MarshalTo(dAtA[i:])
+	n32, err := m.Annotations.MarshalTo(dAtA[i:])
 	if err != nil {
 		return 0, err
 	}
-	i += n31
+	i += n32
 	if len(m.Data) > 0 {
 		dAtA[i] = 0x12
 		i++
@@ -1955,6 +1981,10 @@ func (m *ServiceSpec) Size() (n int) {
 		l = m.Endpoint.Size()
 		n += 1 + l + sovSpecs(uint64(l))
 	}
+	if m.Rollback != nil {
+		l = m.Rollback.Size()
+		n += 1 + l + sovSpecs(uint64(l))
+	}
 	return n
 }
 
@@ -2147,6 +2177,10 @@ func (m *ContainerSpec) Size() (n int) {
 	if m.ReadOnly {
 		n += 3
 	}
+	l = len(m.StopSignal)
+	if l > 0 {
+		n += 2 + l + sovSpecs(uint64(l))
+	}
 	return n
 }
 
@@ -2295,6 +2329,7 @@ func (this *ServiceSpec) String() string {
 		`Update:` + strings.Replace(fmt.Sprintf("%v", this.Update), "UpdateConfig", "UpdateConfig", 1) + `,`,
 		`Networks:` + strings.Replace(fmt.Sprintf("%v", this.Networks), "NetworkAttachmentConfig", "NetworkAttachmentConfig", 1) + `,`,
 		`Endpoint:` + strings.Replace(fmt.Sprintf("%v", this.Endpoint), "EndpointSpec", "EndpointSpec", 1) + `,`,
+		`Rollback:` + strings.Replace(fmt.Sprintf("%v", this.Rollback), "UpdateConfig", "UpdateConfig", 1) + `,`,
 		`}`,
 	}, "")
 	return s
@@ -2418,6 +2453,7 @@ func (this *ContainerSpec) String() string {
 		`Hosts:` + fmt.Sprintf("%v", this.Hosts) + `,`,
 		`OpenStdin:` + fmt.Sprintf("%v", this.OpenStdin) + `,`,
 		`ReadOnly:` + fmt.Sprintf("%v", this.ReadOnly) + `,`,
+		`StopSignal:` + fmt.Sprintf("%v", this.StopSignal) + `,`,
 		`}`,
 	}, "")
 	return s
@@ -2893,6 +2929,39 @@ func (m *ServiceSpec) Unmarshal(dAtA []byte) error {
 				return err
 			}
 			iNdEx = postIndex
+		case 9:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Rollback", wireType)
+			}
+			var msglen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowSpecs
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				msglen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if msglen < 0 {
+				return ErrInvalidLengthSpecs
+			}
+			postIndex := iNdEx + msglen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			if m.Rollback == nil {
+				m.Rollback = &UpdateConfig{}
+			}
+			if err := m.Rollback.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
 		default:
 			iNdEx = preIndex
 			skippy, err := skipSpecs(dAtA[iNdEx:])
@@ -4068,6 +4137,35 @@ func (m *ContainerSpec) Unmarshal(dAtA []byte) error {
 				}
 			}
 			m.ReadOnly = bool(v != 0)
+		case 20:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field StopSignal", 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.StopSignal = string(dAtA[iNdEx:postIndex])
+			iNdEx = postIndex
 		default:
 			iNdEx = preIndex
 			skippy, err := skipSpecs(dAtA[iNdEx:])
@@ -5120,110 +5218,112 @@ var (
 func init() { proto.RegisterFile("specs.proto", fileDescriptorSpecs) }
 
 var fileDescriptorSpecs = []byte{
-	// 1672 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,
-	0x15, 0x26, 0x25, 0x8a, 0x5c, 0xbe, 0xa5, 0x6c, 0x0a, 0x4d, 0xd2, 0x35, 0xdd, 0x50, 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,
-	0xcc, 0x81, 0x14, 0x77, 0x7c, 0xe2, 0x40, 0xbb, 0x10, 0xb9, 0xa3, 0xe5, 0x62, 0x0b, 0x60, 0x99,
-	0xe1, 0xad, 0xc7, 0x8c, 0x0f, 0xfd, 0x07, 0x3a, 0xf5, 0x37, 0xf4, 0x3f, 0xf8, 0xd8, 0x63, 0x4f,
-	0x9a, 0x9a, 0x7f, 0x21, 0x3f, 0xa0, 0x1d, 0x60, 0xb1, 0xe4, 0x32, 0x59, 0xc5, 0x99, 0xa9, 0x6f,
-	0x78, 0x8f, 0xdf, 0xf7, 0x16, 0x78, 0xf8, 0xf0, 0xde, 0x23, 0xd8, 0x22, 0xa2, 0xae, 0xe8, 0x44,
-	0x9c, 0x49, 0x86, 0x90, 0xc7, 0xdc, 0x6b, 0xca, 0x3b, 0xe2, 0x2b, 0xc2, 0xa7, 0xd7, 0xbe, 0xec,
-	0xcc, 0x7e, 0xd9, 0xb0, 0xe5, 0x3c, 0xa2, 0x06, 0xd0, 0x78, 0x6f, 0xcc, 0xc6, 0x4c, 0x2f, 0xf7,
-	0xd5, 0xca, 0x78, 0x9b, 0x63, 0xc6, 0xc6, 0x01, 0xdd, 0xd7, 0xd6, 0x65, 0x7c, 0xb5, 0xef, 0xc5,
-	0x9c, 0x48, 0x9f, 0x85, 0xc9, 0xef, 0xed, 0x9b, 0x12, 0x58, 0x67, 0xcc, 0xa3, 0xe7, 0x11, 0x75,
-	0xd1, 0x11, 0xd8, 0x24, 0x0c, 0x99, 0xd4, 0x00, 0xe1, 0x14, 0x5b, 0xc5, 0x3d, 0xfb, 0x60, 0xb7,
-	0xf3, 0xdd, 0x2f, 0x77, 0xba, 0x2b, 0x58, 0xaf, 0xf4, 0xfa, 0x76, 0xb7, 0x80, 0xb3, 0x4c, 0xf4,
-	0x7b, 0xa8, 0x79, 0x54, 0xf8, 0x9c, 0x7a, 0x23, 0xce, 0x02, 0xea, 0x6c, 0xb4, 0x8a, 0x7b, 0xf7,
-	0x0e, 0x7e, 0x92, 0x17, 0x49, 0x7d, 0x1c, 0xb3, 0x80, 0x62, 0xdb, 0x30, 0x94, 0x81, 0x8e, 0x00,
-	0xa6, 0x74, 0x7a, 0x49, 0xb9, 0x98, 0xf8, 0x91, 0xb3, 0xa9, 0xe9, 0x3f, 0xbb, 0x8b, 0xae, 0xf6,
-	0xde, 0x39, 0x5d, 0xc2, 0x71, 0x86, 0x8a, 0x4e, 0xa1, 0x46, 0x66, 0xc4, 0x0f, 0xc8, 0xa5, 0x1f,
-	0xf8, 0x72, 0xee, 0x94, 0x74, 0xa8, 0x4f, 0xbe, 0x37, 0x54, 0x37, 0x43, 0xc0, 0x6b, 0xf4, 0xb6,
-	0x07, 0xb0, 0xfa, 0x10, 0xfa, 0x18, 0x2a, 0xc3, 0xc1, 0x59, 0xff, 0xf8, 0xec, 0xa8, 0x5e, 0x68,
-	0x3c, 0x78, 0x75, 0xd3, 0x7a, 0x5f, 0xc5, 0x58, 0x01, 0x86, 0x34, 0xf4, 0xfc, 0x70, 0x8c, 0xf6,
-	0xc0, 0xea, 0x1e, 0x1e, 0x0e, 0x86, 0x17, 0x83, 0x7e, 0xbd, 0xd8, 0x68, 0xbc, 0xba, 0x69, 0x7d,
-	0xb0, 0x0e, 0xec, 0xba, 0x2e, 0x8d, 0x24, 0xf5, 0x1a, 0xa5, 0xaf, 0xff, 0xd1, 0x2c, 0xb4, 0xbf,
-	0x2e, 0x42, 0x2d, 0xbb, 0x09, 0xf4, 0x31, 0x94, 0xbb, 0x87, 0x17, 0xc7, 0x2f, 0x06, 0xf5, 0xc2,
-	0x8a, 0x9e, 0x45, 0x74, 0x5d, 0xe9, 0xcf, 0x28, 0x7a, 0x0c, 0x5b, 0xc3, 0xee, 0x97, 0xe7, 0x83,
-	0x7a, 0x71, 0xb5, 0x9d, 0x2c, 0x6c, 0x48, 0x62, 0xa1, 0x51, 0x7d, 0xdc, 0x3d, 0x3e, 0xab, 0x6f,
-	0xe4, 0xa3, 0xfa, 0x9c, 0xf8, 0xa1, 0xd9, 0xca, 0x9b, 0x4d, 0xb0, 0xcf, 0x29, 0x9f, 0xf9, 0xee,
-	0x3b, 0x96, 0xc8, 0x67, 0x50, 0x92, 0x44, 0x5c, 0x6b, 0x69, 0xd8, 0xf9, 0xd2, 0xb8, 0x20, 0xe2,
-	0x5a, 0x7d, 0xd4, 0xd0, 0x35, 0x5e, 0x29, 0x83, 0xd3, 0x28, 0xf0, 0x5d, 0x22, 0xa9, 0xa7, 0x95,
-	0x61, 0x1f, 0xfc, 0x34, 0x8f, 0x8d, 0x97, 0x28, 0xb3, 0xff, 0x67, 0x05, 0x9c, 0xa1, 0xa2, 0xa7,
-	0x50, 0x1e, 0x07, 0xec, 0x92, 0x04, 0x5a, 0x13, 0xf6, 0xc1, 0xa3, 0xbc, 0x20, 0x47, 0x1a, 0xb1,
-	0x0a, 0x60, 0x28, 0xe8, 0x09, 0x94, 0xe3, 0xc8, 0x23, 0x92, 0x3a, 0x65, 0x4d, 0x6e, 0xe5, 0x91,
-	0xbf, 0xd4, 0x88, 0x43, 0x16, 0x5e, 0xf9, 0x63, 0x6c, 0xf0, 0xe8, 0x04, 0xac, 0x90, 0xca, 0xaf,
-	0x18, 0xbf, 0x16, 0x4e, 0xa5, 0xb5, 0xb9, 0x67, 0x1f, 0x7c, 0x9a, 0x2b, 0xc6, 0x04, 0xd3, 0x95,
-	0x92, 0xb8, 0x93, 0x29, 0x0d, 0x65, 0x12, 0xa6, 0xb7, 0xe1, 0x14, 0xf1, 0x32, 0x00, 0xfa, 0x1d,
-	0x58, 0x34, 0xf4, 0x22, 0xe6, 0x87, 0xd2, 0xb1, 0xee, 0xde, 0xc8, 0xc0, 0x60, 0x54, 0x32, 0xf1,
-	0x92, 0xd1, 0x2b, 0x43, 0x69, 0xca, 0x3c, 0xda, 0xde, 0x87, 0x9d, 0xef, 0x24, 0x0b, 0x35, 0xc0,
-	0x32, 0xc9, 0x4a, 0x6e, 0xb9, 0x84, 0x97, 0x76, 0xfb, 0x3e, 0x6c, 0xaf, 0x25, 0xa6, 0xfd, 0xf7,
-	0x12, 0x58, 0xe9, 0x6d, 0xa1, 0x2e, 0x54, 0x5d, 0x16, 0x4a, 0xe2, 0x87, 0x94, 0x1b, 0x81, 0xe4,
-	0xe6, 0xf6, 0x30, 0x05, 0x29, 0xd6, 0xb3, 0x02, 0x5e, 0xb1, 0xd0, 0x1f, 0xa1, 0xca, 0xa9, 0x60,
-	0x31, 0x77, 0xa9, 0x30, 0x0a, 0xd9, 0xcb, 0xbf, 0xe3, 0x04, 0x84, 0xe9, 0x5f, 0x63, 0x9f, 0x53,
-	0x95, 0x27, 0x81, 0x57, 0x54, 0xf4, 0x14, 0x2a, 0x9c, 0x0a, 0x49, 0xb8, 0xfc, 0xbe, 0x4b, 0xc6,
-	0x09, 0x64, 0xc8, 0x02, 0xdf, 0x9d, 0xe3, 0x94, 0x81, 0x9e, 0x42, 0x35, 0x0a, 0x88, 0xab, 0xa3,
-	0x3a, 0x5b, 0x9a, 0xfe, 0x61, 0x1e, 0x7d, 0x98, 0x82, 0xf0, 0x0a, 0x8f, 0x3e, 0x07, 0x08, 0xd8,
-	0x78, 0xe4, 0x71, 0x7f, 0x46, 0xb9, 0x11, 0x49, 0x23, 0x8f, 0xdd, 0xd7, 0x08, 0x5c, 0x0d, 0xd8,
-	0x38, 0x59, 0xa2, 0xa3, 0xff, 0x4b, 0x21, 0x19, 0x75, 0x9c, 0x00, 0x90, 0xe5, 0xaf, 0x46, 0x1f,
-	0x9f, 0xfc, 0xa0, 0x50, 0xe6, 0x46, 0x32, 0x74, 0xf4, 0x08, 0x6a, 0x57, 0x8c, 0xbb, 0x74, 0x64,
-	0x74, 0x5f, 0xd5, 0x9a, 0xb0, 0xb5, 0x2f, 0x11, 0x7a, 0xaf, 0x0a, 0x15, 0x1e, 0x87, 0xd2, 0x9f,
-	0xd2, 0xf6, 0x09, 0xbc, 0x9f, 0x1b, 0x14, 0x1d, 0x40, 0x6d, 0x79, 0xcd, 0x23, 0xdf, 0xd3, 0xfa,
-	0xa8, 0xf6, 0xee, 0x2f, 0x6e, 0x77, 0xed, 0xa5, 0x1e, 0x8e, 0xfb, 0xd8, 0x5e, 0x82, 0x8e, 0xbd,
-	0xf6, 0x37, 0x15, 0xd8, 0x5e, 0x13, 0x0b, 0x7a, 0x0f, 0xb6, 0xfc, 0x29, 0x19, 0xd3, 0x84, 0x8e,
-	0x13, 0x03, 0x0d, 0xa0, 0x1c, 0x90, 0x4b, 0x1a, 0x28, 0xc9, 0xa8, 0xb4, 0xfd, 0xe2, 0xad, 0xaa,
-	0xeb, 0xfc, 0x59, 0xe3, 0x07, 0xa1, 0xe4, 0x73, 0x6c, 0xc8, 0xc8, 0x81, 0x8a, 0xcb, 0xa6, 0x53,
-	0x12, 0xaa, 0xf2, 0xb2, 0xb9, 0x57, 0xc5, 0xa9, 0x89, 0x10, 0x94, 0x08, 0x1f, 0x0b, 0xa7, 0xa4,
-	0xdd, 0x7a, 0x8d, 0xea, 0xb0, 0x49, 0xc3, 0x99, 0xb3, 0xa5, 0x5d, 0x6a, 0xa9, 0x3c, 0x9e, 0x9f,
-	0xdc, 0x79, 0x15, 0xab, 0xa5, 0xe2, 0xc5, 0x82, 0x72, 0xa7, 0xa2, 0x5d, 0x7a, 0x8d, 0x7e, 0x03,
-	0xe5, 0x29, 0x8b, 0x43, 0x29, 0x1c, 0x4b, 0x6f, 0xf6, 0x41, 0xde, 0x66, 0x4f, 0x15, 0xc2, 0x94,
-	0x3f, 0x03, 0x47, 0x03, 0xd8, 0x11, 0x92, 0x45, 0xa3, 0x31, 0x27, 0x2e, 0x1d, 0x45, 0x94, 0xfb,
-	0xcc, 0xd3, 0xb7, 0xa1, 0x62, 0x24, 0xdd, 0xbe, 0x93, 0x76, 0xfb, 0x4e, 0xdf, 0x74, 0x7b, 0x7c,
-	0x5f, 0x71, 0x8e, 0x14, 0x65, 0xa8, 0x19, 0x68, 0x08, 0xb5, 0x28, 0x0e, 0x82, 0x11, 0x8b, 0x92,
-	0x4a, 0x0e, 0x3a, 0xc2, 0x0f, 0x48, 0xd9, 0x30, 0x0e, 0x82, 0xe7, 0x09, 0x09, 0xdb, 0xd1, 0xca,
-	0x40, 0x1f, 0x40, 0x79, 0xcc, 0x59, 0x1c, 0x09, 0xc7, 0xd6, 0xc9, 0x30, 0x16, 0xfa, 0x02, 0x2a,
-	0x82, 0xba, 0x9c, 0x4a, 0xe1, 0xd4, 0xf4, 0x51, 0x3f, 0xca, 0xfb, 0xc8, 0xb9, 0x86, 0x60, 0x7a,
-	0x45, 0x39, 0x0d, 0x5d, 0x8a, 0x53, 0x0e, 0x7a, 0x00, 0x9b, 0x52, 0xce, 0x9d, 0xed, 0x56, 0x71,
-	0xcf, 0xea, 0x55, 0x16, 0xb7, 0xbb, 0x9b, 0x17, 0x17, 0x2f, 0xb1, 0xf2, 0xa9, 0x1a, 0x35, 0x61,
-	0x42, 0x86, 0x64, 0x4a, 0x9d, 0x7b, 0x3a, 0xb7, 0x4b, 0x1b, 0xbd, 0x04, 0xf0, 0x42, 0x31, 0x72,
-	0xf5, 0xa3, 0x70, 0xee, 0xeb, 0xd3, 0x7d, 0xfa, 0xf6, 0xd3, 0xf5, 0xcf, 0xce, 0x4d, 0xa5, 0xdd,
-	0x5e, 0xdc, 0xee, 0x56, 0x97, 0x26, 0xae, 0x7a, 0xa1, 0x48, 0x96, 0xa8, 0x07, 0xf6, 0x84, 0x92,
-	0x40, 0x4e, 0xdc, 0x09, 0x75, 0xaf, 0x9d, 0xfa, 0xdd, 0x85, 0xf7, 0x99, 0x86, 0x99, 0x08, 0x59,
-	0x92, 0x52, 0xb0, 0xda, 0xaa, 0x70, 0x76, 0x74, 0xae, 0x12, 0x03, 0x7d, 0x08, 0xc0, 0x22, 0x1a,
-	0x8e, 0x84, 0xf4, 0xfc, 0xd0, 0x41, 0xea, 0xc8, 0xb8, 0xaa, 0x3c, 0xe7, 0xca, 0x81, 0x1e, 0xaa,
-	0xb2, 0x48, 0xbc, 0x11, 0x0b, 0x83, 0xb9, 0xf3, 0x23, 0xfd, 0xab, 0xa5, 0x1c, 0xcf, 0xc3, 0x60,
-	0xde, 0xf8, 0x1c, 0xec, 0x8c, 0x9a, 0x95, 0x0a, 0xaf, 0xe9, 0xdc, 0x3c, 0x10, 0xb5, 0x54, 0x9f,
-	0x9c, 0x91, 0x20, 0x4e, 0xa6, 0xb1, 0x2a, 0x4e, 0x8c, 0xdf, 0x6e, 0x3c, 0x29, 0x36, 0x0e, 0xc0,
-	0xce, 0xdc, 0x2a, 0xfa, 0x08, 0xb6, 0x39, 0x1d, 0xfb, 0x42, 0xf2, 0xf9, 0x88, 0xc4, 0x72, 0xe2,
-	0xfc, 0x41, 0x13, 0x6a, 0xa9, 0xb3, 0x1b, 0xcb, 0x49, 0x63, 0x04, 0xab, 0xe4, 0xa0, 0x16, 0xd8,
-	0x2a, 0xe9, 0x82, 0xf2, 0x19, 0xe5, 0xaa, 0x5f, 0xa8, 0x33, 0x65, 0x5d, 0x4a, 0x1c, 0x82, 0x12,
-	0xee, 0x4e, 0xf4, 0xdb, 0xac, 0x62, 0x63, 0xa9, 0xc7, 0x96, 0x2a, 0xd0, 0x3c, 0x36, 0x63, 0xb6,
-	0xbf, 0x29, 0x42, 0x2d, 0xdb, 0xb8, 0xd0, 0x61, 0xd2, 0xae, 0xf4, 0x91, 0xee, 0x1d, 0xec, 0xbf,
-	0xad, 0xd1, 0xe9, 0xe6, 0x10, 0xc4, 0x2a, 0xd8, 0xa9, 0x9a, 0x31, 0x35, 0x19, 0xfd, 0x1a, 0xb6,
-	0x22, 0xc6, 0x65, 0x5a, 0x22, 0x9a, 0xb9, 0x05, 0x9d, 0xf1, 0xb4, 0x98, 0x26, 0xe0, 0xf6, 0x04,
-	0xee, 0xad, 0x47, 0x43, 0x8f, 0x61, 0xf3, 0xc5, 0xf1, 0xb0, 0x5e, 0x68, 0x3c, 0x7c, 0x75, 0xd3,
-	0xfa, 0xf1, 0xfa, 0x8f, 0x2f, 0x7c, 0x2e, 0x63, 0x12, 0x1c, 0x0f, 0xd1, 0xcf, 0x61, 0xab, 0x7f,
-	0x76, 0x8e, 0x71, 0xbd, 0xd8, 0xd8, 0x7d, 0x75, 0xd3, 0x7a, 0xb8, 0x8e, 0x53, 0x3f, 0xb1, 0x38,
-	0xf4, 0x30, 0xbb, 0x5c, 0xce, 0x5b, 0xff, 0xdc, 0x00, 0xdb, 0x54, 0xce, 0x77, 0x3d, 0x92, 0x6f,
-	0x27, 0xcd, 0x28, 0x7d, 0x12, 0x1b, 0x6f, 0xed, 0x49, 0xb5, 0x84, 0x60, 0xee, 0xf8, 0x11, 0xd4,
-	0xfc, 0x68, 0xf6, 0xd9, 0x88, 0x86, 0xe4, 0x32, 0x30, 0xa3, 0x97, 0x85, 0x6d, 0xe5, 0x1b, 0x24,
-	0x2e, 0xf5, 0x1e, 0xfd, 0x50, 0x52, 0x1e, 0x9a, 0xa1, 0xca, 0xc2, 0x4b, 0x1b, 0x7d, 0x01, 0x25,
-	0x3f, 0x22, 0x53, 0xd3, 0x48, 0x73, 0x4f, 0x70, 0x3c, 0xec, 0x9e, 0x1a, 0x0d, 0xf6, 0xac, 0xc5,
-	0xed, 0x6e, 0x49, 0x39, 0xb0, 0xa6, 0xa1, 0x66, 0xda, 0xcb, 0xd4, 0x97, 0x74, 0x6d, 0xb5, 0x70,
-	0xc6, 0xd3, 0xfe, 0x6f, 0x09, 0xec, 0xc3, 0x20, 0x16, 0xd2, 0x74, 0x88, 0x77, 0x96, 0xb7, 0x97,
-	0xb0, 0x43, 0xf4, 0x74, 0x4e, 0x42, 0x55, 0x6e, 0xf5, 0x8c, 0x60, 0x72, 0xf7, 0x38, 0x37, 0xdc,
-	0x12, 0x9c, 0xcc, 0x13, 0xbd, 0xb2, 0x8a, 0xe9, 0x14, 0x71, 0x9d, 0x7c, 0xeb, 0x17, 0x74, 0x0e,
-	0xdb, 0x8c, 0xbb, 0x13, 0x2a, 0x64, 0x52, 0xa4, 0xcd, 0x34, 0x9b, 0xfb, 0x3f, 0xe7, 0x79, 0x16,
-	0x68, 0x2a, 0x54, 0xb2, 0xdb, 0xf5, 0x18, 0xe8, 0x09, 0x94, 0x38, 0xb9, 0x4a, 0xe7, 0x9d, 0x5c,
-	0x7d, 0x63, 0x72, 0x25, 0xd7, 0x42, 0x68, 0x06, 0xfa, 0x13, 0x80, 0xe7, 0x8b, 0x88, 0x48, 0x77,
-	0x42, 0xb9, 0xb9, 0xa7, 0xdc, 0x23, 0xf6, 0x97, 0xa8, 0xb5, 0x28, 0x19, 0x36, 0x3a, 0x81, 0xaa,
-	0x4b, 0x52, 0xa5, 0x95, 0xef, 0x1e, 0xf1, 0x0f, 0xbb, 0x26, 0x44, 0x5d, 0x85, 0x58, 0xdc, 0xee,
-	0x5a, 0xa9, 0x07, 0x5b, 0x2e, 0x31, 0xca, 0x3b, 0x81, 0x6d, 0x35, 0xfa, 0x8f, 0x3c, 0x7a, 0x45,
-	0xe2, 0x40, 0x0a, 0xdd, 0x47, 0xef, 0xa8, 0xb8, 0x6a, 0x0a, 0xed, 0x1b, 0x9c, 0xd9, 0x57, 0x4d,
-	0x66, 0x7c, 0xe8, 0x2f, 0xb0, 0x43, 0x43, 0x97, 0xcf, 0xb5, 0xce, 0xd2, 0x1d, 0x5a, 0x77, 0x1f,
-	0x76, 0xb0, 0x04, 0xaf, 0x1d, 0xb6, 0x4e, 0xbf, 0xe5, 0x6f, 0xfb, 0x00, 0x49, 0x0f, 0x7b, 0xb7,
-	0xfa, 0x43, 0x50, 0xf2, 0x88, 0x24, 0x5a, 0x72, 0x35, 0xac, 0xd7, 0x3d, 0xe7, 0xf5, 0x9b, 0x66,
-	0xe1, 0xdf, 0x6f, 0x9a, 0x85, 0xbf, 0x2d, 0x9a, 0xc5, 0xd7, 0x8b, 0x66, 0xf1, 0x5f, 0x8b, 0x66,
-	0xf1, 0x3f, 0x8b, 0x66, 0xf1, 0xb2, 0xac, 0x3b, 0xff, 0xaf, 0xfe, 0x17, 0x00, 0x00, 0xff, 0xff,
-	0xa2, 0xd8, 0xcf, 0x61, 0x3b, 0x10, 0x00, 0x00,
+	0xcc, 0x01, 0x15, 0x77, 0x7c, 0xe2, 0x80, 0xbb, 0x10, 0xb9, 0xa3, 0xe5, 0x62, 0x0b, 0x60, 0x99,
+	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,
 }

+ 7 - 1
vendor/github.com/docker/swarmkit/api/specs.proto

@@ -69,9 +69,12 @@ message ServiceSpec {
 		GlobalService global = 4;
 	}
 
-	// UpdateConfig controls the rate and policy of updates.
+	// Update contains settings which affect updates.
 	UpdateConfig update = 6;
 
+	// Rollback contains settings which affect rollbacks of updates.
+	UpdateConfig rollback = 9;
+
 	// ServiceSpec.Networks has been deprecated and is replaced by
 	// Networks field in Task (TaskSpec.Networks).
 	// This field (ServiceSpec.Networks) is kept for compatibility.
@@ -200,6 +203,9 @@ message ContainerSpec {
 	// they will be decided by the modes passed in the mount definition.
 	bool read_only = 19;
 
+	// StopSignal defines the signal to stop the container.
+	string stop_signal = 20;
+
 	repeated Mount mounts = 8 [(gogoproto.nullable) = false];
 
 	// StopGracePeriod the grace period for stopping the container before

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

@@ -449,12 +449,6 @@ type UpdateConfig_FailureAction int32
 const (
 	UpdateConfig_PAUSE    UpdateConfig_FailureAction = 0
 	UpdateConfig_CONTINUE UpdateConfig_FailureAction = 1
-	// NOTE: Automated rollback triggered as a failure action is an
-	// experimental feature that is not yet exposed to the end
-	// user. Currently, rollbacks must be initiated manually
-	// through the API by setting Spec to PreviousSpec. We may
-	// decide to expose automatic rollback in the future based on
-	// user feedback, or remove this feature otherwise.
 	UpdateConfig_ROLLBACK UpdateConfig_FailureAction = 2
 )
 
@@ -951,11 +945,6 @@ type UpdateConfig struct {
 	// If the failure action is ROLLBACK, the orchestrator will attempt to
 	// roll back to the previous service spec. If the MaxFailureRatio
 	// threshold is hit during the rollback, the rollback will pause.
-	//
-	// TODO(aaronl): Should there be a separate failure threshold for
-	// rollbacks? Should there be a failure action for rollbacks (to allow
-	// them to do something other than pause when the rollback encounters
-	// errors)?
 	MaxFailureRatio float32 `protobuf:"fixed32,5,opt,name=max_failure_ratio,json=maxFailureRatio,proto3" json:"max_failure_ratio,omitempty"`
 }
 

+ 0 - 11
vendor/github.com/docker/swarmkit/api/types.proto

@@ -285,12 +285,6 @@ message UpdateConfig {
 	enum FailureAction {
 		PAUSE = 0;
 		CONTINUE = 1;
-		// NOTE: Automated rollback triggered as a failure action is an
-		// experimental feature that is not yet exposed to the end
-		// user. Currently, rollbacks must be initiated manually
-		// through the API by setting Spec to PreviousSpec. We may
-		// decide to expose automatic rollback in the future based on
-		// user feedback, or remove this feature otherwise.
 		ROLLBACK = 2;
 	}
 
@@ -320,11 +314,6 @@ message UpdateConfig {
 	// If the failure action is ROLLBACK, the orchestrator will attempt to
 	// roll back to the previous service spec. If the MaxFailureRatio
 	// threshold is hit during the rollback, the rollback will pause.
-	//
-	// TODO(aaronl): Should there be a separate failure threshold for
-	// rollbacks? Should there be a failure action for rollbacks (to allow
-	// them to do something other than pause when the rollback encounters
-	// errors)?
 	float max_failure_ratio = 5;
 }
 

+ 30 - 28
vendor/github.com/docker/swarmkit/ca/certificates.go

@@ -4,10 +4,13 @@ import (
 	"bytes"
 	"crypto"
 	"crypto/ecdsa"
+	"crypto/elliptic"
 	"crypto/rand"
+	"crypto/rsa"
 	"crypto/tls"
 	"crypto/x509"
 	"encoding/pem"
+	"fmt"
 	"io"
 	"io/ioutil"
 	"os"
@@ -52,7 +55,7 @@ const (
 	// root CA private key material encryption key. It can be used for seamless
 	// KEK rotations.
 	PassphraseENVVarPrev = "SWARM_ROOT_CA_PASSPHRASE_PREV"
-	// RootCAExpiration represents the expiration for the root CA in seconds (20 years)
+	// RootCAExpiration represents the default expiration for the root CA in seconds (20 years)
 	RootCAExpiration = "630720000s"
 	// DefaultNodeCertExpiration represents the default expiration for node certificates (3 months)
 	DefaultNodeCertExpiration = 2160 * time.Hour
@@ -317,31 +320,7 @@ func (rca *RootCA) ParseValidateAndSignCSR(csrBytes []byte, cn, ou, org string)
 		return nil, errors.Wrap(err, "failed to sign node certificate")
 	}
 
-	return rca.AppendFirstRootPEM(cert)
-}
-
-// AppendFirstRootPEM appends the first certificate from this RootCA's cert
-// bundle to the given cert bundle (which should already be encoded as a series
-// of PEM-encoded certificate blocks).
-func (rca *RootCA) AppendFirstRootPEM(cert []byte) ([]byte, error) {
-	// Append the first root CA Cert to the certificate, to create a valid chain
-	// Get the first Root CA Cert on the bundle
-	firstRootCA, _, err := helpers.ParseOneCertificateFromPEM(rca.Cert)
-	if err != nil {
-		return nil, err
-	}
-	if len(firstRootCA) < 1 {
-		return nil, errors.New("no valid Root CA certificates found")
-	}
-	// Convert the first root CA back to PEM
-	firstRootCAPEM := helpers.EncodeCertificatePEM(firstRootCA[0])
-	if firstRootCAPEM == nil {
-		return nil, errors.New("error while encoding the Root CA certificate")
-	}
-	// Append this Root CA to the certificate to make [Cert PEM]\n[Root PEM][EOF]
-	certChain := append(cert, firstRootCAPEM...)
-
-	return certChain, nil
+	return cert, nil
 }
 
 // NewRootCA creates a new RootCA object from unparsed PEM cert bundle and key byte
@@ -361,8 +340,17 @@ func NewRootCA(certBytes, keyBytes []byte, certExpiry time.Duration) (RootCA, er
 	// Create a Pool with all of the certificates found
 	pool := x509.NewCertPool()
 	for _, cert := range parsedCerts {
+		switch cert.SignatureAlgorithm {
+		case x509.SHA256WithRSA, x509.SHA384WithRSA, x509.SHA512WithRSA, x509.ECDSAWithSHA256, x509.ECDSAWithSHA384, x509.ECDSAWithSHA512:
+			break
+		default:
+			return RootCA{}, fmt.Errorf("unsupported signature algorithm: %s", cert.SignatureAlgorithm.String())
+		}
+
 		// Check to see if all of the certificates are valid, self-signed root CA certs
-		if err := cert.CheckSignature(cert.SignatureAlgorithm, cert.RawTBSCertificate, cert.Signature); err != nil {
+		selfpool := x509.NewCertPool()
+		selfpool.AddCert(cert)
+		if _, err := cert.Verify(x509.VerifyOptions{Roots: selfpool}); err != nil {
 			return RootCA{}, errors.Wrap(err, "error while validating Root CA Certificate")
 		}
 		pool.AddCert(cert)
@@ -429,8 +417,22 @@ func NewRootCA(certBytes, keyBytes []byte, certExpiry time.Duration) (RootCA, er
 
 func ensureCertKeyMatch(cert *x509.Certificate, key crypto.PublicKey) error {
 	switch certPub := cert.PublicKey.(type) {
-	// TODO: Handle RSA keys.
+	case *rsa.PublicKey:
+		if certPub.N.BitLen() < 2048 || certPub.E == 1 {
+			return errors.New("unsupported RSA key parameters")
+		}
+		rsaKey, ok := key.(*rsa.PublicKey)
+		if ok && certPub.E == rsaKey.E && certPub.N.Cmp(rsaKey.N) == 0 {
+			return nil
+		}
 	case *ecdsa.PublicKey:
+		switch certPub.Curve {
+		case elliptic.P256(), elliptic.P384(), elliptic.P521():
+			break
+		default:
+			return errors.New("unsupported ECDSA key parameters")
+		}
+
 		ecKey, ok := key.(*ecdsa.PublicKey)
 		if ok && certPub.X.Cmp(ecKey.X) == 0 && certPub.Y.Cmp(ecKey.Y) == 0 {
 			return nil

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

@@ -89,9 +89,8 @@ func (eca *ExternalCA) Sign(ctx context.Context, req signer.SignRequest) (cert [
 	for _, url := range urls {
 		cert, err = makeExternalSignRequest(ctx, client, url, csrJSON)
 		if err == nil {
-			return eca.rootCA.AppendFirstRootPEM(cert)
+			return cert, err
 		}
-
 		logrus.Debugf("unable to proxy certificate signing request to %s: %s", url, err)
 	}
 

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

@@ -321,7 +321,7 @@ func (k *KeyReadWriter) readKey() (*pem.Block, error) {
 	}
 
 	// If it's encrypted, we can't read without a passphrase (we're assuming
-	// empty passphrases iare invalid)
+	// empty passphrases are invalid)
 	if k.kekData.KEK == nil {
 		return nil, ErrInvalidKEK{Wrapped: x509.IncorrectPasswordError}
 	}

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

@@ -289,8 +289,9 @@ func (a *Allocator) doNetworkInit(ctx context.Context) (err error) {
 			if a.taskAllocateVote(networkVoter, t.ID) {
 				// If the task is not attached to any network, network
 				// allocators job is done. Immediately cast a vote so
-				// that the task can be moved to ALLOCATED state as
+				// that the task can be moved to the PENDING state as
 				// soon as possible.
+				updateTaskStatus(t, api.TaskStatePending, allocatedStatusMessage)
 				allocatedTasks = append(allocatedTasks, t)
 			}
 			continue
@@ -467,7 +468,7 @@ func taskDead(t *api.Task) bool {
 }
 
 // taskReadyForNetworkVote checks if the task is ready for a network
-// vote to move it to ALLOCATED state.
+// vote to move it to PENDING state.
 func taskReadyForNetworkVote(t *api.Task, s *api.Service, nc *networkContext) bool {
 	// Task is ready for vote if the following is true:
 	//

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

@@ -419,7 +419,7 @@ func (na *NetworkAllocator) releaseEndpoints(networks []*api.NetworkAttachment)
 
 		localNet := na.getNetwork(nAttach.Network.ID)
 		if localNet == nil {
-			return fmt.Errorf("could not find network allocater state for network %s", nAttach.Network.ID)
+			return fmt.Errorf("could not find network allocator state for network %s", nAttach.Network.ID)
 		}
 
 		// Do not fail and bail out if we fail to release IP

+ 2 - 1
vendor/github.com/docker/swarmkit/manager/allocator/networkallocator/portallocator.go

@@ -285,7 +285,8 @@ func (pa *portAllocator) portsAllocatedInHostPublishMode(s *api.Service) bool {
 
 	if s.Spec.Endpoint != nil {
 		for _, portConfig := range s.Spec.Endpoint.Ports {
-			if portConfig.PublishMode == api.PublishModeHost {
+			if portConfig.PublishMode == api.PublishModeHost &&
+				portConfig.PublishedPort != 0 {
 				if portStates.delState(portConfig) == nil {
 					return false
 				}

+ 1 - 1
vendor/github.com/docker/swarmkit/manager/controlapi/secret.go

@@ -156,7 +156,7 @@ func (s *Server) ListSecrets(ctx context.Context, request *api.ListSecretsReques
 	return &api.ListSecretsResponse{Secrets: respSecrets}, nil
 }
 
-// CreateSecret creates and return a `CreateSecretResponse` with a `Secret` based
+// CreateSecret creates and returns a `CreateSecretResponse` with a `Secret` based
 // on the provided `CreateSecretRequest.SecretSpec`.
 // - Returns `InvalidArgument` if the `CreateSecretRequest.SecretSpec` is malformed,
 //   or if the secret data is too long or contains invalid characters.

+ 48 - 13
vendor/github.com/docker/swarmkit/manager/controlapi/service.go

@@ -6,12 +6,14 @@ import (
 	"reflect"
 	"strconv"
 	"strings"
+	"time"
 
 	"github.com/docker/distribution/reference"
 	"github.com/docker/swarmkit/api"
 	"github.com/docker/swarmkit/identity"
 	"github.com/docker/swarmkit/manager/constraint"
 	"github.com/docker/swarmkit/manager/state/store"
+	"github.com/docker/swarmkit/protobuf/ptypes"
 	"github.com/docker/swarmkit/template"
 	gogotypes "github.com/gogo/protobuf/types"
 	"golang.org/x/net/context"
@@ -98,6 +100,20 @@ func validateUpdate(uc *api.UpdateConfig) error {
 		return grpc.Errorf(codes.InvalidArgument, "TaskSpec: update-delay cannot be negative")
 	}
 
+	if uc.Monitor != nil {
+		monitor, err := gogotypes.DurationFromProto(uc.Monitor)
+		if err != nil {
+			return err
+		}
+		if monitor < 0 {
+			return grpc.Errorf(codes.InvalidArgument, "TaskSpec: update-monitor cannot be negative")
+		}
+	}
+
+	if uc.MaxFailureRatio < 0 || uc.MaxFailureRatio > 1 {
+		return grpc.Errorf(codes.InvalidArgument, "TaskSpec: update-maxfailureratio cannot be less than 0 or bigger than 1")
+	}
+
 	return nil
 }
 
@@ -125,7 +141,7 @@ func validateContainerSpec(container *api.ContainerSpec) error {
 	return nil
 }
 
-func validateTask(taskSpec api.TaskSpec) error {
+func validateTaskSpec(taskSpec api.TaskSpec) error {
 	if err := validateResourceRequirements(taskSpec.Resources); err != nil {
 		return err
 	}
@@ -138,6 +154,11 @@ func validateTask(taskSpec api.TaskSpec) error {
 		return err
 	}
 
+	// Check to see if the Secret Reference portion of the spec is valid
+	if err := validateSecretRefsSpec(taskSpec); err != nil {
+		return err
+	}
+
 	if taskSpec.GetRuntime() == nil {
 		return grpc.Errorf(codes.InvalidArgument, "TaskSpec: missing runtime")
 	}
@@ -218,8 +239,8 @@ func validateEndpointSpec(epSpec *api.EndpointSpec) error {
 
 // validateSecretRefsSpec finds if the secrets passed in spec are valid and have no
 // conflicting targets.
-func validateSecretRefsSpec(spec *api.ServiceSpec) error {
-	container := spec.Task.GetContainer()
+func validateSecretRefsSpec(spec api.TaskSpec) error {
+	container := spec.GetContainer()
 	if container == nil {
 		return nil
 	}
@@ -257,6 +278,7 @@ func validateSecretRefsSpec(spec *api.ServiceSpec) error {
 
 	return nil
 }
+
 func (s *Server) validateNetworks(networks []*api.NetworkAttachmentConfig) error {
 	for _, na := range networks {
 		var network *api.Network
@@ -297,7 +319,7 @@ func validateServiceSpec(spec *api.ServiceSpec) error {
 	if err := validateAnnotations(spec.Annotations); err != nil {
 		return err
 	}
-	if err := validateTask(spec.Task); err != nil {
+	if err := validateTaskSpec(spec.Task); err != nil {
 		return err
 	}
 	if err := validateUpdate(spec.Update); err != nil {
@@ -309,10 +331,6 @@ func validateServiceSpec(spec *api.ServiceSpec) error {
 	if err := validateMode(spec); err != nil {
 		return err
 	}
-	// Check to see if the Secret Reference portion of the spec is valid
-	if err := validateSecretRefsSpec(spec); err != nil {
-		return err
-	}
 
 	return nil
 }
@@ -406,7 +424,7 @@ func (s *Server) checkSecretExistence(tx store.Tx, spec *api.ServiceSpec) error
 	return nil
 }
 
-// CreateService creates and return a Service based on the provided ServiceSpec.
+// CreateService creates and returns a Service based on the provided ServiceSpec.
 // - Returns `InvalidArgument` if the ServiceSpec is malformed.
 // - Returns `Unimplemented` if the ServiceSpec references unimplemented features.
 // - Returns `AlreadyExists` if the ServiceID conflicts.
@@ -537,11 +555,28 @@ func (s *Server) UpdateService(ctx context.Context, request *api.UpdateServiceRe
 		}
 
 		service.Meta.Version = *request.ServiceVersion
-		service.PreviousSpec = service.Spec.Copy()
-		service.Spec = *request.Spec.Copy()
 
-		// Reset update status
-		service.UpdateStatus = nil
+		if request.Rollback == api.UpdateServiceRequest_PREVIOUS {
+			if service.PreviousSpec == nil {
+				return grpc.Errorf(codes.FailedPrecondition, "service %s does not have a previous spec", request.ServiceID)
+			}
+
+			curSpec := service.Spec.Copy()
+			service.Spec = *service.PreviousSpec.Copy()
+			service.PreviousSpec = curSpec
+
+			service.UpdateStatus = &api.UpdateStatus{
+				State:     api.UpdateStatus_ROLLBACK_STARTED,
+				Message:   "manually requested rollback",
+				StartedAt: ptypes.MustTimestampProto(time.Now()),
+			}
+		} else {
+			service.PreviousSpec = service.Spec.Copy()
+			service.Spec = *request.Spec.Copy()
+
+			// Reset update status
+			service.UpdateStatus = nil
+		}
 
 		return store.UpdateService(tx, service)
 	})

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

@@ -29,7 +29,7 @@ func NewNACLSecretbox(key []byte) NACLSecretbox {
 	return secretbox
 }
 
-// Algorithm returns the type of algorhtm this is (NACL Secretbox using XSalsa20 and Poly1305)
+// Algorithm returns the type of algorithm this is (NACL Secretbox using XSalsa20 and Poly1305)
 func (n NACLSecretbox) Algorithm() api.MaybeEncryptedRecord_Algorithm {
 	return api.MaybeEncryptedRecord_NACLSecretboxSalsa20Poly1305
 }

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

@@ -200,8 +200,6 @@ func (k *KeyManager) Run(ctx context.Context) error {
 	} else {
 		k.keyRing.lClock = cluster.EncryptionKeyLamportClock
 		k.keyRing.keys = cluster.NetworkBootstrapKeys
-
-		k.rotateKey(ctx)
 	}
 
 	ticker := time.NewTicker(k.config.RotationInterval)

+ 16 - 4
vendor/github.com/docker/swarmkit/manager/orchestrator/constraintenforcer/constraint_enforcer.go

@@ -1,11 +1,14 @@
 package constraintenforcer
 
 import (
+	"time"
+
 	"github.com/docker/swarmkit/api"
 	"github.com/docker/swarmkit/log"
 	"github.com/docker/swarmkit/manager/constraint"
 	"github.com/docker/swarmkit/manager/state"
 	"github.com/docker/swarmkit/manager/state/store"
+	"github.com/docker/swarmkit/protobuf/ptypes"
 )
 
 // ConstraintEnforcer watches for updates to nodes and shuts down tasks that no
@@ -43,7 +46,7 @@ func (ce *ConstraintEnforcer) Run() {
 		log.L.WithError(err).Error("failed to check nodes for noncompliant tasks")
 	} else {
 		for _, node := range nodes {
-			ce.shutdownNoncompliantTasks(node)
+			ce.rejectNoncompliantTasks(node)
 		}
 	}
 
@@ -51,14 +54,14 @@ func (ce *ConstraintEnforcer) Run() {
 		select {
 		case event := <-watcher:
 			node := event.(state.EventUpdateNode).Node
-			ce.shutdownNoncompliantTasks(node)
+			ce.rejectNoncompliantTasks(node)
 		case <-ce.stopChan:
 			return
 		}
 	}
 }
 
-func (ce *ConstraintEnforcer) shutdownNoncompliantTasks(node *api.Node) {
+func (ce *ConstraintEnforcer) rejectNoncompliantTasks(node *api.Node) {
 	// If the availability is "drain", the orchestrator will
 	// shut down all tasks.
 	// If the availability is "pause", we shouldn't touch
@@ -134,7 +137,16 @@ func (ce *ConstraintEnforcer) shutdownNoncompliantTasks(node *api.Node) {
 						return nil
 					}
 
-					t.DesiredState = api.TaskStateShutdown
+					// We set the observed state to
+					// REJECTED, rather than the desired
+					// state. Desired state is owned by the
+					// orchestrator, and setting it directly
+					// will bypass actions such as
+					// restarting the task on another node
+					// (if applicable).
+					t.Status.State = api.TaskStateRejected
+					t.Status.Message = "assigned node no longer meets constraints"
+					t.Status.Timestamp = ptypes.MustTimestampProto(time.Now())
 					return store.UpdateTask(tx, t)
 				})
 				if err != nil {

+ 104 - 31
vendor/github.com/docker/swarmkit/manager/orchestrator/global/global.go

@@ -6,6 +6,7 @@ import (
 	"github.com/docker/swarmkit/manager/constraint"
 	"github.com/docker/swarmkit/manager/orchestrator"
 	"github.com/docker/swarmkit/manager/orchestrator/restart"
+	"github.com/docker/swarmkit/manager/orchestrator/taskinit"
 	"github.com/docker/swarmkit/manager/orchestrator/update"
 	"github.com/docker/swarmkit/manager/state"
 	"github.com/docker/swarmkit/manager/state/store"
@@ -27,6 +28,7 @@ type Orchestrator struct {
 	nodes map[string]*api.Node
 	// globalServices has all the global services in the cluster, indexed by ServiceID
 	globalServices map[string]globalService
+	restartTasks   map[string]struct{}
 
 	// stopChan signals to the state machine to stop running.
 	stopChan chan struct{}
@@ -51,9 +53,14 @@ func NewGlobalOrchestrator(store *store.MemoryStore) *Orchestrator {
 		doneChan:       make(chan struct{}),
 		updater:        updater,
 		restarts:       restartSupervisor,
+		restartTasks:   make(map[string]struct{}),
 	}
 }
 
+func (g *Orchestrator) initTasks(ctx context.Context, readTx store.ReadTx) error {
+	return taskinit.CheckTasks(ctx, g.store, readTx, g, g.restarts)
+}
+
 // Run contains the global orchestrator event loop
 func (g *Orchestrator) Run(ctx context.Context) error {
 	defer close(g.doneChan)
@@ -106,6 +113,16 @@ func (g *Orchestrator) Run(ctx context.Context) error {
 			reconcileServiceIDs = append(reconcileServiceIDs, s.ID)
 		}
 	}
+
+	// fix tasks in store before reconciliation loop
+	g.store.View(func(readTx store.ReadTx) {
+		err = g.initTasks(ctx, readTx)
+	})
+	if err != nil {
+		return err
+	}
+
+	g.tickTasks(ctx)
 	g.reconcileServices(ctx, reconcileServiceIDs)
 
 	for {
@@ -152,15 +169,7 @@ func (g *Orchestrator) Run(ctx context.Context) error {
 				g.removeTasksFromNode(ctx, v.Node)
 				delete(g.nodes, v.Node.ID)
 			case state.EventUpdateTask:
-				if _, exists := g.globalServices[v.Task.ServiceID]; !exists {
-					continue
-				}
-				// global orchestrator needs to inspect when a task has terminated
-				// it should ignore tasks whose DesiredState is past running, which
-				// means the task has been processed
-				if isTaskTerminated(v.Task) {
-					g.restartTask(ctx, v.Task.ID, v.Task.ServiceID)
-				}
+				g.handleTaskChange(ctx, v.Task)
 			case state.EventDeleteTask:
 				// CLI allows deleting task
 				if _, exists := g.globalServices[v.Task.ServiceID]; !exists {
@@ -171,6 +180,52 @@ func (g *Orchestrator) Run(ctx context.Context) error {
 		case <-g.stopChan:
 			return nil
 		}
+		g.tickTasks(ctx)
+	}
+}
+
+// FixTask validates a task with the current cluster settings, and takes
+// action to make it conformant to node state and service constraint
+// it's called at orchestrator initialization
+func (g *Orchestrator) FixTask(ctx context.Context, batch *store.Batch, t *api.Task) {
+	if _, exists := g.globalServices[t.ServiceID]; !exists {
+		return
+	}
+	// if a task's DesiredState has past running, the task has been processed
+	if t.DesiredState > api.TaskStateRunning {
+		return
+	}
+
+	var node *api.Node
+	if t.NodeID != "" {
+		node = g.nodes[t.NodeID]
+	}
+	// if the node no longer valid, remove the task
+	if t.NodeID == "" || orchestrator.InvalidNode(node) {
+		g.removeTask(ctx, batch, t)
+		return
+	}
+
+	// restart a task if it fails
+	if t.Status.State > api.TaskStateRunning {
+		g.restartTasks[t.ID] = struct{}{}
+	}
+}
+
+// handleTaskChange defines what orchestrator does when a task is updated by agent
+func (g *Orchestrator) handleTaskChange(ctx context.Context, t *api.Task) {
+	if _, exists := g.globalServices[t.ServiceID]; !exists {
+		return
+	}
+	// if a task's DesiredState has past running, which
+	// means the task has been processed
+	if t.DesiredState > api.TaskStateRunning {
+		return
+	}
+
+	// if a task has passed running, restart it
+	if t.Status.State > api.TaskStateRunning {
+		g.restartTasks[t.ID] = struct{}{}
 	}
 }
 
@@ -227,7 +282,7 @@ func (g *Orchestrator) reconcileServices(ctx context.Context, serviceIDs []strin
 			nodeTasks[serviceID] = make(map[string][]*api.Task)
 
 			for _, t := range tasks {
-				if isTaskRunning(t) {
+				if t.DesiredState <= api.TaskStateRunning {
 					// Collect all running instances of this service
 					nodeTasks[serviceID][t.NodeID] = append(nodeTasks[serviceID][t.NodeID], t)
 				} else {
@@ -369,7 +424,7 @@ func (g *Orchestrator) reconcileServicesOneNode(ctx context.Context, serviceIDs
 			if t.ServiceID != serviceID {
 				continue
 			}
-			if isTaskRunning(t) {
+			if t.DesiredState <= api.TaskStateRunning {
 				tasks[serviceID] = append(tasks[serviceID], t)
 			} else {
 				if isTaskCompleted(t, orchestrator.RestartCondition(t)) {
@@ -447,24 +502,45 @@ func (g *Orchestrator) reconcileServicesOneNode(ctx context.Context, serviceIDs
 	}
 }
 
-// restartTask calls the restart supervisor's Restart function, which
-// sets a task's desired state to shutdown and restarts it if the restart
-// policy calls for it to be restarted.
-func (g *Orchestrator) restartTask(ctx context.Context, taskID string, serviceID string) {
-	err := g.store.Update(func(tx store.Tx) error {
-		t := store.GetTask(tx, taskID)
-		if t == nil || t.DesiredState > api.TaskStateRunning {
-			return nil
-		}
-		service := store.GetService(tx, serviceID)
-		if service == nil {
-			return nil
+func (g *Orchestrator) tickTasks(ctx context.Context) {
+	if len(g.restartTasks) == 0 {
+		return
+	}
+	_, err := g.store.Batch(func(batch *store.Batch) error {
+		for taskID := range g.restartTasks {
+			err := batch.Update(func(tx store.Tx) error {
+				t := store.GetTask(tx, taskID)
+				if t == nil || t.DesiredState > api.TaskStateRunning {
+					return nil
+				}
+
+				service := store.GetService(tx, t.ServiceID)
+				if service == nil {
+					return nil
+				}
+
+				node, nodeExists := g.nodes[t.NodeID]
+				serviceEntry, serviceExists := g.globalServices[t.ServiceID]
+				if !nodeExists || !serviceExists {
+					return nil
+				}
+				if !constraint.NodeMatches(serviceEntry.constraints, node) {
+					t.DesiredState = api.TaskStateShutdown
+					return store.UpdateTask(tx, t)
+				}
+
+				return g.restarts.Restart(ctx, tx, g.cluster, service, *t)
+			})
+			if err != nil {
+				log.G(ctx).WithError(err).Errorf("orchestrator restartTask transaction failed")
+			}
 		}
-		return g.restarts.Restart(ctx, tx, g.cluster, service, *t)
+		return nil
 	})
 	if err != nil {
 		log.G(ctx).WithError(err).Errorf("global orchestrator: restartTask transaction failed")
 	}
+	g.restartTasks = make(map[string]struct{})
 }
 
 func (g *Orchestrator) removeTask(ctx context.Context, batch *store.Batch, t *api.Task) {
@@ -503,18 +579,15 @@ func (g *Orchestrator) removeTasks(ctx context.Context, batch *store.Batch, task
 	}
 }
 
-func isTaskRunning(t *api.Task) bool {
-	return t != nil && t.DesiredState <= api.TaskStateRunning && t.Status.State <= api.TaskStateRunning
+// IsRelatedService returns true if the service should be governed by this orchestrator
+func (g *Orchestrator) IsRelatedService(service *api.Service) bool {
+	return orchestrator.IsGlobalService(service)
 }
 
 func isTaskCompleted(t *api.Task, restartPolicy api.RestartPolicy_RestartCondition) bool {
-	if t == nil || isTaskRunning(t) {
+	if t == nil || t.DesiredState <= api.TaskStateRunning {
 		return false
 	}
 	return restartPolicy == api.RestartOnNone ||
 		(restartPolicy == api.RestartOnFailure && t.Status.State == api.TaskStateCompleted)
 }
-
-func isTaskTerminated(t *api.Task) bool {
-	return t != nil && t.Status.State > api.TaskStateRunning
-}

+ 5 - 0
vendor/github.com/docker/swarmkit/manager/orchestrator/replicated/services.go

@@ -223,3 +223,8 @@ func (r *Orchestrator) deleteTask(ctx context.Context, batch *store.Batch, t *ap
 		log.G(ctx).WithError(err).Errorf("deleting task %s failed", t.ID)
 	}
 }
+
+// IsRelatedService returns true if the service should be governed by this orchestrator
+func (r *Orchestrator) IsRelatedService(service *api.Service) bool {
+	return orchestrator.IsReplicatedService(service)
+}

+ 39 - 92
vendor/github.com/docker/swarmkit/manager/orchestrator/replicated/tasks.go

@@ -1,15 +1,13 @@
 package replicated
 
 import (
-	"time"
-
 	"github.com/docker/go-events"
 	"github.com/docker/swarmkit/api"
 	"github.com/docker/swarmkit/log"
 	"github.com/docker/swarmkit/manager/orchestrator"
+	"github.com/docker/swarmkit/manager/orchestrator/taskinit"
 	"github.com/docker/swarmkit/manager/state"
 	"github.com/docker/swarmkit/manager/state/store"
-	gogotypes "github.com/gogo/protobuf/types"
 	"golang.org/x/net/context"
 )
 
@@ -18,94 +16,8 @@ import (
 // service-level reconciliation, which observes changes to services and creates
 // and/or kills tasks to match the service definition.
 
-func invalidNode(n *api.Node) bool {
-	return n == nil ||
-		n.Status.State == api.NodeStatus_DOWN ||
-		n.Spec.Availability == api.NodeAvailabilityDrain
-}
-
 func (r *Orchestrator) initTasks(ctx context.Context, readTx store.ReadTx) error {
-	tasks, err := store.FindTasks(readTx, store.All)
-	if err != nil {
-		return err
-	}
-	for _, t := range tasks {
-		if t.NodeID != "" {
-			n := store.GetNode(readTx, t.NodeID)
-			if invalidNode(n) && t.Status.State <= api.TaskStateRunning && t.DesiredState <= api.TaskStateRunning {
-				r.restartTasks[t.ID] = struct{}{}
-			}
-		}
-	}
-
-	_, err = r.store.Batch(func(batch *store.Batch) error {
-		for _, t := range tasks {
-			if t.ServiceID == "" {
-				continue
-			}
-
-			// TODO(aluzzardi): We should NOT retrieve the service here.
-			service := store.GetService(readTx, t.ServiceID)
-			if service == nil {
-				// Service was deleted
-				err := batch.Update(func(tx store.Tx) error {
-					return store.DeleteTask(tx, t.ID)
-				})
-				if err != nil {
-					log.G(ctx).WithError(err).Error("failed to set task desired state to dead")
-				}
-				continue
-			}
-			// TODO(aluzzardi): This is shady. We should have a more generic condition.
-			if t.DesiredState != api.TaskStateReady || !orchestrator.IsReplicatedService(service) {
-				continue
-			}
-			restartDelay := orchestrator.DefaultRestartDelay
-			if t.Spec.Restart != nil && t.Spec.Restart.Delay != nil {
-				var err error
-				restartDelay, err = gogotypes.DurationFromProto(t.Spec.Restart.Delay)
-				if err != nil {
-					log.G(ctx).WithError(err).Error("invalid restart delay")
-					restartDelay = orchestrator.DefaultRestartDelay
-				}
-			}
-			if restartDelay != 0 {
-				timestamp, err := gogotypes.TimestampFromProto(t.Status.Timestamp)
-				if err == nil {
-					restartTime := timestamp.Add(restartDelay)
-					calculatedRestartDelay := restartTime.Sub(time.Now())
-					if calculatedRestartDelay < restartDelay {
-						restartDelay = calculatedRestartDelay
-					}
-					if restartDelay > 0 {
-						_ = batch.Update(func(tx store.Tx) error {
-							t := store.GetTask(tx, t.ID)
-							// TODO(aluzzardi): This is shady as well. We should have a more generic condition.
-							if t == nil || t.DesiredState != api.TaskStateReady {
-								return nil
-							}
-							r.restarts.DelayStart(ctx, tx, nil, t.ID, restartDelay, true)
-							return nil
-						})
-						continue
-					}
-				} else {
-					log.G(ctx).WithError(err).Error("invalid status timestamp")
-				}
-			}
-
-			// Start now
-			err := batch.Update(func(tx store.Tx) error {
-				return r.restarts.StartNow(tx, t.ID)
-			})
-			if err != nil {
-				log.G(ctx).WithError(err).WithField("task.id", t.ID).Error("moving task out of delayed state failed")
-			}
-		}
-		return nil
-	})
-
-	return err
+	return taskinit.CheckTasks(ctx, r.store, readTx, r, r.restarts)
 }
 
 func (r *Orchestrator) handleTaskEvent(ctx context.Context, event events.Event) {
@@ -196,13 +108,14 @@ func (r *Orchestrator) restartTasksByNodeID(ctx context.Context, nodeID string)
 }
 
 func (r *Orchestrator) handleNodeChange(ctx context.Context, n *api.Node) {
-	if !invalidNode(n) {
+	if !orchestrator.InvalidNode(n) {
 		return
 	}
 
 	r.restartTasksByNodeID(ctx, n.ID)
 }
 
+// handleTaskChange defines what orchestrator does when a task is updated by agent.
 func (r *Orchestrator) handleTaskChange(ctx context.Context, t *api.Task) {
 	// If we already set the desired state past TaskStateRunning, there is no
 	// further action necessary.
@@ -228,7 +141,41 @@ func (r *Orchestrator) handleTaskChange(ctx context.Context, t *api.Task) {
 	}
 
 	if t.Status.State > api.TaskStateRunning ||
-		(t.NodeID != "" && invalidNode(n)) {
+		(t.NodeID != "" && orchestrator.InvalidNode(n)) {
 		r.restartTasks[t.ID] = struct{}{}
 	}
 }
+
+// FixTask validates a task with the current cluster settings, and takes
+// action to make it conformant. it's called at orchestrator initialization.
+func (r *Orchestrator) FixTask(ctx context.Context, batch *store.Batch, t *api.Task) {
+	// If we already set the desired state past TaskStateRunning, there is no
+	// further action necessary.
+	if t.DesiredState > api.TaskStateRunning {
+		return
+	}
+
+	var (
+		n       *api.Node
+		service *api.Service
+	)
+	batch.Update(func(tx store.Tx) error {
+		if t.NodeID != "" {
+			n = store.GetNode(tx, t.NodeID)
+		}
+		if t.ServiceID != "" {
+			service = store.GetService(tx, t.ServiceID)
+		}
+		return nil
+	})
+
+	if !orchestrator.IsReplicatedService(service) {
+		return
+	}
+
+	if t.Status.State > api.TaskStateRunning ||
+		(t.NodeID != "" && orchestrator.InvalidNode(n)) {
+		r.restartTasks[t.ID] = struct{}{}
+		return
+	}
+}

+ 7 - 0
vendor/github.com/docker/swarmkit/manager/orchestrator/task.go

@@ -65,3 +65,10 @@ func IsTaskDirty(s *api.Service, t *api.Task) bool {
 	return !reflect.DeepEqual(s.Spec.Task, t.Spec) ||
 		(t.Endpoint != nil && !reflect.DeepEqual(s.Spec.Endpoint, t.Endpoint.Spec))
 }
+
+// InvalidNode is true if the node is nil, down, or drained
+func InvalidNode(n *api.Node) bool {
+	return n == nil ||
+		n.Status.State == api.NodeStatus_DOWN ||
+		n.Spec.Availability == api.NodeAvailabilityDrain
+}

+ 103 - 0
vendor/github.com/docker/swarmkit/manager/orchestrator/taskinit/init.go

@@ -0,0 +1,103 @@
+package taskinit
+
+import (
+	"time"
+
+	"github.com/docker/swarmkit/api"
+	"github.com/docker/swarmkit/log"
+	"github.com/docker/swarmkit/manager/orchestrator"
+	"github.com/docker/swarmkit/manager/orchestrator/restart"
+	"github.com/docker/swarmkit/manager/state/store"
+	gogotypes "github.com/gogo/protobuf/types"
+	"golang.org/x/net/context"
+)
+
+// InitHandler defines orchestrator's action to fix tasks at start.
+type InitHandler interface {
+	IsRelatedService(service *api.Service) bool
+	FixTask(ctx context.Context, batch *store.Batch, t *api.Task)
+}
+
+// CheckTasks fixes tasks in the store before orchestrator runs. The previous leader might
+// not have finished processing their updates and left them in an inconsistent state.
+func CheckTasks(ctx context.Context, s *store.MemoryStore, readTx store.ReadTx, initHandler InitHandler, startSupervisor *restart.Supervisor) error {
+	_, err := s.Batch(func(batch *store.Batch) error {
+		tasks, err := store.FindTasks(readTx, store.All)
+		if err != nil {
+			return err
+		}
+		for _, t := range tasks {
+			if t.ServiceID == "" {
+				continue
+			}
+
+			// TODO(aluzzardi): We should NOT retrieve the service here.
+			service := store.GetService(readTx, t.ServiceID)
+			if service == nil {
+				// Service was deleted
+				err := batch.Update(func(tx store.Tx) error {
+					return store.DeleteTask(tx, t.ID)
+				})
+				if err != nil {
+					log.G(ctx).WithError(err).Error("failed to delete task")
+				}
+				continue
+			}
+			if !initHandler.IsRelatedService(service) {
+				continue
+			}
+
+			// handle task updates from agent which should have been triggered by task update events
+			initHandler.FixTask(ctx, batch, t)
+
+			// desired state ready is a transient state that it should be started.
+			// however previous leader may not have started it, retry start here
+			if t.DesiredState != api.TaskStateReady || t.Status.State > api.TaskStateRunning {
+				continue
+			}
+			restartDelay := orchestrator.DefaultRestartDelay
+			if t.Spec.Restart != nil && t.Spec.Restart.Delay != nil {
+				var err error
+				restartDelay, err = gogotypes.DurationFromProto(t.Spec.Restart.Delay)
+				if err != nil {
+					log.G(ctx).WithError(err).Error("invalid restart delay")
+					restartDelay = orchestrator.DefaultRestartDelay
+				}
+			}
+			if restartDelay != 0 {
+				timestamp, err := gogotypes.TimestampFromProto(t.Status.Timestamp)
+				if err == nil {
+					restartTime := timestamp.Add(restartDelay)
+					calculatedRestartDelay := restartTime.Sub(time.Now())
+					if calculatedRestartDelay < restartDelay {
+						restartDelay = calculatedRestartDelay
+					}
+					if restartDelay > 0 {
+						_ = batch.Update(func(tx store.Tx) error {
+							t := store.GetTask(tx, t.ID)
+							// TODO(aluzzardi): This is shady as well. We should have a more generic condition.
+							if t == nil || t.DesiredState != api.TaskStateReady {
+								return nil
+							}
+							startSupervisor.DelayStart(ctx, tx, nil, t.ID, restartDelay, true)
+							return nil
+						})
+						continue
+					}
+				} else {
+					log.G(ctx).WithError(err).Error("invalid status timestamp")
+				}
+			}
+
+			// Start now
+			err := batch.Update(func(tx store.Tx) error {
+				return startSupervisor.StartNow(tx, t.ID)
+			})
+			if err != nil {
+				log.G(ctx).WithError(err).WithField("task.id", t.ID).Error("moving task out of delayed state failed")
+			}
+		}
+		return nil
+	})
+	return err
+}

+ 12 - 5
vendor/github.com/docker/swarmkit/manager/orchestrator/taskreaper/task_reaper.go

@@ -131,11 +131,13 @@ func (tr *TaskReaper) tick() {
 	}
 
 	defer func() {
-		tr.dirty = make(map[instanceTuple]struct{})
 		tr.orphaned = nil
 	}()
 
-	deleteTasks := tr.orphaned
+	deleteTasks := make(map[string]struct{})
+	for _, tID := range tr.orphaned {
+		deleteTasks[tID] = struct{}{}
+	}
 	tr.store.View(func(tx store.ReadTx) {
 		for dirty := range tr.dirty {
 			service := store.GetService(tx, dirty.serviceID)
@@ -180,13 +182,15 @@ func (tr *TaskReaper) tick() {
 			// instead of sorting the whole slice.
 			sort.Sort(tasksByTimestamp(historicTasks))
 
+			runningTasks := 0
 			for _, t := range historicTasks {
-				if t.DesiredState <= api.TaskStateRunning {
+				if t.DesiredState <= api.TaskStateRunning || t.Status.State <= api.TaskStateRunning {
 					// Don't delete running tasks
+					runningTasks++
 					continue
 				}
 
-				deleteTasks = append(deleteTasks, t.ID)
+				deleteTasks[t.ID] = struct{}{}
 
 				taskHistory++
 				if int64(len(historicTasks)) <= taskHistory {
@@ -194,12 +198,15 @@ func (tr *TaskReaper) tick() {
 				}
 			}
 
+			if runningTasks <= 1 {
+				delete(tr.dirty, dirty)
+			}
 		}
 	})
 
 	if len(deleteTasks) > 0 {
 		tr.store.Batch(func(batch *store.Batch) error {
-			for _, taskID := range deleteTasks {
+			for taskID := range deleteTasks {
 				batch.Update(func(tx store.Tx) error {
 					return store.DeleteTask(tx, taskID)
 				})

+ 30 - 23
vendor/github.com/docker/swarmkit/manager/orchestrator/update/updater.go

@@ -156,10 +156,34 @@ func (u *Updater) Run(ctx context.Context, slots []orchestrator.Slot) {
 		u.startUpdate(ctx, service.ID)
 	}
 
-	parallelism := 0
-	if service.Spec.Update != nil {
-		parallelism = int(service.Spec.Update.Parallelism)
+	var (
+		parallelism            int
+		delay                  time.Duration
+		failureAction          = api.UpdateConfig_PAUSE
+		allowedFailureFraction = float32(0)
+		monitoringPeriod       = defaultMonitor
+	)
+
+	updateConfig := service.Spec.Update
+	if service.UpdateStatus != nil && service.UpdateStatus.State == api.UpdateStatus_ROLLBACK_STARTED {
+		updateConfig = service.Spec.Rollback
+	}
+
+	if updateConfig != nil {
+		failureAction = updateConfig.FailureAction
+		allowedFailureFraction = updateConfig.MaxFailureRatio
+		parallelism = int(updateConfig.Parallelism)
+		delay = updateConfig.Delay
+
+		var err error
+		if updateConfig.Monitor != nil {
+			monitoringPeriod, err = gogotypes.DurationFromProto(updateConfig.Monitor)
+			if err != nil {
+				monitoringPeriod = defaultMonitor
+			}
+		}
 	}
+
 	if parallelism == 0 {
 		// TODO(aluzzardi): We could try to optimize unlimited parallelism by performing updates in a single
 		// goroutine using a batch transaction.
@@ -172,28 +196,11 @@ func (u *Updater) Run(ctx context.Context, slots []orchestrator.Slot) {
 	wg.Add(parallelism)
 	for i := 0; i < parallelism; i++ {
 		go func() {
-			u.worker(ctx, slotQueue)
+			u.worker(ctx, slotQueue, delay)
 			wg.Done()
 		}()
 	}
 
-	failureAction := api.UpdateConfig_PAUSE
-	allowedFailureFraction := float32(0)
-	monitoringPeriod := defaultMonitor
-
-	if service.Spec.Update != nil {
-		failureAction = service.Spec.Update.FailureAction
-		allowedFailureFraction = service.Spec.Update.MaxFailureRatio
-
-		if service.Spec.Update.Monitor != nil {
-			var err error
-			monitoringPeriod, err = gogotypes.DurationFromProto(service.Spec.Update.Monitor)
-			if err != nil {
-				monitoringPeriod = defaultMonitor
-			}
-		}
-	}
-
 	var failedTaskWatch chan events.Event
 
 	if failureAction != api.UpdateConfig_CONTINUE {
@@ -303,7 +310,7 @@ slotsLoop:
 	}
 }
 
-func (u *Updater) worker(ctx context.Context, queue <-chan orchestrator.Slot) {
+func (u *Updater) worker(ctx context.Context, queue <-chan orchestrator.Slot, delay time.Duration) {
 	for slot := range queue {
 		// Do we have a task with the new spec in desired state = RUNNING?
 		// If so, all we have to do to complete the update is remove the
@@ -345,7 +352,7 @@ func (u *Updater) worker(ctx context.Context, queue <-chan orchestrator.Slot) {
 			}
 		}
 
-		if u.newService.Spec.Update != nil && u.newService.Spec.Update.Delay != 0 {
+		if delay != 0 {
 			select {
 			case <-time.After(u.newService.Spec.Update.Delay):
 			case <-u.stopChan:

+ 1 - 1
vendor/github.com/docker/swarmkit/manager/state/doc.go

@@ -12,7 +12,7 @@
 //
 //	err := store.Update(func(tx state.Tx) {
 //		if err := tx.Nodes().Update(newNode); err != nil {
-//			reutrn err
+//			return err
 //		}
 //		return nil
 //	})

+ 1 - 1
vendor/github.com/docker/swarmkit/manager/state/raft/storage/snapwrap.go

@@ -100,7 +100,7 @@ func (o originalSnap) New(dirpath string) Snapshotter {
 	return snap.New(dirpath)
 }
 
-// OriginalSnap is the original `snap` package as an implemntation of the SnapFactory interface
+// OriginalSnap is the original `snap` package as an implementation of the SnapFactory interface
 var OriginalSnap SnapFactory = originalSnap{}
 
 // MigrateSnapshot reads the latest existing snapshot from one directory, encoded one way, and writes

+ 1 - 1
vendor/github.com/docker/swarmkit/manager/state/raft/storage/walwrap.go

@@ -136,7 +136,7 @@ func (o originalWAL) Open(dirpath string, walsnap walpb.Snapshot) (WAL, error) {
 	return wal.Open(dirpath, walsnap)
 }
 
-// OriginalWAL is the original `wal` package as an implemntation of the WALFactory interface
+// OriginalWAL is the original `wal` package as an implementation of the WALFactory interface
 var OriginalWAL WALFactory = originalWAL{}
 
 // WALData contains all the data returned by a WAL's ReadAll() function