From cd02a27ee2c06cf9a76bcf82fadbd364a789bf35 Mon Sep 17 00:00:00 2001 From: nolouch Date: Fri, 6 Jul 2018 00:29:30 +0800 Subject: [PATCH 01/30] update proto --- Gopkg.lock | 7 +- Gopkg.toml | 3 +- .../pingcap/kvproto/pkg/eraftpb/eraftpb.pb.go | 53 ++- .../pingcap/kvproto/pkg/metapb/metapb.pb.go | 3 +- .../pingcap/kvproto/pkg/pdpb/pdpb.pb.go | 441 ++++++++++++------ 5 files changed, 325 insertions(+), 182 deletions(-) diff --git a/Gopkg.lock b/Gopkg.lock index 0c10bb8405e..308a033e1c8 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -253,14 +253,15 @@ revision = "1c287c953996ab3a0bf535dba9d53d809d3dc0b6" [[projects]] - branch = "master" + branch = "version-introduce" name = "github.com/pingcap/kvproto" packages = [ "pkg/eraftpb", "pkg/metapb", "pkg/pdpb" ] - revision = "b7ba8ea1c0b4915d333a146eb0e674fb5b33854f" + revision = "1c97132330a421e762e2aa2b389d702db8206008" + source = "https://github.com/nolouch/kvproto" [[projects]] name = "github.com/prometheus/client_golang" @@ -494,6 +495,6 @@ [solve-meta] analyzer-name = "dep" analyzer-version = 1 - inputs-digest = "da8bdc8144bcc6b679548cc3eb0de72258f9a9d480a789c2f43b77be8b5a0087" + inputs-digest = "094f5ca6f62c8202f437b648a06ac9aed91ce959c6ca3867ce56c626d32d916f" solver-name = "gps-cdcl" solver-version = 1 diff --git a/Gopkg.toml b/Gopkg.toml index a60ac716d7e..80df6080429 100644 --- a/Gopkg.toml +++ b/Gopkg.toml @@ -26,4 +26,5 @@ [[constraint]] name = "github.com/pingcap/kvproto" - branch = "master" + source = "https://github.com/nolouch/kvproto" + branch = "version-introduce" diff --git a/vendor/github.com/pingcap/kvproto/pkg/eraftpb/eraftpb.pb.go b/vendor/github.com/pingcap/kvproto/pkg/eraftpb/eraftpb.pb.go index 5d350673510..3dd14dc328b 100644 --- a/vendor/github.com/pingcap/kvproto/pkg/eraftpb/eraftpb.pb.go +++ b/vendor/github.com/pingcap/kvproto/pkg/eraftpb/eraftpb.pb.go @@ -1,6 +1,5 @@ -// Code generated by protoc-gen-gogo. +// Code generated by protoc-gen-gogo. DO NOT EDIT. // source: eraftpb.proto -// DO NOT EDIT! /* Package eraftpb is a generated protocol buffer package. @@ -1903,7 +1902,24 @@ func (m *ConfState) Unmarshal(dAtA []byte) error { } switch fieldNum { case 1: - if wireType == 2 { + if wireType == 0 { + var v uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEraftpb + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.Nodes = append(m.Nodes, v) + } else if wireType == 2 { var packedLen int for shift := uint(0); ; shift += 7 { if shift >= 64 { @@ -1944,7 +1960,11 @@ func (m *ConfState) Unmarshal(dAtA []byte) error { } m.Nodes = append(m.Nodes, v) } - } else if wireType == 0 { + } else { + return fmt.Errorf("proto: wrong wireType = %d for field Nodes", wireType) + } + case 2: + if wireType == 0 { var v uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { @@ -1960,12 +1980,8 @@ func (m *ConfState) Unmarshal(dAtA []byte) error { break } } - m.Nodes = append(m.Nodes, v) - } else { - return fmt.Errorf("proto: wrong wireType = %d for field Nodes", wireType) - } - case 2: - if wireType == 2 { + m.Learners = append(m.Learners, v) + } else if wireType == 2 { var packedLen int for shift := uint(0); ; shift += 7 { if shift >= 64 { @@ -2006,23 +2022,6 @@ func (m *ConfState) Unmarshal(dAtA []byte) error { } m.Learners = append(m.Learners, v) } - } else if wireType == 0 { - var v uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowEraftpb - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.Learners = append(m.Learners, v) } else { return fmt.Errorf("proto: wrong wireType = %d for field Learners", wireType) } diff --git a/vendor/github.com/pingcap/kvproto/pkg/metapb/metapb.pb.go b/vendor/github.com/pingcap/kvproto/pkg/metapb/metapb.pb.go index 497f52d332b..05d8d9d9a6c 100644 --- a/vendor/github.com/pingcap/kvproto/pkg/metapb/metapb.pb.go +++ b/vendor/github.com/pingcap/kvproto/pkg/metapb/metapb.pb.go @@ -1,6 +1,5 @@ -// Code generated by protoc-gen-gogo. +// Code generated by protoc-gen-gogo. DO NOT EDIT. // source: metapb.proto -// DO NOT EDIT! /* Package metapb is a generated protocol buffer package. diff --git a/vendor/github.com/pingcap/kvproto/pkg/pdpb/pdpb.pb.go b/vendor/github.com/pingcap/kvproto/pkg/pdpb/pdpb.pb.go index 743d00e1c6b..09ebf73d666 100644 --- a/vendor/github.com/pingcap/kvproto/pkg/pdpb/pdpb.pb.go +++ b/vendor/github.com/pingcap/kvproto/pkg/pdpb/pdpb.pb.go @@ -1,6 +1,5 @@ -// Code generated by protoc-gen-gogo. +// Code generated by protoc-gen-gogo. DO NOT EDIT. // source: pdpb.proto -// DO NOT EDIT! /* Package pdpb is a generated protocol buffer package. @@ -116,7 +115,9 @@ func (ErrorType) EnumDescriptor() ([]byte, []int) { return fileDescriptorPdpb, [ type RequestHeader struct { // cluster_id is the ID of the cluster which be sent to. - ClusterId uint64 `protobuf:"varint,1,opt,name=cluster_id,json=clusterId,proto3" json:"cluster_id,omitempty"` + ClusterId uint64 `protobuf:"varint,1,opt,name=cluster_id,json=clusterId,proto3" json:"cluster_id,omitempty"` + Version string `protobuf:"bytes,2,opt,name=version,proto3" json:"version,omitempty"` + RequireMinVersion string `protobuf:"bytes,3,opt,name=require_min_version,json=requireMinVersion,proto3" json:"require_min_version,omitempty"` } func (m *RequestHeader) Reset() { *m = RequestHeader{} } @@ -131,10 +132,25 @@ func (m *RequestHeader) GetClusterId() uint64 { return 0 } +func (m *RequestHeader) GetVersion() string { + if m != nil { + return m.Version + } + return "" +} + +func (m *RequestHeader) GetRequireMinVersion() string { + if m != nil { + return m.RequireMinVersion + } + return "" +} + type ResponseHeader struct { // cluster_id is the ID of the cluster which sent the response. - ClusterId uint64 `protobuf:"varint,1,opt,name=cluster_id,json=clusterId,proto3" json:"cluster_id,omitempty"` - Error *Error `protobuf:"bytes,2,opt,name=error" json:"error,omitempty"` + ClusterId uint64 `protobuf:"varint,1,opt,name=cluster_id,json=clusterId,proto3" json:"cluster_id,omitempty"` + Error *Error `protobuf:"bytes,2,opt,name=error" json:"error,omitempty"` + ClusterVersion string `protobuf:"bytes,3,opt,name=cluster_version,json=clusterVersion,proto3" json:"cluster_version,omitempty"` } func (m *ResponseHeader) Reset() { *m = ResponseHeader{} } @@ -156,6 +172,13 @@ func (m *ResponseHeader) GetError() *Error { return nil } +func (m *ResponseHeader) GetClusterVersion() string { + if m != nil { + return m.ClusterVersion + } + return "" +} + type Error struct { Type ErrorType `protobuf:"varint,1,opt,name=type,proto3,enum=pdpb.ErrorType" json:"type,omitempty"` Message string `protobuf:"bytes,2,opt,name=message,proto3" json:"message,omitempty"` @@ -2185,6 +2208,18 @@ func (m *RequestHeader) MarshalTo(dAtA []byte) (int, error) { i++ i = encodeVarintPdpb(dAtA, i, uint64(m.ClusterId)) } + if len(m.Version) > 0 { + dAtA[i] = 0x12 + i++ + i = encodeVarintPdpb(dAtA, i, uint64(len(m.Version))) + i += copy(dAtA[i:], m.Version) + } + if len(m.RequireMinVersion) > 0 { + dAtA[i] = 0x1a + i++ + i = encodeVarintPdpb(dAtA, i, uint64(len(m.RequireMinVersion))) + i += copy(dAtA[i:], m.RequireMinVersion) + } return i, nil } @@ -2218,6 +2253,12 @@ func (m *ResponseHeader) MarshalTo(dAtA []byte) (int, error) { } i += n1 } + if len(m.ClusterVersion) > 0 { + dAtA[i] = 0x1a + i++ + i = encodeVarintPdpb(dAtA, i, uint64(len(m.ClusterVersion))) + i += copy(dAtA[i:], m.ClusterVersion) + } return i, nil } @@ -3981,6 +4022,14 @@ func (m *RequestHeader) Size() (n int) { if m.ClusterId != 0 { n += 1 + sovPdpb(uint64(m.ClusterId)) } + l = len(m.Version) + if l > 0 { + n += 1 + l + sovPdpb(uint64(l)) + } + l = len(m.RequireMinVersion) + if l > 0 { + n += 1 + l + sovPdpb(uint64(l)) + } return n } @@ -3994,6 +4043,10 @@ func (m *ResponseHeader) Size() (n int) { l = m.Error.Size() n += 1 + l + sovPdpb(uint64(l)) } + l = len(m.ClusterVersion) + if l > 0 { + n += 1 + l + sovPdpb(uint64(l)) + } return n } @@ -4741,6 +4794,64 @@ func (m *RequestHeader) Unmarshal(dAtA []byte) error { break } } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Version", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPdpb + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthPdpb + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Version = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field RequireMinVersion", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPdpb + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthPdpb + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.RequireMinVersion = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipPdpb(dAtA[iNdEx:]) @@ -4843,6 +4954,35 @@ func (m *ResponseHeader) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ClusterVersion", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPdpb + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthPdpb + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ClusterVersion = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipPdpb(dAtA[iNdEx:]) @@ -8981,7 +9121,24 @@ func (m *AskSplitResponse) Unmarshal(dAtA []byte) error { } } case 3: - if wireType == 2 { + if wireType == 0 { + var v uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPdpb + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.NewPeerIds = append(m.NewPeerIds, v) + } else if wireType == 2 { var packedLen int for shift := uint(0); ; shift += 7 { if shift >= 64 { @@ -9022,23 +9179,6 @@ func (m *AskSplitResponse) Unmarshal(dAtA []byte) error { } m.NewPeerIds = append(m.NewPeerIds, v) } - } else if wireType == 0 { - var v uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowPdpb - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.NewPeerIds = append(m.NewPeerIds, v) } else { return fmt.Errorf("proto: wrong wireType = %d for field NewPeerIds", wireType) } @@ -10291,131 +10431,134 @@ var ( func init() { proto.RegisterFile("pdpb.proto", fileDescriptorPdpb) } var fileDescriptorPdpb = []byte{ - // 2016 bytes of a gzipped FileDescriptorProto + // 2064 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x59, 0x4b, 0x6f, 0x23, 0xc7, - 0x11, 0xd6, 0x50, 0x24, 0x45, 0x16, 0x9f, 0xdb, 0x7a, 0x71, 0xb9, 0x2b, 0x45, 0xee, 0x75, 0x12, - 0xd9, 0xb1, 0xe9, 0xb5, 0x12, 0x04, 0x06, 0x0c, 0x07, 0xd6, 0x6b, 0x77, 0xe5, 0xf5, 0x8a, 0x42, - 0x93, 0x86, 0x61, 0x20, 0x08, 0x33, 0xe2, 0xb4, 0xa8, 0x89, 0xc8, 0x99, 0xf1, 0x74, 0x53, 0x0a, - 0x7d, 0xca, 0xc9, 0x97, 0x04, 0xc8, 0x2d, 0xc8, 0x25, 0x40, 0xee, 0x01, 0xf2, 0x17, 0x72, 0xcd, - 0x31, 0x3f, 0x21, 0xd8, 0xfc, 0x91, 0xa0, 0x1f, 0xf3, 0x24, 0x25, 0x2b, 0xb3, 0xf1, 0x49, 0x9c, - 0xaa, 0xea, 0xea, 0xea, 0xaf, 0xeb, 0xd5, 0x25, 0x00, 0xcf, 0xf2, 0xce, 0x3b, 0x9e, 0xef, 0x72, - 0x17, 0xe5, 0xc5, 0xef, 0x76, 0x75, 0x42, 0xb9, 0x19, 0xd0, 0xda, 0x35, 0xea, 0x9b, 0x17, 0x3c, - 0xfc, 0x5c, 0x1b, 0xb9, 0x23, 0x57, 0xfe, 0xfc, 0x40, 0xfc, 0x52, 0x54, 0xdc, 0x81, 0x1a, 0xa1, - 0x5f, 0x4f, 0x29, 0xe3, 0x2f, 0xa8, 0x69, 0x51, 0x1f, 0x6d, 0x01, 0x0c, 0xc7, 0x53, 0xc6, 0xa9, - 0x3f, 0xb0, 0xad, 0x96, 0xb1, 0x63, 0xec, 0xe6, 0x49, 0x59, 0x53, 0x4e, 0x2c, 0x4c, 0xa0, 0x4e, - 0x28, 0xf3, 0x5c, 0x87, 0xd1, 0x7b, 0x2d, 0x40, 0x6f, 0x41, 0x81, 0xfa, 0xbe, 0xeb, 0xb7, 0x72, - 0x3b, 0xc6, 0x6e, 0x65, 0xaf, 0xd2, 0x91, 0x56, 0x1f, 0x0b, 0x12, 0x51, 0x1c, 0xfc, 0x0c, 0x0a, - 0xf2, 0x1b, 0x3d, 0x81, 0x3c, 0x9f, 0x79, 0x54, 0x2a, 0xa9, 0xef, 0x35, 0x62, 0xa2, 0xfd, 0x99, - 0x47, 0x89, 0x64, 0xa2, 0x16, 0xac, 0x4c, 0x28, 0x63, 0xe6, 0x88, 0x4a, 0x95, 0x65, 0x12, 0x7c, - 0xe2, 0x2e, 0x40, 0x9f, 0xb9, 0xfa, 0x38, 0xe8, 0x27, 0x50, 0xbc, 0x94, 0x16, 0x4a, 0x75, 0x95, - 0xbd, 0x55, 0xa5, 0x2e, 0x71, 0x5a, 0xa2, 0x45, 0xd0, 0x1a, 0x14, 0x86, 0xee, 0xd4, 0xe1, 0x52, - 0x65, 0x8d, 0xa8, 0x0f, 0xbc, 0x0f, 0xe5, 0xbe, 0x3d, 0xa1, 0x8c, 0x9b, 0x13, 0x0f, 0xb5, 0xa1, - 0xe4, 0x5d, 0xce, 0x98, 0x3d, 0x34, 0xc7, 0x52, 0xe3, 0x32, 0x09, 0xbf, 0x85, 0x4d, 0x63, 0x77, - 0x24, 0x59, 0x39, 0xc9, 0x0a, 0x3e, 0xf1, 0xef, 0x0c, 0xa8, 0x48, 0xa3, 0x14, 0x66, 0xe8, 0xbd, - 0x94, 0x55, 0x6b, 0x81, 0x55, 0x71, 0x4c, 0xef, 0x36, 0x0b, 0xbd, 0x0f, 0x65, 0x1e, 0x98, 0xd5, - 0x5a, 0x96, 0x6a, 0x34, 0x56, 0xa1, 0xb5, 0x24, 0x92, 0xc0, 0x7f, 0x30, 0xa0, 0x79, 0xe0, 0xba, - 0x9c, 0x71, 0xdf, 0xf4, 0x32, 0xa1, 0xf3, 0x04, 0x0a, 0x8c, 0xbb, 0x3e, 0xd5, 0x77, 0x58, 0xeb, - 0x68, 0x3f, 0xeb, 0x09, 0x22, 0x51, 0x3c, 0xf4, 0x23, 0x28, 0xfa, 0x74, 0x64, 0xbb, 0x8e, 0x36, - 0xa9, 0x1e, 0x48, 0x11, 0x49, 0x25, 0x9a, 0x8b, 0xf7, 0xe1, 0x41, 0xcc, 0x9a, 0x2c, 0xb0, 0xe0, - 0x23, 0x58, 0x3f, 0x61, 0xa1, 0x12, 0x8f, 0x5a, 0x59, 0x4e, 0x85, 0x7f, 0x03, 0x1b, 0x69, 0x2d, - 0x99, 0x2e, 0x09, 0x43, 0xf5, 0x3c, 0xa6, 0x45, 0x82, 0x54, 0x22, 0x09, 0x1a, 0xfe, 0x04, 0xea, - 0xfb, 0xe3, 0xb1, 0x3b, 0x3c, 0x39, 0xca, 0x64, 0x6a, 0x17, 0x1a, 0xe1, 0xf2, 0x4c, 0x36, 0xd6, - 0x21, 0x67, 0x2b, 0xcb, 0xf2, 0x24, 0x67, 0x5b, 0xf8, 0x2b, 0x68, 0x3c, 0xa7, 0x5c, 0xdd, 0x5f, - 0x16, 0x8f, 0x78, 0x08, 0x25, 0x79, 0xeb, 0x83, 0x50, 0xeb, 0x8a, 0xfc, 0x3e, 0xb1, 0x30, 0x85, - 0x66, 0xa4, 0x3a, 0x93, 0xb1, 0xf7, 0x71, 0x37, 0x3c, 0x84, 0xc6, 0xd9, 0xf4, 0x0d, 0x4e, 0x70, - 0xaf, 0x4d, 0x3e, 0x85, 0x66, 0xb4, 0x49, 0x26, 0x57, 0x3d, 0x80, 0xd5, 0xe7, 0x94, 0xef, 0x8f, - 0xc7, 0x52, 0x09, 0xcb, 0x74, 0xfb, 0x57, 0xb0, 0x96, 0xd4, 0x91, 0x09, 0xd5, 0x1f, 0x42, 0x51, - 0x1e, 0x8a, 0xb5, 0x72, 0x3b, 0xcb, 0xf3, 0x27, 0xd6, 0x4c, 0xfc, 0x2b, 0x79, 0x7d, 0x3a, 0x66, - 0xb3, 0x00, 0xbb, 0x05, 0xa0, 0x22, 0x7d, 0x70, 0x45, 0x67, 0x12, 0xdd, 0x2a, 0x29, 0x2b, 0xca, - 0x4b, 0x3a, 0xc3, 0x7f, 0x34, 0xe0, 0x41, 0x6c, 0x83, 0x4c, 0x47, 0x89, 0x52, 0x4d, 0xee, 0xae, - 0x54, 0x83, 0xde, 0x86, 0xe2, 0x58, 0x69, 0x55, 0x29, 0xa9, 0x1a, 0xc8, 0x9d, 0x51, 0xa1, 0x4d, - 0xf1, 0xf0, 0xaf, 0x25, 0xbc, 0x6a, 0xe9, 0xc1, 0x2c, 0x5b, 0x84, 0xa2, 0x47, 0xa0, 0xcf, 0x18, - 0x45, 0x44, 0x49, 0x11, 0x4e, 0x2c, 0xfc, 0x0c, 0x36, 0x9f, 0x53, 0x7e, 0xa8, 0x6a, 0xe2, 0xa1, - 0xeb, 0x5c, 0xd8, 0xa3, 0x4c, 0x8e, 0xc0, 0xa0, 0x35, 0xaf, 0x27, 0x13, 0x82, 0xef, 0xc0, 0x8a, - 0x2e, 0xd1, 0x1a, 0xc2, 0x46, 0x00, 0x8d, 0xd6, 0x4e, 0x02, 0x3e, 0xfe, 0x1a, 0x36, 0xcf, 0xa6, - 0x6f, 0x6e, 0xfc, 0xff, 0xb2, 0xe5, 0x0b, 0x68, 0xcd, 0x6f, 0x99, 0x29, 0xfc, 0xfe, 0x6a, 0x40, - 0xf1, 0x15, 0x9d, 0x9c, 0x53, 0x1f, 0x21, 0xc8, 0x3b, 0xe6, 0x44, 0x35, 0x17, 0x65, 0x22, 0x7f, - 0x8b, 0x5b, 0x9b, 0x48, 0x6e, 0xec, 0xd6, 0x14, 0xe1, 0xc4, 0x12, 0x4c, 0x8f, 0x52, 0x7f, 0x30, - 0xf5, 0xc7, 0xac, 0xb5, 0xbc, 0xb3, 0xbc, 0x5b, 0x26, 0x25, 0x41, 0xf8, 0xc2, 0x1f, 0x33, 0xf4, - 0x03, 0xa8, 0x0c, 0xc7, 0x36, 0x75, 0xb8, 0x62, 0xe7, 0x25, 0x1b, 0x14, 0x49, 0x0a, 0xfc, 0x18, - 0x1a, 0xca, 0xbf, 0x06, 0x9e, 0x6f, 0xbb, 0xbe, 0xcd, 0x67, 0xad, 0xc2, 0x8e, 0xb1, 0x5b, 0x20, - 0x75, 0x45, 0x3e, 0xd3, 0x54, 0xfc, 0xa9, 0x8c, 0x07, 0x65, 0x64, 0xb6, 0xfc, 0xf0, 0x0f, 0x03, - 0x50, 0x5c, 0x45, 0xc6, 0x98, 0x5a, 0x51, 0x27, 0x0f, 0xf2, 0x43, 0x55, 0x89, 0x2b, 0xad, 0x24, - 0x60, 0x2e, 0x88, 0xa9, 0xb8, 0x98, 0xe6, 0xa1, 0xf7, 0xa1, 0x42, 0xf9, 0xd0, 0x1a, 0x68, 0xd1, - 0xfc, 0x02, 0x51, 0x10, 0x02, 0x9f, 0xab, 0x13, 0x9c, 0x41, 0x59, 0x84, 0x64, 0x8f, 0x9b, 0x9c, - 0xa1, 0x1d, 0xc8, 0x0b, 0x98, 0xb5, 0xd5, 0xc9, 0x98, 0x95, 0x1c, 0xf4, 0x16, 0x54, 0x2d, 0xf7, - 0xc6, 0x19, 0x30, 0x3a, 0x74, 0x1d, 0x8b, 0xe9, 0x9b, 0xab, 0x08, 0x5a, 0x4f, 0x91, 0xf0, 0xb7, - 0x79, 0xd8, 0x50, 0x21, 0xfd, 0x82, 0x9a, 0x3e, 0x3f, 0xa7, 0x26, 0xcf, 0xe4, 0xb5, 0xff, 0xd7, - 0x54, 0x83, 0x3a, 0x00, 0xd2, 0x70, 0x71, 0x0a, 0xe5, 0x34, 0x61, 0xeb, 0x16, 0x9e, 0x9f, 0x94, - 0x85, 0x88, 0xf8, 0x64, 0xe8, 0x43, 0xa8, 0x79, 0xd4, 0xb1, 0x6c, 0x67, 0xa4, 0x97, 0x14, 0xf4, - 0xd5, 0xc4, 0x95, 0x57, 0xb5, 0x88, 0x5a, 0xf2, 0x04, 0x6a, 0xe7, 0x33, 0x4e, 0xd9, 0xe0, 0xc6, - 0xb7, 0x39, 0xa7, 0x4e, 0xab, 0x28, 0xc1, 0xa9, 0x4a, 0xe2, 0x97, 0x8a, 0x26, 0x72, 0xb4, 0x12, - 0xf2, 0xa9, 0x69, 0xb5, 0x56, 0x54, 0xcf, 0x2e, 0x29, 0x84, 0x9a, 0xa2, 0x67, 0xaf, 0x5e, 0xd1, - 0x59, 0xa4, 0xa2, 0xa4, 0xf0, 0x15, 0xb4, 0x40, 0xc3, 0x23, 0x28, 0x4b, 0x11, 0xa9, 0xa0, 0xac, - 0x22, 0x47, 0x10, 0xe4, 0xfa, 0x77, 0xa0, 0x69, 0x7a, 0x9e, 0xef, 0xfe, 0xd6, 0x9e, 0x98, 0x9c, - 0x0e, 0x98, 0xfd, 0x0d, 0x6d, 0x81, 0x94, 0x69, 0xc4, 0xe8, 0x3d, 0xfb, 0x1b, 0x8a, 0x3a, 0x50, - 0xb2, 0x1d, 0x4e, 0xfd, 0x6b, 0x73, 0xdc, 0xaa, 0x4a, 0xe4, 0x50, 0xd4, 0xca, 0x9e, 0x68, 0x0e, - 0x09, 0x65, 0xd2, 0xaa, 0x7d, 0xf7, 0x86, 0xb5, 0x6a, 0x73, 0xaa, 0x89, 0x7b, 0xc3, 0x3e, 0xcb, - 0x97, 0x2a, 0xcd, 0x2a, 0xbe, 0x04, 0x38, 0xbc, 0x34, 0x9d, 0x11, 0x15, 0xf0, 0xdc, 0xc3, 0xb7, - 0x3e, 0x82, 0xca, 0x50, 0xca, 0x0f, 0xe4, 0x53, 0x24, 0x27, 0x9f, 0x22, 0x9b, 0x9d, 0xe0, 0x2d, - 0x25, 0xb2, 0x91, 0xd2, 0x27, 0x9f, 0x24, 0x30, 0x0c, 0x7f, 0xe3, 0x3d, 0xa8, 0xf7, 0x7d, 0xd3, - 0x61, 0x17, 0xd4, 0x57, 0x6e, 0xfd, 0xdd, 0xbb, 0xe1, 0x0f, 0xa0, 0xf0, 0x8a, 0xfa, 0x23, 0xd9, - 0x3d, 0x73, 0xd3, 0x1f, 0x51, 0xae, 0x85, 0xe7, 0xfc, 0x4c, 0x71, 0x71, 0x0d, 0x2a, 0x3d, 0x6f, - 0x6c, 0xeb, 0x72, 0x85, 0xff, 0xb4, 0x0c, 0x9b, 0x73, 0x6e, 0x9e, 0x29, 0xfe, 0x3f, 0x0c, 0xcf, - 0x2d, 0x4d, 0x56, 0xde, 0xde, 0x54, 0x4b, 0x22, 0x00, 0x83, 0x03, 0x4b, 0x30, 0x3f, 0x81, 0x06, - 0xd7, 0x07, 0x1e, 0x24, 0x9c, 0x5f, 0xef, 0x94, 0x44, 0x83, 0xd4, 0x79, 0x12, 0x9d, 0x44, 0xc9, - 0xcc, 0x27, 0x4b, 0x26, 0xfa, 0x39, 0x54, 0x35, 0x93, 0x7a, 0xee, 0xf0, 0x52, 0xe6, 0x4e, 0x11, - 0xaa, 0x09, 0x54, 0x8e, 0x05, 0x8b, 0x54, 0xfc, 0xe8, 0x43, 0x24, 0x1e, 0x85, 0x94, 0x3a, 0x46, - 0x71, 0x01, 0xf2, 0xa0, 0x04, 0xce, 0x54, 0x26, 0x29, 0x4c, 0x04, 0xfe, 0x32, 0x06, 0xc2, 0xd7, - 0xa9, 0xbc, 0x12, 0xa2, 0x38, 0xe8, 0x67, 0x50, 0x65, 0x02, 0xf1, 0x81, 0xce, 0x03, 0x25, 0x29, - 0xf9, 0x40, 0x49, 0xc6, 0xee, 0x82, 0x54, 0x58, 0xec, 0x62, 0x2e, 0xa0, 0xb1, 0xcf, 0xae, 0x34, - 0xfb, 0xfb, 0xcb, 0x3b, 0xf8, 0x5b, 0x03, 0x9a, 0xd1, 0x46, 0x19, 0xdf, 0x2f, 0x35, 0x87, 0xde, - 0x0c, 0xd2, 0xed, 0x4b, 0xc5, 0xa1, 0x37, 0x24, 0xb8, 0x8e, 0x1d, 0xa8, 0x0a, 0x19, 0x59, 0x0f, - 0x6d, 0x4b, 0x95, 0xc3, 0x3c, 0x01, 0x87, 0xde, 0x08, 0x18, 0x4f, 0x2c, 0x86, 0x7f, 0x6f, 0x00, - 0x22, 0xd4, 0x73, 0x7d, 0x9e, 0xfd, 0xd0, 0x18, 0xf2, 0x63, 0x7a, 0xc1, 0x6f, 0x39, 0xb2, 0xe4, - 0xa1, 0xb7, 0xa1, 0xe0, 0xdb, 0xa3, 0x4b, 0x7e, 0xcb, 0x2b, 0x53, 0x31, 0xf1, 0x21, 0xac, 0x26, - 0x8c, 0xc9, 0xd4, 0x3c, 0xfc, 0x12, 0xaa, 0xf1, 0x2c, 0x24, 0x4a, 0x3a, 0xe3, 0xa6, 0xcf, 0x07, - 0xd1, 0xeb, 0x5b, 0x8d, 0x3b, 0xea, 0x92, 0x1c, 0x8d, 0x0a, 0x9e, 0x40, 0x8d, 0x3a, 0x56, 0x4c, - 0x4c, 0x21, 0x5a, 0xa5, 0x8e, 0x15, 0x0a, 0xe1, 0xbf, 0xe4, 0x01, 0x64, 0xeb, 0xad, 0xaa, 0x5e, - 0xfc, 0x45, 0x65, 0x24, 0x5e, 0x54, 0xa8, 0x0d, 0xa5, 0xa1, 0xe9, 0x99, 0x43, 0xd1, 0x43, 0xe8, - 0x26, 0x25, 0xf8, 0x46, 0x8f, 0xa1, 0x6c, 0x5e, 0x9b, 0xf6, 0xd8, 0x3c, 0x1f, 0x53, 0x09, 0x49, - 0x9e, 0x44, 0x04, 0x91, 0xc8, 0xf5, 0xb5, 0xaa, 0x31, 0x42, 0x5e, 0x8e, 0x11, 0x74, 0xc0, 0x1c, - 0xca, 0x61, 0xc2, 0x7b, 0x80, 0x98, 0x2e, 0x31, 0xcc, 0x31, 0x3d, 0x2d, 0x58, 0x90, 0x82, 0x4d, - 0xcd, 0xe9, 0x39, 0xa6, 0xa7, 0xa4, 0x9f, 0xc2, 0x9a, 0x4f, 0x87, 0xd4, 0xbe, 0x4e, 0xc9, 0x17, - 0xa5, 0x3c, 0x0a, 0x79, 0xd1, 0x8a, 0x2d, 0x80, 0x08, 0x34, 0x19, 0x66, 0x35, 0x52, 0x0e, 0xf1, - 0x42, 0x1d, 0x58, 0x35, 0x3d, 0x6f, 0x3c, 0x4b, 0xe9, 0x2b, 0x49, 0xb9, 0x07, 0x01, 0x2b, 0x52, - 0xb7, 0x09, 0x2b, 0x36, 0x1b, 0x9c, 0x4f, 0xd9, 0x4c, 0x56, 0x9d, 0x12, 0x29, 0xda, 0xec, 0x60, - 0xca, 0x66, 0x22, 0x9b, 0x4c, 0x19, 0xb5, 0xe2, 0xc5, 0xa6, 0x24, 0x08, 0xb2, 0xca, 0xcc, 0x15, - 0xc5, 0xca, 0x82, 0xa2, 0x98, 0xae, 0x7a, 0xd5, 0xf9, 0xaa, 0x97, 0xac, 0x9b, 0xb5, 0x74, 0xdd, - 0x4c, 0x14, 0xc5, 0x7a, 0xaa, 0x28, 0xc6, 0x2b, 0x5d, 0xe3, 0xbb, 0x2b, 0x1d, 0x1e, 0xc3, 0xba, - 0x74, 0x8f, 0x37, 0xed, 0x5f, 0x0a, 0x4c, 0xf8, 0x57, 0x32, 0xa1, 0x47, 0x7e, 0x47, 0x14, 0x1b, - 0x3f, 0x83, 0x8d, 0xf4, 0x6e, 0x99, 0x62, 0xe6, 0xef, 0x06, 0xac, 0xf5, 0x86, 0x26, 0x17, 0xfd, - 0x7c, 0xf6, 0x37, 0xe4, 0x5d, 0xaf, 0xa9, 0xfb, 0x0e, 0x9a, 0x62, 0x2d, 0x59, 0xfe, 0x8e, 0xd7, - 0xdf, 0x31, 0xac, 0xa7, 0xec, 0xcd, 0x72, 0xee, 0x77, 0x29, 0x94, 0xc3, 0x41, 0x25, 0x2a, 0x42, - 0xae, 0xfb, 0xb2, 0xb9, 0x84, 0x2a, 0xb0, 0xf2, 0xc5, 0xe9, 0xcb, 0xd3, 0xee, 0x97, 0xa7, 0x4d, - 0x03, 0xad, 0x41, 0xf3, 0xb4, 0xdb, 0x1f, 0x1c, 0x74, 0xbb, 0xfd, 0x5e, 0x9f, 0xec, 0x9f, 0x9d, - 0x1d, 0x1f, 0x35, 0x73, 0x68, 0x15, 0x1a, 0xbd, 0x7e, 0x97, 0x1c, 0x0f, 0xfa, 0xdd, 0x57, 0x07, - 0xbd, 0x7e, 0xf7, 0xf4, 0xb8, 0xb9, 0x8c, 0x5a, 0xb0, 0xb6, 0xff, 0x39, 0x39, 0xde, 0x3f, 0xfa, - 0x2a, 0x29, 0x9e, 0xdf, 0xfb, 0x5b, 0x19, 0x72, 0x67, 0x47, 0x68, 0x1f, 0x20, 0x6a, 0xf8, 0xd1, - 0xa6, 0xb2, 0x6c, 0xee, 0x15, 0xd1, 0x6e, 0xcd, 0x33, 0x94, 0xf1, 0x78, 0x09, 0x3d, 0x85, 0xe5, - 0x3e, 0x73, 0x91, 0x76, 0x88, 0x68, 0x6e, 0xda, 0x7e, 0x10, 0xa3, 0x04, 0xd2, 0xbb, 0xc6, 0x53, - 0x03, 0xfd, 0x02, 0xca, 0xe1, 0xb4, 0x0c, 0x6d, 0x28, 0xa9, 0xf4, 0x5c, 0xb1, 0xbd, 0x39, 0x47, - 0x0f, 0x77, 0x7c, 0x05, 0xf5, 0xe4, 0xbc, 0x0d, 0x3d, 0x52, 0xc2, 0x0b, 0x67, 0x79, 0xed, 0xc7, - 0x8b, 0x99, 0xa1, 0xba, 0x8f, 0x60, 0x45, 0xcf, 0xc4, 0x90, 0xbe, 0x9a, 0xe4, 0x84, 0xad, 0xbd, - 0x9e, 0xa2, 0x86, 0x2b, 0x3f, 0x86, 0x52, 0x30, 0xa1, 0x42, 0xeb, 0x21, 0x44, 0xf1, 0x51, 0x52, - 0x7b, 0x23, 0x4d, 0x8e, 0x2f, 0x0e, 0x46, 0x42, 0xc1, 0xe2, 0xd4, 0x1c, 0x2a, 0x58, 0x9c, 0x9e, - 0x1c, 0xe1, 0x25, 0xf4, 0x1c, 0xaa, 0xf1, 0x49, 0x0e, 0x7a, 0x18, 0x6e, 0x93, 0x9e, 0x10, 0xb5, - 0xdb, 0x8b, 0x58, 0x71, 0x2c, 0x93, 0xe1, 0x1a, 0x60, 0xb9, 0x30, 0x65, 0x04, 0x58, 0x2e, 0x8e, - 0x70, 0xbc, 0x84, 0xfa, 0xd0, 0x48, 0x75, 0x91, 0xe8, 0x71, 0xe0, 0xee, 0x8b, 0xde, 0x50, 0xed, - 0xad, 0x5b, 0xb8, 0x69, 0x87, 0x09, 0x07, 0x2b, 0x28, 0x42, 0x34, 0x91, 0x17, 0xda, 0x9b, 0x73, - 0xf4, 0xd0, 0xaa, 0x67, 0x50, 0x4b, 0x0c, 0x66, 0x50, 0x3b, 0x25, 0x1b, 0x9b, 0xd6, 0xdc, 0xa5, - 0xe7, 0x63, 0x28, 0x05, 0x2d, 0x52, 0x70, 0x65, 0xa9, 0xde, 0x2c, 0xb8, 0xb2, 0x74, 0x27, 0x85, - 0x97, 0xd0, 0x11, 0x54, 0x62, 0x9d, 0x04, 0x6a, 0x05, 0x07, 0x4f, 0x77, 0x3a, 0xed, 0x87, 0x0b, - 0x38, 0xa1, 0x96, 0x9e, 0x9c, 0xaa, 0x25, 0x26, 0x1a, 0x68, 0x2b, 0xb4, 0x78, 0xd1, 0x70, 0xa5, - 0xbd, 0x7d, 0x1b, 0x3b, 0xae, 0x34, 0x3d, 0x26, 0x09, 0x94, 0xde, 0x32, 0xb1, 0x09, 0x94, 0xde, - 0x36, 0x5d, 0xc1, 0x4b, 0xe8, 0x33, 0xa8, 0x25, 0xf2, 0x61, 0x00, 0xfa, 0xa2, 0xa4, 0xde, 0x7e, - 0xb4, 0x90, 0x17, 0xe8, 0x3a, 0x78, 0xf7, 0x9f, 0xaf, 0xb7, 0x8d, 0x7f, 0xbd, 0xde, 0x36, 0xfe, - 0xfd, 0x7a, 0xdb, 0xf8, 0xf3, 0x7f, 0xb6, 0x97, 0xa0, 0x35, 0x74, 0x27, 0x1d, 0xcf, 0x76, 0x46, - 0x43, 0xd3, 0xeb, 0x70, 0xfb, 0xea, 0xba, 0x73, 0x75, 0x2d, 0xff, 0x11, 0x75, 0x5e, 0x94, 0x7f, - 0x7e, 0xfa, 0xdf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x45, 0x28, 0x8f, 0x40, 0xd6, 0x1a, 0x00, 0x00, + 0x11, 0x16, 0x29, 0x92, 0x22, 0x8b, 0x4f, 0xb5, 0x5e, 0x5c, 0xee, 0x4a, 0x91, 0x7b, 0x9d, 0x58, + 0x76, 0x6c, 0x7a, 0xad, 0x04, 0x81, 0x01, 0xc3, 0x81, 0xf5, 0xda, 0x5d, 0x79, 0x2d, 0x51, 0x68, + 0xd2, 0x31, 0x0c, 0x04, 0x61, 0x46, 0x9c, 0x16, 0x35, 0x11, 0x39, 0x33, 0x3b, 0xdd, 0x94, 0x4c, + 0xe7, 0x92, 0x93, 0x2f, 0x09, 0x90, 0x5b, 0x90, 0x4b, 0x80, 0xdc, 0x03, 0xe4, 0x2f, 0xe4, 0x9a, + 0x63, 0x7e, 0x42, 0xb0, 0xf9, 0x23, 0xc1, 0xf4, 0x63, 0x5e, 0xa4, 0xb4, 0xca, 0x6c, 0x7c, 0x12, + 0xa7, 0xaa, 0xba, 0xba, 0xea, 0xeb, 0xae, 0x47, 0x97, 0x00, 0x5c, 0xd3, 0x3d, 0x6f, 0xbb, 0x9e, + 0xc3, 0x1d, 0x94, 0xf3, 0x7f, 0xb7, 0x2a, 0x63, 0xca, 0x0d, 0x4d, 0x6b, 0x55, 0xa9, 0x67, 0x5c, + 0xf0, 0xe0, 0x73, 0x75, 0xe8, 0x0c, 0x1d, 0xf1, 0xf3, 0x43, 0xff, 0x97, 0xa4, 0xe2, 0x6f, 0xa0, + 0x4a, 0xe8, 0xcb, 0x09, 0x65, 0xfc, 0x39, 0x35, 0x4c, 0xea, 0xa1, 0x4d, 0x80, 0xc1, 0x68, 0xc2, + 0x38, 0xf5, 0xfa, 0x96, 0xd9, 0xcc, 0x6c, 0x67, 0x76, 0x72, 0xa4, 0xa4, 0x28, 0xc7, 0x26, 0x6a, + 0xc2, 0xd2, 0x35, 0xf5, 0x98, 0xe5, 0xd8, 0xcd, 0xec, 0x76, 0x66, 0xa7, 0x44, 0xf4, 0x27, 0x6a, + 0xc3, 0x8a, 0x47, 0x5f, 0x4e, 0x2c, 0x8f, 0xf6, 0xc7, 0x96, 0xdd, 0xd7, 0x52, 0x8b, 0x42, 0x6a, + 0x59, 0xb1, 0x4e, 0x2c, 0xfb, 0x17, 0x92, 0x81, 0x7f, 0x0b, 0x35, 0x42, 0x99, 0xeb, 0xd8, 0x8c, + 0xde, 0x6f, 0xeb, 0xb7, 0x20, 0x4f, 0x3d, 0xcf, 0xf1, 0xc4, 0xc6, 0xe5, 0xdd, 0x72, 0x5b, 0xf8, + 0x7f, 0xe4, 0x93, 0x88, 0xe4, 0xa0, 0x77, 0xa0, 0xae, 0x35, 0xc4, 0xf7, 0xaf, 0x29, 0xb2, 0xde, + 0xfc, 0x29, 0xe4, 0xc5, 0x42, 0xf4, 0x18, 0x72, 0x7c, 0xea, 0x52, 0xb1, 0x5b, 0x6d, 0xb7, 0x1e, + 0xd1, 0xd9, 0x9b, 0xba, 0x94, 0x08, 0xa6, 0xef, 0xf4, 0x98, 0x32, 0x66, 0x0c, 0xa9, 0x76, 0x5a, + 0x7d, 0xe2, 0x0e, 0x40, 0x8f, 0x39, 0x0a, 0x41, 0xf4, 0x63, 0x28, 0x5c, 0x0a, 0x57, 0x84, 0xba, + 0xf2, 0xee, 0x8a, 0x54, 0x17, 0x03, 0x98, 0x28, 0x11, 0xb4, 0x0a, 0xf9, 0x81, 0x33, 0xb1, 0xb9, + 0x50, 0x59, 0x25, 0xf2, 0x03, 0xef, 0x41, 0xa9, 0x67, 0x8d, 0x29, 0xe3, 0xc6, 0xd8, 0x45, 0x2d, + 0x28, 0xba, 0x97, 0x53, 0x66, 0x0d, 0x8c, 0x91, 0xd0, 0xb8, 0x48, 0x82, 0x6f, 0xdf, 0xa6, 0x91, + 0x33, 0x14, 0xac, 0xac, 0x60, 0xe9, 0x4f, 0xfc, 0xbb, 0x0c, 0x94, 0x85, 0x51, 0x12, 0x5c, 0xf4, + 0x7e, 0xc2, 0xaa, 0x55, 0x6d, 0x55, 0x14, 0xfc, 0xbb, 0xcd, 0x42, 0x1f, 0x40, 0x89, 0x6b, 0xb3, + 0x04, 0xa4, 0x65, 0x8d, 0x55, 0x60, 0x2d, 0x09, 0x25, 0xf0, 0x1f, 0x32, 0xd0, 0xd8, 0x77, 0x1c, + 0xce, 0xb8, 0x67, 0xb8, 0xa9, 0xd0, 0x79, 0x0c, 0x79, 0xc6, 0x1d, 0x8f, 0xaa, 0xc3, 0xae, 0xb6, + 0xd5, 0xd5, 0xee, 0xfa, 0x44, 0x22, 0x79, 0xe8, 0x47, 0x50, 0xf0, 0xe8, 0x50, 0x9f, 0x72, 0x79, + 0xb7, 0xa6, 0xa5, 0x88, 0xa0, 0x12, 0xc5, 0xc5, 0x7b, 0xb0, 0x1c, 0xb1, 0x26, 0x0d, 0x2c, 0xf8, + 0x10, 0xd6, 0x8e, 0x59, 0xa0, 0xc4, 0xa5, 0x66, 0x1a, 0xaf, 0xf0, 0x6f, 0x60, 0x3d, 0xa9, 0x25, + 0xd5, 0x21, 0x61, 0xa8, 0x9c, 0x47, 0xb4, 0x08, 0x90, 0x8a, 0x24, 0x46, 0xc3, 0x9f, 0x42, 0x6d, + 0x6f, 0x34, 0x72, 0x06, 0xc7, 0x87, 0xa9, 0x4c, 0xed, 0x40, 0x3d, 0x58, 0x9e, 0xca, 0xc6, 0x1a, + 0x64, 0x2d, 0x69, 0x59, 0x8e, 0x64, 0x2d, 0x13, 0x7f, 0x0d, 0xf5, 0x67, 0x94, 0xcb, 0xf3, 0x4b, + 0x73, 0x23, 0x1e, 0x40, 0x51, 0x9c, 0x7a, 0x3f, 0xd0, 0xba, 0x24, 0xbe, 0x8f, 0x4d, 0x4c, 0xa1, + 0x11, 0xaa, 0x4e, 0x65, 0xec, 0x7d, 0xae, 0x1b, 0x1e, 0x40, 0xfd, 0x6c, 0xf2, 0x06, 0x1e, 0xdc, + 0x6b, 0x93, 0xcf, 0xa0, 0x11, 0x6e, 0x92, 0xea, 0xaa, 0xee, 0xc3, 0xca, 0x33, 0xca, 0xf7, 0x46, + 0x23, 0xa1, 0x84, 0xa5, 0x3a, 0xfd, 0x2b, 0x58, 0x8d, 0xeb, 0x48, 0x85, 0xea, 0x0f, 0xa1, 0x20, + 0x9c, 0x62, 0xcd, 0xec, 0xf6, 0xe2, 0xac, 0xc7, 0x8a, 0x89, 0x7f, 0x25, 0x8e, 0x4f, 0xc5, 0x6c, + 0x1a, 0x60, 0x37, 0x01, 0x64, 0xa4, 0xf7, 0xaf, 0xe8, 0x54, 0xa0, 0x5b, 0x21, 0x25, 0x49, 0x79, + 0x41, 0xa7, 0xf8, 0x8f, 0x19, 0x58, 0x8e, 0x6c, 0x90, 0xca, 0x95, 0x30, 0xd5, 0x64, 0xef, 0x4a, + 0x35, 0xe8, 0x6d, 0x28, 0x8c, 0xa4, 0x56, 0x99, 0x92, 0x2a, 0x5a, 0xee, 0x8c, 0xfa, 0xda, 0x24, + 0x0f, 0xff, 0x5a, 0xc0, 0x2b, 0x97, 0xee, 0x4f, 0xd3, 0x45, 0x28, 0x7a, 0x08, 0xca, 0xc7, 0x30, + 0x22, 0x8a, 0x92, 0x70, 0x6c, 0xe2, 0xa7, 0xb0, 0xf1, 0x8c, 0xf2, 0x03, 0x59, 0xf5, 0x0e, 0x1c, + 0xfb, 0xc2, 0x1a, 0xa6, 0xba, 0x08, 0x0c, 0x9a, 0xb3, 0x7a, 0x52, 0x21, 0xf8, 0x2e, 0x2c, 0xa9, + 0x22, 0xac, 0x20, 0xac, 0x6b, 0x68, 0x94, 0x76, 0xa2, 0xf9, 0xf8, 0x25, 0x6c, 0x9c, 0x4d, 0xde, + 0xdc, 0xf8, 0xff, 0x65, 0xcb, 0xe7, 0xd0, 0x9c, 0xdd, 0x32, 0x55, 0xf8, 0xfd, 0x35, 0x03, 0x85, + 0x13, 0x3a, 0x3e, 0xa7, 0x1e, 0x42, 0x90, 0xb3, 0x8d, 0xb1, 0x6c, 0x2e, 0x4a, 0x44, 0xfc, 0xf6, + 0x4f, 0x6d, 0x2c, 0xb8, 0x91, 0x53, 0x93, 0x84, 0x63, 0xd3, 0x67, 0xba, 0x94, 0x7a, 0xfd, 0x89, + 0x37, 0x62, 0xcd, 0xc5, 0xed, 0xc5, 0x9d, 0x12, 0x29, 0xfa, 0x84, 0x2f, 0xbd, 0x11, 0x43, 0x3f, + 0x80, 0xf2, 0x60, 0x64, 0x51, 0x9b, 0x4b, 0x76, 0x4e, 0xb0, 0x41, 0x92, 0x84, 0xc0, 0x3b, 0x50, + 0x97, 0xf7, 0xab, 0xef, 0x7a, 0x96, 0xe3, 0x59, 0x7c, 0xda, 0xcc, 0x6f, 0x67, 0x76, 0xf2, 0xa4, + 0x26, 0xc9, 0x67, 0x8a, 0x8a, 0x3f, 0x13, 0xf1, 0x20, 0x8d, 0x4c, 0x97, 0x1f, 0xfe, 0x91, 0x01, + 0x14, 0x55, 0x91, 0x32, 0xa6, 0x96, 0xa4, 0xe7, 0x3a, 0x3f, 0x54, 0xa4, 0xb8, 0xd4, 0x4a, 0x34, + 0x73, 0x4e, 0x4c, 0x45, 0xc5, 0x14, 0x0f, 0x7d, 0x00, 0x65, 0xca, 0x07, 0x66, 0x5f, 0x89, 0xe6, + 0xe6, 0x88, 0x82, 0x2f, 0xf0, 0x85, 0xf4, 0xe0, 0x0c, 0x4a, 0x7e, 0x48, 0x76, 0xb9, 0xc1, 0x19, + 0xda, 0x86, 0x9c, 0x0f, 0xb3, 0xb2, 0x3a, 0x1e, 0xb3, 0x82, 0x83, 0xde, 0x82, 0x8a, 0xe9, 0xdc, + 0xd8, 0x7d, 0x46, 0x07, 0x8e, 0x6d, 0x32, 0x75, 0x72, 0x65, 0x9f, 0xd6, 0x95, 0x24, 0xfc, 0x5d, + 0x0e, 0xd6, 0x65, 0x48, 0x3f, 0xa7, 0x86, 0xc7, 0xcf, 0xa9, 0xc1, 0x53, 0xdd, 0xda, 0xff, 0x6b, + 0xaa, 0x41, 0x6d, 0x00, 0x61, 0xb8, 0xef, 0x85, 0xbc, 0x34, 0x41, 0xeb, 0x16, 0xf8, 0x4f, 0x4a, + 0xbe, 0x88, 0xff, 0xc9, 0xd0, 0x47, 0x50, 0x75, 0xa9, 0x6d, 0x5a, 0xf6, 0x50, 0x2d, 0xc9, 0xab, + 0xa3, 0x89, 0x2a, 0xaf, 0x28, 0x11, 0xb9, 0xe4, 0x31, 0x54, 0xcf, 0xa7, 0x9c, 0xb2, 0xfe, 0x8d, + 0x67, 0x71, 0x4e, 0xed, 0x66, 0x41, 0x80, 0x53, 0x11, 0xc4, 0xaf, 0x24, 0xcd, 0xcf, 0xd1, 0x52, + 0xc8, 0xa3, 0x86, 0xd9, 0x5c, 0x92, 0xcd, 0xbd, 0xa0, 0x10, 0x6a, 0xf8, 0xcd, 0x7d, 0xe5, 0x8a, + 0x4e, 0x43, 0x15, 0x45, 0x89, 0xaf, 0x4f, 0xd3, 0x1a, 0x1e, 0x42, 0x49, 0x88, 0x08, 0x05, 0x25, + 0x19, 0x39, 0x3e, 0x41, 0xac, 0x7f, 0x17, 0x1a, 0x86, 0xeb, 0x7a, 0xce, 0x37, 0xd6, 0xd8, 0xe0, + 0xb4, 0xcf, 0xac, 0x6f, 0x69, 0x13, 0x84, 0x4c, 0x3d, 0x42, 0xef, 0x5a, 0xdf, 0x52, 0xd4, 0x86, + 0xa2, 0x65, 0x73, 0xea, 0x5d, 0x1b, 0xa3, 0x66, 0x45, 0x20, 0x87, 0xc2, 0x56, 0xf6, 0x58, 0x71, + 0x48, 0x20, 0x93, 0x54, 0xed, 0x39, 0x37, 0xac, 0x59, 0x9d, 0x51, 0x4d, 0x9c, 0x1b, 0xf6, 0x79, + 0xae, 0x58, 0x6e, 0x54, 0xf0, 0x25, 0xc0, 0xc1, 0xa5, 0x61, 0x0f, 0xa9, 0x0f, 0xcf, 0x3d, 0xee, + 0xd6, 0xc7, 0x50, 0x1e, 0x08, 0xf9, 0xbe, 0x78, 0x8a, 0x64, 0xc5, 0x53, 0x64, 0xa3, 0xad, 0x9f, + 0x6f, 0x7e, 0x36, 0x92, 0xfa, 0xc4, 0x93, 0x04, 0x06, 0xc1, 0x6f, 0xbc, 0x0b, 0xb5, 0x9e, 0x67, + 0xd8, 0xec, 0x82, 0x7a, 0xf2, 0x5a, 0xbf, 0x7e, 0x37, 0xfc, 0x21, 0xe4, 0x4f, 0xa8, 0x37, 0x14, + 0xdd, 0x33, 0x37, 0xbc, 0x21, 0xe5, 0x4a, 0x78, 0xe6, 0x9e, 0x49, 0x2e, 0xae, 0x42, 0xb9, 0xeb, + 0x8e, 0x2c, 0x55, 0xae, 0xf0, 0x9f, 0x16, 0x61, 0x63, 0xe6, 0x9a, 0xa7, 0x8a, 0xff, 0x8f, 0x02, + 0xbf, 0x85, 0xc9, 0xf2, 0xb6, 0x37, 0xe4, 0x92, 0x10, 0x40, 0xed, 0xb0, 0x00, 0xf3, 0x53, 0xa8, + 0x73, 0xe5, 0x70, 0x3f, 0x76, 0xf9, 0xd5, 0x4e, 0x71, 0x34, 0x48, 0x8d, 0xc7, 0xd1, 0x89, 0x95, + 0xcc, 0x5c, 0xbc, 0x64, 0xa2, 0x9f, 0x41, 0x45, 0x31, 0xa9, 0xeb, 0x0c, 0x2e, 0x45, 0xee, 0xf4, + 0x43, 0x35, 0x86, 0xca, 0x91, 0xcf, 0x22, 0x65, 0x2f, 0xfc, 0xf0, 0x13, 0x8f, 0x44, 0x4a, 0xba, + 0x51, 0x98, 0x83, 0x3c, 0x48, 0x81, 0x33, 0x99, 0x49, 0xf2, 0x63, 0x1f, 0x7f, 0x11, 0x03, 0xc1, + 0x33, 0x56, 0x1c, 0x09, 0x91, 0x1c, 0xf4, 0x53, 0xa8, 0x30, 0x1f, 0xf1, 0xbe, 0xca, 0x03, 0x45, + 0x21, 0xb9, 0x2c, 0x25, 0x23, 0x67, 0x41, 0xca, 0x2c, 0x72, 0x30, 0x17, 0x50, 0xdf, 0x63, 0x57, + 0x8a, 0xfd, 0xfd, 0xe5, 0x1d, 0xfc, 0x5d, 0x06, 0x1a, 0xe1, 0x46, 0x29, 0xdf, 0x2f, 0x55, 0x9b, + 0xde, 0xf4, 0x93, 0xed, 0x4b, 0xd9, 0xa6, 0x37, 0x44, 0x1f, 0xc7, 0x36, 0x54, 0x7c, 0x19, 0x51, + 0x0f, 0x2d, 0x53, 0x96, 0xc3, 0x1c, 0x01, 0x9b, 0xde, 0xf8, 0x30, 0x1e, 0x9b, 0x0c, 0xff, 0x3e, + 0x03, 0x88, 0x50, 0xd7, 0xf1, 0x78, 0x7a, 0xa7, 0x31, 0xe4, 0x46, 0xf4, 0x82, 0xdf, 0xe2, 0xb2, + 0xe0, 0xa1, 0xb7, 0x21, 0xef, 0x59, 0xc3, 0x4b, 0x7e, 0xcb, 0x2b, 0x53, 0x32, 0xf1, 0x01, 0xac, + 0xc4, 0x8c, 0x49, 0xd5, 0x3c, 0xfc, 0x12, 0x2a, 0xd1, 0x2c, 0xe4, 0x97, 0x74, 0xc6, 0x0d, 0x8f, + 0xf7, 0xc3, 0xd7, 0xb7, 0x9c, 0x8b, 0xd4, 0x04, 0x39, 0x1c, 0x15, 0x3c, 0x86, 0x2a, 0xb5, 0xcd, + 0x88, 0x98, 0x44, 0xb4, 0x42, 0x6d, 0x33, 0x10, 0xc2, 0x7f, 0xc9, 0x01, 0x88, 0xd6, 0x5b, 0x56, + 0xbd, 0xe8, 0x8b, 0x2a, 0x13, 0x7b, 0x51, 0xa1, 0x16, 0x14, 0x07, 0x86, 0x6b, 0x0c, 0xfc, 0x1e, + 0x42, 0x35, 0x29, 0xfa, 0x1b, 0x3d, 0x82, 0x92, 0x71, 0x6d, 0x58, 0x23, 0xe3, 0x7c, 0x44, 0x05, + 0x24, 0x39, 0x12, 0x12, 0xfc, 0x44, 0xae, 0x8e, 0x55, 0x8e, 0x11, 0x72, 0x62, 0x8c, 0xa0, 0x02, + 0xe6, 0x40, 0x0c, 0x13, 0xde, 0x07, 0xc4, 0x54, 0x89, 0x61, 0xb6, 0xe1, 0x2a, 0xc1, 0xbc, 0x10, + 0x6c, 0x28, 0x4e, 0xd7, 0x36, 0x5c, 0x29, 0xfd, 0x04, 0x56, 0x3d, 0x3a, 0xa0, 0xd6, 0x75, 0x42, + 0xbe, 0x20, 0xe4, 0x51, 0xc0, 0x0b, 0x57, 0x6c, 0x02, 0x84, 0xa0, 0x89, 0x30, 0xab, 0x92, 0x52, + 0x80, 0x17, 0x6a, 0xc3, 0x8a, 0xe1, 0xba, 0xa3, 0x69, 0x42, 0x5f, 0x51, 0xc8, 0x2d, 0x6b, 0x56, + 0xa8, 0x6e, 0x03, 0x96, 0x2c, 0xd6, 0x3f, 0x9f, 0xb0, 0xa9, 0xa8, 0x3a, 0x45, 0x52, 0xb0, 0xd8, + 0xfe, 0x84, 0x4d, 0xfd, 0x6c, 0x32, 0x61, 0xd4, 0x8c, 0x16, 0x9b, 0xa2, 0x4f, 0x10, 0x55, 0x66, + 0xa6, 0x28, 0x96, 0xe7, 0x14, 0xc5, 0x64, 0xd5, 0xab, 0xcc, 0x56, 0xbd, 0x78, 0xdd, 0xac, 0x26, + 0xeb, 0x66, 0xac, 0x28, 0xd6, 0x12, 0x45, 0x31, 0x5a, 0xe9, 0xea, 0xaf, 0xaf, 0x74, 0x78, 0x04, + 0x6b, 0xe2, 0x7a, 0xbc, 0x69, 0xff, 0x92, 0x67, 0xfe, 0xfd, 0x8a, 0x27, 0xf4, 0xf0, 0xde, 0x11, + 0xc9, 0xc6, 0x4f, 0x61, 0x3d, 0xb9, 0x5b, 0xaa, 0x98, 0xf9, 0x7b, 0x06, 0x56, 0xbb, 0x03, 0x83, + 0xfb, 0xfd, 0x7c, 0xfa, 0x37, 0xe4, 0x5d, 0xaf, 0xa9, 0xfb, 0x0e, 0x9a, 0x22, 0x2d, 0x59, 0xee, + 0x8e, 0xd7, 0xdf, 0x11, 0xac, 0x25, 0xec, 0x4d, 0xe3, 0xf7, 0x7b, 0x14, 0x4a, 0xc1, 0xa0, 0x12, + 0x15, 0x20, 0xdb, 0x79, 0xd1, 0x58, 0x40, 0x65, 0x58, 0xfa, 0xf2, 0xf4, 0xc5, 0x69, 0xe7, 0xab, + 0xd3, 0x46, 0x06, 0xad, 0x42, 0xe3, 0xb4, 0xd3, 0xeb, 0xef, 0x77, 0x3a, 0xbd, 0x6e, 0x8f, 0xec, + 0x9d, 0x9d, 0x1d, 0x1d, 0x36, 0xb2, 0x68, 0x05, 0xea, 0xdd, 0x5e, 0x87, 0x1c, 0xf5, 0x7b, 0x9d, + 0x93, 0xfd, 0x6e, 0xaf, 0x73, 0x7a, 0xd4, 0x58, 0x44, 0x4d, 0x58, 0xdd, 0xfb, 0x82, 0x1c, 0xed, + 0x1d, 0x7e, 0x1d, 0x17, 0xcf, 0xed, 0xfe, 0xad, 0x04, 0xd9, 0xb3, 0x43, 0xb4, 0x07, 0x10, 0x36, + 0xfc, 0x68, 0x43, 0x5a, 0x36, 0xf3, 0x8a, 0x68, 0x35, 0x67, 0x19, 0xd2, 0x78, 0xbc, 0x80, 0x9e, + 0xc0, 0x62, 0x8f, 0x39, 0x48, 0x5d, 0x88, 0x70, 0x6e, 0xda, 0x5a, 0x8e, 0x50, 0xb4, 0xf4, 0x4e, + 0xe6, 0x49, 0x06, 0xfd, 0x1c, 0x4a, 0xc1, 0xb4, 0x0c, 0xad, 0x4b, 0xa9, 0xe4, 0x5c, 0xb1, 0xb5, + 0x31, 0x43, 0x0f, 0x76, 0x3c, 0x81, 0x5a, 0x7c, 0xde, 0x86, 0x1e, 0x4a, 0xe1, 0xb9, 0xb3, 0xbc, + 0xd6, 0xa3, 0xf9, 0xcc, 0x40, 0xdd, 0xc7, 0xb0, 0xa4, 0x66, 0x62, 0x48, 0x1d, 0x4d, 0x7c, 0xc2, + 0xd6, 0x5a, 0x4b, 0x50, 0x83, 0x95, 0x9f, 0x40, 0x51, 0x4f, 0xa8, 0xd0, 0x5a, 0x00, 0x51, 0x74, + 0x94, 0xd4, 0x5a, 0x4f, 0x92, 0xa3, 0x8b, 0xf5, 0x48, 0x48, 0x2f, 0x4e, 0xcc, 0xa1, 0xf4, 0xe2, + 0xe4, 0xe4, 0x08, 0x2f, 0xa0, 0x67, 0x50, 0x89, 0x4e, 0x72, 0xd0, 0x83, 0x60, 0x9b, 0xe4, 0x84, + 0xa8, 0xd5, 0x9a, 0xc7, 0x8a, 0x62, 0x19, 0x0f, 0x57, 0x8d, 0xe5, 0xdc, 0x94, 0xa1, 0xb1, 0x9c, + 0x1f, 0xe1, 0x78, 0x01, 0xf5, 0xa0, 0x9e, 0xe8, 0x22, 0xd1, 0x23, 0x7d, 0xdd, 0xe7, 0xbd, 0xa1, + 0x5a, 0x9b, 0xb7, 0x70, 0x93, 0x17, 0x26, 0x18, 0xac, 0xa0, 0x10, 0xd1, 0x58, 0x5e, 0x68, 0x6d, + 0xcc, 0xd0, 0x03, 0xab, 0x9e, 0x42, 0x35, 0x36, 0x98, 0x41, 0xad, 0x84, 0x6c, 0x64, 0x5a, 0x73, + 0x97, 0x9e, 0x4f, 0xa0, 0xa8, 0x5b, 0x24, 0x7d, 0x64, 0x89, 0xde, 0x4c, 0x1f, 0x59, 0xb2, 0x93, + 0xc2, 0x0b, 0xe8, 0x10, 0xca, 0x91, 0x4e, 0x02, 0x35, 0xb5, 0xe3, 0xc9, 0x4e, 0xa7, 0xf5, 0x60, + 0x0e, 0x27, 0xd0, 0xd2, 0x15, 0x53, 0xb5, 0xd8, 0x44, 0x03, 0x6d, 0x06, 0x16, 0xcf, 0x1b, 0xae, + 0xb4, 0xb6, 0x6e, 0x63, 0x47, 0x95, 0x26, 0xc7, 0x24, 0x5a, 0xe9, 0x2d, 0x13, 0x1b, 0xad, 0xf4, + 0xb6, 0xe9, 0x0a, 0x5e, 0x40, 0x9f, 0x43, 0x35, 0x96, 0x0f, 0x35, 0xe8, 0xf3, 0x92, 0x7a, 0xeb, + 0xe1, 0x5c, 0x9e, 0xd6, 0xb5, 0xff, 0xde, 0x3f, 0x5f, 0x6d, 0x65, 0xfe, 0xf5, 0x6a, 0x2b, 0xf3, + 0xef, 0x57, 0x5b, 0x99, 0x3f, 0xff, 0x67, 0x6b, 0x01, 0x9a, 0x03, 0x67, 0xdc, 0x76, 0x2d, 0x7b, + 0x38, 0x30, 0xdc, 0x36, 0xb7, 0xae, 0xae, 0xdb, 0x57, 0xd7, 0xe2, 0x7f, 0x5f, 0xe7, 0x05, 0xf1, + 0xe7, 0x27, 0xff, 0x0d, 0x00, 0x00, 0xff, 0xff, 0x41, 0x5e, 0x0c, 0xfb, 0x49, 0x1b, 0x00, 0x00, } From 52bee4532decd41dc68162e9da6609e0650fa4b2 Mon Sep 17 00:00:00 2001 From: nolouch Date: Fri, 6 Jul 2018 17:41:47 +0800 Subject: [PATCH 02/30] add version --- server/cluster.go | 1 - server/cluster_version.go | 15 ++++ server/config.go | 2 + server/core/store.go | 1 + server/grpc_service.go | 11 ++- server/option.go | 35 ++++++---- server/version.go | 142 ++++++++++++++++++++++++++++++++++++++ 7 files changed, 193 insertions(+), 14 deletions(-) create mode 100644 server/cluster_version.go create mode 100644 server/version.go diff --git a/server/cluster.go b/server/cluster.go index d86ea3415d6..d3aa35d6d02 100644 --- a/server/cluster.go +++ b/server/cluster.go @@ -319,7 +319,6 @@ func (c *RaftCluster) putStore(store *metapb.Store) error { log.Warnf("missing location label %q in store %v", k, s) } } - return cluster.putStore(s) } diff --git a/server/cluster_version.go b/server/cluster_version.go new file mode 100644 index 00000000000..8424ff6fb0a --- /dev/null +++ b/server/cluster_version.go @@ -0,0 +1,15 @@ +// Copyright 2018 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// See the License for the specific language governing permissions and +// limitations under the License. +package server + +type ClusterVersion struct{} diff --git a/server/config.go b/server/config.go index c5b00d4db95..992324f7b58 100644 --- a/server/config.go +++ b/server/config.go @@ -77,6 +77,8 @@ type Config struct { Namespace map[string]NamespaceConfig `json:"namespace"` + ClusterVersion Version `json:"cluster_version"` + // QuotaBackendBytes Raise alarms when backend size exceeds the given quota. 0 means use the default quota. // the default size is 2GB, the maximum is 8GB. QuotaBackendBytes typeutil.ByteSize `toml:"quota-backend-bytes" json:"quota-backend-bytes"` diff --git a/server/core/store.go b/server/core/store.go index 660e3827ff3..dca552782d7 100644 --- a/server/core/store.go +++ b/server/core/store.go @@ -41,6 +41,7 @@ type StoreInfo struct { LeaderWeight float64 RegionWeight float64 RollingStoreStats *RollingStoreStats + Version string } // NewStoreInfo creates StoreInfo with meta data. diff --git a/server/grpc_service.go b/server/grpc_service.go index 9bed0fb7d4b..374393338d7 100644 --- a/server/grpc_service.go +++ b/server/grpc_service.go @@ -532,6 +532,15 @@ func (s *Server) validateRequest(header *pdpb.RequestHeader) error { if !s.IsLeader() { return notLeaderError } + requireVersion, err := ParseVersion(header.GetRequireMinVersion()) + if err != nil { + return grpc.Errorf(codes.FailedPrecondition, "Header meet error: %s", err.Error()) + } + clusterVersion := s.GetConfig().ClusterVersion + if clusterVersion.Less(requireVersion) { + return grpc.Errorf(codes.FailedPrecondition, "require version is %s, but now cluster version is %d", requireVersion, clusterVersion) + + } if header.GetClusterId() != s.clusterID { return grpc.Errorf(codes.FailedPrecondition, "mismatch cluster id, need %d but got %d", s.clusterID, header.GetClusterId()) } @@ -539,7 +548,7 @@ func (s *Server) validateRequest(header *pdpb.RequestHeader) error { } func (s *Server) header() *pdpb.ResponseHeader { - return &pdpb.ResponseHeader{ClusterId: s.clusterID} + return &pdpb.ResponseHeader{ClusterId: s.clusterID, ClusterVersion: s.scheduleOpt.loadClusterVersion().String()} } func (s *Server) errorHeader(err *pdpb.Error) *pdpb.ResponseHeader { diff --git a/server/option.go b/server/option.go index 645a31df647..1c65fac1ac4 100644 --- a/server/option.go +++ b/server/option.go @@ -26,10 +26,11 @@ import ( // scheduleOption is a wrapper to access the configuration safely. type scheduleOption struct { - v atomic.Value - rep *Replication - ns map[string]*namespaceOption - labelProperty atomic.Value + v atomic.Value + rep *Replication + ns map[string]*namespaceOption + labelProperty atomic.Value + clusterVersion atomic.Value } func newScheduleOption(cfg *Config) *scheduleOption { @@ -225,16 +226,25 @@ func (o *scheduleOption) loadLabelPropertyConfig() LabelPropertyConfig { return o.labelProperty.Load().(LabelPropertyConfig) } +func (o *scheduleOption) SetClusterVersion(v *Version) { + o.clusterVersion.Store(v) +} + +func (o *scheduleOption) loadClusterVersion() *Version { + return o.clusterVersion.Load().(*Version) +} + func (o *scheduleOption) persist(kv *core.KV) error { namespaces := make(map[string]NamespaceConfig) for name, ns := range o.ns { namespaces[name] = *ns.load() } cfg := &Config{ - Schedule: *o.load(), - Replication: *o.rep.load(), - Namespace: namespaces, - LabelProperty: o.loadLabelPropertyConfig(), + Schedule: *o.load(), + Replication: *o.rep.load(), + Namespace: namespaces, + LabelProperty: o.loadLabelPropertyConfig(), + ClusterVersion: *o.loadClusterVersion(), } err := kv.SaveConfig(cfg) return errors.Trace(err) @@ -246,10 +256,11 @@ func (o *scheduleOption) reload(kv *core.KV) error { namespaces[name] = *ns.load() } cfg := &Config{ - Schedule: *o.load().clone(), - Replication: *o.rep.load(), - Namespace: namespaces, - LabelProperty: o.loadLabelPropertyConfig().clone(), + Schedule: *o.load().clone(), + Replication: *o.rep.load(), + Namespace: namespaces, + LabelProperty: o.loadLabelPropertyConfig().clone(), + ClusterVersion: *o.loadClusterVersion(), } isExist, err := kv.LoadConfig(cfg) if err != nil { diff --git a/server/version.go b/server/version.go new file mode 100644 index 00000000000..cdd0485a9a0 --- /dev/null +++ b/server/version.go @@ -0,0 +1,142 @@ +// Copyright 2018 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// See the License for the specific language governing permissions and +// limitations under the License. +package server + +import ( + "fmt" + "strconv" + "strings" + + "github.com/juju/errors" +) + +// VersionBase is the empty version +var VersionBase = Version{Marjor: 1} + +// Version record version information. +type Version struct { + Marjor int32 + Minor int32 + Patch int32 + Unstable int32 + UnstablePatch int32 +} + +// Less compare two version. +func (v *Version) Less(ov Version) bool { + if v.Marjor < ov.Marjor { + return true + } else if v.Minor < ov.Minor { + return true + } else if v.Patch < ov.Patch { + return true + } else if v.Unstable < ov.Unstable { + return true + } else if v.UnstablePatch < ov.UnstablePatch { + return true + } + return false +} + +func (v *Version) String() string { + convMap := map[int32]string{ + 1: "alpha", + 2: "beta", + 3: "rc", + } + var res string + if unstable, ok := convMap[v.Unstable]; ok { + res = fmt.Sprintf("%d.%d.%d-%s", v.Marjor, v.Minor, v.Patch, unstable) + if v.UnstablePatch > 0 { + res = fmt.Sprintf("%s.%d", res, v.UnstablePatch) + } + return res + } + res = fmt.Sprintf("%d.%d.%d", v.Marjor, v.Minor, v.Patch) + return res +} + +func convUnstable(s string) int32 { + innerMap := map[string]int32{ + "alpha": 1, + "beta": 2, + "rc": 3, + } + if res, ok := innerMap[s]; ok { + return res + } + return -1 +} + +//ParseVersion parses a version from a string. +//The string format should be "major.minor.patch-". +func ParseVersion(s string) (Version, error) { + splits := strings.Split(s, ".") + if len(splits) != 3 && len(splits) != 4 { + return Version{}, errors.Errorf("invalid version: %s", s) + } + patchAndUnstable := strings.Split(splits[2], "-") + + parts := append(splits[:2], patchAndUnstable...) + if len(splits) == 4 { + parts = append(parts, splits[3]) + } + for i := len(parts); i < 5; i++ { + parts = append(parts, "0") + } + ints := make([]int32, len(parts)) + for i, part := range parts { + if i == 4 && part != "0" { + r := convUnstable(part) + if r < 0 { + return Version{}, errors.Errorf("invalid version: %s ", s) + } + ints[i] = r + continue + } + var ( + val int64 + err error + ) + if val, err = strconv.ParseInt(part, 10, 32); err != nil { + return Version{}, errors.Errorf("invalid version: %s ", s) + } + ints[i] = int32(val) + } + return Version{ + Marjor: ints[0], + Minor: ints[1], + Patch: ints[2], + Unstable: ints[3], + UnstablePatch: ints[4], + }, nil +} + +// MarshalJSON returns the version as a JSON string. +func (v *Version) MarshalJSON() ([]byte, error) { + return []byte(v.String()), nil +} + +// UnmarshalJSON parses a JSON string into the version. +func (v *Version) UnmarshalJSON(text []byte) error { + s, err := strconv.Unquote(string(text)) + if err != nil { + return errors.Trace(err) + } + version, err := ParseVersion(s) + if err != nil { + return errors.Trace(err) + } + *v = version + return nil +} From 595f13312d7ec0a989157df7a6a9b5897549f2fa Mon Sep 17 00:00:00 2001 From: nolouch Date: Thu, 12 Jul 2018 16:56:19 +0800 Subject: [PATCH 03/30] update proto --- Gopkg.lock | 2 +- .../pingcap/kvproto/pkg/metapb/metapb.pb.go | 109 +++++++++++++----- 2 files changed, 79 insertions(+), 32 deletions(-) diff --git a/Gopkg.lock b/Gopkg.lock index 308a033e1c8..69f76fa7287 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -260,7 +260,7 @@ "pkg/metapb", "pkg/pdpb" ] - revision = "1c97132330a421e762e2aa2b389d702db8206008" + revision = "87f65f4fd97bef9f23fa2821da1bd019d9592928" source = "https://github.com/nolouch/kvproto" [[projects]] diff --git a/vendor/github.com/pingcap/kvproto/pkg/metapb/metapb.pb.go b/vendor/github.com/pingcap/kvproto/pkg/metapb/metapb.pb.go index 05d8d9d9a6c..9283c6a74c1 100644 --- a/vendor/github.com/pingcap/kvproto/pkg/metapb/metapb.pb.go +++ b/vendor/github.com/pingcap/kvproto/pkg/metapb/metapb.pb.go @@ -116,6 +116,7 @@ type Store struct { Address string `protobuf:"bytes,2,opt,name=address,proto3" json:"address,omitempty"` State StoreState `protobuf:"varint,3,opt,name=state,proto3,enum=metapb.StoreState" json:"state,omitempty"` Labels []*StoreLabel `protobuf:"bytes,4,rep,name=labels" json:"labels,omitempty"` + Version string `protobuf:"bytes,5,opt,name=version,proto3" json:"version,omitempty"` } func (m *Store) Reset() { *m = Store{} } @@ -151,6 +152,13 @@ func (m *Store) GetLabels() []*StoreLabel { return nil } +func (m *Store) GetVersion() string { + if m != nil { + return m.Version + } + return "" +} + type RegionEpoch struct { // Conf change version, auto increment when add or remove peer ConfVer uint64 `protobuf:"varint,1,opt,name=conf_ver,json=confVer,proto3" json:"conf_ver,omitempty"` @@ -368,6 +376,12 @@ func (m *Store) MarshalTo(dAtA []byte) (int, error) { i += n } } + if len(m.Version) > 0 { + dAtA[i] = 0x2a + i++ + i = encodeVarintMetapb(dAtA, i, uint64(len(m.Version))) + i += copy(dAtA[i:], m.Version) + } return i, nil } @@ -566,6 +580,10 @@ func (m *Store) Size() (n int) { n += 1 + l + sovMetapb(uint64(l)) } } + l = len(m.Version) + if l > 0 { + n += 1 + l + sovMetapb(uint64(l)) + } return n } @@ -959,6 +977,35 @@ func (m *Store) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Version", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetapb + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthMetapb + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Version = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipMetapb(dAtA[iNdEx:]) @@ -1479,35 +1526,35 @@ var ( func init() { proto.RegisterFile("metapb.proto", fileDescriptorMetapb) } var fileDescriptorMetapb = []byte{ - // 474 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x64, 0x92, 0xcf, 0x8e, 0xd3, 0x30, - 0x10, 0xc6, 0xd7, 0xfd, 0x93, 0xb6, 0xd3, 0x6e, 0x55, 0x99, 0x95, 0xc8, 0x82, 0xa8, 0xaa, 0x88, - 0x43, 0xd4, 0x43, 0x41, 0x0b, 0xe2, 0x8a, 0xb4, 0x2b, 0x0e, 0x88, 0x95, 0x58, 0x79, 0x81, 0x6b, - 0xe4, 0x26, 0xd3, 0x62, 0x35, 0xb1, 0x23, 0xdb, 0x8d, 0x76, 0x9f, 0x80, 0x57, 0xe0, 0x19, 0x78, - 0x12, 0x8e, 0x3c, 0x02, 0x2a, 0x2f, 0x82, 0xec, 0x24, 0xd2, 0x6a, 0x7b, 0x8a, 0xbf, 0xf9, 0x66, - 0x26, 0xbf, 0xf1, 0x18, 0x26, 0x05, 0x5a, 0x5e, 0xae, 0x57, 0xa5, 0x56, 0x56, 0xd1, 0xa0, 0x56, - 0xcf, 0xce, 0xb6, 0x6a, 0xab, 0x7c, 0xe8, 0x95, 0x3b, 0xd5, 0x6e, 0xf4, 0x1e, 0x06, 0x57, 0xf9, - 0xde, 0x58, 0xd4, 0x74, 0x0a, 0x1d, 0x91, 0x85, 0x64, 0x41, 0xe2, 0x1e, 0xeb, 0x88, 0x8c, 0xbe, - 0x84, 0x69, 0xc1, 0xef, 0x92, 0x12, 0x51, 0x27, 0xa9, 0xda, 0x4b, 0x1b, 0x76, 0x16, 0x24, 0x3e, - 0x65, 0x93, 0x82, 0xdf, 0xdd, 0x20, 0xea, 0x2b, 0x17, 0x8b, 0xde, 0x02, 0xdc, 0x5a, 0xa5, 0xf1, - 0x9a, 0xaf, 0x31, 0xa7, 0x33, 0xe8, 0xee, 0xf0, 0xde, 0x37, 0x19, 0x31, 0x77, 0xa4, 0x67, 0xd0, - 0xaf, 0x78, 0xbe, 0x47, 0x5f, 0x3c, 0x62, 0xb5, 0x88, 0x7e, 0x10, 0xe8, 0xfb, 0xb2, 0xa3, 0xbf, - 0x86, 0x30, 0xe0, 0x59, 0xa6, 0xd1, 0x98, 0xa6, 0xa2, 0x95, 0x34, 0x86, 0xbe, 0xb1, 0xdc, 0x62, - 0xd8, 0x5d, 0x90, 0x78, 0x7a, 0x41, 0x57, 0xcd, 0x98, 0xbe, 0xcf, 0xad, 0x73, 0x58, 0x9d, 0x40, - 0x97, 0x10, 0xe4, 0x0e, 0xc7, 0x84, 0xbd, 0x45, 0x37, 0x1e, 0x3f, 0x4a, 0xf5, 0xa4, 0xac, 0xc9, - 0x88, 0x2e, 0x61, 0xcc, 0x70, 0x2b, 0x94, 0xfc, 0x50, 0xaa, 0xf4, 0x3b, 0x3d, 0x87, 0x61, 0xaa, - 0xe4, 0x26, 0xa9, 0x50, 0x37, 0x50, 0x03, 0xa7, 0xbf, 0xa1, 0x76, 0x64, 0x15, 0x6a, 0x23, 0x94, - 0xf4, 0x64, 0x3d, 0xd6, 0xca, 0xe8, 0x17, 0x81, 0xa0, 0x6e, 0x72, 0x34, 0xce, 0x73, 0x18, 0x19, - 0xcb, 0xb5, 0x4d, 0xdc, 0xb5, 0xb8, 0xb2, 0x09, 0x1b, 0xfa, 0xc0, 0x27, 0xbc, 0xa7, 0x4f, 0x61, - 0x80, 0x32, 0xf3, 0x56, 0xd7, 0x5b, 0x01, 0xca, 0xcc, 0x19, 0xef, 0x60, 0xa2, 0x7d, 0xbf, 0x04, - 0x1d, 0x55, 0xd8, 0x5b, 0x90, 0x78, 0x7c, 0xf1, 0xa4, 0x1d, 0xe3, 0x01, 0x30, 0x1b, 0xeb, 0x07, - 0xf4, 0x11, 0xf4, 0xdd, 0xba, 0x4c, 0xd8, 0xf7, 0x73, 0x4f, 0xda, 0x02, 0xb7, 0x2e, 0x56, 0x5b, - 0xd1, 0x0d, 0xf4, 0x9c, 0x3c, 0x22, 0x3d, 0x87, 0xa1, 0x71, 0xd7, 0x93, 0x88, 0xac, 0x9d, 0xcf, - 0xeb, 0x8f, 0x19, 0x7d, 0x01, 0x20, 0x4c, 0x92, 0x23, 0xd7, 0x12, 0xb5, 0x47, 0x1d, 0xb2, 0x91, - 0x30, 0xd7, 0x75, 0x60, 0xf9, 0xba, 0x79, 0x02, 0x7e, 0x07, 0x34, 0x80, 0xce, 0xd7, 0x72, 0x76, - 0x42, 0xc7, 0x30, 0xf8, 0xbc, 0xd9, 0xe4, 0x42, 0xe2, 0x8c, 0xd0, 0x53, 0x18, 0x7d, 0x51, 0xc5, - 0xda, 0x58, 0x25, 0x71, 0xd6, 0xb9, 0x5c, 0xfe, 0x3e, 0xcc, 0xc9, 0x9f, 0xc3, 0x9c, 0xfc, 0x3d, - 0xcc, 0xc9, 0xcf, 0x7f, 0xf3, 0x13, 0x08, 0x53, 0x55, 0xac, 0x4a, 0x21, 0xb7, 0x29, 0x2f, 0x57, - 0x56, 0xec, 0xaa, 0xd5, 0xae, 0xf2, 0x2f, 0x74, 0x1d, 0xf8, 0xcf, 0x9b, 0xff, 0x01, 0x00, 0x00, - 0xff, 0xff, 0x2a, 0x28, 0xbc, 0x30, 0xd6, 0x02, 0x00, 0x00, + // 479 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x64, 0x52, 0xc1, 0x8e, 0xd3, 0x3c, + 0x10, 0x5e, 0xa7, 0x4d, 0xda, 0x4e, 0xbb, 0x55, 0xe5, 0x7f, 0xa5, 0x3f, 0x0b, 0xa2, 0xaa, 0x22, + 0x0e, 0x51, 0x0f, 0x05, 0x2d, 0x88, 0x2b, 0xd2, 0xae, 0x38, 0x20, 0x56, 0x62, 0xe5, 0x05, 0xae, + 0x91, 0xdb, 0x4c, 0x8b, 0xd5, 0xd4, 0x8e, 0x6c, 0x37, 0xda, 0x7d, 0x13, 0xae, 0x5c, 0x79, 0x12, + 0x8e, 0x3c, 0x02, 0x2a, 0x2f, 0x82, 0xec, 0x24, 0x52, 0x45, 0x4f, 0xc9, 0x37, 0xdf, 0xcc, 0x37, + 0xdf, 0xcc, 0x18, 0x46, 0x3b, 0xb4, 0xbc, 0x5c, 0x2e, 0x4a, 0xad, 0xac, 0xa2, 0x51, 0x8d, 0x9e, + 0x5c, 0x6c, 0xd4, 0x46, 0xf9, 0xd0, 0x0b, 0xf7, 0x57, 0xb3, 0xc9, 0x5b, 0xe8, 0xdd, 0x14, 0x7b, + 0x63, 0x51, 0xd3, 0x31, 0x04, 0x22, 0x8f, 0xc9, 0x8c, 0xa4, 0x5d, 0x16, 0x88, 0x9c, 0x3e, 0x87, + 0xf1, 0x8e, 0x3f, 0x64, 0x25, 0xa2, 0xce, 0x56, 0x6a, 0x2f, 0x6d, 0x1c, 0xcc, 0x48, 0x7a, 0xce, + 0x46, 0x3b, 0xfe, 0x70, 0x87, 0xa8, 0x6f, 0x5c, 0x2c, 0x79, 0x0d, 0x70, 0x6f, 0x95, 0xc6, 0x5b, + 0xbe, 0xc4, 0x82, 0x4e, 0xa0, 0xb3, 0xc5, 0x47, 0x2f, 0x32, 0x60, 0xee, 0x97, 0x5e, 0x40, 0x58, + 0xf1, 0x62, 0x8f, 0xbe, 0x78, 0xc0, 0x6a, 0x90, 0x7c, 0x27, 0x10, 0xfa, 0xb2, 0x93, 0xae, 0x31, + 0xf4, 0x78, 0x9e, 0x6b, 0x34, 0xa6, 0xa9, 0x68, 0x21, 0x4d, 0x21, 0x34, 0x96, 0x5b, 0x8c, 0x3b, + 0x33, 0x92, 0x8e, 0xaf, 0xe8, 0xa2, 0x19, 0xd3, 0xeb, 0xdc, 0x3b, 0x86, 0xd5, 0x09, 0x74, 0x0e, + 0x51, 0xe1, 0xec, 0x98, 0xb8, 0x3b, 0xeb, 0xa4, 0xc3, 0x7f, 0x52, 0xbd, 0x53, 0xd6, 0x64, 0xb8, + 0x7e, 0x15, 0x6a, 0x23, 0x94, 0x8c, 0xc3, 0xba, 0x5f, 0x03, 0x93, 0x6b, 0x18, 0x32, 0xdc, 0x08, + 0x25, 0xdf, 0x95, 0x6a, 0xf5, 0x95, 0x5e, 0x42, 0x7f, 0xa5, 0xe4, 0x3a, 0xab, 0x50, 0x37, 0x76, + 0x7b, 0x0e, 0x7f, 0x41, 0x7d, 0xac, 0x11, 0xd4, 0x4c, 0xab, 0xf1, 0x83, 0x40, 0x54, 0x8b, 0x9c, + 0x0c, 0xfa, 0x14, 0x06, 0xc6, 0x72, 0x6d, 0x33, 0xb7, 0x30, 0x57, 0x36, 0x62, 0x7d, 0x1f, 0xf8, + 0x80, 0x8f, 0xf4, 0x7f, 0xe8, 0xa1, 0xcc, 0x3d, 0xd5, 0xf1, 0x54, 0x84, 0x32, 0x77, 0xc4, 0x1b, + 0x18, 0x69, 0xaf, 0x97, 0xa1, 0x73, 0x15, 0x77, 0x67, 0x24, 0x1d, 0x5e, 0xfd, 0xd7, 0x0e, 0x78, + 0x64, 0x98, 0x0d, 0xf5, 0x91, 0xfb, 0x04, 0x42, 0x77, 0x48, 0x13, 0x87, 0x7e, 0x23, 0xa3, 0xb6, + 0xc0, 0x1d, 0x92, 0xd5, 0x54, 0x72, 0x07, 0x5d, 0x07, 0x4f, 0x9c, 0x5e, 0x42, 0xdf, 0xb8, 0xc5, + 0x65, 0x22, 0x6f, 0xe7, 0xf3, 0xf8, 0x7d, 0x4e, 0x9f, 0x01, 0x08, 0x93, 0x15, 0xc8, 0xb5, 0x44, + 0xed, 0xad, 0xf6, 0xd9, 0x40, 0x98, 0xdb, 0x3a, 0x30, 0x7f, 0xd9, 0x3c, 0x0e, 0x7f, 0x1d, 0x1a, + 0x41, 0xf0, 0xb9, 0x9c, 0x9c, 0xd1, 0x21, 0xf4, 0x3e, 0xae, 0xd7, 0x85, 0x90, 0x38, 0x21, 0xf4, + 0x1c, 0x06, 0x9f, 0xd4, 0x6e, 0x69, 0xac, 0x92, 0x38, 0x09, 0xae, 0xe7, 0x3f, 0x0f, 0x53, 0xf2, + 0xeb, 0x30, 0x25, 0xbf, 0x0f, 0x53, 0xf2, 0xed, 0xcf, 0xf4, 0x0c, 0xe2, 0x95, 0xda, 0x2d, 0x4a, + 0x21, 0x37, 0x2b, 0x5e, 0x2e, 0xac, 0xd8, 0x56, 0x8b, 0x6d, 0xe5, 0xdf, 0xee, 0x32, 0xf2, 0x9f, + 0x57, 0x7f, 0x03, 0x00, 0x00, 0xff, 0xff, 0x0b, 0x59, 0x52, 0x48, 0xf0, 0x02, 0x00, 0x00, } From 2fdd381922b25bfa6f394b13a96d3fa0f926774d Mon Sep 17 00:00:00 2001 From: nolouch Date: Thu, 12 Jul 2018 19:48:11 +0800 Subject: [PATCH 04/30] on change cluster version --- server/cluster.go | 10 ++++++++++ server/cluster_info.go | 35 +++++++++++++++++++++++++++++++++++ server/version.go | 2 +- 3 files changed, 46 insertions(+), 1 deletion(-) diff --git a/server/cluster.go b/server/cluster.go index d3aa35d6d02..8ae1d759dde 100644 --- a/server/cluster.go +++ b/server/cluster.go @@ -290,6 +290,15 @@ func (c *RaftCluster) putStore(store *metapb.Store) error { return errors.Errorf("invalid put store %v", store) } + v, err := ParseVersion(store.GetVersion()) + if err != nil { + return errors.Errorf("invalid put store %s", err) + } + clusterVersion := c.cachedCluster.opt.loadClusterVersion() + if v.Less(clusterVersion) { + return errors.Errorf("version should be %s, got %s", clusterVersion) + } + cluster := c.cachedCluster // Store address can not be the same as other stores. @@ -310,6 +319,7 @@ func (c *RaftCluster) putStore(store *metapb.Store) error { } else { // Update an existed store. s.Address = store.Address + s.Version = store.Version s.MergeLabels(store.Labels) } diff --git a/server/cluster_info.go b/server/cluster_info.go index 2820bc06e43..f9fdc5cddf8 100644 --- a/server/cluster_info.go +++ b/server/cluster_info.go @@ -78,6 +78,41 @@ func loadClusterInfo(id core.IDAllocator, kv *core.KV, opt *scheduleOption) (*cl return c, nil } +func (c *clusterInfo) OnChangeClusterVersion() { + + var ( + minVersion Version + clusterVersion Version + ) + + clusterVersion = *c.opt.loadClusterVersion() + stores := c.GetStores() + for i, s := range stores { + if s.IsTombstone() { + continue + } + if i == 0 { + v, err := ParseVersion(s.GetVersion()) + if err != nil { + log.Fatalf("on change cluster version meet error: %s", err) + } + minVersion = v + continue + } + v, err := ParseVersion(s.GetVersion()) + if err != nil { + log.Fatalf("on change cluster version: %s", err) + } + if minVersion.Less(v) { + minVersion = v + } + } + if clusterVersion.Less(minVersion) { + c.opt.SetClusterVersion(&minVersion) + log.Info("cluster upgrade finished: version changed from %s to %s", clusterVersion, minVersion) + } +} + func (c *clusterInfo) allocID() (uint64, error) { return c.id.Alloc() } diff --git a/server/version.go b/server/version.go index cdd0485a9a0..f10e9a60125 100644 --- a/server/version.go +++ b/server/version.go @@ -33,7 +33,7 @@ type Version struct { } // Less compare two version. -func (v *Version) Less(ov Version) bool { +func (v *Version) Less(ov *Version) bool { if v.Marjor < ov.Marjor { return true } else if v.Minor < ov.Minor { From efc59f1c19ae737a08b4399b1f3ee8980b2e9467 Mon Sep 17 00:00:00 2001 From: nolouch Date: Fri, 13 Jul 2018 02:18:59 +0800 Subject: [PATCH 05/30] use cluster version to switch new feature --- server/cluster.go | 2 +- server/cluster_info.go | 14 +++++++++++++- server/cluster_version.go | 3 +-- server/coordinator.go | 2 +- server/grpc_service.go | 9 --------- server/version.go | 30 +++++++++++++++++++++++++++--- 6 files changed, 43 insertions(+), 17 deletions(-) diff --git a/server/cluster.go b/server/cluster.go index 8ae1d759dde..dc85f19dd12 100644 --- a/server/cluster.go +++ b/server/cluster.go @@ -295,7 +295,7 @@ func (c *RaftCluster) putStore(store *metapb.Store) error { return errors.Errorf("invalid put store %s", err) } clusterVersion := c.cachedCluster.opt.loadClusterVersion() - if v.Less(clusterVersion) { + if v.Less(*clusterVersion) { return errors.Errorf("version should be %s, got %s", clusterVersion) } diff --git a/server/cluster_info.go b/server/cluster_info.go index f9fdc5cddf8..b875c9aea0c 100644 --- a/server/cluster_info.go +++ b/server/cluster_info.go @@ -79,7 +79,6 @@ func loadClusterInfo(id core.IDAllocator, kv *core.KV, opt *scheduleOption) (*cl } func (c *clusterInfo) OnChangeClusterVersion() { - var ( minVersion Version clusterVersion Version @@ -113,6 +112,16 @@ func (c *clusterInfo) OnChangeClusterVersion() { } } +// IsSupport check if support the features. +func (c *clusterInfo) IsSupport(f VersionFeature) bool { + clusterVersion := c.opt.loadClusterVersion() + minSupportVersion := TargetVersion(f) + if clusterVersion.Less(minSupportVersion) { + return false + } + return true +} + func (c *clusterInfo) allocID() (uint64, error) { return c.id.Alloc() } @@ -653,6 +662,9 @@ func (c *clusterInfo) GetHotRegionLowThreshold() int { } func (c *clusterInfo) IsRaftLearnerEnabled() bool { + if !c.IsSupport(VersionRegionMergeAndRaftLearner) { + return false + } return c.opt.IsRaftLearnerEnabled() } diff --git a/server/cluster_version.go b/server/cluster_version.go index 8424ff6fb0a..53261afe521 100644 --- a/server/cluster_version.go +++ b/server/cluster_version.go @@ -10,6 +10,5 @@ // distributed under the License is distributed on an "AS IS" BASIS, // See the License for the specific language governing permissions and // limitations under the License. -package server -type ClusterVersion struct{} +package server diff --git a/server/coordinator.go b/server/coordinator.go index 959c6b45aa2..10b877b0424 100644 --- a/server/coordinator.go +++ b/server/coordinator.go @@ -178,7 +178,7 @@ func (c *coordinator) checkRegion(region *core.RegionInfo) bool { return true } } - if c.limiter.OperatorCount(schedule.OpReplica) < c.cluster.GetReplicaScheduleLimit() { + if c.cluster.IsSupport(VersionRegionMergeAndRaftLearner) && c.limiter.OperatorCount(schedule.OpReplica) < c.cluster.GetReplicaScheduleLimit() { if op := c.replicaChecker.Check(region); op != nil { if c.addOperator(op) { return true diff --git a/server/grpc_service.go b/server/grpc_service.go index 374393338d7..f25f0c1b839 100644 --- a/server/grpc_service.go +++ b/server/grpc_service.go @@ -532,15 +532,6 @@ func (s *Server) validateRequest(header *pdpb.RequestHeader) error { if !s.IsLeader() { return notLeaderError } - requireVersion, err := ParseVersion(header.GetRequireMinVersion()) - if err != nil { - return grpc.Errorf(codes.FailedPrecondition, "Header meet error: %s", err.Error()) - } - clusterVersion := s.GetConfig().ClusterVersion - if clusterVersion.Less(requireVersion) { - return grpc.Errorf(codes.FailedPrecondition, "require version is %s, but now cluster version is %d", requireVersion, clusterVersion) - - } if header.GetClusterId() != s.clusterID { return grpc.Errorf(codes.FailedPrecondition, "mismatch cluster id, need %d but got %d", s.clusterID, header.GetClusterId()) } diff --git a/server/version.go b/server/version.go index f10e9a60125..28cd53ed632 100644 --- a/server/version.go +++ b/server/version.go @@ -10,6 +10,7 @@ // distributed under the License is distributed on an "AS IS" BASIS, // See the License for the specific language governing permissions and // limitations under the License. + package server import ( @@ -18,10 +19,33 @@ import ( "strings" "github.com/juju/errors" + log "github.com/sirupsen/logrus" +) + +// VersionFeature is a unique identifier for minimum support version. +type VersionFeature int + +// Version Fetures. +const ( + VersionBase VersionFeature = iota + VersionRegionMergeAndRaftLearner + VersionBatchSplit ) -// VersionBase is the empty version -var VersionBase = Version{Marjor: 1} +var featuresDict = map[VersionFeature]Version{ + VersionBase: Version{Marjor: 1}, + VersionRegionMergeAndRaftLearner: Version{Marjor: 2, Minor: 0}, + VersionBatchSplit: Version{Marjor: 2, Minor: 1}, +} + +// TargetVersion get target version by version featrue +func TargetVersion(v VersionFeature) Version { + target, ok := featuresDict[v] + if !ok { + log.Fatalf("version not exist, feature %d", v) + } + return target +} // Version record version information. type Version struct { @@ -33,7 +57,7 @@ type Version struct { } // Less compare two version. -func (v *Version) Less(ov *Version) bool { +func (v *Version) Less(ov Version) bool { if v.Marjor < ov.Marjor { return true } else if v.Minor < ov.Minor { From 726ef071eb987185c5ef8bdc71d8fe875cdb8621 Mon Sep 17 00:00:00 2001 From: nolouch Date: Fri, 13 Jul 2018 07:23:03 +0800 Subject: [PATCH 06/30] add tests --- pkg/integration_test/cluster.go | 6 + pkg/integration_test/version_upgrade_test.go | 153 ++++++++++++++++++ server/api/label_test.go | 4 + server/api/operator_test.go | 1 + server/api/store_test.go | 4 + server/cluster.go | 5 +- server/cluster_info.go | 9 +- server/config.go | 2 +- server/coordinator_test.go | 1 + server/core/kv.go | 1 + server/core/store.go | 1 - server/grpc_service.go | 1 + server/option.go | 12 +- server/server.go | 5 + server/version.go | 59 ++++--- .../{cluster_version.go => version_test.go} | 28 ++++ 16 files changed, 248 insertions(+), 44 deletions(-) create mode 100644 pkg/integration_test/version_upgrade_test.go rename server/{cluster_version.go => version_test.go} (54%) diff --git a/pkg/integration_test/cluster.go b/pkg/integration_test/cluster.go index a1270d5795c..d22655cc3eb 100644 --- a/pkg/integration_test/cluster.go +++ b/pkg/integration_test/cluster.go @@ -116,6 +116,12 @@ func (s *testServer) GetClusterID() uint64 { return s.server.ClusterID() } +func (s *testServer) GetClusterVersion() server.Version { + s.RLock() + defer s.RUnlock() + return s.server.ClusterVersion() +} + func (s *testServer) GetServerID() uint64 { s.RLock() defer s.RUnlock() diff --git a/pkg/integration_test/version_upgrade_test.go b/pkg/integration_test/version_upgrade_test.go new file mode 100644 index 00000000000..1afbfda50d3 --- /dev/null +++ b/pkg/integration_test/version_upgrade_test.go @@ -0,0 +1,153 @@ +// Copyright 2018 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// See the License for the specific language governing permissions and +// limitations under the License. + +package integration + +import ( + "context" + + . "github.com/pingcap/check" + "github.com/pingcap/kvproto/pkg/metapb" + "github.com/pingcap/kvproto/pkg/pdpb" + "github.com/pingcap/pd/server" +) + +var _ = Suite(&versionTestSuite{}) + +type versionTestSuite struct{} + +func (s *versionTestSuite) SetUpSuite(c *C) { + server.EnableZap = true +} + +func (s *versionTestSuite) bootstrapCluster(server *testServer, c *C) { + bootstrapReq := &pdpb.BootstrapRequest{ + Header: &pdpb.RequestHeader{ClusterId: server.GetClusterID()}, + Store: &metapb.Store{Id: 1, Address: "mock://1"}, + Region: &metapb.Region{Id: 2, Peers: []*metapb.Peer{{3, 1, false}}}, + } + _, err := server.server.Bootstrap(context.Background(), bootstrapReq) + c.Assert(err, IsNil) +} + +func (s *versionTestSuite) TestStoreRegister(c *C) { + c.Parallel() + cluster, err := newTestCluster(3) + c.Assert(err, IsNil) + defer cluster.Destory() + + err = cluster.RunInitialServers() + c.Assert(err, IsNil) + cluster.WaitLeader() + leaderServer := cluster.GetServer(cluster.GetLeader()) + s.bootstrapCluster(leaderServer, c) + + putStoreRequest := &pdpb.PutStoreRequest{ + Header: &pdpb.RequestHeader{ClusterId: leaderServer.GetClusterID()}, + Store: &metapb.Store{ + Id: 1, + Address: "mock-1", + Version: "v2.0.1", + }, + } + _, err = leaderServer.server.PutStore(context.Background(), putStoreRequest) + c.Assert(err, IsNil) + // FIX ME: read v0.0.0 in sometime + cluster.WaitLeader() + version := leaderServer.GetClusterVersion() + // Restart all PDs. + err = cluster.StopAll() + c.Assert(err, IsNil) + err = cluster.RunInitialServers() + c.Assert(err, IsNil) + cluster.WaitLeader() + + leaderServer = cluster.GetServer(cluster.GetLeader()) + newVersion := leaderServer.GetClusterVersion() + c.Assert(version, Equals, newVersion) + + // putNewStore with old version + putStoreRequest = &pdpb.PutStoreRequest{ + Header: &pdpb.RequestHeader{ClusterId: leaderServer.GetClusterID()}, + Store: &metapb.Store{ + Id: 4, + Address: "mock-4", + Version: "v1.0.1", + }, + } + _, err = leaderServer.server.PutStore(context.Background(), putStoreRequest) + c.Assert(err, NotNil) +} + +func (s *versionTestSuite) TestRollingUpgrade(c *C) { + c.Parallel() + cluster, err := newTestCluster(3) + c.Assert(err, IsNil) + defer cluster.Destory() + err = cluster.RunInitialServers() + c.Assert(err, IsNil) + cluster.WaitLeader() + leaderServer := cluster.GetServer(cluster.GetLeader()) + s.bootstrapCluster(leaderServer, c) + + stores := []*pdpb.PutStoreRequest{ + { + Header: &pdpb.RequestHeader{ClusterId: leaderServer.GetClusterID()}, + Store: &metapb.Store{ + Id: 1, + Address: "mock-1", + Version: "v2.0.1", + }, + }, + { + Header: &pdpb.RequestHeader{ClusterId: leaderServer.GetClusterID()}, + Store: &metapb.Store{ + Id: 4, + Address: "mock-4", + Version: "v2.0.1", + }, + }, + { + Header: &pdpb.RequestHeader{ClusterId: leaderServer.GetClusterID()}, + Store: &metapb.Store{ + Id: 6, + Address: "mock-6", + Version: "v2.0.1", + }, + }, + { + Header: &pdpb.RequestHeader{ClusterId: leaderServer.GetClusterID()}, + Store: &metapb.Store{ + Id: 7, + Address: "mock-7", + Version: "v2.0.1", + }, + }, + } + for _, store := range stores { + _, err = leaderServer.server.PutStore(context.Background(), store) + c.Assert(err, IsNil) + } + c.Assert(leaderServer.GetClusterVersion(), Equals, server.Version{Marjor: 2, Minor: 0, Patch: 1}) + // rolling update + for i, store := range stores { + store.Store.Version = "v2.1.0" + resp, err := leaderServer.server.PutStore(context.Background(), store) + c.Assert(err, IsNil) + if i != len(stores)-1 { + c.Assert(leaderServer.GetClusterVersion(), Equals, server.Version{Marjor: 2, Minor: 0, Patch: 1}) + c.Assert(resp.GetHeader().GetError(), IsNil) + } + } + c.Assert(leaderServer.GetClusterVersion(), Equals, server.Version{Marjor: 2, Minor: 1}) +} diff --git a/server/api/label_test.go b/server/api/label_test.go index 62fba9622a8..4738f5abafc 100644 --- a/server/api/label_test.go +++ b/server/api/label_test.go @@ -46,6 +46,7 @@ func (s *testLabelsStoreSuite) SetUpSuite(c *C) { Value: "ssd", }, }, + Version: "v2.0.0", }, { Id: 4, @@ -61,6 +62,7 @@ func (s *testLabelsStoreSuite) SetUpSuite(c *C) { Value: "hdd", }, }, + Version: "v2.0.0", }, { Id: 6, @@ -76,6 +78,7 @@ func (s *testLabelsStoreSuite) SetUpSuite(c *C) { Value: "ssd", }, }, + Version: "v2.0.0", }, { Id: 7, @@ -95,6 +98,7 @@ func (s *testLabelsStoreSuite) SetUpSuite(c *C) { Value: "test", }, }, + Version: "v2.0.0", }, } diff --git a/server/api/operator_test.go b/server/api/operator_test.go index 966c9dcbd23..a135a6606f1 100644 --- a/server/api/operator_test.go +++ b/server/api/operator_test.go @@ -87,6 +87,7 @@ func mustPutStore(c *C, svr *server.Server, id uint64, state metapb.StoreState, Address: fmt.Sprintf("tikv%d", id), State: state, Labels: labels, + Version: server.TargetVersion(server.VersionRegionMergeAndRaftLearner).String(), }, }) c.Assert(err, IsNil) diff --git a/server/api/store_test.go b/server/api/store_test.go index d2a8eaf58e5..d733fb40e97 100644 --- a/server/api/store_test.go +++ b/server/api/store_test.go @@ -44,23 +44,27 @@ func (s *testStoreSuite) SetUpSuite(c *C) { Id: 1, Address: "tikv1", State: metapb.StoreState_Up, + Version: "v2.0.0", }, { Id: 4, Address: "tikv4", State: metapb.StoreState_Up, + Version: "v2.0.0", }, { // metapb.StoreState_Offline == 1 Id: 6, Address: "tikv6", State: metapb.StoreState_Offline, + Version: "v2.0.0", }, { // metapb.StoreState_Tombstone == 2 Id: 7, Address: "tikv7", State: metapb.StoreState_Tombstone, + Version: "v2.0.0", }, } diff --git a/server/cluster.go b/server/cluster.go index dc85f19dd12..f0ac7eace21 100644 --- a/server/cluster.go +++ b/server/cluster.go @@ -295,8 +295,8 @@ func (c *RaftCluster) putStore(store *metapb.Store) error { return errors.Errorf("invalid put store %s", err) } clusterVersion := c.cachedCluster.opt.loadClusterVersion() - if v.Less(*clusterVersion) { - return errors.Errorf("version should be %s, got %s", clusterVersion) + if v.Less(clusterVersion) { + return errors.Errorf("version should compatible with version %s, got %s", clusterVersion, v) } cluster := c.cachedCluster @@ -322,7 +322,6 @@ func (c *RaftCluster) putStore(store *metapb.Store) error { s.Version = store.Version s.MergeLabels(store.Labels) } - // Check location labels. for _, k := range c.cachedCluster.GetLocationLabels() { if v := s.GetLabelValue(k); len(v) == 0 { diff --git a/server/cluster_info.go b/server/cluster_info.go index b875c9aea0c..cd5a17712f1 100644 --- a/server/cluster_info.go +++ b/server/cluster_info.go @@ -84,7 +84,7 @@ func (c *clusterInfo) OnChangeClusterVersion() { clusterVersion Version ) - clusterVersion = *c.opt.loadClusterVersion() + clusterVersion = c.opt.loadClusterVersion() stores := c.GetStores() for i, s := range stores { if s.IsTombstone() { @@ -102,13 +102,14 @@ func (c *clusterInfo) OnChangeClusterVersion() { if err != nil { log.Fatalf("on change cluster version: %s", err) } - if minVersion.Less(v) { + if v.Less(minVersion) { minVersion = v } } if clusterVersion.Less(minVersion) { - c.opt.SetClusterVersion(&minVersion) - log.Info("cluster upgrade finished: version changed from %s to %s", clusterVersion, minVersion) + c.opt.SetClusterVersion(minVersion) + c.opt.persist(c.kv) + log.Infof("cluster version changed from %s to %s", clusterVersion, minVersion) } } diff --git a/server/config.go b/server/config.go index 992324f7b58..1275d6d04e1 100644 --- a/server/config.go +++ b/server/config.go @@ -77,7 +77,7 @@ type Config struct { Namespace map[string]NamespaceConfig `json:"namespace"` - ClusterVersion Version `json:"cluster_version"` + ClusterVersion Version `json:"cluster-version"` // QuotaBackendBytes Raise alarms when backend size exceeds the given quota. 0 means use the default quota. // the default size is 2GB, the maximum is 8GB. diff --git a/server/coordinator_test.go b/server/coordinator_test.go index 5aeefcba832..b0d3b8b181d 100644 --- a/server/coordinator_test.go +++ b/server/coordinator_test.go @@ -38,6 +38,7 @@ func newTestScheduleConfig() (*ScheduleConfig, *scheduleOption) { cfg := NewConfig() cfg.adjust(nil) opt := newScheduleOption(cfg) + opt.SetClusterVersion(TargetVersion(VersionRegionMergeAndRaftLearner)) return &cfg.Schedule, opt } diff --git a/server/core/kv.go b/server/core/kv.go index deff43f9fdf..bd2f7e4b997 100644 --- a/server/core/kv.go +++ b/server/core/kv.go @@ -107,6 +107,7 @@ func (kv *KV) DeleteRegion(region *metapb.Region) error { // SaveConfig stores marshalable cfg to the configPath. func (kv *KV) SaveConfig(cfg interface{}) error { value, err := json.Marshal(cfg) + fmt.Println("pesist config:", string(value)) if err != nil { return errors.Trace(err) } diff --git a/server/core/store.go b/server/core/store.go index dca552782d7..660e3827ff3 100644 --- a/server/core/store.go +++ b/server/core/store.go @@ -41,7 +41,6 @@ type StoreInfo struct { LeaderWeight float64 RegionWeight float64 RollingStoreStats *RollingStoreStats - Version string } // NewStoreInfo creates StoreInfo with meta data. diff --git a/server/grpc_service.go b/server/grpc_service.go index f25f0c1b839..3136784d24d 100644 --- a/server/grpc_service.go +++ b/server/grpc_service.go @@ -218,6 +218,7 @@ func (s *Server) PutStore(ctx context.Context, request *pdpb.PutStoreRequest) (* } log.Infof("put store ok - %v", store) + cluster.cachedCluster.OnChangeClusterVersion() return &pdpb.PutStoreResponse{ Header: s.header(), diff --git a/server/option.go b/server/option.go index 1c65fac1ac4..115a95e4c92 100644 --- a/server/option.go +++ b/server/option.go @@ -43,6 +43,7 @@ func newScheduleOption(cfg *Config) *scheduleOption { } o.rep = newReplication(&cfg.Replication) o.labelProperty.Store(cfg.LabelProperty) + o.clusterVersion.Store(cfg.ClusterVersion) return o } @@ -226,12 +227,12 @@ func (o *scheduleOption) loadLabelPropertyConfig() LabelPropertyConfig { return o.labelProperty.Load().(LabelPropertyConfig) } -func (o *scheduleOption) SetClusterVersion(v *Version) { +func (o *scheduleOption) SetClusterVersion(v Version) { o.clusterVersion.Store(v) } -func (o *scheduleOption) loadClusterVersion() *Version { - return o.clusterVersion.Load().(*Version) +func (o *scheduleOption) loadClusterVersion() Version { + return o.clusterVersion.Load().(Version) } func (o *scheduleOption) persist(kv *core.KV) error { @@ -244,7 +245,7 @@ func (o *scheduleOption) persist(kv *core.KV) error { Replication: *o.rep.load(), Namespace: namespaces, LabelProperty: o.loadLabelPropertyConfig(), - ClusterVersion: *o.loadClusterVersion(), + ClusterVersion: o.loadClusterVersion(), } err := kv.SaveConfig(cfg) return errors.Trace(err) @@ -260,7 +261,7 @@ func (o *scheduleOption) reload(kv *core.KV) error { Replication: *o.rep.load(), Namespace: namespaces, LabelProperty: o.loadLabelPropertyConfig().clone(), - ClusterVersion: *o.loadClusterVersion(), + ClusterVersion: o.loadClusterVersion(), } isExist, err := kv.LoadConfig(cfg) if err != nil { @@ -275,6 +276,7 @@ func (o *scheduleOption) reload(kv *core.KV) error { o.ns[name] = newNamespaceOption(&nsCfg) } o.labelProperty.Store(cfg.LabelProperty) + o.clusterVersion.Store(cfg.ClusterVersion) } return nil } diff --git a/server/server.go b/server/server.go index b958da11ee7..45fd033820f 100644 --- a/server/server.go +++ b/server/server.go @@ -400,6 +400,11 @@ func (s *Server) ClusterID() uint64 { return s.clusterID } +// ClusterVersion returns the cluster version of this server. +func (s *Server) ClusterVersion() Version { + return s.scheduleOpt.loadClusterVersion() +} + // txn returns an etcd client transaction wrapper. // The wrapper will set a request timeout to the context and log slow transactions. func (s *Server) txn() clientv3.Txn { diff --git a/server/version.go b/server/version.go index 28cd53ed632..4206572ec25 100644 --- a/server/version.go +++ b/server/version.go @@ -33,9 +33,9 @@ const ( ) var featuresDict = map[VersionFeature]Version{ - VersionBase: Version{Marjor: 1}, - VersionRegionMergeAndRaftLearner: Version{Marjor: 2, Minor: 0}, - VersionBatchSplit: Version{Marjor: 2, Minor: 1}, + VersionBase: {Marjor: 1}, + VersionRegionMergeAndRaftLearner: {Marjor: 2, Minor: 0}, + VersionBatchSplit: {Marjor: 2, Minor: 1}, } // TargetVersion get target version by version featrue @@ -60,19 +60,31 @@ type Version struct { func (v *Version) Less(ov Version) bool { if v.Marjor < ov.Marjor { return true - } else if v.Minor < ov.Minor { + } else if v.Marjor > ov.Marjor { + return false + } + if v.Minor < ov.Minor { return true - } else if v.Patch < ov.Patch { + } else if v.Minor > ov.Minor { + return false + } + if v.Patch < ov.Patch { return true - } else if v.Unstable < ov.Unstable { + } else if v.Patch > ov.Patch { + return false + } + if v.Unstable < ov.Unstable { return true - } else if v.UnstablePatch < ov.UnstablePatch { + } else if v.Unstable > ov.Unstable { + return false + } + if v.UnstablePatch < ov.UnstablePatch { return true } return false } -func (v *Version) String() string { +func (v Version) String() string { convMap := map[int32]string{ 1: "alpha", 2: "beta", @@ -80,13 +92,13 @@ func (v *Version) String() string { } var res string if unstable, ok := convMap[v.Unstable]; ok { - res = fmt.Sprintf("%d.%d.%d-%s", v.Marjor, v.Minor, v.Patch, unstable) + res = fmt.Sprintf("v%d.%d.%d-%s", v.Marjor, v.Minor, v.Patch, unstable) if v.UnstablePatch > 0 { res = fmt.Sprintf("%s.%d", res, v.UnstablePatch) } return res } - res = fmt.Sprintf("%d.%d.%d", v.Marjor, v.Minor, v.Patch) + res = fmt.Sprintf("v%d.%d.%d", v.Marjor, v.Minor, v.Patch) return res } @@ -105,6 +117,12 @@ func convUnstable(s string) int32 { //ParseVersion parses a version from a string. //The string format should be "major.minor.patch-". func ParseVersion(s string) (Version, error) { + if s == "" { + return TargetVersion(VersionBase), nil + } + if strings.HasPrefix(s, "v") { + s = s[1:] + } splits := strings.Split(s, ".") if len(splits) != 3 && len(splits) != 4 { return Version{}, errors.Errorf("invalid version: %s", s) @@ -120,7 +138,7 @@ func ParseVersion(s string) (Version, error) { } ints := make([]int32, len(parts)) for i, part := range parts { - if i == 4 && part != "0" { + if i == 3 && part != "0" { r := convUnstable(part) if r < 0 { return Version{}, errors.Errorf("invalid version: %s ", s) @@ -145,22 +163,3 @@ func ParseVersion(s string) (Version, error) { UnstablePatch: ints[4], }, nil } - -// MarshalJSON returns the version as a JSON string. -func (v *Version) MarshalJSON() ([]byte, error) { - return []byte(v.String()), nil -} - -// UnmarshalJSON parses a JSON string into the version. -func (v *Version) UnmarshalJSON(text []byte) error { - s, err := strconv.Unquote(string(text)) - if err != nil { - return errors.Trace(err) - } - version, err := ParseVersion(s) - if err != nil { - return errors.Trace(err) - } - *v = version - return nil -} diff --git a/server/cluster_version.go b/server/version_test.go similarity index 54% rename from server/cluster_version.go rename to server/version_test.go index 53261afe521..810dae26ee4 100644 --- a/server/cluster_version.go +++ b/server/version_test.go @@ -12,3 +12,31 @@ // limitations under the License. package server + +import ( + . "github.com/pingcap/check" +) + +var _ = Suite(&testVersion{}) + +type testVersion struct{} + +func (t *testVersion) TestVersion(c *C) { + vers := []string{ + "", + "v1.0.1", + "v1.0.1-beta", + "v2.0.1", + "2.1.0", + } + var ( + lastVersion Version + newVersion Version + err error + ) + for _, ver := range vers { + newVersion, err = ParseVersion(ver) + c.Assert(err, IsNil) + c.Assert(lastVersion.Less(newVersion), IsTrue) + } +} From 3178fae54930520fdb3c7d9b5b6f8be550541e46 Mon Sep 17 00:00:00 2001 From: nolouch Date: Fri, 13 Jul 2018 17:29:38 +0800 Subject: [PATCH 07/30] address comments --- pkg/integration_test/version_upgrade_test.go | 6 +++--- server/version.go | 20 ++++++++++---------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/pkg/integration_test/version_upgrade_test.go b/pkg/integration_test/version_upgrade_test.go index 1afbfda50d3..882fc710fe6 100644 --- a/pkg/integration_test/version_upgrade_test.go +++ b/pkg/integration_test/version_upgrade_test.go @@ -138,16 +138,16 @@ func (s *versionTestSuite) TestRollingUpgrade(c *C) { _, err = leaderServer.server.PutStore(context.Background(), store) c.Assert(err, IsNil) } - c.Assert(leaderServer.GetClusterVersion(), Equals, server.Version{Marjor: 2, Minor: 0, Patch: 1}) + c.Assert(leaderServer.GetClusterVersion(), Equals, server.Version{Major: 2, Minor: 0, Patch: 1}) // rolling update for i, store := range stores { store.Store.Version = "v2.1.0" resp, err := leaderServer.server.PutStore(context.Background(), store) c.Assert(err, IsNil) if i != len(stores)-1 { - c.Assert(leaderServer.GetClusterVersion(), Equals, server.Version{Marjor: 2, Minor: 0, Patch: 1}) + c.Assert(leaderServer.GetClusterVersion(), Equals, server.Version{Major: 2, Minor: 0, Patch: 1}) c.Assert(resp.GetHeader().GetError(), IsNil) } } - c.Assert(leaderServer.GetClusterVersion(), Equals, server.Version{Marjor: 2, Minor: 1}) + c.Assert(leaderServer.GetClusterVersion(), Equals, server.Version{Major: 2, Minor: 1}) } diff --git a/server/version.go b/server/version.go index 4206572ec25..23e4b2824db 100644 --- a/server/version.go +++ b/server/version.go @@ -33,12 +33,12 @@ const ( ) var featuresDict = map[VersionFeature]Version{ - VersionBase: {Marjor: 1}, - VersionRegionMergeAndRaftLearner: {Marjor: 2, Minor: 0}, - VersionBatchSplit: {Marjor: 2, Minor: 1}, + VersionBase: {Major: 1}, + VersionRegionMergeAndRaftLearner: {Major: 2, Minor: 0}, + VersionBatchSplit: {Major: 2, Minor: 1}, } -// TargetVersion get target version by version featrue +// TargetVersion get target version by version feature func TargetVersion(v VersionFeature) Version { target, ok := featuresDict[v] if !ok { @@ -49,7 +49,7 @@ func TargetVersion(v VersionFeature) Version { // Version record version information. type Version struct { - Marjor int32 + Major int32 Minor int32 Patch int32 Unstable int32 @@ -58,9 +58,9 @@ type Version struct { // Less compare two version. func (v *Version) Less(ov Version) bool { - if v.Marjor < ov.Marjor { + if v.Major < ov.Major { return true - } else if v.Marjor > ov.Marjor { + } else if v.Major > ov.Major { return false } if v.Minor < ov.Minor { @@ -92,13 +92,13 @@ func (v Version) String() string { } var res string if unstable, ok := convMap[v.Unstable]; ok { - res = fmt.Sprintf("v%d.%d.%d-%s", v.Marjor, v.Minor, v.Patch, unstable) + res = fmt.Sprintf("v%d.%d.%d-%s", v.Major, v.Minor, v.Patch, unstable) if v.UnstablePatch > 0 { res = fmt.Sprintf("%s.%d", res, v.UnstablePatch) } return res } - res = fmt.Sprintf("v%d.%d.%d", v.Marjor, v.Minor, v.Patch) + res = fmt.Sprintf("v%d.%d.%d", v.Major, v.Minor, v.Patch) return res } @@ -156,7 +156,7 @@ func ParseVersion(s string) (Version, error) { ints[i] = int32(val) } return Version{ - Marjor: ints[0], + Major: ints[0], Minor: ints[1], Patch: ints[2], Unstable: ints[3], From cbe6d32f4d9c8b2625e26ac067c3335ca6f30036 Mon Sep 17 00:00:00 2001 From: nolouch Date: Fri, 13 Jul 2018 17:36:28 +0800 Subject: [PATCH 08/30] update proto --- Gopkg.lock | 2 +- .../pingcap/kvproto/pkg/pdpb/pdpb.pb.go | 1190 ++++++++++++----- 2 files changed, 891 insertions(+), 301 deletions(-) diff --git a/Gopkg.lock b/Gopkg.lock index 69f76fa7287..e6857057b8d 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -260,7 +260,7 @@ "pkg/metapb", "pkg/pdpb" ] - revision = "87f65f4fd97bef9f23fa2821da1bd019d9592928" + revision = "7e27708b456d3d668fe68f774c86d50d7bdacc30" source = "https://github.com/nolouch/kvproto" [[projects]] diff --git a/vendor/github.com/pingcap/kvproto/pkg/pdpb/pdpb.pb.go b/vendor/github.com/pingcap/kvproto/pkg/pdpb/pdpb.pb.go index 09ebf73d666..555d2554645 100644 --- a/vendor/github.com/pingcap/kvproto/pkg/pdpb/pdpb.pb.go +++ b/vendor/github.com/pingcap/kvproto/pkg/pdpb/pdpb.pb.go @@ -53,6 +53,10 @@ StoreHeartbeatResponse ScatterRegionRequest ScatterRegionResponse + GetGCSafePointRequest + GetGCSafePointResponse + UpdateGCSafePointRequest + UpdateGCSafePointResponse */ package pdpb @@ -115,9 +119,7 @@ func (ErrorType) EnumDescriptor() ([]byte, []int) { return fileDescriptorPdpb, [ type RequestHeader struct { // cluster_id is the ID of the cluster which be sent to. - ClusterId uint64 `protobuf:"varint,1,opt,name=cluster_id,json=clusterId,proto3" json:"cluster_id,omitempty"` - Version string `protobuf:"bytes,2,opt,name=version,proto3" json:"version,omitempty"` - RequireMinVersion string `protobuf:"bytes,3,opt,name=require_min_version,json=requireMinVersion,proto3" json:"require_min_version,omitempty"` + ClusterId uint64 `protobuf:"varint,1,opt,name=cluster_id,json=clusterId,proto3" json:"cluster_id,omitempty"` } func (m *RequestHeader) Reset() { *m = RequestHeader{} } @@ -132,25 +134,10 @@ func (m *RequestHeader) GetClusterId() uint64 { return 0 } -func (m *RequestHeader) GetVersion() string { - if m != nil { - return m.Version - } - return "" -} - -func (m *RequestHeader) GetRequireMinVersion() string { - if m != nil { - return m.RequireMinVersion - } - return "" -} - type ResponseHeader struct { // cluster_id is the ID of the cluster which sent the response. - ClusterId uint64 `protobuf:"varint,1,opt,name=cluster_id,json=clusterId,proto3" json:"cluster_id,omitempty"` - Error *Error `protobuf:"bytes,2,opt,name=error" json:"error,omitempty"` - ClusterVersion string `protobuf:"bytes,3,opt,name=cluster_version,json=clusterVersion,proto3" json:"cluster_version,omitempty"` + ClusterId uint64 `protobuf:"varint,1,opt,name=cluster_id,json=clusterId,proto3" json:"cluster_id,omitempty"` + Error *Error `protobuf:"bytes,2,opt,name=error" json:"error,omitempty"` } func (m *ResponseHeader) Reset() { *m = ResponseHeader{} } @@ -172,13 +159,6 @@ func (m *ResponseHeader) GetError() *Error { return nil } -func (m *ResponseHeader) GetClusterVersion() string { - if m != nil { - return m.ClusterVersion - } - return "" -} - type Error struct { Type ErrorType `protobuf:"varint,1,opt,name=type,proto3,enum=pdpb.ErrorType" json:"type,omitempty"` Message string `protobuf:"bytes,2,opt,name=message,proto3" json:"message,omitempty"` @@ -849,8 +829,8 @@ type RegionHeartbeatRequest struct { ApproximateSize uint64 `protobuf:"varint,10,opt,name=approximate_size,json=approximateSize,proto3" json:"approximate_size,omitempty"` // Actually reported time interval Interval *TimeInterval `protobuf:"bytes,12,opt,name=interval" json:"interval,omitempty"` - // Approximate number of records. - ApproximateRows uint64 `protobuf:"varint,13,opt,name=approximate_rows,json=approximateRows,proto3" json:"approximate_rows,omitempty"` + // Approximate number of keys. + ApproximateKeys uint64 `protobuf:"varint,13,opt,name=approximate_keys,json=approximateKeys,proto3" json:"approximate_keys,omitempty"` } func (m *RegionHeartbeatRequest) Reset() { *m = RegionHeartbeatRequest{} } @@ -935,9 +915,9 @@ func (m *RegionHeartbeatRequest) GetInterval() *TimeInterval { return nil } -func (m *RegionHeartbeatRequest) GetApproximateRows() uint64 { +func (m *RegionHeartbeatRequest) GetApproximateKeys() uint64 { if m != nil { - return m.ApproximateRows + return m.ApproximateKeys } return 0 } @@ -1470,6 +1450,94 @@ func (m *ScatterRegionResponse) GetHeader() *ResponseHeader { return nil } +type GetGCSafePointRequest struct { + Header *RequestHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"` +} + +func (m *GetGCSafePointRequest) Reset() { *m = GetGCSafePointRequest{} } +func (m *GetGCSafePointRequest) String() string { return proto.CompactTextString(m) } +func (*GetGCSafePointRequest) ProtoMessage() {} +func (*GetGCSafePointRequest) Descriptor() ([]byte, []int) { return fileDescriptorPdpb, []int{45} } + +func (m *GetGCSafePointRequest) GetHeader() *RequestHeader { + if m != nil { + return m.Header + } + return nil +} + +type GetGCSafePointResponse struct { + Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"` + SafePoint uint64 `protobuf:"varint,2,opt,name=safe_point,json=safePoint,proto3" json:"safe_point,omitempty"` +} + +func (m *GetGCSafePointResponse) Reset() { *m = GetGCSafePointResponse{} } +func (m *GetGCSafePointResponse) String() string { return proto.CompactTextString(m) } +func (*GetGCSafePointResponse) ProtoMessage() {} +func (*GetGCSafePointResponse) Descriptor() ([]byte, []int) { return fileDescriptorPdpb, []int{46} } + +func (m *GetGCSafePointResponse) GetHeader() *ResponseHeader { + if m != nil { + return m.Header + } + return nil +} + +func (m *GetGCSafePointResponse) GetSafePoint() uint64 { + if m != nil { + return m.SafePoint + } + return 0 +} + +type UpdateGCSafePointRequest struct { + Header *RequestHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"` + SafePoint uint64 `protobuf:"varint,2,opt,name=safe_point,json=safePoint,proto3" json:"safe_point,omitempty"` +} + +func (m *UpdateGCSafePointRequest) Reset() { *m = UpdateGCSafePointRequest{} } +func (m *UpdateGCSafePointRequest) String() string { return proto.CompactTextString(m) } +func (*UpdateGCSafePointRequest) ProtoMessage() {} +func (*UpdateGCSafePointRequest) Descriptor() ([]byte, []int) { return fileDescriptorPdpb, []int{47} } + +func (m *UpdateGCSafePointRequest) GetHeader() *RequestHeader { + if m != nil { + return m.Header + } + return nil +} + +func (m *UpdateGCSafePointRequest) GetSafePoint() uint64 { + if m != nil { + return m.SafePoint + } + return 0 +} + +type UpdateGCSafePointResponse struct { + Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"` + NewSafePoint uint64 `protobuf:"varint,2,opt,name=new_safe_point,json=newSafePoint,proto3" json:"new_safe_point,omitempty"` +} + +func (m *UpdateGCSafePointResponse) Reset() { *m = UpdateGCSafePointResponse{} } +func (m *UpdateGCSafePointResponse) String() string { return proto.CompactTextString(m) } +func (*UpdateGCSafePointResponse) ProtoMessage() {} +func (*UpdateGCSafePointResponse) Descriptor() ([]byte, []int) { return fileDescriptorPdpb, []int{48} } + +func (m *UpdateGCSafePointResponse) GetHeader() *ResponseHeader { + if m != nil { + return m.Header + } + return nil +} + +func (m *UpdateGCSafePointResponse) GetNewSafePoint() uint64 { + if m != nil { + return m.NewSafePoint + } + return 0 +} + func init() { proto.RegisterType((*RequestHeader)(nil), "pdpb.RequestHeader") proto.RegisterType((*ResponseHeader)(nil), "pdpb.ResponseHeader") @@ -1516,6 +1584,10 @@ func init() { proto.RegisterType((*StoreHeartbeatResponse)(nil), "pdpb.StoreHeartbeatResponse") proto.RegisterType((*ScatterRegionRequest)(nil), "pdpb.ScatterRegionRequest") proto.RegisterType((*ScatterRegionResponse)(nil), "pdpb.ScatterRegionResponse") + proto.RegisterType((*GetGCSafePointRequest)(nil), "pdpb.GetGCSafePointRequest") + proto.RegisterType((*GetGCSafePointResponse)(nil), "pdpb.GetGCSafePointResponse") + proto.RegisterType((*UpdateGCSafePointRequest)(nil), "pdpb.UpdateGCSafePointRequest") + proto.RegisterType((*UpdateGCSafePointResponse)(nil), "pdpb.UpdateGCSafePointResponse") proto.RegisterEnum("pdpb.ErrorType", ErrorType_name, ErrorType_value) } @@ -1549,6 +1621,8 @@ type PDClient interface { GetClusterConfig(ctx context.Context, in *GetClusterConfigRequest, opts ...grpc.CallOption) (*GetClusterConfigResponse, error) PutClusterConfig(ctx context.Context, in *PutClusterConfigRequest, opts ...grpc.CallOption) (*PutClusterConfigResponse, error) ScatterRegion(ctx context.Context, in *ScatterRegionRequest, opts ...grpc.CallOption) (*ScatterRegionResponse, error) + GetGCSafePoint(ctx context.Context, in *GetGCSafePointRequest, opts ...grpc.CallOption) (*GetGCSafePointResponse, error) + UpdateGCSafePoint(ctx context.Context, in *UpdateGCSafePointRequest, opts ...grpc.CallOption) (*UpdateGCSafePointResponse, error) } type pDClient struct { @@ -1756,6 +1830,24 @@ func (c *pDClient) ScatterRegion(ctx context.Context, in *ScatterRegionRequest, return out, nil } +func (c *pDClient) GetGCSafePoint(ctx context.Context, in *GetGCSafePointRequest, opts ...grpc.CallOption) (*GetGCSafePointResponse, error) { + out := new(GetGCSafePointResponse) + err := grpc.Invoke(ctx, "/pdpb.PD/GetGCSafePoint", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *pDClient) UpdateGCSafePoint(ctx context.Context, in *UpdateGCSafePointRequest, opts ...grpc.CallOption) (*UpdateGCSafePointResponse, error) { + out := new(UpdateGCSafePointResponse) + err := grpc.Invoke(ctx, "/pdpb.PD/UpdateGCSafePoint", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // Server API for PD service type PDServer interface { @@ -1778,6 +1870,8 @@ type PDServer interface { GetClusterConfig(context.Context, *GetClusterConfigRequest) (*GetClusterConfigResponse, error) PutClusterConfig(context.Context, *PutClusterConfigRequest) (*PutClusterConfigResponse, error) ScatterRegion(context.Context, *ScatterRegionRequest) (*ScatterRegionResponse, error) + GetGCSafePoint(context.Context, *GetGCSafePointRequest) (*GetGCSafePointResponse, error) + UpdateGCSafePoint(context.Context, *UpdateGCSafePointRequest) (*UpdateGCSafePointResponse, error) } func RegisterPDServer(s *grpc.Server, srv PDServer) { @@ -2106,6 +2200,42 @@ func _PD_ScatterRegion_Handler(srv interface{}, ctx context.Context, dec func(in return interceptor(ctx, in, info, handler) } +func _PD_GetGCSafePoint_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetGCSafePointRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(PDServer).GetGCSafePoint(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pdpb.PD/GetGCSafePoint", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(PDServer).GetGCSafePoint(ctx, req.(*GetGCSafePointRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _PD_UpdateGCSafePoint_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UpdateGCSafePointRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(PDServer).UpdateGCSafePoint(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pdpb.PD/UpdateGCSafePoint", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(PDServer).UpdateGCSafePoint(ctx, req.(*UpdateGCSafePointRequest)) + } + return interceptor(ctx, in, info, handler) +} + var _PD_serviceDesc = grpc.ServiceDesc{ ServiceName: "pdpb.PD", HandlerType: (*PDServer)(nil), @@ -2170,6 +2300,14 @@ var _PD_serviceDesc = grpc.ServiceDesc{ MethodName: "ScatterRegion", Handler: _PD_ScatterRegion_Handler, }, + { + MethodName: "GetGCSafePoint", + Handler: _PD_GetGCSafePoint_Handler, + }, + { + MethodName: "UpdateGCSafePoint", + Handler: _PD_UpdateGCSafePoint_Handler, + }, }, Streams: []grpc.StreamDesc{ { @@ -2208,18 +2346,6 @@ func (m *RequestHeader) MarshalTo(dAtA []byte) (int, error) { i++ i = encodeVarintPdpb(dAtA, i, uint64(m.ClusterId)) } - if len(m.Version) > 0 { - dAtA[i] = 0x12 - i++ - i = encodeVarintPdpb(dAtA, i, uint64(len(m.Version))) - i += copy(dAtA[i:], m.Version) - } - if len(m.RequireMinVersion) > 0 { - dAtA[i] = 0x1a - i++ - i = encodeVarintPdpb(dAtA, i, uint64(len(m.RequireMinVersion))) - i += copy(dAtA[i:], m.RequireMinVersion) - } return i, nil } @@ -2253,12 +2379,6 @@ func (m *ResponseHeader) MarshalTo(dAtA []byte) (int, error) { } i += n1 } - if len(m.ClusterVersion) > 0 { - dAtA[i] = 0x1a - i++ - i = encodeVarintPdpb(dAtA, i, uint64(len(m.ClusterVersion))) - i += copy(dAtA[i:], m.ClusterVersion) - } return i, nil } @@ -3339,10 +3459,10 @@ func (m *RegionHeartbeatRequest) MarshalTo(dAtA []byte) (int, error) { } i += n40 } - if m.ApproximateRows != 0 { + if m.ApproximateKeys != 0 { dAtA[i] = 0x68 i++ - i = encodeVarintPdpb(dAtA, i, uint64(m.ApproximateRows)) + i = encodeVarintPdpb(dAtA, i, uint64(m.ApproximateKeys)) } return i, nil } @@ -3989,6 +4109,133 @@ func (m *ScatterRegionResponse) MarshalTo(dAtA []byte) (int, error) { return i, nil } +func (m *GetGCSafePointRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *GetGCSafePointRequest) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Header != nil { + dAtA[i] = 0xa + i++ + i = encodeVarintPdpb(dAtA, i, uint64(m.Header.Size())) + n68, err := m.Header.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n68 + } + return i, nil +} + +func (m *GetGCSafePointResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *GetGCSafePointResponse) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Header != nil { + dAtA[i] = 0xa + i++ + i = encodeVarintPdpb(dAtA, i, uint64(m.Header.Size())) + n69, err := m.Header.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n69 + } + if m.SafePoint != 0 { + dAtA[i] = 0x10 + i++ + i = encodeVarintPdpb(dAtA, i, uint64(m.SafePoint)) + } + return i, nil +} + +func (m *UpdateGCSafePointRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *UpdateGCSafePointRequest) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Header != nil { + dAtA[i] = 0xa + i++ + i = encodeVarintPdpb(dAtA, i, uint64(m.Header.Size())) + n70, err := m.Header.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n70 + } + if m.SafePoint != 0 { + dAtA[i] = 0x10 + i++ + i = encodeVarintPdpb(dAtA, i, uint64(m.SafePoint)) + } + return i, nil +} + +func (m *UpdateGCSafePointResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *UpdateGCSafePointResponse) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Header != nil { + dAtA[i] = 0xa + i++ + i = encodeVarintPdpb(dAtA, i, uint64(m.Header.Size())) + n71, err := m.Header.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n71 + } + if m.NewSafePoint != 0 { + dAtA[i] = 0x10 + i++ + i = encodeVarintPdpb(dAtA, i, uint64(m.NewSafePoint)) + } + return i, nil +} + func encodeFixed64Pdpb(dAtA []byte, offset int, v uint64) int { dAtA[offset] = uint8(v) dAtA[offset+1] = uint8(v >> 8) @@ -4022,14 +4269,6 @@ func (m *RequestHeader) Size() (n int) { if m.ClusterId != 0 { n += 1 + sovPdpb(uint64(m.ClusterId)) } - l = len(m.Version) - if l > 0 { - n += 1 + l + sovPdpb(uint64(l)) - } - l = len(m.RequireMinVersion) - if l > 0 { - n += 1 + l + sovPdpb(uint64(l)) - } return n } @@ -4043,10 +4282,6 @@ func (m *ResponseHeader) Size() (n int) { l = m.Error.Size() n += 1 + l + sovPdpb(uint64(l)) } - l = len(m.ClusterVersion) - if l > 0 { - n += 1 + l + sovPdpb(uint64(l)) - } return n } @@ -4470,8 +4705,8 @@ func (m *RegionHeartbeatRequest) Size() (n int) { l = m.Interval.Size() n += 1 + l + sovPdpb(uint64(l)) } - if m.ApproximateRows != 0 { - n += 1 + sovPdpb(uint64(m.ApproximateRows)) + if m.ApproximateKeys != 0 { + n += 1 + sovPdpb(uint64(m.ApproximateKeys)) } return n } @@ -4733,25 +4968,74 @@ func (m *ScatterRegionResponse) Size() (n int) { return n } -func sovPdpb(x uint64) (n int) { - for { - n++ - x >>= 7 - if x == 0 { - break - } +func (m *GetGCSafePointRequest) Size() (n int) { + var l int + _ = l + if m.Header != nil { + l = m.Header.Size() + n += 1 + l + sovPdpb(uint64(l)) } return n } -func sozPdpb(x uint64) (n int) { - return sovPdpb(uint64((x << 1) ^ uint64((int64(x) >> 63)))) -} -func (m *RequestHeader) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 + +func (m *GetGCSafePointResponse) Size() (n int) { + var l int + _ = l + if m.Header != nil { + l = m.Header.Size() + n += 1 + l + sovPdpb(uint64(l)) + } + if m.SafePoint != 0 { + n += 1 + sovPdpb(uint64(m.SafePoint)) + } + return n +} + +func (m *UpdateGCSafePointRequest) Size() (n int) { + var l int + _ = l + if m.Header != nil { + l = m.Header.Size() + n += 1 + l + sovPdpb(uint64(l)) + } + if m.SafePoint != 0 { + n += 1 + sovPdpb(uint64(m.SafePoint)) + } + return n +} + +func (m *UpdateGCSafePointResponse) Size() (n int) { + var l int + _ = l + if m.Header != nil { + l = m.Header.Size() + n += 1 + l + sovPdpb(uint64(l)) + } + if m.NewSafePoint != 0 { + n += 1 + sovPdpb(uint64(m.NewSafePoint)) + } + return n +} + +func sovPdpb(x uint64) (n int) { + for { + n++ + x >>= 7 + if x == 0 { + break + } + } + return n +} +func sozPdpb(x uint64) (n int) { + return sovPdpb(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *RequestHeader) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowPdpb @@ -4794,64 +5078,6 @@ func (m *RequestHeader) Unmarshal(dAtA []byte) error { break } } - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Version", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowPdpb - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthPdpb - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Version = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field RequireMinVersion", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowPdpb - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthPdpb - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.RequireMinVersion = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipPdpb(dAtA[iNdEx:]) @@ -4954,35 +5180,6 @@ func (m *ResponseHeader) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ClusterVersion", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowPdpb - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthPdpb - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.ClusterVersion = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipPdpb(dAtA[iNdEx:]) @@ -8267,9 +8464,9 @@ func (m *RegionHeartbeatRequest) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 13: if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field ApproximateRows", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ApproximateKeys", wireType) } - m.ApproximateRows = 0 + m.ApproximateKeys = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowPdpb @@ -8279,7 +8476,7 @@ func (m *RegionHeartbeatRequest) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.ApproximateRows |= (uint64(b) & 0x7F) << shift + m.ApproximateKeys |= (uint64(b) & 0x7F) << shift if b < 0x80 { break } @@ -10323,6 +10520,395 @@ func (m *ScatterRegionResponse) Unmarshal(dAtA []byte) error { } return nil } +func (m *GetGCSafePointRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPdpb + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: GetGCSafePointRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: GetGCSafePointRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Header", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPdpb + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthPdpb + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Header == nil { + m.Header = &RequestHeader{} + } + if err := m.Header.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipPdpb(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthPdpb + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *GetGCSafePointResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPdpb + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: GetGCSafePointResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: GetGCSafePointResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Header", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPdpb + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthPdpb + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Header == nil { + m.Header = &ResponseHeader{} + } + if err := m.Header.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field SafePoint", wireType) + } + m.SafePoint = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPdpb + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.SafePoint |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipPdpb(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthPdpb + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *UpdateGCSafePointRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPdpb + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: UpdateGCSafePointRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: UpdateGCSafePointRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Header", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPdpb + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthPdpb + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Header == nil { + m.Header = &RequestHeader{} + } + if err := m.Header.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field SafePoint", wireType) + } + m.SafePoint = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPdpb + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.SafePoint |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipPdpb(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthPdpb + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *UpdateGCSafePointResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPdpb + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: UpdateGCSafePointResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: UpdateGCSafePointResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Header", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPdpb + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthPdpb + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Header == nil { + m.Header = &ResponseHeader{} + } + if err := m.Header.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field NewSafePoint", wireType) + } + m.NewSafePoint = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPdpb + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.NewSafePoint |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipPdpb(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthPdpb + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func skipPdpb(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 @@ -10431,134 +11017,138 @@ var ( func init() { proto.RegisterFile("pdpb.proto", fileDescriptorPdpb) } var fileDescriptorPdpb = []byte{ - // 2064 bytes of a gzipped FileDescriptorProto + // 2114 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x59, 0x4b, 0x6f, 0x23, 0xc7, - 0x11, 0x16, 0x29, 0x92, 0x22, 0x8b, 0x4f, 0xb5, 0x5e, 0x5c, 0xee, 0x4a, 0x91, 0x7b, 0x9d, 0x58, - 0x76, 0x6c, 0x7a, 0xad, 0x04, 0x81, 0x01, 0xc3, 0x81, 0xf5, 0xda, 0x5d, 0x79, 0x2d, 0x51, 0x68, - 0xd2, 0x31, 0x0c, 0x04, 0x61, 0x46, 0x9c, 0x16, 0x35, 0x11, 0x39, 0x33, 0x3b, 0xdd, 0x94, 0x4c, - 0xe7, 0x92, 0x93, 0x2f, 0x09, 0x90, 0x5b, 0x90, 0x4b, 0x80, 0xdc, 0x03, 0xe4, 0x2f, 0xe4, 0x9a, - 0x63, 0x7e, 0x42, 0xb0, 0xf9, 0x23, 0xc1, 0xf4, 0x63, 0x5e, 0xa4, 0xb4, 0xca, 0x6c, 0x7c, 0x12, - 0xa7, 0xaa, 0xba, 0xba, 0xea, 0xeb, 0xae, 0x47, 0x97, 0x00, 0x5c, 0xd3, 0x3d, 0x6f, 0xbb, 0x9e, - 0xc3, 0x1d, 0x94, 0xf3, 0x7f, 0xb7, 0x2a, 0x63, 0xca, 0x0d, 0x4d, 0x6b, 0x55, 0xa9, 0x67, 0x5c, - 0xf0, 0xe0, 0x73, 0x75, 0xe8, 0x0c, 0x1d, 0xf1, 0xf3, 0x43, 0xff, 0x97, 0xa4, 0xe2, 0x6f, 0xa0, - 0x4a, 0xe8, 0xcb, 0x09, 0x65, 0xfc, 0x39, 0x35, 0x4c, 0xea, 0xa1, 0x4d, 0x80, 0xc1, 0x68, 0xc2, - 0x38, 0xf5, 0xfa, 0x96, 0xd9, 0xcc, 0x6c, 0x67, 0x76, 0x72, 0xa4, 0xa4, 0x28, 0xc7, 0x26, 0x6a, - 0xc2, 0xd2, 0x35, 0xf5, 0x98, 0xe5, 0xd8, 0xcd, 0xec, 0x76, 0x66, 0xa7, 0x44, 0xf4, 0x27, 0x6a, - 0xc3, 0x8a, 0x47, 0x5f, 0x4e, 0x2c, 0x8f, 0xf6, 0xc7, 0x96, 0xdd, 0xd7, 0x52, 0x8b, 0x42, 0x6a, - 0x59, 0xb1, 0x4e, 0x2c, 0xfb, 0x17, 0x92, 0x81, 0x7f, 0x0b, 0x35, 0x42, 0x99, 0xeb, 0xd8, 0x8c, - 0xde, 0x6f, 0xeb, 0xb7, 0x20, 0x4f, 0x3d, 0xcf, 0xf1, 0xc4, 0xc6, 0xe5, 0xdd, 0x72, 0x5b, 0xf8, - 0x7f, 0xe4, 0x93, 0x88, 0xe4, 0xa0, 0x77, 0xa0, 0xae, 0x35, 0xc4, 0xf7, 0xaf, 0x29, 0xb2, 0xde, - 0xfc, 0x29, 0xe4, 0xc5, 0x42, 0xf4, 0x18, 0x72, 0x7c, 0xea, 0x52, 0xb1, 0x5b, 0x6d, 0xb7, 0x1e, - 0xd1, 0xd9, 0x9b, 0xba, 0x94, 0x08, 0xa6, 0xef, 0xf4, 0x98, 0x32, 0x66, 0x0c, 0xa9, 0x76, 0x5a, - 0x7d, 0xe2, 0x0e, 0x40, 0x8f, 0x39, 0x0a, 0x41, 0xf4, 0x63, 0x28, 0x5c, 0x0a, 0x57, 0x84, 0xba, - 0xf2, 0xee, 0x8a, 0x54, 0x17, 0x03, 0x98, 0x28, 0x11, 0xb4, 0x0a, 0xf9, 0x81, 0x33, 0xb1, 0xb9, - 0x50, 0x59, 0x25, 0xf2, 0x03, 0xef, 0x41, 0xa9, 0x67, 0x8d, 0x29, 0xe3, 0xc6, 0xd8, 0x45, 0x2d, - 0x28, 0xba, 0x97, 0x53, 0x66, 0x0d, 0x8c, 0x91, 0xd0, 0xb8, 0x48, 0x82, 0x6f, 0xdf, 0xa6, 0x91, - 0x33, 0x14, 0xac, 0xac, 0x60, 0xe9, 0x4f, 0xfc, 0xbb, 0x0c, 0x94, 0x85, 0x51, 0x12, 0x5c, 0xf4, - 0x7e, 0xc2, 0xaa, 0x55, 0x6d, 0x55, 0x14, 0xfc, 0xbb, 0xcd, 0x42, 0x1f, 0x40, 0x89, 0x6b, 0xb3, - 0x04, 0xa4, 0x65, 0x8d, 0x55, 0x60, 0x2d, 0x09, 0x25, 0xf0, 0x1f, 0x32, 0xd0, 0xd8, 0x77, 0x1c, - 0xce, 0xb8, 0x67, 0xb8, 0xa9, 0xd0, 0x79, 0x0c, 0x79, 0xc6, 0x1d, 0x8f, 0xaa, 0xc3, 0xae, 0xb6, - 0xd5, 0xd5, 0xee, 0xfa, 0x44, 0x22, 0x79, 0xe8, 0x47, 0x50, 0xf0, 0xe8, 0x50, 0x9f, 0x72, 0x79, - 0xb7, 0xa6, 0xa5, 0x88, 0xa0, 0x12, 0xc5, 0xc5, 0x7b, 0xb0, 0x1c, 0xb1, 0x26, 0x0d, 0x2c, 0xf8, - 0x10, 0xd6, 0x8e, 0x59, 0xa0, 0xc4, 0xa5, 0x66, 0x1a, 0xaf, 0xf0, 0x6f, 0x60, 0x3d, 0xa9, 0x25, - 0xd5, 0x21, 0x61, 0xa8, 0x9c, 0x47, 0xb4, 0x08, 0x90, 0x8a, 0x24, 0x46, 0xc3, 0x9f, 0x42, 0x6d, - 0x6f, 0x34, 0x72, 0x06, 0xc7, 0x87, 0xa9, 0x4c, 0xed, 0x40, 0x3d, 0x58, 0x9e, 0xca, 0xc6, 0x1a, - 0x64, 0x2d, 0x69, 0x59, 0x8e, 0x64, 0x2d, 0x13, 0x7f, 0x0d, 0xf5, 0x67, 0x94, 0xcb, 0xf3, 0x4b, - 0x73, 0x23, 0x1e, 0x40, 0x51, 0x9c, 0x7a, 0x3f, 0xd0, 0xba, 0x24, 0xbe, 0x8f, 0x4d, 0x4c, 0xa1, - 0x11, 0xaa, 0x4e, 0x65, 0xec, 0x7d, 0xae, 0x1b, 0x1e, 0x40, 0xfd, 0x6c, 0xf2, 0x06, 0x1e, 0xdc, - 0x6b, 0x93, 0xcf, 0xa0, 0x11, 0x6e, 0x92, 0xea, 0xaa, 0xee, 0xc3, 0xca, 0x33, 0xca, 0xf7, 0x46, - 0x23, 0xa1, 0x84, 0xa5, 0x3a, 0xfd, 0x2b, 0x58, 0x8d, 0xeb, 0x48, 0x85, 0xea, 0x0f, 0xa1, 0x20, - 0x9c, 0x62, 0xcd, 0xec, 0xf6, 0xe2, 0xac, 0xc7, 0x8a, 0x89, 0x7f, 0x25, 0x8e, 0x4f, 0xc5, 0x6c, - 0x1a, 0x60, 0x37, 0x01, 0x64, 0xa4, 0xf7, 0xaf, 0xe8, 0x54, 0xa0, 0x5b, 0x21, 0x25, 0x49, 0x79, - 0x41, 0xa7, 0xf8, 0x8f, 0x19, 0x58, 0x8e, 0x6c, 0x90, 0xca, 0x95, 0x30, 0xd5, 0x64, 0xef, 0x4a, - 0x35, 0xe8, 0x6d, 0x28, 0x8c, 0xa4, 0x56, 0x99, 0x92, 0x2a, 0x5a, 0xee, 0x8c, 0xfa, 0xda, 0x24, - 0x0f, 0xff, 0x5a, 0xc0, 0x2b, 0x97, 0xee, 0x4f, 0xd3, 0x45, 0x28, 0x7a, 0x08, 0xca, 0xc7, 0x30, - 0x22, 0x8a, 0x92, 0x70, 0x6c, 0xe2, 0xa7, 0xb0, 0xf1, 0x8c, 0xf2, 0x03, 0x59, 0xf5, 0x0e, 0x1c, - 0xfb, 0xc2, 0x1a, 0xa6, 0xba, 0x08, 0x0c, 0x9a, 0xb3, 0x7a, 0x52, 0x21, 0xf8, 0x2e, 0x2c, 0xa9, - 0x22, 0xac, 0x20, 0xac, 0x6b, 0x68, 0x94, 0x76, 0xa2, 0xf9, 0xf8, 0x25, 0x6c, 0x9c, 0x4d, 0xde, - 0xdc, 0xf8, 0xff, 0x65, 0xcb, 0xe7, 0xd0, 0x9c, 0xdd, 0x32, 0x55, 0xf8, 0xfd, 0x35, 0x03, 0x85, - 0x13, 0x3a, 0x3e, 0xa7, 0x1e, 0x42, 0x90, 0xb3, 0x8d, 0xb1, 0x6c, 0x2e, 0x4a, 0x44, 0xfc, 0xf6, - 0x4f, 0x6d, 0x2c, 0xb8, 0x91, 0x53, 0x93, 0x84, 0x63, 0xd3, 0x67, 0xba, 0x94, 0x7a, 0xfd, 0x89, - 0x37, 0x62, 0xcd, 0xc5, 0xed, 0xc5, 0x9d, 0x12, 0x29, 0xfa, 0x84, 0x2f, 0xbd, 0x11, 0x43, 0x3f, - 0x80, 0xf2, 0x60, 0x64, 0x51, 0x9b, 0x4b, 0x76, 0x4e, 0xb0, 0x41, 0x92, 0x84, 0xc0, 0x3b, 0x50, - 0x97, 0xf7, 0xab, 0xef, 0x7a, 0x96, 0xe3, 0x59, 0x7c, 0xda, 0xcc, 0x6f, 0x67, 0x76, 0xf2, 0xa4, - 0x26, 0xc9, 0x67, 0x8a, 0x8a, 0x3f, 0x13, 0xf1, 0x20, 0x8d, 0x4c, 0x97, 0x1f, 0xfe, 0x91, 0x01, - 0x14, 0x55, 0x91, 0x32, 0xa6, 0x96, 0xa4, 0xe7, 0x3a, 0x3f, 0x54, 0xa4, 0xb8, 0xd4, 0x4a, 0x34, - 0x73, 0x4e, 0x4c, 0x45, 0xc5, 0x14, 0x0f, 0x7d, 0x00, 0x65, 0xca, 0x07, 0x66, 0x5f, 0x89, 0xe6, - 0xe6, 0x88, 0x82, 0x2f, 0xf0, 0x85, 0xf4, 0xe0, 0x0c, 0x4a, 0x7e, 0x48, 0x76, 0xb9, 0xc1, 0x19, - 0xda, 0x86, 0x9c, 0x0f, 0xb3, 0xb2, 0x3a, 0x1e, 0xb3, 0x82, 0x83, 0xde, 0x82, 0x8a, 0xe9, 0xdc, - 0xd8, 0x7d, 0x46, 0x07, 0x8e, 0x6d, 0x32, 0x75, 0x72, 0x65, 0x9f, 0xd6, 0x95, 0x24, 0xfc, 0x5d, - 0x0e, 0xd6, 0x65, 0x48, 0x3f, 0xa7, 0x86, 0xc7, 0xcf, 0xa9, 0xc1, 0x53, 0xdd, 0xda, 0xff, 0x6b, - 0xaa, 0x41, 0x6d, 0x00, 0x61, 0xb8, 0xef, 0x85, 0xbc, 0x34, 0x41, 0xeb, 0x16, 0xf8, 0x4f, 0x4a, - 0xbe, 0x88, 0xff, 0xc9, 0xd0, 0x47, 0x50, 0x75, 0xa9, 0x6d, 0x5a, 0xf6, 0x50, 0x2d, 0xc9, 0xab, - 0xa3, 0x89, 0x2a, 0xaf, 0x28, 0x11, 0xb9, 0xe4, 0x31, 0x54, 0xcf, 0xa7, 0x9c, 0xb2, 0xfe, 0x8d, - 0x67, 0x71, 0x4e, 0xed, 0x66, 0x41, 0x80, 0x53, 0x11, 0xc4, 0xaf, 0x24, 0xcd, 0xcf, 0xd1, 0x52, - 0xc8, 0xa3, 0x86, 0xd9, 0x5c, 0x92, 0xcd, 0xbd, 0xa0, 0x10, 0x6a, 0xf8, 0xcd, 0x7d, 0xe5, 0x8a, - 0x4e, 0x43, 0x15, 0x45, 0x89, 0xaf, 0x4f, 0xd3, 0x1a, 0x1e, 0x42, 0x49, 0x88, 0x08, 0x05, 0x25, - 0x19, 0x39, 0x3e, 0x41, 0xac, 0x7f, 0x17, 0x1a, 0x86, 0xeb, 0x7a, 0xce, 0x37, 0xd6, 0xd8, 0xe0, - 0xb4, 0xcf, 0xac, 0x6f, 0x69, 0x13, 0x84, 0x4c, 0x3d, 0x42, 0xef, 0x5a, 0xdf, 0x52, 0xd4, 0x86, - 0xa2, 0x65, 0x73, 0xea, 0x5d, 0x1b, 0xa3, 0x66, 0x45, 0x20, 0x87, 0xc2, 0x56, 0xf6, 0x58, 0x71, - 0x48, 0x20, 0x93, 0x54, 0xed, 0x39, 0x37, 0xac, 0x59, 0x9d, 0x51, 0x4d, 0x9c, 0x1b, 0xf6, 0x79, - 0xae, 0x58, 0x6e, 0x54, 0xf0, 0x25, 0xc0, 0xc1, 0xa5, 0x61, 0x0f, 0xa9, 0x0f, 0xcf, 0x3d, 0xee, - 0xd6, 0xc7, 0x50, 0x1e, 0x08, 0xf9, 0xbe, 0x78, 0x8a, 0x64, 0xc5, 0x53, 0x64, 0xa3, 0xad, 0x9f, - 0x6f, 0x7e, 0x36, 0x92, 0xfa, 0xc4, 0x93, 0x04, 0x06, 0xc1, 0x6f, 0xbc, 0x0b, 0xb5, 0x9e, 0x67, - 0xd8, 0xec, 0x82, 0x7a, 0xf2, 0x5a, 0xbf, 0x7e, 0x37, 0xfc, 0x21, 0xe4, 0x4f, 0xa8, 0x37, 0x14, - 0xdd, 0x33, 0x37, 0xbc, 0x21, 0xe5, 0x4a, 0x78, 0xe6, 0x9e, 0x49, 0x2e, 0xae, 0x42, 0xb9, 0xeb, - 0x8e, 0x2c, 0x55, 0xae, 0xf0, 0x9f, 0x16, 0x61, 0x63, 0xe6, 0x9a, 0xa7, 0x8a, 0xff, 0x8f, 0x02, - 0xbf, 0x85, 0xc9, 0xf2, 0xb6, 0x37, 0xe4, 0x92, 0x10, 0x40, 0xed, 0xb0, 0x00, 0xf3, 0x53, 0xa8, - 0x73, 0xe5, 0x70, 0x3f, 0x76, 0xf9, 0xd5, 0x4e, 0x71, 0x34, 0x48, 0x8d, 0xc7, 0xd1, 0x89, 0x95, - 0xcc, 0x5c, 0xbc, 0x64, 0xa2, 0x9f, 0x41, 0x45, 0x31, 0xa9, 0xeb, 0x0c, 0x2e, 0x45, 0xee, 0xf4, - 0x43, 0x35, 0x86, 0xca, 0x91, 0xcf, 0x22, 0x65, 0x2f, 0xfc, 0xf0, 0x13, 0x8f, 0x44, 0x4a, 0xba, - 0x51, 0x98, 0x83, 0x3c, 0x48, 0x81, 0x33, 0x99, 0x49, 0xf2, 0x63, 0x1f, 0x7f, 0x11, 0x03, 0xc1, - 0x33, 0x56, 0x1c, 0x09, 0x91, 0x1c, 0xf4, 0x53, 0xa8, 0x30, 0x1f, 0xf1, 0xbe, 0xca, 0x03, 0x45, - 0x21, 0xb9, 0x2c, 0x25, 0x23, 0x67, 0x41, 0xca, 0x2c, 0x72, 0x30, 0x17, 0x50, 0xdf, 0x63, 0x57, - 0x8a, 0xfd, 0xfd, 0xe5, 0x1d, 0xfc, 0x5d, 0x06, 0x1a, 0xe1, 0x46, 0x29, 0xdf, 0x2f, 0x55, 0x9b, - 0xde, 0xf4, 0x93, 0xed, 0x4b, 0xd9, 0xa6, 0x37, 0x44, 0x1f, 0xc7, 0x36, 0x54, 0x7c, 0x19, 0x51, - 0x0f, 0x2d, 0x53, 0x96, 0xc3, 0x1c, 0x01, 0x9b, 0xde, 0xf8, 0x30, 0x1e, 0x9b, 0x0c, 0xff, 0x3e, - 0x03, 0x88, 0x50, 0xd7, 0xf1, 0x78, 0x7a, 0xa7, 0x31, 0xe4, 0x46, 0xf4, 0x82, 0xdf, 0xe2, 0xb2, - 0xe0, 0xa1, 0xb7, 0x21, 0xef, 0x59, 0xc3, 0x4b, 0x7e, 0xcb, 0x2b, 0x53, 0x32, 0xf1, 0x01, 0xac, - 0xc4, 0x8c, 0x49, 0xd5, 0x3c, 0xfc, 0x12, 0x2a, 0xd1, 0x2c, 0xe4, 0x97, 0x74, 0xc6, 0x0d, 0x8f, - 0xf7, 0xc3, 0xd7, 0xb7, 0x9c, 0x8b, 0xd4, 0x04, 0x39, 0x1c, 0x15, 0x3c, 0x86, 0x2a, 0xb5, 0xcd, - 0x88, 0x98, 0x44, 0xb4, 0x42, 0x6d, 0x33, 0x10, 0xc2, 0x7f, 0xc9, 0x01, 0x88, 0xd6, 0x5b, 0x56, - 0xbd, 0xe8, 0x8b, 0x2a, 0x13, 0x7b, 0x51, 0xa1, 0x16, 0x14, 0x07, 0x86, 0x6b, 0x0c, 0xfc, 0x1e, - 0x42, 0x35, 0x29, 0xfa, 0x1b, 0x3d, 0x82, 0x92, 0x71, 0x6d, 0x58, 0x23, 0xe3, 0x7c, 0x44, 0x05, - 0x24, 0x39, 0x12, 0x12, 0xfc, 0x44, 0xae, 0x8e, 0x55, 0x8e, 0x11, 0x72, 0x62, 0x8c, 0xa0, 0x02, - 0xe6, 0x40, 0x0c, 0x13, 0xde, 0x07, 0xc4, 0x54, 0x89, 0x61, 0xb6, 0xe1, 0x2a, 0xc1, 0xbc, 0x10, - 0x6c, 0x28, 0x4e, 0xd7, 0x36, 0x5c, 0x29, 0xfd, 0x04, 0x56, 0x3d, 0x3a, 0xa0, 0xd6, 0x75, 0x42, - 0xbe, 0x20, 0xe4, 0x51, 0xc0, 0x0b, 0x57, 0x6c, 0x02, 0x84, 0xa0, 0x89, 0x30, 0xab, 0x92, 0x52, - 0x80, 0x17, 0x6a, 0xc3, 0x8a, 0xe1, 0xba, 0xa3, 0x69, 0x42, 0x5f, 0x51, 0xc8, 0x2d, 0x6b, 0x56, - 0xa8, 0x6e, 0x03, 0x96, 0x2c, 0xd6, 0x3f, 0x9f, 0xb0, 0xa9, 0xa8, 0x3a, 0x45, 0x52, 0xb0, 0xd8, - 0xfe, 0x84, 0x4d, 0xfd, 0x6c, 0x32, 0x61, 0xd4, 0x8c, 0x16, 0x9b, 0xa2, 0x4f, 0x10, 0x55, 0x66, - 0xa6, 0x28, 0x96, 0xe7, 0x14, 0xc5, 0x64, 0xd5, 0xab, 0xcc, 0x56, 0xbd, 0x78, 0xdd, 0xac, 0x26, - 0xeb, 0x66, 0xac, 0x28, 0xd6, 0x12, 0x45, 0x31, 0x5a, 0xe9, 0xea, 0xaf, 0xaf, 0x74, 0x78, 0x04, - 0x6b, 0xe2, 0x7a, 0xbc, 0x69, 0xff, 0x92, 0x67, 0xfe, 0xfd, 0x8a, 0x27, 0xf4, 0xf0, 0xde, 0x11, - 0xc9, 0xc6, 0x4f, 0x61, 0x3d, 0xb9, 0x5b, 0xaa, 0x98, 0xf9, 0x7b, 0x06, 0x56, 0xbb, 0x03, 0x83, - 0xfb, 0xfd, 0x7c, 0xfa, 0x37, 0xe4, 0x5d, 0xaf, 0xa9, 0xfb, 0x0e, 0x9a, 0x22, 0x2d, 0x59, 0xee, - 0x8e, 0xd7, 0xdf, 0x11, 0xac, 0x25, 0xec, 0x4d, 0xe3, 0xf7, 0x7b, 0x14, 0x4a, 0xc1, 0xa0, 0x12, - 0x15, 0x20, 0xdb, 0x79, 0xd1, 0x58, 0x40, 0x65, 0x58, 0xfa, 0xf2, 0xf4, 0xc5, 0x69, 0xe7, 0xab, - 0xd3, 0x46, 0x06, 0xad, 0x42, 0xe3, 0xb4, 0xd3, 0xeb, 0xef, 0x77, 0x3a, 0xbd, 0x6e, 0x8f, 0xec, - 0x9d, 0x9d, 0x1d, 0x1d, 0x36, 0xb2, 0x68, 0x05, 0xea, 0xdd, 0x5e, 0x87, 0x1c, 0xf5, 0x7b, 0x9d, - 0x93, 0xfd, 0x6e, 0xaf, 0x73, 0x7a, 0xd4, 0x58, 0x44, 0x4d, 0x58, 0xdd, 0xfb, 0x82, 0x1c, 0xed, - 0x1d, 0x7e, 0x1d, 0x17, 0xcf, 0xed, 0xfe, 0xad, 0x04, 0xd9, 0xb3, 0x43, 0xb4, 0x07, 0x10, 0x36, - 0xfc, 0x68, 0x43, 0x5a, 0x36, 0xf3, 0x8a, 0x68, 0x35, 0x67, 0x19, 0xd2, 0x78, 0xbc, 0x80, 0x9e, - 0xc0, 0x62, 0x8f, 0x39, 0x48, 0x5d, 0x88, 0x70, 0x6e, 0xda, 0x5a, 0x8e, 0x50, 0xb4, 0xf4, 0x4e, - 0xe6, 0x49, 0x06, 0xfd, 0x1c, 0x4a, 0xc1, 0xb4, 0x0c, 0xad, 0x4b, 0xa9, 0xe4, 0x5c, 0xb1, 0xb5, - 0x31, 0x43, 0x0f, 0x76, 0x3c, 0x81, 0x5a, 0x7c, 0xde, 0x86, 0x1e, 0x4a, 0xe1, 0xb9, 0xb3, 0xbc, - 0xd6, 0xa3, 0xf9, 0xcc, 0x40, 0xdd, 0xc7, 0xb0, 0xa4, 0x66, 0x62, 0x48, 0x1d, 0x4d, 0x7c, 0xc2, - 0xd6, 0x5a, 0x4b, 0x50, 0x83, 0x95, 0x9f, 0x40, 0x51, 0x4f, 0xa8, 0xd0, 0x5a, 0x00, 0x51, 0x74, - 0x94, 0xd4, 0x5a, 0x4f, 0x92, 0xa3, 0x8b, 0xf5, 0x48, 0x48, 0x2f, 0x4e, 0xcc, 0xa1, 0xf4, 0xe2, - 0xe4, 0xe4, 0x08, 0x2f, 0xa0, 0x67, 0x50, 0x89, 0x4e, 0x72, 0xd0, 0x83, 0x60, 0x9b, 0xe4, 0x84, - 0xa8, 0xd5, 0x9a, 0xc7, 0x8a, 0x62, 0x19, 0x0f, 0x57, 0x8d, 0xe5, 0xdc, 0x94, 0xa1, 0xb1, 0x9c, - 0x1f, 0xe1, 0x78, 0x01, 0xf5, 0xa0, 0x9e, 0xe8, 0x22, 0xd1, 0x23, 0x7d, 0xdd, 0xe7, 0xbd, 0xa1, - 0x5a, 0x9b, 0xb7, 0x70, 0x93, 0x17, 0x26, 0x18, 0xac, 0xa0, 0x10, 0xd1, 0x58, 0x5e, 0x68, 0x6d, - 0xcc, 0xd0, 0x03, 0xab, 0x9e, 0x42, 0x35, 0x36, 0x98, 0x41, 0xad, 0x84, 0x6c, 0x64, 0x5a, 0x73, - 0x97, 0x9e, 0x4f, 0xa0, 0xa8, 0x5b, 0x24, 0x7d, 0x64, 0x89, 0xde, 0x4c, 0x1f, 0x59, 0xb2, 0x93, - 0xc2, 0x0b, 0xe8, 0x10, 0xca, 0x91, 0x4e, 0x02, 0x35, 0xb5, 0xe3, 0xc9, 0x4e, 0xa7, 0xf5, 0x60, - 0x0e, 0x27, 0xd0, 0xd2, 0x15, 0x53, 0xb5, 0xd8, 0x44, 0x03, 0x6d, 0x06, 0x16, 0xcf, 0x1b, 0xae, - 0xb4, 0xb6, 0x6e, 0x63, 0x47, 0x95, 0x26, 0xc7, 0x24, 0x5a, 0xe9, 0x2d, 0x13, 0x1b, 0xad, 0xf4, - 0xb6, 0xe9, 0x0a, 0x5e, 0x40, 0x9f, 0x43, 0x35, 0x96, 0x0f, 0x35, 0xe8, 0xf3, 0x92, 0x7a, 0xeb, - 0xe1, 0x5c, 0x9e, 0xd6, 0xb5, 0xff, 0xde, 0x3f, 0x5f, 0x6d, 0x65, 0xfe, 0xf5, 0x6a, 0x2b, 0xf3, - 0xef, 0x57, 0x5b, 0x99, 0x3f, 0xff, 0x67, 0x6b, 0x01, 0x9a, 0x03, 0x67, 0xdc, 0x76, 0x2d, 0x7b, - 0x38, 0x30, 0xdc, 0x36, 0xb7, 0xae, 0xae, 0xdb, 0x57, 0xd7, 0xe2, 0x7f, 0x5f, 0xe7, 0x05, 0xf1, - 0xe7, 0x27, 0xff, 0x0d, 0x00, 0x00, 0xff, 0xff, 0x41, 0x5e, 0x0c, 0xfb, 0x49, 0x1b, 0x00, 0x00, + 0x11, 0x16, 0x29, 0x92, 0x22, 0x8b, 0x4f, 0xb5, 0x5e, 0x5c, 0xee, 0x4a, 0x96, 0x7b, 0x37, 0x89, + 0xec, 0xd8, 0xf4, 0x5a, 0x09, 0x02, 0x03, 0x86, 0x03, 0xeb, 0xb5, 0x5a, 0x79, 0xbd, 0x22, 0xd1, + 0xe4, 0xc6, 0x30, 0x10, 0x84, 0x19, 0x71, 0x5a, 0xd4, 0x44, 0xe4, 0xcc, 0x78, 0xba, 0x25, 0x85, + 0x3e, 0xe5, 0xe4, 0x4b, 0x02, 0xe4, 0x16, 0xe4, 0x12, 0x20, 0xbf, 0x20, 0x7f, 0x21, 0xd7, 0x1c, + 0x83, 0xfc, 0x82, 0x60, 0xf3, 0x47, 0x82, 0x7e, 0xcc, 0x93, 0x94, 0x56, 0x99, 0x8d, 0x4f, 0xe2, + 0x54, 0x55, 0x7f, 0x5d, 0x55, 0x5d, 0x8f, 0xee, 0x12, 0x80, 0x6b, 0xba, 0x67, 0x6d, 0xd7, 0x73, + 0xb8, 0x83, 0x72, 0xe2, 0x77, 0xab, 0x32, 0xa1, 0xdc, 0xf0, 0x69, 0xad, 0x2a, 0xf5, 0x8c, 0x73, + 0x1e, 0x7c, 0xae, 0x8e, 0x9c, 0x91, 0x23, 0x7f, 0x7e, 0x24, 0x7e, 0x29, 0x2a, 0x6e, 0x43, 0x95, + 0xd0, 0x6f, 0xae, 0x28, 0xe3, 0xcf, 0xa9, 0x61, 0x52, 0x0f, 0x6d, 0x02, 0x0c, 0xc7, 0x57, 0x8c, + 0x53, 0x6f, 0x60, 0x99, 0xcd, 0xcc, 0x76, 0x66, 0x27, 0x47, 0x4a, 0x9a, 0x72, 0x62, 0x62, 0x02, + 0x35, 0x42, 0x99, 0xeb, 0xd8, 0x8c, 0xde, 0x6b, 0x01, 0x7a, 0x17, 0xf2, 0xd4, 0xf3, 0x1c, 0xaf, + 0x99, 0xdd, 0xce, 0xec, 0x94, 0x77, 0xcb, 0x6d, 0xa9, 0xf5, 0x91, 0x20, 0x11, 0xc5, 0xc1, 0xcf, + 0x20, 0x2f, 0xbf, 0xd1, 0x63, 0xc8, 0xf1, 0xa9, 0x4b, 0x25, 0x48, 0x6d, 0xb7, 0x1e, 0x11, 0xed, + 0x4f, 0x5d, 0x4a, 0x24, 0x13, 0x35, 0x61, 0x69, 0x42, 0x19, 0x33, 0x46, 0x54, 0x42, 0x96, 0x88, + 0xff, 0x89, 0x3b, 0x00, 0x7d, 0xe6, 0x68, 0x73, 0xd0, 0x8f, 0xa1, 0x70, 0x21, 0x35, 0x94, 0x70, + 0xe5, 0xdd, 0x15, 0x05, 0x17, 0xb3, 0x96, 0x68, 0x11, 0xb4, 0x0a, 0xf9, 0xa1, 0x73, 0x65, 0x73, + 0x09, 0x59, 0x25, 0xea, 0x03, 0xef, 0x41, 0xa9, 0x6f, 0x4d, 0x28, 0xe3, 0xc6, 0xc4, 0x45, 0x2d, + 0x28, 0xba, 0x17, 0x53, 0x66, 0x0d, 0x8d, 0xb1, 0x44, 0x5c, 0x24, 0xc1, 0xb7, 0xd0, 0x69, 0xec, + 0x8c, 0x24, 0x2b, 0x2b, 0x59, 0xfe, 0x27, 0xfe, 0x5d, 0x06, 0xca, 0x52, 0x29, 0xe5, 0x33, 0xf4, + 0x41, 0x42, 0xab, 0x55, 0x5f, 0xab, 0xa8, 0x4f, 0xef, 0x56, 0x0b, 0x7d, 0x08, 0x25, 0xee, 0xab, + 0xd5, 0x5c, 0x94, 0x30, 0xda, 0x57, 0x81, 0xb6, 0x24, 0x94, 0xc0, 0x7f, 0xc8, 0x40, 0x63, 0xdf, + 0x71, 0x38, 0xe3, 0x9e, 0xe1, 0xa6, 0xf2, 0xce, 0x63, 0xc8, 0x33, 0xee, 0x78, 0x54, 0x9f, 0x61, + 0xb5, 0xad, 0xe3, 0xac, 0x27, 0x88, 0x44, 0xf1, 0xd0, 0x0f, 0xa1, 0xe0, 0xd1, 0x91, 0xe5, 0xd8, + 0x5a, 0xa5, 0x9a, 0x2f, 0x45, 0x24, 0x95, 0x68, 0x2e, 0xde, 0x83, 0xe5, 0x88, 0x36, 0x69, 0xdc, + 0x82, 0x0f, 0x61, 0xed, 0x84, 0x05, 0x20, 0x2e, 0x35, 0xd3, 0x58, 0x85, 0x7f, 0x03, 0xeb, 0x49, + 0x94, 0x54, 0x87, 0x84, 0xa1, 0x72, 0x16, 0x41, 0x91, 0x4e, 0x2a, 0x92, 0x18, 0x0d, 0x7f, 0x06, + 0xb5, 0xbd, 0xf1, 0xd8, 0x19, 0x9e, 0x1c, 0xa6, 0x52, 0xb5, 0x03, 0xf5, 0x60, 0x79, 0x2a, 0x1d, + 0x6b, 0x90, 0xb5, 0x94, 0x66, 0x39, 0x92, 0xb5, 0x4c, 0xfc, 0x35, 0xd4, 0x8f, 0x29, 0x57, 0xe7, + 0x97, 0x26, 0x22, 0x1e, 0x40, 0x51, 0x9e, 0xfa, 0x20, 0x40, 0x5d, 0x92, 0xdf, 0x27, 0x26, 0xa6, + 0xd0, 0x08, 0xa1, 0x53, 0x29, 0x7b, 0x9f, 0x70, 0xc3, 0x43, 0xa8, 0x77, 0xaf, 0xde, 0xc2, 0x82, + 0x7b, 0x6d, 0xf2, 0x39, 0x34, 0xc2, 0x4d, 0x52, 0x85, 0xea, 0x3e, 0xac, 0x1c, 0x53, 0xbe, 0x37, + 0x1e, 0x4b, 0x10, 0x96, 0xea, 0xf4, 0x2f, 0x61, 0x35, 0x8e, 0x91, 0xca, 0xab, 0x3f, 0x80, 0x82, + 0x34, 0x8a, 0x35, 0xb3, 0xdb, 0x8b, 0xb3, 0x16, 0x6b, 0x26, 0xfe, 0x95, 0x3c, 0x3e, 0x9d, 0xb3, + 0x69, 0x1c, 0xbb, 0x09, 0xa0, 0x32, 0x7d, 0x70, 0x49, 0xa7, 0xd2, 0xbb, 0x15, 0x52, 0x52, 0x94, + 0x17, 0x74, 0x8a, 0xff, 0x98, 0x81, 0xe5, 0xc8, 0x06, 0xa9, 0x4c, 0x09, 0x4b, 0x4d, 0xf6, 0xae, + 0x52, 0x83, 0x9e, 0x40, 0x61, 0xac, 0x50, 0x55, 0x49, 0xaa, 0xf8, 0x72, 0x5d, 0x2a, 0xd0, 0x14, + 0x0f, 0xff, 0x5a, 0xba, 0x57, 0x2d, 0xdd, 0x9f, 0xa6, 0xcb, 0x50, 0xf4, 0x10, 0xb4, 0x8d, 0x61, + 0x46, 0x14, 0x15, 0xe1, 0xc4, 0xc4, 0xcf, 0x60, 0xe3, 0x98, 0xf2, 0x03, 0xd5, 0x13, 0x0f, 0x1c, + 0xfb, 0xdc, 0x1a, 0xa5, 0x0a, 0x04, 0x06, 0xcd, 0x59, 0x9c, 0x54, 0x1e, 0x7c, 0x0f, 0x96, 0x74, + 0x8b, 0xd6, 0x2e, 0xac, 0xfb, 0xae, 0xd1, 0xe8, 0xc4, 0xe7, 0xe3, 0x6f, 0x60, 0xa3, 0x7b, 0xf5, + 0xf6, 0xca, 0xff, 0x2f, 0x5b, 0x3e, 0x87, 0xe6, 0xec, 0x96, 0xa9, 0xd2, 0xef, 0xaf, 0x19, 0x28, + 0xbc, 0xa4, 0x93, 0x33, 0xea, 0x21, 0x04, 0x39, 0xdb, 0x98, 0xa8, 0xcb, 0x45, 0x89, 0xc8, 0xdf, + 0xe2, 0xd4, 0x26, 0x92, 0x1b, 0x39, 0x35, 0x45, 0x38, 0x31, 0x05, 0xd3, 0xa5, 0xd4, 0x1b, 0x5c, + 0x79, 0x63, 0xd6, 0x5c, 0xdc, 0x5e, 0xdc, 0x29, 0x91, 0xa2, 0x20, 0xbc, 0xf2, 0xc6, 0x0c, 0xbd, + 0x03, 0xe5, 0xe1, 0xd8, 0xa2, 0x36, 0x57, 0xec, 0x9c, 0x64, 0x83, 0x22, 0x49, 0x81, 0x1f, 0x41, + 0x5d, 0xc5, 0xd7, 0xc0, 0xf5, 0x2c, 0xc7, 0xb3, 0xf8, 0xb4, 0x99, 0xdf, 0xce, 0xec, 0xe4, 0x49, + 0x4d, 0x91, 0xbb, 0x9a, 0x8a, 0x3f, 0x97, 0xf9, 0xa0, 0x94, 0x4c, 0x57, 0x1f, 0xfe, 0x9e, 0x01, + 0x14, 0x85, 0x48, 0x99, 0x53, 0x4b, 0xca, 0x72, 0xbf, 0x3e, 0x54, 0x94, 0xb8, 0x42, 0x25, 0x3e, + 0x73, 0x4e, 0x4e, 0x45, 0xc5, 0x34, 0x0f, 0x7d, 0x08, 0x65, 0xca, 0x87, 0xe6, 0x40, 0x8b, 0xe6, + 0xe6, 0x88, 0x82, 0x10, 0xf8, 0x52, 0x59, 0xd0, 0x85, 0x92, 0x48, 0xc9, 0x1e, 0x37, 0x38, 0x43, + 0xdb, 0x90, 0x13, 0x6e, 0xd6, 0x5a, 0xc7, 0x73, 0x56, 0x72, 0xd0, 0xbb, 0x50, 0x31, 0x9d, 0x1b, + 0x7b, 0xc0, 0xe8, 0xd0, 0xb1, 0x4d, 0xa6, 0x4f, 0xae, 0x2c, 0x68, 0x3d, 0x45, 0xc2, 0xdf, 0xe5, + 0x60, 0x5d, 0xa5, 0xf4, 0x73, 0x6a, 0x78, 0xfc, 0x8c, 0x1a, 0x3c, 0x55, 0xd4, 0xfe, 0x5f, 0x4b, + 0x0d, 0x6a, 0x03, 0x48, 0xc5, 0x85, 0x15, 0x2a, 0x68, 0x82, 0xab, 0x5b, 0x60, 0x3f, 0x29, 0x09, + 0x11, 0xf1, 0xc9, 0xd0, 0xc7, 0x50, 0x75, 0xa9, 0x6d, 0x5a, 0xf6, 0x48, 0x2f, 0xc9, 0xeb, 0xa3, + 0x89, 0x82, 0x57, 0xb4, 0x88, 0x5a, 0xf2, 0x18, 0xaa, 0x67, 0x53, 0x4e, 0xd9, 0xe0, 0xc6, 0xb3, + 0x38, 0xa7, 0x76, 0xb3, 0x20, 0x9d, 0x53, 0x91, 0xc4, 0xaf, 0x14, 0x4d, 0xd4, 0x68, 0x25, 0xe4, + 0x51, 0xc3, 0x6c, 0x2e, 0xa9, 0x3b, 0xbb, 0xa4, 0x10, 0x6a, 0x88, 0x3b, 0x7b, 0xe5, 0x92, 0x4e, + 0x43, 0x88, 0xa2, 0xf2, 0xaf, 0xa0, 0xf9, 0x08, 0x0f, 0xa1, 0x24, 0x45, 0x24, 0x40, 0x49, 0x65, + 0x8e, 0x20, 0xc8, 0xf5, 0xef, 0x41, 0xc3, 0x70, 0x5d, 0xcf, 0xf9, 0xad, 0x35, 0x31, 0x38, 0x1d, + 0x30, 0xeb, 0x5b, 0xda, 0x04, 0x29, 0x53, 0x8f, 0xd0, 0x7b, 0xd6, 0xb7, 0x14, 0xb5, 0xa1, 0x68, + 0xd9, 0x9c, 0x7a, 0xd7, 0xc6, 0xb8, 0x59, 0x91, 0x9e, 0x43, 0xe1, 0x55, 0xf6, 0x44, 0x73, 0x48, + 0x20, 0x93, 0x84, 0x16, 0x5b, 0x36, 0xab, 0x33, 0xd0, 0x2f, 0xe8, 0x94, 0x7d, 0x91, 0x2b, 0x96, + 0x1b, 0x15, 0x7c, 0x01, 0x70, 0x70, 0x61, 0xd8, 0x23, 0x2a, 0xdc, 0x73, 0x8f, 0xd8, 0xfa, 0x04, + 0xca, 0x43, 0x29, 0x3f, 0x90, 0x4f, 0x91, 0xac, 0x7c, 0x8a, 0x6c, 0xb4, 0xfd, 0xb7, 0x94, 0xa8, + 0x46, 0x0a, 0x4f, 0x3e, 0x49, 0x60, 0x18, 0xfc, 0xc6, 0xbb, 0x50, 0xeb, 0x7b, 0x86, 0xcd, 0xce, + 0xa9, 0xa7, 0xc2, 0xfa, 0xcd, 0xbb, 0xe1, 0x8f, 0x20, 0xff, 0x92, 0x7a, 0x23, 0x79, 0x7b, 0xe6, + 0x86, 0x37, 0xa2, 0x5c, 0x0b, 0xcf, 0xc4, 0x99, 0xe2, 0xe2, 0x2a, 0x94, 0x7b, 0xee, 0xd8, 0xd2, + 0xed, 0x0a, 0xff, 0x69, 0x11, 0x36, 0x66, 0xc2, 0x3c, 0x55, 0xfe, 0x7f, 0x1c, 0xd8, 0x2d, 0x55, + 0x56, 0xd1, 0xde, 0x50, 0x4b, 0x42, 0x07, 0xfa, 0x06, 0x4b, 0x67, 0x7e, 0x06, 0x75, 0xae, 0x0d, + 0x1e, 0xc4, 0x82, 0x5f, 0xef, 0x14, 0xf7, 0x06, 0xa9, 0xf1, 0xb8, 0x77, 0x62, 0x2d, 0x33, 0x17, + 0x6f, 0x99, 0xe8, 0x67, 0x50, 0xd1, 0x4c, 0xea, 0x3a, 0xc3, 0x0b, 0x59, 0x3b, 0x45, 0xaa, 0xc6, + 0xbc, 0x72, 0x24, 0x58, 0xa4, 0xec, 0x85, 0x1f, 0xa2, 0xf0, 0x28, 0x4f, 0x29, 0x33, 0x0a, 0x73, + 0x3c, 0x0f, 0x4a, 0xa0, 0xab, 0x2a, 0x49, 0x7e, 0x22, 0xfc, 0x2f, 0x73, 0x20, 0x78, 0x9d, 0xca, + 0x23, 0x21, 0x8a, 0x83, 0x7e, 0x0a, 0x15, 0x26, 0x3c, 0x3e, 0xd0, 0x75, 0xa0, 0x28, 0x25, 0x97, + 0x95, 0x64, 0xe4, 0x2c, 0x48, 0x99, 0x45, 0x0e, 0xe6, 0x1c, 0xea, 0x7b, 0xec, 0x52, 0xb3, 0xbf, + 0xbf, 0xba, 0x83, 0xbf, 0xcb, 0x40, 0x23, 0xdc, 0x28, 0xe5, 0xfb, 0xa5, 0x6a, 0xd3, 0x9b, 0x41, + 0xf2, 0xfa, 0x52, 0xb6, 0xe9, 0x0d, 0xf1, 0x8f, 0x63, 0x1b, 0x2a, 0x42, 0x46, 0xf6, 0x43, 0xcb, + 0x54, 0xed, 0x30, 0x47, 0xc0, 0xa6, 0x37, 0xc2, 0x8d, 0x27, 0x26, 0xc3, 0xbf, 0xcf, 0x00, 0x22, + 0xd4, 0x75, 0x3c, 0x9e, 0xde, 0x68, 0x0c, 0xb9, 0x31, 0x3d, 0xe7, 0xb7, 0x98, 0x2c, 0x79, 0xe8, + 0x09, 0xe4, 0x3d, 0x6b, 0x74, 0xc1, 0x6f, 0x79, 0x65, 0x2a, 0x26, 0x3e, 0x80, 0x95, 0x98, 0x32, + 0xa9, 0x2e, 0x0f, 0xbf, 0x84, 0x4a, 0xb4, 0x0a, 0x89, 0x96, 0xce, 0xb8, 0xe1, 0xf1, 0x41, 0xf8, + 0xfa, 0x56, 0xe3, 0x8e, 0x9a, 0x24, 0x87, 0xa3, 0x82, 0xc7, 0x50, 0xa5, 0xb6, 0x19, 0x11, 0x53, + 0x1e, 0xad, 0x50, 0xdb, 0x0c, 0x84, 0xf0, 0x5f, 0x72, 0x00, 0xf2, 0xea, 0xad, 0xba, 0x5e, 0xf4, + 0x45, 0x95, 0x89, 0xbd, 0xa8, 0x50, 0x0b, 0x8a, 0x43, 0xc3, 0x35, 0x86, 0xe2, 0x0e, 0xa1, 0x2f, + 0x29, 0xfe, 0x37, 0x7a, 0x04, 0x25, 0xe3, 0xda, 0xb0, 0xc6, 0xc6, 0xd9, 0x98, 0x4a, 0x97, 0xe4, + 0x48, 0x48, 0x10, 0x85, 0x5c, 0x1f, 0xab, 0x1a, 0x23, 0xe4, 0xe4, 0x18, 0x41, 0x27, 0xcc, 0x81, + 0x1c, 0x26, 0x7c, 0x00, 0x88, 0xe9, 0x16, 0xc3, 0x6c, 0xc3, 0xd5, 0x82, 0x79, 0x29, 0xd8, 0xd0, + 0x9c, 0x9e, 0x6d, 0xb8, 0x4a, 0xfa, 0x29, 0xac, 0x7a, 0x74, 0x48, 0xad, 0xeb, 0x84, 0x7c, 0x41, + 0xca, 0xa3, 0x80, 0x17, 0xae, 0xd8, 0x04, 0x08, 0x9d, 0x26, 0xd3, 0xac, 0x4a, 0x4a, 0x81, 0xbf, + 0x50, 0x1b, 0x56, 0x0c, 0xd7, 0x1d, 0x4f, 0x13, 0x78, 0x45, 0x29, 0xb7, 0xec, 0xb3, 0x42, 0xb8, + 0x0d, 0x58, 0xb2, 0xd8, 0xe0, 0xec, 0x8a, 0x4d, 0x65, 0xd7, 0x29, 0x92, 0x82, 0xc5, 0xf6, 0xaf, + 0xd8, 0x54, 0x54, 0x93, 0x2b, 0x46, 0xcd, 0x68, 0xb3, 0x29, 0x0a, 0x82, 0xec, 0x32, 0x33, 0x4d, + 0xb1, 0x3c, 0xa7, 0x29, 0x26, 0xbb, 0x5e, 0x65, 0xb6, 0xeb, 0xc5, 0xfb, 0x66, 0x35, 0xd9, 0x37, + 0x63, 0x4d, 0xb1, 0x96, 0x68, 0x8a, 0xd1, 0x4e, 0x57, 0x7f, 0x73, 0xa7, 0xc3, 0x63, 0x58, 0x93, + 0xe1, 0xf1, 0xb6, 0xf7, 0x97, 0x3c, 0x13, 0xf1, 0x15, 0x2f, 0xe8, 0x61, 0xdc, 0x11, 0xc5, 0xc6, + 0xcf, 0x60, 0x3d, 0xb9, 0x5b, 0xaa, 0x9c, 0xf9, 0x5b, 0x06, 0x56, 0x7b, 0x43, 0x83, 0x8b, 0xfb, + 0x7c, 0xfa, 0x37, 0xe4, 0x5d, 0xaf, 0xa9, 0xfb, 0x0e, 0x9a, 0x22, 0x57, 0xb2, 0xdc, 0x1d, 0xaf, + 0xbf, 0x23, 0x58, 0x4b, 0xe8, 0x9b, 0x76, 0x24, 0x75, 0x4c, 0xf9, 0xf1, 0x41, 0xcf, 0x38, 0xa7, + 0x5d, 0xc7, 0xb2, 0x53, 0x9d, 0x16, 0xa6, 0xb0, 0x9e, 0x44, 0x49, 0x55, 0xd2, 0x45, 0xd2, 0x19, + 0xe7, 0x74, 0xe0, 0x0a, 0x0c, 0xed, 0xc0, 0x12, 0xf3, 0x41, 0xf1, 0x39, 0x34, 0x5f, 0xb9, 0xa6, + 0xc1, 0xe9, 0x5b, 0xea, 0xfb, 0xa6, 0x7d, 0x1c, 0x78, 0x30, 0x67, 0x9f, 0x54, 0x16, 0x3d, 0x81, + 0x9a, 0x68, 0x40, 0x33, 0xbb, 0x89, 0xb6, 0x14, 0x60, 0xbf, 0x4f, 0xa1, 0x14, 0x8c, 0x8b, 0x51, + 0x01, 0xb2, 0x9d, 0x17, 0x8d, 0x05, 0x54, 0x86, 0xa5, 0x57, 0xa7, 0x2f, 0x4e, 0x3b, 0x5f, 0x9d, + 0x36, 0x32, 0x68, 0x15, 0x1a, 0xa7, 0x9d, 0xfe, 0x60, 0xbf, 0xd3, 0xe9, 0xf7, 0xfa, 0x64, 0xaf, + 0xdb, 0x3d, 0x3a, 0x6c, 0x64, 0xd1, 0x0a, 0xd4, 0x7b, 0xfd, 0x0e, 0x39, 0x1a, 0xf4, 0x3b, 0x2f, + 0xf7, 0x7b, 0xfd, 0xce, 0xe9, 0x51, 0x63, 0x11, 0x35, 0x61, 0x75, 0xef, 0x4b, 0x72, 0xb4, 0x77, + 0xf8, 0x75, 0x5c, 0x3c, 0xb7, 0xfb, 0x2f, 0x80, 0x6c, 0xf7, 0x10, 0xed, 0x01, 0x84, 0xcf, 0x2e, + 0xb4, 0xa1, 0xf4, 0x9f, 0x79, 0xcb, 0xb5, 0x9a, 0xb3, 0x0c, 0x65, 0x22, 0x5e, 0x40, 0x4f, 0x61, + 0xb1, 0xcf, 0x1c, 0xa4, 0xd3, 0x32, 0x9c, 0x5e, 0xb7, 0x96, 0x23, 0x14, 0x5f, 0x7a, 0x27, 0xf3, + 0x34, 0x83, 0x7e, 0x0e, 0xa5, 0x60, 0x66, 0x89, 0xd6, 0x95, 0x54, 0x72, 0xba, 0xdb, 0xda, 0x98, + 0xa1, 0x07, 0x3b, 0xbe, 0x84, 0x5a, 0x7c, 0xea, 0x89, 0x1e, 0x2a, 0xe1, 0xb9, 0x13, 0xd5, 0xd6, + 0xa3, 0xf9, 0xcc, 0x00, 0xee, 0x13, 0x58, 0xd2, 0x93, 0x49, 0xa4, 0x0f, 0x30, 0x3e, 0xe7, 0x6c, + 0xad, 0x25, 0xa8, 0xc1, 0xca, 0x4f, 0xa1, 0xe8, 0xcf, 0x09, 0xd1, 0x5a, 0xe0, 0xa2, 0xe8, 0x40, + 0xaf, 0xb5, 0x9e, 0x24, 0x47, 0x17, 0xfb, 0x83, 0x39, 0x7f, 0x71, 0x62, 0x1a, 0xe8, 0x2f, 0x4e, + 0xce, 0xef, 0xf0, 0x02, 0x3a, 0x86, 0x4a, 0x74, 0x9e, 0x86, 0x1e, 0x04, 0xdb, 0x24, 0xe7, 0x74, + 0xad, 0xd6, 0x3c, 0x56, 0xd4, 0x97, 0xf1, 0xa2, 0xe9, 0xfb, 0x72, 0x6e, 0xe1, 0xf6, 0x7d, 0x39, + 0xbf, 0xce, 0xe2, 0x05, 0xd4, 0x87, 0x7a, 0xe2, 0x2e, 0x8f, 0x1e, 0xf9, 0x49, 0x31, 0xef, 0x25, + 0xdb, 0xda, 0xbc, 0x85, 0x9b, 0x0c, 0x98, 0x60, 0xbc, 0x85, 0x42, 0x8f, 0xc6, 0xaa, 0x73, 0x6b, + 0x63, 0x86, 0x1e, 0x68, 0xf5, 0x0c, 0xaa, 0xb1, 0xf1, 0x18, 0x6a, 0x25, 0x64, 0x23, 0x33, 0xb3, + 0xbb, 0x70, 0x3e, 0x85, 0xa2, 0x7f, 0x51, 0xf5, 0x8f, 0x2c, 0x71, 0x43, 0xf6, 0x8f, 0x2c, 0x79, + 0x9f, 0xc5, 0x0b, 0xe8, 0x10, 0xca, 0x91, 0xfb, 0x1c, 0x6a, 0xfa, 0x86, 0x27, 0xef, 0x9b, 0xad, + 0x07, 0x73, 0x38, 0x01, 0x4a, 0x4f, 0xce, 0x36, 0x63, 0x73, 0x25, 0xb4, 0x19, 0x68, 0x3c, 0x6f, + 0xc4, 0xd5, 0xda, 0xba, 0x8d, 0x1d, 0x05, 0x4d, 0x0e, 0xab, 0x7c, 0xd0, 0x5b, 0xe6, 0x66, 0x3e, + 0xe8, 0x6d, 0x33, 0x2e, 0xbc, 0x80, 0xbe, 0x80, 0x6a, 0xac, 0x2b, 0xf9, 0x4e, 0x9f, 0xd7, 0x5a, + 0x5b, 0x0f, 0xe7, 0xf2, 0xa2, 0x51, 0x1a, 0x6f, 0x2a, 0x7e, 0x94, 0xce, 0x6d, 0x58, 0x7e, 0x94, + 0xce, 0xef, 0x43, 0x78, 0x01, 0xfd, 0x02, 0x96, 0x67, 0x8a, 0x3a, 0xd2, 0x16, 0xdd, 0xd6, 0x55, + 0x5a, 0xef, 0xdc, 0xca, 0xf7, 0x71, 0xf7, 0xdf, 0xff, 0xc7, 0xeb, 0xad, 0xcc, 0x3f, 0x5f, 0x6f, + 0x65, 0xfe, 0xfd, 0x7a, 0x2b, 0xf3, 0xe7, 0xff, 0x6c, 0x2d, 0x40, 0x73, 0xe8, 0x4c, 0xda, 0xae, + 0x65, 0x8f, 0x86, 0x86, 0xdb, 0xe6, 0xd6, 0xe5, 0x75, 0xfb, 0xf2, 0x5a, 0xfe, 0xd7, 0xf2, 0xac, + 0x20, 0xff, 0xfc, 0xe4, 0xbf, 0x01, 0x00, 0x00, 0xff, 0xff, 0x62, 0x49, 0x56, 0xcf, 0x03, 0x1d, + 0x00, 0x00, } From d18d0aaec545ec3e0d9196da7dafae21ff9c74a2 Mon Sep 17 00:00:00 2001 From: nolouch Date: Fri, 13 Jul 2018 17:47:06 +0800 Subject: [PATCH 09/30] fix response --- server/grpc_service.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/grpc_service.go b/server/grpc_service.go index 36f0c04e870..b8fcea23752 100644 --- a/server/grpc_service.go +++ b/server/grpc_service.go @@ -597,7 +597,7 @@ func (s *Server) validateRequest(header *pdpb.RequestHeader) error { } func (s *Server) header() *pdpb.ResponseHeader { - return &pdpb.ResponseHeader{ClusterId: s.clusterID, ClusterVersion: s.scheduleOpt.loadClusterVersion().String()} + return &pdpb.ResponseHeader{ClusterId: s.clusterID} } func (s *Server) errorHeader(err *pdpb.Error) *pdpb.ResponseHeader { From 13bccce9734071ba4ec37fa99071b1b374b1a415 Mon Sep 17 00:00:00 2001 From: nolouch Date: Mon, 16 Jul 2018 14:06:43 +0800 Subject: [PATCH 10/30] rename version --- server/api/operator_test.go | 2 +- server/cluster_info.go | 8 ++++---- server/coordinator.go | 2 +- server/coordinator_test.go | 2 +- server/core/kv.go | 1 - server/version.go | 30 +++++++++++++++++------------- 6 files changed, 24 insertions(+), 21 deletions(-) diff --git a/server/api/operator_test.go b/server/api/operator_test.go index a135a6606f1..c354270989a 100644 --- a/server/api/operator_test.go +++ b/server/api/operator_test.go @@ -87,7 +87,7 @@ func mustPutStore(c *C, svr *server.Server, id uint64, state metapb.StoreState, Address: fmt.Sprintf("tikv%d", id), State: state, Labels: labels, - Version: server.TargetVersion(server.VersionRegionMergeAndRaftLearner).String(), + Version: server.MinSupportedVersion(server.Version2_0).String(), }, }) c.Assert(err, IsNil) diff --git a/server/cluster_info.go b/server/cluster_info.go index a876721b36f..3f7428af9a2 100644 --- a/server/cluster_info.go +++ b/server/cluster_info.go @@ -113,10 +113,10 @@ func (c *clusterInfo) OnChangeClusterVersion() { } } -// IsSupport check if support the features. -func (c *clusterInfo) IsSupport(f VersionFeature) bool { +// IsSupported check if support the features. +func (c *clusterInfo) IsSupported(f Feature) bool { clusterVersion := c.opt.loadClusterVersion() - minSupportVersion := TargetVersion(f) + minSupportVersion := MinSupportedVersion(f) if clusterVersion.Less(minSupportVersion) { return false } @@ -663,7 +663,7 @@ func (c *clusterInfo) GetHotRegionLowThreshold() int { } func (c *clusterInfo) IsRaftLearnerEnabled() bool { - if !c.IsSupport(VersionRegionMergeAndRaftLearner) { + if !c.IsSupported(Version2_0) { return false } return c.opt.IsRaftLearnerEnabled() diff --git a/server/coordinator.go b/server/coordinator.go index 10b877b0424..70f1dde5e92 100644 --- a/server/coordinator.go +++ b/server/coordinator.go @@ -178,7 +178,7 @@ func (c *coordinator) checkRegion(region *core.RegionInfo) bool { return true } } - if c.cluster.IsSupport(VersionRegionMergeAndRaftLearner) && c.limiter.OperatorCount(schedule.OpReplica) < c.cluster.GetReplicaScheduleLimit() { + if c.cluster.IsSupported(Version2_0) && c.limiter.OperatorCount(schedule.OpReplica) < c.cluster.GetReplicaScheduleLimit() { if op := c.replicaChecker.Check(region); op != nil { if c.addOperator(op) { return true diff --git a/server/coordinator_test.go b/server/coordinator_test.go index afbbf9d3138..315f36633c9 100644 --- a/server/coordinator_test.go +++ b/server/coordinator_test.go @@ -38,7 +38,7 @@ func newTestScheduleConfig() (*ScheduleConfig, *scheduleOption) { cfg := NewConfig() cfg.adjust(nil) opt := newScheduleOption(cfg) - opt.SetClusterVersion(TargetVersion(VersionRegionMergeAndRaftLearner)) + opt.SetClusterVersion(MinSupportedVersion(Version2_0)) return &cfg.Schedule, opt } diff --git a/server/core/kv.go b/server/core/kv.go index ff89ac872f4..33c0d5ffd18 100644 --- a/server/core/kv.go +++ b/server/core/kv.go @@ -108,7 +108,6 @@ func (kv *KV) DeleteRegion(region *metapb.Region) error { // SaveConfig stores marshalable cfg to the configPath. func (kv *KV) SaveConfig(cfg interface{}) error { value, err := json.Marshal(cfg) - fmt.Println("pesist config:", string(value)) if err != nil { return errors.Trace(err) } diff --git a/server/version.go b/server/version.go index 23e4b2824db..c4d26316de5 100644 --- a/server/version.go +++ b/server/version.go @@ -22,24 +22,28 @@ import ( log "github.com/sirupsen/logrus" ) -// VersionFeature is a unique identifier for minimum support version. -type VersionFeature int +// Feature is now support feature. +type Feature int -// Version Fetures. +// Fetures list. const ( - VersionBase VersionFeature = iota - VersionRegionMergeAndRaftLearner - VersionBatchSplit + Base Feature = iota + Version2_0 + RegionMerge + RaftLearner + BatchSplit ) -var featuresDict = map[VersionFeature]Version{ - VersionBase: {Major: 1}, - VersionRegionMergeAndRaftLearner: {Major: 2, Minor: 0}, - VersionBatchSplit: {Major: 2, Minor: 1}, +var featuresDict = map[Feature]Version{ + Base: {Major: 1}, + Version2_0: {Major: 2}, + RegionMerge: {Major: 2, Minor: 0}, + RaftLearner: {Major: 2, Minor: 0}, + BatchSplit: {Major: 2, Minor: 1, Unstable: 2}, } -// TargetVersion get target version by version feature -func TargetVersion(v VersionFeature) Version { +// MinSupportedVersion returns the minimum support version for the feature. +func MinSupportedVersion(v Feature) Version { target, ok := featuresDict[v] if !ok { log.Fatalf("version not exist, feature %d", v) @@ -118,7 +122,7 @@ func convUnstable(s string) int32 { //The string format should be "major.minor.patch-". func ParseVersion(s string) (Version, error) { if s == "" { - return TargetVersion(VersionBase), nil + return MinSupportedVersion(Base), nil } if strings.HasPrefix(s, "v") { s = s[1:] From 69cf42044a38c65884592d00b670909a26e7d9e3 Mon Sep 17 00:00:00 2001 From: nolouch Date: Mon, 16 Jul 2018 15:25:04 +0800 Subject: [PATCH 11/30] use go-semver --- pkg/integration_test/cluster.go | 3 +- pkg/integration_test/version_upgrade_test.go | 21 +-- server/api/label_test.go | 8 +- server/api/store_test.go | 8 +- server/cluster.go | 5 +- server/cluster_info.go | 25 ++-- server/config.go | 3 +- server/option.go | 7 +- server/server.go | 3 +- server/version.go | 129 +------------------ server/version_test.go | 42 ------ 11 files changed, 46 insertions(+), 208 deletions(-) delete mode 100644 server/version_test.go diff --git a/pkg/integration_test/cluster.go b/pkg/integration_test/cluster.go index d22655cc3eb..7771b9ca42f 100644 --- a/pkg/integration_test/cluster.go +++ b/pkg/integration_test/cluster.go @@ -20,6 +20,7 @@ import ( "time" "github.com/coreos/etcd/clientv3" + "github.com/coreos/go-semver/semver" "github.com/juju/errors" "github.com/pingcap/kvproto/pkg/pdpb" "github.com/pingcap/pd/server" @@ -116,7 +117,7 @@ func (s *testServer) GetClusterID() uint64 { return s.server.ClusterID() } -func (s *testServer) GetClusterVersion() server.Version { +func (s *testServer) GetClusterVersion() semver.Version { s.RLock() defer s.RUnlock() return s.server.ClusterVersion() diff --git a/pkg/integration_test/version_upgrade_test.go b/pkg/integration_test/version_upgrade_test.go index 882fc710fe6..cd9bcb3a6ed 100644 --- a/pkg/integration_test/version_upgrade_test.go +++ b/pkg/integration_test/version_upgrade_test.go @@ -16,6 +16,7 @@ package integration import ( "context" + "github.com/coreos/go-semver/semver" . "github.com/pingcap/check" "github.com/pingcap/kvproto/pkg/metapb" "github.com/pingcap/kvproto/pkg/pdpb" @@ -57,7 +58,7 @@ func (s *versionTestSuite) TestStoreRegister(c *C) { Store: &metapb.Store{ Id: 1, Address: "mock-1", - Version: "v2.0.1", + Version: "2.0.1", }, } _, err = leaderServer.server.PutStore(context.Background(), putStoreRequest) @@ -82,7 +83,7 @@ func (s *versionTestSuite) TestStoreRegister(c *C) { Store: &metapb.Store{ Id: 4, Address: "mock-4", - Version: "v1.0.1", + Version: "1.0.1", }, } _, err = leaderServer.server.PutStore(context.Background(), putStoreRequest) @@ -106,7 +107,7 @@ func (s *versionTestSuite) TestRollingUpgrade(c *C) { Store: &metapb.Store{ Id: 1, Address: "mock-1", - Version: "v2.0.1", + Version: "2.0.1", }, }, { @@ -114,7 +115,7 @@ func (s *versionTestSuite) TestRollingUpgrade(c *C) { Store: &metapb.Store{ Id: 4, Address: "mock-4", - Version: "v2.0.1", + Version: "2.0.1", }, }, { @@ -122,7 +123,7 @@ func (s *versionTestSuite) TestRollingUpgrade(c *C) { Store: &metapb.Store{ Id: 6, Address: "mock-6", - Version: "v2.0.1", + Version: "2.0.1", }, }, { @@ -130,7 +131,7 @@ func (s *versionTestSuite) TestRollingUpgrade(c *C) { Store: &metapb.Store{ Id: 7, Address: "mock-7", - Version: "v2.0.1", + Version: "2.0.1", }, }, } @@ -138,16 +139,16 @@ func (s *versionTestSuite) TestRollingUpgrade(c *C) { _, err = leaderServer.server.PutStore(context.Background(), store) c.Assert(err, IsNil) } - c.Assert(leaderServer.GetClusterVersion(), Equals, server.Version{Major: 2, Minor: 0, Patch: 1}) + c.Assert(leaderServer.GetClusterVersion(), Equals, semver.Version{Major: 2, Minor: 0, Patch: 1}) // rolling update for i, store := range stores { - store.Store.Version = "v2.1.0" + store.Store.Version = "2.1.0" resp, err := leaderServer.server.PutStore(context.Background(), store) c.Assert(err, IsNil) if i != len(stores)-1 { - c.Assert(leaderServer.GetClusterVersion(), Equals, server.Version{Major: 2, Minor: 0, Patch: 1}) + c.Assert(leaderServer.GetClusterVersion(), Equals, semver.Version{Major: 2, Minor: 0, Patch: 1}) c.Assert(resp.GetHeader().GetError(), IsNil) } } - c.Assert(leaderServer.GetClusterVersion(), Equals, server.Version{Major: 2, Minor: 1}) + c.Assert(leaderServer.GetClusterVersion(), Equals, semver.Version{Major: 2, Minor: 1}) } diff --git a/server/api/label_test.go b/server/api/label_test.go index 4738f5abafc..105d5ecc89b 100644 --- a/server/api/label_test.go +++ b/server/api/label_test.go @@ -46,7 +46,7 @@ func (s *testLabelsStoreSuite) SetUpSuite(c *C) { Value: "ssd", }, }, - Version: "v2.0.0", + Version: "2.0.0", }, { Id: 4, @@ -62,7 +62,7 @@ func (s *testLabelsStoreSuite) SetUpSuite(c *C) { Value: "hdd", }, }, - Version: "v2.0.0", + Version: "2.0.0", }, { Id: 6, @@ -78,7 +78,7 @@ func (s *testLabelsStoreSuite) SetUpSuite(c *C) { Value: "ssd", }, }, - Version: "v2.0.0", + Version: "2.0.0", }, { Id: 7, @@ -98,7 +98,7 @@ func (s *testLabelsStoreSuite) SetUpSuite(c *C) { Value: "test", }, }, - Version: "v2.0.0", + Version: "2.0.0", }, } diff --git a/server/api/store_test.go b/server/api/store_test.go index d733fb40e97..c0832cbc8c2 100644 --- a/server/api/store_test.go +++ b/server/api/store_test.go @@ -44,27 +44,27 @@ func (s *testStoreSuite) SetUpSuite(c *C) { Id: 1, Address: "tikv1", State: metapb.StoreState_Up, - Version: "v2.0.0", + Version: "2.0.0", }, { Id: 4, Address: "tikv4", State: metapb.StoreState_Up, - Version: "v2.0.0", + Version: "2.0.0", }, { // metapb.StoreState_Offline == 1 Id: 6, Address: "tikv6", State: metapb.StoreState_Offline, - Version: "v2.0.0", + Version: "2.0.0", }, { // metapb.StoreState_Tombstone == 2 Id: 7, Address: "tikv7", State: metapb.StoreState_Tombstone, - Version: "v2.0.0", + Version: "2.0.0", }, } diff --git a/server/cluster.go b/server/cluster.go index f0ac7eace21..36a1d852cf7 100644 --- a/server/cluster.go +++ b/server/cluster.go @@ -15,6 +15,7 @@ package server import ( "fmt" + "github.com/coreos/go-semver/semver" "path" "sync" "time" @@ -290,12 +291,12 @@ func (c *RaftCluster) putStore(store *metapb.Store) error { return errors.Errorf("invalid put store %v", store) } - v, err := ParseVersion(store.GetVersion()) + v, err := semver.NewVersion(store.GetVersion()) if err != nil { return errors.Errorf("invalid put store %s", err) } clusterVersion := c.cachedCluster.opt.loadClusterVersion() - if v.Less(clusterVersion) { + if v.LessThan(clusterVersion) { return errors.Errorf("version should compatible with version %s, got %s", clusterVersion, v) } diff --git a/server/cluster_info.go b/server/cluster_info.go index 3f7428af9a2..494f7b15c9e 100644 --- a/server/cluster_info.go +++ b/server/cluster_info.go @@ -17,6 +17,7 @@ import ( "sync" "time" + "github.com/coreos/go-semver/semver" "github.com/gogo/protobuf/proto" "github.com/juju/errors" "github.com/pingcap/kvproto/pkg/metapb" @@ -80,8 +81,8 @@ func loadClusterInfo(id core.IDAllocator, kv *core.KV, opt *scheduleOption) (*cl func (c *clusterInfo) OnChangeClusterVersion() { var ( - minVersion Version - clusterVersion Version + minVersion semver.Version + clusterVersion semver.Version ) clusterVersion = c.opt.loadClusterVersion() @@ -91,22 +92,16 @@ func (c *clusterInfo) OnChangeClusterVersion() { continue } if i == 0 { - v, err := ParseVersion(s.GetVersion()) - if err != nil { - log.Fatalf("on change cluster version meet error: %s", err) - } - minVersion = v + minVersion = *semver.New(s.GetVersion()) continue } - v, err := ParseVersion(s.GetVersion()) - if err != nil { - log.Fatalf("on change cluster version: %s", err) - } - if v.Less(minVersion) { - minVersion = v + v := semver.New(s.GetVersion()) + + if v.LessThan(minVersion) { + minVersion = *v } } - if clusterVersion.Less(minVersion) { + if clusterVersion.LessThan(minVersion) { c.opt.SetClusterVersion(minVersion) c.opt.persist(c.kv) log.Infof("cluster version changed from %s to %s", clusterVersion, minVersion) @@ -117,7 +112,7 @@ func (c *clusterInfo) OnChangeClusterVersion() { func (c *clusterInfo) IsSupported(f Feature) bool { clusterVersion := c.opt.loadClusterVersion() minSupportVersion := MinSupportedVersion(f) - if clusterVersion.Less(minSupportVersion) { + if clusterVersion.LessThan(minSupportVersion) { return false } return true diff --git a/server/config.go b/server/config.go index b1802ebe5d1..7c0a4880e4f 100644 --- a/server/config.go +++ b/server/config.go @@ -26,6 +26,7 @@ import ( "github.com/BurntSushi/toml" "github.com/coreos/etcd/embed" "github.com/coreos/etcd/pkg/transport" + "github.com/coreos/go-semver/semver" "github.com/juju/errors" "github.com/pingcap/pd/pkg/logutil" "github.com/pingcap/pd/pkg/metricutil" @@ -77,7 +78,7 @@ type Config struct { Namespace map[string]NamespaceConfig `json:"namespace"` - ClusterVersion Version `json:"cluster-version"` + ClusterVersion semver.Version `json:"cluster-version"` // QuotaBackendBytes Raise alarms when backend size exceeds the given quota. 0 means use the default quota. // the default size is 2GB, the maximum is 8GB. diff --git a/server/option.go b/server/option.go index 05ff738ec77..d476f63f24d 100644 --- a/server/option.go +++ b/server/option.go @@ -18,6 +18,7 @@ import ( "sync/atomic" "time" + "github.com/coreos/go-semver/semver" "github.com/juju/errors" "github.com/pingcap/kvproto/pkg/metapb" "github.com/pingcap/pd/server/core" @@ -247,12 +248,12 @@ func (o *scheduleOption) loadLabelPropertyConfig() LabelPropertyConfig { return o.labelProperty.Load().(LabelPropertyConfig) } -func (o *scheduleOption) SetClusterVersion(v Version) { +func (o *scheduleOption) SetClusterVersion(v semver.Version) { o.clusterVersion.Store(v) } -func (o *scheduleOption) loadClusterVersion() Version { - return o.clusterVersion.Load().(Version) +func (o *scheduleOption) loadClusterVersion() semver.Version { + return o.clusterVersion.Load().(semver.Version) } func (o *scheduleOption) persist(kv *core.KV) error { diff --git a/server/server.go b/server/server.go index 45fd033820f..7373b989961 100644 --- a/server/server.go +++ b/server/server.go @@ -28,6 +28,7 @@ import ( "github.com/coreos/etcd/clientv3" "github.com/coreos/etcd/embed" "github.com/coreos/etcd/pkg/types" + "github.com/coreos/go-semver/semver" "github.com/juju/errors" "github.com/pingcap/kvproto/pkg/metapb" "github.com/pingcap/kvproto/pkg/pdpb" @@ -401,7 +402,7 @@ func (s *Server) ClusterID() uint64 { } // ClusterVersion returns the cluster version of this server. -func (s *Server) ClusterVersion() Version { +func (s *Server) ClusterVersion() semver.Version { return s.scheduleOpt.loadClusterVersion() } diff --git a/server/version.go b/server/version.go index c4d26316de5..4aa4bcfaa1d 100644 --- a/server/version.go +++ b/server/version.go @@ -14,11 +14,7 @@ package server import ( - "fmt" - "strconv" - "strings" - - "github.com/juju/errors" + "github.com/coreos/go-semver/semver" log "github.com/sirupsen/logrus" ) @@ -34,136 +30,19 @@ const ( BatchSplit ) -var featuresDict = map[Feature]Version{ +var featuresDict = map[Feature]semver.Version{ Base: {Major: 1}, Version2_0: {Major: 2}, RegionMerge: {Major: 2, Minor: 0}, RaftLearner: {Major: 2, Minor: 0}, - BatchSplit: {Major: 2, Minor: 1, Unstable: 2}, + BatchSplit: {Major: 2, Minor: 1, PreRelease: "beta"}, } // MinSupportedVersion returns the minimum support version for the feature. -func MinSupportedVersion(v Feature) Version { +func MinSupportedVersion(v Feature) semver.Version { target, ok := featuresDict[v] if !ok { log.Fatalf("version not exist, feature %d", v) } return target } - -// Version record version information. -type Version struct { - Major int32 - Minor int32 - Patch int32 - Unstable int32 - UnstablePatch int32 -} - -// Less compare two version. -func (v *Version) Less(ov Version) bool { - if v.Major < ov.Major { - return true - } else if v.Major > ov.Major { - return false - } - if v.Minor < ov.Minor { - return true - } else if v.Minor > ov.Minor { - return false - } - if v.Patch < ov.Patch { - return true - } else if v.Patch > ov.Patch { - return false - } - if v.Unstable < ov.Unstable { - return true - } else if v.Unstable > ov.Unstable { - return false - } - if v.UnstablePatch < ov.UnstablePatch { - return true - } - return false -} - -func (v Version) String() string { - convMap := map[int32]string{ - 1: "alpha", - 2: "beta", - 3: "rc", - } - var res string - if unstable, ok := convMap[v.Unstable]; ok { - res = fmt.Sprintf("v%d.%d.%d-%s", v.Major, v.Minor, v.Patch, unstable) - if v.UnstablePatch > 0 { - res = fmt.Sprintf("%s.%d", res, v.UnstablePatch) - } - return res - } - res = fmt.Sprintf("v%d.%d.%d", v.Major, v.Minor, v.Patch) - return res -} - -func convUnstable(s string) int32 { - innerMap := map[string]int32{ - "alpha": 1, - "beta": 2, - "rc": 3, - } - if res, ok := innerMap[s]; ok { - return res - } - return -1 -} - -//ParseVersion parses a version from a string. -//The string format should be "major.minor.patch-". -func ParseVersion(s string) (Version, error) { - if s == "" { - return MinSupportedVersion(Base), nil - } - if strings.HasPrefix(s, "v") { - s = s[1:] - } - splits := strings.Split(s, ".") - if len(splits) != 3 && len(splits) != 4 { - return Version{}, errors.Errorf("invalid version: %s", s) - } - patchAndUnstable := strings.Split(splits[2], "-") - - parts := append(splits[:2], patchAndUnstable...) - if len(splits) == 4 { - parts = append(parts, splits[3]) - } - for i := len(parts); i < 5; i++ { - parts = append(parts, "0") - } - ints := make([]int32, len(parts)) - for i, part := range parts { - if i == 3 && part != "0" { - r := convUnstable(part) - if r < 0 { - return Version{}, errors.Errorf("invalid version: %s ", s) - } - ints[i] = r - continue - } - var ( - val int64 - err error - ) - if val, err = strconv.ParseInt(part, 10, 32); err != nil { - return Version{}, errors.Errorf("invalid version: %s ", s) - } - ints[i] = int32(val) - } - return Version{ - Major: ints[0], - Minor: ints[1], - Patch: ints[2], - Unstable: ints[3], - UnstablePatch: ints[4], - }, nil -} diff --git a/server/version_test.go b/server/version_test.go deleted file mode 100644 index 810dae26ee4..00000000000 --- a/server/version_test.go +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright 2018 PingCAP, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// See the License for the specific language governing permissions and -// limitations under the License. - -package server - -import ( - . "github.com/pingcap/check" -) - -var _ = Suite(&testVersion{}) - -type testVersion struct{} - -func (t *testVersion) TestVersion(c *C) { - vers := []string{ - "", - "v1.0.1", - "v1.0.1-beta", - "v2.0.1", - "2.1.0", - } - var ( - lastVersion Version - newVersion Version - err error - ) - for _, ver := range vers { - newVersion, err = ParseVersion(ver) - c.Assert(err, IsNil) - c.Assert(lastVersion.Less(newVersion), IsTrue) - } -} From 9d81d8442746b536ddf477d09dc95fbcf04a4923 Mon Sep 17 00:00:00 2001 From: nolouch Date: Mon, 16 Jul 2018 16:43:01 +0800 Subject: [PATCH 12/30] fix tests --- pkg/integration_test/version_upgrade_test.go | 15 ++++--------- server/cluster.go | 5 ++--- server/cluster_info.go | 4 ++-- server/version.go | 23 ++++++++++++++++++-- 4 files changed, 29 insertions(+), 18 deletions(-) diff --git a/pkg/integration_test/version_upgrade_test.go b/pkg/integration_test/version_upgrade_test.go index cd9bcb3a6ed..b3bc7026c43 100644 --- a/pkg/integration_test/version_upgrade_test.go +++ b/pkg/integration_test/version_upgrade_test.go @@ -20,18 +20,11 @@ import ( . "github.com/pingcap/check" "github.com/pingcap/kvproto/pkg/metapb" "github.com/pingcap/kvproto/pkg/pdpb" - "github.com/pingcap/pd/server" ) -var _ = Suite(&versionTestSuite{}) +var _ = Suite(&integrationTestSuite{}) -type versionTestSuite struct{} - -func (s *versionTestSuite) SetUpSuite(c *C) { - server.EnableZap = true -} - -func (s *versionTestSuite) bootstrapCluster(server *testServer, c *C) { +func (s *integrationTestSuite) bootstrapCluster(server *testServer, c *C) { bootstrapReq := &pdpb.BootstrapRequest{ Header: &pdpb.RequestHeader{ClusterId: server.GetClusterID()}, Store: &metapb.Store{Id: 1, Address: "mock://1"}, @@ -41,7 +34,7 @@ func (s *versionTestSuite) bootstrapCluster(server *testServer, c *C) { c.Assert(err, IsNil) } -func (s *versionTestSuite) TestStoreRegister(c *C) { +func (s *integrationTestSuite) TestStoreRegister(c *C) { c.Parallel() cluster, err := newTestCluster(3) c.Assert(err, IsNil) @@ -90,7 +83,7 @@ func (s *versionTestSuite) TestStoreRegister(c *C) { c.Assert(err, NotNil) } -func (s *versionTestSuite) TestRollingUpgrade(c *C) { +func (s *integrationTestSuite) TestRollingUpgrade(c *C) { c.Parallel() cluster, err := newTestCluster(3) c.Assert(err, IsNil) diff --git a/server/cluster.go b/server/cluster.go index 36a1d852cf7..fffe582e670 100644 --- a/server/cluster.go +++ b/server/cluster.go @@ -15,7 +15,6 @@ package server import ( "fmt" - "github.com/coreos/go-semver/semver" "path" "sync" "time" @@ -291,9 +290,9 @@ func (c *RaftCluster) putStore(store *metapb.Store) error { return errors.Errorf("invalid put store %v", store) } - v, err := semver.NewVersion(store.GetVersion()) + v, err := ParseVersion(store.GetVersion()) if err != nil { - return errors.Errorf("invalid put store %s", err) + return errors.Errorf("invalid put store %v, error: %s", store, err) } clusterVersion := c.cachedCluster.opt.loadClusterVersion() if v.LessThan(clusterVersion) { diff --git a/server/cluster_info.go b/server/cluster_info.go index 494f7b15c9e..4b9cc75f678 100644 --- a/server/cluster_info.go +++ b/server/cluster_info.go @@ -92,10 +92,10 @@ func (c *clusterInfo) OnChangeClusterVersion() { continue } if i == 0 { - minVersion = *semver.New(s.GetVersion()) + minVersion = *MustParseVersion(s.GetVersion()) continue } - v := semver.New(s.GetVersion()) + v := MustParseVersion(s.GetVersion()) if v.LessThan(minVersion) { minVersion = *v diff --git a/server/version.go b/server/version.go index 4aa4bcfaa1d..22aeb107529 100644 --- a/server/version.go +++ b/server/version.go @@ -18,7 +18,7 @@ import ( log "github.com/sirupsen/logrus" ) -// Feature is now support feature. +// Feature supported features. type Feature int // Fetures list. @@ -38,7 +38,7 @@ var featuresDict = map[Feature]semver.Version{ BatchSplit: {Major: 2, Minor: 1, PreRelease: "beta"}, } -// MinSupportedVersion returns the minimum support version for the feature. +// MinSupportedVersion returns the minimum support version for the specified feature. func MinSupportedVersion(v Feature) semver.Version { target, ok := featuresDict[v] if !ok { @@ -46,3 +46,22 @@ func MinSupportedVersion(v Feature) semver.Version { } return target } + +// ParseVersion parses a string to Version. +func ParseVersion(v string) (*semver.Version, error) { + // for compatibility with old version which not support `version` mechanism. + baseVersion := MinSupportedVersion(Base) + if v == "" { + return &baseVersion, nil + } + return semver.NewVersion(v) +} + +// MustParseVersion wrapping ParseVersion and will panic if err is not nil. +func MustParseVersion(v string) *semver.Version { + ver, err := ParseVersion(v) + if err != nil { + log.Fatalf("version string is illegal: %s", err) + } + return ver +} From 9e6866ea64bb5d355c32f2fdf71cb632252455f2 Mon Sep 17 00:00:00 2001 From: nolouch Date: Mon, 16 Jul 2018 17:34:34 +0800 Subject: [PATCH 13/30] clean up --- pkg/integration_test/version_upgrade_test.go | 2 -- server/cluster.go | 2 +- server/cluster_info.go | 4 ++-- server/coordinator.go | 4 ++-- server/version.go | 10 +++++++++- 5 files changed, 14 insertions(+), 8 deletions(-) diff --git a/pkg/integration_test/version_upgrade_test.go b/pkg/integration_test/version_upgrade_test.go index b3bc7026c43..aa8c725f6c4 100644 --- a/pkg/integration_test/version_upgrade_test.go +++ b/pkg/integration_test/version_upgrade_test.go @@ -22,8 +22,6 @@ import ( "github.com/pingcap/kvproto/pkg/pdpb" ) -var _ = Suite(&integrationTestSuite{}) - func (s *integrationTestSuite) bootstrapCluster(server *testServer, c *C) { bootstrapReq := &pdpb.BootstrapRequest{ Header: &pdpb.RequestHeader{ClusterId: server.GetClusterID()}, diff --git a/server/cluster.go b/server/cluster.go index fffe582e670..9801db22a63 100644 --- a/server/cluster.go +++ b/server/cluster.go @@ -295,7 +295,7 @@ func (c *RaftCluster) putStore(store *metapb.Store) error { return errors.Errorf("invalid put store %v, error: %s", store, err) } clusterVersion := c.cachedCluster.opt.loadClusterVersion() - if v.LessThan(clusterVersion) { + if !IsCompatible(clusterVersion, *v) { return errors.Errorf("version should compatible with version %s, got %s", clusterVersion, v) } diff --git a/server/cluster_info.go b/server/cluster_info.go index 4b9cc75f678..a397ed9d6a0 100644 --- a/server/cluster_info.go +++ b/server/cluster_info.go @@ -108,7 +108,7 @@ func (c *clusterInfo) OnChangeClusterVersion() { } } -// IsSupported check if support the features. +// IsSupported check if support the feature. func (c *clusterInfo) IsSupported(f Feature) bool { clusterVersion := c.opt.loadClusterVersion() minSupportVersion := MinSupportedVersion(f) @@ -658,7 +658,7 @@ func (c *clusterInfo) GetHotRegionLowThreshold() int { } func (c *clusterInfo) IsRaftLearnerEnabled() bool { - if !c.IsSupported(Version2_0) { + if !c.IsSupported(RaftLearner) { return false } return c.opt.IsRaftLearnerEnabled() diff --git a/server/coordinator.go b/server/coordinator.go index 70f1dde5e92..b89527f7de4 100644 --- a/server/coordinator.go +++ b/server/coordinator.go @@ -178,14 +178,14 @@ func (c *coordinator) checkRegion(region *core.RegionInfo) bool { return true } } - if c.cluster.IsSupported(Version2_0) && c.limiter.OperatorCount(schedule.OpReplica) < c.cluster.GetReplicaScheduleLimit() { + if c.cluster.IsSupported(RaftLearner) && c.limiter.OperatorCount(schedule.OpReplica) < c.cluster.GetReplicaScheduleLimit() { if op := c.replicaChecker.Check(region); op != nil { if c.addOperator(op) { return true } } } - if c.limiter.OperatorCount(schedule.OpMerge) < c.cluster.GetMergeScheduleLimit() { + if c.cluster.IsSupported(RegionMerge) && c.limiter.OperatorCount(schedule.OpMerge) < c.cluster.GetMergeScheduleLimit() { if op1, op2 := c.mergeChecker.Check(region); op1 != nil && op2 != nil { // make sure two operators can add successfully altogether if c.addOperator(op1, op2) { diff --git a/server/version.go b/server/version.go index 22aeb107529..cf607f81e2b 100644 --- a/server/version.go +++ b/server/version.go @@ -35,7 +35,7 @@ var featuresDict = map[Feature]semver.Version{ Version2_0: {Major: 2}, RegionMerge: {Major: 2, Minor: 0}, RaftLearner: {Major: 2, Minor: 0}, - BatchSplit: {Major: 2, Minor: 1, PreRelease: "beta"}, + BatchSplit: {Major: 2, Minor: 1}, } // MinSupportedVersion returns the minimum support version for the specified feature. @@ -65,3 +65,11 @@ func MustParseVersion(v string) *semver.Version { } return ver } + +// IsCompatible checks if the clusterVersion is compatible with the specify version. +func IsCompatible(clusterVersion, v semver.Version) bool { + if clusterVersion.LessThan(v) { + return true + } + return clusterVersion.Major == v.Major && clusterVersion.Minor == v.Minor +} From f51bacf0eb26c15993b55a9aba671fbc0b59e8a7 Mon Sep 17 00:00:00 2001 From: nolouch Date: Mon, 16 Jul 2018 17:39:29 +0800 Subject: [PATCH 14/30] handle onchange cluster version failed situation --- server/cluster.go | 1 + 1 file changed, 1 insertion(+) diff --git a/server/cluster.go b/server/cluster.go index 9801db22a63..0763db6e22e 100644 --- a/server/cluster.go +++ b/server/cluster.go @@ -526,6 +526,7 @@ func (c *RaftCluster) runBackgroundJobs(interval time.Duration) { c.checkStores() c.collectMetrics() c.coordinator.pruneHistory() + c.cachedCluster.OnChangeClusterVersion() } } } From 365da06116c18ffbd7dbe5211bc3f59be1a223b5 Mon Sep 17 00:00:00 2001 From: nolouch Date: Mon, 16 Jul 2018 19:52:05 +0800 Subject: [PATCH 15/30] address comments --- pkg/integration_test/version_upgrade_test.go | 3 +++ server/cluster_info.go | 27 ++++++++------------ server/coordinator.go | 4 +-- 3 files changed, 15 insertions(+), 19 deletions(-) diff --git a/pkg/integration_test/version_upgrade_test.go b/pkg/integration_test/version_upgrade_test.go index aa8c725f6c4..6846441a1c2 100644 --- a/pkg/integration_test/version_upgrade_test.go +++ b/pkg/integration_test/version_upgrade_test.go @@ -133,6 +133,9 @@ func (s *integrationTestSuite) TestRollingUpgrade(c *C) { c.Assert(leaderServer.GetClusterVersion(), Equals, semver.Version{Major: 2, Minor: 0, Patch: 1}) // rolling update for i, store := range stores { + if i == 0 { + store.Store.State = metapb.StoreState_Tombstone + } store.Store.Version = "2.1.0" resp, err := leaderServer.server.PutStore(context.Background(), store) c.Assert(err, IsNil) diff --git a/server/cluster_info.go b/server/cluster_info.go index a397ed9d6a0..c647937882b 100644 --- a/server/cluster_info.go +++ b/server/cluster_info.go @@ -81,41 +81,34 @@ func loadClusterInfo(id core.IDAllocator, kv *core.KV, opt *scheduleOption) (*cl func (c *clusterInfo) OnChangeClusterVersion() { var ( - minVersion semver.Version + minVersion *semver.Version clusterVersion semver.Version ) clusterVersion = c.opt.loadClusterVersion() stores := c.GetStores() - for i, s := range stores { + for _, s := range stores { if s.IsTombstone() { continue } - if i == 0 { - minVersion = *MustParseVersion(s.GetVersion()) - continue - } v := MustParseVersion(s.GetVersion()) - if v.LessThan(minVersion) { - minVersion = *v + if minVersion == nil || v.LessThan(*minVersion) { + minVersion = v } } - if clusterVersion.LessThan(minVersion) { - c.opt.SetClusterVersion(minVersion) + if clusterVersion.LessThan(*minVersion) { + c.opt.SetClusterVersion(*minVersion) c.opt.persist(c.kv) log.Infof("cluster version changed from %s to %s", clusterVersion, minVersion) } } -// IsSupported check if support the feature. -func (c *clusterInfo) IsSupported(f Feature) bool { +// IsFeatureSupported check if support the feature. +func (c *clusterInfo) IsFeatureSupported(f Feature) bool { clusterVersion := c.opt.loadClusterVersion() minSupportVersion := MinSupportedVersion(f) - if clusterVersion.LessThan(minSupportVersion) { - return false - } - return true + return !clusterVersion.LessThan(minSupportVersion) } func (c *clusterInfo) allocID() (uint64, error) { @@ -658,7 +651,7 @@ func (c *clusterInfo) GetHotRegionLowThreshold() int { } func (c *clusterInfo) IsRaftLearnerEnabled() bool { - if !c.IsSupported(RaftLearner) { + if !c.IsFeatureSupported(RaftLearner) { return false } return c.opt.IsRaftLearnerEnabled() diff --git a/server/coordinator.go b/server/coordinator.go index b89527f7de4..64b1c428987 100644 --- a/server/coordinator.go +++ b/server/coordinator.go @@ -178,14 +178,14 @@ func (c *coordinator) checkRegion(region *core.RegionInfo) bool { return true } } - if c.cluster.IsSupported(RaftLearner) && c.limiter.OperatorCount(schedule.OpReplica) < c.cluster.GetReplicaScheduleLimit() { + if c.cluster.IsFeatureSupported(RaftLearner) && c.limiter.OperatorCount(schedule.OpReplica) < c.cluster.GetReplicaScheduleLimit() { if op := c.replicaChecker.Check(region); op != nil { if c.addOperator(op) { return true } } } - if c.cluster.IsSupported(RegionMerge) && c.limiter.OperatorCount(schedule.OpMerge) < c.cluster.GetMergeScheduleLimit() { + if c.cluster.IsFeatureSupported(RegionMerge) && c.limiter.OperatorCount(schedule.OpMerge) < c.cluster.GetMergeScheduleLimit() { if op1, op2 := c.mergeChecker.Check(region); op1 != nil && op2 != nil { // make sure two operators can add successfully altogether if c.addOperator(op1, op2) { From e1a3e655a11fce5a045a491b92dbedc4e58673db Mon Sep 17 00:00:00 2001 From: nolouch Date: Mon, 16 Jul 2018 19:57:24 +0800 Subject: [PATCH 16/30] rename to OnStoreVersionChange --- server/cluster.go | 2 +- server/cluster_info.go | 2 +- server/grpc_service.go | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/server/cluster.go b/server/cluster.go index 0763db6e22e..c7f5a5b2821 100644 --- a/server/cluster.go +++ b/server/cluster.go @@ -526,7 +526,7 @@ func (c *RaftCluster) runBackgroundJobs(interval time.Duration) { c.checkStores() c.collectMetrics() c.coordinator.pruneHistory() - c.cachedCluster.OnChangeClusterVersion() + c.cachedCluster.OnStoreVersionChange() } } } diff --git a/server/cluster_info.go b/server/cluster_info.go index c647937882b..1f3b10115c5 100644 --- a/server/cluster_info.go +++ b/server/cluster_info.go @@ -79,7 +79,7 @@ func loadClusterInfo(id core.IDAllocator, kv *core.KV, opt *scheduleOption) (*cl return c, nil } -func (c *clusterInfo) OnChangeClusterVersion() { +func (c *clusterInfo) OnStoreVersionChange() { var ( minVersion *semver.Version clusterVersion semver.Version diff --git a/server/grpc_service.go b/server/grpc_service.go index b8fcea23752..66779f1ee52 100644 --- a/server/grpc_service.go +++ b/server/grpc_service.go @@ -218,7 +218,7 @@ func (s *Server) PutStore(ctx context.Context, request *pdpb.PutStoreRequest) (* } log.Infof("put store ok - %v", store) - cluster.cachedCluster.OnChangeClusterVersion() + cluster.cachedCluster.OnStoreVersionChange() return &pdpb.PutStoreResponse{ Header: s.header(), From 2eaabf1b0cf81aa303468891d677412b28275b1f Mon Sep 17 00:00:00 2001 From: nolouch Date: Mon, 16 Jul 2018 20:01:29 +0800 Subject: [PATCH 17/30] address comment --- server/cluster_info.go | 2 +- server/server.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/server/cluster_info.go b/server/cluster_info.go index 1f3b10115c5..ef393be3179 100644 --- a/server/cluster_info.go +++ b/server/cluster_info.go @@ -104,7 +104,7 @@ func (c *clusterInfo) OnStoreVersionChange() { } } -// IsFeatureSupported check if support the feature. +// IsFeatureSupported checks if the feature is supported by current cluster. func (c *clusterInfo) IsFeatureSupported(f Feature) bool { clusterVersion := c.opt.loadClusterVersion() minSupportVersion := MinSupportedVersion(f) diff --git a/server/server.go b/server/server.go index 7373b989961..f2311027880 100644 --- a/server/server.go +++ b/server/server.go @@ -401,7 +401,7 @@ func (s *Server) ClusterID() uint64 { return s.clusterID } -// ClusterVersion returns the cluster version of this server. +// ClusterVersion returns the version of the cluster. func (s *Server) ClusterVersion() semver.Version { return s.scheduleOpt.loadClusterVersion() } From 0a1cea3fcb960e583383b6b3876194c45eca76b0 Mon Sep 17 00:00:00 2001 From: nolouch Date: Tue, 17 Jul 2018 13:20:14 +0800 Subject: [PATCH 18/30] supported pd-ctl set cluster version --- pdctl/command/config_command.go | 35 +++++++++++++++++++++++++++------ pkg/integration_test/cluster.go | 2 +- server/api/config.go | 22 +++++++++++++++++++++ server/api/router.go | 2 ++ server/leader.go | 1 + server/server.go | 23 +++++++++++++++++----- server/version.go | 2 +- 7 files changed, 74 insertions(+), 13 deletions(-) diff --git a/pdctl/command/config_command.go b/pdctl/command/config_command.go index 37a0852dadf..d710588e81b 100644 --- a/pdctl/command/config_command.go +++ b/pdctl/command/config_command.go @@ -25,11 +25,12 @@ import ( ) var ( - configPrefix = "pd/api/v1/config" - schedulePrefix = "pd/api/v1/config/schedule" - replicationPrefix = "pd/api/v1/config/replicate" - namespacePrefix = "pd/api/v1/config/namespace" - labelPropertyPrefix = "pd/api/v1/config/label-property" + configPrefix = "pd/api/v1/config" + schedulePrefix = "pd/api/v1/config/schedule" + replicationPrefix = "pd/api/v1/config/replicate" + namespacePrefix = "pd/api/v1/config/namespace" + labelPropertyPrefix = "pd/api/v1/config/label-property" + clusterVersionPrefix = "pd/api/v1/config/cluster-version" ) // NewConfigCommand return a config subcommand of rootCmd @@ -101,12 +102,13 @@ func NewShowLabelPropertyCommand() *cobra.Command { // NewSetConfigCommand return a set subcommand of configCmd func NewSetConfigCommand() *cobra.Command { sc := &cobra.Command{ - Use: "set