Browse code

Swarmkit vendoring.

Signed-off-by: Anshul Pundir <anshul.pundir@docker.com>

Anshul Pundir authored on 2017/12/05 09:38:37
Showing 41 changed files
... ...
@@ -114,7 +114,7 @@ github.com/dmcgowan/go-tar go1.10
114 114
 github.com/stevvooe/ttrpc 76e68349ad9ab4d03d764c713826d31216715e4f
115 115
 
116 116
 # cluster
117
-github.com/docker/swarmkit de950a7ed842c7b7e47e9451cde9bf8f96031894
117
+github.com/docker/swarmkit 4429c763170d9ca96929249353c3270c19e7d39e
118 118
 github.com/gogo/protobuf v0.4
119 119
 github.com/cloudflare/cfssl 7fb22c8cba7ecaf98e4082d22d65800cf45e042a
120 120
 github.com/google/certificate-transparency d90e65c3a07988180c5b1ece71791c0b6506826e
... ...
@@ -288,7 +288,9 @@ func Do(ctx context.Context, task *api.Task, ctlr Controller) (*api.TaskStatus,
288 288
 		status.PortStatus = portStatus
289 289
 	}()
290 290
 
291
-	if task.DesiredState == api.TaskStateShutdown {
291
+	// this branch bounds the largest state achievable in the agent as SHUTDOWN, which
292
+	// is exactly the correct behavior for the agent.
293
+	if task.DesiredState >= api.TaskStateShutdown {
292 294
 		if status.State >= api.TaskStateCompleted {
293 295
 			return noop()
294 296
 		}
... ...
@@ -131,6 +131,8 @@
131 131
 		LeaveResponse
132 132
 		ProcessRaftMessageRequest
133 133
 		ProcessRaftMessageResponse
134
+		StreamRaftMessageRequest
135
+		StreamRaftMessageResponse
134 136
 		ResolveAddressRequest
135 137
 		ResolveAddressResponse
136 138
 		InternalRaftRequest
... ...
@@ -235,6 +237,7 @@ import (
235 235
 
236 236
 import raftselector "github.com/docker/swarmkit/manager/raftselector"
237 237
 import codes "google.golang.org/grpc/codes"
238
+import status "google.golang.org/grpc/status"
238 239
 import metadata "google.golang.org/grpc/metadata"
239 240
 import transport "google.golang.org/grpc/transport"
240 241
 import rafttime "time"
... ...
@@ -984,12 +987,12 @@ func NewRaftProxyCAServer(local CAServer, connSelector raftselector.ConnProvider
984 984
 	redirectChecker := func(ctx context.Context) (context.Context, error) {
985 985
 		s, ok := transport.StreamFromContext(ctx)
986 986
 		if !ok {
987
-			return ctx, grpc.Errorf(codes.InvalidArgument, "remote addr is not found in context")
987
+			return ctx, status.Errorf(codes.InvalidArgument, "remote addr is not found in context")
988 988
 		}
989 989
 		addr := s.ServerTransport().RemoteAddr().String()
990 990
 		md, ok := metadata.FromContext(ctx)
991 991
 		if ok && len(md["redirect"]) != 0 {
992
-			return ctx, grpc.Errorf(codes.ResourceExhausted, "more than one redirect to leader from: %s", md["redirect"])
992
+			return ctx, status.Errorf(codes.ResourceExhausted, "more than one redirect to leader from: %s", md["redirect"])
993 993
 		}
994 994
 		if !ok {
995 995
 			md = metadata.New(map[string]string{})
... ...
@@ -1126,12 +1129,12 @@ func NewRaftProxyNodeCAServer(local NodeCAServer, connSelector raftselector.Conn
1126 1126
 	redirectChecker := func(ctx context.Context) (context.Context, error) {
1127 1127
 		s, ok := transport.StreamFromContext(ctx)
1128 1128
 		if !ok {
1129
-			return ctx, grpc.Errorf(codes.InvalidArgument, "remote addr is not found in context")
1129
+			return ctx, status.Errorf(codes.InvalidArgument, "remote addr is not found in context")
1130 1130
 		}
1131 1131
 		addr := s.ServerTransport().RemoteAddr().String()
1132 1132
 		md, ok := metadata.FromContext(ctx)
1133 1133
 		if ok && len(md["redirect"]) != 0 {
1134
-			return ctx, grpc.Errorf(codes.ResourceExhausted, "more than one redirect to leader from: %s", md["redirect"])
1134
+			return ctx, status.Errorf(codes.ResourceExhausted, "more than one redirect to leader from: %s", md["redirect"])
1135 1135
 		}
1136 1136
 		if !ok {
1137 1137
 			md = metadata.New(map[string]string{})
... ...
@@ -19,6 +19,7 @@ import (
19 19
 
20 20
 import raftselector "github.com/docker/swarmkit/manager/raftselector"
21 21
 import codes "google.golang.org/grpc/codes"
22
+import status "google.golang.org/grpc/status"
22 23
 import metadata "google.golang.org/grpc/metadata"
23 24
 import transport "google.golang.org/grpc/transport"
24 25
 import rafttime "time"
... ...
@@ -5859,12 +5860,12 @@ func NewRaftProxyControlServer(local ControlServer, connSelector raftselector.Co
5859 5859
 	redirectChecker := func(ctx context.Context) (context.Context, error) {
5860 5860
 		s, ok := transport.StreamFromContext(ctx)
5861 5861
 		if !ok {
5862
-			return ctx, grpc.Errorf(codes.InvalidArgument, "remote addr is not found in context")
5862
+			return ctx, status.Errorf(codes.InvalidArgument, "remote addr is not found in context")
5863 5863
 		}
5864 5864
 		addr := s.ServerTransport().RemoteAddr().String()
5865 5865
 		md, ok := metadata.FromContext(ctx)
5866 5866
 		if ok && len(md["redirect"]) != 0 {
5867
-			return ctx, grpc.Errorf(codes.ResourceExhausted, "more than one redirect to leader from: %s", md["redirect"])
5867
+			return ctx, status.Errorf(codes.ResourceExhausted, "more than one redirect to leader from: %s", md["redirect"])
5868 5868
 		}
5869 5869
 		if !ok {
5870 5870
 			md = metadata.New(map[string]string{})
... ...
@@ -24,6 +24,7 @@ import github_com_gogo_protobuf_types "github.com/gogo/protobuf/types"
24 24
 
25 25
 import raftselector "github.com/docker/swarmkit/manager/raftselector"
26 26
 import codes "google.golang.org/grpc/codes"
27
+import status "google.golang.org/grpc/status"
27 28
 import metadata "google.golang.org/grpc/metadata"
28 29
 import transport "google.golang.org/grpc/transport"
29 30
 import rafttime "time"
... ...
@@ -1602,12 +1603,12 @@ func NewRaftProxyDispatcherServer(local DispatcherServer, connSelector raftselec
1602 1602
 	redirectChecker := func(ctx context.Context) (context.Context, error) {
1603 1603
 		s, ok := transport.StreamFromContext(ctx)
1604 1604
 		if !ok {
1605
-			return ctx, grpc.Errorf(codes.InvalidArgument, "remote addr is not found in context")
1605
+			return ctx, status.Errorf(codes.InvalidArgument, "remote addr is not found in context")
1606 1606
 		}
1607 1607
 		addr := s.ServerTransport().RemoteAddr().String()
1608 1608
 		md, ok := metadata.FromContext(ctx)
1609 1609
 		if ok && len(md["redirect"]) != 0 {
1610
-			return ctx, grpc.Errorf(codes.ResourceExhausted, "more than one redirect to leader from: %s", md["redirect"])
1610
+			return ctx, status.Errorf(codes.ResourceExhausted, "more than one redirect to leader from: %s", md["redirect"])
1611 1611
 		}
1612 1612
 		if !ok {
1613 1613
 			md = metadata.New(map[string]string{})
... ...
@@ -17,6 +17,7 @@ import (
17 17
 
18 18
 import raftselector "github.com/docker/swarmkit/manager/raftselector"
19 19
 import codes "google.golang.org/grpc/codes"
20
+import status "google.golang.org/grpc/status"
20 21
 import metadata "google.golang.org/grpc/metadata"
21 22
 import transport "google.golang.org/grpc/transport"
22 23
 import rafttime "time"
... ...
@@ -286,12 +287,12 @@ func NewRaftProxyHealthServer(local HealthServer, connSelector raftselector.Conn
286 286
 	redirectChecker := func(ctx context.Context) (context.Context, error) {
287 287
 		s, ok := transport.StreamFromContext(ctx)
288 288
 		if !ok {
289
-			return ctx, grpc.Errorf(codes.InvalidArgument, "remote addr is not found in context")
289
+			return ctx, status.Errorf(codes.InvalidArgument, "remote addr is not found in context")
290 290
 		}
291 291
 		addr := s.ServerTransport().RemoteAddr().String()
292 292
 		md, ok := metadata.FromContext(ctx)
293 293
 		if ok && len(md["redirect"]) != 0 {
294
-			return ctx, grpc.Errorf(codes.ResourceExhausted, "more than one redirect to leader from: %s", md["redirect"])
294
+			return ctx, status.Errorf(codes.ResourceExhausted, "more than one redirect to leader from: %s", md["redirect"])
295 295
 		}
296 296
 		if !ok {
297 297
 			md = metadata.New(map[string]string{})
... ...
@@ -20,6 +20,7 @@ import (
20 20
 
21 21
 import raftselector "github.com/docker/swarmkit/manager/raftselector"
22 22
 import codes "google.golang.org/grpc/codes"
23
+import status "google.golang.org/grpc/status"
23 24
 import metadata "google.golang.org/grpc/metadata"
24 25
 import transport "google.golang.org/grpc/transport"
25 26
 import rafttime "time"
... ...
@@ -1273,12 +1274,12 @@ func NewRaftProxyLogsServer(local LogsServer, connSelector raftselector.ConnProv
1273 1273
 	redirectChecker := func(ctx context.Context) (context.Context, error) {
1274 1274
 		s, ok := transport.StreamFromContext(ctx)
1275 1275
 		if !ok {
1276
-			return ctx, grpc.Errorf(codes.InvalidArgument, "remote addr is not found in context")
1276
+			return ctx, status.Errorf(codes.InvalidArgument, "remote addr is not found in context")
1277 1277
 		}
1278 1278
 		addr := s.ServerTransport().RemoteAddr().String()
1279 1279
 		md, ok := metadata.FromContext(ctx)
1280 1280
 		if ok && len(md["redirect"]) != 0 {
1281
-			return ctx, grpc.Errorf(codes.ResourceExhausted, "more than one redirect to leader from: %s", md["redirect"])
1281
+			return ctx, status.Errorf(codes.ResourceExhausted, "more than one redirect to leader from: %s", md["redirect"])
1282 1282
 		}
1283 1283
 		if !ok {
1284 1284
 			md = metadata.New(map[string]string{})
... ...
@@ -1396,12 +1397,12 @@ func NewRaftProxyLogBrokerServer(local LogBrokerServer, connSelector raftselecto
1396 1396
 	redirectChecker := func(ctx context.Context) (context.Context, error) {
1397 1397
 		s, ok := transport.StreamFromContext(ctx)
1398 1398
 		if !ok {
1399
-			return ctx, grpc.Errorf(codes.InvalidArgument, "remote addr is not found in context")
1399
+			return ctx, status.Errorf(codes.InvalidArgument, "remote addr is not found in context")
1400 1400
 		}
1401 1401
 		addr := s.ServerTransport().RemoteAddr().String()
1402 1402
 		md, ok := metadata.FromContext(ctx)
1403 1403
 		if ok && len(md["redirect"]) != 0 {
1404
-			return ctx, grpc.Errorf(codes.ResourceExhausted, "more than one redirect to leader from: %s", md["redirect"])
1404
+			return ctx, status.Errorf(codes.ResourceExhausted, "more than one redirect to leader from: %s", md["redirect"])
1405 1405
 		}
1406 1406
 		if !ok {
1407 1407
 			md = metadata.New(map[string]string{})
... ...
@@ -21,6 +21,7 @@ import (
21 21
 
22 22
 import raftselector "github.com/docker/swarmkit/manager/raftselector"
23 23
 import codes "google.golang.org/grpc/codes"
24
+import status "google.golang.org/grpc/status"
24 25
 import metadata "google.golang.org/grpc/metadata"
25 26
 import transport "google.golang.org/grpc/transport"
26 27
 import rafttime "time"
... ...
@@ -133,6 +134,23 @@ func (m *ProcessRaftMessageResponse) Reset()                    { *m = ProcessRa
133 133
 func (*ProcessRaftMessageResponse) ProtoMessage()               {}
134 134
 func (*ProcessRaftMessageResponse) Descriptor() ([]byte, []int) { return fileDescriptorRaft, []int{6} }
135 135
 
136
+// Raft message streaming request.
137
+type StreamRaftMessageRequest struct {
138
+	Message *raftpb.Message `protobuf:"bytes,1,opt,name=message" json:"message,omitempty"`
139
+}
140
+
141
+func (m *StreamRaftMessageRequest) Reset()                    { *m = StreamRaftMessageRequest{} }
142
+func (*StreamRaftMessageRequest) ProtoMessage()               {}
143
+func (*StreamRaftMessageRequest) Descriptor() ([]byte, []int) { return fileDescriptorRaft, []int{7} }
144
+
145
+// Raft message streaming response.
146
+type StreamRaftMessageResponse struct {
147
+}
148
+
149
+func (m *StreamRaftMessageResponse) Reset()                    { *m = StreamRaftMessageResponse{} }
150
+func (*StreamRaftMessageResponse) ProtoMessage()               {}
151
+func (*StreamRaftMessageResponse) Descriptor() ([]byte, []int) { return fileDescriptorRaft, []int{8} }
152
+
136 153
 type ResolveAddressRequest struct {
137 154
 	// raft_id is the ID to resolve to an address.
138 155
 	RaftID uint64 `protobuf:"varint,1,opt,name=raft_id,json=raftId,proto3" json:"raft_id,omitempty"`
... ...
@@ -140,7 +158,7 @@ type ResolveAddressRequest struct {
140 140
 
141 141
 func (m *ResolveAddressRequest) Reset()                    { *m = ResolveAddressRequest{} }
142 142
 func (*ResolveAddressRequest) ProtoMessage()               {}
143
-func (*ResolveAddressRequest) Descriptor() ([]byte, []int) { return fileDescriptorRaft, []int{7} }
143
+func (*ResolveAddressRequest) Descriptor() ([]byte, []int) { return fileDescriptorRaft, []int{9} }
144 144
 
145 145
 type ResolveAddressResponse struct {
146 146
 	// Addr specifies the address of the member
... ...
@@ -149,7 +167,7 @@ type ResolveAddressResponse struct {
149 149
 
150 150
 func (m *ResolveAddressResponse) Reset()                    { *m = ResolveAddressResponse{} }
151 151
 func (*ResolveAddressResponse) ProtoMessage()               {}
152
-func (*ResolveAddressResponse) Descriptor() ([]byte, []int) { return fileDescriptorRaft, []int{8} }
152
+func (*ResolveAddressResponse) Descriptor() ([]byte, []int) { return fileDescriptorRaft, []int{10} }
153 153
 
154 154
 // Contains one of many protobuf encoded objects to replicate
155 155
 // over the raft backend with a request ID to track when the
... ...
@@ -161,7 +179,7 @@ type InternalRaftRequest struct {
161 161
 
162 162
 func (m *InternalRaftRequest) Reset()                    { *m = InternalRaftRequest{} }
163 163
 func (*InternalRaftRequest) ProtoMessage()               {}
164
-func (*InternalRaftRequest) Descriptor() ([]byte, []int) { return fileDescriptorRaft, []int{9} }
164
+func (*InternalRaftRequest) Descriptor() ([]byte, []int) { return fileDescriptorRaft, []int{11} }
165 165
 
166 166
 // StoreAction defines a target and operation to apply on the storage system.
167 167
 type StoreAction struct {
... ...
@@ -181,7 +199,7 @@ type StoreAction struct {
181 181
 
182 182
 func (m *StoreAction) Reset()                    { *m = StoreAction{} }
183 183
 func (*StoreAction) ProtoMessage()               {}
184
-func (*StoreAction) Descriptor() ([]byte, []int) { return fileDescriptorRaft, []int{10} }
184
+func (*StoreAction) Descriptor() ([]byte, []int) { return fileDescriptorRaft, []int{12} }
185 185
 
186 186
 type isStoreAction_Target interface {
187 187
 	isStoreAction_Target()
... ...
@@ -512,6 +530,8 @@ func init() {
512 512
 	proto.RegisterType((*LeaveResponse)(nil), "docker.swarmkit.v1.LeaveResponse")
513 513
 	proto.RegisterType((*ProcessRaftMessageRequest)(nil), "docker.swarmkit.v1.ProcessRaftMessageRequest")
514 514
 	proto.RegisterType((*ProcessRaftMessageResponse)(nil), "docker.swarmkit.v1.ProcessRaftMessageResponse")
515
+	proto.RegisterType((*StreamRaftMessageRequest)(nil), "docker.swarmkit.v1.StreamRaftMessageRequest")
516
+	proto.RegisterType((*StreamRaftMessageResponse)(nil), "docker.swarmkit.v1.StreamRaftMessageResponse")
515 517
 	proto.RegisterType((*ResolveAddressRequest)(nil), "docker.swarmkit.v1.ResolveAddressRequest")
516 518
 	proto.RegisterType((*ResolveAddressResponse)(nil), "docker.swarmkit.v1.ResolveAddressResponse")
517 519
 	proto.RegisterType((*InternalRaftRequest)(nil), "docker.swarmkit.v1.InternalRaftRequest")
... ...
@@ -539,6 +559,14 @@ func (p *authenticatedWrapperRaftServer) ProcessRaftMessage(ctx context.Context,
539 539
 	return p.local.ProcessRaftMessage(ctx, r)
540 540
 }
541 541
 
542
+func (p *authenticatedWrapperRaftServer) StreamRaftMessage(stream Raft_StreamRaftMessageServer) error {
543
+
544
+	if err := p.authorize(stream.Context(), []string{"swarm-manager"}); err != nil {
545
+		return err
546
+	}
547
+	return p.local.StreamRaftMessage(stream)
548
+}
549
+
542 550
 func (p *authenticatedWrapperRaftServer) ResolveAddress(ctx context.Context, r *ResolveAddressRequest) (*ResolveAddressResponse, error) {
543 551
 
544 552
 	if err := p.authorize(ctx, []string{"swarm-manager"}); err != nil {
... ...
@@ -673,6 +701,16 @@ func (m *ProcessRaftMessageResponse) Copy() *ProcessRaftMessageResponse {
673 673
 }
674 674
 
675 675
 func (m *ProcessRaftMessageResponse) CopyFrom(src interface{}) {}
676
+func (m *StreamRaftMessageResponse) Copy() *StreamRaftMessageResponse {
677
+	if m == nil {
678
+		return nil
679
+	}
680
+	o := &StreamRaftMessageResponse{}
681
+	o.CopyFrom(m)
682
+	return o
683
+}
684
+
685
+func (m *StreamRaftMessageResponse) CopyFrom(src interface{}) {}
676 686
 func (m *ResolveAddressRequest) Copy() *ResolveAddressRequest {
677 687
 	if m == nil {
678 688
 		return nil
... ...
@@ -813,6 +851,12 @@ type RaftClient interface {
813 813
 	// ProcessRaftMessage sends a raft message to be processed on a raft member, it is
814 814
 	// called from the RaftMember willing to send a message to its destination ('To' field)
815 815
 	ProcessRaftMessage(ctx context.Context, in *ProcessRaftMessageRequest, opts ...grpc.CallOption) (*ProcessRaftMessageResponse, error)
816
+	// StreamRaftMessage accepts a stream of raft messages of type StreamRaftMessageRequest
817
+	// to be processed on a raft member, returning a StreamRaftMessageResponse
818
+	// when processing of the streamed messages is complete. A single stream corresponds
819
+	// to a single raft message, which may be disassembled and streamed as individual messages.
820
+	// It is called from the Raft leader, which uses it to stream messages to a raft member.
821
+	StreamRaftMessage(ctx context.Context, opts ...grpc.CallOption) (Raft_StreamRaftMessageClient, error)
816 822
 	// ResolveAddress returns the address where the node with the given ID can be reached.
817 823
 	ResolveAddress(ctx context.Context, in *ResolveAddressRequest, opts ...grpc.CallOption) (*ResolveAddressResponse, error)
818 824
 }
... ...
@@ -834,6 +878,40 @@ func (c *raftClient) ProcessRaftMessage(ctx context.Context, in *ProcessRaftMess
834 834
 	return out, nil
835 835
 }
836 836
 
837
+func (c *raftClient) StreamRaftMessage(ctx context.Context, opts ...grpc.CallOption) (Raft_StreamRaftMessageClient, error) {
838
+	stream, err := grpc.NewClientStream(ctx, &_Raft_serviceDesc.Streams[0], c.cc, "/docker.swarmkit.v1.Raft/StreamRaftMessage", opts...)
839
+	if err != nil {
840
+		return nil, err
841
+	}
842
+	x := &raftStreamRaftMessageClient{stream}
843
+	return x, nil
844
+}
845
+
846
+type Raft_StreamRaftMessageClient interface {
847
+	Send(*StreamRaftMessageRequest) error
848
+	CloseAndRecv() (*StreamRaftMessageResponse, error)
849
+	grpc.ClientStream
850
+}
851
+
852
+type raftStreamRaftMessageClient struct {
853
+	grpc.ClientStream
854
+}
855
+
856
+func (x *raftStreamRaftMessageClient) Send(m *StreamRaftMessageRequest) error {
857
+	return x.ClientStream.SendMsg(m)
858
+}
859
+
860
+func (x *raftStreamRaftMessageClient) CloseAndRecv() (*StreamRaftMessageResponse, error) {
861
+	if err := x.ClientStream.CloseSend(); err != nil {
862
+		return nil, err
863
+	}
864
+	m := new(StreamRaftMessageResponse)
865
+	if err := x.ClientStream.RecvMsg(m); err != nil {
866
+		return nil, err
867
+	}
868
+	return m, nil
869
+}
870
+
837 871
 func (c *raftClient) ResolveAddress(ctx context.Context, in *ResolveAddressRequest, opts ...grpc.CallOption) (*ResolveAddressResponse, error) {
838 872
 	out := new(ResolveAddressResponse)
839 873
 	err := grpc.Invoke(ctx, "/docker.swarmkit.v1.Raft/ResolveAddress", in, out, c.cc, opts...)
... ...
@@ -849,6 +927,12 @@ type RaftServer interface {
849 849
 	// ProcessRaftMessage sends a raft message to be processed on a raft member, it is
850 850
 	// called from the RaftMember willing to send a message to its destination ('To' field)
851 851
 	ProcessRaftMessage(context.Context, *ProcessRaftMessageRequest) (*ProcessRaftMessageResponse, error)
852
+	// StreamRaftMessage accepts a stream of raft messages of type StreamRaftMessageRequest
853
+	// to be processed on a raft member, returning a StreamRaftMessageResponse
854
+	// when processing of the streamed messages is complete. A single stream corresponds
855
+	// to a single raft message, which may be disassembled and streamed as individual messages.
856
+	// It is called from the Raft leader, which uses it to stream messages to a raft member.
857
+	StreamRaftMessage(Raft_StreamRaftMessageServer) error
852 858
 	// ResolveAddress returns the address where the node with the given ID can be reached.
853 859
 	ResolveAddress(context.Context, *ResolveAddressRequest) (*ResolveAddressResponse, error)
854 860
 }
... ...
@@ -875,6 +959,32 @@ func _Raft_ProcessRaftMessage_Handler(srv interface{}, ctx context.Context, dec
875 875
 	return interceptor(ctx, in, info, handler)
876 876
 }
877 877
 
878
+func _Raft_StreamRaftMessage_Handler(srv interface{}, stream grpc.ServerStream) error {
879
+	return srv.(RaftServer).StreamRaftMessage(&raftStreamRaftMessageServer{stream})
880
+}
881
+
882
+type Raft_StreamRaftMessageServer interface {
883
+	SendAndClose(*StreamRaftMessageResponse) error
884
+	Recv() (*StreamRaftMessageRequest, error)
885
+	grpc.ServerStream
886
+}
887
+
888
+type raftStreamRaftMessageServer struct {
889
+	grpc.ServerStream
890
+}
891
+
892
+func (x *raftStreamRaftMessageServer) SendAndClose(m *StreamRaftMessageResponse) error {
893
+	return x.ServerStream.SendMsg(m)
894
+}
895
+
896
+func (x *raftStreamRaftMessageServer) Recv() (*StreamRaftMessageRequest, error) {
897
+	m := new(StreamRaftMessageRequest)
898
+	if err := x.ServerStream.RecvMsg(m); err != nil {
899
+		return nil, err
900
+	}
901
+	return m, nil
902
+}
903
+
878 904
 func _Raft_ResolveAddress_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
879 905
 	in := new(ResolveAddressRequest)
880 906
 	if err := dec(in); err != nil {
... ...
@@ -906,7 +1016,13 @@ var _Raft_serviceDesc = grpc.ServiceDesc{
906 906
 			Handler:    _Raft_ResolveAddress_Handler,
907 907
 		},
908 908
 	},
909
-	Streams:  []grpc.StreamDesc{},
909
+	Streams: []grpc.StreamDesc{
910
+		{
911
+			StreamName:    "StreamRaftMessage",
912
+			Handler:       _Raft_StreamRaftMessage_Handler,
913
+			ClientStreams: true,
914
+		},
915
+	},
910 916
 	Metadata: "github.com/docker/swarmkit/api/raft.proto",
911 917
 }
912 918
 
... ...
@@ -1212,6 +1328,52 @@ func (m *ProcessRaftMessageResponse) MarshalTo(dAtA []byte) (int, error) {
1212 1212
 	return i, nil
1213 1213
 }
1214 1214
 
1215
+func (m *StreamRaftMessageRequest) Marshal() (dAtA []byte, err error) {
1216
+	size := m.Size()
1217
+	dAtA = make([]byte, size)
1218
+	n, err := m.MarshalTo(dAtA)
1219
+	if err != nil {
1220
+		return nil, err
1221
+	}
1222
+	return dAtA[:n], nil
1223
+}
1224
+
1225
+func (m *StreamRaftMessageRequest) MarshalTo(dAtA []byte) (int, error) {
1226
+	var i int
1227
+	_ = i
1228
+	var l int
1229
+	_ = l
1230
+	if m.Message != nil {
1231
+		dAtA[i] = 0xa
1232
+		i++
1233
+		i = encodeVarintRaft(dAtA, i, uint64(m.Message.Size()))
1234
+		n4, err := m.Message.MarshalTo(dAtA[i:])
1235
+		if err != nil {
1236
+			return 0, err
1237
+		}
1238
+		i += n4
1239
+	}
1240
+	return i, nil
1241
+}
1242
+
1243
+func (m *StreamRaftMessageResponse) Marshal() (dAtA []byte, err error) {
1244
+	size := m.Size()
1245
+	dAtA = make([]byte, size)
1246
+	n, err := m.MarshalTo(dAtA)
1247
+	if err != nil {
1248
+		return nil, err
1249
+	}
1250
+	return dAtA[:n], nil
1251
+}
1252
+
1253
+func (m *StreamRaftMessageResponse) MarshalTo(dAtA []byte) (int, error) {
1254
+	var i int
1255
+	_ = i
1256
+	var l int
1257
+	_ = l
1258
+	return i, nil
1259
+}
1260
+
1215 1261
 func (m *ResolveAddressRequest) Marshal() (dAtA []byte, err error) {
1216 1262
 	size := m.Size()
1217 1263
 	dAtA = make([]byte, size)
... ...
@@ -1315,11 +1477,11 @@ func (m *StoreAction) MarshalTo(dAtA []byte) (int, error) {
1315 1315
 		i = encodeVarintRaft(dAtA, i, uint64(m.Action))
1316 1316
 	}
1317 1317
 	if m.Target != nil {
1318
-		nn4, err := m.Target.MarshalTo(dAtA[i:])
1318
+		nn5, err := m.Target.MarshalTo(dAtA[i:])
1319 1319
 		if err != nil {
1320 1320
 			return 0, err
1321 1321
 		}
1322
-		i += nn4
1322
+		i += nn5
1323 1323
 	}
1324 1324
 	return i, nil
1325 1325
 }
... ...
@@ -1330,11 +1492,11 @@ func (m *StoreAction_Node) MarshalTo(dAtA []byte) (int, error) {
1330 1330
 		dAtA[i] = 0x12
1331 1331
 		i++
1332 1332
 		i = encodeVarintRaft(dAtA, i, uint64(m.Node.Size()))
1333
-		n5, err := m.Node.MarshalTo(dAtA[i:])
1333
+		n6, err := m.Node.MarshalTo(dAtA[i:])
1334 1334
 		if err != nil {
1335 1335
 			return 0, err
1336 1336
 		}
1337
-		i += n5
1337
+		i += n6
1338 1338
 	}
1339 1339
 	return i, nil
1340 1340
 }
... ...
@@ -1344,11 +1506,11 @@ func (m *StoreAction_Service) MarshalTo(dAtA []byte) (int, error) {
1344 1344
 		dAtA[i] = 0x1a
1345 1345
 		i++
1346 1346
 		i = encodeVarintRaft(dAtA, i, uint64(m.Service.Size()))
1347
-		n6, err := m.Service.MarshalTo(dAtA[i:])
1347
+		n7, err := m.Service.MarshalTo(dAtA[i:])
1348 1348
 		if err != nil {
1349 1349
 			return 0, err
1350 1350
 		}
1351
-		i += n6
1351
+		i += n7
1352 1352
 	}
1353 1353
 	return i, nil
1354 1354
 }
... ...
@@ -1358,11 +1520,11 @@ func (m *StoreAction_Task) MarshalTo(dAtA []byte) (int, error) {
1358 1358
 		dAtA[i] = 0x22
1359 1359
 		i++
1360 1360
 		i = encodeVarintRaft(dAtA, i, uint64(m.Task.Size()))
1361
-		n7, err := m.Task.MarshalTo(dAtA[i:])
1361
+		n8, err := m.Task.MarshalTo(dAtA[i:])
1362 1362
 		if err != nil {
1363 1363
 			return 0, err
1364 1364
 		}
1365
-		i += n7
1365
+		i += n8
1366 1366
 	}
1367 1367
 	return i, nil
1368 1368
 }
... ...
@@ -1372,11 +1534,11 @@ func (m *StoreAction_Network) MarshalTo(dAtA []byte) (int, error) {
1372 1372
 		dAtA[i] = 0x2a
1373 1373
 		i++
1374 1374
 		i = encodeVarintRaft(dAtA, i, uint64(m.Network.Size()))
1375
-		n8, err := m.Network.MarshalTo(dAtA[i:])
1375
+		n9, err := m.Network.MarshalTo(dAtA[i:])
1376 1376
 		if err != nil {
1377 1377
 			return 0, err
1378 1378
 		}
1379
-		i += n8
1379
+		i += n9
1380 1380
 	}
1381 1381
 	return i, nil
1382 1382
 }
... ...
@@ -1386,11 +1548,11 @@ func (m *StoreAction_Cluster) MarshalTo(dAtA []byte) (int, error) {
1386 1386
 		dAtA[i] = 0x32
1387 1387
 		i++
1388 1388
 		i = encodeVarintRaft(dAtA, i, uint64(m.Cluster.Size()))
1389
-		n9, err := m.Cluster.MarshalTo(dAtA[i:])
1389
+		n10, err := m.Cluster.MarshalTo(dAtA[i:])
1390 1390
 		if err != nil {
1391 1391
 			return 0, err
1392 1392
 		}
1393
-		i += n9
1393
+		i += n10
1394 1394
 	}
1395 1395
 	return i, nil
1396 1396
 }
... ...
@@ -1400,11 +1562,11 @@ func (m *StoreAction_Secret) MarshalTo(dAtA []byte) (int, error) {
1400 1400
 		dAtA[i] = 0x3a
1401 1401
 		i++
1402 1402
 		i = encodeVarintRaft(dAtA, i, uint64(m.Secret.Size()))
1403
-		n10, err := m.Secret.MarshalTo(dAtA[i:])
1403
+		n11, err := m.Secret.MarshalTo(dAtA[i:])
1404 1404
 		if err != nil {
1405 1405
 			return 0, err
1406 1406
 		}
1407
-		i += n10
1407
+		i += n11
1408 1408
 	}
1409 1409
 	return i, nil
1410 1410
 }
... ...
@@ -1414,11 +1576,11 @@ func (m *StoreAction_Resource) MarshalTo(dAtA []byte) (int, error) {
1414 1414
 		dAtA[i] = 0x42
1415 1415
 		i++
1416 1416
 		i = encodeVarintRaft(dAtA, i, uint64(m.Resource.Size()))
1417
-		n11, err := m.Resource.MarshalTo(dAtA[i:])
1417
+		n12, err := m.Resource.MarshalTo(dAtA[i:])
1418 1418
 		if err != nil {
1419 1419
 			return 0, err
1420 1420
 		}
1421
-		i += n11
1421
+		i += n12
1422 1422
 	}
1423 1423
 	return i, nil
1424 1424
 }
... ...
@@ -1428,11 +1590,11 @@ func (m *StoreAction_Extension) MarshalTo(dAtA []byte) (int, error) {
1428 1428
 		dAtA[i] = 0x4a
1429 1429
 		i++
1430 1430
 		i = encodeVarintRaft(dAtA, i, uint64(m.Extension.Size()))
1431
-		n12, err := m.Extension.MarshalTo(dAtA[i:])
1431
+		n13, err := m.Extension.MarshalTo(dAtA[i:])
1432 1432
 		if err != nil {
1433 1433
 			return 0, err
1434 1434
 		}
1435
-		i += n12
1435
+		i += n13
1436 1436
 	}
1437 1437
 	return i, nil
1438 1438
 }
... ...
@@ -1442,11 +1604,11 @@ func (m *StoreAction_Config) MarshalTo(dAtA []byte) (int, error) {
1442 1442
 		dAtA[i] = 0x52
1443 1443
 		i++
1444 1444
 		i = encodeVarintRaft(dAtA, i, uint64(m.Config.Size()))
1445
-		n13, err := m.Config.MarshalTo(dAtA[i:])
1445
+		n14, err := m.Config.MarshalTo(dAtA[i:])
1446 1446
 		if err != nil {
1447 1447
 			return 0, err
1448 1448
 		}
1449
-		i += n13
1449
+		i += n14
1450 1450
 	}
1451 1451
 	return i, nil
1452 1452
 }
... ...
@@ -1488,12 +1650,12 @@ func NewRaftProxyRaftServer(local RaftServer, connSelector raftselector.ConnProv
1488 1488
 	redirectChecker := func(ctx context.Context) (context.Context, error) {
1489 1489
 		s, ok := transport.StreamFromContext(ctx)
1490 1490
 		if !ok {
1491
-			return ctx, grpc.Errorf(codes.InvalidArgument, "remote addr is not found in context")
1491
+			return ctx, status.Errorf(codes.InvalidArgument, "remote addr is not found in context")
1492 1492
 		}
1493 1493
 		addr := s.ServerTransport().RemoteAddr().String()
1494 1494
 		md, ok := metadata.FromContext(ctx)
1495 1495
 		if ok && len(md["redirect"]) != 0 {
1496
-			return ctx, grpc.Errorf(codes.ResourceExhausted, "more than one redirect to leader from: %s", md["redirect"])
1496
+			return ctx, status.Errorf(codes.ResourceExhausted, "more than one redirect to leader from: %s", md["redirect"])
1497 1497
 		}
1498 1498
 		if !ok {
1499 1499
 			md = metadata.New(map[string]string{})
... ...
@@ -1585,6 +1747,63 @@ func (p *raftProxyRaftServer) ProcessRaftMessage(ctx context.Context, r *Process
1585 1585
 	return resp, err
1586 1586
 }
1587 1587
 
1588
+type Raft_StreamRaftMessageServerWrapper struct {
1589
+	Raft_StreamRaftMessageServer
1590
+	ctx context.Context
1591
+}
1592
+
1593
+func (s Raft_StreamRaftMessageServerWrapper) Context() context.Context {
1594
+	return s.ctx
1595
+}
1596
+
1597
+func (p *raftProxyRaftServer) StreamRaftMessage(stream Raft_StreamRaftMessageServer) error {
1598
+	ctx := stream.Context()
1599
+	conn, err := p.connSelector.LeaderConn(ctx)
1600
+	if err != nil {
1601
+		if err == raftselector.ErrIsLeader {
1602
+			ctx, err = p.runCtxMods(ctx, p.localCtxMods)
1603
+			if err != nil {
1604
+				return err
1605
+			}
1606
+			streamWrapper := Raft_StreamRaftMessageServerWrapper{
1607
+				Raft_StreamRaftMessageServer: stream,
1608
+				ctx: ctx,
1609
+			}
1610
+			return p.local.StreamRaftMessage(streamWrapper)
1611
+		}
1612
+		return err
1613
+	}
1614
+	ctx, err = p.runCtxMods(ctx, p.remoteCtxMods)
1615
+	if err != nil {
1616
+		return err
1617
+	}
1618
+	clientStream, err := NewRaftClient(conn).StreamRaftMessage(ctx)
1619
+
1620
+	if err != nil {
1621
+		return err
1622
+	}
1623
+
1624
+	for {
1625
+		msg, err := stream.Recv()
1626
+		if err == io.EOF {
1627
+			break
1628
+		}
1629
+		if err != nil {
1630
+			return err
1631
+		}
1632
+		if err := clientStream.Send(msg); err != nil {
1633
+			return err
1634
+		}
1635
+	}
1636
+
1637
+	reply, err := clientStream.CloseAndRecv()
1638
+	if err != nil {
1639
+		return err
1640
+	}
1641
+
1642
+	return stream.SendAndClose(reply)
1643
+}
1644
+
1588 1645
 func (p *raftProxyRaftServer) ResolveAddress(ctx context.Context, r *ResolveAddressRequest) (*ResolveAddressResponse, error) {
1589 1646
 
1590 1647
 	conn, err := p.connSelector.LeaderConn(ctx)
... ...
@@ -1630,12 +1849,12 @@ func NewRaftProxyRaftMembershipServer(local RaftMembershipServer, connSelector r
1630 1630
 	redirectChecker := func(ctx context.Context) (context.Context, error) {
1631 1631
 		s, ok := transport.StreamFromContext(ctx)
1632 1632
 		if !ok {
1633
-			return ctx, grpc.Errorf(codes.InvalidArgument, "remote addr is not found in context")
1633
+			return ctx, status.Errorf(codes.InvalidArgument, "remote addr is not found in context")
1634 1634
 		}
1635 1635
 		addr := s.ServerTransport().RemoteAddr().String()
1636 1636
 		md, ok := metadata.FromContext(ctx)
1637 1637
 		if ok && len(md["redirect"]) != 0 {
1638
-			return ctx, grpc.Errorf(codes.ResourceExhausted, "more than one redirect to leader from: %s", md["redirect"])
1638
+			return ctx, status.Errorf(codes.ResourceExhausted, "more than one redirect to leader from: %s", md["redirect"])
1639 1639
 		}
1640 1640
 		if !ok {
1641 1641
 			md = metadata.New(map[string]string{})
... ...
@@ -1843,6 +2062,22 @@ func (m *ProcessRaftMessageResponse) Size() (n int) {
1843 1843
 	return n
1844 1844
 }
1845 1845
 
1846
+func (m *StreamRaftMessageRequest) Size() (n int) {
1847
+	var l int
1848
+	_ = l
1849
+	if m.Message != nil {
1850
+		l = m.Message.Size()
1851
+		n += 1 + l + sovRaft(uint64(l))
1852
+	}
1853
+	return n
1854
+}
1855
+
1856
+func (m *StreamRaftMessageResponse) Size() (n int) {
1857
+	var l int
1858
+	_ = l
1859
+	return n
1860
+}
1861
+
1846 1862
 func (m *ResolveAddressRequest) Size() (n int) {
1847 1863
 	var l int
1848 1864
 	_ = l
... ...
@@ -2057,6 +2292,25 @@ func (this *ProcessRaftMessageResponse) String() string {
2057 2057
 	}, "")
2058 2058
 	return s
2059 2059
 }
2060
+func (this *StreamRaftMessageRequest) String() string {
2061
+	if this == nil {
2062
+		return "nil"
2063
+	}
2064
+	s := strings.Join([]string{`&StreamRaftMessageRequest{`,
2065
+		`Message:` + strings.Replace(fmt.Sprintf("%v", this.Message), "Message", "raftpb.Message", 1) + `,`,
2066
+		`}`,
2067
+	}, "")
2068
+	return s
2069
+}
2070
+func (this *StreamRaftMessageResponse) String() string {
2071
+	if this == nil {
2072
+		return "nil"
2073
+	}
2074
+	s := strings.Join([]string{`&StreamRaftMessageResponse{`,
2075
+		`}`,
2076
+	}, "")
2077
+	return s
2078
+}
2060 2079
 func (this *ResolveAddressRequest) String() string {
2061 2080
 	if this == nil {
2062 2081
 		return "nil"
... ...
@@ -2861,6 +3115,139 @@ func (m *ProcessRaftMessageResponse) Unmarshal(dAtA []byte) error {
2861 2861
 	}
2862 2862
 	return nil
2863 2863
 }
2864
+func (m *StreamRaftMessageRequest) Unmarshal(dAtA []byte) error {
2865
+	l := len(dAtA)
2866
+	iNdEx := 0
2867
+	for iNdEx < l {
2868
+		preIndex := iNdEx
2869
+		var wire uint64
2870
+		for shift := uint(0); ; shift += 7 {
2871
+			if shift >= 64 {
2872
+				return ErrIntOverflowRaft
2873
+			}
2874
+			if iNdEx >= l {
2875
+				return io.ErrUnexpectedEOF
2876
+			}
2877
+			b := dAtA[iNdEx]
2878
+			iNdEx++
2879
+			wire |= (uint64(b) & 0x7F) << shift
2880
+			if b < 0x80 {
2881
+				break
2882
+			}
2883
+		}
2884
+		fieldNum := int32(wire >> 3)
2885
+		wireType := int(wire & 0x7)
2886
+		if wireType == 4 {
2887
+			return fmt.Errorf("proto: StreamRaftMessageRequest: wiretype end group for non-group")
2888
+		}
2889
+		if fieldNum <= 0 {
2890
+			return fmt.Errorf("proto: StreamRaftMessageRequest: illegal tag %d (wire type %d)", fieldNum, wire)
2891
+		}
2892
+		switch fieldNum {
2893
+		case 1:
2894
+			if wireType != 2 {
2895
+				return fmt.Errorf("proto: wrong wireType = %d for field Message", wireType)
2896
+			}
2897
+			var msglen int
2898
+			for shift := uint(0); ; shift += 7 {
2899
+				if shift >= 64 {
2900
+					return ErrIntOverflowRaft
2901
+				}
2902
+				if iNdEx >= l {
2903
+					return io.ErrUnexpectedEOF
2904
+				}
2905
+				b := dAtA[iNdEx]
2906
+				iNdEx++
2907
+				msglen |= (int(b) & 0x7F) << shift
2908
+				if b < 0x80 {
2909
+					break
2910
+				}
2911
+			}
2912
+			if msglen < 0 {
2913
+				return ErrInvalidLengthRaft
2914
+			}
2915
+			postIndex := iNdEx + msglen
2916
+			if postIndex > l {
2917
+				return io.ErrUnexpectedEOF
2918
+			}
2919
+			if m.Message == nil {
2920
+				m.Message = &raftpb.Message{}
2921
+			}
2922
+			if err := m.Message.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
2923
+				return err
2924
+			}
2925
+			iNdEx = postIndex
2926
+		default:
2927
+			iNdEx = preIndex
2928
+			skippy, err := skipRaft(dAtA[iNdEx:])
2929
+			if err != nil {
2930
+				return err
2931
+			}
2932
+			if skippy < 0 {
2933
+				return ErrInvalidLengthRaft
2934
+			}
2935
+			if (iNdEx + skippy) > l {
2936
+				return io.ErrUnexpectedEOF
2937
+			}
2938
+			iNdEx += skippy
2939
+		}
2940
+	}
2941
+
2942
+	if iNdEx > l {
2943
+		return io.ErrUnexpectedEOF
2944
+	}
2945
+	return nil
2946
+}
2947
+func (m *StreamRaftMessageResponse) Unmarshal(dAtA []byte) error {
2948
+	l := len(dAtA)
2949
+	iNdEx := 0
2950
+	for iNdEx < l {
2951
+		preIndex := iNdEx
2952
+		var wire uint64
2953
+		for shift := uint(0); ; shift += 7 {
2954
+			if shift >= 64 {
2955
+				return ErrIntOverflowRaft
2956
+			}
2957
+			if iNdEx >= l {
2958
+				return io.ErrUnexpectedEOF
2959
+			}
2960
+			b := dAtA[iNdEx]
2961
+			iNdEx++
2962
+			wire |= (uint64(b) & 0x7F) << shift
2963
+			if b < 0x80 {
2964
+				break
2965
+			}
2966
+		}
2967
+		fieldNum := int32(wire >> 3)
2968
+		wireType := int(wire & 0x7)
2969
+		if wireType == 4 {
2970
+			return fmt.Errorf("proto: StreamRaftMessageResponse: wiretype end group for non-group")
2971
+		}
2972
+		if fieldNum <= 0 {
2973
+			return fmt.Errorf("proto: StreamRaftMessageResponse: illegal tag %d (wire type %d)", fieldNum, wire)
2974
+		}
2975
+		switch fieldNum {
2976
+		default:
2977
+			iNdEx = preIndex
2978
+			skippy, err := skipRaft(dAtA[iNdEx:])
2979
+			if err != nil {
2980
+				return err
2981
+			}
2982
+			if skippy < 0 {
2983
+				return ErrInvalidLengthRaft
2984
+			}
2985
+			if (iNdEx + skippy) > l {
2986
+				return io.ErrUnexpectedEOF
2987
+			}
2988
+			iNdEx += skippy
2989
+		}
2990
+	}
2991
+
2992
+	if iNdEx > l {
2993
+		return io.ErrUnexpectedEOF
2994
+	}
2995
+	return nil
2996
+}
2864 2997
 func (m *ResolveAddressRequest) Unmarshal(dAtA []byte) error {
2865 2998
 	l := len(dAtA)
2866 2999
 	iNdEx := 0
... ...
@@ -3574,66 +3961,69 @@ var (
3574 3574
 func init() { proto.RegisterFile("github.com/docker/swarmkit/api/raft.proto", fileDescriptorRaft) }
3575 3575
 
3576 3576
 var fileDescriptorRaft = []byte{
3577
-	// 974 bytes of a gzipped FileDescriptorProto
3578
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x96, 0x4f, 0x6f, 0x1b, 0x45,
3579
-	0x18, 0xc6, 0x77, 0xd7, 0x5b, 0x27, 0x79, 0xd3, 0x26, 0xd1, 0x94, 0x84, 0xed, 0x52, 0x1c, 0x77,
3580
-	0x8b, 0x84, 0x13, 0x9a, 0xb5, 0x30, 0x48, 0x45, 0x85, 0x1e, 0x62, 0xc7, 0x92, 0x4d, 0x5b, 0xa7,
3581
-	0xda, 0x24, 0xd0, 0x5b, 0x58, 0xef, 0x4e, 0xdc, 0xc5, 0xf6, 0x8e, 0x99, 0x19, 0x3b, 0x70, 0x41,
3582
-	0x3d, 0xa2, 0x5c, 0x39, 0x80, 0x90, 0x7a, 0x82, 0x73, 0x3f, 0x00, 0x1f, 0x00, 0x45, 0x9c, 0xb8,
3583
-	0xc1, 0x29, 0xa2, 0xfe, 0x00, 0xf0, 0x15, 0xd0, 0xcc, 0xee, 0x3a, 0xc6, 0x59, 0x3b, 0xb9, 0x24,
3584
-	0xa3, 0x9d, 0xdf, 0xf3, 0x3e, 0xef, 0x3b, 0x7f, 0xde, 0x31, 0x6c, 0xb4, 0x02, 0xfe, 0xbc, 0xdf,
3585
-	0xb4, 0x3d, 0xd2, 0x2d, 0xfa, 0xc4, 0x6b, 0x63, 0x5a, 0x64, 0xc7, 0x2e, 0xed, 0xb6, 0x03, 0x5e,
3586
-	0x74, 0x7b, 0x41, 0x91, 0xba, 0x47, 0xdc, 0xee, 0x51, 0xc2, 0x09, 0x42, 0xd1, 0xbc, 0x9d, 0xcc,
3587
-	0xdb, 0x83, 0xf7, 0xcd, 0x7b, 0x97, 0xc8, 0x49, 0xf3, 0x4b, 0xec, 0x71, 0x16, 0x45, 0x30, 0x37,
3588
-	0x2f, 0xa1, 0xf9, 0x37, 0x3d, 0x9c, 0xb0, 0x5b, 0x63, 0xac, 0x47, 0x28, 0x26, 0xac, 0x88, 0xb9,
3589
-	0xe7, 0xcb, 0x84, 0xe4, 0x9f, 0x5e, 0x73, 0x2c, 0x39, 0xf3, 0x8d, 0x16, 0x69, 0x11, 0x39, 0x2c,
3590
-	0x8a, 0x51, 0xfc, 0xf5, 0xfe, 0x0c, 0x43, 0x49, 0x34, 0xfb, 0x47, 0xc5, 0x5e, 0xa7, 0xdf, 0x0a,
3591
-	0xc2, 0xf8, 0x5f, 0x24, 0xb4, 0x5e, 0xa9, 0x00, 0x8e, 0x7b, 0xc4, 0x9f, 0xe0, 0x6e, 0x13, 0x53,
3592
-	0x74, 0x17, 0xe6, 0x84, 0xd7, 0x61, 0xe0, 0x1b, 0x6a, 0x5e, 0x2d, 0xe8, 0x65, 0x18, 0x9e, 0xad,
3593
-	0x67, 0x05, 0x50, 0xdf, 0x71, 0xb2, 0x62, 0xaa, 0xee, 0x0b, 0x28, 0x24, 0x3e, 0x16, 0x90, 0x96,
3594
-	0x57, 0x0b, 0x0b, 0x11, 0xd4, 0x20, 0x3e, 0x16, 0x90, 0x98, 0xaa, 0xfb, 0x08, 0x81, 0xee, 0xfa,
3595
-	0x3e, 0x35, 0x32, 0x82, 0x70, 0xe4, 0x18, 0x95, 0x21, 0xcb, 0xb8, 0xcb, 0xfb, 0xcc, 0xd0, 0xf3,
3596
-	0x6a, 0x61, 0xb1, 0xf4, 0x8e, 0x7d, 0x71, 0xa5, 0xed, 0xf3, 0x6c, 0xf6, 0x24, 0x5b, 0xd6, 0x4f,
3597
-	0xcf, 0xd6, 0x15, 0x27, 0x56, 0x5a, 0x77, 0x60, 0xf1, 0x53, 0x12, 0x84, 0x0e, 0xfe, 0xaa, 0x8f,
3598
-	0x19, 0x1f, 0xd9, 0xa8, 0xe7, 0x36, 0xd6, 0x4f, 0x2a, 0x5c, 0x8f, 0x18, 0xd6, 0x23, 0x21, 0xc3,
3599
-	0x57, 0xab, 0xea, 0x23, 0x98, 0xeb, 0x4a, 0x5b, 0x66, 0x68, 0xf9, 0x4c, 0x61, 0xb1, 0x94, 0x9b,
3600
-	0x9d, 0x9d, 0x93, 0xe0, 0xe8, 0x3d, 0x58, 0xa6, 0xb8, 0x4b, 0x06, 0xd8, 0x3f, 0x4c, 0x22, 0x64,
3601
-	0xf2, 0x99, 0x82, 0x5e, 0xd6, 0x56, 0x14, 0x67, 0x29, 0x9e, 0x8a, 0x44, 0xcc, 0x2a, 0xc3, 0xf5,
3602
-	0xc7, 0xd8, 0x1d, 0xe0, 0xa4, 0x80, 0x12, 0xe8, 0x62, 0xc5, 0x64, 0x62, 0x97, 0x7b, 0x4a, 0xd6,
3603
-	0x5a, 0x86, 0x1b, 0x71, 0x8c, 0xa8, 0x40, 0xeb, 0x31, 0xdc, 0x7a, 0x4a, 0x89, 0x87, 0x19, 0x8b,
3604
-	0x58, 0xc6, 0xdc, 0xd6, 0xc8, 0x61, 0x43, 0x14, 0x26, 0xbf, 0xc4, 0x26, 0xcb, 0x76, 0x74, 0xac,
3605
-	0xec, 0x04, 0x4c, 0xe6, 0x1f, 0xe8, 0x2f, 0x7e, 0xb0, 0x14, 0xeb, 0x36, 0x98, 0x69, 0xd1, 0x62,
3606
-	0xaf, 0x4f, 0x60, 0xd5, 0xc1, 0x8c, 0x74, 0x06, 0x78, 0xdb, 0xf7, 0xa9, 0x80, 0x62, 0x9f, 0xab,
3607
-	0xac, 0xb2, 0x75, 0x0f, 0xd6, 0x26, 0xd5, 0xf1, 0x26, 0xa5, 0xed, 0x64, 0x07, 0x6e, 0xd6, 0x43,
3608
-	0x8e, 0x69, 0xe8, 0x76, 0x44, 0x9c, 0xc4, 0x69, 0x0d, 0xb4, 0x91, 0x49, 0x76, 0x78, 0xb6, 0xae,
3609
-	0xd5, 0x77, 0x1c, 0x2d, 0xf0, 0xd1, 0x43, 0xc8, 0xba, 0x1e, 0x0f, 0x48, 0x18, 0xef, 0xe0, 0x7a,
3610
-	0xda, 0x6a, 0xee, 0x71, 0x42, 0xf1, 0xb6, 0xc4, 0x92, 0xa3, 0x15, 0x89, 0xac, 0xdf, 0x74, 0x58,
3611
-	0x1c, 0x9b, 0x45, 0x1f, 0x8f, 0xc2, 0x09, 0xab, 0xa5, 0xd2, 0xdd, 0x4b, 0xc2, 0x3d, 0x0a, 0x42,
3612
-	0x3f, 0x09, 0x86, 0xec, 0x78, 0x5f, 0x35, 0xb9, 0xe4, 0x46, 0x9a, 0x54, 0xdc, 0x98, 0x9a, 0x12,
3613
-	0xed, 0x29, 0xba, 0x0f, 0x73, 0x0c, 0xd3, 0x41, 0xe0, 0x61, 0x79, 0x65, 0x16, 0x4b, 0x6f, 0xa5,
3614
-	0xba, 0x45, 0x48, 0x4d, 0x71, 0x12, 0x5a, 0x18, 0x71, 0x97, 0xb5, 0xe3, 0x2b, 0x95, 0x6a, 0xb4,
3615
-	0xef, 0xb2, 0xb6, 0x30, 0x12, 0x9c, 0x30, 0x0a, 0x31, 0x3f, 0x26, 0xb4, 0x6d, 0x5c, 0x9b, 0x6e,
3616
-	0xd4, 0x88, 0x10, 0x61, 0x14, 0xd3, 0x42, 0xe8, 0x75, 0xfa, 0x8c, 0x63, 0x6a, 0x64, 0xa7, 0x0b,
3617
-	0x2b, 0x11, 0x22, 0x84, 0x31, 0x8d, 0x3e, 0x84, 0x2c, 0xc3, 0x1e, 0xc5, 0xdc, 0x98, 0x93, 0x3a,
3618
-	0x33, 0xbd, 0x32, 0x41, 0xd4, 0xc4, 0x45, 0x97, 0x23, 0xf4, 0x00, 0xe6, 0x29, 0x66, 0xa4, 0x4f,
3619
-	0x3d, 0x6c, 0xcc, 0x4b, 0xdd, 0xed, 0xd4, 0xcb, 0x11, 0x33, 0x35, 0xc5, 0x19, 0xf1, 0xe8, 0x21,
3620
-	0x2c, 0xe0, 0xaf, 0x39, 0x0e, 0x99, 0xd8, 0xbc, 0x05, 0x29, 0x7e, 0x3b, 0x4d, 0x5c, 0x4d, 0xa0,
3621
-	0x9a, 0xe2, 0x9c, 0x2b, 0x44, 0xc2, 0x1e, 0x09, 0x8f, 0x82, 0x96, 0x01, 0xd3, 0x13, 0xae, 0x48,
3622
-	0x42, 0x24, 0x1c, 0xb1, 0xe5, 0x79, 0xc8, 0x72, 0x97, 0xb6, 0x30, 0xdf, 0xfc, 0x57, 0x85, 0xe5,
3623
-	0x89, 0x73, 0x81, 0xde, 0x85, 0xb9, 0x83, 0xc6, 0xa3, 0xc6, 0xee, 0xe7, 0x8d, 0x15, 0xc5, 0x34,
3624
-	0x4f, 0x5e, 0xe6, 0xd7, 0x26, 0x88, 0x83, 0xb0, 0x1d, 0x92, 0xe3, 0x10, 0x95, 0xe0, 0xe6, 0xde,
3625
-	0xfe, 0xae, 0x53, 0x3d, 0xdc, 0xae, 0xec, 0xd7, 0x77, 0x1b, 0x87, 0x15, 0xa7, 0xba, 0xbd, 0x5f,
3626
-	0x5d, 0x51, 0xcd, 0x5b, 0x27, 0x2f, 0xf3, 0xab, 0x13, 0xa2, 0x0a, 0xc5, 0x2e, 0xc7, 0x17, 0x34,
3627
-	0x07, 0x4f, 0x77, 0x84, 0x46, 0x4b, 0xd5, 0x1c, 0xf4, 0xfc, 0x34, 0x8d, 0x53, 0x7d, 0xb2, 0xfb,
3628
-	0x59, 0x75, 0x25, 0x93, 0xaa, 0x71, 0x64, 0x13, 0x33, 0xdf, 0xfc, 0xee, 0xe7, 0x9c, 0xf2, 0xeb,
3629
-	0x2f, 0xb9, 0xc9, 0xea, 0x4a, 0xdf, 0x6b, 0xa0, 0x8b, 0x1b, 0x8a, 0x4e, 0x54, 0x40, 0x17, 0x9b,
3630
-	0x07, 0xda, 0x4a, 0x5b, 0xc1, 0xa9, 0x2d, 0xcb, 0xb4, 0xaf, 0x8a, 0xc7, 0x3d, 0x69, 0xf5, 0xf7,
3631
-	0x57, 0xff, 0xfc, 0xa8, 0x2d, 0xc3, 0x0d, 0xc9, 0x6f, 0x75, 0xdd, 0xd0, 0x6d, 0x61, 0x8a, 0xbe,
3632
-	0x85, 0xa5, 0xff, 0x37, 0x1b, 0xb4, 0x31, 0xed, 0x08, 0x5d, 0x68, 0x67, 0xe6, 0xe6, 0x55, 0xd0,
3633
-	0x99, 0xfe, 0xa5, 0x3f, 0x55, 0x58, 0x3a, 0x6f, 0xde, 0xec, 0x79, 0xd0, 0x43, 0x5f, 0x80, 0x2e,
3634
-	0x9e, 0x26, 0x94, 0xda, 0x9a, 0xc6, 0x1e, 0x36, 0x33, 0x3f, 0x1d, 0x98, 0x5d, 0xb4, 0x07, 0xd7,
3635
-	0xe4, 0xe3, 0x80, 0x52, 0x23, 0x8c, 0xbf, 0x3d, 0xe6, 0x9d, 0x19, 0xc4, 0x4c, 0x93, 0xb2, 0x71,
3636
-	0xfa, 0x3a, 0xa7, 0xfc, 0xf5, 0x3a, 0xa7, 0xbc, 0x18, 0xe6, 0xd4, 0xd3, 0x61, 0x4e, 0xfd, 0x63,
3637
-	0x98, 0x53, 0xff, 0x1e, 0xe6, 0xd4, 0x67, 0x99, 0x67, 0x7a, 0x33, 0x2b, 0x7f, 0x5b, 0x7c, 0xf0,
3638
-	0x5f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x64, 0x01, 0xa3, 0x4f, 0x74, 0x09, 0x00, 0x00,
3577
+	// 1015 bytes of a gzipped FileDescriptorProto
3578
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x96, 0xc1, 0x6e, 0x1b, 0x45,
3579
+	0x18, 0xc7, 0x77, 0xed, 0xad, 0xd3, 0x7c, 0x69, 0x93, 0x30, 0x25, 0x61, 0xb3, 0x2d, 0x8e, 0xbb,
3580
+	0x45, 0xc2, 0x09, 0xc9, 0x5a, 0x18, 0xa4, 0xa2, 0x42, 0x0f, 0x71, 0x62, 0x29, 0x26, 0xad, 0x53,
3581
+	0x6d, 0x12, 0xe8, 0x2d, 0xac, 0x77, 0x27, 0xee, 0x62, 0x7b, 0xc7, 0xcc, 0x8c, 0x1d, 0xb8, 0xa0,
3582
+	0x1e, 0x21, 0x2f, 0x00, 0x42, 0xaa, 0x38, 0xc0, 0xb9, 0x0f, 0xc0, 0x03, 0xa0, 0x88, 0x13, 0x37,
3583
+	0x38, 0x45, 0xd4, 0x0f, 0x00, 0xaf, 0x80, 0x66, 0x76, 0xd7, 0x31, 0xf6, 0xda, 0xf1, 0x81, 0x4b,
3584
+	0x32, 0xda, 0xf9, 0xfd, 0xbf, 0xff, 0x37, 0x33, 0xdf, 0x7c, 0x63, 0x58, 0xab, 0xfb, 0xfc, 0x59,
3585
+	0xa7, 0x66, 0xb9, 0xa4, 0x55, 0xf0, 0x88, 0xdb, 0xc0, 0xb4, 0xc0, 0x4e, 0x1d, 0xda, 0x6a, 0xf8,
3586
+	0xbc, 0xe0, 0xb4, 0xfd, 0x02, 0x75, 0x4e, 0xb8, 0xd5, 0xa6, 0x84, 0x13, 0x84, 0xc2, 0x79, 0x2b,
3587
+	0x9e, 0xb7, 0xba, 0xef, 0x1a, 0x1b, 0x57, 0xc8, 0x49, 0xed, 0x73, 0xec, 0x72, 0x16, 0x46, 0x30,
3588
+	0xd6, 0xaf, 0xa0, 0xf9, 0x57, 0x6d, 0x1c, 0xb3, 0x9b, 0x03, 0xac, 0x4b, 0x28, 0x26, 0xac, 0x80,
3589
+	0xb9, 0xeb, 0xc9, 0x84, 0xe4, 0x9f, 0x76, 0x6d, 0x20, 0x39, 0xe3, 0xf5, 0x3a, 0xa9, 0x13, 0x39,
3590
+	0x2c, 0x88, 0x51, 0xf4, 0xf5, 0xfe, 0x04, 0x43, 0x49, 0xd4, 0x3a, 0x27, 0x85, 0x76, 0xb3, 0x53,
3591
+	0xf7, 0x83, 0xe8, 0x5f, 0x28, 0x34, 0x5f, 0xaa, 0x00, 0xb6, 0x73, 0xc2, 0x1f, 0xe3, 0x56, 0x0d,
3592
+	0x53, 0x74, 0x0f, 0x66, 0x84, 0xd7, 0xb1, 0xef, 0xe9, 0x6a, 0x4e, 0xcd, 0x6b, 0x25, 0xe8, 0x5d,
3593
+	0xac, 0x66, 0x04, 0x50, 0xd9, 0xb1, 0x33, 0x62, 0xaa, 0xe2, 0x09, 0x28, 0x20, 0x1e, 0x16, 0x50,
3594
+	0x2a, 0xa7, 0xe6, 0x67, 0x43, 0xa8, 0x4a, 0x3c, 0x2c, 0x20, 0x31, 0x55, 0xf1, 0x10, 0x02, 0xcd,
3595
+	0xf1, 0x3c, 0xaa, 0xa7, 0x05, 0x61, 0xcb, 0x31, 0x2a, 0x41, 0x86, 0x71, 0x87, 0x77, 0x98, 0xae,
3596
+	0xe5, 0xd4, 0xfc, 0x5c, 0xf1, 0x2d, 0x6b, 0x74, 0xa7, 0xad, 0xcb, 0x6c, 0x0e, 0x24, 0x5b, 0xd2,
3597
+	0xce, 0x2f, 0x56, 0x15, 0x3b, 0x52, 0x9a, 0x77, 0x61, 0xee, 0x63, 0xe2, 0x07, 0x36, 0xfe, 0xa2,
3598
+	0x83, 0x19, 0xef, 0xdb, 0xa8, 0x97, 0x36, 0xe6, 0x0f, 0x2a, 0xdc, 0x08, 0x19, 0xd6, 0x26, 0x01,
3599
+	0xc3, 0xd3, 0xad, 0xea, 0x03, 0x98, 0x69, 0x49, 0x5b, 0xa6, 0xa7, 0x72, 0xe9, 0xfc, 0x5c, 0x31,
3600
+	0x3b, 0x39, 0x3b, 0x3b, 0xc6, 0xd1, 0x3b, 0xb0, 0x40, 0x71, 0x8b, 0x74, 0xb1, 0x77, 0x1c, 0x47,
3601
+	0x48, 0xe7, 0xd2, 0x79, 0xad, 0x94, 0x5a, 0x54, 0xec, 0xf9, 0x68, 0x2a, 0x14, 0x31, 0xb3, 0x04,
3602
+	0x37, 0x1e, 0x61, 0xa7, 0x8b, 0xe3, 0x05, 0x14, 0x41, 0x13, 0x3b, 0x26, 0x13, 0xbb, 0xda, 0x53,
3603
+	0xb2, 0xe6, 0x02, 0xdc, 0x8c, 0x62, 0x84, 0x0b, 0x34, 0x1f, 0xc1, 0xca, 0x13, 0x4a, 0x5c, 0xcc,
3604
+	0x58, 0xc8, 0x32, 0xe6, 0xd4, 0xfb, 0x0e, 0x6b, 0x62, 0x61, 0xf2, 0x4b, 0x64, 0xb2, 0x60, 0x85,
3605
+	0x65, 0x65, 0xc5, 0x60, 0x3c, 0xff, 0x40, 0x7b, 0xfe, 0x9d, 0xa9, 0x98, 0x77, 0xc0, 0x48, 0x8a,
3606
+	0x16, 0x79, 0xed, 0x81, 0x7e, 0xc0, 0x29, 0x76, 0x5a, 0xff, 0x87, 0xd5, 0x6d, 0x58, 0x49, 0x08,
3607
+	0x16, 0x39, 0x7d, 0x04, 0x4b, 0x36, 0x66, 0xa4, 0xd9, 0xc5, 0x5b, 0x9e, 0x47, 0x45, 0x3a, 0x91,
3608
+	0xcd, 0x34, 0xe7, 0x69, 0x6e, 0xc0, 0xf2, 0xb0, 0x3a, 0x2a, 0x87, 0xa4, 0x9a, 0x69, 0xc2, 0xad,
3609
+	0x4a, 0xc0, 0x31, 0x0d, 0x9c, 0xa6, 0x88, 0x13, 0x3b, 0x2d, 0x43, 0xaa, 0x6f, 0x92, 0xe9, 0x5d,
3610
+	0xac, 0xa6, 0x2a, 0x3b, 0x76, 0xca, 0xf7, 0xd0, 0x43, 0xc8, 0x38, 0x2e, 0xf7, 0x49, 0x10, 0xd5,
3611
+	0xca, 0x6a, 0xd2, 0xb9, 0x1d, 0x70, 0x42, 0xf1, 0x96, 0xc4, 0xe2, 0x22, 0x0e, 0x45, 0xe6, 0xaf,
3612
+	0x1a, 0xcc, 0x0d, 0xcc, 0xa2, 0x0f, 0xfb, 0xe1, 0x84, 0xd5, 0x7c, 0xf1, 0xde, 0x15, 0xe1, 0xf6,
3613
+	0xfc, 0xc0, 0x8b, 0x83, 0x21, 0x2b, 0xaa, 0xa0, 0x94, 0xdc, 0x71, 0x3d, 0x49, 0x2a, 0xee, 0xe6,
3614
+	0xae, 0x12, 0x56, 0x0f, 0xba, 0x0f, 0x33, 0x0c, 0xd3, 0xae, 0xef, 0x62, 0x79, 0x39, 0xe7, 0x8a,
3615
+	0xb7, 0x13, 0xdd, 0x42, 0x64, 0x57, 0xb1, 0x63, 0x5a, 0x18, 0x71, 0x87, 0x35, 0xa2, 0xcb, 0x9b,
3616
+	0x68, 0x74, 0xe8, 0xb0, 0x86, 0x30, 0x12, 0x9c, 0x30, 0x0a, 0x30, 0x3f, 0x25, 0xb4, 0xa1, 0x5f,
3617
+	0x1b, 0x6f, 0x54, 0x0d, 0x11, 0x61, 0x14, 0xd1, 0x42, 0xe8, 0x36, 0x3b, 0x8c, 0x63, 0xaa, 0x67,
3618
+	0xc6, 0x0b, 0xb7, 0x43, 0x44, 0x08, 0x23, 0x1a, 0xbd, 0x0f, 0x19, 0x86, 0x5d, 0x8a, 0xb9, 0x3e,
3619
+	0x23, 0x75, 0x46, 0xf2, 0xca, 0x04, 0xb1, 0x2b, 0x5a, 0x8a, 0x1c, 0xa1, 0x07, 0x70, 0x9d, 0x62,
3620
+	0x46, 0x3a, 0xd4, 0xc5, 0xfa, 0x75, 0xa9, 0xbb, 0x93, 0x78, 0x0d, 0x23, 0x66, 0x57, 0xb1, 0xfb,
3621
+	0x3c, 0x7a, 0x08, 0xb3, 0xf8, 0x4b, 0x8e, 0x03, 0x26, 0x0e, 0x6f, 0x56, 0x8a, 0xdf, 0x4c, 0x12,
3622
+	0x97, 0x63, 0x68, 0x57, 0xb1, 0x2f, 0x15, 0x22, 0x61, 0x97, 0x04, 0x27, 0x7e, 0x5d, 0x87, 0xf1,
3623
+	0x09, 0x6f, 0x4b, 0x42, 0x24, 0x1c, 0xb2, 0xa5, 0xeb, 0x90, 0xe1, 0x0e, 0xad, 0x63, 0xbe, 0xfe,
3624
+	0x8f, 0x0a, 0x0b, 0x43, 0x75, 0x81, 0xde, 0x86, 0x99, 0xa3, 0xea, 0x5e, 0x75, 0xff, 0xd3, 0xea,
3625
+	0xa2, 0x62, 0x18, 0x67, 0x2f, 0x72, 0xcb, 0x43, 0xc4, 0x51, 0xd0, 0x08, 0xc8, 0x69, 0x80, 0x8a,
3626
+	0x70, 0xeb, 0xe0, 0x70, 0xdf, 0x2e, 0x1f, 0x6f, 0x6d, 0x1f, 0x56, 0xf6, 0xab, 0xc7, 0xdb, 0x76,
3627
+	0x79, 0xeb, 0xb0, 0xbc, 0xa8, 0x1a, 0x2b, 0x67, 0x2f, 0x72, 0x4b, 0x43, 0xa2, 0x6d, 0x8a, 0x1d,
3628
+	0x8e, 0x47, 0x34, 0x47, 0x4f, 0x76, 0x84, 0x26, 0x95, 0xa8, 0x39, 0x6a, 0x7b, 0x49, 0x1a, 0xbb,
3629
+	0xfc, 0x78, 0xff, 0x93, 0xf2, 0x62, 0x3a, 0x51, 0x63, 0xcb, 0x76, 0x69, 0xbc, 0xf1, 0xcd, 0x4f,
3630
+	0x59, 0xe5, 0x97, 0x9f, 0xb3, 0xc3, 0xab, 0x2b, 0xfe, 0x98, 0x06, 0x4d, 0xdc, 0x50, 0x74, 0xa6,
3631
+	0x02, 0x1a, 0x6d, 0x53, 0x68, 0x33, 0x69, 0x07, 0xc7, 0x36, 0x47, 0xc3, 0x9a, 0x16, 0x8f, 0x7a,
3632
+	0xd2, 0xd2, 0x6f, 0x2f, 0xff, 0xfe, 0x3e, 0xb5, 0x00, 0x37, 0x25, 0xbf, 0xd9, 0x72, 0x02, 0xa7,
3633
+	0x8e, 0x29, 0xfa, 0x56, 0x85, 0xd7, 0x46, 0x1a, 0x19, 0xda, 0x48, 0xbe, 0xc6, 0xc9, 0xcd, 0xd3,
3634
+	0xd8, 0x9c, 0x92, 0x9e, 0x98, 0x49, 0x5e, 0x45, 0x5f, 0xc3, 0xfc, 0x7f, 0x1b, 0x1f, 0x5a, 0x1b,
3635
+	0x57, 0xce, 0x23, 0xad, 0xd5, 0x58, 0x9f, 0x06, 0x9d, 0x98, 0x41, 0xf1, 0x0f, 0x15, 0xe6, 0x2f,
3636
+	0x9f, 0x2c, 0xf6, 0xcc, 0x6f, 0xa3, 0xcf, 0x40, 0x13, 0x0f, 0x32, 0x4a, 0x6c, 0x93, 0x03, 0xcf,
3637
+	0xb9, 0x91, 0x1b, 0x0f, 0x4c, 0x3e, 0x00, 0x17, 0xae, 0xc9, 0x27, 0x11, 0x25, 0x46, 0x18, 0x7c,
3638
+	0x71, 0x8d, 0xbb, 0x13, 0x88, 0x89, 0x26, 0x25, 0xfd, 0xfc, 0x55, 0x56, 0xf9, 0xf3, 0x55, 0x56,
3639
+	0x79, 0xde, 0xcb, 0xaa, 0xe7, 0xbd, 0xac, 0xfa, 0x7b, 0x2f, 0xab, 0xfe, 0xd5, 0xcb, 0xaa, 0x4f,
3640
+	0xd3, 0x4f, 0xb5, 0x5a, 0x46, 0xfe, 0xa2, 0x7a, 0xef, 0xdf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x3e,
3641
+	0x7a, 0x8b, 0xe7, 0x6a, 0x0a, 0x00, 0x00,
3639 3642
 }
... ...
@@ -16,6 +16,15 @@ service Raft {
16 16
 		option (docker.protobuf.plugin.tls_authorization) = { roles: "swarm-manager" };
17 17
 	};
18 18
 
19
+	// StreamRaftMessage accepts a stream of raft messages of type StreamRaftMessageRequest
20
+	// to be processed on a raft member, returning a StreamRaftMessageResponse 
21
+	// when processing of the streamed messages is complete. A single stream corresponds 
22
+	// to a single raft message, which may be disassembled and streamed as individual messages.
23
+	// It is called from the Raft leader, which uses it to stream messages to a raft member.
24
+	rpc StreamRaftMessage(stream StreamRaftMessageRequest) returns (StreamRaftMessageResponse) {
25
+		option (docker.protobuf.plugin.tls_authorization) = { roles: "swarm-manager" };
26
+	};
27
+
19 28
 	// ResolveAddress returns the address where the node with the given ID can be reached.
20 29
 	rpc ResolveAddress(ResolveAddressRequest) returns (ResolveAddressResponse) {
21 30
 		option (docker.protobuf.plugin.tls_authorization) = { roles: "swarm-manager" };
... ...
@@ -82,6 +91,15 @@ message ProcessRaftMessageRequest {
82 82
 
83 83
 message ProcessRaftMessageResponse {}
84 84
 
85
+// Raft message streaming request.
86
+message StreamRaftMessageRequest {
87
+	option (docker.protobuf.plugin.deepcopy) = false;
88
+	raftpb.Message message = 1;
89
+}
90
+
91
+// Raft message streaming response.
92
+message StreamRaftMessageResponse {}
93
+
85 94
 message ResolveAddressRequest {
86 95
 	// raft_id is the ID to resolve to an address.
87 96
 	uint64 raft_id = 1;
... ...
@@ -19,6 +19,7 @@ import (
19 19
 
20 20
 import raftselector "github.com/docker/swarmkit/manager/raftselector"
21 21
 import codes "google.golang.org/grpc/codes"
22
+import status "google.golang.org/grpc/status"
22 23
 import metadata "google.golang.org/grpc/metadata"
23 24
 import transport "google.golang.org/grpc/transport"
24 25
 import rafttime "time"
... ...
@@ -403,12 +404,12 @@ func NewRaftProxyResourceAllocatorServer(local ResourceAllocatorServer, connSele
403 403
 	redirectChecker := func(ctx context.Context) (context.Context, error) {
404 404
 		s, ok := transport.StreamFromContext(ctx)
405 405
 		if !ok {
406
-			return ctx, grpc.Errorf(codes.InvalidArgument, "remote addr is not found in context")
406
+			return ctx, status.Errorf(codes.InvalidArgument, "remote addr is not found in context")
407 407
 		}
408 408
 		addr := s.ServerTransport().RemoteAddr().String()
409 409
 		md, ok := metadata.FromContext(ctx)
410 410
 		if ok && len(md["redirect"]) != 0 {
411
-			return ctx, grpc.Errorf(codes.ResourceExhausted, "more than one redirect to leader from: %s", md["redirect"])
411
+			return ctx, status.Errorf(codes.ResourceExhausted, "more than one redirect to leader from: %s", md["redirect"])
412 412
 		}
413 413
 		if !ok {
414 414
 			md = metadata.New(map[string]string{})
... ...
@@ -72,7 +72,16 @@ const (
72 72
 	TaskStateShutdown  TaskState = 640
73 73
 	TaskStateFailed    TaskState = 704
74 74
 	TaskStateRejected  TaskState = 768
75
-	TaskStateOrphaned  TaskState = 832
75
+	// TaskStateRemove is used to correctly handle service deletions and scale
76
+	// downs. This allows us to keep track of tasks that have been marked for
77
+	// deletion, but can't yet be removed because the agent is in the process of
78
+	// shutting them down. Once the agent has shut down tasks with desired state
79
+	// REMOVE, the task reaper is responsible for removing them.
80
+	TaskStateRemove TaskState = 800
81
+	// TaskStateOrphaned is used to free up resources associated with service
82
+	// tasks on unresponsive nodes without having to delete those tasks. This
83
+	// state is directly assigned to the task by the orchestrator.
84
+	TaskStateOrphaned TaskState = 832
76 85
 )
77 86
 
78 87
 var TaskState_name = map[int32]string{
... ...
@@ -88,6 +97,7 @@ var TaskState_name = map[int32]string{
88 88
 	640: "SHUTDOWN",
89 89
 	704: "FAILED",
90 90
 	768: "REJECTED",
91
+	800: "REMOVE",
91 92
 	832: "ORPHANED",
92 93
 }
93 94
 var TaskState_value = map[string]int32{
... ...
@@ -103,6 +113,7 @@ var TaskState_value = map[string]int32{
103 103
 	"SHUTDOWN":  640,
104 104
 	"FAILED":    704,
105 105
 	"REJECTED":  768,
106
+	"REMOVE":    800,
106 107
 	"ORPHANED":  832,
107 108
 }
108 109
 
... ...
@@ -17029,319 +17040,321 @@ var (
17029 17029
 func init() { proto.RegisterFile("github.com/docker/swarmkit/api/types.proto", fileDescriptorTypes) }
17030 17030
 
17031 17031
 var fileDescriptorTypes = []byte{
17032
-	// 5020 bytes of a gzipped FileDescriptorProto
17033
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x5a, 0x4d, 0x6c, 0x24, 0x49,
17034
-	0x56, 0x76, 0xfd, 0xba, 0xea, 0x55, 0xd9, 0x4e, 0x47, 0x7b, 0x7b, 0xdc, 0xb5, 0xdd, 0x76, 0x4d,
17035
-	0xce, 0xf4, 0xce, 0x6c, 0x6f, 0x53, 0xfd, 0xb7, 0xbb, 0xea, 0x99, 0x61, 0x77, 0xa6, 0xfe, 0x6c,
17036
-	0xd7, 0xb6, 0x5d, 0x55, 0x8a, 0x2a, 0x77, 0xef, 0x22, 0x41, 0x2a, 0x9d, 0x19, 0x2e, 0xe7, 0x38,
17037
-	0x2b, 0xa3, 0xc8, 0xcc, 0xb2, 0xbb, 0x58, 0x10, 0x2d, 0x0e, 0x80, 0x7c, 0x82, 0xdb, 0x22, 0x64,
17038
-	0x2e, 0x70, 0x42, 0x48, 0x1c, 0x40, 0x42, 0x70, 0x1a, 0x24, 0x0e, 0x7b, 0x83, 0x05, 0x09, 0xad,
17039
-	0x40, 0x32, 0xac, 0x0f, 0xdc, 0x56, 0x70, 0x59, 0x71, 0x01, 0x09, 0xc5, 0x4f, 0x66, 0xa5, 0xab,
17040
-	0xd3, 0x76, 0x0f, 0xb3, 0x17, 0xbb, 0xe2, 0xbd, 0xef, 0xbd, 0x78, 0xf1, 0x22, 0xe2, 0xc5, 0x7b,
17041
-	0x11, 0x09, 0xf7, 0x06, 0x96, 0x7f, 0x30, 0xde, 0xab, 0x18, 0x74, 0xf8, 0xc0, 0xa4, 0xc6, 0x21,
17042
-	0x71, 0x1f, 0x78, 0xc7, 0xba, 0x3b, 0x3c, 0xb4, 0xfc, 0x07, 0xfa, 0xc8, 0x7a, 0xe0, 0x4f, 0x46,
17043
-	0xc4, 0xab, 0x8c, 0x5c, 0xea, 0x53, 0x84, 0x04, 0xa0, 0x12, 0x00, 0x2a, 0x47, 0x8f, 0x4a, 0xeb,
17044
-	0x03, 0x4a, 0x07, 0x36, 0x79, 0xc0, 0x11, 0x7b, 0xe3, 0xfd, 0x07, 0xbe, 0x35, 0x24, 0x9e, 0xaf,
17045
-	0x0f, 0x47, 0x42, 0xa8, 0xb4, 0x36, 0x0b, 0x30, 0xc7, 0xae, 0xee, 0x5b, 0xd4, 0x91, 0xfc, 0x95,
17046
-	0x01, 0x1d, 0x50, 0xfe, 0xf3, 0x01, 0xfb, 0x25, 0xa8, 0xea, 0x3a, 0xcc, 0x3f, 0x27, 0xae, 0x67,
17047
-	0x51, 0x07, 0xad, 0x40, 0xc6, 0x72, 0x4c, 0xf2, 0x72, 0x35, 0x51, 0x4e, 0xbc, 0x9f, 0xc6, 0xa2,
17048
-	0xa1, 0x3e, 0x04, 0x68, 0xb1, 0x1f, 0x4d, 0xc7, 0x77, 0x27, 0x48, 0x81, 0xd4, 0x21, 0x99, 0x70,
17049
-	0x44, 0x1e, 0xb3, 0x9f, 0x8c, 0x72, 0xa4, 0xdb, 0xab, 0x49, 0x41, 0x39, 0xd2, 0x6d, 0xf5, 0x27,
17050
-	0x09, 0x28, 0x54, 0x1d, 0x87, 0xfa, 0xbc, 0x77, 0x0f, 0x21, 0x48, 0x3b, 0xfa, 0x90, 0x48, 0x21,
17051
-	0xfe, 0x1b, 0xd5, 0x21, 0x6b, 0xeb, 0x7b, 0xc4, 0xf6, 0x56, 0x93, 0xe5, 0xd4, 0xfb, 0x85, 0xc7,
17052
-	0x5f, 0xab, 0xbc, 0x3e, 0xe4, 0x4a, 0x44, 0x49, 0x65, 0x9b, 0xa3, 0xb9, 0x11, 0x58, 0x8a, 0xa2,
17053
-	0x6f, 0xc3, 0xbc, 0xe5, 0x98, 0x96, 0x41, 0xbc, 0xd5, 0x34, 0xd7, 0xb2, 0x16, 0xa7, 0x65, 0x6a,
17054
-	0x7d, 0x2d, 0xfd, 0xc3, 0xb3, 0xf5, 0x39, 0x1c, 0x08, 0x95, 0x3e, 0x80, 0x42, 0x44, 0x6d, 0xcc,
17055
-	0xd8, 0x56, 0x20, 0x73, 0xa4, 0xdb, 0x63, 0x22, 0x47, 0x27, 0x1a, 0x1f, 0x26, 0x9f, 0x26, 0xd4,
17056
-	0x4f, 0x60, 0xa5, 0xad, 0x0f, 0x89, 0xb9, 0x49, 0x1c, 0xe2, 0x5a, 0x06, 0x26, 0x1e, 0x1d, 0xbb,
17057
-	0x06, 0x61, 0x63, 0x3d, 0xb4, 0x1c, 0x33, 0x18, 0x2b, 0xfb, 0x1d, 0xaf, 0x45, 0xad, 0xc3, 0x5b,
17058
-	0x0d, 0xcb, 0x33, 0x5c, 0xe2, 0x93, 0xcf, 0xad, 0x24, 0x15, 0x28, 0x39, 0x4b, 0xc0, 0xd2, 0xac,
17059
-	0xf4, 0x2f, 0xc1, 0x0d, 0xe6, 0x62, 0x53, 0x73, 0x25, 0x45, 0xf3, 0x46, 0xc4, 0xe0, 0xca, 0x0a,
17060
-	0x8f, 0xdf, 0x8f, 0xf3, 0x50, 0xdc, 0x48, 0xb6, 0xe6, 0xf0, 0x32, 0x57, 0x13, 0x10, 0x7a, 0x23,
17061
-	0x62, 0x20, 0x03, 0x6e, 0x9a, 0xd2, 0xe8, 0x19, 0xf5, 0x49, 0xae, 0x3e, 0x76, 0x1a, 0x2f, 0x19,
17062
-	0xe6, 0xd6, 0x1c, 0x5e, 0x09, 0x94, 0x45, 0x3b, 0xa9, 0x01, 0xe4, 0x02, 0xdd, 0xea, 0x0f, 0x12,
17063
-	0x90, 0x0f, 0x98, 0x1e, 0xfa, 0x2a, 0xe4, 0x1d, 0xdd, 0xa1, 0x9a, 0x31, 0x1a, 0x7b, 0x7c, 0x40,
17064
-	0xa9, 0x5a, 0xf1, 0xfc, 0x6c, 0x3d, 0xd7, 0xd6, 0x1d, 0x5a, 0xef, 0xee, 0x7a, 0x38, 0xc7, 0xd8,
17065
-	0xf5, 0xd1, 0xd8, 0x43, 0x6f, 0x43, 0x71, 0x48, 0x86, 0xd4, 0x9d, 0x68, 0x7b, 0x13, 0x9f, 0x78,
17066
-	0xd2, 0x6d, 0x05, 0x41, 0xab, 0x31, 0x12, 0xfa, 0x16, 0xcc, 0x0f, 0x84, 0x49, 0xab, 0x29, 0xbe,
17067
-	0x7c, 0xde, 0x89, 0xb3, 0x7e, 0xc6, 0x6a, 0x1c, 0xc8, 0xa8, 0xbf, 0x97, 0x80, 0x95, 0x90, 0x4a,
17068
-	0x7e, 0x75, 0x6c, 0xb9, 0x64, 0x48, 0x1c, 0xdf, 0x43, 0xdf, 0x80, 0xac, 0x6d, 0x0d, 0x2d, 0xdf,
17069
-	0x93, 0x3e, 0xbf, 0x13, 0xa7, 0x36, 0x1c, 0x14, 0x96, 0x60, 0x54, 0x85, 0xa2, 0x4b, 0x3c, 0xe2,
17070
-	0x1e, 0x89, 0x15, 0x2f, 0x3d, 0x7a, 0x8d, 0xf0, 0x05, 0x11, 0x75, 0x03, 0x72, 0x5d, 0x5b, 0xf7,
17071
-	0xf7, 0xa9, 0x3b, 0x44, 0x2a, 0x14, 0x75, 0xd7, 0x38, 0xb0, 0x7c, 0x62, 0xf8, 0x63, 0x37, 0xd8,
17072
-	0x7d, 0x17, 0x68, 0xe8, 0x26, 0x24, 0xa9, 0xe8, 0x28, 0x5f, 0xcb, 0x9e, 0x9f, 0xad, 0x27, 0x3b,
17073
-	0x3d, 0x9c, 0xa4, 0x9e, 0xfa, 0x11, 0x2c, 0x77, 0xed, 0xf1, 0xc0, 0x72, 0x1a, 0xc4, 0x33, 0x5c,
17074
-	0x6b, 0xc4, 0xb4, 0xb3, 0x55, 0xc9, 0x62, 0x54, 0xb0, 0x2a, 0xd9, 0xef, 0x70, 0x6b, 0x27, 0xa7,
17075
-	0x5b, 0x5b, 0xfd, 0x9d, 0x24, 0x2c, 0x37, 0x9d, 0x81, 0xe5, 0x90, 0xa8, 0xf4, 0x5d, 0x58, 0x24,
17076
-	0x9c, 0xa8, 0x1d, 0x89, 0x70, 0x23, 0xf5, 0x2c, 0x08, 0x6a, 0x10, 0x83, 0x5a, 0x33, 0x71, 0xe1,
17077
-	0x51, 0xdc, 0xf0, 0x5f, 0xd3, 0x1e, 0x1b, 0x1d, 0x9a, 0x30, 0x3f, 0xe2, 0x83, 0xf0, 0xe4, 0xf4,
17078
-	0xde, 0x8d, 0xd3, 0xf5, 0xda, 0x38, 0x83, 0x20, 0x21, 0x65, 0xbf, 0x48, 0x90, 0xf8, 0xb3, 0x24,
17079
-	0x2c, 0xb5, 0xa9, 0x79, 0xc1, 0x0f, 0x25, 0xc8, 0x1d, 0x50, 0xcf, 0x8f, 0x04, 0xc4, 0xb0, 0x8d,
17080
-	0x9e, 0x42, 0x6e, 0x24, 0xa7, 0x4f, 0xce, 0xfe, 0xed, 0x78, 0x93, 0x05, 0x06, 0x87, 0x68, 0xf4,
17081
-	0x11, 0xe4, 0x83, 0x2d, 0xc3, 0x46, 0xfb, 0x06, 0x0b, 0x67, 0x8a, 0x47, 0xdf, 0x82, 0xac, 0x98,
17082
-	0x84, 0xd5, 0x34, 0x97, 0xbc, 0xfb, 0x46, 0x3e, 0xc7, 0x52, 0x08, 0x6d, 0x42, 0xce, 0xb7, 0x3d,
17083
-	0xcd, 0x72, 0xf6, 0xe9, 0x6a, 0x86, 0x2b, 0x58, 0x8f, 0x0d, 0x32, 0xd4, 0x24, 0xfd, 0xed, 0x5e,
17084
-	0xcb, 0xd9, 0xa7, 0xb5, 0xc2, 0xf9, 0xd9, 0xfa, 0xbc, 0x6c, 0xe0, 0x79, 0xdf, 0xf6, 0xd8, 0x0f,
17085
-	0xf5, 0xf7, 0x13, 0x50, 0x88, 0xa0, 0xd0, 0x1d, 0x00, 0xdf, 0x1d, 0x7b, 0xbe, 0xe6, 0x52, 0xea,
17086
-	0x73, 0x67, 0x15, 0x71, 0x9e, 0x53, 0x30, 0xa5, 0x3e, 0xaa, 0xc0, 0x0d, 0x83, 0xb8, 0xbe, 0x66,
17087
-	0x79, 0xde, 0x98, 0xb8, 0x9a, 0x37, 0xde, 0xfb, 0x94, 0x18, 0x3e, 0x77, 0x5c, 0x11, 0x2f, 0x33,
17088
-	0x56, 0x8b, 0x73, 0x7a, 0x82, 0x81, 0x9e, 0xc0, 0xcd, 0x28, 0x7e, 0x34, 0xde, 0xb3, 0x2d, 0x43,
17089
-	0x63, 0x93, 0x99, 0xe2, 0x22, 0x37, 0xa6, 0x22, 0x5d, 0xce, 0x7b, 0x46, 0x26, 0xea, 0x8f, 0x13,
17090
-	0xa0, 0x60, 0x7d, 0xdf, 0xdf, 0x21, 0xc3, 0x3d, 0xe2, 0xf6, 0x7c, 0xdd, 0x1f, 0x7b, 0xe8, 0x26,
17091
-	0x64, 0x6d, 0xa2, 0x9b, 0xc4, 0xe5, 0x46, 0xe5, 0xb0, 0x6c, 0xa1, 0x5d, 0xb6, 0x83, 0x75, 0xe3,
17092
-	0x40, 0xdf, 0xb3, 0x6c, 0xcb, 0x9f, 0x70, 0x53, 0x16, 0xe3, 0x97, 0xf0, 0xac, 0xce, 0x0a, 0x8e,
17093
-	0x08, 0xe2, 0x0b, 0x6a, 0xd0, 0x2a, 0xcc, 0x0f, 0x89, 0xe7, 0xe9, 0x03, 0xc2, 0x2d, 0xcd, 0xe3,
17094
-	0xa0, 0xa9, 0x7e, 0x04, 0xc5, 0xa8, 0x1c, 0x2a, 0xc0, 0xfc, 0x6e, 0xfb, 0x59, 0xbb, 0xf3, 0xa2,
17095
-	0xad, 0xcc, 0xa1, 0x25, 0x28, 0xec, 0xb6, 0x71, 0xb3, 0x5a, 0xdf, 0xaa, 0xd6, 0xb6, 0x9b, 0x4a,
17096
-	0x02, 0x2d, 0x40, 0x7e, 0xda, 0x4c, 0xaa, 0x7f, 0x91, 0x00, 0x60, 0xee, 0x96, 0x83, 0xfa, 0x10,
17097
-	0x32, 0x9e, 0xaf, 0xfb, 0x62, 0x55, 0x2e, 0x3e, 0x7e, 0xf7, 0xb2, 0x39, 0x94, 0xf6, 0xb2, 0x7f,
17098
-	0x04, 0x0b, 0x91, 0xa8, 0x85, 0xc9, 0x0b, 0x16, 0xb2, 0x00, 0xa1, 0x9b, 0xa6, 0x2b, 0x0d, 0xe7,
17099
-	0xbf, 0xd5, 0x8f, 0x20, 0xc3, 0xa5, 0x2f, 0x9a, 0x9b, 0x83, 0x74, 0x83, 0xfd, 0x4a, 0xa0, 0x3c,
17100
-	0x64, 0x70, 0xb3, 0xda, 0xf8, 0x9e, 0x92, 0x44, 0x0a, 0x14, 0x1b, 0xad, 0x5e, 0xbd, 0xd3, 0x6e,
17101
-	0x37, 0xeb, 0xfd, 0x66, 0x43, 0x49, 0xa9, 0x77, 0x21, 0xd3, 0x1a, 0x32, 0xcd, 0xb7, 0xd9, 0x92,
17102
-	0xdf, 0x27, 0x2e, 0x71, 0x8c, 0x60, 0x27, 0x4d, 0x09, 0xea, 0x4f, 0x0b, 0x90, 0xd9, 0xa1, 0x63,
17103
-	0xc7, 0x47, 0x8f, 0x23, 0x61, 0x6b, 0x31, 0x3e, 0x43, 0xe0, 0xc0, 0x4a, 0x7f, 0x32, 0x22, 0x32,
17104
-	0xac, 0xdd, 0x84, 0xac, 0xd8, 0x1c, 0x72, 0x38, 0xb2, 0xc5, 0xe8, 0xbe, 0xee, 0x0e, 0x88, 0x2f,
17105
-	0xc7, 0x23, 0x5b, 0xe8, 0x7d, 0x76, 0x62, 0xe9, 0x26, 0x75, 0xec, 0x09, 0xdf, 0x43, 0x39, 0x71,
17106
-	0x2c, 0x61, 0xa2, 0x9b, 0x1d, 0xc7, 0x9e, 0xe0, 0x90, 0x8b, 0xb6, 0xa0, 0xb8, 0x67, 0x39, 0xa6,
17107
-	0x46, 0x47, 0x22, 0xc8, 0x67, 0x2e, 0xdf, 0x71, 0xc2, 0xaa, 0x9a, 0xe5, 0x98, 0x1d, 0x01, 0xc6,
17108
-	0x85, 0xbd, 0x69, 0x03, 0xb5, 0x61, 0xf1, 0x88, 0xda, 0xe3, 0x21, 0x09, 0x75, 0x65, 0xb9, 0xae,
17109
-	0xf7, 0x2e, 0xd7, 0xf5, 0x9c, 0xe3, 0x03, 0x6d, 0x0b, 0x47, 0xd1, 0x26, 0x7a, 0x06, 0x0b, 0xfe,
17110
-	0x70, 0xb4, 0xef, 0x85, 0xea, 0xe6, 0xb9, 0xba, 0xaf, 0x5c, 0xe1, 0x30, 0x06, 0x0f, 0xb4, 0x15,
17111
-	0xfd, 0x48, 0x0b, 0x6d, 0x42, 0xc1, 0xa0, 0x8e, 0x67, 0x79, 0x3e, 0x71, 0x8c, 0xc9, 0x6a, 0x8e,
17112
-	0xfb, 0xfe, 0x8a, 0x51, 0xd6, 0xa7, 0x60, 0x1c, 0x95, 0x2c, 0xfd, 0x56, 0x0a, 0x0a, 0x11, 0x17,
17113
-	0xa0, 0x1e, 0x14, 0x46, 0x2e, 0x1d, 0xe9, 0x03, 0x7e, 0xe2, 0xc9, 0x49, 0x7d, 0xf4, 0x46, 0xee,
17114
-	0xab, 0x74, 0xa7, 0x82, 0x38, 0xaa, 0x45, 0x3d, 0x4d, 0x42, 0x21, 0xc2, 0x44, 0xf7, 0x20, 0x87,
17115
-	0xbb, 0xb8, 0xf5, 0xbc, 0xda, 0x6f, 0x2a, 0x73, 0xa5, 0xdb, 0x27, 0xa7, 0xe5, 0x55, 0xae, 0x2d,
17116
-	0xaa, 0xa0, 0xeb, 0x5a, 0x47, 0x6c, 0x0d, 0xbf, 0x0f, 0xf3, 0x01, 0x34, 0x51, 0xfa, 0xf2, 0xc9,
17117
-	0x69, 0xf9, 0xad, 0x59, 0x68, 0x04, 0x89, 0x7b, 0x5b, 0x55, 0xdc, 0x6c, 0x28, 0xc9, 0x78, 0x24,
17118
-	0xee, 0x1d, 0xe8, 0x2e, 0x31, 0xd1, 0x57, 0x20, 0x2b, 0x81, 0xa9, 0x52, 0xe9, 0xe4, 0xb4, 0x7c,
17119
-	0x73, 0x16, 0x38, 0xc5, 0xe1, 0xde, 0x76, 0xf5, 0x79, 0x53, 0x49, 0xc7, 0xe3, 0x70, 0xcf, 0xd6,
17120
-	0x8f, 0x08, 0x7a, 0x17, 0x32, 0x02, 0x96, 0x29, 0xdd, 0x3a, 0x39, 0x2d, 0x7f, 0xe9, 0x35, 0x75,
17121
-	0x0c, 0x55, 0x5a, 0xfd, 0xdd, 0x3f, 0x5e, 0x9b, 0xfb, 0x9b, 0x3f, 0x59, 0x53, 0x66, 0xd9, 0xa5,
17122
-	0xff, 0x49, 0xc0, 0xc2, 0x85, 0xb5, 0x83, 0x54, 0xc8, 0x3a, 0xd4, 0xa0, 0x23, 0x71, 0x10, 0xe6,
17123
-	0x6a, 0x70, 0x7e, 0xb6, 0x9e, 0x6d, 0xd3, 0x3a, 0x1d, 0x4d, 0xb0, 0xe4, 0xa0, 0x67, 0x33, 0x47,
17124
-	0xf9, 0x93, 0x37, 0x5c, 0x98, 0xb1, 0x87, 0xf9, 0xc7, 0xb0, 0x60, 0xba, 0xd6, 0x11, 0x71, 0x35,
17125
-	0x83, 0x3a, 0xfb, 0xd6, 0x40, 0x1e, 0x72, 0xa5, 0xd8, 0x7c, 0x93, 0x03, 0x71, 0x51, 0x08, 0xd4,
17126
-	0x39, 0xfe, 0x0b, 0x1c, 0xe3, 0xa5, 0xe7, 0x50, 0x8c, 0x2e, 0x75, 0x76, 0x2e, 0x79, 0xd6, 0xaf,
17127
-	0x11, 0x99, 0x58, 0xf2, 0x34, 0x14, 0xe7, 0x19, 0x45, 0xa4, 0x95, 0xef, 0x41, 0x7a, 0x48, 0x4d,
17128
-	0xa1, 0x67, 0xa1, 0x76, 0x83, 0x65, 0x13, 0xff, 0x72, 0xb6, 0x5e, 0xa0, 0x5e, 0x65, 0xc3, 0xb2,
17129
-	0xc9, 0x0e, 0x35, 0x09, 0xe6, 0x00, 0xf5, 0x08, 0xd2, 0x2c, 0xe6, 0xa0, 0x2f, 0x43, 0xba, 0xd6,
17130
-	0x6a, 0x37, 0x94, 0xb9, 0xd2, 0xf2, 0xc9, 0x69, 0x79, 0x81, 0xbb, 0x84, 0x31, 0xd8, 0xda, 0x45,
17131
-	0xeb, 0x90, 0x7d, 0xde, 0xd9, 0xde, 0xdd, 0x61, 0xcb, 0xeb, 0xc6, 0xc9, 0x69, 0x79, 0x29, 0x64,
17132
-	0x0b, 0xa7, 0xa1, 0x3b, 0x90, 0xe9, 0xef, 0x74, 0x37, 0x7a, 0x4a, 0xb2, 0x84, 0x4e, 0x4e, 0xcb,
17133
-	0x8b, 0x21, 0x9f, 0xdb, 0x5c, 0x5a, 0x96, 0xb3, 0x9a, 0x0f, 0xe9, 0xea, 0x8f, 0x12, 0x50, 0x88,
17134
-	0x6c, 0x38, 0xb6, 0x30, 0x1b, 0xcd, 0x8d, 0xea, 0xee, 0x76, 0x5f, 0x99, 0x8b, 0x2c, 0xcc, 0x08,
17135
-	0xa4, 0x41, 0xf6, 0xf5, 0xb1, 0xcd, 0xe2, 0x1c, 0xd4, 0x3b, 0xed, 0x5e, 0xab, 0xd7, 0x6f, 0xb6,
17136
-	0xfb, 0x4a, 0xa2, 0xb4, 0x7a, 0x72, 0x5a, 0x5e, 0x99, 0x05, 0x6f, 0x8c, 0x6d, 0x9b, 0x2d, 0xcd,
17137
-	0x7a, 0xb5, 0xbe, 0xc5, 0xd7, 0xfa, 0x74, 0x69, 0x46, 0x50, 0x75, 0xdd, 0x38, 0x20, 0x26, 0xba,
17138
-	0x0f, 0xf9, 0x46, 0x73, 0xbb, 0xb9, 0x59, 0xe5, 0xd1, 0xbd, 0x74, 0xe7, 0xe4, 0xb4, 0x7c, 0xeb,
17139
-	0xf5, 0xde, 0x6d, 0x32, 0xd0, 0x7d, 0x62, 0xce, 0x2c, 0xd1, 0x08, 0x44, 0xfd, 0x59, 0x12, 0x16,
17140
-	0x30, 0x2b, 0x87, 0x5d, 0xbf, 0x4b, 0x6d, 0xcb, 0x98, 0xa0, 0x2e, 0xe4, 0x0d, 0xea, 0x98, 0x56,
17141
-	0x24, 0x4e, 0x3c, 0xbe, 0x24, 0x25, 0x9a, 0x4a, 0x05, 0xad, 0x7a, 0x20, 0x89, 0xa7, 0x4a, 0xd0,
17142
-	0x03, 0xc8, 0x98, 0xc4, 0xd6, 0x27, 0x32, 0x37, 0xbb, 0x55, 0x11, 0x05, 0x77, 0x25, 0x28, 0xb8,
17143
-	0x2b, 0x0d, 0x59, 0x70, 0x63, 0x81, 0xe3, 0x35, 0x88, 0xfe, 0x52, 0xd3, 0x7d, 0x9f, 0x0c, 0x47,
17144
-	0xbe, 0x48, 0xcc, 0xd2, 0xb8, 0x30, 0xd4, 0x5f, 0x56, 0x25, 0x09, 0x3d, 0x82, 0xec, 0xb1, 0xe5,
17145
-	0x98, 0xf4, 0x58, 0xe6, 0x5e, 0x57, 0x28, 0x95, 0x40, 0xf5, 0x84, 0xa5, 0x24, 0x33, 0x66, 0xb2,
17146
-	0x35, 0xd4, 0xee, 0xb4, 0x9b, 0xc1, 0x1a, 0x92, 0xfc, 0x8e, 0xd3, 0xa6, 0x0e, 0xdb, 0xff, 0xd0,
17147
-	0x69, 0x6b, 0x1b, 0xd5, 0xd6, 0xf6, 0x2e, 0x66, 0xeb, 0x68, 0xe5, 0xe4, 0xb4, 0xac, 0x84, 0x90,
17148
-	0x0d, 0xdd, 0xb2, 0x59, 0x31, 0x70, 0x0b, 0x52, 0xd5, 0xf6, 0xf7, 0x94, 0x64, 0x49, 0x39, 0x39,
17149
-	0x2d, 0x17, 0x43, 0x76, 0xd5, 0x99, 0x4c, 0xfd, 0x3e, 0xdb, 0xaf, 0xfa, 0xf7, 0x29, 0x28, 0xee,
17150
-	0x8e, 0x4c, 0xdd, 0x27, 0x62, 0x9f, 0xa1, 0x32, 0x14, 0x46, 0xba, 0xab, 0xdb, 0x36, 0xb1, 0x2d,
17151
-	0x6f, 0x28, 0xaf, 0x12, 0xa2, 0x24, 0xf4, 0xc1, 0x9b, 0xba, 0xb1, 0x96, 0x63, 0x7b, 0xe7, 0x07,
17152
-	0xff, 0xb6, 0x9e, 0x08, 0x1c, 0xba, 0x0b, 0x8b, 0xfb, 0xc2, 0x5a, 0x4d, 0x37, 0xf8, 0xc4, 0xa6,
17153
-	0xf8, 0xc4, 0x56, 0xe2, 0x26, 0x36, 0x6a, 0x56, 0x45, 0x0e, 0xb2, 0xca, 0xa5, 0xf0, 0xc2, 0x7e,
17154
-	0xb4, 0x89, 0x9e, 0xc0, 0xfc, 0x90, 0x3a, 0x96, 0x4f, 0xdd, 0xeb, 0x67, 0x21, 0x40, 0xa2, 0x7b,
17155
-	0xb0, 0xcc, 0x26, 0x37, 0xb0, 0x87, 0xb3, 0xf9, 0x71, 0x9e, 0xc4, 0x4b, 0x43, 0xfd, 0xa5, 0xec,
17156
-	0x10, 0x33, 0x32, 0xaa, 0x41, 0x86, 0xba, 0x2c, 0x5f, 0xcc, 0x72, 0x73, 0xef, 0x5f, 0x6b, 0xae,
17157
-	0x68, 0x74, 0x98, 0x0c, 0x16, 0xa2, 0xea, 0x37, 0x61, 0xe1, 0xc2, 0x20, 0x58, 0x9a, 0xd4, 0xad,
17158
-	0xee, 0xf6, 0x9a, 0xca, 0x1c, 0x2a, 0x42, 0xae, 0xde, 0x69, 0xf7, 0x5b, 0xed, 0x5d, 0x96, 0xe7,
17159
-	0x15, 0x21, 0x87, 0x3b, 0xdb, 0xdb, 0xb5, 0x6a, 0xfd, 0x99, 0x92, 0x54, 0x2b, 0x50, 0x88, 0x68,
17160
-	0x43, 0x8b, 0x00, 0xbd, 0x7e, 0xa7, 0xab, 0x6d, 0xb4, 0x70, 0xaf, 0x2f, 0xb2, 0xc4, 0x5e, 0xbf,
17161
-	0x8a, 0xfb, 0x92, 0x90, 0x50, 0xff, 0x33, 0x19, 0xcc, 0xa8, 0x4c, 0x0c, 0x6b, 0x17, 0x13, 0xc3,
17162
-	0x2b, 0x8c, 0x97, 0xa9, 0xe1, 0xb4, 0x11, 0x26, 0x88, 0x1f, 0x00, 0xf0, 0x85, 0x43, 0x4c, 0x4d,
17163
-	0xf7, 0xe5, 0xc4, 0x97, 0x5e, 0x73, 0x72, 0x3f, 0xb8, 0xd1, 0xc2, 0x79, 0x89, 0xae, 0xfa, 0xe8,
17164
-	0x5b, 0x50, 0x34, 0xe8, 0x70, 0x64, 0x13, 0x29, 0x9c, 0xba, 0x56, 0xb8, 0x10, 0xe2, 0xab, 0x7e,
17165
-	0x34, 0x35, 0x4d, 0x5f, 0x4c, 0x9e, 0x7f, 0x3b, 0x11, 0x78, 0x26, 0x26, 0x1b, 0x2d, 0x42, 0x6e,
17166
-	0xb7, 0xdb, 0xa8, 0xf6, 0x5b, 0xed, 0x4d, 0x25, 0x81, 0x00, 0xb2, 0xdc, 0xd5, 0x0d, 0x25, 0xc9,
17167
-	0xb2, 0xe8, 0x7a, 0x67, 0xa7, 0xbb, 0xdd, 0xe4, 0x11, 0x0b, 0xad, 0x80, 0x12, 0x38, 0x5b, 0xe3,
17168
-	0x8e, 0x6c, 0x36, 0x94, 0x34, 0xba, 0x01, 0x4b, 0x21, 0x55, 0x4a, 0x66, 0xd0, 0x4d, 0x40, 0x21,
17169
-	0x71, 0xaa, 0x22, 0xab, 0xfe, 0x06, 0x2c, 0xd5, 0xa9, 0xe3, 0xeb, 0x96, 0x13, 0x56, 0x18, 0x8f,
17170
-	0xd9, 0xa0, 0x25, 0x49, 0xb3, 0xe4, 0x4d, 0x50, 0x6d, 0xe9, 0xfc, 0x6c, 0xbd, 0x10, 0x42, 0x5b,
17171
-	0x0d, 0x9e, 0x2a, 0xc9, 0x86, 0xc9, 0xf6, 0xef, 0xc8, 0x32, 0xb9, 0x73, 0x33, 0xb5, 0xf9, 0xf3,
17172
-	0xb3, 0xf5, 0x54, 0xb7, 0xd5, 0xc0, 0x8c, 0x86, 0xbe, 0x0c, 0x79, 0xf2, 0xd2, 0xf2, 0x35, 0x83,
17173
-	0x9d, 0x4b, 0xcc, 0x81, 0x19, 0x9c, 0x63, 0x84, 0x3a, 0x3b, 0x86, 0x6a, 0x00, 0x5d, 0xea, 0xfa,
17174
-	0xb2, 0xe7, 0xaf, 0x43, 0x66, 0x44, 0x5d, 0x7e, 0x77, 0x71, 0xe9, 0x8d, 0x1a, 0x83, 0x8b, 0x85,
17175
-	0x8a, 0x05, 0x58, 0xfd, 0x83, 0x14, 0x40, 0x5f, 0xf7, 0x0e, 0xa5, 0x92, 0xa7, 0x90, 0x0f, 0x6f,
17176
-	0x27, 0xe5, 0x25, 0xc8, 0x95, 0xb3, 0x1d, 0x82, 0xd1, 0x93, 0x60, 0xb1, 0x89, 0xda, 0x29, 0xb6,
17177
-	0x88, 0x0d, 0x3a, 0x8a, 0x2b, 0x3f, 0x2e, 0x16, 0x48, 0xec, 0x98, 0x27, 0xae, 0x2b, 0x67, 0x9e,
17178
-	0xfd, 0x44, 0x75, 0x7e, 0x2c, 0x08, 0xa7, 0xc9, 0xec, 0x3b, 0xf6, 0xda, 0x67, 0x66, 0x46, 0xb6,
17179
-	0xe6, 0xf0, 0x54, 0x0e, 0x7d, 0x0c, 0x05, 0x36, 0x6e, 0xcd, 0xe3, 0x3c, 0x99, 0x78, 0x5f, 0xea,
17180
-	0x2a, 0xa1, 0x01, 0xc3, 0x68, 0xea, 0xe5, 0x3b, 0x00, 0xfa, 0x68, 0x64, 0x5b, 0xc4, 0xd4, 0xf6,
17181
-	0x26, 0x3c, 0xd3, 0xce, 0xe3, 0xbc, 0xa4, 0xd4, 0x26, 0x6c, 0xbb, 0x04, 0x6c, 0xdd, 0xe7, 0xd9,
17182
-	0xf3, 0x35, 0x0e, 0x94, 0xe8, 0xaa, 0x5f, 0x53, 0x60, 0xd1, 0x1d, 0x3b, 0xcc, 0xa1, 0xd2, 0x3a,
17183
-	0xf5, 0xcf, 0x93, 0xf0, 0x56, 0x9b, 0xf8, 0xc7, 0xd4, 0x3d, 0xac, 0xfa, 0xbe, 0x6e, 0x1c, 0x0c,
17184
-	0x89, 0x23, 0xa7, 0x2f, 0x52, 0xd0, 0x24, 0x2e, 0x14, 0x34, 0xab, 0x30, 0xaf, 0xdb, 0x96, 0xee,
17185
-	0x11, 0x91, 0xbc, 0xe5, 0x71, 0xd0, 0x64, 0x65, 0x17, 0x2b, 0xe2, 0x88, 0xe7, 0x11, 0x71, 0xaf,
17186
-	0xc2, 0x0c, 0x0f, 0x08, 0xe8, 0xfb, 0x70, 0x53, 0xa6, 0x69, 0x7a, 0xd8, 0x15, 0x2b, 0x28, 0x82,
17187
-	0x0b, 0xda, 0x66, 0x6c, 0x55, 0x19, 0x6f, 0x9c, 0xcc, 0xe3, 0xa6, 0xe4, 0xce, 0xc8, 0x97, 0x59,
17188
-	0xe1, 0x8a, 0x19, 0xc3, 0x2a, 0x6d, 0xc2, 0xad, 0x4b, 0x45, 0x3e, 0xd7, 0xbd, 0xcd, 0x3f, 0x25,
17189
-	0x01, 0x5a, 0xdd, 0xea, 0x8e, 0x74, 0x52, 0x03, 0xb2, 0xfb, 0xfa, 0xd0, 0xb2, 0x27, 0x57, 0x45,
17190
-	0xc0, 0x29, 0xbe, 0x52, 0x15, 0xee, 0xd8, 0xe0, 0x32, 0x58, 0xca, 0xf2, 0x9a, 0x72, 0xbc, 0xe7,
17191
-	0x10, 0x3f, 0xac, 0x29, 0x79, 0x8b, 0x99, 0xe1, 0xea, 0x4e, 0xb8, 0x74, 0x45, 0x83, 0x4d, 0x00,
17192
-	0x4b, 0x79, 0x8e, 0xf5, 0x49, 0x10, 0xb6, 0x64, 0x13, 0x6d, 0xf1, 0xdb, 0x51, 0xe2, 0x1e, 0x11,
17193
-	0x73, 0x35, 0xc3, 0x9d, 0x7a, 0x9d, 0x3d, 0x58, 0xc2, 0x85, 0xef, 0x42, 0xe9, 0xd2, 0x47, 0x3c,
17194
-	0x65, 0x9a, 0xb2, 0x3e, 0x97, 0x8f, 0x1e, 0xc2, 0xc2, 0x85, 0x71, 0xbe, 0x56, 0xcc, 0xb7, 0xba,
17195
-	0xcf, 0xbf, 0xae, 0xa4, 0xe5, 0xaf, 0x6f, 0x2a, 0x59, 0xf5, 0x4f, 0x53, 0x22, 0xd0, 0x48, 0xaf,
17196
-	0xc6, 0xbf, 0x0a, 0xe4, 0xf8, 0xea, 0x36, 0xa8, 0x2d, 0x03, 0xc0, 0x7b, 0x57, 0xc7, 0x1f, 0x56,
17197
-	0xd3, 0x71, 0x38, 0x0e, 0x05, 0xd1, 0x3a, 0x14, 0xc4, 0x2a, 0xd6, 0xd8, 0x86, 0xe3, 0x6e, 0x5d,
17198
-	0xc0, 0x20, 0x48, 0x4c, 0x12, 0xdd, 0x85, 0x45, 0x7e, 0xf9, 0xe3, 0x1d, 0x10, 0x53, 0x60, 0xd2,
17199
-	0x1c, 0xb3, 0x10, 0x52, 0x39, 0x6c, 0x07, 0x8a, 0x92, 0xa0, 0xf1, 0x7c, 0x3e, 0xc3, 0x0d, 0xba,
17200
-	0x77, 0x9d, 0x41, 0x42, 0x84, 0xa7, 0xf9, 0x85, 0xd1, 0xb4, 0xa1, 0x36, 0x20, 0x17, 0x18, 0x8b,
17201
-	0x56, 0x21, 0xd5, 0xaf, 0x77, 0x95, 0xb9, 0xd2, 0xd2, 0xc9, 0x69, 0xb9, 0x10, 0x90, 0xfb, 0xf5,
17202
-	0x2e, 0xe3, 0xec, 0x36, 0xba, 0x4a, 0xe2, 0x22, 0x67, 0xb7, 0xd1, 0x2d, 0xa5, 0x59, 0x0e, 0xa6,
17203
-	0xee, 0x43, 0x21, 0xd2, 0x03, 0x7a, 0x07, 0xe6, 0x5b, 0xed, 0x4d, 0xdc, 0xec, 0xf5, 0x94, 0xb9,
17204
-	0xd2, 0xcd, 0x93, 0xd3, 0x32, 0x8a, 0x70, 0x5b, 0xce, 0x80, 0xcd, 0x0f, 0xba, 0x03, 0xe9, 0xad,
17205
-	0x0e, 0x3b, 0xdb, 0x45, 0x01, 0x11, 0x41, 0x6c, 0x51, 0xcf, 0x2f, 0xdd, 0x90, 0xc9, 0x5d, 0x54,
17206
-	0xb1, 0xfa, 0x87, 0x09, 0xc8, 0x8a, 0xcd, 0x14, 0x3b, 0x51, 0x55, 0x98, 0x0f, 0xae, 0x09, 0x44,
17207
-	0x71, 0xf7, 0xde, 0xe5, 0x85, 0x58, 0x45, 0xd6, 0x4d, 0x62, 0xf9, 0x05, 0x72, 0xa5, 0x0f, 0xa1,
17208
-	0x18, 0x65, 0x7c, 0xae, 0xc5, 0xf7, 0x7d, 0x28, 0xb0, 0xf5, 0x1d, 0x14, 0x64, 0x8f, 0x21, 0x2b,
17209
-	0x02, 0x42, 0x78, 0xd6, 0x5c, 0x5e, 0x15, 0x4a, 0x24, 0x7a, 0x0a, 0xf3, 0xa2, 0x92, 0x0c, 0x6e,
17210
-	0x87, 0xd7, 0xae, 0xde, 0x45, 0x38, 0x80, 0xab, 0x1f, 0x43, 0xba, 0x4b, 0x88, 0xcb, 0x7c, 0xef,
17211
-	0x50, 0x93, 0x4c, 0x8f, 0x67, 0x59, 0x04, 0x9b, 0xa4, 0xd5, 0x60, 0x45, 0xb0, 0x49, 0x5a, 0x66,
17212
-	0x78, 0xff, 0x95, 0x8c, 0xdc, 0x7f, 0xf5, 0xa1, 0xf8, 0x82, 0x58, 0x83, 0x03, 0x9f, 0x98, 0x5c,
17213
-	0xd1, 0x7d, 0x48, 0x8f, 0x48, 0x68, 0xfc, 0x6a, 0xec, 0x02, 0x23, 0xc4, 0xc5, 0x1c, 0xc5, 0xe2,
17214
-	0xc8, 0x31, 0x97, 0x96, 0x4f, 0x1a, 0xb2, 0xa5, 0xfe, 0x63, 0x12, 0x16, 0x5b, 0x9e, 0x37, 0xd6,
17215
-	0x1d, 0x23, 0xc8, 0xdc, 0xbe, 0x7d, 0x31, 0x73, 0x8b, 0x7d, 0xfb, 0xb9, 0x28, 0x72, 0xf1, 0x5a,
17216
-	0x4f, 0x9e, 0x9e, 0xc9, 0xf0, 0xf4, 0x54, 0x7f, 0x9a, 0x08, 0xee, 0xee, 0xee, 0x46, 0xb6, 0xbb,
17217
-	0xa8, 0x03, 0xa3, 0x9a, 0xc8, 0xae, 0x73, 0xe8, 0xd0, 0x63, 0x07, 0xbd, 0x0d, 0x19, 0xdc, 0x6c,
17218
-	0x37, 0x5f, 0x28, 0x09, 0xb1, 0x3c, 0x2f, 0x80, 0x30, 0x71, 0xc8, 0x31, 0xd3, 0xd4, 0x6d, 0xb6,
17219
-	0x1b, 0x2c, 0xd3, 0x4a, 0xc6, 0x68, 0xea, 0x12, 0xc7, 0xb4, 0x9c, 0x01, 0x7a, 0x07, 0xb2, 0xad,
17220
-	0x5e, 0x6f, 0x97, 0x97, 0x89, 0x6f, 0x9d, 0x9c, 0x96, 0x6f, 0x5c, 0x40, 0xf1, 0x7b, 0x5b, 0x93,
17221
-	0x81, 0x58, 0x99, 0xc3, 0x72, 0xb0, 0x18, 0x10, 0xcb, 0x9f, 0x05, 0x08, 0x77, 0xfa, 0xd5, 0x7e,
17222
-	0x53, 0xc9, 0xc4, 0x80, 0x30, 0x65, 0x7f, 0xe5, 0x76, 0xfb, 0xd7, 0x24, 0x28, 0x55, 0xc3, 0x20,
17223
-	0x23, 0x9f, 0xf1, 0x65, 0x65, 0xd9, 0x87, 0xdc, 0x88, 0xfd, 0xb2, 0x48, 0x90, 0x25, 0x3d, 0x8d,
17224
-	0x7d, 0xbd, 0x9c, 0x91, 0xab, 0x60, 0x6a, 0x93, 0xaa, 0x39, 0xb4, 0x3c, 0xcf, 0xa2, 0x8e, 0xa0,
17225
-	0xe1, 0x50, 0x53, 0xe9, 0xbf, 0x12, 0x70, 0x23, 0x06, 0x81, 0x1e, 0x42, 0xda, 0xa5, 0x76, 0x30,
17226
-	0x87, 0xb7, 0x2f, 0xbb, 0x96, 0x65, 0xa2, 0x98, 0x23, 0xd1, 0x1a, 0x80, 0x3e, 0xf6, 0xa9, 0xce,
17227
-	0xfb, 0xe7, 0xb3, 0x97, 0xc3, 0x11, 0x0a, 0x7a, 0x01, 0x59, 0x8f, 0x18, 0x2e, 0x09, 0x72, 0xe9,
17228
-	0x8f, 0xff, 0xbf, 0xd6, 0x57, 0x7a, 0x5c, 0x0d, 0x96, 0xea, 0x4a, 0x15, 0xc8, 0x0a, 0x0a, 0x5b,
17229
-	0xf6, 0xa6, 0xee, 0xeb, 0xf2, 0xd2, 0x9e, 0xff, 0x66, 0xab, 0x49, 0xb7, 0x07, 0xc1, 0x6a, 0xd2,
17230
-	0xed, 0x81, 0xfa, 0x77, 0x49, 0x80, 0xe6, 0x4b, 0x9f, 0xb8, 0x8e, 0x6e, 0xd7, 0xab, 0xa8, 0x19,
17231
-	0x89, 0xfe, 0x62, 0xb4, 0x5f, 0x8d, 0x7d, 0x89, 0x08, 0x25, 0x2a, 0xf5, 0x6a, 0x4c, 0xfc, 0xbf,
17232
-	0x05, 0xa9, 0xb1, 0x2b, 0x1f, 0xa4, 0x45, 0x1e, 0xbc, 0x8b, 0xb7, 0x31, 0xa3, 0xa1, 0xe6, 0x34,
17233
-	0x6c, 0xa5, 0x2e, 0x7f, 0x76, 0x8e, 0x74, 0x10, 0x1b, 0xba, 0xd8, 0xce, 0x37, 0x74, 0xcd, 0x20,
17234
-	0xf2, 0xe4, 0x28, 0x8a, 0x9d, 0x5f, 0xaf, 0xd6, 0x89, 0xeb, 0xe3, 0xac, 0xa1, 0xb3, 0xff, 0x5f,
17235
-	0x28, 0xbe, 0xdd, 0x07, 0x98, 0x0e, 0x0d, 0xad, 0x41, 0xa6, 0xbe, 0xd1, 0xeb, 0x6d, 0x2b, 0x73,
17236
-	0x22, 0x80, 0x4f, 0x59, 0x9c, 0xac, 0xfe, 0x75, 0x12, 0x72, 0xf5, 0xaa, 0x3c, 0x56, 0xeb, 0xa0,
17237
-	0xf0, 0xa8, 0xc4, 0x9f, 0x3a, 0xc8, 0xcb, 0x91, 0xe5, 0x4e, 0x64, 0x60, 0xb9, 0xa2, 0xa8, 0x5d,
17238
-	0x64, 0x22, 0xcc, 0xea, 0x26, 0x17, 0x40, 0x18, 0x8a, 0x44, 0x3a, 0x41, 0x33, 0xf4, 0x20, 0xc6,
17239
-	0xaf, 0x5d, 0xed, 0x2c, 0x51, 0x9e, 0x4c, 0xdb, 0x1e, 0x2e, 0x04, 0x4a, 0xea, 0xba, 0x87, 0x3e,
17240
-	0x80, 0x25, 0xcf, 0x1a, 0x38, 0x96, 0x33, 0xd0, 0x02, 0xe7, 0xf1, 0x77, 0x97, 0xda, 0xf2, 0xf9,
17241
-	0xd9, 0xfa, 0x42, 0x4f, 0xb0, 0xa4, 0x0f, 0x17, 0x24, 0xb2, 0xce, 0x5d, 0x89, 0xbe, 0x09, 0x8b,
17242
-	0x11, 0x51, 0xe6, 0x45, 0xe1, 0x76, 0xe5, 0xfc, 0x6c, 0xbd, 0x18, 0x4a, 0x3e, 0x23, 0x13, 0x5c,
17243
-	0x0c, 0x05, 0x9f, 0x11, 0x7e, 0xff, 0xb2, 0x4f, 0x5d, 0x83, 0x68, 0x2e, 0xdf, 0xd3, 0xfc, 0x04,
17244
-	0x4f, 0xe3, 0x02, 0xa7, 0x89, 0x6d, 0xae, 0x3e, 0x87, 0x1b, 0x1d, 0xd7, 0x38, 0x20, 0x9e, 0x2f,
17245
-	0x5c, 0x21, 0xbd, 0xf8, 0x31, 0xdc, 0xf6, 0x75, 0xef, 0x50, 0x3b, 0xb0, 0x3c, 0x9f, 0xba, 0x13,
17246
-	0xcd, 0x25, 0x3e, 0x71, 0x18, 0x5f, 0xe3, 0x8f, 0xb5, 0xf2, 0xd2, 0xef, 0x16, 0xc3, 0x6c, 0x09,
17247
-	0x08, 0x0e, 0x10, 0xdb, 0x0c, 0xa0, 0xb6, 0xa0, 0xc8, 0xca, 0x14, 0x79, 0x71, 0xc6, 0x46, 0x0f,
17248
-	0x36, 0x1d, 0x68, 0x6f, 0x7c, 0x4c, 0xe5, 0x6d, 0x3a, 0x10, 0x3f, 0xd5, 0xef, 0x82, 0xd2, 0xb0,
17249
-	0xbc, 0x91, 0xee, 0x1b, 0x07, 0xc1, 0x6d, 0x26, 0x6a, 0x80, 0x72, 0x40, 0x74, 0xd7, 0xdf, 0x23,
17250
-	0xba, 0xaf, 0x8d, 0x88, 0x6b, 0x51, 0xf3, 0xfa, 0x59, 0x5e, 0x0a, 0x45, 0xba, 0x5c, 0x42, 0xfd,
17251
-	0xef, 0x04, 0x00, 0xd6, 0xf7, 0x83, 0x8c, 0xec, 0x6b, 0xb0, 0xec, 0x39, 0xfa, 0xc8, 0x3b, 0xa0,
17252
-	0xbe, 0x66, 0x39, 0x3e, 0x71, 0x8f, 0x74, 0x5b, 0x5e, 0xe0, 0x28, 0x01, 0xa3, 0x25, 0xe9, 0xe8,
17253
-	0x3e, 0xa0, 0x43, 0x42, 0x46, 0x1a, 0xb5, 0x4d, 0x2d, 0x60, 0x8a, 0xa7, 0xe4, 0x34, 0x56, 0x18,
17254
-	0xa7, 0x63, 0x9b, 0xbd, 0x80, 0x8e, 0x6a, 0xb0, 0xc6, 0x86, 0x4f, 0x1c, 0xdf, 0xb5, 0x88, 0xa7,
17255
-	0xed, 0x53, 0x57, 0xf3, 0x6c, 0x7a, 0xac, 0xed, 0x53, 0xdb, 0xa6, 0xc7, 0xc4, 0x0d, 0xee, 0xc6,
17256
-	0x4a, 0x36, 0x1d, 0x34, 0x05, 0x68, 0x83, 0xba, 0x3d, 0x9b, 0x1e, 0x6f, 0x04, 0x08, 0x96, 0xb6,
17257
-	0x4d, 0xc7, 0xec, 0x5b, 0xc6, 0x61, 0x90, 0xb6, 0x85, 0xd4, 0xbe, 0x65, 0x1c, 0xa2, 0x77, 0x60,
17258
-	0x81, 0xd8, 0x84, 0x5f, 0x91, 0x08, 0x54, 0x86, 0xa3, 0x8a, 0x01, 0x91, 0x81, 0xd4, 0x4f, 0x40,
17259
-	0x69, 0x3a, 0x86, 0x3b, 0x19, 0x45, 0xe6, 0xfc, 0x3e, 0x20, 0x16, 0x24, 0x35, 0x9b, 0x1a, 0x87,
17260
-	0xda, 0x50, 0x77, 0xf4, 0x01, 0xb3, 0x4b, 0xbc, 0xf0, 0x29, 0x8c, 0xb3, 0x4d, 0x8d, 0xc3, 0x1d,
17261
-	0x49, 0x57, 0x3f, 0x00, 0xe8, 0x8d, 0x5c, 0xa2, 0x9b, 0x1d, 0x96, 0x4d, 0x30, 0xd7, 0xf1, 0x96,
17262
-	0x66, 0xca, 0x17, 0x52, 0xea, 0xca, 0xad, 0xae, 0x08, 0x46, 0x23, 0xa4, 0xab, 0xbf, 0x0c, 0x37,
17263
-	0xba, 0xb6, 0x6e, 0xf0, 0xaf, 0x05, 0xba, 0xe1, 0x93, 0x15, 0x7a, 0x0a, 0x59, 0x01, 0x95, 0x33,
17264
-	0x19, 0xbb, 0xdd, 0xa6, 0x7d, 0x6e, 0xcd, 0x61, 0x89, 0xaf, 0x15, 0x01, 0xa6, 0x7a, 0xd4, 0xbf,
17265
-	0x4c, 0x40, 0x3e, 0xd4, 0x8f, 0xca, 0xe2, 0x25, 0xc6, 0x77, 0x75, 0xcb, 0x91, 0x55, 0x7d, 0x1e,
17266
-	0x47, 0x49, 0xa8, 0x05, 0x85, 0x51, 0x28, 0x7d, 0x65, 0x3e, 0x17, 0x63, 0x35, 0x8e, 0xca, 0xa2,
17267
-	0x0f, 0x21, 0x1f, 0x3c, 0x49, 0x07, 0x11, 0xf6, 0xea, 0x17, 0xec, 0x29, 0x5c, 0xfd, 0x36, 0xc0,
17268
-	0x77, 0xa8, 0xe5, 0xf4, 0xe9, 0x21, 0x71, 0xf8, 0x13, 0x2b, 0xab, 0x09, 0x49, 0xe0, 0x45, 0xd9,
17269
-	0xe2, 0xa5, 0xbe, 0x98, 0x82, 0xf0, 0xa5, 0x51, 0x34, 0xd5, 0xbf, 0x4d, 0x42, 0x16, 0x53, 0xea,
17270
-	0xd7, 0xab, 0xa8, 0x0c, 0x59, 0x19, 0x27, 0xf8, 0xf9, 0x53, 0xcb, 0x9f, 0x9f, 0xad, 0x67, 0x44,
17271
-	0x80, 0xc8, 0x18, 0x3c, 0x32, 0x44, 0x22, 0x78, 0xf2, 0xb2, 0x08, 0x8e, 0x1e, 0x42, 0x51, 0x82,
17272
-	0xb4, 0x03, 0xdd, 0x3b, 0x10, 0x05, 0x5a, 0x6d, 0xf1, 0xfc, 0x6c, 0x1d, 0x04, 0x72, 0x4b, 0xf7,
17273
-	0x0e, 0x30, 0x08, 0x34, 0xfb, 0x8d, 0x9a, 0x50, 0xf8, 0x94, 0x5a, 0x8e, 0xe6, 0xf3, 0x41, 0xc8,
17274
-	0xcb, 0xc4, 0xd8, 0x79, 0x9c, 0x0e, 0x55, 0x7e, 0x6f, 0x00, 0x9f, 0x4e, 0x07, 0xdf, 0x84, 0x05,
17275
-	0x97, 0x52, 0x5f, 0x84, 0x2d, 0x8b, 0x3a, 0xf2, 0x9e, 0xa2, 0x1c, 0x7b, 0x7d, 0x4d, 0xa9, 0x8f,
17276
-	0x25, 0x0e, 0x17, 0xdd, 0x48, 0x0b, 0x3d, 0x84, 0x15, 0x5b, 0xf7, 0x7c, 0x8d, 0xc7, 0x3b, 0x73,
17277
-	0xaa, 0x2d, 0xcb, 0xb7, 0x1a, 0x62, 0xbc, 0x0d, 0xce, 0x0a, 0x24, 0xd4, 0x7f, 0x4e, 0x40, 0x81,
17278
-	0x0d, 0xc6, 0xda, 0xb7, 0x0c, 0x96, 0xe4, 0x7d, 0xfe, 0xdc, 0xe3, 0x16, 0xa4, 0x0c, 0xcf, 0x95,
17279
-	0x4e, 0xe5, 0x87, 0x6f, 0xbd, 0x87, 0x31, 0xa3, 0xa1, 0x4f, 0x20, 0x2b, 0xef, 0x4b, 0x44, 0xda,
17280
-	0xa1, 0x5e, 0x9f, 0x8e, 0x4a, 0xdf, 0x48, 0x39, 0xbe, 0x96, 0xa7, 0xd6, 0x89, 0x43, 0x00, 0x47,
17281
-	0x49, 0xe8, 0x26, 0x24, 0x0d, 0xe1, 0x2e, 0xf9, 0x41, 0x4b, 0xbd, 0x8d, 0x93, 0x86, 0xa3, 0xfe,
17282
-	0x28, 0x01, 0x0b, 0xd3, 0x0d, 0xcf, 0x56, 0xc0, 0x6d, 0xc8, 0x7b, 0xe3, 0x3d, 0x6f, 0xe2, 0xf9,
17283
-	0x64, 0x18, 0x3c, 0x1f, 0x87, 0x04, 0xd4, 0x82, 0xbc, 0x6e, 0x0f, 0xa8, 0x6b, 0xf9, 0x07, 0x43,
17284
-	0x59, 0x89, 0xc6, 0xa7, 0x0a, 0x51, 0x9d, 0x95, 0x6a, 0x20, 0x82, 0xa7, 0xd2, 0xc1, 0xb9, 0x2f,
17285
-	0xbe, 0x31, 0xe0, 0xe7, 0xfe, 0xdb, 0x50, 0xb4, 0xf5, 0x21, 0xbf, 0x40, 0xf2, 0xad, 0xa1, 0x18,
17286
-	0x47, 0x1a, 0x17, 0x24, 0xad, 0x6f, 0x0d, 0x89, 0xaa, 0x42, 0x3e, 0x54, 0x86, 0x96, 0xa0, 0x50,
17287
-	0x6d, 0xf6, 0xb4, 0x47, 0x8f, 0x9f, 0x6a, 0x9b, 0xf5, 0x1d, 0x65, 0x4e, 0xe6, 0xa6, 0x7f, 0x95,
17288
-	0x80, 0x05, 0x19, 0x8e, 0x64, 0xbe, 0xff, 0x0e, 0xcc, 0xbb, 0xfa, 0xbe, 0x1f, 0x54, 0x24, 0x69,
17289
-	0xb1, 0xaa, 0x59, 0x84, 0x67, 0x15, 0x09, 0x63, 0xc5, 0x57, 0x24, 0x91, 0x0f, 0x1a, 0x52, 0x57,
17290
-	0x7e, 0xd0, 0x90, 0xfe, 0xb9, 0x7c, 0xd0, 0xa0, 0xfe, 0x26, 0xc0, 0x86, 0x65, 0x93, 0xbe, 0xb8,
17291
-	0x6b, 0x8a, 0xab, 0x2f, 0x59, 0x0e, 0x27, 0xef, 0x32, 0x83, 0x1c, 0xae, 0xd5, 0xc0, 0x8c, 0xc6,
17292
-	0x58, 0x03, 0xcb, 0x94, 0x9b, 0x91, 0xb3, 0x36, 0x19, 0x6b, 0x60, 0x99, 0xe1, 0xcb, 0x5b, 0xfa,
17293
-	0xba, 0x97, 0xb7, 0xd3, 0x04, 0x2c, 0xc9, 0xdc, 0x35, 0x0c, 0xbf, 0x5f, 0x85, 0xbc, 0x48, 0x63,
17294
-	0xa7, 0x05, 0x1d, 0x7f, 0xc4, 0x17, 0xb8, 0x56, 0x03, 0xe7, 0x04, 0xbb, 0x65, 0xa2, 0x75, 0x28,
17295
-	0x48, 0x68, 0xe4, 0xe3, 0x27, 0x10, 0xa4, 0x36, 0x33, 0xff, 0xeb, 0x90, 0xde, 0xb7, 0x6c, 0x22,
17296
-	0x17, 0x7a, 0x6c, 0x00, 0x98, 0x3a, 0x60, 0x6b, 0x0e, 0x73, 0x74, 0x2d, 0x17, 0x5c, 0xc6, 0x71,
17297
-	0xfb, 0x64, 0xd9, 0x19, 0xb5, 0x4f, 0x54, 0xa0, 0x33, 0xf6, 0x09, 0x1c, 0xb3, 0x4f, 0xb0, 0x85,
17298
-	0x7d, 0x12, 0x1a, 0xb5, 0x4f, 0x90, 0x7e, 0x2e, 0xf6, 0x6d, 0xc3, 0xcd, 0x9a, 0xad, 0x1b, 0x87,
17299
-	0xb6, 0xe5, 0xf9, 0xc4, 0x8c, 0x46, 0x8c, 0xc7, 0x90, 0xbd, 0x90, 0x74, 0x5e, 0x75, 0x6b, 0x29,
17300
-	0x91, 0xea, 0x7f, 0x24, 0xa0, 0xb8, 0x45, 0x74, 0xdb, 0x3f, 0x98, 0x5e, 0x0d, 0xf9, 0xc4, 0xf3,
17301
-	0xe5, 0x61, 0xc5, 0x7f, 0xa3, 0x6f, 0x40, 0x2e, 0xcc, 0x49, 0xae, 0x7d, 0x7f, 0x0b, 0xa1, 0xe8,
17302
-	0x09, 0xcc, 0xb3, 0x3d, 0x46, 0xc7, 0x41, 0xb1, 0x73, 0xd5, 0xd3, 0x8e, 0x44, 0xb2, 0x43, 0xc6,
17303
-	0x25, 0x3c, 0x09, 0xe1, 0x4b, 0x29, 0x83, 0x83, 0x26, 0xfa, 0x45, 0x28, 0xf2, 0x97, 0x89, 0x20,
17304
-	0xe7, 0xca, 0x5c, 0xa7, 0xb3, 0x20, 0x1e, 0x17, 0x45, 0xbe, 0xf5, 0xbf, 0x09, 0x58, 0xd9, 0xd1,
17305
-	0x27, 0x7b, 0x44, 0x86, 0x0d, 0x62, 0x62, 0x62, 0x50, 0xd7, 0x44, 0xdd, 0x68, 0xb8, 0xb9, 0xe2,
17306
-	0xad, 0x32, 0x4e, 0x38, 0x3e, 0xea, 0x04, 0x05, 0x58, 0x32, 0x52, 0x80, 0xad, 0x40, 0xc6, 0xa1,
17307
-	0x8e, 0x41, 0x64, 0x2c, 0x12, 0x0d, 0xd5, 0x8a, 0x86, 0x9a, 0x52, 0xf8, 0x8c, 0xc8, 0x1f, 0x01,
17308
-	0xdb, 0xd4, 0x0f, 0x7b, 0x43, 0x9f, 0x40, 0xa9, 0xd7, 0xac, 0xe3, 0x66, 0xbf, 0xd6, 0xf9, 0xae,
17309
-	0xd6, 0xab, 0x6e, 0xf7, 0xaa, 0x8f, 0x1f, 0x6a, 0xdd, 0xce, 0xf6, 0xf7, 0x1e, 0x3d, 0x79, 0xf8,
17310
-	0x0d, 0x25, 0x51, 0x2a, 0x9f, 0x9c, 0x96, 0x6f, 0xb7, 0xab, 0xf5, 0x6d, 0xb1, 0x63, 0xf6, 0xe8,
17311
-	0xcb, 0x9e, 0x6e, 0x7b, 0xfa, 0xe3, 0x87, 0x5d, 0x6a, 0x4f, 0x18, 0x86, 0x2d, 0xeb, 0x62, 0xf4,
17312
-	0xbc, 0x8a, 0x1e, 0xc3, 0x89, 0x4b, 0x8f, 0xe1, 0xe9, 0x69, 0x9e, 0xbc, 0xe4, 0x34, 0xdf, 0x80,
17313
-	0x15, 0xc3, 0xa5, 0x9e, 0xa7, 0xb1, 0xec, 0x9f, 0x98, 0x33, 0xf5, 0xc5, 0x97, 0xce, 0xcf, 0xd6,
17314
-	0x97, 0xeb, 0x8c, 0xdf, 0xe3, 0x6c, 0xa9, 0x7e, 0xd9, 0x88, 0x90, 0x78, 0x4f, 0xea, 0x1f, 0xa5,
17315
-	0x58, 0x22, 0x65, 0x1d, 0x59, 0x36, 0x19, 0x10, 0x0f, 0x3d, 0x87, 0x25, 0xc3, 0x25, 0x26, 0x4b,
17316
-	0xeb, 0x75, 0x3b, 0xfa, 0x11, 0xed, 0x2f, 0xc4, 0xe6, 0x34, 0xa1, 0x60, 0xa5, 0x1e, 0x4a, 0xf5,
17317
-	0x46, 0xc4, 0xc0, 0x8b, 0xc6, 0x85, 0x36, 0xfa, 0x14, 0x96, 0x3c, 0x62, 0x5b, 0xce, 0xf8, 0xa5,
17318
-	0x66, 0x50, 0xc7, 0x27, 0x2f, 0x83, 0x17, 0xb1, 0xeb, 0xf4, 0xf6, 0x9a, 0xdb, 0x4c, 0xaa, 0x2e,
17319
-	0x84, 0x6a, 0xe8, 0xfc, 0x6c, 0x7d, 0xf1, 0x22, 0x0d, 0x2f, 0x4a, 0xcd, 0xb2, 0x5d, 0x6a, 0xc3,
17320
-	0xe2, 0x45, 0x6b, 0xd0, 0x8a, 0xdc, 0xfb, 0x3c, 0x84, 0x04, 0x7b, 0x1b, 0xdd, 0x86, 0x9c, 0x4b,
17321
-	0x06, 0x96, 0xe7, 0xbb, 0xc2, 0xcd, 0x8c, 0x13, 0x52, 0xd8, 0xce, 0x17, 0x5f, 0x40, 0x95, 0x7e,
17322
-	0x1d, 0x66, 0x7a, 0x64, 0x9b, 0xc5, 0xb4, 0x3c, 0x7d, 0x4f, 0xaa, 0xcc, 0xe1, 0xa0, 0xc9, 0xd6,
17323
-	0xe0, 0xd8, 0x0b, 0x13, 0x35, 0xfe, 0x9b, 0xd1, 0x78, 0x46, 0x21, 0xbf, 0x07, 0xe3, 0x39, 0x43,
17324
-	0xf0, 0x61, 0x69, 0x3a, 0xf2, 0x61, 0xe9, 0x0a, 0x64, 0x6c, 0x72, 0x44, 0x6c, 0x71, 0x96, 0x63,
17325
-	0xd1, 0xb8, 0xf7, 0x10, 0x8a, 0xc1, 0x17, 0x8c, 0xfc, 0xcb, 0x89, 0x1c, 0xa4, 0xfb, 0xd5, 0xde,
17326
-	0x33, 0x65, 0x0e, 0x01, 0x64, 0xc5, 0xe2, 0x14, 0xaf, 0x75, 0xf5, 0x4e, 0x7b, 0xa3, 0xb5, 0xa9,
17327
-	0x24, 0xef, 0xfd, 0x2c, 0x05, 0xf9, 0xf0, 0xbd, 0x88, 0x9d, 0x1d, 0xed, 0xe6, 0x8b, 0x60, 0x75,
17328
-	0x87, 0xf4, 0x36, 0x39, 0x46, 0x6f, 0x4f, 0x6f, 0xa1, 0x3e, 0x11, 0x0f, 0xe4, 0x21, 0x3b, 0xb8,
17329
-	0x81, 0x7a, 0x17, 0x72, 0xd5, 0x5e, 0xaf, 0xb5, 0xd9, 0x6e, 0x36, 0x94, 0xcf, 0x12, 0xa5, 0x2f,
17330
-	0x9d, 0x9c, 0x96, 0x97, 0x43, 0x50, 0xd5, 0x13, 0x8b, 0x8f, 0xa3, 0xea, 0xf5, 0x66, 0xb7, 0xdf,
17331
-	0x6c, 0x28, 0xaf, 0x92, 0xb3, 0x28, 0x7e, 0xab, 0xc2, 0x3f, 0xdd, 0xc9, 0x77, 0x71, 0xb3, 0x5b,
17332
-	0xc5, 0xac, 0xc3, 0xcf, 0x92, 0xe2, 0x72, 0x6c, 0xda, 0xa3, 0x4b, 0x46, 0xba, 0xcb, 0xfa, 0x5c,
17333
-	0x0b, 0xbe, 0x85, 0x7b, 0x95, 0x12, 0x9f, 0x77, 0x4c, 0x1f, 0xbf, 0x88, 0x6e, 0x4e, 0x58, 0x6f,
17334
-	0xfc, 0xd5, 0x91, 0xab, 0x49, 0xcd, 0xf4, 0xd6, 0x63, 0xb1, 0x87, 0x69, 0x51, 0x61, 0x1e, 0xef,
17335
-	0xb6, 0xdb, 0x0c, 0xf4, 0x2a, 0x3d, 0x33, 0x3a, 0x3c, 0x76, 0x58, 0xc5, 0x8c, 0xee, 0x42, 0x2e,
17336
-	0x78, 0x94, 0x54, 0x3e, 0x4b, 0xcf, 0x18, 0x54, 0x0f, 0x5e, 0x54, 0x79, 0x87, 0x5b, 0xbb, 0x7d,
17337
-	0xfe, 0xa9, 0xde, 0xab, 0xcc, 0x6c, 0x87, 0x07, 0x63, 0xdf, 0xa4, 0xc7, 0x0e, 0xdb, 0xb3, 0xf2,
17338
-	0x1e, 0xee, 0xb3, 0x8c, 0xb8, 0xb4, 0x08, 0x31, 0xf2, 0x12, 0xee, 0x5d, 0xc8, 0xe1, 0xe6, 0x77,
17339
-	0xc4, 0x57, 0x7d, 0xaf, 0xb2, 0x33, 0x7a, 0x30, 0xf9, 0x94, 0x18, 0xb2, 0xb7, 0x0e, 0xee, 0x6e,
17340
-	0x55, 0xb9, 0xcb, 0x67, 0x51, 0x1d, 0x77, 0x74, 0xa0, 0x3b, 0xc4, 0x9c, 0x7e, 0xe3, 0x12, 0xb2,
17341
-	0xee, 0xfd, 0x0a, 0xe4, 0x82, 0xcc, 0x14, 0xad, 0x41, 0xf6, 0x45, 0x07, 0x3f, 0x6b, 0x62, 0x65,
17342
-	0x4e, 0xf8, 0x30, 0xe0, 0xbc, 0x10, 0x35, 0x45, 0x19, 0xe6, 0x77, 0xaa, 0xed, 0xea, 0x66, 0x13,
17343
-	0x07, 0x57, 0xe4, 0x01, 0x40, 0xa6, 0x57, 0x25, 0x45, 0x76, 0x10, 0xea, 0xac, 0xad, 0xfe, 0xf0,
17344
-	0x27, 0x6b, 0x73, 0x3f, 0xfe, 0xc9, 0xda, 0xdc, 0xab, 0xf3, 0xb5, 0xc4, 0x0f, 0xcf, 0xd7, 0x12,
17345
-	0xff, 0x70, 0xbe, 0x96, 0xf8, 0xf7, 0xf3, 0xb5, 0xc4, 0x5e, 0x96, 0x1f, 0x02, 0x4f, 0xfe, 0x2f,
17346
-	0x00, 0x00, 0xff, 0xff, 0x4b, 0xdb, 0xdc, 0xec, 0xf0, 0x31, 0x00, 0x00,
17032
+	// 5043 bytes of a gzipped FileDescriptorProto
17033
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x7a, 0x4d, 0x6c, 0x24, 0x49,
17034
+	0x56, 0xbf, 0xeb, 0xd3, 0x55, 0xaf, 0xca, 0x76, 0x3a, 0xda, 0xdb, 0xe3, 0xae, 0xed, 0xb6, 0x6b,
17035
+	0x72, 0xa6, 0x77, 0x66, 0x7b, 0xfb, 0x5f, 0xfd, 0xb5, 0xbb, 0xea, 0x99, 0xf9, 0xef, 0xce, 0xd4,
17036
+	0x97, 0xed, 0xda, 0xb6, 0xab, 0x4a, 0x51, 0xe5, 0xee, 0x5d, 0x24, 0x48, 0xa5, 0x33, 0xc3, 0xe5,
17037
+	0x1c, 0x67, 0x65, 0x14, 0x99, 0x59, 0x76, 0x17, 0x0b, 0xa2, 0xc5, 0x01, 0x90, 0x4f, 0x70, 0x62,
17038
+	0x11, 0x32, 0x42, 0x82, 0x13, 0x42, 0xe2, 0x00, 0x12, 0x82, 0xd3, 0x20, 0x71, 0xd8, 0x1b, 0x2c,
17039
+	0x48, 0x68, 0x05, 0x92, 0x61, 0x7d, 0xe0, 0xb6, 0x82, 0x0b, 0xe2, 0x02, 0x12, 0x8a, 0x8f, 0xcc,
17040
+	0x4a, 0x57, 0xa7, 0xed, 0x1e, 0x66, 0x2f, 0x76, 0xc5, 0x7b, 0xbf, 0xf7, 0xe2, 0xc5, 0x8b, 0x88,
17041
+	0x17, 0xef, 0x45, 0x24, 0xdc, 0x1b, 0x58, 0xfe, 0xc1, 0x78, 0xaf, 0x62, 0xd0, 0xe1, 0x03, 0x93,
17042
+	0x1a, 0x87, 0xc4, 0x7d, 0xe0, 0x1d, 0xeb, 0xee, 0xf0, 0xd0, 0xf2, 0x1f, 0xe8, 0x23, 0xeb, 0x81,
17043
+	0x3f, 0x19, 0x11, 0xaf, 0x32, 0x72, 0xa9, 0x4f, 0x11, 0x12, 0x80, 0x4a, 0x00, 0xa8, 0x1c, 0x3d,
17044
+	0x2a, 0xad, 0x0f, 0x28, 0x1d, 0xd8, 0xe4, 0x01, 0x47, 0xec, 0x8d, 0xf7, 0x1f, 0xf8, 0xd6, 0x90,
17045
+	0x78, 0xbe, 0x3e, 0x1c, 0x09, 0xa1, 0xd2, 0xda, 0x2c, 0xc0, 0x1c, 0xbb, 0xba, 0x6f, 0x51, 0x47,
17046
+	0xf2, 0x57, 0x06, 0x74, 0x40, 0xf9, 0xcf, 0x07, 0xec, 0x97, 0xa0, 0xaa, 0xeb, 0x30, 0xff, 0x9c,
17047
+	0xb8, 0x9e, 0x45, 0x1d, 0xb4, 0x02, 0x19, 0xcb, 0x31, 0xc9, 0xcb, 0xd5, 0x44, 0x39, 0xf1, 0x7e,
17048
+	0x1a, 0x8b, 0x86, 0xfa, 0x10, 0xa0, 0xc5, 0x7e, 0x34, 0x1d, 0xdf, 0x9d, 0x20, 0x05, 0x52, 0x87,
17049
+	0x64, 0xc2, 0x11, 0x79, 0xcc, 0x7e, 0x32, 0xca, 0x91, 0x6e, 0xaf, 0x26, 0x05, 0xe5, 0x48, 0xb7,
17050
+	0xd5, 0x9f, 0x24, 0xa0, 0x50, 0x75, 0x1c, 0xea, 0xf3, 0xde, 0x3d, 0x84, 0x20, 0xed, 0xe8, 0x43,
17051
+	0x22, 0x85, 0xf8, 0x6f, 0x54, 0x87, 0xac, 0xad, 0xef, 0x11, 0xdb, 0x5b, 0x4d, 0x96, 0x53, 0xef,
17052
+	0x17, 0x1e, 0x7f, 0xad, 0xf2, 0xfa, 0x90, 0x2b, 0x11, 0x25, 0x95, 0x6d, 0x8e, 0xe6, 0x46, 0x60,
17053
+	0x29, 0x8a, 0xbe, 0x0d, 0xf3, 0x96, 0x63, 0x5a, 0x06, 0xf1, 0x56, 0xd3, 0x5c, 0xcb, 0x5a, 0x9c,
17054
+	0x96, 0xa9, 0xf5, 0xb5, 0xf4, 0x0f, 0xcf, 0xd6, 0xe7, 0x70, 0x20, 0x54, 0xfa, 0x00, 0x0a, 0x11,
17055
+	0xb5, 0x31, 0x63, 0x5b, 0x81, 0xcc, 0x91, 0x6e, 0x8f, 0x89, 0x1c, 0x9d, 0x68, 0x7c, 0x98, 0x7c,
17056
+	0x9a, 0x50, 0x3f, 0x81, 0x95, 0xb6, 0x3e, 0x24, 0xe6, 0x26, 0x71, 0x88, 0x6b, 0x19, 0x98, 0x78,
17057
+	0x74, 0xec, 0x1a, 0x84, 0x8d, 0xf5, 0xd0, 0x72, 0xcc, 0x60, 0xac, 0xec, 0x77, 0xbc, 0x16, 0xb5,
17058
+	0x0e, 0x6f, 0x35, 0x2c, 0xcf, 0x70, 0x89, 0x4f, 0x3e, 0xb7, 0x92, 0x54, 0xa0, 0xe4, 0x2c, 0x01,
17059
+	0x4b, 0xb3, 0xd2, 0x3f, 0x07, 0x37, 0x98, 0x8b, 0x4d, 0xcd, 0x95, 0x14, 0xcd, 0x1b, 0x11, 0x83,
17060
+	0x2b, 0x2b, 0x3c, 0x7e, 0x3f, 0xce, 0x43, 0x71, 0x23, 0xd9, 0x9a, 0xc3, 0xcb, 0x5c, 0x4d, 0x40,
17061
+	0xe8, 0x8d, 0x88, 0x81, 0x0c, 0xb8, 0x69, 0x4a, 0xa3, 0x67, 0xd4, 0x27, 0xb9, 0xfa, 0xd8, 0x69,
17062
+	0xbc, 0x64, 0x98, 0x5b, 0x73, 0x78, 0x25, 0x50, 0x16, 0xed, 0xa4, 0x06, 0x90, 0x0b, 0x74, 0xab,
17063
+	0x3f, 0x48, 0x40, 0x3e, 0x60, 0x7a, 0xe8, 0xab, 0x90, 0x77, 0x74, 0x87, 0x6a, 0xc6, 0x68, 0xec,
17064
+	0xf1, 0x01, 0xa5, 0x6a, 0xc5, 0xf3, 0xb3, 0xf5, 0x5c, 0x5b, 0x77, 0x68, 0xbd, 0xbb, 0xeb, 0xe1,
17065
+	0x1c, 0x63, 0xd7, 0x47, 0x63, 0x0f, 0xbd, 0x0d, 0xc5, 0x21, 0x19, 0x52, 0x77, 0xa2, 0xed, 0x4d,
17066
+	0x7c, 0xe2, 0x49, 0xb7, 0x15, 0x04, 0xad, 0xc6, 0x48, 0xe8, 0x5b, 0x30, 0x3f, 0x10, 0x26, 0xad,
17067
+	0xa6, 0xf8, 0xf2, 0x79, 0x27, 0xce, 0xfa, 0x19, 0xab, 0x71, 0x20, 0xa3, 0xfe, 0x56, 0x02, 0x56,
17068
+	0x42, 0x2a, 0xf9, 0xc5, 0xb1, 0xe5, 0x92, 0x21, 0x71, 0x7c, 0x0f, 0x7d, 0x03, 0xb2, 0xb6, 0x35,
17069
+	0xb4, 0x7c, 0x4f, 0xfa, 0xfc, 0x4e, 0x9c, 0xda, 0x70, 0x50, 0x58, 0x82, 0x51, 0x15, 0x8a, 0x2e,
17070
+	0xf1, 0x88, 0x7b, 0x24, 0x56, 0xbc, 0xf4, 0xe8, 0x35, 0xc2, 0x17, 0x44, 0xd4, 0x0d, 0xc8, 0x75,
17071
+	0x6d, 0xdd, 0xdf, 0xa7, 0xee, 0x10, 0xa9, 0x50, 0xd4, 0x5d, 0xe3, 0xc0, 0xf2, 0x89, 0xe1, 0x8f,
17072
+	0xdd, 0x60, 0xf7, 0x5d, 0xa0, 0xa1, 0x9b, 0x90, 0xa4, 0xa2, 0xa3, 0x7c, 0x2d, 0x7b, 0x7e, 0xb6,
17073
+	0x9e, 0xec, 0xf4, 0x70, 0x92, 0x7a, 0xea, 0x47, 0xb0, 0xdc, 0xb5, 0xc7, 0x03, 0xcb, 0x69, 0x10,
17074
+	0xcf, 0x70, 0xad, 0x11, 0xd3, 0xce, 0x56, 0x25, 0x8b, 0x51, 0xc1, 0xaa, 0x64, 0xbf, 0xc3, 0xad,
17075
+	0x9d, 0x9c, 0x6e, 0x6d, 0xf5, 0x37, 0x92, 0xb0, 0xdc, 0x74, 0x06, 0x96, 0x43, 0xa2, 0xd2, 0x77,
17076
+	0x61, 0x91, 0x70, 0xa2, 0x76, 0x24, 0xc2, 0x8d, 0xd4, 0xb3, 0x20, 0xa8, 0x41, 0x0c, 0x6a, 0xcd,
17077
+	0xc4, 0x85, 0x47, 0x71, 0xc3, 0x7f, 0x4d, 0x7b, 0x6c, 0x74, 0x68, 0xc2, 0xfc, 0x88, 0x0f, 0xc2,
17078
+	0x93, 0xd3, 0x7b, 0x37, 0x4e, 0xd7, 0x6b, 0xe3, 0x0c, 0x82, 0x84, 0x94, 0xfd, 0x22, 0x41, 0xe2,
17079
+	0x4f, 0x92, 0xb0, 0xd4, 0xa6, 0xe6, 0x05, 0x3f, 0x94, 0x20, 0x77, 0x40, 0x3d, 0x3f, 0x12, 0x10,
17080
+	0xc3, 0x36, 0x7a, 0x0a, 0xb9, 0x91, 0x9c, 0x3e, 0x39, 0xfb, 0xb7, 0xe3, 0x4d, 0x16, 0x18, 0x1c,
17081
+	0xa2, 0xd1, 0x47, 0x90, 0x0f, 0xb6, 0x0c, 0x1b, 0xed, 0x1b, 0x2c, 0x9c, 0x29, 0x1e, 0x7d, 0x0b,
17082
+	0xb2, 0x62, 0x12, 0x56, 0xd3, 0x5c, 0xf2, 0xee, 0x1b, 0xf9, 0x1c, 0x4b, 0x21, 0xb4, 0x09, 0x39,
17083
+	0xdf, 0xf6, 0x34, 0xcb, 0xd9, 0xa7, 0xab, 0x19, 0xae, 0x60, 0x3d, 0x36, 0xc8, 0x50, 0x93, 0xf4,
17084
+	0xb7, 0x7b, 0x2d, 0x67, 0x9f, 0xd6, 0x0a, 0xe7, 0x67, 0xeb, 0xf3, 0xb2, 0x81, 0xe7, 0x7d, 0xdb,
17085
+	0x63, 0x3f, 0xd4, 0xdf, 0x4e, 0x40, 0x21, 0x82, 0x42, 0x77, 0x00, 0x7c, 0x77, 0xec, 0xf9, 0x9a,
17086
+	0x4b, 0xa9, 0xcf, 0x9d, 0x55, 0xc4, 0x79, 0x4e, 0xc1, 0x94, 0xfa, 0xa8, 0x02, 0x37, 0x0c, 0xe2,
17087
+	0xfa, 0x9a, 0xe5, 0x79, 0x63, 0xe2, 0x6a, 0xde, 0x78, 0xef, 0x53, 0x62, 0xf8, 0xdc, 0x71, 0x45,
17088
+	0xbc, 0xcc, 0x58, 0x2d, 0xce, 0xe9, 0x09, 0x06, 0x7a, 0x02, 0x37, 0xa3, 0xf8, 0xd1, 0x78, 0xcf,
17089
+	0xb6, 0x0c, 0x8d, 0x4d, 0x66, 0x8a, 0x8b, 0xdc, 0x98, 0x8a, 0x74, 0x39, 0xef, 0x19, 0x99, 0xa8,
17090
+	0x3f, 0x4e, 0x80, 0x82, 0xf5, 0x7d, 0x7f, 0x87, 0x0c, 0xf7, 0x88, 0xdb, 0xf3, 0x75, 0x7f, 0xec,
17091
+	0xa1, 0x9b, 0x90, 0xb5, 0x89, 0x6e, 0x12, 0x97, 0x1b, 0x95, 0xc3, 0xb2, 0x85, 0x76, 0xd9, 0x0e,
17092
+	0xd6, 0x8d, 0x03, 0x7d, 0xcf, 0xb2, 0x2d, 0x7f, 0xc2, 0x4d, 0x59, 0x8c, 0x5f, 0xc2, 0xb3, 0x3a,
17093
+	0x2b, 0x38, 0x22, 0x88, 0x2f, 0xa8, 0x41, 0xab, 0x30, 0x3f, 0x24, 0x9e, 0xa7, 0x0f, 0x08, 0xb7,
17094
+	0x34, 0x8f, 0x83, 0xa6, 0xfa, 0x11, 0x14, 0xa3, 0x72, 0xa8, 0x00, 0xf3, 0xbb, 0xed, 0x67, 0xed,
17095
+	0xce, 0x8b, 0xb6, 0x32, 0x87, 0x96, 0xa0, 0xb0, 0xdb, 0xc6, 0xcd, 0x6a, 0x7d, 0xab, 0x5a, 0xdb,
17096
+	0x6e, 0x2a, 0x09, 0xb4, 0x00, 0xf9, 0x69, 0x33, 0xa9, 0xfe, 0x59, 0x02, 0x80, 0xb9, 0x5b, 0x0e,
17097
+	0xea, 0x43, 0xc8, 0x78, 0xbe, 0xee, 0x8b, 0x55, 0xb9, 0xf8, 0xf8, 0xdd, 0xcb, 0xe6, 0x50, 0xda,
17098
+	0xcb, 0xfe, 0x11, 0x2c, 0x44, 0xa2, 0x16, 0x26, 0x2f, 0x58, 0xc8, 0x02, 0x84, 0x6e, 0x9a, 0xae,
17099
+	0x34, 0x9c, 0xff, 0x56, 0x3f, 0x82, 0x0c, 0x97, 0xbe, 0x68, 0x6e, 0x0e, 0xd2, 0x0d, 0xf6, 0x2b,
17100
+	0x81, 0xf2, 0x90, 0xc1, 0xcd, 0x6a, 0xe3, 0x7b, 0x4a, 0x12, 0x29, 0x50, 0x6c, 0xb4, 0x7a, 0xf5,
17101
+	0x4e, 0xbb, 0xdd, 0xac, 0xf7, 0x9b, 0x0d, 0x25, 0xa5, 0xde, 0x85, 0x4c, 0x6b, 0xc8, 0x34, 0xdf,
17102
+	0x66, 0x4b, 0x7e, 0x9f, 0xb8, 0xc4, 0x31, 0x82, 0x9d, 0x34, 0x25, 0xa8, 0x3f, 0x2d, 0x40, 0x66,
17103
+	0x87, 0x8e, 0x1d, 0x1f, 0x3d, 0x8e, 0x84, 0xad, 0xc5, 0xf8, 0x0c, 0x81, 0x03, 0x2b, 0xfd, 0xc9,
17104
+	0x88, 0xc8, 0xb0, 0x76, 0x13, 0xb2, 0x62, 0x73, 0xc8, 0xe1, 0xc8, 0x16, 0xa3, 0xfb, 0xba, 0x3b,
17105
+	0x20, 0xbe, 0x1c, 0x8f, 0x6c, 0xa1, 0xf7, 0xd9, 0x89, 0xa5, 0x9b, 0xd4, 0xb1, 0x27, 0x7c, 0x0f,
17106
+	0xe5, 0xc4, 0xb1, 0x84, 0x89, 0x6e, 0x76, 0x1c, 0x7b, 0x82, 0x43, 0x2e, 0xda, 0x82, 0xe2, 0x9e,
17107
+	0xe5, 0x98, 0x1a, 0x1d, 0x89, 0x20, 0x9f, 0xb9, 0x7c, 0xc7, 0x09, 0xab, 0x6a, 0x96, 0x63, 0x76,
17108
+	0x04, 0x18, 0x17, 0xf6, 0xa6, 0x0d, 0xd4, 0x86, 0xc5, 0x23, 0x6a, 0x8f, 0x87, 0x24, 0xd4, 0x95,
17109
+	0xe5, 0xba, 0xde, 0xbb, 0x5c, 0xd7, 0x73, 0x8e, 0x0f, 0xb4, 0x2d, 0x1c, 0x45, 0x9b, 0xe8, 0x19,
17110
+	0x2c, 0xf8, 0xc3, 0xd1, 0xbe, 0x17, 0xaa, 0x9b, 0xe7, 0xea, 0xbe, 0x72, 0x85, 0xc3, 0x18, 0x3c,
17111
+	0xd0, 0x56, 0xf4, 0x23, 0x2d, 0xb4, 0x09, 0x05, 0x83, 0x3a, 0x9e, 0xe5, 0xf9, 0xc4, 0x31, 0x26,
17112
+	0xab, 0x39, 0xee, 0xfb, 0x2b, 0x46, 0x59, 0x9f, 0x82, 0x71, 0x54, 0xb2, 0xf4, 0x6b, 0x29, 0x28,
17113
+	0x44, 0x5c, 0x80, 0x7a, 0x50, 0x18, 0xb9, 0x74, 0xa4, 0x0f, 0xf8, 0x89, 0x27, 0x27, 0xf5, 0xd1,
17114
+	0x1b, 0xb9, 0xaf, 0xd2, 0x9d, 0x0a, 0xe2, 0xa8, 0x16, 0xf5, 0x34, 0x09, 0x85, 0x08, 0x13, 0xdd,
17115
+	0x83, 0x1c, 0xee, 0xe2, 0xd6, 0xf3, 0x6a, 0xbf, 0xa9, 0xcc, 0x95, 0x6e, 0x9f, 0x9c, 0x96, 0x57,
17116
+	0xb9, 0xb6, 0xa8, 0x82, 0xae, 0x6b, 0x1d, 0xb1, 0x35, 0xfc, 0x3e, 0xcc, 0x07, 0xd0, 0x44, 0xe9,
17117
+	0xcb, 0x27, 0xa7, 0xe5, 0xb7, 0x66, 0xa1, 0x11, 0x24, 0xee, 0x6d, 0x55, 0x71, 0xb3, 0xa1, 0x24,
17118
+	0xe3, 0x91, 0xb8, 0x77, 0xa0, 0xbb, 0xc4, 0x44, 0x5f, 0x81, 0xac, 0x04, 0xa6, 0x4a, 0xa5, 0x93,
17119
+	0xd3, 0xf2, 0xcd, 0x59, 0xe0, 0x14, 0x87, 0x7b, 0xdb, 0xd5, 0xe7, 0x4d, 0x25, 0x1d, 0x8f, 0xc3,
17120
+	0x3d, 0x5b, 0x3f, 0x22, 0xe8, 0x5d, 0xc8, 0x08, 0x58, 0xa6, 0x74, 0xeb, 0xe4, 0xb4, 0xfc, 0xa5,
17121
+	0xd7, 0xd4, 0x31, 0x54, 0x69, 0xf5, 0x37, 0xff, 0x70, 0x6d, 0xee, 0xaf, 0xfe, 0x68, 0x4d, 0x99,
17122
+	0x65, 0x97, 0xfe, 0x3b, 0x01, 0x0b, 0x17, 0xd6, 0x0e, 0x52, 0x21, 0xeb, 0x50, 0x83, 0x8e, 0xc4,
17123
+	0x41, 0x98, 0xab, 0xc1, 0xf9, 0xd9, 0x7a, 0xb6, 0x4d, 0xeb, 0x74, 0x34, 0xc1, 0x92, 0x83, 0x9e,
17124
+	0xcd, 0x1c, 0xe5, 0x4f, 0xde, 0x70, 0x61, 0xc6, 0x1e, 0xe6, 0x1f, 0xc3, 0x82, 0xe9, 0x5a, 0x47,
17125
+	0xc4, 0xd5, 0x0c, 0xea, 0xec, 0x5b, 0x03, 0x79, 0xc8, 0x95, 0x62, 0xf3, 0x4d, 0x0e, 0xc4, 0x45,
17126
+	0x21, 0x50, 0xe7, 0xf8, 0x2f, 0x70, 0x8c, 0x97, 0x9e, 0x43, 0x31, 0xba, 0xd4, 0xd9, 0xb9, 0xe4,
17127
+	0x59, 0xbf, 0x44, 0x64, 0x62, 0xc9, 0xd3, 0x50, 0x9c, 0x67, 0x14, 0x91, 0x56, 0xbe, 0x07, 0xe9,
17128
+	0x21, 0x35, 0x85, 0x9e, 0x85, 0xda, 0x0d, 0x96, 0x4d, 0xfc, 0xd3, 0xd9, 0x7a, 0x81, 0x7a, 0x95,
17129
+	0x0d, 0xcb, 0x26, 0x3b, 0xd4, 0x24, 0x98, 0x03, 0xd4, 0x23, 0x48, 0xb3, 0x98, 0x83, 0xbe, 0x0c,
17130
+	0xe9, 0x5a, 0xab, 0xdd, 0x50, 0xe6, 0x4a, 0xcb, 0x27, 0xa7, 0xe5, 0x05, 0xee, 0x12, 0xc6, 0x60,
17131
+	0x6b, 0x17, 0xad, 0x43, 0xf6, 0x79, 0x67, 0x7b, 0x77, 0x87, 0x2d, 0xaf, 0x1b, 0x27, 0xa7, 0xe5,
17132
+	0xa5, 0x90, 0x2d, 0x9c, 0x86, 0xee, 0x40, 0xa6, 0xbf, 0xd3, 0xdd, 0xe8, 0x29, 0xc9, 0x12, 0x3a,
17133
+	0x39, 0x2d, 0x2f, 0x86, 0x7c, 0x6e, 0x73, 0x69, 0x59, 0xce, 0x6a, 0x3e, 0xa4, 0xab, 0x3f, 0x4a,
17134
+	0x40, 0x21, 0xb2, 0xe1, 0xd8, 0xc2, 0x6c, 0x34, 0x37, 0xaa, 0xbb, 0xdb, 0x7d, 0x65, 0x2e, 0xb2,
17135
+	0x30, 0x23, 0x90, 0x06, 0xd9, 0xd7, 0xc7, 0x36, 0x8b, 0x73, 0x50, 0xef, 0xb4, 0x7b, 0xad, 0x5e,
17136
+	0xbf, 0xd9, 0xee, 0x2b, 0x89, 0xd2, 0xea, 0xc9, 0x69, 0x79, 0x65, 0x16, 0xbc, 0x31, 0xb6, 0x6d,
17137
+	0xb6, 0x34, 0xeb, 0xd5, 0xfa, 0x16, 0x5f, 0xeb, 0xd3, 0xa5, 0x19, 0x41, 0xd5, 0x75, 0xe3, 0x80,
17138
+	0x98, 0xe8, 0x3e, 0xe4, 0x1b, 0xcd, 0xed, 0xe6, 0x66, 0x95, 0x47, 0xf7, 0xd2, 0x9d, 0x93, 0xd3,
17139
+	0xf2, 0xad, 0xd7, 0x7b, 0xb7, 0xc9, 0x40, 0xf7, 0x89, 0x39, 0xb3, 0x44, 0x23, 0x10, 0xf5, 0x3f,
17140
+	0x93, 0xb0, 0x80, 0x59, 0x39, 0xec, 0xfa, 0x5d, 0x6a, 0x5b, 0xc6, 0x04, 0x75, 0x21, 0x6f, 0x50,
17141
+	0xc7, 0xb4, 0x22, 0x71, 0xe2, 0xf1, 0x25, 0x29, 0xd1, 0x54, 0x2a, 0x68, 0xd5, 0x03, 0x49, 0x3c,
17142
+	0x55, 0x82, 0x1e, 0x40, 0xc6, 0x24, 0xb6, 0x3e, 0x91, 0xb9, 0xd9, 0xad, 0x8a, 0x28, 0xb8, 0x2b,
17143
+	0x41, 0xc1, 0x5d, 0x69, 0xc8, 0x82, 0x1b, 0x0b, 0x1c, 0xaf, 0x41, 0xf4, 0x97, 0x9a, 0xee, 0xfb,
17144
+	0x64, 0x38, 0xf2, 0x45, 0x62, 0x96, 0xc6, 0x85, 0xa1, 0xfe, 0xb2, 0x2a, 0x49, 0xe8, 0x11, 0x64,
17145
+	0x8f, 0x2d, 0xc7, 0xa4, 0xc7, 0x32, 0xf7, 0xba, 0x42, 0xa9, 0x04, 0xaa, 0x27, 0x2c, 0x25, 0x99,
17146
+	0x31, 0x93, 0xad, 0xa1, 0x76, 0xa7, 0xdd, 0x0c, 0xd6, 0x90, 0xe4, 0x77, 0x9c, 0x36, 0x75, 0xd8,
17147
+	0xfe, 0x87, 0x4e, 0x5b, 0xdb, 0xa8, 0xb6, 0xb6, 0x77, 0x31, 0x5b, 0x47, 0x2b, 0x27, 0xa7, 0x65,
17148
+	0x25, 0x84, 0x6c, 0xe8, 0x96, 0xcd, 0x8a, 0x81, 0x5b, 0x90, 0xaa, 0xb6, 0xbf, 0xa7, 0x24, 0x4b,
17149
+	0xca, 0xc9, 0x69, 0xb9, 0x18, 0xb2, 0xab, 0xce, 0x64, 0xea, 0xf7, 0xd9, 0x7e, 0xd5, 0xbf, 0x4d,
17150
+	0x41, 0x71, 0x77, 0x64, 0xea, 0x3e, 0x11, 0xfb, 0x0c, 0x95, 0xa1, 0x30, 0xd2, 0x5d, 0xdd, 0xb6,
17151
+	0x89, 0x6d, 0x79, 0x43, 0x79, 0x95, 0x10, 0x25, 0xa1, 0x0f, 0xde, 0xd4, 0x8d, 0xb5, 0x1c, 0xdb,
17152
+	0x3b, 0x3f, 0xf8, 0x97, 0xf5, 0x44, 0xe0, 0xd0, 0x5d, 0x58, 0xdc, 0x17, 0xd6, 0x6a, 0xba, 0xc1,
17153
+	0x27, 0x36, 0xc5, 0x27, 0xb6, 0x12, 0x37, 0xb1, 0x51, 0xb3, 0x2a, 0x72, 0x90, 0x55, 0x2e, 0x85,
17154
+	0x17, 0xf6, 0xa3, 0x4d, 0xf4, 0x04, 0xe6, 0x87, 0xd4, 0xb1, 0x7c, 0xea, 0x5e, 0x3f, 0x0b, 0x01,
17155
+	0x12, 0xdd, 0x83, 0x65, 0x36, 0xb9, 0x81, 0x3d, 0x9c, 0xcd, 0x8f, 0xf3, 0x24, 0x5e, 0x1a, 0xea,
17156
+	0x2f, 0x65, 0x87, 0x98, 0x91, 0x51, 0x0d, 0x32, 0xd4, 0x65, 0xf9, 0x62, 0x96, 0x9b, 0x7b, 0xff,
17157
+	0x5a, 0x73, 0x45, 0xa3, 0xc3, 0x64, 0xb0, 0x10, 0x55, 0xbf, 0x09, 0x0b, 0x17, 0x06, 0xc1, 0xd2,
17158
+	0xa4, 0x6e, 0x75, 0xb7, 0xd7, 0x54, 0xe6, 0x50, 0x11, 0x72, 0xf5, 0x4e, 0xbb, 0xdf, 0x6a, 0xef,
17159
+	0xb2, 0x3c, 0xaf, 0x08, 0x39, 0xdc, 0xd9, 0xde, 0xae, 0x55, 0xeb, 0xcf, 0x94, 0xa4, 0x5a, 0x81,
17160
+	0x42, 0x44, 0x1b, 0x5a, 0x04, 0xe8, 0xf5, 0x3b, 0x5d, 0x6d, 0xa3, 0x85, 0x7b, 0x7d, 0x91, 0x25,
17161
+	0xf6, 0xfa, 0x55, 0xdc, 0x97, 0x84, 0x84, 0xfa, 0xef, 0xc9, 0x60, 0x46, 0x65, 0x62, 0x58, 0xbb,
17162
+	0x98, 0x18, 0x5e, 0x61, 0xbc, 0x4c, 0x0d, 0xa7, 0x8d, 0x30, 0x41, 0xfc, 0x00, 0x80, 0x2f, 0x1c,
17163
+	0x62, 0x6a, 0xba, 0x2f, 0x27, 0xbe, 0xf4, 0x9a, 0x93, 0xfb, 0xc1, 0x8d, 0x16, 0xce, 0x4b, 0x74,
17164
+	0xd5, 0x47, 0xdf, 0x82, 0xa2, 0x41, 0x87, 0x23, 0x9b, 0x48, 0xe1, 0xd4, 0xb5, 0xc2, 0x85, 0x10,
17165
+	0x5f, 0xf5, 0xa3, 0xa9, 0x69, 0xfa, 0x62, 0xf2, 0xfc, 0xeb, 0x89, 0xc0, 0x33, 0x31, 0xd9, 0x68,
17166
+	0x11, 0x72, 0xbb, 0xdd, 0x46, 0xb5, 0xdf, 0x6a, 0x6f, 0x2a, 0x09, 0x04, 0x90, 0xe5, 0xae, 0x6e,
17167
+	0x28, 0x49, 0x96, 0x45, 0xd7, 0x3b, 0x3b, 0xdd, 0xed, 0x26, 0x8f, 0x58, 0x68, 0x05, 0x94, 0xc0,
17168
+	0xd9, 0x1a, 0x77, 0x64, 0xb3, 0xa1, 0xa4, 0xd1, 0x0d, 0x58, 0x0a, 0xa9, 0x52, 0x32, 0x83, 0x6e,
17169
+	0x02, 0x0a, 0x89, 0x53, 0x15, 0x59, 0xf5, 0x57, 0x60, 0xa9, 0x4e, 0x1d, 0x5f, 0xb7, 0x9c, 0xb0,
17170
+	0xc2, 0x78, 0xcc, 0x06, 0x2d, 0x49, 0x9a, 0x25, 0x6f, 0x82, 0x6a, 0x4b, 0xe7, 0x67, 0xeb, 0x85,
17171
+	0x10, 0xda, 0x6a, 0xf0, 0x54, 0x49, 0x36, 0x4c, 0xb6, 0x7f, 0x47, 0x96, 0xc9, 0x9d, 0x9b, 0xa9,
17172
+	0xcd, 0x9f, 0x9f, 0xad, 0xa7, 0xba, 0xad, 0x06, 0x66, 0x34, 0xf4, 0x65, 0xc8, 0x93, 0x97, 0x96,
17173
+	0xaf, 0x19, 0xec, 0x5c, 0x62, 0x0e, 0xcc, 0xe0, 0x1c, 0x23, 0xd4, 0xd9, 0x31, 0x54, 0x03, 0xe8,
17174
+	0x52, 0xd7, 0x97, 0x3d, 0x7f, 0x1d, 0x32, 0x23, 0xea, 0xf2, 0xbb, 0x8b, 0x4b, 0x6f, 0xd4, 0x18,
17175
+	0x5c, 0x2c, 0x54, 0x2c, 0xc0, 0xea, 0xef, 0xa6, 0x00, 0xfa, 0xba, 0x77, 0x28, 0x95, 0x3c, 0x85,
17176
+	0x7c, 0x78, 0x3b, 0x29, 0x2f, 0x41, 0xae, 0x9c, 0xed, 0x10, 0x8c, 0x9e, 0x04, 0x8b, 0x4d, 0xd4,
17177
+	0x4e, 0xb1, 0x45, 0x6c, 0xd0, 0x51, 0x5c, 0xf9, 0x71, 0xb1, 0x40, 0x62, 0xc7, 0x3c, 0x71, 0x5d,
17178
+	0x39, 0xf3, 0xec, 0x27, 0xaa, 0xf3, 0x63, 0x41, 0x38, 0x4d, 0x66, 0xdf, 0xb1, 0xd7, 0x3e, 0x33,
17179
+	0x33, 0xb2, 0x35, 0x87, 0xa7, 0x72, 0xe8, 0x63, 0x28, 0xb0, 0x71, 0x6b, 0x1e, 0xe7, 0xc9, 0xc4,
17180
+	0xfb, 0x52, 0x57, 0x09, 0x0d, 0x18, 0x46, 0x53, 0x2f, 0xdf, 0x01, 0xd0, 0x47, 0x23, 0xdb, 0x22,
17181
+	0xa6, 0xb6, 0x37, 0xe1, 0x99, 0x76, 0x1e, 0xe7, 0x25, 0xa5, 0x36, 0x61, 0xdb, 0x25, 0x60, 0xeb,
17182
+	0x3e, 0xcf, 0x9e, 0xaf, 0x71, 0xa0, 0x44, 0x57, 0xfd, 0x9a, 0x02, 0x8b, 0xee, 0xd8, 0x61, 0x0e,
17183
+	0x95, 0xd6, 0xa9, 0x7f, 0x9a, 0x84, 0xb7, 0xda, 0xc4, 0x3f, 0xa6, 0xee, 0x61, 0xd5, 0xf7, 0x75,
17184
+	0xe3, 0x60, 0x48, 0x1c, 0x39, 0x7d, 0x91, 0x82, 0x26, 0x71, 0xa1, 0xa0, 0x59, 0x85, 0x79, 0xdd,
17185
+	0xb6, 0x74, 0x8f, 0x88, 0xe4, 0x2d, 0x8f, 0x83, 0x26, 0x2b, 0xbb, 0x58, 0x11, 0x47, 0x3c, 0x8f,
17186
+	0x88, 0x7b, 0x15, 0x66, 0x78, 0x40, 0x40, 0xdf, 0x87, 0x9b, 0x32, 0x4d, 0xd3, 0xc3, 0xae, 0x58,
17187
+	0x41, 0x11, 0x5c, 0xd0, 0x36, 0x63, 0xab, 0xca, 0x78, 0xe3, 0x64, 0x1e, 0x37, 0x25, 0x77, 0x46,
17188
+	0xbe, 0xcc, 0x0a, 0x57, 0xcc, 0x18, 0x56, 0x69, 0x13, 0x6e, 0x5d, 0x2a, 0xf2, 0xb9, 0xee, 0x6d,
17189
+	0xfe, 0x21, 0x09, 0xd0, 0xea, 0x56, 0x77, 0xa4, 0x93, 0x1a, 0x90, 0xdd, 0xd7, 0x87, 0x96, 0x3d,
17190
+	0xb9, 0x2a, 0x02, 0x4e, 0xf1, 0x95, 0xaa, 0x70, 0xc7, 0x06, 0x97, 0xc1, 0x52, 0x96, 0xd7, 0x94,
17191
+	0xe3, 0x3d, 0x87, 0xf8, 0x61, 0x4d, 0xc9, 0x5b, 0xcc, 0x0c, 0x57, 0x77, 0xc2, 0xa5, 0x2b, 0x1a,
17192
+	0x6c, 0x02, 0x58, 0xca, 0x73, 0xac, 0x4f, 0x82, 0xb0, 0x25, 0x9b, 0x68, 0x8b, 0xdf, 0x8e, 0x12,
17193
+	0xf7, 0x88, 0x98, 0xab, 0x19, 0xee, 0xd4, 0xeb, 0xec, 0xc1, 0x12, 0x2e, 0x7c, 0x17, 0x4a, 0x97,
17194
+	0x3e, 0xe2, 0x29, 0xd3, 0x94, 0xf5, 0xb9, 0x7c, 0xf4, 0x10, 0x16, 0x2e, 0x8c, 0xf3, 0xb5, 0x62,
17195
+	0xbe, 0xd5, 0x7d, 0xfe, 0x75, 0x25, 0x2d, 0x7f, 0x7d, 0x53, 0xc9, 0xaa, 0x7f, 0x9c, 0x12, 0x81,
17196
+	0x46, 0x7a, 0x35, 0xfe, 0x55, 0x20, 0xc7, 0x57, 0xb7, 0x41, 0x6d, 0x19, 0x00, 0xde, 0xbb, 0x3a,
17197
+	0xfe, 0xb0, 0x9a, 0x8e, 0xc3, 0x71, 0x28, 0x88, 0xd6, 0xa1, 0x20, 0x56, 0xb1, 0xc6, 0x36, 0x1c,
17198
+	0x77, 0xeb, 0x02, 0x06, 0x41, 0x62, 0x92, 0xe8, 0x2e, 0x2c, 0xf2, 0xcb, 0x1f, 0xef, 0x80, 0x98,
17199
+	0x02, 0x93, 0xe6, 0x98, 0x85, 0x90, 0xca, 0x61, 0x3b, 0x50, 0x94, 0x04, 0x8d, 0xe7, 0xf3, 0x19,
17200
+	0x6e, 0xd0, 0xbd, 0xeb, 0x0c, 0x12, 0x22, 0x3c, 0xcd, 0x2f, 0x8c, 0xa6, 0x0d, 0xb5, 0x01, 0xb9,
17201
+	0xc0, 0x58, 0xb4, 0x0a, 0xa9, 0x7e, 0xbd, 0xab, 0xcc, 0x95, 0x96, 0x4e, 0x4e, 0xcb, 0x85, 0x80,
17202
+	0xdc, 0xaf, 0x77, 0x19, 0x67, 0xb7, 0xd1, 0x55, 0x12, 0x17, 0x39, 0xbb, 0x8d, 0x6e, 0x29, 0xcd,
17203
+	0x72, 0x30, 0x75, 0x1f, 0x0a, 0x91, 0x1e, 0xd0, 0x3b, 0x30, 0xdf, 0x6a, 0x6f, 0xe2, 0x66, 0xaf,
17204
+	0xa7, 0xcc, 0x95, 0x6e, 0x9e, 0x9c, 0x96, 0x51, 0x84, 0xdb, 0x72, 0x06, 0x6c, 0x7e, 0xd0, 0x1d,
17205
+	0x48, 0x6f, 0x75, 0xd8, 0xd9, 0x2e, 0x0a, 0x88, 0x08, 0x62, 0x8b, 0x7a, 0x7e, 0xe9, 0x86, 0x4c,
17206
+	0xee, 0xa2, 0x8a, 0xd5, 0xdf, 0x4b, 0x40, 0x56, 0x6c, 0xa6, 0xd8, 0x89, 0xaa, 0xc2, 0x7c, 0x70,
17207
+	0x4d, 0x20, 0x8a, 0xbb, 0xf7, 0x2e, 0x2f, 0xc4, 0x2a, 0xb2, 0x6e, 0x12, 0xcb, 0x2f, 0x90, 0x2b,
17208
+	0x7d, 0x08, 0xc5, 0x28, 0xe3, 0x73, 0x2d, 0xbe, 0xef, 0x43, 0x81, 0xad, 0xef, 0xa0, 0x20, 0x7b,
17209
+	0x0c, 0x59, 0x11, 0x10, 0xc2, 0xb3, 0xe6, 0xf2, 0xaa, 0x50, 0x22, 0xd1, 0x53, 0x98, 0x17, 0x95,
17210
+	0x64, 0x70, 0x3b, 0xbc, 0x76, 0xf5, 0x2e, 0xc2, 0x01, 0x5c, 0xfd, 0x18, 0xd2, 0x5d, 0x42, 0x5c,
17211
+	0xe6, 0x7b, 0x87, 0x9a, 0x64, 0x7a, 0x3c, 0xcb, 0x22, 0xd8, 0x24, 0xad, 0x06, 0x2b, 0x82, 0x4d,
17212
+	0xd2, 0x32, 0xc3, 0xfb, 0xaf, 0x64, 0xe4, 0xfe, 0xab, 0x0f, 0xc5, 0x17, 0xc4, 0x1a, 0x1c, 0xf8,
17213
+	0xc4, 0xe4, 0x8a, 0xee, 0x43, 0x7a, 0x44, 0x42, 0xe3, 0x57, 0x63, 0x17, 0x18, 0x21, 0x2e, 0xe6,
17214
+	0x28, 0x16, 0x47, 0x8e, 0xb9, 0xb4, 0x7c, 0xd2, 0x90, 0x2d, 0xf5, 0xef, 0x93, 0xb0, 0xd8, 0xf2,
17215
+	0xbc, 0xb1, 0xee, 0x18, 0x41, 0xe6, 0xf6, 0xed, 0x8b, 0x99, 0x5b, 0xec, 0xdb, 0xcf, 0x45, 0x91,
17216
+	0x8b, 0xd7, 0x7a, 0xf2, 0xf4, 0x4c, 0x86, 0xa7, 0xa7, 0xfa, 0xd3, 0x44, 0x70, 0x77, 0x77, 0x37,
17217
+	0xb2, 0xdd, 0x45, 0x1d, 0x18, 0xd5, 0x44, 0x76, 0x9d, 0x43, 0x87, 0x1e, 0x3b, 0xe8, 0x6d, 0xc8,
17218
+	0xe0, 0x66, 0xbb, 0xf9, 0x42, 0x49, 0x88, 0xe5, 0x79, 0x01, 0x84, 0x89, 0x43, 0x8e, 0x99, 0xa6,
17219
+	0x6e, 0xb3, 0xdd, 0x60, 0x99, 0x56, 0x32, 0x46, 0x53, 0x97, 0x38, 0xa6, 0xe5, 0x0c, 0xd0, 0x3b,
17220
+	0x90, 0x6d, 0xf5, 0x7a, 0xbb, 0xbc, 0x4c, 0x7c, 0xeb, 0xe4, 0xb4, 0x7c, 0xe3, 0x02, 0x8a, 0xdf,
17221
+	0xdb, 0x9a, 0x0c, 0xc4, 0xca, 0x1c, 0x96, 0x83, 0xc5, 0x80, 0x58, 0xfe, 0x2c, 0x40, 0xb8, 0xd3,
17222
+	0xaf, 0xf6, 0x9b, 0x4a, 0x26, 0x06, 0x84, 0x29, 0xfb, 0x2b, 0xb7, 0xdb, 0x3f, 0x27, 0x41, 0xa9,
17223
+	0x1a, 0x06, 0x19, 0xf9, 0x8c, 0x2f, 0x2b, 0xcb, 0x3e, 0xe4, 0x46, 0xec, 0x97, 0x45, 0x82, 0x2c,
17224
+	0xe9, 0x69, 0xec, 0xeb, 0xe5, 0x8c, 0x5c, 0x05, 0x53, 0x9b, 0x54, 0xcd, 0xa1, 0xe5, 0x79, 0x16,
17225
+	0x75, 0x04, 0x0d, 0x87, 0x9a, 0x4a, 0xff, 0x91, 0x80, 0x1b, 0x31, 0x08, 0xf4, 0x10, 0xd2, 0x2e,
17226
+	0xb5, 0x83, 0x39, 0xbc, 0x7d, 0xd9, 0xb5, 0x2c, 0x13, 0xc5, 0x1c, 0x89, 0xd6, 0x00, 0xf4, 0xb1,
17227
+	0x4f, 0x75, 0xde, 0x3f, 0x9f, 0xbd, 0x1c, 0x8e, 0x50, 0xd0, 0x0b, 0xc8, 0x7a, 0xc4, 0x70, 0x49,
17228
+	0x90, 0x4b, 0x7f, 0xfc, 0x7f, 0xb5, 0xbe, 0xd2, 0xe3, 0x6a, 0xb0, 0x54, 0x57, 0xaa, 0x40, 0x56,
17229
+	0x50, 0xd8, 0xb2, 0x37, 0x75, 0x5f, 0x97, 0x97, 0xf6, 0xfc, 0x37, 0x5b, 0x4d, 0xba, 0x3d, 0x08,
17230
+	0x56, 0x93, 0x6e, 0x0f, 0xd4, 0xbf, 0x49, 0x02, 0x34, 0x5f, 0xfa, 0xc4, 0x75, 0x74, 0xbb, 0x5e,
17231
+	0x45, 0xcd, 0x48, 0xf4, 0x17, 0xa3, 0xfd, 0x6a, 0xec, 0x4b, 0x44, 0x28, 0x51, 0xa9, 0x57, 0x63,
17232
+	0xe2, 0xff, 0x2d, 0x48, 0x8d, 0x5d, 0xf9, 0x20, 0x2d, 0xf2, 0xe0, 0x5d, 0xbc, 0x8d, 0x19, 0x0d,
17233
+	0x35, 0xa7, 0x61, 0x2b, 0x75, 0xf9, 0xb3, 0x73, 0xa4, 0x83, 0xd8, 0xd0, 0xc5, 0x76, 0xbe, 0xa1,
17234
+	0x6b, 0x06, 0x91, 0x27, 0x47, 0x51, 0xec, 0xfc, 0x7a, 0xb5, 0x4e, 0x5c, 0x1f, 0x67, 0x0d, 0x9d,
17235
+	0xfd, 0xff, 0x42, 0xf1, 0xed, 0x3e, 0xc0, 0x74, 0x68, 0x68, 0x0d, 0x32, 0xf5, 0x8d, 0x5e, 0x6f,
17236
+	0x5b, 0x99, 0x13, 0x01, 0x7c, 0xca, 0xe2, 0x64, 0xf5, 0x2f, 0x93, 0x90, 0xab, 0x57, 0xe5, 0xb1,
17237
+	0x5a, 0x07, 0x85, 0x47, 0x25, 0xfe, 0xd4, 0x41, 0x5e, 0x8e, 0x2c, 0x77, 0x22, 0x03, 0xcb, 0x15,
17238
+	0x45, 0xed, 0x22, 0x13, 0x61, 0x56, 0x37, 0xb9, 0x00, 0xc2, 0x50, 0x24, 0xd2, 0x09, 0x9a, 0xa1,
17239
+	0x07, 0x31, 0x7e, 0xed, 0x6a, 0x67, 0x89, 0xf2, 0x64, 0xda, 0xf6, 0x70, 0x21, 0x50, 0x52, 0xd7,
17240
+	0x3d, 0xf4, 0x01, 0x2c, 0x79, 0xd6, 0xc0, 0xb1, 0x9c, 0x81, 0x16, 0x38, 0x8f, 0xbf, 0xbb, 0xd4,
17241
+	0x96, 0xcf, 0xcf, 0xd6, 0x17, 0x7a, 0x82, 0x25, 0x7d, 0xb8, 0x20, 0x91, 0x75, 0xee, 0x4a, 0xf4,
17242
+	0x4d, 0x58, 0x8c, 0x88, 0x32, 0x2f, 0x0a, 0xb7, 0x2b, 0xe7, 0x67, 0xeb, 0xc5, 0x50, 0xf2, 0x19,
17243
+	0x99, 0xe0, 0x62, 0x28, 0xf8, 0x8c, 0xf0, 0xfb, 0x97, 0x7d, 0xea, 0x1a, 0x44, 0x73, 0xf9, 0x9e,
17244
+	0xe6, 0x27, 0x78, 0x1a, 0x17, 0x38, 0x4d, 0x6c, 0x73, 0xf5, 0x39, 0xdc, 0xe8, 0xb8, 0xc6, 0x01,
17245
+	0xf1, 0x7c, 0xe1, 0x0a, 0xe9, 0xc5, 0x8f, 0xe1, 0xb6, 0xaf, 0x7b, 0x87, 0xda, 0x81, 0xe5, 0xf9,
17246
+	0xd4, 0x9d, 0x68, 0x2e, 0xf1, 0x89, 0xc3, 0xf8, 0x1a, 0x7f, 0xac, 0x95, 0x97, 0x7e, 0xb7, 0x18,
17247
+	0x66, 0x4b, 0x40, 0x70, 0x80, 0xd8, 0x66, 0x00, 0xb5, 0x05, 0x45, 0x56, 0xa6, 0xc8, 0x8b, 0x33,
17248
+	0x36, 0x7a, 0xb0, 0xe9, 0x40, 0x7b, 0xe3, 0x63, 0x2a, 0x6f, 0xd3, 0x81, 0xf8, 0xa9, 0x7e, 0x17,
17249
+	0x94, 0x86, 0xe5, 0x8d, 0x74, 0xdf, 0x38, 0x08, 0x6e, 0x33, 0x51, 0x03, 0x94, 0x03, 0xa2, 0xbb,
17250
+	0xfe, 0x1e, 0xd1, 0x7d, 0x6d, 0x44, 0x5c, 0x8b, 0x9a, 0xd7, 0xcf, 0xf2, 0x52, 0x28, 0xd2, 0xe5,
17251
+	0x12, 0xea, 0x7f, 0x25, 0x00, 0xb0, 0xbe, 0x1f, 0x64, 0x64, 0x5f, 0x83, 0x65, 0xcf, 0xd1, 0x47,
17252
+	0xde, 0x01, 0xf5, 0x35, 0xcb, 0xf1, 0x89, 0x7b, 0xa4, 0xdb, 0xf2, 0x02, 0x47, 0x09, 0x18, 0x2d,
17253
+	0x49, 0x47, 0xf7, 0x01, 0x1d, 0x12, 0x32, 0xd2, 0xa8, 0x6d, 0x6a, 0x01, 0x53, 0x3c, 0x25, 0xa7,
17254
+	0xb1, 0xc2, 0x38, 0x1d, 0xdb, 0xec, 0x05, 0x74, 0x54, 0x83, 0x35, 0x36, 0x7c, 0xe2, 0xf8, 0xae,
17255
+	0x45, 0x3c, 0x6d, 0x9f, 0xba, 0x9a, 0x67, 0xd3, 0x63, 0x6d, 0x9f, 0xda, 0x36, 0x3d, 0x26, 0x6e,
17256
+	0x70, 0x37, 0x56, 0xb2, 0xe9, 0xa0, 0x29, 0x40, 0x1b, 0xd4, 0xed, 0xd9, 0xf4, 0x78, 0x23, 0x40,
17257
+	0xb0, 0xb4, 0x6d, 0x3a, 0x66, 0xdf, 0x32, 0x0e, 0x83, 0xb4, 0x2d, 0xa4, 0xf6, 0x2d, 0xe3, 0x10,
17258
+	0xbd, 0x03, 0x0b, 0xc4, 0x26, 0xfc, 0x8a, 0x44, 0xa0, 0x32, 0x1c, 0x55, 0x0c, 0x88, 0x0c, 0xa4,
17259
+	0x7e, 0x02, 0x4a, 0xd3, 0x31, 0xdc, 0xc9, 0x28, 0x32, 0xe7, 0xf7, 0x01, 0xb1, 0x20, 0xa9, 0xd9,
17260
+	0xd4, 0x38, 0xd4, 0x86, 0xba, 0xa3, 0x0f, 0x98, 0x5d, 0xe2, 0x85, 0x4f, 0x61, 0x9c, 0x6d, 0x6a,
17261
+	0x1c, 0xee, 0x48, 0xba, 0xfa, 0x01, 0x40, 0x6f, 0xe4, 0x12, 0xdd, 0xec, 0xb0, 0x6c, 0x82, 0xb9,
17262
+	0x8e, 0xb7, 0x34, 0x53, 0xbe, 0x90, 0x52, 0x57, 0x6e, 0x75, 0x45, 0x30, 0x1a, 0x21, 0x5d, 0xfd,
17263
+	0x79, 0xb8, 0xd1, 0xb5, 0x75, 0x83, 0x7f, 0x2d, 0xd0, 0x0d, 0x9f, 0xac, 0xd0, 0x53, 0xc8, 0x0a,
17264
+	0xa8, 0x9c, 0xc9, 0xd8, 0xed, 0x36, 0xed, 0x73, 0x6b, 0x0e, 0x4b, 0x7c, 0xad, 0x08, 0x30, 0xd5,
17265
+	0xa3, 0xfe, 0x79, 0x02, 0xf2, 0xa1, 0x7e, 0x54, 0x16, 0x2f, 0x31, 0xbe, 0xab, 0x5b, 0x8e, 0xac,
17266
+	0xea, 0xf3, 0x38, 0x4a, 0x42, 0x2d, 0x28, 0x8c, 0x42, 0xe9, 0x2b, 0xf3, 0xb9, 0x18, 0xab, 0x71,
17267
+	0x54, 0x16, 0x7d, 0x08, 0xf9, 0xe0, 0x49, 0x3a, 0x88, 0xb0, 0x57, 0xbf, 0x60, 0x4f, 0xe1, 0xea,
17268
+	0xb7, 0x01, 0xbe, 0x43, 0x2d, 0xa7, 0x4f, 0x0f, 0x89, 0xc3, 0x9f, 0x58, 0x59, 0x4d, 0x48, 0x02,
17269
+	0x2f, 0xca, 0x16, 0x2f, 0xf5, 0xc5, 0x14, 0x84, 0x2f, 0x8d, 0xa2, 0xa9, 0xfe, 0x75, 0x12, 0xb2,
17270
+	0x98, 0x52, 0xbf, 0x5e, 0x45, 0x65, 0xc8, 0xca, 0x38, 0xc1, 0xcf, 0x9f, 0x5a, 0xfe, 0xfc, 0x6c,
17271
+	0x3d, 0x23, 0x02, 0x44, 0xc6, 0xe0, 0x91, 0x21, 0x12, 0xc1, 0x93, 0x97, 0x45, 0x70, 0xf4, 0x10,
17272
+	0x8a, 0x12, 0xa4, 0x1d, 0xe8, 0xde, 0x81, 0x28, 0xd0, 0x6a, 0x8b, 0xe7, 0x67, 0xeb, 0x20, 0x90,
17273
+	0x5b, 0xba, 0x77, 0x80, 0x41, 0xa0, 0xd9, 0x6f, 0xd4, 0x84, 0xc2, 0xa7, 0xd4, 0x72, 0x34, 0x9f,
17274
+	0x0f, 0x42, 0x5e, 0x26, 0xc6, 0xce, 0xe3, 0x74, 0xa8, 0xf2, 0x7b, 0x03, 0xf8, 0x74, 0x3a, 0xf8,
17275
+	0x26, 0x2c, 0xb8, 0x94, 0xfa, 0x22, 0x6c, 0x59, 0xd4, 0x91, 0xf7, 0x14, 0xe5, 0xd8, 0xeb, 0x6b,
17276
+	0x4a, 0x7d, 0x2c, 0x71, 0xb8, 0xe8, 0x46, 0x5a, 0xe8, 0x21, 0xac, 0xd8, 0xba, 0xe7, 0x6b, 0x3c,
17277
+	0xde, 0x99, 0x53, 0x6d, 0x59, 0xbe, 0xd5, 0x10, 0xe3, 0x6d, 0x70, 0x56, 0x20, 0xa1, 0xfe, 0x63,
17278
+	0x02, 0x0a, 0x6c, 0x30, 0xd6, 0xbe, 0x65, 0xb0, 0x24, 0xef, 0xf3, 0xe7, 0x1e, 0xb7, 0x20, 0x65,
17279
+	0x78, 0xae, 0x74, 0x2a, 0x3f, 0x7c, 0xeb, 0x3d, 0x8c, 0x19, 0x0d, 0x7d, 0x02, 0x59, 0x79, 0x5f,
17280
+	0x22, 0xd2, 0x0e, 0xf5, 0xfa, 0x74, 0x54, 0xfa, 0x46, 0xca, 0xf1, 0xb5, 0x3c, 0xb5, 0x4e, 0x1c,
17281
+	0x02, 0x38, 0x4a, 0x42, 0x37, 0x21, 0x69, 0x08, 0x77, 0xc9, 0x0f, 0x5a, 0xea, 0x6d, 0x9c, 0x34,
17282
+	0x1c, 0xf5, 0x47, 0x09, 0x58, 0x98, 0x6e, 0x78, 0xb6, 0x02, 0x6e, 0x43, 0xde, 0x1b, 0xef, 0x79,
17283
+	0x13, 0xcf, 0x27, 0xc3, 0xe0, 0xf9, 0x38, 0x24, 0xa0, 0x16, 0xe4, 0x75, 0x7b, 0x40, 0x5d, 0xcb,
17284
+	0x3f, 0x18, 0xca, 0x4a, 0x34, 0x3e, 0x55, 0x88, 0xea, 0xac, 0x54, 0x03, 0x11, 0x3c, 0x95, 0x0e,
17285
+	0xce, 0x7d, 0xf1, 0x8d, 0x01, 0x3f, 0xf7, 0xdf, 0x86, 0xa2, 0xad, 0x0f, 0xf9, 0x05, 0x92, 0x6f,
17286
+	0x0d, 0xc5, 0x38, 0xd2, 0xb8, 0x20, 0x69, 0x7d, 0x6b, 0x48, 0x54, 0x15, 0xf2, 0xa1, 0x32, 0xb4,
17287
+	0x04, 0x85, 0x6a, 0xb3, 0xa7, 0x3d, 0x7a, 0xfc, 0x54, 0xdb, 0xac, 0xef, 0x28, 0x73, 0x32, 0x37,
17288
+	0xfd, 0x8b, 0x04, 0x2c, 0xc8, 0x70, 0x24, 0xf3, 0xfd, 0x77, 0x60, 0xde, 0xd5, 0xf7, 0xfd, 0xa0,
17289
+	0x22, 0x49, 0x8b, 0x55, 0xcd, 0x22, 0x3c, 0xab, 0x48, 0x18, 0x2b, 0xbe, 0x22, 0x89, 0x7c, 0xd0,
17290
+	0x90, 0xba, 0xf2, 0x83, 0x86, 0xf4, 0xcf, 0xe4, 0x83, 0x06, 0xf5, 0x57, 0x01, 0x36, 0x2c, 0x9b,
17291
+	0xf4, 0xc5, 0x5d, 0x53, 0x5c, 0x7d, 0xc9, 0x72, 0x38, 0x79, 0x97, 0x19, 0xe4, 0x70, 0xad, 0x06,
17292
+	0x66, 0x34, 0xc6, 0x1a, 0x58, 0xa6, 0xdc, 0x8c, 0x9c, 0xb5, 0xc9, 0x58, 0x03, 0xcb, 0x0c, 0x5f,
17293
+	0xde, 0xd2, 0xd7, 0xbd, 0xbc, 0x9d, 0x26, 0x60, 0x49, 0xe6, 0xae, 0x61, 0xf8, 0xfd, 0x2a, 0xe4,
17294
+	0x45, 0x1a, 0x3b, 0x2d, 0xe8, 0xf8, 0x23, 0xbe, 0xc0, 0xb5, 0x1a, 0x38, 0x27, 0xd8, 0x2d, 0x13,
17295
+	0xad, 0x43, 0x41, 0x42, 0x23, 0x1f, 0x3f, 0x81, 0x20, 0xb5, 0x99, 0xf9, 0x5f, 0x87, 0xf4, 0xbe,
17296
+	0x65, 0x13, 0xb9, 0xd0, 0x63, 0x03, 0xc0, 0xd4, 0x01, 0x5b, 0x73, 0x98, 0xa3, 0x6b, 0xb9, 0xe0,
17297
+	0x32, 0x8e, 0xdb, 0x27, 0xcb, 0xce, 0xa8, 0x7d, 0xa2, 0x02, 0x9d, 0xb1, 0x4f, 0xe0, 0x98, 0x7d,
17298
+	0x82, 0x2d, 0xec, 0x93, 0xd0, 0xa8, 0x7d, 0x82, 0xf4, 0x33, 0xb1, 0x6f, 0x1b, 0x6e, 0xd6, 0x6c,
17299
+	0xdd, 0x38, 0xb4, 0x2d, 0xcf, 0x27, 0x66, 0x34, 0x62, 0x3c, 0x86, 0xec, 0x85, 0xa4, 0xf3, 0xaa,
17300
+	0x5b, 0x4b, 0x89, 0x54, 0xff, 0x2d, 0x01, 0xc5, 0x2d, 0xa2, 0xdb, 0xfe, 0xc1, 0xf4, 0x6a, 0xc8,
17301
+	0x27, 0x9e, 0x2f, 0x0f, 0x2b, 0xfe, 0x1b, 0x7d, 0x03, 0x72, 0x61, 0x4e, 0x72, 0xed, 0xfb, 0x5b,
17302
+	0x08, 0x45, 0x4f, 0x60, 0x9e, 0xed, 0x31, 0x3a, 0x0e, 0x8a, 0x9d, 0xab, 0x9e, 0x76, 0x24, 0x92,
17303
+	0x1d, 0x32, 0x2e, 0xe1, 0x49, 0x08, 0x5f, 0x4a, 0x19, 0x1c, 0x34, 0xd1, 0xff, 0x87, 0x22, 0x7f,
17304
+	0x99, 0x08, 0x72, 0xae, 0xcc, 0x75, 0x3a, 0x0b, 0xe2, 0x71, 0x51, 0xe4, 0x5b, 0xff, 0x93, 0x80,
17305
+	0x95, 0x1d, 0x7d, 0xb2, 0x47, 0x64, 0xd8, 0x20, 0x26, 0x26, 0x06, 0x75, 0x4d, 0xd4, 0x8d, 0x86,
17306
+	0x9b, 0x2b, 0xde, 0x2a, 0xe3, 0x84, 0xe3, 0xa3, 0x4e, 0x50, 0x80, 0x25, 0x23, 0x05, 0xd8, 0x0a,
17307
+	0x64, 0x1c, 0xea, 0x18, 0x44, 0xc6, 0x22, 0xd1, 0x50, 0xad, 0x68, 0xa8, 0x29, 0x85, 0xcf, 0x88,
17308
+	0xfc, 0x11, 0xb0, 0x4d, 0xfd, 0xb0, 0x37, 0xf4, 0x09, 0x94, 0x7a, 0xcd, 0x3a, 0x6e, 0xf6, 0x6b,
17309
+	0x9d, 0xef, 0x6a, 0xbd, 0xea, 0x76, 0xaf, 0xfa, 0xf8, 0xa1, 0xd6, 0xed, 0x6c, 0x7f, 0xef, 0xd1,
17310
+	0x93, 0x87, 0xdf, 0x50, 0x12, 0xa5, 0xf2, 0xc9, 0x69, 0xf9, 0x76, 0xbb, 0x5a, 0xdf, 0x16, 0x3b,
17311
+	0x66, 0x8f, 0xbe, 0xec, 0xe9, 0xb6, 0xa7, 0x3f, 0x7e, 0xd8, 0xa5, 0xf6, 0x84, 0x61, 0xd8, 0xb2,
17312
+	0x2e, 0x46, 0xcf, 0xab, 0xe8, 0x31, 0x9c, 0xb8, 0xf4, 0x18, 0x9e, 0x9e, 0xe6, 0xc9, 0x4b, 0x4e,
17313
+	0xf3, 0x0d, 0x58, 0x31, 0x5c, 0xea, 0x79, 0x1a, 0xcb, 0xfe, 0x89, 0x39, 0x53, 0x5f, 0x7c, 0xe9,
17314
+	0xfc, 0x6c, 0x7d, 0xb9, 0xce, 0xf8, 0x3d, 0xce, 0x96, 0xea, 0x97, 0x8d, 0x08, 0x89, 0xf7, 0xa4,
17315
+	0xfe, 0x7e, 0x8a, 0x25, 0x52, 0xd6, 0x91, 0x65, 0x93, 0x01, 0xf1, 0xd0, 0x73, 0x58, 0x32, 0x5c,
17316
+	0x62, 0xb2, 0xb4, 0x5e, 0xb7, 0xa3, 0x1f, 0xd1, 0xfe, 0xbf, 0xd8, 0x9c, 0x26, 0x14, 0xac, 0xd4,
17317
+	0x43, 0xa9, 0xde, 0x88, 0x18, 0x78, 0xd1, 0xb8, 0xd0, 0x46, 0x9f, 0xc2, 0x92, 0x47, 0x6c, 0xcb,
17318
+	0x19, 0xbf, 0xd4, 0x0c, 0xea, 0xf8, 0xe4, 0x65, 0xf0, 0x22, 0x76, 0x9d, 0xde, 0x5e, 0x73, 0x9b,
17319
+	0x49, 0xd5, 0x85, 0x50, 0x0d, 0x9d, 0x9f, 0xad, 0x2f, 0x5e, 0xa4, 0xe1, 0x45, 0xa9, 0x59, 0xb6,
17320
+	0x4b, 0x6d, 0x58, 0xbc, 0x68, 0x0d, 0x5a, 0x91, 0x7b, 0x9f, 0x87, 0x90, 0x60, 0x6f, 0xa3, 0xdb,
17321
+	0x90, 0x73, 0xc9, 0xc0, 0xf2, 0x7c, 0x57, 0xb8, 0x99, 0x71, 0x42, 0x0a, 0xdb, 0xf9, 0xe2, 0x0b,
17322
+	0xa8, 0xd2, 0x2f, 0xc3, 0x4c, 0x8f, 0x6c, 0xb3, 0x98, 0x96, 0xa7, 0xef, 0x49, 0x95, 0x39, 0x1c,
17323
+	0x34, 0xd9, 0x1a, 0x1c, 0x7b, 0x61, 0xa2, 0xc6, 0x7f, 0x33, 0x1a, 0xcf, 0x28, 0xe4, 0xf7, 0x60,
17324
+	0x3c, 0x67, 0x08, 0x3e, 0x2c, 0x4d, 0x47, 0x3e, 0x2c, 0x5d, 0x81, 0x8c, 0x4d, 0x8e, 0x88, 0x2d,
17325
+	0xce, 0x72, 0x2c, 0x1a, 0xf7, 0x1e, 0x42, 0x31, 0xf8, 0x82, 0x91, 0x7f, 0x39, 0x91, 0x83, 0x74,
17326
+	0xbf, 0xda, 0x7b, 0xa6, 0xcc, 0x21, 0x80, 0xac, 0x58, 0x9c, 0xe2, 0xb5, 0xae, 0xde, 0x69, 0x6f,
17327
+	0xb4, 0x36, 0x95, 0xe4, 0xbd, 0xdf, 0x49, 0x43, 0x3e, 0x7c, 0x2f, 0x62, 0x67, 0x47, 0xbb, 0xf9,
17328
+	0x22, 0x58, 0xdd, 0x21, 0xbd, 0x4d, 0x8e, 0xd1, 0xdb, 0xd3, 0x5b, 0xa8, 0x4f, 0xc4, 0x03, 0x79,
17329
+	0xc8, 0x0e, 0x6e, 0xa0, 0xde, 0x85, 0x5c, 0xb5, 0xd7, 0x6b, 0x6d, 0xb6, 0x9b, 0x0d, 0xe5, 0xb3,
17330
+	0x44, 0xe9, 0x4b, 0x27, 0xa7, 0xe5, 0xe5, 0x10, 0x54, 0xf5, 0xc4, 0xe2, 0xe3, 0xa8, 0x7a, 0xbd,
17331
+	0xd9, 0xed, 0x37, 0x1b, 0xca, 0xab, 0xe4, 0x2c, 0x8a, 0xdf, 0xaa, 0xf0, 0x4f, 0x77, 0xf2, 0x5d,
17332
+	0xdc, 0xec, 0x56, 0x31, 0xeb, 0xf0, 0xb3, 0xa4, 0xb8, 0x1c, 0x9b, 0xf6, 0xe8, 0x92, 0x91, 0xee,
17333
+	0xb2, 0x3e, 0xd7, 0x82, 0x6f, 0xe1, 0x5e, 0xa5, 0xc4, 0xe7, 0x1d, 0xd3, 0xc7, 0x2f, 0xa2, 0x9b,
17334
+	0x13, 0xd6, 0x1b, 0x7f, 0x75, 0xe4, 0x6a, 0x52, 0x33, 0xbd, 0xf5, 0x58, 0xec, 0x61, 0x5a, 0x54,
17335
+	0x98, 0xc7, 0xbb, 0xed, 0x36, 0x03, 0xbd, 0x4a, 0xcf, 0x8c, 0x0e, 0x8f, 0x1d, 0x56, 0x31, 0xa3,
17336
+	0xbb, 0x90, 0x0b, 0x1e, 0x25, 0x95, 0xcf, 0xd2, 0x33, 0x06, 0xd5, 0x83, 0x17, 0x55, 0xde, 0xe1,
17337
+	0xd6, 0x6e, 0x9f, 0x7f, 0xaa, 0xf7, 0x2a, 0x33, 0xdb, 0xe1, 0xc1, 0xd8, 0x37, 0xe9, 0xb1, 0xc3,
17338
+	0xf6, 0xac, 0xbc, 0x87, 0xfb, 0x2c, 0x23, 0x2e, 0x2d, 0x42, 0x8c, 0xbc, 0x84, 0x7b, 0x17, 0x72,
17339
+	0xb8, 0xf9, 0x1d, 0xf1, 0x55, 0xdf, 0xab, 0xec, 0x8c, 0x1e, 0x4c, 0x3e, 0x25, 0x06, 0xeb, 0xad,
17340
+	0x0c, 0x59, 0xdc, 0xdc, 0xe9, 0x3c, 0x6f, 0x2a, 0x7f, 0x90, 0x9d, 0xd1, 0x83, 0xc9, 0x90, 0xf2,
17341
+	0x6f, 0x9b, 0x72, 0x1d, 0xdc, 0xdd, 0xaa, 0xf2, 0x49, 0x99, 0xd5, 0xd3, 0x71, 0x47, 0x07, 0xba,
17342
+	0x43, 0xcc, 0xe9, 0x57, 0x30, 0x21, 0xeb, 0xde, 0x2f, 0x40, 0x2e, 0xc8, 0x5d, 0xd1, 0x1a, 0x64,
17343
+	0x5f, 0x74, 0xf0, 0xb3, 0x26, 0x56, 0xe6, 0x84, 0x97, 0x03, 0xce, 0x0b, 0x51, 0x75, 0x94, 0x61,
17344
+	0x7e, 0xa7, 0xda, 0xae, 0x6e, 0x36, 0x71, 0x70, 0x89, 0x1e, 0x00, 0x64, 0x02, 0x56, 0x52, 0x64,
17345
+	0x07, 0xa1, 0xce, 0xda, 0xea, 0x0f, 0x7f, 0xb2, 0x36, 0xf7, 0xe3, 0x9f, 0xac, 0xcd, 0xbd, 0x3a,
17346
+	0x5f, 0x4b, 0xfc, 0xf0, 0x7c, 0x2d, 0xf1, 0x77, 0xe7, 0x6b, 0x89, 0x7f, 0x3d, 0x5f, 0x4b, 0xec,
17347
+	0x65, 0xf9, 0x31, 0xf1, 0xe4, 0x7f, 0x03, 0x00, 0x00, 0xff, 0xff, 0x08, 0x6c, 0xc9, 0x88, 0x12,
17348
+	0x32, 0x00, 0x00,
17347 17349
 }
... ...
@@ -458,7 +458,16 @@ enum TaskState {
458 458
 	SHUTDOWN = 640 [(gogoproto.enumvalue_customname)="TaskStateShutdown"]; // orchestrator requested shutdown
459 459
 	FAILED = 704 [(gogoproto.enumvalue_customname)="TaskStateFailed"]; // task execution failed with error
460 460
 	REJECTED = 768 [(gogoproto.enumvalue_customname)="TaskStateRejected"]; // task could not be executed here.
461
-	ORPHANED = 832 [(gogoproto.enumvalue_customname)="TaskStateOrphaned"]; // The node on which this task is scheduled is Down for too long
461
+	// TaskStateRemove is used to correctly handle service deletions and scale
462
+	// downs. This allows us to keep track of tasks that have been marked for
463
+	// deletion, but can't yet be removed because the agent is in the process of
464
+	// shutting them down. Once the agent has shut down tasks with desired state
465
+	// REMOVE, the task reaper is responsible for removing them.
466
+	REMOVE = 800 [(gogoproto.enumvalue_customname)="TaskStateRemove"];
467
+	// TaskStateOrphaned is used to free up resources associated with service
468
+	// tasks on unresponsive nodes without having to delete those tasks. This
469
+	// state is directly assigned to the task by the orchestrator.
470
+	ORPHANED = 832 [(gogoproto.enumvalue_customname)="TaskStateOrphaned"];
462 471
 
463 472
 	// NOTE(stevvooe): The state of a task is actually a lamport clock, in that
464 473
 	// given two observations, the greater of the two can be considered
... ...
@@ -19,6 +19,7 @@ import (
19 19
 
20 20
 import raftselector "github.com/docker/swarmkit/manager/raftselector"
21 21
 import codes "google.golang.org/grpc/codes"
22
+import status "google.golang.org/grpc/status"
22 23
 import metadata "google.golang.org/grpc/metadata"
23 24
 import transport "google.golang.org/grpc/transport"
24 25
 import rafttime "time"
... ...
@@ -2043,12 +2044,12 @@ func NewRaftProxyWatchServer(local WatchServer, connSelector raftselector.ConnPr
2043 2043
 	redirectChecker := func(ctx context.Context) (context.Context, error) {
2044 2044
 		s, ok := transport.StreamFromContext(ctx)
2045 2045
 		if !ok {
2046
-			return ctx, grpc.Errorf(codes.InvalidArgument, "remote addr is not found in context")
2046
+			return ctx, status.Errorf(codes.InvalidArgument, "remote addr is not found in context")
2047 2047
 		}
2048 2048
 		addr := s.ServerTransport().RemoteAddr().String()
2049 2049
 		md, ok := metadata.FromContext(ctx)
2050 2050
 		if ok && len(md["redirect"]) != 0 {
2051
-			return ctx, grpc.Errorf(codes.ResourceExhausted, "more than one redirect to leader from: %s", md["redirect"])
2051
+			return ctx, status.Errorf(codes.ResourceExhausted, "more than one redirect to leader from: %s", md["redirect"])
2052 2052
 		}
2053 2053
 		if !ok {
2054 2054
 			md = metadata.New(map[string]string{})
... ...
@@ -10,10 +10,10 @@ import (
10 10
 	"github.com/docker/swarmkit/api"
11 11
 	"github.com/docker/swarmkit/log"
12 12
 	"golang.org/x/net/context"
13
-	"google.golang.org/grpc"
14 13
 	"google.golang.org/grpc/codes"
15 14
 	"google.golang.org/grpc/credentials"
16 15
 	"google.golang.org/grpc/peer"
16
+	"google.golang.org/grpc/status"
17 17
 )
18 18
 
19 19
 type localRequestKeyType struct{}
... ...
@@ -52,13 +52,13 @@ func LogTLSState(ctx context.Context, tlsState *tls.ConnectionState) {
52 52
 // getCertificateSubject extracts the subject from a verified client certificate
53 53
 func getCertificateSubject(tlsState *tls.ConnectionState) (pkix.Name, error) {
54 54
 	if tlsState == nil {
55
-		return pkix.Name{}, grpc.Errorf(codes.PermissionDenied, "request is not using TLS")
55
+		return pkix.Name{}, status.Errorf(codes.PermissionDenied, "request is not using TLS")
56 56
 	}
57 57
 	if len(tlsState.PeerCertificates) == 0 {
58
-		return pkix.Name{}, grpc.Errorf(codes.PermissionDenied, "no client certificates in request")
58
+		return pkix.Name{}, status.Errorf(codes.PermissionDenied, "no client certificates in request")
59 59
 	}
60 60
 	if len(tlsState.VerifiedChains) == 0 {
61
-		return pkix.Name{}, grpc.Errorf(codes.PermissionDenied, "no verified chains for remote certificate")
61
+		return pkix.Name{}, status.Errorf(codes.PermissionDenied, "no verified chains for remote certificate")
62 62
 	}
63 63
 
64 64
 	return tlsState.VerifiedChains[0][0].Subject, nil
... ...
@@ -67,11 +67,11 @@ func getCertificateSubject(tlsState *tls.ConnectionState) (pkix.Name, error) {
67 67
 func tlsConnStateFromContext(ctx context.Context) (*tls.ConnectionState, error) {
68 68
 	peer, ok := peer.FromContext(ctx)
69 69
 	if !ok {
70
-		return nil, grpc.Errorf(codes.PermissionDenied, "Permission denied: no peer info")
70
+		return nil, status.Errorf(codes.PermissionDenied, "Permission denied: no peer info")
71 71
 	}
72 72
 	tlsInfo, ok := peer.AuthInfo.(credentials.TLSInfo)
73 73
 	if !ok {
74
-		return nil, grpc.Errorf(codes.PermissionDenied, "Permission denied: peer didn't not present valid peer certificate")
74
+		return nil, status.Errorf(codes.PermissionDenied, "Permission denied: peer didn't not present valid peer certificate")
75 75
 	}
76 76
 	return &tlsInfo.State, nil
77 77
 }
... ...
@@ -98,21 +98,21 @@ func AuthorizeOrgAndRole(ctx context.Context, org string, blacklistedCerts map[s
98 98
 		return authorizeOrg(certSubj, org, blacklistedCerts)
99 99
 	}
100 100
 
101
-	return "", grpc.Errorf(codes.PermissionDenied, "Permission denied: remote certificate not part of OUs: %v", ou)
101
+	return "", status.Errorf(codes.PermissionDenied, "Permission denied: remote certificate not part of OUs: %v", ou)
102 102
 }
103 103
 
104 104
 // authorizeOrg takes in a certificate subject and an organization, and returns
105 105
 // the Node ID of the node.
106 106
 func authorizeOrg(certSubj pkix.Name, org string, blacklistedCerts map[string]*api.BlacklistedCertificate) (string, error) {
107 107
 	if _, ok := blacklistedCerts[certSubj.CommonName]; ok {
108
-		return "", grpc.Errorf(codes.PermissionDenied, "Permission denied: node %s was removed from swarm", certSubj.CommonName)
108
+		return "", status.Errorf(codes.PermissionDenied, "Permission denied: node %s was removed from swarm", certSubj.CommonName)
109 109
 	}
110 110
 
111 111
 	if len(certSubj.Organization) > 0 && certSubj.Organization[0] == org {
112 112
 		return certSubj.CommonName, nil
113 113
 	}
114 114
 
115
-	return "", grpc.Errorf(codes.PermissionDenied, "Permission denied: remote certificate not part of organization: %s", org)
115
+	return "", status.Errorf(codes.PermissionDenied, "Permission denied: remote certificate not part of organization: %s", org)
116 116
 }
117 117
 
118 118
 // AuthorizeForwardedRoleAndOrg checks for proper roles and organization of caller. The RPC may have
... ...
@@ -123,7 +123,7 @@ func AuthorizeForwardedRoleAndOrg(ctx context.Context, authorizedRoles, forwarde
123 123
 	if isForwardedRequest(ctx) {
124 124
 		_, err := AuthorizeOrgAndRole(ctx, org, blacklistedCerts, forwarderRoles...)
125 125
 		if err != nil {
126
-			return "", grpc.Errorf(codes.PermissionDenied, "Permission denied: unauthorized forwarder role: %v", err)
126
+			return "", status.Errorf(codes.PermissionDenied, "Permission denied: unauthorized forwarder role: %v", err)
127 127
 		}
128 128
 
129 129
 		// This was a forwarded request. Authorize the forwarder, and
... ...
@@ -132,15 +132,15 @@ func AuthorizeForwardedRoleAndOrg(ctx context.Context, authorizedRoles, forwarde
132 132
 		_, forwardedID, forwardedOrg, forwardedOUs := forwardedTLSInfoFromContext(ctx)
133 133
 
134 134
 		if len(forwardedOUs) == 0 || forwardedID == "" || forwardedOrg == "" {
135
-			return "", grpc.Errorf(codes.PermissionDenied, "Permission denied: missing information in forwarded request")
135
+			return "", status.Errorf(codes.PermissionDenied, "Permission denied: missing information in forwarded request")
136 136
 		}
137 137
 
138 138
 		if !intersectArrays(forwardedOUs, authorizedRoles) {
139
-			return "", grpc.Errorf(codes.PermissionDenied, "Permission denied: unauthorized forwarded role, expecting: %v", authorizedRoles)
139
+			return "", status.Errorf(codes.PermissionDenied, "Permission denied: unauthorized forwarded role, expecting: %v", authorizedRoles)
140 140
 		}
141 141
 
142 142
 		if forwardedOrg != org {
143
-			return "", grpc.Errorf(codes.PermissionDenied, "Permission denied: organization mismatch, expecting: %s", org)
143
+			return "", status.Errorf(codes.PermissionDenied, "Permission denied: organization mismatch, expecting: %s", org)
144 144
 		}
145 145
 
146 146
 		return forwardedID, nil
... ...
@@ -152,7 +152,7 @@ func AuthorizeForwardedRoleAndOrg(ctx context.Context, authorizedRoles, forwarde
152 152
 		return nodeID, nil
153 153
 	}
154 154
 
155
-	return "", grpc.Errorf(codes.PermissionDenied, "Permission denied: unauthorized peer role: %v", err)
155
+	return "", status.Errorf(codes.PermissionDenied, "Permission denied: unauthorized peer role: %v", err)
156 156
 }
157 157
 
158 158
 // intersectArrays returns true when there is at least one element in common
... ...
@@ -219,7 +219,7 @@ func RemoteNode(ctx context.Context) (RemoteNodeInfo, error) {
219 219
 
220 220
 	peer, ok := peer.FromContext(ctx)
221 221
 	if !ok {
222
-		return RemoteNodeInfo{}, grpc.Errorf(codes.PermissionDenied, "Permission denied: no peer info")
222
+		return RemoteNodeInfo{}, status.Errorf(codes.PermissionDenied, "Permission denied: no peer info")
223 223
 	}
224 224
 
225 225
 	directInfo := RemoteNodeInfo{
... ...
@@ -232,7 +232,7 @@ func RemoteNode(ctx context.Context) (RemoteNodeInfo, error) {
232 232
 	if isForwardedRequest(ctx) {
233 233
 		remoteAddr, cn, org, ous := forwardedTLSInfoFromContext(ctx)
234 234
 		if len(ous) == 0 || cn == "" || org == "" {
235
-			return RemoteNodeInfo{}, grpc.Errorf(codes.PermissionDenied, "Permission denied: missing information in forwarded request")
235
+			return RemoteNodeInfo{}, status.Errorf(codes.PermissionDenied, "Permission denied: missing information in forwarded request")
236 236
 		}
237 237
 		return RemoteNodeInfo{
238 238
 			Roles:        ous,
... ...
@@ -16,8 +16,8 @@ import (
16 16
 	"github.com/pkg/errors"
17 17
 	"github.com/sirupsen/logrus"
18 18
 	"golang.org/x/net/context"
19
-	"google.golang.org/grpc"
20 19
 	"google.golang.org/grpc/codes"
20
+	"google.golang.org/grpc/status"
21 21
 )
22 22
 
23 23
 const (
... ...
@@ -149,7 +149,7 @@ func (s *Server) GetUnlockKey(ctx context.Context, request *api.GetUnlockKeyRequ
149 149
 // NodeCertificateStatus returns the current issuance status of an issuance request identified by the nodeID
150 150
 func (s *Server) NodeCertificateStatus(ctx context.Context, request *api.NodeCertificateStatusRequest) (*api.NodeCertificateStatusResponse, error) {
151 151
 	if request.NodeID == "" {
152
-		return nil, grpc.Errorf(codes.InvalidArgument, codes.InvalidArgument.String())
152
+		return nil, status.Errorf(codes.InvalidArgument, codes.InvalidArgument.String())
153 153
 	}
154 154
 
155 155
 	serverCtx, err := s.isRunningLocked()
... ...
@@ -180,7 +180,7 @@ func (s *Server) NodeCertificateStatus(ctx context.Context, request *api.NodeCer
180 180
 
181 181
 	// This node ID doesn't exist
182 182
 	if node == nil {
183
-		return nil, grpc.Errorf(codes.NotFound, codes.NotFound.String())
183
+		return nil, status.Errorf(codes.NotFound, codes.NotFound.String())
184 184
 	}
185 185
 
186 186
 	log.G(ctx).WithFields(logrus.Fields{
... ...
@@ -236,7 +236,7 @@ func (s *Server) NodeCertificateStatus(ctx context.Context, request *api.NodeCer
236 236
 func (s *Server) IssueNodeCertificate(ctx context.Context, request *api.IssueNodeCertificateRequest) (*api.IssueNodeCertificateResponse, error) {
237 237
 	// First, let's see if the remote node is presenting a non-empty CSR
238 238
 	if len(request.CSR) == 0 {
239
-		return nil, grpc.Errorf(codes.InvalidArgument, codes.InvalidArgument.String())
239
+		return nil, status.Errorf(codes.InvalidArgument, codes.InvalidArgument.String())
240 240
 	}
241 241
 
242 242
 	if err := s.isReadyLocked(); err != nil {
... ...
@@ -295,7 +295,7 @@ func (s *Server) IssueNodeCertificate(ctx context.Context, request *api.IssueNod
295 295
 	s.mu.Unlock()
296 296
 
297 297
 	if role < 0 {
298
-		return nil, grpc.Errorf(codes.InvalidArgument, "A valid join token is necessary to join this cluster")
298
+		return nil, status.Errorf(codes.InvalidArgument, "A valid join token is necessary to join this cluster")
299 299
 	}
300 300
 
301 301
 	// Max number of collisions of ID or CN to tolerate before giving up
... ...
@@ -369,7 +369,7 @@ func (s *Server) issueRenewCertificate(ctx context.Context, nodeID string, csr [
369 369
 				"method":  "issueRenewCertificate",
370 370
 			}).Warnf("node does not exist")
371 371
 			// If this node doesn't exist, we shouldn't be renewing a certificate for it
372
-			return grpc.Errorf(codes.NotFound, "node %s not found when attempting to renew certificate", nodeID)
372
+			return status.Errorf(codes.NotFound, "node %s not found when attempting to renew certificate", nodeID)
373 373
 		}
374 374
 
375 375
 		// Create a new Certificate entry for this node with the new CSR and a RENEW state
... ...
@@ -594,7 +594,7 @@ func (s *Server) isRunningLocked() (context.Context, error) {
594 594
 	s.mu.Lock()
595 595
 	if !s.isRunning() {
596 596
 		s.mu.Unlock()
597
-		return nil, grpc.Errorf(codes.Aborted, "CA signer is stopped")
597
+		return nil, status.Errorf(codes.Aborted, "CA signer is stopped")
598 598
 	}
599 599
 	ctx := s.ctx
600 600
 	s.mu.Unlock()
... ...
@@ -605,10 +605,10 @@ func (s *Server) isReadyLocked() error {
605 605
 	s.mu.Lock()
606 606
 	defer s.mu.Unlock()
607 607
 	if !s.isRunning() {
608
-		return grpc.Errorf(codes.Aborted, "CA signer is stopped")
608
+		return status.Errorf(codes.Aborted, "CA signer is stopped")
609 609
 	}
610 610
 	if s.joinTokens == nil {
611
-		return grpc.Errorf(codes.Aborted, "CA signer is still starting")
611
+		return status.Errorf(codes.Aborted, "CA signer is still starting")
612 612
 	}
613 613
 	return nil
614 614
 }
... ...
@@ -10,13 +10,12 @@ import (
10 10
 	"net/url"
11 11
 	"time"
12 12
 
13
-	"google.golang.org/grpc"
14
-	"google.golang.org/grpc/codes"
15
-
16 13
 	"github.com/cloudflare/cfssl/helpers"
17 14
 	"github.com/docker/swarmkit/api"
18 15
 	"github.com/docker/swarmkit/ca"
19 16
 	"github.com/docker/swarmkit/log"
17
+	"google.golang.org/grpc/codes"
18
+	"google.golang.org/grpc/status"
20 19
 )
21 20
 
22 21
 var minRootExpiration = 1 * helpers.OneYear
... ...
@@ -60,7 +59,7 @@ func newRootRotationObject(ctx context.Context, securityConfig *ca.SecurityConfi
60 60
 			crossSignedCert, err = oldRootCA.CrossSignCACertificate(rootCert)
61 61
 		}
62 62
 	case !newRootHasSigner: // the original CA and the new CA both require external CAs
63
-		return nil, grpc.Errorf(codes.InvalidArgument, "rotating from one external CA to a different external CA is not supported")
63
+		return nil, status.Errorf(codes.InvalidArgument, "rotating from one external CA to a different external CA is not supported")
64 64
 	default:
65 65
 		// We need the same credentials but to connect to the original URLs (in case we are in the middle of a root rotation already)
66 66
 		var urls []string
... ...
@@ -70,7 +69,7 @@ func newRootRotationObject(ctx context.Context, securityConfig *ca.SecurityConfi
70 70
 			}
71 71
 		}
72 72
 		if len(urls) == 0 {
73
-			return nil, grpc.Errorf(codes.InvalidArgument,
73
+			return nil, status.Errorf(codes.InvalidArgument,
74 74
 				"must provide an external CA for the current external root CA to generate a cross-signed certificate")
75 75
 		}
76 76
 		rootPool := x509.NewCertPool()
... ...
@@ -83,7 +82,7 @@ func newRootRotationObject(ctx context.Context, securityConfig *ca.SecurityConfi
83 83
 
84 84
 	if err != nil {
85 85
 		log.G(ctx).WithError(err).Error("unable to generate a cross-signed certificate for root rotation")
86
-		return nil, grpc.Errorf(codes.Internal, "unable to generate a cross-signed certificate for root rotation")
86
+		return nil, status.Errorf(codes.Internal, "unable to generate a cross-signed certificate for root rotation")
87 87
 	}
88 88
 
89 89
 	copied := apiRootCA.Copy()
... ...
@@ -146,7 +145,7 @@ func validateHasAtLeastOneExternalCA(ctx context.Context, externalCAs map[string
146 146
 			}
147 147
 		}
148 148
 	}
149
-	return nil, grpc.Errorf(codes.InvalidArgument, "there must be at least one valid, reachable external CA corresponding to the %s CA certificate", desc)
149
+	return nil, status.Errorf(codes.InvalidArgument, "there must be at least one valid, reachable external CA corresponding to the %s CA certificate", desc)
150 150
 }
151 151
 
152 152
 // validates that the list of external CAs have valid certs associated with them, and produce a mapping of subject/pubkey:external
... ...
@@ -193,7 +192,7 @@ func validateCAConfig(ctx context.Context, securityConfig *ca.SecurityConfig, cl
193 193
 	newConfig.SigningCACert = ca.NormalizePEMs(newConfig.SigningCACert) // ensure this is normalized before we use it
194 194
 
195 195
 	if len(newConfig.SigningCAKey) > 0 && len(newConfig.SigningCACert) == 0 {
196
-		return nil, grpc.Errorf(codes.InvalidArgument, "if a signing CA key is provided, the signing CA cert must also be provided")
196
+		return nil, status.Errorf(codes.InvalidArgument, "if a signing CA key is provided, the signing CA cert must also be provided")
197 197
 	}
198 198
 
199 199
 	normalizedRootCA := ca.NormalizePEMs(cluster.RootCA.CACert)
... ...
@@ -216,7 +215,7 @@ func validateCAConfig(ctx context.Context, securityConfig *ca.SecurityConfig, cl
216 216
 		if cluster.RootCA.LastForcedRotation != newConfig.ForceRotate {
217 217
 			newRootCA, err := ca.CreateRootCA(ca.DefaultRootCN)
218 218
 			if err != nil {
219
-				return nil, grpc.Errorf(codes.Internal, err.Error())
219
+				return nil, status.Errorf(codes.Internal, err.Error())
220 220
 			}
221 221
 			return newRootRotationObject(ctx, securityConfig, &cluster.RootCA, newRootCA, oldCertExtCAs, newConfig.ForceRotate)
222 222
 		}
... ...
@@ -240,21 +239,21 @@ func validateCAConfig(ctx context.Context, securityConfig *ca.SecurityConfig, cl
240 240
 	}
241 241
 	newRootCA, err := ca.NewRootCA(newConfig.SigningCACert, signingCert, newConfig.SigningCAKey, ca.DefaultNodeCertExpiration, nil)
242 242
 	if err != nil {
243
-		return nil, grpc.Errorf(codes.InvalidArgument, err.Error())
243
+		return nil, status.Errorf(codes.InvalidArgument, err.Error())
244 244
 	}
245 245
 
246 246
 	if len(newRootCA.Pool.Subjects()) != 1 {
247
-		return nil, grpc.Errorf(codes.InvalidArgument, "the desired CA certificate cannot contain multiple certificates")
247
+		return nil, status.Errorf(codes.InvalidArgument, "the desired CA certificate cannot contain multiple certificates")
248 248
 	}
249 249
 
250 250
 	parsedCert, err := helpers.ParseCertificatePEM(newConfig.SigningCACert)
251 251
 	if err != nil {
252
-		return nil, grpc.Errorf(codes.InvalidArgument, "could not parse the desired CA certificate")
252
+		return nil, status.Errorf(codes.InvalidArgument, "could not parse the desired CA certificate")
253 253
 	}
254 254
 
255 255
 	// The new certificate's expiry must be at least one year away
256 256
 	if parsedCert.NotAfter.Before(time.Now().Add(minRootExpiration)) {
257
-		return nil, grpc.Errorf(codes.InvalidArgument, "CA certificate expires too soon")
257
+		return nil, status.Errorf(codes.InvalidArgument, "CA certificate expires too soon")
258 258
 	}
259 259
 
260 260
 	if !hasSigningKey(newConfig) {
... ...
@@ -11,8 +11,8 @@ import (
11 11
 	"github.com/docker/swarmkit/manager/state/store"
12 12
 	gogotypes "github.com/gogo/protobuf/types"
13 13
 	"golang.org/x/net/context"
14
-	"google.golang.org/grpc"
15 14
 	"google.golang.org/grpc/codes"
15
+	"google.golang.org/grpc/status"
16 16
 )
17 17
 
18 18
 const (
... ...
@@ -23,17 +23,17 @@ const (
23 23
 
24 24
 func validateClusterSpec(spec *api.ClusterSpec) error {
25 25
 	if spec == nil {
26
-		return grpc.Errorf(codes.InvalidArgument, errInvalidArgument.Error())
26
+		return status.Errorf(codes.InvalidArgument, errInvalidArgument.Error())
27 27
 	}
28 28
 
29 29
 	// Validate that expiry time being provided is valid, and over our minimum
30 30
 	if spec.CAConfig.NodeCertExpiry != nil {
31 31
 		expiry, err := gogotypes.DurationFromProto(spec.CAConfig.NodeCertExpiry)
32 32
 		if err != nil {
33
-			return grpc.Errorf(codes.InvalidArgument, errInvalidArgument.Error())
33
+			return status.Errorf(codes.InvalidArgument, errInvalidArgument.Error())
34 34
 		}
35 35
 		if expiry < ca.MinNodeCertExpiration {
36
-			return grpc.Errorf(codes.InvalidArgument, "minimum certificate expiry time is: %s", ca.MinNodeCertExpiration)
36
+			return status.Errorf(codes.InvalidArgument, "minimum certificate expiry time is: %s", ca.MinNodeCertExpiration)
37 37
 		}
38 38
 	}
39 39
 
... ...
@@ -42,7 +42,7 @@ func validateClusterSpec(spec *api.ClusterSpec) error {
42 42
 	if len(spec.AcceptancePolicy.Policies) > 0 {
43 43
 		for _, policy := range spec.AcceptancePolicy.Policies {
44 44
 			if policy.Secret != nil && strings.ToLower(policy.Secret.Alg) != "bcrypt" {
45
-				return grpc.Errorf(codes.InvalidArgument, "hashing algorithm is not supported: %s", policy.Secret.Alg)
45
+				return status.Errorf(codes.InvalidArgument, "hashing algorithm is not supported: %s", policy.Secret.Alg)
46 46
 			}
47 47
 		}
48 48
 	}
... ...
@@ -51,13 +51,17 @@ func validateClusterSpec(spec *api.ClusterSpec) error {
51 51
 	if spec.Dispatcher.HeartbeatPeriod != nil {
52 52
 		heartbeatPeriod, err := gogotypes.DurationFromProto(spec.Dispatcher.HeartbeatPeriod)
53 53
 		if err != nil {
54
-			return grpc.Errorf(codes.InvalidArgument, errInvalidArgument.Error())
54
+			return status.Errorf(codes.InvalidArgument, errInvalidArgument.Error())
55 55
 		}
56 56
 		if heartbeatPeriod < 0 {
57
-			return grpc.Errorf(codes.InvalidArgument, "heartbeat time period cannot be a negative duration")
57
+			return status.Errorf(codes.InvalidArgument, "heartbeat time period cannot be a negative duration")
58 58
 		}
59 59
 	}
60 60
 
61
+	if spec.Annotations.Name != store.DefaultClusterName {
62
+		return status.Errorf(codes.InvalidArgument, "modification of cluster name is not allowed")
63
+	}
64
+
61 65
 	return nil
62 66
 }
63 67
 
... ...
@@ -66,7 +70,7 @@ func validateClusterSpec(spec *api.ClusterSpec) error {
66 66
 // - Returns `NotFound` if the Cluster is not found.
67 67
 func (s *Server) GetCluster(ctx context.Context, request *api.GetClusterRequest) (*api.GetClusterResponse, error) {
68 68
 	if request.ClusterID == "" {
69
-		return nil, grpc.Errorf(codes.InvalidArgument, errInvalidArgument.Error())
69
+		return nil, status.Errorf(codes.InvalidArgument, errInvalidArgument.Error())
70 70
 	}
71 71
 
72 72
 	var cluster *api.Cluster
... ...
@@ -74,7 +78,7 @@ func (s *Server) GetCluster(ctx context.Context, request *api.GetClusterRequest)
74 74
 		cluster = store.GetCluster(tx, request.ClusterID)
75 75
 	})
76 76
 	if cluster == nil {
77
-		return nil, grpc.Errorf(codes.NotFound, "cluster %s not found", request.ClusterID)
77
+		return nil, status.Errorf(codes.NotFound, "cluster %s not found", request.ClusterID)
78 78
 	}
79 79
 
80 80
 	redactedClusters := redactClusters([]*api.Cluster{cluster})
... ...
@@ -92,7 +96,7 @@ func (s *Server) GetCluster(ctx context.Context, request *api.GetClusterRequest)
92 92
 // - Returns an error if the update fails.
93 93
 func (s *Server) UpdateCluster(ctx context.Context, request *api.UpdateClusterRequest) (*api.UpdateClusterResponse, error) {
94 94
 	if request.ClusterID == "" || request.ClusterVersion == nil {
95
-		return nil, grpc.Errorf(codes.InvalidArgument, errInvalidArgument.Error())
95
+		return nil, status.Errorf(codes.InvalidArgument, errInvalidArgument.Error())
96 96
 	}
97 97
 	if err := validateClusterSpec(request.Spec); err != nil {
98 98
 		return nil, err
... ...
@@ -102,7 +106,7 @@ func (s *Server) UpdateCluster(ctx context.Context, request *api.UpdateClusterRe
102 102
 	err := s.store.Update(func(tx store.Tx) error {
103 103
 		cluster = store.GetCluster(tx, request.ClusterID)
104 104
 		if cluster == nil {
105
-			return grpc.Errorf(codes.NotFound, "cluster %s not found", request.ClusterID)
105
+			return status.Errorf(codes.NotFound, "cluster %s not found", request.ClusterID)
106 106
 		}
107 107
 		// This ensures that we have the current rootCA with which to generate tokens (expiration doesn't matter
108 108
 		// for generating the tokens)
... ...
@@ -110,7 +114,7 @@ func (s *Server) UpdateCluster(ctx context.Context, request *api.UpdateClusterRe
110 110
 		if err != nil {
111 111
 			log.G(ctx).WithField(
112 112
 				"method", "(*controlapi.Server).UpdateCluster").WithError(err).Error("invalid cluster root CA")
113
-			return grpc.Errorf(codes.Internal, "error loading cluster rootCA for update")
113
+			return status.Errorf(codes.Internal, "error loading cluster rootCA for update")
114 114
 		}
115 115
 
116 116
 		cluster.Meta.Version = *request.ClusterVersion
... ...
@@ -10,8 +10,8 @@ import (
10 10
 	"github.com/docker/swarmkit/api"
11 11
 	"github.com/docker/swarmkit/manager/allocator"
12 12
 	"github.com/docker/swarmkit/manager/state/store"
13
-	"google.golang.org/grpc"
14 13
 	"google.golang.org/grpc/codes"
14
+	"google.golang.org/grpc/status"
15 15
 )
16 16
 
17 17
 var isValidDNSName = regexp.MustCompile(`^[a-zA-Z0-9](?:[-_]*[A-Za-z0-9]+)*$`)
... ...
@@ -70,25 +70,25 @@ func filterMatchLabels(match map[string]string, candidates map[string]string) bo
70 70
 
71 71
 func validateAnnotations(m api.Annotations) error {
72 72
 	if m.Name == "" {
73
-		return grpc.Errorf(codes.InvalidArgument, "meta: name must be provided")
73
+		return status.Errorf(codes.InvalidArgument, "meta: name must be provided")
74 74
 	}
75 75
 	if !isValidDNSName.MatchString(m.Name) {
76 76
 		// if the name doesn't match the regex
77
-		return grpc.Errorf(codes.InvalidArgument, "name must be valid as a DNS name component")
77
+		return status.Errorf(codes.InvalidArgument, "name must be valid as a DNS name component")
78 78
 	}
79 79
 	if len(m.Name) > 63 {
80 80
 		// DNS labels are limited to 63 characters
81
-		return grpc.Errorf(codes.InvalidArgument, "name must be 63 characters or fewer")
81
+		return status.Errorf(codes.InvalidArgument, "name must be 63 characters or fewer")
82 82
 	}
83 83
 	return nil
84 84
 }
85 85
 
86 86
 func validateConfigOrSecretAnnotations(m api.Annotations) error {
87 87
 	if m.Name == "" {
88
-		return grpc.Errorf(codes.InvalidArgument, "name must be provided")
88
+		return status.Errorf(codes.InvalidArgument, "name must be provided")
89 89
 	} else if len(m.Name) > 64 || !isValidConfigOrSecretName.MatchString(m.Name) {
90 90
 		// if the name doesn't match the regex
91
-		return grpc.Errorf(codes.InvalidArgument,
91
+		return status.Errorf(codes.InvalidArgument,
92 92
 			"invalid name, only 64 [a-zA-Z0-9-_.] characters allowed, and the start and end character must be [a-zA-Z0-9]")
93 93
 	}
94 94
 	return nil
... ...
@@ -102,7 +102,7 @@ func validateDriver(driver *api.Driver, pg plugingetter.PluginGetter, pluginType
102 102
 	}
103 103
 
104 104
 	if driver.Name == "" {
105
-		return grpc.Errorf(codes.InvalidArgument, "driver name: if driver is specified name is required")
105
+		return status.Errorf(codes.InvalidArgument, "driver name: if driver is specified name is required")
106 106
 	}
107 107
 
108 108
 	// First check against the known drivers
... ...
@@ -119,16 +119,16 @@ func validateDriver(driver *api.Driver, pg plugingetter.PluginGetter, pluginType
119 119
 	}
120 120
 
121 121
 	if pg == nil {
122
-		return grpc.Errorf(codes.InvalidArgument, "plugin %s not supported", driver.Name)
122
+		return status.Errorf(codes.InvalidArgument, "plugin %s not supported", driver.Name)
123 123
 	}
124 124
 
125 125
 	p, err := pg.Get(driver.Name, pluginType, plugingetter.Lookup)
126 126
 	if err != nil {
127
-		return grpc.Errorf(codes.InvalidArgument, "error during lookup of plugin %s", driver.Name)
127
+		return status.Errorf(codes.InvalidArgument, "error during lookup of plugin %s", driver.Name)
128 128
 	}
129 129
 
130 130
 	if p.IsV1() {
131
-		return grpc.Errorf(codes.InvalidArgument, "legacy plugin %s of type %s is not supported in swarm mode", driver.Name, pluginType)
131
+		return status.Errorf(codes.InvalidArgument, "legacy plugin %s of type %s is not supported in swarm mode", driver.Name, pluginType)
132 132
 	}
133 133
 
134 134
 	return nil
... ...
@@ -10,8 +10,8 @@ import (
10 10
 	"github.com/docker/swarmkit/manager/state/store"
11 11
 	"github.com/sirupsen/logrus"
12 12
 	"golang.org/x/net/context"
13
-	"google.golang.org/grpc"
14 13
 	"google.golang.org/grpc/codes"
14
+	"google.golang.org/grpc/status"
15 15
 )
16 16
 
17 17
 // MaxConfigSize is the maximum byte length of the `Config.Spec.Data` field.
... ...
@@ -32,7 +32,7 @@ func configFromConfigSpec(spec *api.ConfigSpec) *api.Config {
32 32
 // - Returns an error if getting fails.
33 33
 func (s *Server) GetConfig(ctx context.Context, request *api.GetConfigRequest) (*api.GetConfigResponse, error) {
34 34
 	if request.ConfigID == "" {
35
-		return nil, grpc.Errorf(codes.InvalidArgument, "config ID must be provided")
35
+		return nil, status.Errorf(codes.InvalidArgument, "config ID must be provided")
36 36
 	}
37 37
 
38 38
 	var config *api.Config
... ...
@@ -41,7 +41,7 @@ func (s *Server) GetConfig(ctx context.Context, request *api.GetConfigRequest) (
41 41
 	})
42 42
 
43 43
 	if config == nil {
44
-		return nil, grpc.Errorf(codes.NotFound, "config %s not found", request.ConfigID)
44
+		return nil, status.Errorf(codes.NotFound, "config %s not found", request.ConfigID)
45 45
 	}
46 46
 
47 47
 	return &api.GetConfigResponse{Config: config}, nil
... ...
@@ -53,21 +53,21 @@ func (s *Server) GetConfig(ctx context.Context, request *api.GetConfigRequest) (
53 53
 // - Returns an error if the update fails.
54 54
 func (s *Server) UpdateConfig(ctx context.Context, request *api.UpdateConfigRequest) (*api.UpdateConfigResponse, error) {
55 55
 	if request.ConfigID == "" || request.ConfigVersion == nil {
56
-		return nil, grpc.Errorf(codes.InvalidArgument, errInvalidArgument.Error())
56
+		return nil, status.Errorf(codes.InvalidArgument, errInvalidArgument.Error())
57 57
 	}
58 58
 
59 59
 	var config *api.Config
60 60
 	err := s.store.Update(func(tx store.Tx) error {
61 61
 		config = store.GetConfig(tx, request.ConfigID)
62 62
 		if config == nil {
63
-			return grpc.Errorf(codes.NotFound, "config %s not found", request.ConfigID)
63
+			return status.Errorf(codes.NotFound, "config %s not found", request.ConfigID)
64 64
 		}
65 65
 
66 66
 		// Check if the Name is different than the current name, or the config is non-nil and different
67 67
 		// than the current config
68 68
 		if config.Spec.Annotations.Name != request.Spec.Annotations.Name ||
69 69
 			(request.Spec.Data != nil && !bytes.Equal(request.Spec.Data, config.Spec.Data)) {
70
-			return grpc.Errorf(codes.InvalidArgument, "only updates to Labels are allowed")
70
+			return status.Errorf(codes.InvalidArgument, "only updates to Labels are allowed")
71 71
 		}
72 72
 
73 73
 		// We only allow updating Labels
... ...
@@ -164,7 +164,7 @@ func (s *Server) CreateConfig(ctx context.Context, request *api.CreateConfigRequ
164 164
 
165 165
 	switch err {
166 166
 	case store.ErrNameConflict:
167
-		return nil, grpc.Errorf(codes.AlreadyExists, "config %s already exists", request.Spec.Annotations.Name)
167
+		return nil, status.Errorf(codes.AlreadyExists, "config %s already exists", request.Spec.Annotations.Name)
168 168
 	case nil:
169 169
 		log.G(ctx).WithFields(logrus.Fields{
170 170
 			"config.Name": request.Spec.Annotations.Name,
... ...
@@ -184,20 +184,20 @@ func (s *Server) CreateConfig(ctx context.Context, request *api.CreateConfigRequ
184 184
 // - Returns an error if the deletion fails.
185 185
 func (s *Server) RemoveConfig(ctx context.Context, request *api.RemoveConfigRequest) (*api.RemoveConfigResponse, error) {
186 186
 	if request.ConfigID == "" {
187
-		return nil, grpc.Errorf(codes.InvalidArgument, "config ID must be provided")
187
+		return nil, status.Errorf(codes.InvalidArgument, "config ID must be provided")
188 188
 	}
189 189
 
190 190
 	err := s.store.Update(func(tx store.Tx) error {
191 191
 		// Check if the config exists
192 192
 		config := store.GetConfig(tx, request.ConfigID)
193 193
 		if config == nil {
194
-			return grpc.Errorf(codes.NotFound, "could not find config %s", request.ConfigID)
194
+			return status.Errorf(codes.NotFound, "could not find config %s", request.ConfigID)
195 195
 		}
196 196
 
197 197
 		// Check if any services currently reference this config, return error if so
198 198
 		services, err := store.FindServices(tx, store.ByReferencedConfigID(request.ConfigID))
199 199
 		if err != nil {
200
-			return grpc.Errorf(codes.Internal, "could not find services using config %s: %v", request.ConfigID, err)
200
+			return status.Errorf(codes.Internal, "could not find services using config %s: %v", request.ConfigID, err)
201 201
 		}
202 202
 
203 203
 		if len(services) != 0 {
... ...
@@ -213,14 +213,14 @@ func (s *Server) RemoveConfig(ctx context.Context, request *api.RemoveConfigRequ
213 213
 				serviceStr = "service"
214 214
 			}
215 215
 
216
-			return grpc.Errorf(codes.InvalidArgument, "config '%s' is in use by the following %s: %v", configName, serviceStr, serviceNameStr)
216
+			return status.Errorf(codes.InvalidArgument, "config '%s' is in use by the following %s: %v", configName, serviceStr, serviceNameStr)
217 217
 		}
218 218
 
219 219
 		return store.DeleteConfig(tx, request.ConfigID)
220 220
 	})
221 221
 	switch err {
222 222
 	case store.ErrNotExist:
223
-		return nil, grpc.Errorf(codes.NotFound, "config %s not found", request.ConfigID)
223
+		return nil, status.Errorf(codes.NotFound, "config %s not found", request.ConfigID)
224 224
 	case nil:
225 225
 		log.G(ctx).WithFields(logrus.Fields{
226 226
 			"config.ID": request.ConfigID,
... ...
@@ -235,14 +235,14 @@ func (s *Server) RemoveConfig(ctx context.Context, request *api.RemoveConfigRequ
235 235
 
236 236
 func validateConfigSpec(spec *api.ConfigSpec) error {
237 237
 	if spec == nil {
238
-		return grpc.Errorf(codes.InvalidArgument, errInvalidArgument.Error())
238
+		return status.Errorf(codes.InvalidArgument, errInvalidArgument.Error())
239 239
 	}
240 240
 	if err := validateConfigOrSecretAnnotations(spec.Annotations); err != nil {
241 241
 		return err
242 242
 	}
243 243
 
244 244
 	if len(spec.Data) >= MaxConfigSize || len(spec.Data) < 1 {
245
-		return grpc.Errorf(codes.InvalidArgument, "config data must be larger than 0 and less than %d bytes", MaxConfigSize)
245
+		return status.Errorf(codes.InvalidArgument, "config data must be larger than 0 and less than %d bytes", MaxConfigSize)
246 246
 	}
247 247
 	return nil
248 248
 }
... ...
@@ -12,39 +12,39 @@ import (
12 12
 	"github.com/docker/swarmkit/manager/allocator/networkallocator"
13 13
 	"github.com/docker/swarmkit/manager/state/store"
14 14
 	"golang.org/x/net/context"
15
-	"google.golang.org/grpc"
16 15
 	"google.golang.org/grpc/codes"
16
+	"google.golang.org/grpc/status"
17 17
 )
18 18
 
19 19
 func validateIPAMConfiguration(ipamConf *api.IPAMConfig) error {
20 20
 	if ipamConf == nil {
21
-		return grpc.Errorf(codes.InvalidArgument, "ipam configuration: cannot be empty")
21
+		return status.Errorf(codes.InvalidArgument, "ipam configuration: cannot be empty")
22 22
 	}
23 23
 
24 24
 	_, subnet, err := net.ParseCIDR(ipamConf.Subnet)
25 25
 	if err != nil {
26
-		return grpc.Errorf(codes.InvalidArgument, "ipam configuration: invalid subnet %s", ipamConf.Subnet)
26
+		return status.Errorf(codes.InvalidArgument, "ipam configuration: invalid subnet %s", ipamConf.Subnet)
27 27
 	}
28 28
 
29 29
 	if ipamConf.Range != "" {
30 30
 		ip, _, err := net.ParseCIDR(ipamConf.Range)
31 31
 		if err != nil {
32
-			return grpc.Errorf(codes.InvalidArgument, "ipam configuration: invalid range %s", ipamConf.Range)
32
+			return status.Errorf(codes.InvalidArgument, "ipam configuration: invalid range %s", ipamConf.Range)
33 33
 		}
34 34
 
35 35
 		if !subnet.Contains(ip) {
36
-			return grpc.Errorf(codes.InvalidArgument, "ipam configuration: subnet %s does not contain range %s", ipamConf.Subnet, ipamConf.Range)
36
+			return status.Errorf(codes.InvalidArgument, "ipam configuration: subnet %s does not contain range %s", ipamConf.Subnet, ipamConf.Range)
37 37
 		}
38 38
 	}
39 39
 
40 40
 	if ipamConf.Gateway != "" {
41 41
 		ip := net.ParseIP(ipamConf.Gateway)
42 42
 		if ip == nil {
43
-			return grpc.Errorf(codes.InvalidArgument, "ipam configuration: invalid gateway %s", ipamConf.Gateway)
43
+			return status.Errorf(codes.InvalidArgument, "ipam configuration: invalid gateway %s", ipamConf.Gateway)
44 44
 		}
45 45
 
46 46
 		if !subnet.Contains(ip) {
47
-			return grpc.Errorf(codes.InvalidArgument, "ipam configuration: subnet %s does not contain gateway %s", ipamConf.Subnet, ipamConf.Gateway)
47
+			return status.Errorf(codes.InvalidArgument, "ipam configuration: subnet %s does not contain gateway %s", ipamConf.Subnet, ipamConf.Gateway)
48 48
 		}
49 49
 	}
50 50
 
... ...
@@ -73,15 +73,15 @@ func validateIPAM(ipam *api.IPAMOptions, pg plugingetter.PluginGetter) error {
73 73
 
74 74
 func validateNetworkSpec(spec *api.NetworkSpec, pg plugingetter.PluginGetter) error {
75 75
 	if spec == nil {
76
-		return grpc.Errorf(codes.InvalidArgument, errInvalidArgument.Error())
76
+		return status.Errorf(codes.InvalidArgument, errInvalidArgument.Error())
77 77
 	}
78 78
 
79 79
 	if spec.Ingress && spec.DriverConfig != nil && spec.DriverConfig.Name != "overlay" {
80
-		return grpc.Errorf(codes.Unimplemented, "only overlay driver is currently supported for ingress network")
80
+		return status.Errorf(codes.Unimplemented, "only overlay driver is currently supported for ingress network")
81 81
 	}
82 82
 
83 83
 	if spec.Attachable && spec.Ingress {
84
-		return grpc.Errorf(codes.InvalidArgument, "ingress network cannot be attachable")
84
+		return status.Errorf(codes.InvalidArgument, "ingress network cannot be attachable")
85 85
 	}
86 86
 
87 87
 	if err := validateAnnotations(spec.Annotations); err != nil {
... ...
@@ -89,7 +89,7 @@ func validateNetworkSpec(spec *api.NetworkSpec, pg plugingetter.PluginGetter) er
89 89
 	}
90 90
 
91 91
 	if _, ok := spec.Annotations.Labels[networkallocator.PredefinedLabel]; ok {
92
-		return grpc.Errorf(codes.PermissionDenied, "label %s is for internally created predefined networks and cannot be applied by users",
92
+		return status.Errorf(codes.PermissionDenied, "label %s is for internally created predefined networks and cannot be applied by users",
93 93
 			networkallocator.PredefinedLabel)
94 94
 	}
95 95
 	if err := validateDriver(spec.DriverConfig, pg, driverapi.NetworkPluginEndpointType); err != nil {
... ...
@@ -117,9 +117,9 @@ func (s *Server) CreateNetwork(ctx context.Context, request *api.CreateNetworkRe
117 117
 	err := s.store.Update(func(tx store.Tx) error {
118 118
 		if request.Spec.Ingress {
119 119
 			if n, err := allocator.GetIngressNetwork(s.store); err == nil {
120
-				return grpc.Errorf(codes.AlreadyExists, "ingress network (%s) is already present", n.ID)
120
+				return status.Errorf(codes.AlreadyExists, "ingress network (%s) is already present", n.ID)
121 121
 			} else if err != allocator.ErrNoIngress {
122
-				return grpc.Errorf(codes.Internal, "failed ingress network presence check: %v", err)
122
+				return status.Errorf(codes.Internal, "failed ingress network presence check: %v", err)
123 123
 			}
124 124
 		}
125 125
 		return store.CreateNetwork(tx, n)
... ...
@@ -138,7 +138,7 @@ func (s *Server) CreateNetwork(ctx context.Context, request *api.CreateNetworkRe
138 138
 // - Returns `NotFound` if the Network is not found.
139 139
 func (s *Server) GetNetwork(ctx context.Context, request *api.GetNetworkRequest) (*api.GetNetworkResponse, error) {
140 140
 	if request.NetworkID == "" {
141
-		return nil, grpc.Errorf(codes.InvalidArgument, errInvalidArgument.Error())
141
+		return nil, status.Errorf(codes.InvalidArgument, errInvalidArgument.Error())
142 142
 	}
143 143
 
144 144
 	var n *api.Network
... ...
@@ -146,7 +146,7 @@ func (s *Server) GetNetwork(ctx context.Context, request *api.GetNetworkRequest)
146 146
 		n = store.GetNetwork(tx, request.NetworkID)
147 147
 	})
148 148
 	if n == nil {
149
-		return nil, grpc.Errorf(codes.NotFound, "network %s not found", request.NetworkID)
149
+		return nil, status.Errorf(codes.NotFound, "network %s not found", request.NetworkID)
150 150
 	}
151 151
 	return &api.GetNetworkResponse{
152 152
 		Network: n,
... ...
@@ -159,7 +159,7 @@ func (s *Server) GetNetwork(ctx context.Context, request *api.GetNetworkRequest)
159 159
 // - Returns an error if the deletion fails.
160 160
 func (s *Server) RemoveNetwork(ctx context.Context, request *api.RemoveNetworkRequest) (*api.RemoveNetworkResponse, error) {
161 161
 	if request.NetworkID == "" {
162
-		return nil, grpc.Errorf(codes.InvalidArgument, errInvalidArgument.Error())
162
+		return nil, status.Errorf(codes.InvalidArgument, errInvalidArgument.Error())
163 163
 	}
164 164
 
165 165
 	var (
... ...
@@ -171,7 +171,7 @@ func (s *Server) RemoveNetwork(ctx context.Context, request *api.RemoveNetworkRe
171 171
 		n = store.GetNetwork(tx, request.NetworkID)
172 172
 	})
173 173
 	if n == nil {
174
-		return nil, grpc.Errorf(codes.NotFound, "network %s not found", request.NetworkID)
174
+		return nil, status.Errorf(codes.NotFound, "network %s not found", request.NetworkID)
175 175
 	}
176 176
 
177 177
 	if allocator.IsIngressNetwork(n) {
... ...
@@ -179,13 +179,13 @@ func (s *Server) RemoveNetwork(ctx context.Context, request *api.RemoveNetworkRe
179 179
 	}
180 180
 
181 181
 	if v, ok := n.Spec.Annotations.Labels[networkallocator.PredefinedLabel]; ok && v == "true" {
182
-		return nil, grpc.Errorf(codes.FailedPrecondition, "network %s (%s) is a swarm predefined network and cannot be removed",
182
+		return nil, status.Errorf(codes.FailedPrecondition, "network %s (%s) is a swarm predefined network and cannot be removed",
183 183
 			request.NetworkID, n.Spec.Annotations.Name)
184 184
 	}
185 185
 
186 186
 	if err := rm(n.ID); err != nil {
187 187
 		if err == store.ErrNotExist {
188
-			return nil, grpc.Errorf(codes.NotFound, "network %s not found", request.NetworkID)
188
+			return nil, status.Errorf(codes.NotFound, "network %s not found", request.NetworkID)
189 189
 		}
190 190
 		return nil, err
191 191
 	}
... ...
@@ -196,21 +196,21 @@ func (s *Server) removeNetwork(id string) error {
196 196
 	return s.store.Update(func(tx store.Tx) error {
197 197
 		services, err := store.FindServices(tx, store.ByReferencedNetworkID(id))
198 198
 		if err != nil {
199
-			return grpc.Errorf(codes.Internal, "could not find services using network %s: %v", id, err)
199
+			return status.Errorf(codes.Internal, "could not find services using network %s: %v", id, err)
200 200
 		}
201 201
 
202 202
 		if len(services) != 0 {
203
-			return grpc.Errorf(codes.FailedPrecondition, "network %s is in use by service %s", id, services[0].ID)
203
+			return status.Errorf(codes.FailedPrecondition, "network %s is in use by service %s", id, services[0].ID)
204 204
 		}
205 205
 
206 206
 		tasks, err := store.FindTasks(tx, store.ByReferencedNetworkID(id))
207 207
 		if err != nil {
208
-			return grpc.Errorf(codes.Internal, "could not find tasks using network %s: %v", id, err)
208
+			return status.Errorf(codes.Internal, "could not find tasks using network %s: %v", id, err)
209 209
 		}
210 210
 
211 211
 		for _, t := range tasks {
212 212
 			if t.DesiredState <= api.TaskStateRunning && t.Status.State <= api.TaskStateRunning {
213
-				return grpc.Errorf(codes.FailedPrecondition, "network %s is in use by task %s", id, t.ID)
213
+				return status.Errorf(codes.FailedPrecondition, "network %s is in use by task %s", id, t.ID)
214 214
 			}
215 215
 		}
216 216
 
... ...
@@ -222,11 +222,11 @@ func (s *Server) removeIngressNetwork(id string) error {
222 222
 	return s.store.Update(func(tx store.Tx) error {
223 223
 		services, err := store.FindServices(tx, store.All)
224 224
 		if err != nil {
225
-			return grpc.Errorf(codes.Internal, "could not find services using network %s: %v", id, err)
225
+			return status.Errorf(codes.Internal, "could not find services using network %s: %v", id, err)
226 226
 		}
227 227
 		for _, srv := range services {
228 228
 			if allocator.IsIngressNetworkNeeded(srv) {
229
-				return grpc.Errorf(codes.FailedPrecondition, "ingress network cannot be removed because service %s depends on it", srv.ID)
229
+				return status.Errorf(codes.FailedPrecondition, "ingress network cannot be removed because service %s depends on it", srv.ID)
230 230
 			}
231 231
 		}
232 232
 		return store.DeleteNetwork(tx, id)
... ...
@@ -9,13 +9,13 @@ import (
9 9
 	"github.com/docker/swarmkit/manager/state/store"
10 10
 	gogotypes "github.com/gogo/protobuf/types"
11 11
 	"golang.org/x/net/context"
12
-	"google.golang.org/grpc"
13 12
 	"google.golang.org/grpc/codes"
13
+	"google.golang.org/grpc/status"
14 14
 )
15 15
 
16 16
 func validateNodeSpec(spec *api.NodeSpec) error {
17 17
 	if spec == nil {
18
-		return grpc.Errorf(codes.InvalidArgument, errInvalidArgument.Error())
18
+		return status.Errorf(codes.InvalidArgument, errInvalidArgument.Error())
19 19
 	}
20 20
 	return nil
21 21
 }
... ...
@@ -25,7 +25,7 @@ func validateNodeSpec(spec *api.NodeSpec) error {
25 25
 // - Returns `NotFound` if the Node is not found.
26 26
 func (s *Server) GetNode(ctx context.Context, request *api.GetNodeRequest) (*api.GetNodeResponse, error) {
27 27
 	if request.NodeID == "" {
28
-		return nil, grpc.Errorf(codes.InvalidArgument, errInvalidArgument.Error())
28
+		return nil, status.Errorf(codes.InvalidArgument, errInvalidArgument.Error())
29 29
 	}
30 30
 
31 31
 	var node *api.Node
... ...
@@ -33,7 +33,7 @@ func (s *Server) GetNode(ctx context.Context, request *api.GetNodeRequest) (*api
33 33
 		node = store.GetNode(tx, request.NodeID)
34 34
 	})
35 35
 	if node == nil {
36
-		return nil, grpc.Errorf(codes.NotFound, "node %s not found", request.NodeID)
36
+		return nil, status.Errorf(codes.NotFound, "node %s not found", request.NodeID)
37 37
 	}
38 38
 
39 39
 	if s.raft != nil {
... ...
@@ -196,7 +196,7 @@ func (s *Server) ListNodes(ctx context.Context, request *api.ListNodesRequest) (
196 196
 // - Returns an error if the update fails.
197 197
 func (s *Server) UpdateNode(ctx context.Context, request *api.UpdateNodeRequest) (*api.UpdateNodeResponse, error) {
198 198
 	if request.NodeID == "" || request.NodeVersion == nil {
199
-		return nil, grpc.Errorf(codes.InvalidArgument, errInvalidArgument.Error())
199
+		return nil, status.Errorf(codes.InvalidArgument, errInvalidArgument.Error())
200 200
 	}
201 201
 	if err := validateNodeSpec(request.Spec); err != nil {
202 202
 		return nil, err
... ...
@@ -210,7 +210,7 @@ func (s *Server) UpdateNode(ctx context.Context, request *api.UpdateNodeRequest)
210 210
 	err := s.store.Update(func(tx store.Tx) error {
211 211
 		node = store.GetNode(tx, request.NodeID)
212 212
 		if node == nil {
213
-			return grpc.Errorf(codes.NotFound, "node %s not found", request.NodeID)
213
+			return status.Errorf(codes.NotFound, "node %s not found", request.NodeID)
214 214
 		}
215 215
 
216 216
 		// Demotion sanity checks.
... ...
@@ -218,20 +218,20 @@ func (s *Server) UpdateNode(ctx context.Context, request *api.UpdateNodeRequest)
218 218
 			// Check for manager entries in Store.
219 219
 			managers, err := store.FindNodes(tx, store.ByRole(api.NodeRoleManager))
220 220
 			if err != nil {
221
-				return grpc.Errorf(codes.Internal, "internal store error: %v", err)
221
+				return status.Errorf(codes.Internal, "internal store error: %v", err)
222 222
 			}
223 223
 			if len(managers) == 1 && managers[0].ID == node.ID {
224
-				return grpc.Errorf(codes.FailedPrecondition, "attempting to demote the last manager of the swarm")
224
+				return status.Errorf(codes.FailedPrecondition, "attempting to demote the last manager of the swarm")
225 225
 			}
226 226
 
227 227
 			// Check for node in memberlist
228 228
 			if member = s.raft.GetMemberByNodeID(request.NodeID); member == nil {
229
-				return grpc.Errorf(codes.NotFound, "can't find manager in raft memberlist")
229
+				return status.Errorf(codes.NotFound, "can't find manager in raft memberlist")
230 230
 			}
231 231
 
232 232
 			// Quorum safeguard
233 233
 			if !s.raft.CanRemoveMember(member.RaftID) {
234
-				return grpc.Errorf(codes.FailedPrecondition, "can't remove member from the raft: this would result in a loss of quorum")
234
+				return status.Errorf(codes.FailedPrecondition, "can't remove member from the raft: this would result in a loss of quorum")
235 235
 			}
236 236
 		}
237 237
 
... ...
@@ -278,33 +278,33 @@ func removeNodeAttachments(tx store.Tx, nodeID string) error {
278 278
 // - Returns an error if the delete fails.
279 279
 func (s *Server) RemoveNode(ctx context.Context, request *api.RemoveNodeRequest) (*api.RemoveNodeResponse, error) {
280 280
 	if request.NodeID == "" {
281
-		return nil, grpc.Errorf(codes.InvalidArgument, errInvalidArgument.Error())
281
+		return nil, status.Errorf(codes.InvalidArgument, errInvalidArgument.Error())
282 282
 	}
283 283
 
284 284
 	err := s.store.Update(func(tx store.Tx) error {
285 285
 		node := store.GetNode(tx, request.NodeID)
286 286
 		if node == nil {
287
-			return grpc.Errorf(codes.NotFound, "node %s not found", request.NodeID)
287
+			return status.Errorf(codes.NotFound, "node %s not found", request.NodeID)
288 288
 		}
289 289
 		if node.Spec.DesiredRole == api.NodeRoleManager {
290 290
 			if s.raft == nil {
291
-				return grpc.Errorf(codes.FailedPrecondition, "node %s is a manager but cannot access node information from the raft memberlist", request.NodeID)
291
+				return status.Errorf(codes.FailedPrecondition, "node %s is a manager but cannot access node information from the raft memberlist", request.NodeID)
292 292
 			}
293 293
 			if member := s.raft.GetMemberByNodeID(request.NodeID); member != nil {
294
-				return grpc.Errorf(codes.FailedPrecondition, "node %s is a cluster manager and is a member of the raft cluster. It must be demoted to worker before removal", request.NodeID)
294
+				return status.Errorf(codes.FailedPrecondition, "node %s is a cluster manager and is a member of the raft cluster. It must be demoted to worker before removal", request.NodeID)
295 295
 			}
296 296
 		}
297 297
 		if !request.Force && node.Status.State == api.NodeStatus_READY {
298
-			return grpc.Errorf(codes.FailedPrecondition, "node %s is not down and can't be removed", request.NodeID)
298
+			return status.Errorf(codes.FailedPrecondition, "node %s is not down and can't be removed", request.NodeID)
299 299
 		}
300 300
 
301 301
 		// lookup the cluster
302
-		clusters, err := store.FindClusters(tx, store.ByName("default"))
302
+		clusters, err := store.FindClusters(tx, store.ByName(store.DefaultClusterName))
303 303
 		if err != nil {
304 304
 			return err
305 305
 		}
306 306
 		if len(clusters) != 1 {
307
-			return grpc.Errorf(codes.Internal, "could not fetch cluster object")
307
+			return status.Errorf(codes.Internal, "could not fetch cluster object")
308 308
 		}
309 309
 		cluster := clusters[0]
310 310
 
... ...
@@ -11,8 +11,8 @@ import (
11 11
 	"github.com/docker/swarmkit/manager/state/store"
12 12
 	"github.com/sirupsen/logrus"
13 13
 	"golang.org/x/net/context"
14
-	"google.golang.org/grpc"
15 14
 	"google.golang.org/grpc/codes"
15
+	"google.golang.org/grpc/status"
16 16
 )
17 17
 
18 18
 // assumes spec is not nil
... ...
@@ -30,7 +30,7 @@ func secretFromSecretSpec(spec *api.SecretSpec) *api.Secret {
30 30
 // - Returns an error if getting fails.
31 31
 func (s *Server) GetSecret(ctx context.Context, request *api.GetSecretRequest) (*api.GetSecretResponse, error) {
32 32
 	if request.SecretID == "" {
33
-		return nil, grpc.Errorf(codes.InvalidArgument, "secret ID must be provided")
33
+		return nil, status.Errorf(codes.InvalidArgument, "secret ID must be provided")
34 34
 	}
35 35
 
36 36
 	var secret *api.Secret
... ...
@@ -39,7 +39,7 @@ func (s *Server) GetSecret(ctx context.Context, request *api.GetSecretRequest) (
39 39
 	})
40 40
 
41 41
 	if secret == nil {
42
-		return nil, grpc.Errorf(codes.NotFound, "secret %s not found", request.SecretID)
42
+		return nil, status.Errorf(codes.NotFound, "secret %s not found", request.SecretID)
43 43
 	}
44 44
 
45 45
 	secret.Spec.Data = nil // clean the actual secret data so it's never returned
... ...
@@ -52,20 +52,20 @@ func (s *Server) GetSecret(ctx context.Context, request *api.GetSecretRequest) (
52 52
 // - Returns an error if the update fails.
53 53
 func (s *Server) UpdateSecret(ctx context.Context, request *api.UpdateSecretRequest) (*api.UpdateSecretResponse, error) {
54 54
 	if request.SecretID == "" || request.SecretVersion == nil {
55
-		return nil, grpc.Errorf(codes.InvalidArgument, errInvalidArgument.Error())
55
+		return nil, status.Errorf(codes.InvalidArgument, errInvalidArgument.Error())
56 56
 	}
57 57
 	var secret *api.Secret
58 58
 	err := s.store.Update(func(tx store.Tx) error {
59 59
 		secret = store.GetSecret(tx, request.SecretID)
60 60
 		if secret == nil {
61
-			return grpc.Errorf(codes.NotFound, "secret %s not found", request.SecretID)
61
+			return status.Errorf(codes.NotFound, "secret %s not found", request.SecretID)
62 62
 		}
63 63
 
64 64
 		// Check if the Name is different than the current name, or the secret is non-nil and different
65 65
 		// than the current secret
66 66
 		if secret.Spec.Annotations.Name != request.Spec.Annotations.Name ||
67 67
 			(request.Spec.Data != nil && subtle.ConstantTimeCompare(request.Spec.Data, secret.Spec.Data) == 0) {
68
-			return grpc.Errorf(codes.InvalidArgument, "only updates to Labels are allowed")
68
+			return status.Errorf(codes.InvalidArgument, "only updates to Labels are allowed")
69 69
 		}
70 70
 
71 71
 		// We only allow updating Labels
... ...
@@ -171,7 +171,7 @@ func (s *Server) CreateSecret(ctx context.Context, request *api.CreateSecretRequ
171 171
 
172 172
 	switch err {
173 173
 	case store.ErrNameConflict:
174
-		return nil, grpc.Errorf(codes.AlreadyExists, "secret %s already exists", request.Spec.Annotations.Name)
174
+		return nil, status.Errorf(codes.AlreadyExists, "secret %s already exists", request.Spec.Annotations.Name)
175 175
 	case nil:
176 176
 		secret.Spec.Data = nil // clean the actual secret data so it's never returned
177 177
 		log.G(ctx).WithFields(logrus.Fields{
... ...
@@ -192,20 +192,20 @@ func (s *Server) CreateSecret(ctx context.Context, request *api.CreateSecretRequ
192 192
 // - Returns an error if the deletion fails.
193 193
 func (s *Server) RemoveSecret(ctx context.Context, request *api.RemoveSecretRequest) (*api.RemoveSecretResponse, error) {
194 194
 	if request.SecretID == "" {
195
-		return nil, grpc.Errorf(codes.InvalidArgument, "secret ID must be provided")
195
+		return nil, status.Errorf(codes.InvalidArgument, "secret ID must be provided")
196 196
 	}
197 197
 
198 198
 	err := s.store.Update(func(tx store.Tx) error {
199 199
 		// Check if the secret exists
200 200
 		secret := store.GetSecret(tx, request.SecretID)
201 201
 		if secret == nil {
202
-			return grpc.Errorf(codes.NotFound, "could not find secret %s", request.SecretID)
202
+			return status.Errorf(codes.NotFound, "could not find secret %s", request.SecretID)
203 203
 		}
204 204
 
205 205
 		// Check if any services currently reference this secret, return error if so
206 206
 		services, err := store.FindServices(tx, store.ByReferencedSecretID(request.SecretID))
207 207
 		if err != nil {
208
-			return grpc.Errorf(codes.Internal, "could not find services using secret %s: %v", request.SecretID, err)
208
+			return status.Errorf(codes.Internal, "could not find services using secret %s: %v", request.SecretID, err)
209 209
 		}
210 210
 
211 211
 		if len(services) != 0 {
... ...
@@ -221,14 +221,14 @@ func (s *Server) RemoveSecret(ctx context.Context, request *api.RemoveSecretRequ
221 221
 				serviceStr = "service"
222 222
 			}
223 223
 
224
-			return grpc.Errorf(codes.InvalidArgument, "secret '%s' is in use by the following %s: %v", secretName, serviceStr, serviceNameStr)
224
+			return status.Errorf(codes.InvalidArgument, "secret '%s' is in use by the following %s: %v", secretName, serviceStr, serviceNameStr)
225 225
 		}
226 226
 
227 227
 		return store.DeleteSecret(tx, request.SecretID)
228 228
 	})
229 229
 	switch err {
230 230
 	case store.ErrNotExist:
231
-		return nil, grpc.Errorf(codes.NotFound, "secret %s not found", request.SecretID)
231
+		return nil, status.Errorf(codes.NotFound, "secret %s not found", request.SecretID)
232 232
 	case nil:
233 233
 		log.G(ctx).WithFields(logrus.Fields{
234 234
 			"secret.ID": request.SecretID,
... ...
@@ -243,7 +243,7 @@ func (s *Server) RemoveSecret(ctx context.Context, request *api.RemoveSecretRequ
243 243
 
244 244
 func validateSecretSpec(spec *api.SecretSpec) error {
245 245
 	if spec == nil {
246
-		return grpc.Errorf(codes.InvalidArgument, errInvalidArgument.Error())
246
+		return status.Errorf(codes.InvalidArgument, errInvalidArgument.Error())
247 247
 	}
248 248
 	if err := validateConfigOrSecretAnnotations(spec.Annotations); err != nil {
249 249
 		return err
... ...
@@ -252,12 +252,12 @@ func validateSecretSpec(spec *api.SecretSpec) error {
252 252
 	if spec.Driver != nil {
253 253
 		// Ensure secret driver has a name
254 254
 		if spec.Driver.Name == "" {
255
-			return grpc.Errorf(codes.InvalidArgument, "secret driver must have a name")
255
+			return status.Errorf(codes.InvalidArgument, "secret driver must have a name")
256 256
 		}
257 257
 		return nil
258 258
 	}
259 259
 	if err := validation.ValidateSecretPayload(spec.Data); err != nil {
260
-		return grpc.Errorf(codes.InvalidArgument, "%s", err.Error())
260
+		return status.Errorf(codes.InvalidArgument, "%s", err.Error())
261 261
 	}
262 262
 	return nil
263 263
 }
... ...
@@ -19,8 +19,8 @@ import (
19 19
 	"github.com/docker/swarmkit/template"
20 20
 	gogotypes "github.com/gogo/protobuf/types"
21 21
 	"golang.org/x/net/context"
22
-	"google.golang.org/grpc"
23 22
 	"google.golang.org/grpc/codes"
23
+	"google.golang.org/grpc/status"
24 24
 )
25 25
 
26 26
 var (
... ...
@@ -37,11 +37,11 @@ func validateResources(r *api.Resources) error {
37 37
 	}
38 38
 
39 39
 	if r.NanoCPUs != 0 && r.NanoCPUs < 1e6 {
40
-		return grpc.Errorf(codes.InvalidArgument, "invalid cpu value %g: Must be at least %g", float64(r.NanoCPUs)/1e9, 1e6/1e9)
40
+		return status.Errorf(codes.InvalidArgument, "invalid cpu value %g: Must be at least %g", float64(r.NanoCPUs)/1e9, 1e6/1e9)
41 41
 	}
42 42
 
43 43
 	if r.MemoryBytes != 0 && r.MemoryBytes < 4*1024*1024 {
44
-		return grpc.Errorf(codes.InvalidArgument, "invalid memory value %d: Must be at least 4MiB", r.MemoryBytes)
44
+		return status.Errorf(codes.InvalidArgument, "invalid memory value %d: Must be at least 4MiB", r.MemoryBytes)
45 45
 	}
46 46
 	if err := genericresource.ValidateTask(r); err != nil {
47 47
 		return nil
... ...
@@ -70,7 +70,7 @@ func validateRestartPolicy(rp *api.RestartPolicy) error {
70 70
 			return err
71 71
 		}
72 72
 		if delay < 0 {
73
-			return grpc.Errorf(codes.InvalidArgument, "TaskSpec: restart-delay cannot be negative")
73
+			return status.Errorf(codes.InvalidArgument, "TaskSpec: restart-delay cannot be negative")
74 74
 		}
75 75
 	}
76 76
 
... ...
@@ -80,7 +80,7 @@ func validateRestartPolicy(rp *api.RestartPolicy) error {
80 80
 			return err
81 81
 		}
82 82
 		if win < 0 {
83
-			return grpc.Errorf(codes.InvalidArgument, "TaskSpec: restart-window cannot be negative")
83
+			return status.Errorf(codes.InvalidArgument, "TaskSpec: restart-window cannot be negative")
84 84
 		}
85 85
 	}
86 86
 
... ...
@@ -101,7 +101,7 @@ func validateUpdate(uc *api.UpdateConfig) error {
101 101
 	}
102 102
 
103 103
 	if uc.Delay < 0 {
104
-		return grpc.Errorf(codes.InvalidArgument, "TaskSpec: update-delay cannot be negative")
104
+		return status.Errorf(codes.InvalidArgument, "TaskSpec: update-delay cannot be negative")
105 105
 	}
106 106
 
107 107
 	if uc.Monitor != nil {
... ...
@@ -110,12 +110,12 @@ func validateUpdate(uc *api.UpdateConfig) error {
110 110
 			return err
111 111
 		}
112 112
 		if monitor < 0 {
113
-			return grpc.Errorf(codes.InvalidArgument, "TaskSpec: update-monitor cannot be negative")
113
+			return status.Errorf(codes.InvalidArgument, "TaskSpec: update-monitor cannot be negative")
114 114
 		}
115 115
 	}
116 116
 
117 117
 	if uc.MaxFailureRatio < 0 || uc.MaxFailureRatio > 1 {
118
-		return grpc.Errorf(codes.InvalidArgument, "TaskSpec: update-maxfailureratio cannot be less than 0 or bigger than 1")
118
+		return status.Errorf(codes.InvalidArgument, "TaskSpec: update-maxfailureratio cannot be less than 0 or bigger than 1")
119 119
 	}
120 120
 
121 121
 	return nil
... ...
@@ -147,7 +147,7 @@ func validateContainerSpec(taskSpec api.TaskSpec) error {
147 147
 		LogDriver: taskSpec.LogDriver,
148 148
 	})
149 149
 	if err != nil {
150
-		return grpc.Errorf(codes.InvalidArgument, err.Error())
150
+		return status.Errorf(codes.InvalidArgument, err.Error())
151 151
 	}
152 152
 
153 153
 	if err := validateImage(container.Image); err != nil {
... ...
@@ -164,11 +164,11 @@ func validateContainerSpec(taskSpec api.TaskSpec) error {
164 164
 // validateImage validates image name in containerSpec
165 165
 func validateImage(image string) error {
166 166
 	if image == "" {
167
-		return grpc.Errorf(codes.InvalidArgument, "ContainerSpec: image reference must be provided")
167
+		return status.Errorf(codes.InvalidArgument, "ContainerSpec: image reference must be provided")
168 168
 	}
169 169
 
170 170
 	if _, err := reference.ParseNormalizedNamed(image); err != nil {
171
-		return grpc.Errorf(codes.InvalidArgument, "ContainerSpec: %q is not a valid repository/tag", image)
171
+		return status.Errorf(codes.InvalidArgument, "ContainerSpec: %q is not a valid repository/tag", image)
172 172
 	}
173 173
 	return nil
174 174
 }
... ...
@@ -178,7 +178,7 @@ func validateMounts(mounts []api.Mount) error {
178 178
 	mountMap := make(map[string]bool)
179 179
 	for _, mount := range mounts {
180 180
 		if _, exists := mountMap[mount.Target]; exists {
181
-			return grpc.Errorf(codes.InvalidArgument, "ContainerSpec: duplicate mount point: %s", mount.Target)
181
+			return status.Errorf(codes.InvalidArgument, "ContainerSpec: duplicate mount point: %s", mount.Target)
182 182
 		}
183 183
 		mountMap[mount.Target] = true
184 184
 	}
... ...
@@ -198,7 +198,7 @@ func validateHealthCheck(hc *api.HealthConfig) error {
198 198
 			return err
199 199
 		}
200 200
 		if interval != 0 && interval < time.Duration(minimumDuration) {
201
-			return grpc.Errorf(codes.InvalidArgument, "ContainerSpec: Interval in HealthConfig cannot be less than %s", minimumDuration)
201
+			return status.Errorf(codes.InvalidArgument, "ContainerSpec: Interval in HealthConfig cannot be less than %s", minimumDuration)
202 202
 		}
203 203
 	}
204 204
 
... ...
@@ -208,7 +208,7 @@ func validateHealthCheck(hc *api.HealthConfig) error {
208 208
 			return err
209 209
 		}
210 210
 		if timeout != 0 && timeout < time.Duration(minimumDuration) {
211
-			return grpc.Errorf(codes.InvalidArgument, "ContainerSpec: Timeout in HealthConfig cannot be less than %s", minimumDuration)
211
+			return status.Errorf(codes.InvalidArgument, "ContainerSpec: Timeout in HealthConfig cannot be less than %s", minimumDuration)
212 212
 		}
213 213
 	}
214 214
 
... ...
@@ -218,12 +218,12 @@ func validateHealthCheck(hc *api.HealthConfig) error {
218 218
 			return err
219 219
 		}
220 220
 		if sp != 0 && sp < time.Duration(minimumDuration) {
221
-			return grpc.Errorf(codes.InvalidArgument, "ContainerSpec: StartPeriod in HealthConfig cannot be less than %s", minimumDuration)
221
+			return status.Errorf(codes.InvalidArgument, "ContainerSpec: StartPeriod in HealthConfig cannot be less than %s", minimumDuration)
222 222
 		}
223 223
 	}
224 224
 
225 225
 	if hc.Retries < 0 {
226
-		return grpc.Errorf(codes.InvalidArgument, "ContainerSpec: Retries in HealthConfig cannot be negative")
226
+		return status.Errorf(codes.InvalidArgument, "ContainerSpec: Retries in HealthConfig cannot be negative")
227 227
 	}
228 228
 
229 229
 	return nil
... ...
@@ -233,28 +233,28 @@ func validateGenericRuntimeSpec(taskSpec api.TaskSpec) error {
233 233
 	generic := taskSpec.GetGeneric()
234 234
 
235 235
 	if len(generic.Kind) < 3 {
236
-		return grpc.Errorf(codes.InvalidArgument, "Generic runtime: Invalid name %q", generic.Kind)
236
+		return status.Errorf(codes.InvalidArgument, "Generic runtime: Invalid name %q", generic.Kind)
237 237
 	}
238 238
 
239 239
 	reservedNames := []string{"container", "attachment"}
240 240
 	for _, n := range reservedNames {
241 241
 		if strings.ToLower(generic.Kind) == n {
242
-			return grpc.Errorf(codes.InvalidArgument, "Generic runtime: %q is a reserved name", generic.Kind)
242
+			return status.Errorf(codes.InvalidArgument, "Generic runtime: %q is a reserved name", generic.Kind)
243 243
 		}
244 244
 	}
245 245
 
246 246
 	payload := generic.Payload
247 247
 
248 248
 	if payload == nil {
249
-		return grpc.Errorf(codes.InvalidArgument, "Generic runtime is missing payload")
249
+		return status.Errorf(codes.InvalidArgument, "Generic runtime is missing payload")
250 250
 	}
251 251
 
252 252
 	if payload.TypeUrl == "" {
253
-		return grpc.Errorf(codes.InvalidArgument, "Generic runtime is missing payload type")
253
+		return status.Errorf(codes.InvalidArgument, "Generic runtime is missing payload type")
254 254
 	}
255 255
 
256 256
 	if len(payload.Value) == 0 {
257
-		return grpc.Errorf(codes.InvalidArgument, "Generic runtime has an empty payload")
257
+		return status.Errorf(codes.InvalidArgument, "Generic runtime has an empty payload")
258 258
 	}
259 259
 
260 260
 	return nil
... ...
@@ -284,7 +284,7 @@ func validateTaskSpec(taskSpec api.TaskSpec) error {
284 284
 	}
285 285
 
286 286
 	if taskSpec.GetRuntime() == nil {
287
-		return grpc.Errorf(codes.InvalidArgument, "TaskSpec: missing runtime")
287
+		return status.Errorf(codes.InvalidArgument, "TaskSpec: missing runtime")
288 288
 	}
289 289
 
290 290
 	switch taskSpec.GetRuntime().(type) {
... ...
@@ -297,7 +297,7 @@ func validateTaskSpec(taskSpec api.TaskSpec) error {
297 297
 			return err
298 298
 		}
299 299
 	default:
300
-		return grpc.Errorf(codes.Unimplemented, "RuntimeSpec: unimplemented runtime in service spec")
300
+		return status.Errorf(codes.Unimplemented, "RuntimeSpec: unimplemented runtime in service spec")
301 301
 	}
302 302
 
303 303
 	return nil
... ...
@@ -324,7 +324,7 @@ func validateEndpointSpec(epSpec *api.EndpointSpec) error {
324 324
 		// for the backend network and hence we accept that configuration.
325 325
 
326 326
 		if epSpec.Mode == api.ResolutionModeDNSRoundRobin && port.PublishMode == api.PublishModeIngress {
327
-			return grpc.Errorf(codes.InvalidArgument, "EndpointSpec: port published with ingress mode can't be used with dnsrr mode")
327
+			return status.Errorf(codes.InvalidArgument, "EndpointSpec: port published with ingress mode can't be used with dnsrr mode")
328 328
 		}
329 329
 
330 330
 		// If published port is not specified, it does not conflict
... ...
@@ -335,7 +335,7 @@ func validateEndpointSpec(epSpec *api.EndpointSpec) error {
335 335
 
336 336
 		portSpec := portSpec{publishedPort: port.PublishedPort, protocol: port.Protocol}
337 337
 		if _, ok := portSet[portSpec]; ok {
338
-			return grpc.Errorf(codes.InvalidArgument, "EndpointSpec: duplicate published ports provided")
338
+			return status.Errorf(codes.InvalidArgument, "EndpointSpec: duplicate published ports provided")
339 339
 		}
340 340
 
341 341
 		portSet[portSpec] = struct{}{}
... ...
@@ -358,23 +358,23 @@ func validateSecretRefsSpec(spec api.TaskSpec) error {
358 358
 	for _, secretRef := range container.Secrets {
359 359
 		// SecretID and SecretName are mandatory, we have invalid references without them
360 360
 		if secretRef.SecretID == "" || secretRef.SecretName == "" {
361
-			return grpc.Errorf(codes.InvalidArgument, "malformed secret reference")
361
+			return status.Errorf(codes.InvalidArgument, "malformed secret reference")
362 362
 		}
363 363
 
364 364
 		// Every secret reference requires a Target
365 365
 		if secretRef.GetTarget() == nil {
366
-			return grpc.Errorf(codes.InvalidArgument, "malformed secret reference, no target provided")
366
+			return status.Errorf(codes.InvalidArgument, "malformed secret reference, no target provided")
367 367
 		}
368 368
 
369 369
 		// If this is a file target, we will ensure filename uniqueness
370 370
 		if secretRef.GetFile() != nil {
371 371
 			fileName := secretRef.GetFile().Name
372 372
 			if fileName == "" {
373
-				return grpc.Errorf(codes.InvalidArgument, "malformed file secret reference, invalid target file name provided")
373
+				return status.Errorf(codes.InvalidArgument, "malformed file secret reference, invalid target file name provided")
374 374
 			}
375 375
 			// If this target is already in use, we have conflicting targets
376 376
 			if prevSecretName, ok := existingTargets[fileName]; ok {
377
-				return grpc.Errorf(codes.InvalidArgument, "secret references '%s' and '%s' have a conflicting target: '%s'", prevSecretName, secretRef.SecretName, fileName)
377
+				return status.Errorf(codes.InvalidArgument, "secret references '%s' and '%s' have a conflicting target: '%s'", prevSecretName, secretRef.SecretName, fileName)
378 378
 			}
379 379
 
380 380
 			existingTargets[fileName] = secretRef.SecretName
... ...
@@ -398,12 +398,12 @@ func validateConfigRefsSpec(spec api.TaskSpec) error {
398 398
 	for _, configRef := range container.Configs {
399 399
 		// ConfigID and ConfigName are mandatory, we have invalid references without them
400 400
 		if configRef.ConfigID == "" || configRef.ConfigName == "" {
401
-			return grpc.Errorf(codes.InvalidArgument, "malformed config reference")
401
+			return status.Errorf(codes.InvalidArgument, "malformed config reference")
402 402
 		}
403 403
 
404 404
 		// Every config reference requires a Target
405 405
 		if configRef.GetTarget() == nil {
406
-			return grpc.Errorf(codes.InvalidArgument, "malformed config reference, no target provided")
406
+			return status.Errorf(codes.InvalidArgument, "malformed config reference, no target provided")
407 407
 		}
408 408
 
409 409
 		// If this is a file target, we will ensure filename uniqueness
... ...
@@ -411,12 +411,12 @@ func validateConfigRefsSpec(spec api.TaskSpec) error {
411 411
 			fileName := configRef.GetFile().Name
412 412
 			// Validate the file name
413 413
 			if fileName == "" {
414
-				return grpc.Errorf(codes.InvalidArgument, "malformed file config reference, invalid target file name provided")
414
+				return status.Errorf(codes.InvalidArgument, "malformed file config reference, invalid target file name provided")
415 415
 			}
416 416
 
417 417
 			// If this target is already in use, we have conflicting targets
418 418
 			if prevConfigName, ok := existingTargets[fileName]; ok {
419
-				return grpc.Errorf(codes.InvalidArgument, "config references '%s' and '%s' have a conflicting target: '%s'", prevConfigName, configRef.ConfigName, fileName)
419
+				return status.Errorf(codes.InvalidArgument, "config references '%s' and '%s' have a conflicting target: '%s'", prevConfigName, configRef.ConfigName, fileName)
420 420
 			}
421 421
 
422 422
 			existingTargets[fileName] = configRef.ConfigName
... ...
@@ -436,7 +436,7 @@ func (s *Server) validateNetworks(networks []*api.NetworkAttachmentConfig) error
436 436
 			continue
437 437
 		}
438 438
 		if allocator.IsIngressNetwork(network) {
439
-			return grpc.Errorf(codes.InvalidArgument,
439
+			return status.Errorf(codes.InvalidArgument,
440 440
 				"Service cannot be explicitly attached to the ingress network %q", network.Spec.Annotations.Name)
441 441
 		}
442 442
 	}
... ...
@@ -448,11 +448,11 @@ func validateMode(s *api.ServiceSpec) error {
448 448
 	switch m.(type) {
449 449
 	case *api.ServiceSpec_Replicated:
450 450
 		if int64(m.(*api.ServiceSpec_Replicated).Replicated.Replicas) < 0 {
451
-			return grpc.Errorf(codes.InvalidArgument, "Number of replicas must be non-negative")
451
+			return status.Errorf(codes.InvalidArgument, "Number of replicas must be non-negative")
452 452
 		}
453 453
 	case *api.ServiceSpec_Global:
454 454
 	default:
455
-		return grpc.Errorf(codes.InvalidArgument, "Unrecognized service mode")
455
+		return status.Errorf(codes.InvalidArgument, "Unrecognized service mode")
456 456
 	}
457 457
 
458 458
 	return nil
... ...
@@ -460,7 +460,7 @@ func validateMode(s *api.ServiceSpec) error {
460 460
 
461 461
 func validateServiceSpec(spec *api.ServiceSpec) error {
462 462
 	if spec == nil {
463
-		return grpc.Errorf(codes.InvalidArgument, errInvalidArgument.Error())
463
+		return status.Errorf(codes.InvalidArgument, errInvalidArgument.Error())
464 464
 	}
465 465
 	if err := validateAnnotations(spec.Annotations); err != nil {
466 466
 		return err
... ...
@@ -536,7 +536,7 @@ func (s *Server) checkPortConflicts(spec *api.ServiceSpec, serviceID string) err
536 536
 		switch pc.PublishMode {
537 537
 		case api.PublishModeHost:
538 538
 			if _, ok := ingressPorts[pcToStruct(pc)]; ok {
539
-				return grpc.Errorf(codes.InvalidArgument, "port '%d' is already in use by service '%s' (%s) as a host-published port", pc.PublishedPort, service.Spec.Annotations.Name, service.ID)
539
+				return status.Errorf(codes.InvalidArgument, "port '%d' is already in use by service '%s' (%s) as a host-published port", pc.PublishedPort, service.Spec.Annotations.Name, service.ID)
540 540
 			}
541 541
 
542 542
 			// Multiple services with same port in host publish mode can
... ...
@@ -546,7 +546,7 @@ func (s *Server) checkPortConflicts(spec *api.ServiceSpec, serviceID string) err
546 546
 			_, ingressConflict := ingressPorts[pcToStruct(pc)]
547 547
 			_, hostModeConflict := hostModePorts[pcToStruct(pc)]
548 548
 			if ingressConflict || hostModeConflict {
549
-				return grpc.Errorf(codes.InvalidArgument, "port '%d' is already in use by service '%s' (%s) as an ingress port", pc.PublishedPort, service.Spec.Annotations.Name, service.ID)
549
+				return status.Errorf(codes.InvalidArgument, "port '%d' is already in use by service '%s' (%s) as an ingress port", pc.PublishedPort, service.Spec.Annotations.Name, service.ID)
550 550
 			}
551 551
 		}
552 552
 
... ...
@@ -598,7 +598,7 @@ func (s *Server) checkSecretExistence(tx store.Tx, spec *api.ServiceSpec) error
598 598
 			secretStr = "secret"
599 599
 		}
600 600
 
601
-		return grpc.Errorf(codes.InvalidArgument, "%s not found: %v", secretStr, strings.Join(failedSecrets, ", "))
601
+		return status.Errorf(codes.InvalidArgument, "%s not found: %v", secretStr, strings.Join(failedSecrets, ", "))
602 602
 
603 603
 	}
604 604
 
... ...
@@ -627,7 +627,7 @@ func (s *Server) checkConfigExistence(tx store.Tx, spec *api.ServiceSpec) error
627 627
 			configStr = "config"
628 628
 		}
629 629
 
630
-		return grpc.Errorf(codes.InvalidArgument, "%s not found: %v", configStr, strings.Join(failedConfigs, ", "))
630
+		return status.Errorf(codes.InvalidArgument, "%s not found: %v", configStr, strings.Join(failedConfigs, ", "))
631 631
 
632 632
 	}
633 633
 
... ...
@@ -662,7 +662,7 @@ func (s *Server) CreateService(ctx context.Context, request *api.CreateServiceRe
662 662
 
663 663
 	if allocator.IsIngressNetworkNeeded(service) {
664 664
 		if _, err := allocator.GetIngressNetwork(s.store); err == allocator.ErrNoIngress {
665
-			return nil, grpc.Errorf(codes.FailedPrecondition, "service needs ingress network, but no ingress network is present")
665
+			return nil, status.Errorf(codes.FailedPrecondition, "service needs ingress network, but no ingress network is present")
666 666
 		}
667 667
 	}
668 668
 
... ...
@@ -694,7 +694,7 @@ func (s *Server) CreateService(ctx context.Context, request *api.CreateServiceRe
694 694
 // - Returns `NotFound` if the Service is not found.
695 695
 func (s *Server) GetService(ctx context.Context, request *api.GetServiceRequest) (*api.GetServiceResponse, error) {
696 696
 	if request.ServiceID == "" {
697
-		return nil, grpc.Errorf(codes.InvalidArgument, errInvalidArgument.Error())
697
+		return nil, status.Errorf(codes.InvalidArgument, errInvalidArgument.Error())
698 698
 	}
699 699
 
700 700
 	var service *api.Service
... ...
@@ -702,7 +702,7 @@ func (s *Server) GetService(ctx context.Context, request *api.GetServiceRequest)
702 702
 		service = store.GetService(tx, request.ServiceID)
703 703
 	})
704 704
 	if service == nil {
705
-		return nil, grpc.Errorf(codes.NotFound, "service %s not found", request.ServiceID)
705
+		return nil, status.Errorf(codes.NotFound, "service %s not found", request.ServiceID)
706 706
 	}
707 707
 
708 708
 	if request.InsertDefaults {
... ...
@@ -721,7 +721,7 @@ func (s *Server) GetService(ctx context.Context, request *api.GetServiceRequest)
721 721
 // - Returns an error if the update fails.
722 722
 func (s *Server) UpdateService(ctx context.Context, request *api.UpdateServiceRequest) (*api.UpdateServiceResponse, error) {
723 723
 	if request.ServiceID == "" || request.ServiceVersion == nil {
724
-		return nil, grpc.Errorf(codes.InvalidArgument, errInvalidArgument.Error())
724
+		return nil, status.Errorf(codes.InvalidArgument, errInvalidArgument.Error())
725 725
 	}
726 726
 	if err := validateServiceSpec(request.Spec); err != nil {
727 727
 		return nil, err
... ...
@@ -732,7 +732,7 @@ func (s *Server) UpdateService(ctx context.Context, request *api.UpdateServiceRe
732 732
 		service = store.GetService(tx, request.ServiceID)
733 733
 	})
734 734
 	if service == nil {
735
-		return nil, grpc.Errorf(codes.NotFound, "service %s not found", request.ServiceID)
735
+		return nil, status.Errorf(codes.NotFound, "service %s not found", request.ServiceID)
736 736
 	}
737 737
 
738 738
 	if request.Spec.Endpoint != nil && !reflect.DeepEqual(request.Spec.Endpoint, service.Spec.Endpoint) {
... ...
@@ -744,7 +744,7 @@ func (s *Server) UpdateService(ctx context.Context, request *api.UpdateServiceRe
744 744
 	err := s.store.Update(func(tx store.Tx) error {
745 745
 		service = store.GetService(tx, request.ServiceID)
746 746
 		if service == nil {
747
-			return grpc.Errorf(codes.NotFound, "service %s not found", request.ServiceID)
747
+			return status.Errorf(codes.NotFound, "service %s not found", request.ServiceID)
748 748
 		}
749 749
 
750 750
 		// It's not okay to update Service.Spec.Networks on its own.
... ...
@@ -754,7 +754,7 @@ func (s *Server) UpdateService(ctx context.Context, request *api.UpdateServiceRe
754 754
 		if (len(request.Spec.Networks) != 0 || len(service.Spec.Networks) != 0) &&
755 755
 			!reflect.DeepEqual(request.Spec.Networks, service.Spec.Networks) &&
756 756
 			reflect.DeepEqual(request.Spec.Task.Networks, service.Spec.Task.Networks) {
757
-			return grpc.Errorf(codes.Unimplemented, errNetworkUpdateNotSupported.Error())
757
+			return status.Errorf(codes.Unimplemented, errNetworkUpdateNotSupported.Error())
758 758
 		}
759 759
 
760 760
 		// Check to see if all the secrets being added exist as objects
... ...
@@ -773,18 +773,18 @@ func (s *Server) UpdateService(ctx context.Context, request *api.UpdateServiceRe
773 773
 		// with service mode change (comparing current config with previous config).
774 774
 		// proper way to change service mode is to delete and re-add.
775 775
 		if reflect.TypeOf(service.Spec.Mode) != reflect.TypeOf(request.Spec.Mode) {
776
-			return grpc.Errorf(codes.Unimplemented, errModeChangeNotAllowed.Error())
776
+			return status.Errorf(codes.Unimplemented, errModeChangeNotAllowed.Error())
777 777
 		}
778 778
 
779 779
 		if service.Spec.Annotations.Name != request.Spec.Annotations.Name {
780
-			return grpc.Errorf(codes.Unimplemented, errRenameNotSupported.Error())
780
+			return status.Errorf(codes.Unimplemented, errRenameNotSupported.Error())
781 781
 		}
782 782
 
783 783
 		service.Meta.Version = *request.ServiceVersion
784 784
 
785 785
 		if request.Rollback == api.UpdateServiceRequest_PREVIOUS {
786 786
 			if service.PreviousSpec == nil {
787
-				return grpc.Errorf(codes.FailedPrecondition, "service %s does not have a previous spec", request.ServiceID)
787
+				return status.Errorf(codes.FailedPrecondition, "service %s does not have a previous spec", request.ServiceID)
788 788
 			}
789 789
 
790 790
 			curSpec := service.Spec.Copy()
... ...
@@ -815,7 +815,7 @@ func (s *Server) UpdateService(ctx context.Context, request *api.UpdateServiceRe
815 815
 
816 816
 		if allocator.IsIngressNetworkNeeded(service) {
817 817
 			if _, err := allocator.GetIngressNetwork(s.store); err == allocator.ErrNoIngress {
818
-				return grpc.Errorf(codes.FailedPrecondition, "service needs ingress network, but no ingress network is present")
818
+				return status.Errorf(codes.FailedPrecondition, "service needs ingress network, but no ingress network is present")
819 819
 			}
820 820
 		}
821 821
 
... ...
@@ -836,7 +836,7 @@ func (s *Server) UpdateService(ctx context.Context, request *api.UpdateServiceRe
836 836
 // - Returns an error if the deletion fails.
837 837
 func (s *Server) RemoveService(ctx context.Context, request *api.RemoveServiceRequest) (*api.RemoveServiceResponse, error) {
838 838
 	if request.ServiceID == "" {
839
-		return nil, grpc.Errorf(codes.InvalidArgument, errInvalidArgument.Error())
839
+		return nil, status.Errorf(codes.InvalidArgument, errInvalidArgument.Error())
840 840
 	}
841 841
 
842 842
 	err := s.store.Update(func(tx store.Tx) error {
... ...
@@ -844,7 +844,7 @@ func (s *Server) RemoveService(ctx context.Context, request *api.RemoveServiceRe
844 844
 	})
845 845
 	if err != nil {
846 846
 		if err == store.ErrNotExist {
847
-			return nil, grpc.Errorf(codes.NotFound, "service %s not found", request.ServiceID)
847
+			return nil, status.Errorf(codes.NotFound, "service %s not found", request.ServiceID)
848 848
 		}
849 849
 		return nil, err
850 850
 	}
... ...
@@ -6,8 +6,8 @@ import (
6 6
 	"github.com/docker/swarmkit/manager/orchestrator"
7 7
 	"github.com/docker/swarmkit/manager/state/store"
8 8
 	"golang.org/x/net/context"
9
-	"google.golang.org/grpc"
10 9
 	"google.golang.org/grpc/codes"
10
+	"google.golang.org/grpc/status"
11 11
 )
12 12
 
13 13
 // GetTask returns a Task given a TaskID.
... ...
@@ -15,7 +15,7 @@ import (
15 15
 // - Returns `NotFound` if the Task is not found.
16 16
 func (s *Server) GetTask(ctx context.Context, request *api.GetTaskRequest) (*api.GetTaskResponse, error) {
17 17
 	if request.TaskID == "" {
18
-		return nil, grpc.Errorf(codes.InvalidArgument, errInvalidArgument.Error())
18
+		return nil, status.Errorf(codes.InvalidArgument, errInvalidArgument.Error())
19 19
 	}
20 20
 
21 21
 	var task *api.Task
... ...
@@ -23,7 +23,7 @@ func (s *Server) GetTask(ctx context.Context, request *api.GetTaskRequest) (*api
23 23
 		task = store.GetTask(tx, request.TaskID)
24 24
 	})
25 25
 	if task == nil {
26
-		return nil, grpc.Errorf(codes.NotFound, "task %s not found", request.TaskID)
26
+		return nil, status.Errorf(codes.NotFound, "task %s not found", request.TaskID)
27 27
 	}
28 28
 	return &api.GetTaskResponse{
29 29
 		Task: task,
... ...
@@ -36,7 +36,7 @@ func (s *Server) GetTask(ctx context.Context, request *api.GetTaskRequest) (*api
36 36
 // - Returns an error if the deletion fails.
37 37
 func (s *Server) RemoveTask(ctx context.Context, request *api.RemoveTaskRequest) (*api.RemoveTaskResponse, error) {
38 38
 	if request.TaskID == "" {
39
-		return nil, grpc.Errorf(codes.InvalidArgument, errInvalidArgument.Error())
39
+		return nil, status.Errorf(codes.InvalidArgument, errInvalidArgument.Error())
40 40
 	}
41 41
 
42 42
 	err := s.store.Update(func(tx store.Tx) error {
... ...
@@ -44,7 +44,7 @@ func (s *Server) RemoveTask(ctx context.Context, request *api.RemoveTaskRequest)
44 44
 	})
45 45
 	if err != nil {
46 46
 		if err == store.ErrNotExist {
47
-			return nil, grpc.Errorf(codes.NotFound, "task %s not found", request.TaskID)
47
+			return nil, status.Errorf(codes.NotFound, "task %s not found", request.TaskID)
48 48
 		}
49 49
 		return nil, err
50 50
 	}
... ...
@@ -7,11 +7,8 @@ import (
7 7
 	"sync"
8 8
 	"time"
9 9
 
10
-	"google.golang.org/grpc"
11
-	"google.golang.org/grpc/codes"
12
-	"google.golang.org/grpc/transport"
13
-
14 10
 	"github.com/docker/go-events"
11
+	"github.com/docker/go-metrics"
15 12
 	"github.com/docker/swarmkit/api"
16 13
 	"github.com/docker/swarmkit/api/equality"
17 14
 	"github.com/docker/swarmkit/ca"
... ...
@@ -25,6 +22,9 @@ import (
25 25
 	"github.com/pkg/errors"
26 26
 	"github.com/sirupsen/logrus"
27 27
 	"golang.org/x/net/context"
28
+	"google.golang.org/grpc/codes"
29
+	"google.golang.org/grpc/status"
30
+	"google.golang.org/grpc/transport"
28 31
 )
29 32
 
30 33
 const (
... ...
@@ -66,8 +66,18 @@ var (
66 66
 	ErrSessionInvalid = errors.New("session invalid")
67 67
 	// ErrNodeNotFound returned when the Node doesn't exist in raft.
68 68
 	ErrNodeNotFound = errors.New("node not found")
69
+
70
+	// Scheduling delay timer.
71
+	schedulingDelayTimer metrics.Timer
69 72
 )
70 73
 
74
+func init() {
75
+	ns := metrics.NewNamespace("swarm", "dispatcher", nil)
76
+	schedulingDelayTimer = ns.NewTimer("scheduling_delay",
77
+		"Scheduling delay is the time a task takes to go from NEW to RUNNING state.")
78
+	metrics.Register(ns)
79
+}
80
+
71 81
 // Config is configuration for Dispatcher. For default you should use
72 82
 // DefaultConfig.
73 83
 type Config struct {
... ...
@@ -322,7 +332,7 @@ func (d *Dispatcher) isRunningLocked() (context.Context, error) {
322 322
 	d.mu.Lock()
323 323
 	if !d.isRunning() {
324 324
 		d.mu.Unlock()
325
-		return nil, grpc.Errorf(codes.Aborted, "dispatcher is stopped")
325
+		return nil, status.Errorf(codes.Aborted, "dispatcher is stopped")
326 326
 	}
327 327
 	ctx := d.ctx
328 328
 	d.mu.Unlock()
... ...
@@ -556,7 +566,7 @@ func (d *Dispatcher) UpdateTaskStatus(ctx context.Context, r *api.UpdateTaskStat
556 556
 		}
557 557
 
558 558
 		if t.NodeID != nodeID {
559
-			err := grpc.Errorf(codes.PermissionDenied, "cannot update a task not assigned this node")
559
+			err := status.Errorf(codes.PermissionDenied, "cannot update a task not assigned this node")
560 560
 			log.WithField("task.id", u.TaskID).Error(err)
561 561
 			return nil, err
562 562
 		}
... ...
@@ -632,6 +642,17 @@ func (d *Dispatcher) processUpdates(ctx context.Context) {
632 632
 					return nil
633 633
 				}
634 634
 
635
+				// Update scheduling delay metric for running tasks.
636
+				// We use the status update time on the leader to calculate the scheduling delay.
637
+				// Because of this, the recorded scheduling delay will be an overestimate and include
638
+				// the network delay between the worker and the leader.
639
+				// This is not ideal, but its a known overestimation, rather than using the status update time
640
+				// from the worker node, which may cause unknown incorrect results due to possible clock skew.
641
+				if status.State == api.TaskStateRunning {
642
+					start := time.Unix(status.AppliedAt.GetSeconds(), int64(status.AppliedAt.GetNanos()))
643
+					schedulingDelayTimer.UpdateSince(start)
644
+				}
645
+
635 646
 				task.Status = *status
636 647
 				task.Status.AppliedBy = d.securityConfig.ClientTLSCreds.NodeID()
637 648
 				task.Status.AppliedAt = ptypes.MustTimestampProto(time.Now())
... ...
@@ -1189,7 +1210,7 @@ func (d *Dispatcher) Session(r *api.SessionRequest, stream api.Dispatcher_Sessio
1189 1189
 			log.WithError(err).Error("failed to remove node")
1190 1190
 		}
1191 1191
 		// still return an abort if the transport closure was ineffective.
1192
-		return grpc.Errorf(codes.Aborted, "node must disconnect")
1192
+		return status.Errorf(codes.Aborted, "node must disconnect")
1193 1193
 	}
1194 1194
 
1195 1195
 	for {
... ...
@@ -4,12 +4,11 @@ import (
4 4
 	"sync"
5 5
 	"time"
6 6
 
7
-	"google.golang.org/grpc"
8
-	"google.golang.org/grpc/codes"
9
-
10 7
 	"github.com/docker/swarmkit/api"
11 8
 	"github.com/docker/swarmkit/identity"
12 9
 	"github.com/docker/swarmkit/manager/dispatcher/heartbeat"
10
+	"google.golang.org/grpc/codes"
11
+	"google.golang.org/grpc/status"
13 12
 )
14 13
 
15 14
 const rateLimitCount = 3
... ...
@@ -36,7 +35,7 @@ func (rn *registeredNode) checkSessionID(sessionID string) error {
36 36
 	// changed. If it has, we will the stream and make the node
37 37
 	// re-register.
38 38
 	if sessionID == "" || rn.SessionID != sessionID {
39
-		return grpc.Errorf(codes.InvalidArgument, ErrSessionInvalid.Error())
39
+		return status.Errorf(codes.InvalidArgument, ErrSessionInvalid.Error())
40 40
 	}
41 41
 
42 42
 	return nil
... ...
@@ -97,7 +96,7 @@ func (s *nodeStore) CheckRateLimit(id string) error {
97 97
 		}
98 98
 		existRn.Attempts++
99 99
 		if existRn.Attempts > rateLimitCount {
100
-			return grpc.Errorf(codes.Unavailable, "node %s exceeded rate limit count of registrations", id)
100
+			return status.Errorf(codes.Unavailable, "node %s exceeded rate limit count of registrations", id)
101 101
 		}
102 102
 		existRn.Registered = time.Now()
103 103
 	}
... ...
@@ -136,7 +135,7 @@ func (s *nodeStore) Get(id string) (*registeredNode, error) {
136 136
 	rn, ok := s.nodes[id]
137 137
 	s.mu.RUnlock()
138 138
 	if !ok {
139
-		return nil, grpc.Errorf(codes.NotFound, ErrNodeNotRegistered.Error())
139
+		return nil, status.Errorf(codes.NotFound, ErrNodeNotRegistered.Error())
140 140
 	}
141 141
 	return rn, nil
142 142
 }
... ...
@@ -146,7 +145,7 @@ func (s *nodeStore) GetWithSession(id, sid string) (*registeredNode, error) {
146 146
 	rn, ok := s.nodes[id]
147 147
 	s.mu.RUnlock()
148 148
 	if !ok {
149
-		return nil, grpc.Errorf(codes.NotFound, ErrNodeNotRegistered.Error())
149
+		return nil, status.Errorf(codes.NotFound, ErrNodeNotRegistered.Error())
150 150
 	}
151 151
 	return rn, rn.checkSessionID(sid)
152 152
 }
... ...
@@ -12,8 +12,8 @@ import (
12 12
 
13 13
 	"github.com/docker/swarmkit/api"
14 14
 	"golang.org/x/net/context"
15
-	"google.golang.org/grpc"
16 15
 	"google.golang.org/grpc/codes"
16
+	"google.golang.org/grpc/status"
17 17
 )
18 18
 
19 19
 // Server represents a Health Check server to check
... ...
@@ -46,7 +46,7 @@ func (s *Server) Check(ctx context.Context, in *api.HealthCheckRequest) (*api.He
46 46
 			Status: status,
47 47
 		}, nil
48 48
 	}
49
-	return nil, grpc.Errorf(codes.NotFound, "unknown service")
49
+	return nil, status.Errorf(codes.NotFound, "unknown service")
50 50
 }
51 51
 
52 52
 // SetServingStatus is called when need to reset the serving status of a service
... ...
@@ -6,9 +6,6 @@ import (
6 6
 	"io"
7 7
 	"sync"
8 8
 
9
-	"google.golang.org/grpc"
10
-	"google.golang.org/grpc/codes"
11
-
12 9
 	"github.com/docker/go-events"
13 10
 	"github.com/docker/swarmkit/api"
14 11
 	"github.com/docker/swarmkit/ca"
... ...
@@ -18,6 +15,8 @@ import (
18 18
 	"github.com/docker/swarmkit/watch"
19 19
 	"github.com/sirupsen/logrus"
20 20
 	"golang.org/x/net/context"
21
+	"google.golang.org/grpc/codes"
22
+	"google.golang.org/grpc/status"
21 23
 )
22 24
 
23 25
 var (
... ...
@@ -93,11 +92,11 @@ func (lb *LogBroker) Stop() error {
93 93
 
94 94
 func validateSelector(selector *api.LogSelector) error {
95 95
 	if selector == nil {
96
-		return grpc.Errorf(codes.InvalidArgument, "log selector must be provided")
96
+		return status.Errorf(codes.InvalidArgument, "log selector must be provided")
97 97
 	}
98 98
 
99 99
 	if len(selector.ServiceIDs) == 0 && len(selector.TaskIDs) == 0 && len(selector.NodeIDs) == 0 {
100
-		return grpc.Errorf(codes.InvalidArgument, "log selector must not be empty")
100
+		return status.Errorf(codes.InvalidArgument, "log selector must not be empty")
101 101
 	}
102 102
 
103 103
 	return nil
... ...
@@ -401,17 +400,17 @@ func (lb *LogBroker) PublishLogs(stream api.LogBroker_PublishLogsServer) (err er
401 401
 		}
402 402
 
403 403
 		if logMsg.SubscriptionID == "" {
404
-			return grpc.Errorf(codes.InvalidArgument, "missing subscription ID")
404
+			return status.Errorf(codes.InvalidArgument, "missing subscription ID")
405 405
 		}
406 406
 
407 407
 		if currentSubscription == nil {
408 408
 			currentSubscription = lb.getSubscription(logMsg.SubscriptionID)
409 409
 			if currentSubscription == nil {
410
-				return grpc.Errorf(codes.NotFound, "unknown subscription ID")
410
+				return status.Errorf(codes.NotFound, "unknown subscription ID")
411 411
 			}
412 412
 		} else {
413 413
 			if logMsg.SubscriptionID != currentSubscription.message.ID {
414
-				return grpc.Errorf(codes.InvalidArgument, "different subscription IDs in the same session")
414
+				return status.Errorf(codes.InvalidArgument, "different subscription IDs in the same session")
415 415
 			}
416 416
 		}
417 417
 
... ...
@@ -427,7 +426,7 @@ func (lb *LogBroker) PublishLogs(stream api.LogBroker_PublishLogsServer) (err er
427 427
 		// Make sure logs are emitted using the right Node ID to avoid impersonation.
428 428
 		for _, msg := range logMsg.Messages {
429 429
 			if msg.Context.NodeID != remote.NodeID {
430
-				return grpc.Errorf(codes.PermissionDenied, "invalid NodeID: expected=%s;received=%s", remote.NodeID, msg.Context.NodeID)
430
+				return status.Errorf(codes.PermissionDenied, "invalid NodeID: expected=%s;received=%s", remote.NodeID, msg.Context.NodeID)
431 431
 			}
432 432
 		}
433 433
 
... ...
@@ -38,6 +38,7 @@ import (
38 38
 	"github.com/docker/swarmkit/manager/resourceapi"
39 39
 	"github.com/docker/swarmkit/manager/scheduler"
40 40
 	"github.com/docker/swarmkit/manager/state/raft"
41
+	"github.com/docker/swarmkit/manager/state/raft/transport"
41 42
 	"github.com/docker/swarmkit/manager/state/store"
42 43
 	"github.com/docker/swarmkit/manager/watchapi"
43 44
 	"github.com/docker/swarmkit/remotes"
... ...
@@ -54,9 +55,6 @@ import (
54 54
 const (
55 55
 	// defaultTaskHistoryRetentionLimit is the number of tasks to keep.
56 56
 	defaultTaskHistoryRetentionLimit = 5
57
-
58
-	// Default value for grpc max message size.
59
-	grpcMaxMessageSize = 128 << 20
60 57
 )
61 58
 
62 59
 // RemoteAddrs provides a listening address and an optional advertise address
... ...
@@ -234,7 +232,7 @@ func New(config *Config) (*Manager, error) {
234 234
 		grpc.Creds(config.SecurityConfig.ServerTLSCreds),
235 235
 		grpc.StreamInterceptor(grpc_prometheus.StreamServerInterceptor),
236 236
 		grpc.UnaryInterceptor(grpc_prometheus.UnaryServerInterceptor),
237
-		grpc.MaxMsgSize(grpcMaxMessageSize),
237
+		grpc.MaxMsgSize(transport.GRPCMaxMsgSize),
238 238
 	}
239 239
 
240 240
 	m := &Manager{
... ...
@@ -404,7 +402,7 @@ func (m *Manager) Run(parent context.Context) error {
404 404
 		)
405 405
 
406 406
 		m.raftNode.MemoryStore().View(func(readTx store.ReadTx) {
407
-			clusters, err = store.FindClusters(readTx, store.ByName("default"))
407
+			clusters, err = store.FindClusters(readTx, store.ByName(store.DefaultClusterName))
408 408
 
409 409
 		})
410 410
 
... ...
@@ -954,13 +952,18 @@ func (m *Manager) becomeLeader(ctx context.Context) {
954 954
 		// store. Don't check the error because
955 955
 		// we expect this to fail unless this
956 956
 		// is a brand new cluster.
957
-		store.CreateCluster(tx, defaultClusterObject(
957
+		err := store.CreateCluster(tx, defaultClusterObject(
958 958
 			clusterID,
959 959
 			initialCAConfig,
960 960
 			raftCfg,
961 961
 			api.EncryptionConfig{AutoLockManagers: m.config.AutoLockManagers},
962 962
 			unlockKeys,
963 963
 			rootCA))
964
+
965
+		if err != nil && err != store.ErrExist {
966
+			log.G(ctx).WithError(err).Errorf("error creating cluster object")
967
+		}
968
+
964 969
 		// Add Node entry for ourself, if one
965 970
 		// doesn't exist already.
966 971
 		freshCluster := nil == store.CreateNode(tx, managerNode(nodeID, m.config.Availability))
... ...
@@ -73,7 +73,7 @@ func (g *Orchestrator) Run(ctx context.Context) error {
73 73
 	var err error
74 74
 	g.store.View(func(readTx store.ReadTx) {
75 75
 		var clusters []*api.Cluster
76
-		clusters, err = store.FindClusters(readTx, store.ByName("default"))
76
+		clusters, err = store.FindClusters(readTx, store.ByName(store.DefaultClusterName))
77 77
 
78 78
 		if len(clusters) != 1 {
79 79
 			return // just pick up the cluster when it is created.
... ...
@@ -147,7 +147,7 @@ func (g *Orchestrator) Run(ctx context.Context) error {
147 147
 				if !orchestrator.IsGlobalService(v.Service) {
148 148
 					continue
149 149
 				}
150
-				orchestrator.DeleteServiceTasks(ctx, g.store, v.Service)
150
+				orchestrator.SetServiceTasksRemove(ctx, g.store, v.Service)
151 151
 				// delete the service from service map
152 152
 				delete(g.globalServices, v.Service.ID)
153 153
 				g.restarts.ClearServiceHistory(v.Service.ID)
... ...
@@ -17,7 +17,7 @@ import (
17 17
 // responds to changes in individual tasks (or nodes which run them).
18 18
 
19 19
 func (r *Orchestrator) initCluster(readTx store.ReadTx) error {
20
-	clusters, err := store.FindClusters(readTx, store.ByName("default"))
20
+	clusters, err := store.FindClusters(readTx, store.ByName(store.DefaultClusterName))
21 21
 	if err != nil {
22 22
 		return err
23 23
 	}
... ...
@@ -50,7 +50,7 @@ func (r *Orchestrator) handleServiceEvent(ctx context.Context, event events.Even
50 50
 		if !orchestrator.IsReplicatedService(v.Service) {
51 51
 			return
52 52
 		}
53
-		orchestrator.DeleteServiceTasks(ctx, r.store, v.Service)
53
+		orchestrator.SetServiceTasksRemove(ctx, r.store, v.Service)
54 54
 		r.restarts.ClearServiceHistory(v.Service.ID)
55 55
 		delete(r.reconcileServices, v.Service.ID)
56 56
 	case api.EventCreateService:
... ...
@@ -86,6 +86,12 @@ func (r *Orchestrator) resolveService(ctx context.Context, task *api.Task) *api.
86 86
 	return service
87 87
 }
88 88
 
89
+// reconcile decides what actions must be taken depending on the number of
90
+// specificed slots and actual running slots. If the actual running slots are
91
+// fewer than what is requested, it creates new tasks. If the actual running
92
+// slots are more than requested, then it decides which slots must be removed
93
+// and sets desired state of those tasks to REMOVE (the actual removal is handled
94
+// by the task reaper, after the agent shuts the tasks down).
89 95
 func (r *Orchestrator) reconcile(ctx context.Context, service *api.Service) {
90 96
 	runningSlots, deadSlots, err := r.updatableAndDeadSlots(ctx, service)
91 97
 	if err != nil {
... ...
@@ -157,7 +163,11 @@ func (r *Orchestrator) reconcile(ctx context.Context, service *api.Service) {
157 157
 		r.updater.Update(ctx, r.cluster, service, sortedSlots[:specifiedSlots])
158 158
 		err = r.store.Batch(func(batch *store.Batch) error {
159 159
 			r.deleteTasksMap(ctx, batch, deadSlots)
160
-			r.deleteTasks(ctx, batch, sortedSlots[specifiedSlots:])
160
+			// for all slots that we are removing, we set the desired state of those tasks
161
+			// to REMOVE. Then, the agent is responsible for shutting them down, and the
162
+			// task reaper is responsible for actually removing them from the store after
163
+			// shutdown.
164
+			r.setTasksDesiredState(ctx, batch, sortedSlots[specifiedSlots:], api.TaskStateRemove)
161 165
 			return nil
162 166
 		})
163 167
 		if err != nil {
... ...
@@ -198,10 +208,34 @@ func (r *Orchestrator) addTasks(ctx context.Context, batch *store.Batch, service
198 198
 	}
199 199
 }
200 200
 
201
-func (r *Orchestrator) deleteTasks(ctx context.Context, batch *store.Batch, slots []orchestrator.Slot) {
201
+// setTasksDesiredState sets the desired state for all tasks for the given slots to the
202
+// requested state
203
+func (r *Orchestrator) setTasksDesiredState(ctx context.Context, batch *store.Batch, slots []orchestrator.Slot, newDesiredState api.TaskState) {
202 204
 	for _, slot := range slots {
203 205
 		for _, t := range slot {
204
-			r.deleteTask(ctx, batch, t)
206
+			err := batch.Update(func(tx store.Tx) error {
207
+				// time travel is not allowed. if the current desired state is
208
+				// above the one we're trying to go to we can't go backwards.
209
+				// we have nothing to do and we should skip to the next task
210
+				if t.DesiredState > newDesiredState {
211
+					// log a warning, though. we shouln't be trying to rewrite
212
+					// a state to an earlier state
213
+					log.G(ctx).Warnf(
214
+						"cannot update task %v in desired state %v to an earlier desired state %v",
215
+						t.ID, t.DesiredState, newDesiredState,
216
+					)
217
+					return nil
218
+				}
219
+				// update desired state
220
+				t.DesiredState = newDesiredState
221
+
222
+				return store.UpdateTask(tx, t)
223
+			})
224
+
225
+			// log an error if we get one
226
+			if err != nil {
227
+				log.G(ctx).WithError(err).Errorf("failed to update task to %v", newDesiredState.String())
228
+			}
205 229
 		}
206 230
 	}
207 231
 }
... ...
@@ -27,8 +27,10 @@ func IsGlobalService(service *api.Service) bool {
27 27
 	return ok
28 28
 }
29 29
 
30
-// DeleteServiceTasks deletes the tasks associated with a service.
31
-func DeleteServiceTasks(ctx context.Context, s *store.MemoryStore, service *api.Service) {
30
+// SetServiceTasksRemove sets the desired state of tasks associated with a service
31
+// to REMOVE, so that they can be properly shut down by the agent and later removed
32
+// by the task reaper.
33
+func SetServiceTasksRemove(ctx context.Context, s *store.MemoryStore, service *api.Service) {
32 34
 	var (
33 35
 		tasks []*api.Task
34 36
 		err   error
... ...
@@ -44,8 +46,23 @@ func DeleteServiceTasks(ctx context.Context, s *store.MemoryStore, service *api.
44 44
 	err = s.Batch(func(batch *store.Batch) error {
45 45
 		for _, t := range tasks {
46 46
 			err := batch.Update(func(tx store.Tx) error {
47
-				if err := store.DeleteTask(tx, t.ID); err != nil {
48
-					log.G(ctx).WithError(err).Errorf("failed to delete task")
47
+				// time travel is not allowed. if the current desired state is
48
+				// above the one we're trying to go to we can't go backwards.
49
+				// we have nothing to do and we should skip to the next task
50
+				if t.DesiredState > api.TaskStateRemove {
51
+					// log a warning, though. we shouln't be trying to rewrite
52
+					// a state to an earlier state
53
+					log.G(ctx).Warnf(
54
+						"cannot update task %v in desired state %v to an earlier desired state %v",
55
+						t.ID, t.DesiredState, api.TaskStateRemove,
56
+					)
57
+					return nil
58
+				}
59
+				// update desired state to REMOVE
60
+				t.DesiredState = api.TaskStateRemove
61
+
62
+				if err := store.UpdateTask(tx, t); err != nil {
63
+					log.G(ctx).WithError(err).Errorf("failed transaction: update task desired state to REMOVE")
49 64
 				}
50 65
 				return nil
51 66
 			})
... ...
@@ -23,12 +23,19 @@ const (
23 23
 // exist for the same service/instance or service/nodeid combination.
24 24
 type TaskReaper struct {
25 25
 	store *store.MemoryStore
26
+
26 27
 	// taskHistory is the number of tasks to keep
27 28
 	taskHistory int64
28
-	dirty       map[orchestrator.SlotTuple]struct{}
29
-	orphaned    []string
30
-	stopChan    chan struct{}
31
-	doneChan    chan struct{}
29
+
30
+	// List of slot tubles to be inspected for task history cleanup.
31
+	dirty map[orchestrator.SlotTuple]struct{}
32
+
33
+	// List of tasks collected for cleanup, which includes two kinds of tasks
34
+	// - serviceless orphaned tasks
35
+	// - tasks with desired state REMOVE that have already been shut down
36
+	cleanup  []string
37
+	stopChan chan struct{}
38
+	doneChan chan struct{}
32 39
 }
33 40
 
34 41
 // New creates a new TaskReaper.
... ...
@@ -41,7 +48,13 @@ func New(store *store.MemoryStore) *TaskReaper {
41 41
 	}
42 42
 }
43 43
 
44
-// Run is the TaskReaper's main loop.
44
+// Run is the TaskReaper's watch loop which collects candidates for cleanup.
45
+// Task history is mainly used in task restarts but is also available for administrative purposes.
46
+// Note that the task history is stored per-slot-per-service for replicated services
47
+// and per-node-per-service for global services. History does not apply to serviceless
48
+// since they are not attached to a service. In addition, the TaskReaper watch loop is also
49
+// responsible for cleaning up tasks associated with slots that were removed as part of
50
+// service scale down or service removal.
45 51
 func (tr *TaskReaper) Run(ctx context.Context) {
46 52
 	watcher, watchCancel := state.Watch(tr.store.WatchQueue(), api.EventCreateTask{}, api.EventUpdateTask{}, api.EventUpdateCluster{})
47 53
 
... ...
@@ -50,7 +63,8 @@ func (tr *TaskReaper) Run(ctx context.Context) {
50 50
 		watchCancel()
51 51
 	}()
52 52
 
53
-	var tasks []*api.Task
53
+	var orphanedTasks []*api.Task
54
+	var removeTasks []*api.Task
54 55
 	tr.store.View(func(readTx store.ReadTx) {
55 56
 		var err error
56 57
 
... ...
@@ -59,29 +73,54 @@ func (tr *TaskReaper) Run(ctx context.Context) {
59 59
 			tr.taskHistory = clusters[0].Spec.Orchestration.TaskHistoryRetentionLimit
60 60
 		}
61 61
 
62
-		tasks, err = store.FindTasks(readTx, store.ByTaskState(api.TaskStateOrphaned))
62
+		// On startup, scan the entire store and inspect orphaned tasks from previous life.
63
+		orphanedTasks, err = store.FindTasks(readTx, store.ByTaskState(api.TaskStateOrphaned))
63 64
 		if err != nil {
64 65
 			log.G(ctx).WithError(err).Error("failed to find Orphaned tasks in task reaper init")
65 66
 		}
67
+		removeTasks, err = store.FindTasks(readTx, store.ByDesiredState(api.TaskStateRemove))
68
+		if err != nil {
69
+			log.G(ctx).WithError(err).Error("failed to find tasks with desired state REMOVE in task reaper init")
70
+		}
66 71
 	})
67 72
 
68
-	if len(tasks) > 0 {
69
-		for _, t := range tasks {
70
-			// Do not reap service tasks immediately
73
+	if len(orphanedTasks)+len(removeTasks) > 0 {
74
+		for _, t := range orphanedTasks {
75
+			// Do not reap service tasks immediately.
76
+			// Let them go through the regular history cleanup process
77
+			// of checking TaskHistoryRetentionLimit.
71 78
 			if t.ServiceID != "" {
72 79
 				continue
73 80
 			}
74 81
 
75
-			tr.orphaned = append(tr.orphaned, t.ID)
82
+			// Serviceless tasks can be cleaned up right away since they are not attached to a service.
83
+			tr.cleanup = append(tr.cleanup, t.ID)
76 84
 		}
77
-
78
-		if len(tr.orphaned) > 0 {
85
+		// tasks with desired state REMOVE that have progressed beyond SHUTDOWN can be cleaned up
86
+		// right away
87
+		for _, t := range removeTasks {
88
+			if t.Status.State >= api.TaskStateShutdown {
89
+				tr.cleanup = append(tr.cleanup, t.ID)
90
+			}
91
+		}
92
+		// Clean up tasks in 'cleanup' right away
93
+		if len(tr.cleanup) > 0 {
79 94
 			tr.tick()
80 95
 		}
81 96
 	}
82 97
 
98
+	// Clean up when we hit TaskHistoryRetentionLimit or when the timer expires,
99
+	// whichever happens first.
83 100
 	timer := time.NewTimer(reaperBatchingInterval)
84 101
 
102
+	// Watch for:
103
+	// 1. EventCreateTask for cleaning slots, which is the best time to cleanup that node/slot.
104
+	// 2. EventUpdateTask for cleaning
105
+	//    - serviceless orphaned tasks (when orchestrator updates the task status to ORPHANED)
106
+	//    - tasks which have desired state REMOVE and have been shut down by the agent
107
+	//      (these are tasks which are associated with slots removed as part of service
108
+	//       remove or scale down)
109
+	// 3. EventUpdateCluster for TaskHistoryRetentionLimit update.
85 110
 	for {
86 111
 		select {
87 112
 		case event := <-watcher:
... ...
@@ -95,14 +134,21 @@ func (tr *TaskReaper) Run(ctx context.Context) {
95 95
 				}] = struct{}{}
96 96
 			case api.EventUpdateTask:
97 97
 				t := v.Task
98
+				// add serviceless orphaned tasks
98 99
 				if t.Status.State >= api.TaskStateOrphaned && t.ServiceID == "" {
99
-					tr.orphaned = append(tr.orphaned, t.ID)
100
+					tr.cleanup = append(tr.cleanup, t.ID)
101
+				}
102
+				// add tasks that have progressed beyond SHUTDOWN and have desired state REMOVE. These
103
+				// tasks are associated with slots that were removed as part of a service scale down
104
+				// or service removal.
105
+				if t.DesiredState == api.TaskStateRemove && t.Status.State >= api.TaskStateShutdown {
106
+					tr.cleanup = append(tr.cleanup, t.ID)
100 107
 				}
101 108
 			case api.EventUpdateCluster:
102 109
 				tr.taskHistory = v.Cluster.Spec.Orchestration.TaskHistoryRetentionLimit
103 110
 			}
104 111
 
105
-			if len(tr.dirty)+len(tr.orphaned) > maxDirty {
112
+			if len(tr.dirty)+len(tr.cleanup) > maxDirty {
106 113
 				timer.Stop()
107 114
 				tr.tick()
108 115
 			} else {
... ...
@@ -118,19 +164,22 @@ func (tr *TaskReaper) Run(ctx context.Context) {
118 118
 	}
119 119
 }
120 120
 
121
+// tick performs task history cleanup.
121 122
 func (tr *TaskReaper) tick() {
122
-	if len(tr.dirty) == 0 && len(tr.orphaned) == 0 {
123
+	if len(tr.dirty) == 0 && len(tr.cleanup) == 0 {
123 124
 		return
124 125
 	}
125 126
 
126 127
 	defer func() {
127
-		tr.orphaned = nil
128
+		tr.cleanup = nil
128 129
 	}()
129 130
 
130 131
 	deleteTasks := make(map[string]struct{})
131
-	for _, tID := range tr.orphaned {
132
+	for _, tID := range tr.cleanup {
132 133
 		deleteTasks[tID] = struct{}{}
133 134
 	}
135
+
136
+	// Check history of dirty tasks for cleanup.
134 137
 	tr.store.View(func(tx store.ReadTx) {
135 138
 		for dirty := range tr.dirty {
136 139
 			service := store.GetService(tx, dirty.ServiceID)
... ...
@@ -141,8 +190,8 @@ func (tr *TaskReaper) tick() {
141 141
 			taskHistory := tr.taskHistory
142 142
 
143 143
 			// If MaxAttempts is set, keep at least one more than
144
-			// that number of tasks. This is necessary reconstruct
145
-			// restart history when the orchestrator starts up.
144
+			// that number of tasks (this overrides TaskHistoryRetentionLimit).
145
+			// This is necessary to reconstruct restart history when the orchestrator starts up.
146 146
 			// TODO(aaronl): Consider hiding tasks beyond the normal
147 147
 			// retention limit in the UI.
148 148
 			// TODO(aaronl): There are some ways to cut down the
... ...
@@ -156,6 +205,7 @@ func (tr *TaskReaper) tick() {
156 156
 				taskHistory = int64(service.Spec.Task.Restart.MaxAttempts) + 1
157 157
 			}
158 158
 
159
+			// Negative value for TaskHistoryRetentionLimit is an indication to never clean up task history.
159 160
 			if taskHistory < 0 {
160 161
 				continue
161 162
 			}
... ...
@@ -164,6 +214,7 @@ func (tr *TaskReaper) tick() {
164 164
 
165 165
 			switch service.Spec.GetMode().(type) {
166 166
 			case *api.ServiceSpec_Replicated:
167
+				// Clean out the slot for which we received EventCreateTask.
167 168
 				var err error
168 169
 				historicTasks, err = store.FindTasks(tx, store.BySlot(dirty.ServiceID, dirty.Slot))
169 170
 				if err != nil {
... ...
@@ -171,6 +222,7 @@ func (tr *TaskReaper) tick() {
171 171
 				}
172 172
 
173 173
 			case *api.ServiceSpec_Global:
174
+				// Clean out the node history in case of global services.
174 175
 				tasksByNode, err := store.FindTasks(tx, store.ByNodeID(dirty.NodeID))
175 176
 				if err != nil {
176 177
 					continue
... ...
@@ -215,6 +267,7 @@ func (tr *TaskReaper) tick() {
215 215
 		}
216 216
 	})
217 217
 
218
+	// Perform cleanup.
218 219
 	if len(deleteTasks) > 0 {
219 220
 		tr.store.Batch(func(batch *store.Batch) error {
220 221
 			for taskID := range deleteTasks {
... ...
@@ -10,8 +10,8 @@ import (
10 10
 	"github.com/docker/swarmkit/manager/state/store"
11 11
 	"github.com/docker/swarmkit/protobuf/ptypes"
12 12
 	"golang.org/x/net/context"
13
-	"google.golang.org/grpc"
14 13
 	"google.golang.org/grpc/codes"
14
+	"google.golang.org/grpc/status"
15 15
 )
16 16
 
17 17
 var (
... ...
@@ -50,11 +50,11 @@ func (ra *ResourceAllocator) AttachNetwork(ctx context.Context, request *api.Att
50 50
 		}
51 51
 	})
52 52
 	if network == nil {
53
-		return nil, grpc.Errorf(codes.NotFound, "network %s not found", request.Config.Target)
53
+		return nil, status.Errorf(codes.NotFound, "network %s not found", request.Config.Target)
54 54
 	}
55 55
 
56 56
 	if !network.Spec.Attachable {
57
-		return nil, grpc.Errorf(codes.PermissionDenied, "network %s not manually attachable", request.Config.Target)
57
+		return nil, status.Errorf(codes.PermissionDenied, "network %s not manually attachable", request.Config.Target)
58 58
 	}
59 59
 
60 60
 	t := &api.Task{
... ...
@@ -98,7 +98,7 @@ func (ra *ResourceAllocator) AttachNetwork(ctx context.Context, request *api.Att
98 98
 // - Returns an error if the deletion fails.
99 99
 func (ra *ResourceAllocator) DetachNetwork(ctx context.Context, request *api.DetachNetworkRequest) (*api.DetachNetworkResponse, error) {
100 100
 	if request.AttachmentID == "" {
101
-		return nil, grpc.Errorf(codes.InvalidArgument, errInvalidArgument.Error())
101
+		return nil, status.Errorf(codes.InvalidArgument, errInvalidArgument.Error())
102 102
 	}
103 103
 
104 104
 	nodeInfo, err := ca.RemoteNode(ctx)
... ...
@@ -109,10 +109,10 @@ func (ra *ResourceAllocator) DetachNetwork(ctx context.Context, request *api.Det
109 109
 	if err := ra.store.Update(func(tx store.Tx) error {
110 110
 		t := store.GetTask(tx, request.AttachmentID)
111 111
 		if t == nil {
112
-			return grpc.Errorf(codes.NotFound, "attachment %s not found", request.AttachmentID)
112
+			return status.Errorf(codes.NotFound, "attachment %s not found", request.AttachmentID)
113 113
 		}
114 114
 		if t.NodeID != nodeInfo.NodeID {
115
-			return grpc.Errorf(codes.PermissionDenied, "attachment %s doesn't belong to this node", request.AttachmentID)
115
+			return status.Errorf(codes.PermissionDenied, "attachment %s doesn't belong to this node", request.AttachmentID)
116 116
 		}
117 117
 
118 118
 		return store.DeleteTask(tx, request.AttachmentID)
... ...
@@ -169,7 +169,10 @@ func (f *PluginFilter) Check(n *NodeInfo) bool {
169 169
 		}
170 170
 	}
171 171
 
172
-	if f.t.Spec.LogDriver != nil && f.t.Spec.LogDriver.Name != "none" {
172
+	// It's possible that the LogDriver object does not carry a name, just some
173
+	// configuration options. In that case, the plugin filter shouldn't fail to
174
+	// schedule the task
175
+	if f.t.Spec.LogDriver != nil && f.t.Spec.LogDriver.Name != "none" && f.t.Spec.LogDriver.Name != "" {
173 176
 		// If there are no log driver types in the list at all, most likely this is
174 177
 		// an older daemon that did not report this information. In this case don't filter
175 178
 		if typeFound, exists := f.pluginExistsOnNode("Log", f.t.Spec.LogDriver.Name, nodePlugins); !exists && typeFound {
... ...
@@ -294,6 +297,14 @@ func (f *PlatformFilter) platformEqual(imgPlatform, nodePlatform api.Platform) b
294 294
 		nodePlatform.Architecture = "amd64"
295 295
 	}
296 296
 
297
+	// normalize "aarch64" architectures to "arm64"
298
+	if imgPlatform.Architecture == "aarch64" {
299
+		imgPlatform.Architecture = "arm64"
300
+	}
301
+	if nodePlatform.Architecture == "aarch64" {
302
+		nodePlatform.Architecture = "arm64"
303
+	}
304
+
297 305
 	if (imgPlatform.Architecture == "" || imgPlatform.Architecture == nodePlatform.Architecture) && (imgPlatform.OS == "" || imgPlatform.OS == nodePlatform.OS) {
298 306
 		return true
299 307
 	}
... ...
@@ -2,6 +2,7 @@ package raft
2 2
 
3 3
 import (
4 4
 	"fmt"
5
+	"io"
5 6
 	"math"
6 7
 	"math/rand"
7 8
 	"net"
... ...
@@ -14,6 +15,7 @@ import (
14 14
 	"github.com/coreos/etcd/raft/raftpb"
15 15
 	"github.com/docker/docker/pkg/signal"
16 16
 	"github.com/docker/go-events"
17
+	"github.com/docker/go-metrics"
17 18
 	"github.com/docker/swarmkit/api"
18 19
 	"github.com/docker/swarmkit/ca"
19 20
 	"github.com/docker/swarmkit/log"
... ...
@@ -34,6 +36,7 @@ import (
34 34
 	"google.golang.org/grpc/codes"
35 35
 	"google.golang.org/grpc/credentials"
36 36
 	"google.golang.org/grpc/peer"
37
+	"google.golang.org/grpc/status"
37 38
 )
38 39
 
39 40
 var (
... ...
@@ -62,6 +65,9 @@ var (
62 62
 	// work around lint
63 63
 	lostQuorumMessage = "The swarm does not have a leader. It's possible that too few managers are online. Make sure more than half of the managers are online."
64 64
 	errLostQuorum     = errors.New(lostQuorumMessage)
65
+
66
+	// Timer to capture ProposeValue() latency.
67
+	proposeLatencyTimer metrics.Timer
65 68
 )
66 69
 
67 70
 // LeadershipState indicates whether the node is a leader or follower.
... ...
@@ -180,12 +186,9 @@ type NodeOptions struct {
180 180
 	ClockSource clock.Clock
181 181
 	// SendTimeout is the timeout on the sending messages to other raft
182 182
 	// nodes. Leave this as 0 to get the default value.
183
-	SendTimeout time.Duration
184
-	// LargeSendTimeout is the timeout on the sending snapshots to other raft
185
-	// nodes. Leave this as 0 to get the default value.
186
-	LargeSendTimeout time.Duration
187
-	TLSCredentials   credentials.TransportCredentials
188
-	KeyRotator       EncryptionKeyRotator
183
+	SendTimeout    time.Duration
184
+	TLSCredentials credentials.TransportCredentials
185
+	KeyRotator     EncryptionKeyRotator
189 186
 	// DisableStackDump prevents Run from dumping goroutine stacks when the
190 187
 	// store becomes stuck.
191 188
 	DisableStackDump bool
... ...
@@ -193,6 +196,9 @@ type NodeOptions struct {
193 193
 
194 194
 func init() {
195 195
 	rand.Seed(time.Now().UnixNano())
196
+	ns := metrics.NewNamespace("swarm", "raft", nil)
197
+	proposeLatencyTimer = ns.NewTimer("transaction_latency", "Raft transaction latency.")
198
+	metrics.Register(ns)
196 199
 }
197 200
 
198 201
 // NewNode generates a new Raft node
... ...
@@ -207,11 +213,6 @@ func NewNode(opts NodeOptions) *Node {
207 207
 	if opts.SendTimeout == 0 {
208 208
 		opts.SendTimeout = 2 * time.Second
209 209
 	}
210
-	if opts.LargeSendTimeout == 0 {
211
-		// a "slow" 100Mbps connection can send over 240MB data in 20 seconds
212
-		// which is well over the gRPC message limit of 128MB allowed by SwarmKit
213
-		opts.LargeSendTimeout = 20 * time.Second
214
-	}
215 210
 
216 211
 	raftStore := raft.NewMemoryStorage()
217 212
 
... ...
@@ -357,7 +358,6 @@ func (n *Node) initTransport() {
357 357
 	transportConfig := &transport.Config{
358 358
 		HeartbeatInterval: time.Duration(n.Config.ElectionTick) * n.opts.TickInterval,
359 359
 		SendTimeout:       n.opts.SendTimeout,
360
-		LargeSendTimeout:  n.opts.LargeSendTimeout,
361 360
 		Credentials:       n.opts.TLSCredentials,
362 361
 		Raft:              n,
363 362
 	}
... ...
@@ -664,7 +664,7 @@ func (n *Node) Run(ctx context.Context) error {
664 664
 			if n.snapshotInProgress == nil &&
665 665
 				(n.needsSnapshot(ctx) || raftConfig.SnapshotInterval > 0 &&
666 666
 					n.appliedIndex-n.snapshotMeta.Index >= raftConfig.SnapshotInterval) {
667
-				n.doSnapshot(ctx, raftConfig)
667
+				n.triggerSnapshot(ctx, raftConfig)
668 668
 			}
669 669
 
670 670
 			if wasLeader && atomic.LoadUint32(&n.signalledLeadership) != 1 {
... ...
@@ -706,7 +706,7 @@ func (n *Node) Run(ctx context.Context) error {
706 706
 				// there was a key rotation that took place before while the snapshot
707 707
 				// was in progress - we have to take another snapshot and encrypt with the new key
708 708
 				n.rotationQueued = false
709
-				n.doSnapshot(ctx, raftConfig)
709
+				n.triggerSnapshot(ctx, raftConfig)
710 710
 			}
711 711
 		case <-n.keyRotator.RotationNotify():
712 712
 			// There are 2 separate checks:  rotationQueued, and n.needsSnapshot().
... ...
@@ -719,7 +719,7 @@ func (n *Node) Run(ctx context.Context) error {
719 719
 			case n.snapshotInProgress != nil:
720 720
 				n.rotationQueued = true
721 721
 			case n.needsSnapshot(ctx):
722
-				n.doSnapshot(ctx, n.getCurrentRaftConfig())
722
+				n.triggerSnapshot(ctx, n.getCurrentRaftConfig())
723 723
 			}
724 724
 		case <-ctx.Done():
725 725
 			return nil
... ...
@@ -929,11 +929,11 @@ func (n *Node) Join(ctx context.Context, req *api.JoinRequest) (*api.JoinRespons
929 929
 	defer n.membershipLock.Unlock()
930 930
 
931 931
 	if !n.IsMember() {
932
-		return nil, grpc.Errorf(codes.FailedPrecondition, "%s", ErrNoRaftMember.Error())
932
+		return nil, status.Errorf(codes.FailedPrecondition, "%s", ErrNoRaftMember.Error())
933 933
 	}
934 934
 
935 935
 	if !n.isLeader() {
936
-		return nil, grpc.Errorf(codes.FailedPrecondition, "%s", ErrLostLeadership.Error())
936
+		return nil, status.Errorf(codes.FailedPrecondition, "%s", ErrLostLeadership.Error())
937 937
 	}
938 938
 
939 939
 	remoteAddr := req.Addr
... ...
@@ -944,7 +944,7 @@ func (n *Node) Join(ctx context.Context, req *api.JoinRequest) (*api.JoinRespons
944 944
 
945 945
 	requestHost, requestPort, err := net.SplitHostPort(remoteAddr)
946 946
 	if err != nil {
947
-		return nil, grpc.Errorf(codes.InvalidArgument, "invalid address %s in raft join request", remoteAddr)
947
+		return nil, status.Errorf(codes.InvalidArgument, "invalid address %s in raft join request", remoteAddr)
948 948
 	}
949 949
 
950 950
 	requestIP := net.ParseIP(requestHost)
... ...
@@ -1118,7 +1118,7 @@ func (n *Node) UpdateNode(id uint64, addr string) {
1118 1118
 // membership to an active member of the raft
1119 1119
 func (n *Node) Leave(ctx context.Context, req *api.LeaveRequest) (*api.LeaveResponse, error) {
1120 1120
 	if req.Node == nil {
1121
-		return nil, grpc.Errorf(codes.InvalidArgument, "no node information provided")
1121
+		return nil, status.Errorf(codes.InvalidArgument, "no node information provided")
1122 1122
 	}
1123 1123
 
1124 1124
 	nodeInfo, err := ca.RemoteNode(ctx)
... ...
@@ -1302,6 +1302,82 @@ func (n *Node) reportNewAddress(ctx context.Context, id uint64) error {
1302 1302
 	return n.transport.UpdatePeerAddr(id, newAddr)
1303 1303
 }
1304 1304
 
1305
+// StreamRaftMessage is the server endpoint for streaming Raft messages.
1306
+// It accepts a stream of raft messages to be processed on this raft member,
1307
+// returning a StreamRaftMessageResponse when processing of the streamed
1308
+// messages is complete.
1309
+// It is called from the Raft leader, which uses it to stream messages
1310
+// to this raft member.
1311
+// A single stream corresponds to a single raft message,
1312
+// which may be disassembled and streamed by the sender
1313
+// as individual messages. Therefore, each of the messages
1314
+// received by the stream will have the same raft message type and index.
1315
+// Currently, only messages of type raftpb.MsgSnap can be disassembled, sent
1316
+// and received on the stream.
1317
+func (n *Node) StreamRaftMessage(stream api.Raft_StreamRaftMessageServer) error {
1318
+	// recvdMsg is the current messasge received from the stream.
1319
+	// assembledMessage is where the data from recvdMsg is appended to.
1320
+	var recvdMsg, assembledMessage *api.StreamRaftMessageRequest
1321
+	var err error
1322
+
1323
+	// First message index.
1324
+	var raftMsgIndex uint64
1325
+
1326
+	for {
1327
+		recvdMsg, err = stream.Recv()
1328
+		if err == io.EOF {
1329
+			break
1330
+		} else if err != nil {
1331
+			log.G(stream.Context()).WithError(err).Error("error while reading from stream")
1332
+			return err
1333
+		}
1334
+
1335
+		// Initialized the message to be used for assembling
1336
+		// the raft message.
1337
+		if assembledMessage == nil {
1338
+			// For all message types except raftpb.MsgSnap,
1339
+			// we don't expect more than a single message
1340
+			// on the stream so we'll get an EOF on the next Recv()
1341
+			// and go on to process the received message.
1342
+			assembledMessage = recvdMsg
1343
+			raftMsgIndex = recvdMsg.Message.Index
1344
+			continue
1345
+		}
1346
+
1347
+		// Verify raft message index.
1348
+		if recvdMsg.Message.Index != raftMsgIndex {
1349
+			errMsg := fmt.Sprintf("Raft message chunk with index %d is different from the previously received raft message index %d",
1350
+				recvdMsg.Message.Index, raftMsgIndex)
1351
+			log.G(stream.Context()).Errorf(errMsg)
1352
+			return status.Errorf(codes.InvalidArgument, "%s", errMsg)
1353
+		}
1354
+
1355
+		// Verify that multiple message received on a stream
1356
+		// can only be of type raftpb.MsgSnap.
1357
+		if recvdMsg.Message.Type != raftpb.MsgSnap {
1358
+			errMsg := fmt.Sprintf("Raft message chunk is not of type %d",
1359
+				raftpb.MsgSnap)
1360
+			log.G(stream.Context()).Errorf(errMsg)
1361
+			return status.Errorf(codes.InvalidArgument, "%s", errMsg)
1362
+		}
1363
+
1364
+		// Append the received snapshot data.
1365
+		assembledMessage.Message.Snapshot.Data = append(assembledMessage.Message.Snapshot.Data, recvdMsg.Message.Snapshot.Data...)
1366
+	}
1367
+
1368
+	// We should have the complete snapshot. Verify and process.
1369
+	if err == io.EOF {
1370
+		_, err = n.ProcessRaftMessage(stream.Context(), &api.ProcessRaftMessageRequest{Message: assembledMessage.Message})
1371
+		if err == nil {
1372
+			// Translate the response of ProcessRaftMessage() from
1373
+			// ProcessRaftMessageResponse to StreamRaftMessageResponse if needed.
1374
+			return stream.SendAndClose(&api.StreamRaftMessageResponse{})
1375
+		}
1376
+	}
1377
+
1378
+	return err
1379
+}
1380
+
1305 1381
 // ProcessRaftMessage calls 'Step' which advances the
1306 1382
 // raft state machine with the provided message on the
1307 1383
 // receiving node
... ...
@@ -1315,7 +1391,7 @@ func (n *Node) ProcessRaftMessage(ctx context.Context, msg *api.ProcessRaftMessa
1315 1315
 	// a node in the remove set
1316 1316
 	if n.cluster.IsIDRemoved(msg.Message.From) {
1317 1317
 		n.processRaftMessageLogger(ctx, msg).Debug("received message from removed member")
1318
-		return nil, grpc.Errorf(codes.NotFound, "%s", membership.ErrMemberRemoved.Error())
1318
+		return nil, status.Errorf(codes.NotFound, "%s", membership.ErrMemberRemoved.Error())
1319 1319
 	}
1320 1320
 
1321 1321
 	ctx, cancel := n.WithContext(ctx)
... ...
@@ -1393,7 +1469,7 @@ func (n *Node) ResolveAddress(ctx context.Context, msg *api.ResolveAddressReques
1393 1393
 
1394 1394
 	member := n.cluster.GetMember(msg.RaftID)
1395 1395
 	if member == nil {
1396
-		return nil, grpc.Errorf(codes.NotFound, "member %x not found", msg.RaftID)
1396
+		return nil, status.Errorf(codes.NotFound, "member %x not found", msg.RaftID)
1397 1397
 	}
1398 1398
 	return &api.ResolveAddressResponse{Addr: member.Addr}, nil
1399 1399
 }
... ...
@@ -1497,9 +1573,11 @@ func (n *Node) registerNode(node *api.RaftMember) error {
1497 1497
 // ProposeValue calls Propose on the underlying raft library(etcd/raft) and waits
1498 1498
 // on the commit log action before returning a result
1499 1499
 func (n *Node) ProposeValue(ctx context.Context, storeAction []api.StoreAction, cb func()) error {
1500
+	defer metrics.StartTimer(proposeLatencyTimer)()
1500 1501
 	ctx, cancel := n.WithContext(ctx)
1501 1502
 	defer cancel()
1502 1503
 	_, err := n.processInternalRaftRequest(ctx, &api.InternalRaftRequest{Action: storeAction}, cb)
1504
+
1503 1505
 	if err != nil {
1504 1506
 		return err
1505 1507
 	}
... ...
@@ -1808,12 +1886,13 @@ func (n *Node) processEntry(ctx context.Context, entry raftpb.Entry) error {
1808 1808
 	}
1809 1809
 
1810 1810
 	if !n.wait.trigger(r.ID, r) {
1811
-		log.G(ctx).Errorf("wait not found for raft request id %x", r.ID)
1812
-
1813 1811
 		// There was no wait on this ID, meaning we don't have a
1814 1812
 		// transaction in progress that would be committed to the
1815
-		// memory store by the "trigger" call. Either a different node
1816
-		// wrote this to raft, or we wrote it before losing the leader
1813
+		// memory store by the "trigger" call. This could mean that:
1814
+		// 1. Startup is in progress, and the raft WAL is being parsed,
1815
+		// processed and applied to the store, or
1816
+		// 2. Either a different node wrote this to raft,
1817
+		// or we wrote it before losing the leader
1817 1818
 		// position and cancelling the transaction. This entry still needs
1818 1819
 		// to be committed since other nodes have already committed it.
1819 1820
 		// Create a new transaction to commit this entry.
... ...
@@ -1827,7 +1906,6 @@ func (n *Node) processEntry(ctx context.Context, entry raftpb.Entry) error {
1827 1827
 		err := n.memoryStore.ApplyStoreActions(r.Action)
1828 1828
 		if err != nil {
1829 1829
 			log.G(ctx).WithError(err).Error("failed to apply actions from raft")
1830
-			// TODO(anshul) return err here ?
1831 1830
 		}
1832 1831
 	}
1833 1832
 	return nil
... ...
@@ -5,6 +5,7 @@ import (
5 5
 
6 6
 	"github.com/coreos/etcd/raft"
7 7
 	"github.com/coreos/etcd/raft/raftpb"
8
+	"github.com/docker/go-metrics"
8 9
 	"github.com/docker/swarmkit/api"
9 10
 	"github.com/docker/swarmkit/log"
10 11
 	"github.com/docker/swarmkit/manager/encryption"
... ...
@@ -15,6 +16,18 @@ import (
15 15
 	"golang.org/x/net/context"
16 16
 )
17 17
 
18
+var (
19
+	// Snapshot create latency timer.
20
+	snapshotLatencyTimer metrics.Timer
21
+)
22
+
23
+func init() {
24
+	ns := metrics.NewNamespace("swarm", "raft", nil)
25
+	snapshotLatencyTimer = ns.NewTimer("snapshot_latency",
26
+		"Raft snapshot create latency.")
27
+	metrics.Register(ns)
28
+}
29
+
18 30
 func (n *Node) readFromDisk(ctx context.Context) (*raftpb.Snapshot, storage.WALData, error) {
19 31
 	keys := n.keyRotator.GetKeys()
20 32
 
... ...
@@ -169,7 +182,7 @@ func (n *Node) newRaftLogs(nodeID string) (raft.Peer, error) {
169 169
 	return raft.Peer{ID: n.Config.ID, Context: metadata}, nil
170 170
 }
171 171
 
172
-func (n *Node) doSnapshot(ctx context.Context, raftConfig api.RaftConfig) {
172
+func (n *Node) triggerSnapshot(ctx context.Context, raftConfig api.RaftConfig) {
173 173
 	snapshot := api.Snapshot{Version: api.Snapshot_V0}
174 174
 	for _, member := range n.cluster.Members() {
175 175
 		snapshot.Membership.Members = append(snapshot.Membership.Members,
... ...
@@ -185,6 +198,9 @@ func (n *Node) doSnapshot(ctx context.Context, raftConfig api.RaftConfig) {
185 185
 	n.asyncTasks.Add(1)
186 186
 	n.snapshotInProgress = make(chan raftpb.SnapshotMetadata, 1) // buffered in case Shutdown is called during the snapshot
187 187
 	go func(appliedIndex uint64, snapshotMeta raftpb.SnapshotMetadata) {
188
+		// Deferred latency capture.
189
+		defer metrics.StartTimer(snapshotLatencyTimer)()
190
+
188 191
 		defer func() {
189 192
 			n.asyncTasks.Done()
190 193
 			n.snapshotInProgress <- snapshotMeta
... ...
@@ -18,6 +18,11 @@ import (
18 18
 	"github.com/pkg/errors"
19 19
 )
20 20
 
21
+const (
22
+	// GRPCMaxMsgSize is the max allowed gRPC message size for raft messages.
23
+	GRPCMaxMsgSize = 4 << 20
24
+)
25
+
21 26
 type peer struct {
22 27
 	id uint64
23 28
 
... ...
@@ -132,17 +137,112 @@ func (p *peer) resolveAddr(ctx context.Context, id uint64) (string, error) {
132 132
 	return resp.Addr, nil
133 133
 }
134 134
 
135
-func (p *peer) sendProcessMessage(ctx context.Context, m raftpb.Message) error {
136
-	timeout := p.tr.config.SendTimeout
137
-	// if a snapshot is being sent, set timeout to LargeSendTimeout because
138
-	// sending snapshots can take more time than other messages sent between peers.
139
-	// The same applies to AppendEntries as well, where messages can get large.
140
-	if m.Type == raftpb.MsgSnap || m.Type == raftpb.MsgApp {
141
-		timeout = p.tr.config.LargeSendTimeout
135
+// Returns the raft message struct size (not including the payload size) for the given raftpb.Message.
136
+// The payload is typically the snapshot or append entries.
137
+func raftMessageStructSize(m *raftpb.Message) int {
138
+	return (&api.ProcessRaftMessageRequest{Message: m}).Size() - len(m.Snapshot.Data)
139
+}
140
+
141
+// Returns the max allowable payload based on MaxRaftMsgSize and
142
+// the struct size for the given raftpb.Message.
143
+func raftMessagePayloadSize(m *raftpb.Message) int {
144
+	return GRPCMaxMsgSize - raftMessageStructSize(m)
145
+}
146
+
147
+// Split a large raft message into smaller messages.
148
+// Currently this means splitting the []Snapshot.Data into chunks whose size
149
+// is dictacted by MaxRaftMsgSize.
150
+func splitSnapshotData(ctx context.Context, m *raftpb.Message) []api.StreamRaftMessageRequest {
151
+	var messages []api.StreamRaftMessageRequest
152
+	if m.Type != raftpb.MsgSnap {
153
+		return messages
154
+	}
155
+
156
+	// get the size of the data to be split.
157
+	size := len(m.Snapshot.Data)
158
+
159
+	// Get the max payload size.
160
+	payloadSize := raftMessagePayloadSize(m)
161
+
162
+	// split the snapshot into smaller messages.
163
+	for snapDataIndex := 0; snapDataIndex < size; {
164
+		chunkSize := size - snapDataIndex
165
+		if chunkSize > payloadSize {
166
+			chunkSize = payloadSize
167
+		}
168
+
169
+		raftMsg := *m
170
+
171
+		// sub-slice for this snapshot chunk.
172
+		raftMsg.Snapshot.Data = m.Snapshot.Data[snapDataIndex : snapDataIndex+chunkSize]
173
+
174
+		snapDataIndex += chunkSize
175
+
176
+		// add message to the list of messages to be sent.
177
+		msg := api.StreamRaftMessageRequest{Message: &raftMsg}
178
+		messages = append(messages, msg)
142 179
 	}
143
-	ctx, cancel := context.WithTimeout(ctx, timeout)
180
+
181
+	return messages
182
+}
183
+
184
+// Function to check if this message needs to be split to be streamed
185
+// (because it is larger than GRPCMaxMsgSize).
186
+// Returns true if the message type is MsgSnap
187
+// and size larger than MaxRaftMsgSize.
188
+func needsSplitting(m *raftpb.Message) bool {
189
+	raftMsg := api.ProcessRaftMessageRequest{Message: m}
190
+	return m.Type == raftpb.MsgSnap && raftMsg.Size() > GRPCMaxMsgSize
191
+}
192
+
193
+func (p *peer) sendProcessMessage(ctx context.Context, m raftpb.Message) error {
194
+	ctx, cancel := context.WithTimeout(ctx, p.tr.config.SendTimeout)
144 195
 	defer cancel()
145
-	_, err := api.NewRaftClient(p.conn()).ProcessRaftMessage(ctx, &api.ProcessRaftMessageRequest{Message: &m})
196
+
197
+	var err error
198
+	var stream api.Raft_StreamRaftMessageClient
199
+	stream, err = api.NewRaftClient(p.conn()).StreamRaftMessage(ctx)
200
+
201
+	if err == nil {
202
+		// Split the message if needed.
203
+		// Currently only supported for MsgSnap.
204
+		var msgs []api.StreamRaftMessageRequest
205
+		if needsSplitting(&m) {
206
+			msgs = splitSnapshotData(ctx, &m)
207
+		} else {
208
+			raftMsg := api.StreamRaftMessageRequest{Message: &m}
209
+			msgs = append(msgs, raftMsg)
210
+		}
211
+
212
+		// Stream
213
+		for _, msg := range msgs {
214
+			err = stream.Send(&msg)
215
+			if err != nil {
216
+				log.G(ctx).WithError(err).Error("error streaming message to peer")
217
+				stream.CloseAndRecv()
218
+				break
219
+			}
220
+		}
221
+
222
+		// Finished sending all the messages.
223
+		// Close and receive response.
224
+		if err == nil {
225
+			_, err = stream.CloseAndRecv()
226
+
227
+			if err != nil {
228
+				log.G(ctx).WithError(err).Error("error receiving response")
229
+			}
230
+		}
231
+	} else {
232
+		log.G(ctx).WithError(err).Error("error sending message to peer")
233
+	}
234
+
235
+	// Try doing a regular rpc if the receiver doesn't support streaming.
236
+	if grpc.Code(err) == codes.Unimplemented {
237
+		_, err = api.NewRaftClient(p.conn()).ProcessRaftMessage(ctx, &api.ProcessRaftMessageRequest{Message: &m})
238
+	}
239
+
240
+	// Handle errors.
146 241
 	if grpc.Code(err) == codes.NotFound && grpc.ErrorDesc(err) == membership.ErrMemberRemoved.Error() {
147 242
 		p.tr.config.NodeRemoved()
148 243
 	}
... ...
@@ -36,7 +36,6 @@ type Raft interface {
36 36
 type Config struct {
37 37
 	HeartbeatInterval time.Duration
38 38
 	SendTimeout       time.Duration
39
-	LargeSendTimeout  time.Duration
40 39
 	Credentials       credentials.TransportCredentials
41 40
 	RaftID            string
42 41
 
... ...
@@ -11,6 +11,7 @@ import (
11 11
 	"time"
12 12
 
13 13
 	"github.com/docker/go-events"
14
+	"github.com/docker/go-metrics"
14 15
 	"github.com/docker/swarmkit/api"
15 16
 	pb "github.com/docker/swarmkit/api"
16 17
 	"github.com/docker/swarmkit/manager/state"
... ...
@@ -76,8 +77,38 @@ var (
76 76
 	// WedgeTimeout is the maximum amount of time the store lock may be
77 77
 	// held before declaring a suspected deadlock.
78 78
 	WedgeTimeout = 30 * time.Second
79
+
80
+	// update()/write tx latency timer.
81
+	updateLatencyTimer metrics.Timer
82
+
83
+	// view()/read tx latency timer.
84
+	viewLatencyTimer metrics.Timer
85
+
86
+	// lookup() latency timer.
87
+	lookupLatencyTimer metrics.Timer
88
+
89
+	// Batch() latency timer.
90
+	batchLatencyTimer metrics.Timer
91
+
92
+	// timer to capture the duration for which the memory store mutex is locked.
93
+	storeLockDurationTimer metrics.Timer
79 94
 )
80 95
 
96
+func init() {
97
+	ns := metrics.NewNamespace("swarm", "store", nil)
98
+	updateLatencyTimer = ns.NewTimer("write_tx_latency",
99
+		"Raft store write tx latency.")
100
+	viewLatencyTimer = ns.NewTimer("read_tx_latency",
101
+		"Raft store read tx latency.")
102
+	lookupLatencyTimer = ns.NewTimer("lookup_latency",
103
+		"Raft store read latency.")
104
+	batchLatencyTimer = ns.NewTimer("batch_latency",
105
+		"Raft store batch latency.")
106
+	storeLockDurationTimer = ns.NewTimer("memory_store_lock_duration",
107
+		"Duration for which the raft memory store lock was held.")
108
+	metrics.Register(ns)
109
+}
110
+
81 111
 func register(os ObjectStoreConfig) {
82 112
 	objectStorers = append(objectStorers, os)
83 113
 	schema.Tables[os.Table.Name] = os.Table
... ...
@@ -94,8 +125,13 @@ func (m *timedMutex) Lock() {
94 94
 	m.lockedAt.Store(time.Now())
95 95
 }
96 96
 
97
+// Unlocks the timedMutex and captures the duration
98
+// for which it was locked in a metric.
97 99
 func (m *timedMutex) Unlock() {
100
+	unlockedTimestamp := m.lockedAt.Load()
98 101
 	m.Mutex.Unlock()
102
+	lockedFor := time.Since(unlockedTimestamp.(time.Time))
103
+	storeLockDurationTimer.Update(lockedFor)
99 104
 	m.lockedAt.Store(time.Time{})
100 105
 }
101 106
 
... ...
@@ -184,6 +220,7 @@ type readTx struct {
184 184
 
185 185
 // View executes a read transaction.
186 186
 func (s *MemoryStore) View(cb func(ReadTx)) {
187
+	defer metrics.StartTimer(viewLatencyTimer)()
187 188
 	memDBTx := s.memDB.Txn(false)
188 189
 
189 190
 	readTx := readTx{
... ...
@@ -280,6 +317,7 @@ func applyStoreAction(tx Tx, sa api.StoreAction) error {
280 280
 }
281 281
 
282 282
 func (s *MemoryStore) update(proposer state.Proposer, cb func(Tx) error) error {
283
+	defer metrics.StartTimer(updateLatencyTimer)()
283 284
 	s.updateLock.Lock()
284 285
 	memDBTx := s.memDB.Txn(true)
285 286
 
... ...
@@ -329,7 +367,6 @@ func (s *MemoryStore) update(proposer state.Proposer, cb func(Tx) error) error {
329 329
 	}
330 330
 	s.updateLock.Unlock()
331 331
 	return err
332
-
333 332
 }
334 333
 
335 334
 func (s *MemoryStore) updateLocal(cb func(Tx) error) error {
... ...
@@ -458,6 +495,7 @@ func (batch *Batch) commit() error {
458 458
 // If Batch returns an error, no guarantees are made about how many updates
459 459
 // were committed successfully.
460 460
 func (s *MemoryStore) Batch(cb func(*Batch) error) error {
461
+	defer metrics.StartTimer(batchLatencyTimer)()
461 462
 	s.updateLock.Lock()
462 463
 
463 464
 	batch := Batch{
... ...
@@ -498,6 +536,7 @@ func (tx tx) changelistStoreActions() ([]api.StoreAction, error) {
498 498
 
499 499
 // lookup is an internal typed wrapper around memdb.
500 500
 func (tx readTx) lookup(table, index, id string) api.StoreObject {
501
+	defer metrics.StartTimer(lookupLatencyTimer)()
501 502
 	j, err := tx.memDBTx.First(table, index, id)
502 503
 	if err != nil {
503 504
 		return nil
... ...
@@ -1,12 +1,11 @@
1 1
 package watchapi
2 2
 
3 3
 import (
4
-	"google.golang.org/grpc"
5
-	"google.golang.org/grpc/codes"
6
-
7 4
 	"github.com/docker/swarmkit/api"
8 5
 	"github.com/docker/swarmkit/manager/state"
9 6
 	"github.com/docker/swarmkit/manager/state/store"
7
+	"google.golang.org/grpc/codes"
8
+	"google.golang.org/grpc/status"
10 9
 )
11 10
 
12 11
 // Watch starts a stream that returns any changes to objects that match
... ...
@@ -26,7 +25,7 @@ func (s *Server) Watch(request *api.WatchRequest, stream api.Watch_WatchServer)
26 26
 
27 27
 	watchArgs, err := api.ConvertWatchArgs(request.Entries)
28 28
 	if err != nil {
29
-		return grpc.Errorf(codes.InvalidArgument, "%s", err.Error())
29
+		return status.Errorf(codes.InvalidArgument, "%s", err.Error())
30 30
 	}
31 31
 
32 32
 	watchArgs = append(watchArgs, state.EventCommit{})