diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json index 75a1a6f0e6d..05967728763 100644 --- a/Godeps/Godeps.json +++ b/Godeps/Godeps.json @@ -353,263 +353,263 @@ }, { "ImportPath": "github.com/coreos/etcd/alarm", - "Comment": "v3.0.10", - "Rev": "546c0f7ed65523c24390f0f26c7e4af2232f52d2" + "Comment": "v3.0.12", + "Rev": "2d1e2e8e646e65f73ca0d9ee905a5343d6135a50" }, { "ImportPath": "github.com/coreos/etcd/auth", - "Comment": "v3.0.10", - "Rev": "546c0f7ed65523c24390f0f26c7e4af2232f52d2" + "Comment": "v3.0.12", + "Rev": "2d1e2e8e646e65f73ca0d9ee905a5343d6135a50" }, { "ImportPath": "github.com/coreos/etcd/auth/authpb", - "Comment": "v3.0.10", - "Rev": "546c0f7ed65523c24390f0f26c7e4af2232f52d2" + "Comment": "v3.0.12", + "Rev": "2d1e2e8e646e65f73ca0d9ee905a5343d6135a50" }, { "ImportPath": "github.com/coreos/etcd/client", - "Comment": "v3.0.10", - "Rev": "546c0f7ed65523c24390f0f26c7e4af2232f52d2" + "Comment": "v3.0.12", + "Rev": "2d1e2e8e646e65f73ca0d9ee905a5343d6135a50" }, { "ImportPath": "github.com/coreos/etcd/clientv3", - "Comment": "v3.0.10", - "Rev": "546c0f7ed65523c24390f0f26c7e4af2232f52d2" + "Comment": "v3.0.12", + "Rev": "2d1e2e8e646e65f73ca0d9ee905a5343d6135a50" }, { "ImportPath": "github.com/coreos/etcd/compactor", - "Comment": "v3.0.10", - "Rev": "546c0f7ed65523c24390f0f26c7e4af2232f52d2" + "Comment": "v3.0.12", + "Rev": "2d1e2e8e646e65f73ca0d9ee905a5343d6135a50" }, { "ImportPath": "github.com/coreos/etcd/discovery", - "Comment": "v3.0.10", - "Rev": "546c0f7ed65523c24390f0f26c7e4af2232f52d2" + "Comment": "v3.0.12", + "Rev": "2d1e2e8e646e65f73ca0d9ee905a5343d6135a50" }, { "ImportPath": "github.com/coreos/etcd/error", - "Comment": "v3.0.10", - "Rev": "546c0f7ed65523c24390f0f26c7e4af2232f52d2" + "Comment": "v3.0.12", + "Rev": "2d1e2e8e646e65f73ca0d9ee905a5343d6135a50" }, { "ImportPath": "github.com/coreos/etcd/etcdserver", - "Comment": "v3.0.10", - "Rev": "546c0f7ed65523c24390f0f26c7e4af2232f52d2" + "Comment": "v3.0.12", + "Rev": "2d1e2e8e646e65f73ca0d9ee905a5343d6135a50" }, { "ImportPath": "github.com/coreos/etcd/etcdserver/api", - "Comment": "v3.0.10", - "Rev": "546c0f7ed65523c24390f0f26c7e4af2232f52d2" + "Comment": "v3.0.12", + "Rev": "2d1e2e8e646e65f73ca0d9ee905a5343d6135a50" }, { "ImportPath": "github.com/coreos/etcd/etcdserver/api/v2http", - "Comment": "v3.0.10", - "Rev": "546c0f7ed65523c24390f0f26c7e4af2232f52d2" + "Comment": "v3.0.12", + "Rev": "2d1e2e8e646e65f73ca0d9ee905a5343d6135a50" }, { "ImportPath": "github.com/coreos/etcd/etcdserver/api/v2http/httptypes", - "Comment": "v3.0.10", - "Rev": "546c0f7ed65523c24390f0f26c7e4af2232f52d2" + "Comment": "v3.0.12", + "Rev": "2d1e2e8e646e65f73ca0d9ee905a5343d6135a50" }, { "ImportPath": "github.com/coreos/etcd/etcdserver/api/v3rpc", - "Comment": "v3.0.10", - "Rev": "546c0f7ed65523c24390f0f26c7e4af2232f52d2" + "Comment": "v3.0.12", + "Rev": "2d1e2e8e646e65f73ca0d9ee905a5343d6135a50" }, { "ImportPath": "github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes", - "Comment": "v3.0.10", - "Rev": "546c0f7ed65523c24390f0f26c7e4af2232f52d2" + "Comment": "v3.0.12", + "Rev": "2d1e2e8e646e65f73ca0d9ee905a5343d6135a50" }, { "ImportPath": "github.com/coreos/etcd/etcdserver/auth", - "Comment": "v3.0.10", - "Rev": "546c0f7ed65523c24390f0f26c7e4af2232f52d2" + "Comment": "v3.0.12", + "Rev": "2d1e2e8e646e65f73ca0d9ee905a5343d6135a50" }, { "ImportPath": "github.com/coreos/etcd/etcdserver/etcdserverpb", - "Comment": "v3.0.10", - "Rev": "546c0f7ed65523c24390f0f26c7e4af2232f52d2" + "Comment": "v3.0.12", + "Rev": "2d1e2e8e646e65f73ca0d9ee905a5343d6135a50" }, { "ImportPath": "github.com/coreos/etcd/etcdserver/membership", - "Comment": "v3.0.10", - "Rev": "546c0f7ed65523c24390f0f26c7e4af2232f52d2" + "Comment": "v3.0.12", + "Rev": "2d1e2e8e646e65f73ca0d9ee905a5343d6135a50" }, { "ImportPath": "github.com/coreos/etcd/etcdserver/stats", - "Comment": "v3.0.10", - "Rev": "546c0f7ed65523c24390f0f26c7e4af2232f52d2" + "Comment": "v3.0.12", + "Rev": "2d1e2e8e646e65f73ca0d9ee905a5343d6135a50" }, { "ImportPath": "github.com/coreos/etcd/integration", - "Comment": "v3.0.10", - "Rev": "546c0f7ed65523c24390f0f26c7e4af2232f52d2" + "Comment": "v3.0.12", + "Rev": "2d1e2e8e646e65f73ca0d9ee905a5343d6135a50" }, { "ImportPath": "github.com/coreos/etcd/lease", - "Comment": "v3.0.10", - "Rev": "546c0f7ed65523c24390f0f26c7e4af2232f52d2" + "Comment": "v3.0.12", + "Rev": "2d1e2e8e646e65f73ca0d9ee905a5343d6135a50" }, { "ImportPath": "github.com/coreos/etcd/lease/leasehttp", - "Comment": "v3.0.10", - "Rev": "546c0f7ed65523c24390f0f26c7e4af2232f52d2" + "Comment": "v3.0.12", + "Rev": "2d1e2e8e646e65f73ca0d9ee905a5343d6135a50" }, { "ImportPath": "github.com/coreos/etcd/lease/leasepb", - "Comment": "v3.0.10", - "Rev": "546c0f7ed65523c24390f0f26c7e4af2232f52d2" + "Comment": "v3.0.12", + "Rev": "2d1e2e8e646e65f73ca0d9ee905a5343d6135a50" }, { "ImportPath": "github.com/coreos/etcd/mvcc", - "Comment": "v3.0.10", - "Rev": "546c0f7ed65523c24390f0f26c7e4af2232f52d2" + "Comment": "v3.0.12", + "Rev": "2d1e2e8e646e65f73ca0d9ee905a5343d6135a50" }, { "ImportPath": "github.com/coreos/etcd/mvcc/backend", - "Comment": "v3.0.10", - "Rev": "546c0f7ed65523c24390f0f26c7e4af2232f52d2" + "Comment": "v3.0.12", + "Rev": "2d1e2e8e646e65f73ca0d9ee905a5343d6135a50" }, { "ImportPath": "github.com/coreos/etcd/mvcc/mvccpb", - "Comment": "v3.0.10", - "Rev": "546c0f7ed65523c24390f0f26c7e4af2232f52d2" + "Comment": "v3.0.12", + "Rev": "2d1e2e8e646e65f73ca0d9ee905a5343d6135a50" }, { "ImportPath": "github.com/coreos/etcd/pkg/adt", - "Comment": "v3.0.10", - "Rev": "546c0f7ed65523c24390f0f26c7e4af2232f52d2" + "Comment": "v3.0.12", + "Rev": "2d1e2e8e646e65f73ca0d9ee905a5343d6135a50" }, { "ImportPath": "github.com/coreos/etcd/pkg/contention", - "Comment": "v3.0.10", - "Rev": "546c0f7ed65523c24390f0f26c7e4af2232f52d2" + "Comment": "v3.0.12", + "Rev": "2d1e2e8e646e65f73ca0d9ee905a5343d6135a50" }, { "ImportPath": "github.com/coreos/etcd/pkg/crc", - "Comment": "v3.0.10", - "Rev": "546c0f7ed65523c24390f0f26c7e4af2232f52d2" + "Comment": "v3.0.12", + "Rev": "2d1e2e8e646e65f73ca0d9ee905a5343d6135a50" }, { "ImportPath": "github.com/coreos/etcd/pkg/fileutil", - "Comment": "v3.0.10", - "Rev": "546c0f7ed65523c24390f0f26c7e4af2232f52d2" + "Comment": "v3.0.12", + "Rev": "2d1e2e8e646e65f73ca0d9ee905a5343d6135a50" }, { "ImportPath": "github.com/coreos/etcd/pkg/httputil", - "Comment": "v3.0.10", - "Rev": "546c0f7ed65523c24390f0f26c7e4af2232f52d2" + "Comment": "v3.0.12", + "Rev": "2d1e2e8e646e65f73ca0d9ee905a5343d6135a50" }, { "ImportPath": "github.com/coreos/etcd/pkg/idutil", - "Comment": "v3.0.10", - "Rev": "546c0f7ed65523c24390f0f26c7e4af2232f52d2" + "Comment": "v3.0.12", + "Rev": "2d1e2e8e646e65f73ca0d9ee905a5343d6135a50" }, { "ImportPath": "github.com/coreos/etcd/pkg/ioutil", - "Comment": "v3.0.10", - "Rev": "546c0f7ed65523c24390f0f26c7e4af2232f52d2" + "Comment": "v3.0.12", + "Rev": "2d1e2e8e646e65f73ca0d9ee905a5343d6135a50" }, { "ImportPath": "github.com/coreos/etcd/pkg/logutil", - "Comment": "v3.0.10", - "Rev": "546c0f7ed65523c24390f0f26c7e4af2232f52d2" + "Comment": "v3.0.12", + "Rev": "2d1e2e8e646e65f73ca0d9ee905a5343d6135a50" }, { "ImportPath": "github.com/coreos/etcd/pkg/netutil", - "Comment": "v3.0.10", - "Rev": "546c0f7ed65523c24390f0f26c7e4af2232f52d2" + "Comment": "v3.0.12", + "Rev": "2d1e2e8e646e65f73ca0d9ee905a5343d6135a50" }, { "ImportPath": "github.com/coreos/etcd/pkg/pathutil", - "Comment": "v3.0.10", - "Rev": "546c0f7ed65523c24390f0f26c7e4af2232f52d2" + "Comment": "v3.0.12", + "Rev": "2d1e2e8e646e65f73ca0d9ee905a5343d6135a50" }, { "ImportPath": "github.com/coreos/etcd/pkg/pbutil", - "Comment": "v3.0.10", - "Rev": "546c0f7ed65523c24390f0f26c7e4af2232f52d2" + "Comment": "v3.0.12", + "Rev": "2d1e2e8e646e65f73ca0d9ee905a5343d6135a50" }, { "ImportPath": "github.com/coreos/etcd/pkg/runtime", - "Comment": "v3.0.10", - "Rev": "546c0f7ed65523c24390f0f26c7e4af2232f52d2" + "Comment": "v3.0.12", + "Rev": "2d1e2e8e646e65f73ca0d9ee905a5343d6135a50" }, { "ImportPath": "github.com/coreos/etcd/pkg/schedule", - "Comment": "v3.0.10", - "Rev": "546c0f7ed65523c24390f0f26c7e4af2232f52d2" + "Comment": "v3.0.12", + "Rev": "2d1e2e8e646e65f73ca0d9ee905a5343d6135a50" }, { "ImportPath": "github.com/coreos/etcd/pkg/testutil", - "Comment": "v3.0.10", - "Rev": "546c0f7ed65523c24390f0f26c7e4af2232f52d2" + "Comment": "v3.0.12", + "Rev": "2d1e2e8e646e65f73ca0d9ee905a5343d6135a50" }, { "ImportPath": "github.com/coreos/etcd/pkg/tlsutil", - "Comment": "v3.0.10", - "Rev": "546c0f7ed65523c24390f0f26c7e4af2232f52d2" + "Comment": "v3.0.12", + "Rev": "2d1e2e8e646e65f73ca0d9ee905a5343d6135a50" }, { "ImportPath": "github.com/coreos/etcd/pkg/transport", - "Comment": "v3.0.10", - "Rev": "546c0f7ed65523c24390f0f26c7e4af2232f52d2" + "Comment": "v3.0.12", + "Rev": "2d1e2e8e646e65f73ca0d9ee905a5343d6135a50" }, { "ImportPath": "github.com/coreos/etcd/pkg/types", - "Comment": "v3.0.10", - "Rev": "546c0f7ed65523c24390f0f26c7e4af2232f52d2" + "Comment": "v3.0.12", + "Rev": "2d1e2e8e646e65f73ca0d9ee905a5343d6135a50" }, { "ImportPath": "github.com/coreos/etcd/pkg/wait", - "Comment": "v3.0.10", - "Rev": "546c0f7ed65523c24390f0f26c7e4af2232f52d2" + "Comment": "v3.0.12", + "Rev": "2d1e2e8e646e65f73ca0d9ee905a5343d6135a50" }, { "ImportPath": "github.com/coreos/etcd/raft", - "Comment": "v3.0.10", - "Rev": "546c0f7ed65523c24390f0f26c7e4af2232f52d2" + "Comment": "v3.0.12", + "Rev": "2d1e2e8e646e65f73ca0d9ee905a5343d6135a50" }, { "ImportPath": "github.com/coreos/etcd/raft/raftpb", - "Comment": "v3.0.10", - "Rev": "546c0f7ed65523c24390f0f26c7e4af2232f52d2" + "Comment": "v3.0.12", + "Rev": "2d1e2e8e646e65f73ca0d9ee905a5343d6135a50" }, { "ImportPath": "github.com/coreos/etcd/rafthttp", - "Comment": "v3.0.10", - "Rev": "546c0f7ed65523c24390f0f26c7e4af2232f52d2" + "Comment": "v3.0.12", + "Rev": "2d1e2e8e646e65f73ca0d9ee905a5343d6135a50" }, { "ImportPath": "github.com/coreos/etcd/snap", - "Comment": "v3.0.10", - "Rev": "546c0f7ed65523c24390f0f26c7e4af2232f52d2" + "Comment": "v3.0.12", + "Rev": "2d1e2e8e646e65f73ca0d9ee905a5343d6135a50" }, { "ImportPath": "github.com/coreos/etcd/snap/snappb", - "Comment": "v3.0.10", - "Rev": "546c0f7ed65523c24390f0f26c7e4af2232f52d2" + "Comment": "v3.0.12", + "Rev": "2d1e2e8e646e65f73ca0d9ee905a5343d6135a50" }, { "ImportPath": "github.com/coreos/etcd/store", - "Comment": "v3.0.10", - "Rev": "546c0f7ed65523c24390f0f26c7e4af2232f52d2" + "Comment": "v3.0.12", + "Rev": "2d1e2e8e646e65f73ca0d9ee905a5343d6135a50" }, { "ImportPath": "github.com/coreos/etcd/version", - "Comment": "v3.0.10", - "Rev": "546c0f7ed65523c24390f0f26c7e4af2232f52d2" + "Comment": "v3.0.12", + "Rev": "2d1e2e8e646e65f73ca0d9ee905a5343d6135a50" }, { "ImportPath": "github.com/coreos/etcd/wal", - "Comment": "v3.0.10", - "Rev": "546c0f7ed65523c24390f0f26c7e4af2232f52d2" + "Comment": "v3.0.12", + "Rev": "2d1e2e8e646e65f73ca0d9ee905a5343d6135a50" }, { "ImportPath": "github.com/coreos/etcd/wal/walpb", - "Comment": "v3.0.10", - "Rev": "546c0f7ed65523c24390f0f26c7e4af2232f52d2" + "Comment": "v3.0.12", + "Rev": "2d1e2e8e646e65f73ca0d9ee905a5343d6135a50" }, { "ImportPath": "github.com/coreos/go-oidc/http", @@ -2252,7 +2252,7 @@ }, { "ImportPath": "github.com/xiang90/probing", - "Rev": "6a0cc1ae81b4cc11db5e491e030e4b98fba79c19" + "Rev": "07dd2e8dfe18522e9c447ba95f2fe95262f63bb2" }, { "ImportPath": "github.com/xyproto/simpleredis", diff --git a/pkg/storage/etcd3/event.go b/pkg/storage/etcd3/event.go index 585c371b5dc..4746dafb421 100644 --- a/pkg/storage/etcd3/event.go +++ b/pkg/storage/etcd3/event.go @@ -24,15 +24,17 @@ import ( type event struct { key string value []byte + prevValue []byte rev int64 isDeleted bool isCreated bool } -func parseKV(kv *mvccpb.KeyValue) *event { +func parseKV(kv *mvccpb.KeyValue, prevVal []byte) *event { return &event{ key: string(kv.Key), value: kv.Value, + prevValue: prevVal, rev: kv.ModRevision, isDeleted: false, isCreated: kv.ModRevision == kv.CreateRevision, @@ -40,11 +42,15 @@ func parseKV(kv *mvccpb.KeyValue) *event { } func parseEvent(e *clientv3.Event) *event { - return &event{ + ret := &event{ key: string(e.Kv.Key), value: e.Kv.Value, rev: e.Kv.ModRevision, isDeleted: e.Type == clientv3.EventTypeDelete, isCreated: e.IsCreate(), } + if e.PrevKv != nil { + ret.prevValue = e.PrevKv.Value + } + return ret } diff --git a/pkg/storage/etcd3/watcher.go b/pkg/storage/etcd3/watcher.go index 1a6bbbf2464..3c41b29e240 100644 --- a/pkg/storage/etcd3/watcher.go +++ b/pkg/storage/etcd3/watcher.go @@ -154,7 +154,15 @@ func (wc *watchChan) sync() error { wc.initialRev = getResp.Header.Revision for _, kv := range getResp.Kvs { - wc.sendEvent(parseKV(kv)) + prevResp, err := wc.watcher.client.Get(wc.ctx, string(kv.Key), clientv3.WithRev(kv.ModRevision-1)) + if err != nil { + return err + } + var prevVal []byte + if len(prevResp.Kvs) > 0 { + prevVal = prevResp.Kvs[0].Value + } + wc.sendEvent(parseKV(kv, prevVal)) } return nil } @@ -170,7 +178,7 @@ func (wc *watchChan) startWatching(watchClosedCh chan struct{}) { return } } - opts := []clientv3.OpOption{clientv3.WithRev(wc.initialRev + 1)} + opts := []clientv3.OpOption{clientv3.WithRev(wc.initialRev + 1), clientv3.WithPrevKV()} if wc.recursive { opts = append(opts, clientv3.WithPrefix()) } @@ -331,16 +339,12 @@ func prepareObjs(ctx context.Context, e *event, client *clientv3.Client, codec r return nil, nil, err } } - if e.isDeleted || !e.isCreated { - getResp, err := client.Get(ctx, e.key, clientv3.WithRev(e.rev-1), clientv3.WithSerializable()) - if err != nil { - return nil, nil, err - } + if len(e.prevValue) > 0 { // Note that this sends the *old* object with the etcd revision for the time at // which it gets deleted. // We assume old object is returned only in Deleted event. Users (e.g. cacher) need // to have larger than previous rev to tell the ordering. - oldObj, err = decodeObj(codec, versioner, getResp.Kvs[0].Value, e.rev) + oldObj, err = decodeObj(codec, versioner, e.prevValue, e.rev) if err != nil { return nil, nil, err } diff --git a/vendor/github.com/coreos/etcd/auth/authpb/auth.pb.go b/vendor/github.com/coreos/etcd/auth/authpb/auth.pb.go index 448e1eaa0d5..bafa775d52f 100644 --- a/vendor/github.com/coreos/etcd/auth/authpb/auth.pb.go +++ b/vendor/github.com/coreos/etcd/auth/authpb/auth.pb.go @@ -21,9 +21,9 @@ import ( proto "github.com/golang/protobuf/proto" math "math" -) -import io "io" + io "io" +) // Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal diff --git a/vendor/github.com/coreos/etcd/clientv3/kv.go b/vendor/github.com/coreos/etcd/clientv3/kv.go index 27f9110f803..58491298583 100644 --- a/vendor/github.com/coreos/etcd/clientv3/kv.go +++ b/vendor/github.com/coreos/etcd/clientv3/kv.go @@ -157,14 +157,14 @@ func (kv *kv) do(ctx context.Context, op Op) (OpResponse, error) { } case tPut: var resp *pb.PutResponse - r := &pb.PutRequest{Key: op.key, Value: op.val, Lease: int64(op.leaseID)} + r := &pb.PutRequest{Key: op.key, Value: op.val, Lease: int64(op.leaseID), PrevKv: op.prevKV} resp, err = kv.remote.Put(ctx, r) if err == nil { return OpResponse{put: (*PutResponse)(resp)}, nil } case tDeleteRange: var resp *pb.DeleteRangeResponse - r := &pb.DeleteRangeRequest{Key: op.key, RangeEnd: op.end} + r := &pb.DeleteRangeRequest{Key: op.key, RangeEnd: op.end, PrevKv: op.prevKV} resp, err = kv.remote.DeleteRange(ctx, r) if err == nil { return OpResponse{del: (*DeleteResponse)(resp)}, nil diff --git a/vendor/github.com/coreos/etcd/clientv3/op.go b/vendor/github.com/coreos/etcd/clientv3/op.go index 89698be2341..e2afdd52833 100644 --- a/vendor/github.com/coreos/etcd/clientv3/op.go +++ b/vendor/github.com/coreos/etcd/clientv3/op.go @@ -47,6 +47,9 @@ type Op struct { // for range, watch rev int64 + // for watch, put, delete + prevKV bool + // progressNotify is for progress updates. progressNotify bool @@ -73,10 +76,10 @@ func (op Op) toRequestOp() *pb.RequestOp { } return &pb.RequestOp{Request: &pb.RequestOp_RequestRange{RequestRange: r}} case tPut: - r := &pb.PutRequest{Key: op.key, Value: op.val, Lease: int64(op.leaseID)} + r := &pb.PutRequest{Key: op.key, Value: op.val, Lease: int64(op.leaseID), PrevKv: op.prevKV} return &pb.RequestOp{Request: &pb.RequestOp_RequestPut{RequestPut: r}} case tDeleteRange: - r := &pb.DeleteRangeRequest{Key: op.key, RangeEnd: op.end} + r := &pb.DeleteRangeRequest{Key: op.key, RangeEnd: op.end, PrevKv: op.prevKV} return &pb.RequestOp{Request: &pb.RequestOp_RequestDeleteRange{RequestDeleteRange: r}} default: panic("Unknown Op") @@ -271,3 +274,11 @@ func WithProgressNotify() OpOption { op.progressNotify = true } } + +// WithPrevKV gets the previous key-value pair before the event happens. If the previous KV is already compacted, +// nothing will be returned. +func WithPrevKV() OpOption { + return func(op *Op) { + op.prevKV = true + } +} diff --git a/vendor/github.com/coreos/etcd/clientv3/watch.go b/vendor/github.com/coreos/etcd/clientv3/watch.go index 2b9d015fb25..10b97f2ee70 100644 --- a/vendor/github.com/coreos/etcd/clientv3/watch.go +++ b/vendor/github.com/coreos/etcd/clientv3/watch.go @@ -61,6 +61,9 @@ type WatchResponse struct { // the channel sends a final response that has Canceled set to true with a non-nil Err(). Canceled bool + // created is used to indicate the creation of the watcher. + created bool + closeErr error } @@ -89,7 +92,7 @@ func (wr *WatchResponse) Err() error { // IsProgressNotify returns true if the WatchResponse is progress notification. func (wr *WatchResponse) IsProgressNotify() bool { - return len(wr.Events) == 0 && !wr.Canceled + return len(wr.Events) == 0 && !wr.Canceled && !wr.created && wr.CompactRevision == 0 && wr.Header.Revision != 0 } // watcher implements the Watcher interface @@ -102,6 +105,7 @@ type watcher struct { streams map[string]*watchGrpcStream } +// watchGrpcStream tracks all watch resources attached to a single grpc stream. type watchGrpcStream struct { owner *watcher remote pb.WatchClient @@ -112,10 +116,10 @@ type watchGrpcStream struct { ctxKey string cancel context.CancelFunc - // mu protects the streams map - mu sync.RWMutex - // streams holds all active watchers - streams map[int64]*watcherStream + // substreams holds all active watchers on this grpc stream + substreams map[int64]*watcherStream + // resuming holds all resuming watchers on this grpc stream + resuming []*watcherStream // reqc sends a watch request from Watch() to the main goroutine reqc chan *watchRequest @@ -130,7 +134,9 @@ type watchGrpcStream struct { // closingc gets the watcherStream of closing watchers closingc chan *watcherStream - // the error that closed the watch stream + // resumec closes to signal that all substreams should begin resuming + resumec chan struct{} + // closeErr is the error that closed the watch stream closeErr error } @@ -142,6 +148,8 @@ type watchRequest struct { rev int64 // progressNotify is for progress updates. progressNotify bool + // get the previous key-value pair before the event happens + prevKV bool // retc receives a chan WatchResponse once the watcher is established retc chan chan WatchResponse } @@ -152,15 +160,18 @@ type watcherStream struct { initReq watchRequest // outc publishes watch responses to subscriber - outc chan<- WatchResponse + outc chan WatchResponse // recvc buffers watch responses before publishing recvc chan *WatchResponse - id int64 + // donec closes when the watcherStream goroutine stops. + donec chan struct{} + // closing is set to true when stream should be scheduled to shutdown. + closing bool + // id is the registered watch id on the grpc stream + id int64 - // lastRev is revision last successfully sent over outc - lastRev int64 - // resumec indicates the stream must recover at a given revision - resumec chan int64 + // buf holds all events received from etcd but not yet consumed by the client + buf []*WatchResponse } func NewWatcher(c *Client) Watcher { @@ -184,12 +195,12 @@ func (vc *valCtx) Err() error { return nil } func (w *watcher) newWatcherGrpcStream(inctx context.Context) *watchGrpcStream { ctx, cancel := context.WithCancel(&valCtx{inctx}) wgs := &watchGrpcStream{ - owner: w, - remote: w.remote, - ctx: ctx, - ctxKey: fmt.Sprintf("%v", inctx), - cancel: cancel, - streams: make(map[int64]*watcherStream), + owner: w, + remote: w.remote, + ctx: ctx, + ctxKey: fmt.Sprintf("%v", inctx), + cancel: cancel, + substreams: make(map[int64]*watcherStream), respc: make(chan *pb.WatchResponse), reqc: make(chan *watchRequest), @@ -197,6 +208,7 @@ func (w *watcher) newWatcherGrpcStream(inctx context.Context) *watchGrpcStream { donec: make(chan struct{}), errc: make(chan error, 1), closingc: make(chan *watcherStream), + resumec: make(chan struct{}), } go wgs.run() return wgs @@ -206,14 +218,14 @@ func (w *watcher) newWatcherGrpcStream(inctx context.Context) *watchGrpcStream { func (w *watcher) Watch(ctx context.Context, key string, opts ...OpOption) WatchChan { ow := opWatch(key, opts...) - retc := make(chan chan WatchResponse, 1) wr := &watchRequest{ ctx: ctx, key: string(ow.key), end: string(ow.end), rev: ow.rev, progressNotify: ow.progressNotify, - retc: retc, + prevKV: ow.prevKV, + retc: make(chan chan WatchResponse, 1), } ok := false @@ -257,7 +269,7 @@ func (w *watcher) Watch(ctx context.Context, key string, opts ...OpOption) Watch // receive channel if ok { select { - case ret := <-retc: + case ret := <-wr.retc: return ret case <-ctx.Done(): case <-donec: @@ -288,12 +300,7 @@ func (w *watcher) Close() (err error) { } func (w *watchGrpcStream) Close() (err error) { - w.mu.Lock() - if w.stopc != nil { - close(w.stopc) - w.stopc = nil - } - w.mu.Unlock() + close(w.stopc) <-w.donec select { case err = <-w.errc: @@ -302,71 +309,57 @@ func (w *watchGrpcStream) Close() (err error) { return toErr(w.ctx, err) } -func (w *watchGrpcStream) addStream(resp *pb.WatchResponse, pendingReq *watchRequest) { - if pendingReq == nil { - // no pending request; ignore - return - } - if resp.Canceled || resp.CompactRevision != 0 { - // a cancel at id creation time means the start revision has - // been compacted out of the store - ret := make(chan WatchResponse, 1) - ret <- WatchResponse{ - Header: *resp.Header, - CompactRevision: resp.CompactRevision, - Canceled: true} - close(ret) - pendingReq.retc <- ret - return - } - - ret := make(chan WatchResponse) - if resp.WatchId == -1 { - // failed; no channel - close(ret) - pendingReq.retc <- ret - return - } - - ws := &watcherStream{ - initReq: *pendingReq, - id: resp.WatchId, - outc: ret, - // buffered so unlikely to block on sending while holding mu - recvc: make(chan *WatchResponse, 4), - resumec: make(chan int64), - } - - if pendingReq.rev == 0 { - // note the header revision so that a put following a current watcher - // disconnect will arrive on the watcher channel after reconnect - ws.initReq.rev = resp.Header.Revision - } - +func (w *watcher) closeStream(wgs *watchGrpcStream) { w.mu.Lock() - w.streams[ws.id] = ws + close(wgs.donec) + wgs.cancel() + if w.streams != nil { + delete(w.streams, wgs.ctxKey) + } w.mu.Unlock() - - // pass back the subscriber channel for the watcher - pendingReq.retc <- ret - - // send messages to subscriber - go w.serveStream(ws) } -func (w *watchGrpcStream) closeStream(ws *watcherStream) bool { - w.mu.Lock() - // cancels request stream; subscriber receives nil channel - close(ws.initReq.retc) - // close subscriber's channel - close(ws.outc) - delete(w.streams, ws.id) - empty := len(w.streams) == 0 - if empty && w.stopc != nil { - w.stopc = nil +func (w *watchGrpcStream) addSubstream(resp *pb.WatchResponse, ws *watcherStream) { + if resp.WatchId == -1 { + // failed; no channel + close(ws.recvc) + return + } + ws.id = resp.WatchId + w.substreams[ws.id] = ws +} + +func (w *watchGrpcStream) sendCloseSubstream(ws *watcherStream, resp *WatchResponse) { + select { + case ws.outc <- *resp: + case <-ws.initReq.ctx.Done(): + case <-time.After(closeSendErrTimeout): + } + close(ws.outc) +} + +func (w *watchGrpcStream) closeSubstream(ws *watcherStream) { + // send channel response in case stream was never established + select { + case ws.initReq.retc <- ws.outc: + default: + } + // close subscriber's channel + if closeErr := w.closeErr; closeErr != nil && ws.initReq.ctx.Err() == nil { + go w.sendCloseSubstream(ws, &WatchResponse{closeErr: w.closeErr}) + } else { + close(ws.outc) + } + if ws.id != -1 { + delete(w.substreams, ws.id) + return + } + for i := range w.resuming { + if w.resuming[i] == ws { + w.resuming[i] = nil + return + } } - w.mu.Unlock() - return empty } // run is the root of the goroutines for managing a watcher client @@ -374,66 +367,79 @@ func (w *watchGrpcStream) run() { var wc pb.Watch_WatchClient var closeErr error - defer func() { - w.owner.mu.Lock() - w.closeErr = closeErr - if w.owner.streams != nil { - delete(w.owner.streams, w.ctxKey) - } - close(w.donec) - w.owner.mu.Unlock() - w.cancel() - }() + // substreams marked to close but goroutine still running; needed for + // avoiding double-closing recvc on grpc stream teardown + closing := make(map[*watcherStream]struct{}) - // already stopped? - w.mu.RLock() - stopc := w.stopc - w.mu.RUnlock() - if stopc == nil { - return - } + defer func() { + w.closeErr = closeErr + // shutdown substreams and resuming substreams + for _, ws := range w.substreams { + if _, ok := closing[ws]; !ok { + close(ws.recvc) + } + } + for _, ws := range w.resuming { + if _, ok := closing[ws]; ws != nil && !ok { + close(ws.recvc) + } + } + w.joinSubstreams() + for toClose := len(w.substreams) + len(w.resuming); toClose > 0; toClose-- { + w.closeSubstream(<-w.closingc) + } + + w.owner.closeStream(w) + }() // start a stream with the etcd grpc server if wc, closeErr = w.newWatchClient(); closeErr != nil { return } - var pendingReq, failedReq *watchRequest - curReqC := w.reqc cancelSet := make(map[int64]struct{}) for { select { // Watch() requested - case pendingReq = <-curReqC: - // no more watch requests until there's a response - curReqC = nil - if err := wc.Send(pendingReq.toPB()); err == nil { - // pendingReq now waits on w.respc - break + case wreq := <-w.reqc: + outc := make(chan WatchResponse, 1) + ws := &watcherStream{ + initReq: *wreq, + id: -1, + outc: outc, + // unbufffered so resumes won't cause repeat events + recvc: make(chan *WatchResponse), + } + + ws.donec = make(chan struct{}) + go w.serveSubstream(ws, w.resumec) + + // queue up for watcher creation/resume + w.resuming = append(w.resuming, ws) + if len(w.resuming) == 1 { + // head of resume queue, can register a new watcher + wc.Send(ws.initReq.toPB()) } - failedReq = pendingReq // New events from the watch client case pbresp := <-w.respc: switch { case pbresp.Created: - // response to pending req, try to add - w.addStream(pbresp, pendingReq) - pendingReq = nil - curReqC = w.reqc + // response to head of queue creation + if ws := w.resuming[0]; ws != nil { + w.addSubstream(pbresp, ws) + w.dispatchEvent(pbresp) + w.resuming[0] = nil + } + if ws := w.nextResume(); ws != nil { + wc.Send(ws.initReq.toPB()) + } case pbresp.Canceled: delete(cancelSet, pbresp.WatchId) - // shutdown serveStream, if any - w.mu.Lock() - if ws, ok := w.streams[pbresp.WatchId]; ok { + if ws, ok := w.substreams[pbresp.WatchId]; ok { + // signal to stream goroutine to update closingc close(ws.recvc) - delete(w.streams, ws.id) - } - numStreams := len(w.streams) - w.mu.Unlock() - if numStreams == 0 { - // don't leak watcher streams - return + closing[ws] = struct{}{} } default: // dispatch to appropriate watch stream @@ -454,7 +460,6 @@ func (w *watchGrpcStream) run() { wc.Send(req) } // watch client failed to recv; spawn another if possible - // TODO report watch client errors from errc? case err := <-w.errc: if toErr(w.ctx, err) == v3rpc.ErrNoLeader { closeErr = err @@ -463,52 +468,58 @@ func (w *watchGrpcStream) run() { if wc, closeErr = w.newWatchClient(); closeErr != nil { return } - curReqC = w.reqc - if pendingReq != nil { - failedReq = pendingReq + if ws := w.nextResume(); ws != nil { + wc.Send(ws.initReq.toPB()) } cancelSet = make(map[int64]struct{}) - case <-stopc: + case <-w.stopc: return case ws := <-w.closingc: - if w.closeStream(ws) { + w.closeSubstream(ws) + delete(closing, ws) + if len(w.substreams)+len(w.resuming) == 0 { + // no more watchers on this stream, shutdown return } } - - // send failed; queue for retry - if failedReq != nil { - go func(wr *watchRequest) { - select { - case w.reqc <- wr: - case <-wr.ctx.Done(): - case <-w.donec: - } - }(pendingReq) - failedReq = nil - pendingReq = nil - } } } +// nextResume chooses the next resuming to register with the grpc stream. Abandoned +// streams are marked as nil in the queue since the head must wait for its inflight registration. +func (w *watchGrpcStream) nextResume() *watcherStream { + for len(w.resuming) != 0 { + if w.resuming[0] != nil { + return w.resuming[0] + } + w.resuming = w.resuming[1:len(w.resuming)] + } + return nil +} + // dispatchEvent sends a WatchResponse to the appropriate watcher stream func (w *watchGrpcStream) dispatchEvent(pbresp *pb.WatchResponse) bool { - w.mu.RLock() - defer w.mu.RUnlock() - ws, ok := w.streams[pbresp.WatchId] + ws, ok := w.substreams[pbresp.WatchId] + if !ok { + return false + } events := make([]*Event, len(pbresp.Events)) for i, ev := range pbresp.Events { events[i] = (*Event)(ev) } - if ok { - wr := &WatchResponse{ - Header: *pbresp.Header, - Events: events, - CompactRevision: pbresp.CompactRevision, - Canceled: pbresp.Canceled} - ws.recvc <- wr + wr := &WatchResponse{ + Header: *pbresp.Header, + Events: events, + CompactRevision: pbresp.CompactRevision, + created: pbresp.Created, + Canceled: pbresp.Canceled, } - return ok + select { + case ws.recvc <- wr: + case <-ws.donec: + return false + } + return true } // serveWatchClient forwards messages from the grpc stream to run() @@ -530,132 +541,123 @@ func (w *watchGrpcStream) serveWatchClient(wc pb.Watch_WatchClient) { } } -// serveStream forwards watch responses from run() to the subscriber -func (w *watchGrpcStream) serveStream(ws *watcherStream) { +// serveSubstream forwards watch responses from run() to the subscriber +func (w *watchGrpcStream) serveSubstream(ws *watcherStream, resumec chan struct{}) { + if ws.closing { + panic("created substream goroutine but substream is closing") + } + + // nextRev is the minimum expected next revision + nextRev := ws.initReq.rev + resuming := false defer func() { - // signal that this watcherStream is finished - select { - case w.closingc <- ws: - case <-w.donec: - w.closeStream(ws) + if !resuming { + ws.closing = true + } + close(ws.donec) + if !resuming { + w.closingc <- ws } }() - var closeErr error emptyWr := &WatchResponse{} - wrs := []*WatchResponse{} - resuming := false - closing := false - for !closing { + for { curWr := emptyWr outc := ws.outc - if len(wrs) > 0 { - curWr = wrs[0] + + if len(ws.buf) > 0 && ws.buf[0].created { + select { + case ws.initReq.retc <- ws.outc: + default: + } + ws.buf = ws.buf[1:] + } + + if len(ws.buf) > 0 { + curWr = ws.buf[0] } else { outc = nil } select { case outc <- *curWr: - if wrs[0].Err() != nil { - closing = true - break - } - var newRev int64 - if len(wrs[0].Events) > 0 { - newRev = wrs[0].Events[len(wrs[0].Events)-1].Kv.ModRevision - } else { - newRev = wrs[0].Header.Revision - } - if newRev != ws.lastRev { - ws.lastRev = newRev - } - wrs[0] = nil - wrs = wrs[1:] - case wr, ok := <-ws.recvc: - if !ok { - // shutdown from closeStream + if ws.buf[0].Err() != nil { return } - // resume up to last seen event if disconnected - if resuming && wr.Err() == nil { - resuming = false - // trim events already seen - for i := 0; i < len(wr.Events); i++ { - if wr.Events[i].Kv.ModRevision > ws.lastRev { - wr.Events = wr.Events[i:] - break - } - } - // only forward new events - if wr.Events[0].Kv.ModRevision == ws.lastRev { - break - } + ws.buf[0] = nil + ws.buf = ws.buf[1:] + case wr, ok := <-ws.recvc: + if !ok { + // shutdown from closeSubstream + return } - resuming = false - // TODO don't keep buffering if subscriber stops reading - wrs = append(wrs, wr) - case resumeRev := <-ws.resumec: - wrs = nil - resuming = true - if resumeRev == -1 { - // pause serving stream while resume gets set up - break + // TODO pause channel if buffer gets too large + ws.buf = append(ws.buf, wr) + nextRev = wr.Header.Revision + if len(wr.Events) > 0 { + nextRev = wr.Events[len(wr.Events)-1].Kv.ModRevision + 1 } - if resumeRev != ws.lastRev { - panic("unexpected resume revision") - } - case <-w.donec: - closing = true - closeErr = w.closeErr + ws.initReq.rev = nextRev case <-ws.initReq.ctx.Done(): - closing = true + return + case <-resumec: + resuming = true + return } } - - // try to send off close error - if closeErr != nil { - select { - case ws.outc <- WatchResponse{closeErr: w.closeErr}: - case <-w.donec: - case <-time.After(closeSendErrTimeout): - } - } - // lazily send cancel message if events on missing id } func (w *watchGrpcStream) newWatchClient() (pb.Watch_WatchClient, error) { - ws, rerr := w.resume() - if rerr != nil { - return nil, rerr + // connect to grpc stream + wc, err := w.openWatchClient() + if err != nil { + return nil, v3rpc.Error(err) } - go w.serveWatchClient(ws) - return ws, nil -} - -// resume creates a new WatchClient with all current watchers reestablished -func (w *watchGrpcStream) resume() (ws pb.Watch_WatchClient, err error) { - for { - if ws, err = w.openWatchClient(); err != nil { - break - } else if err = w.resumeWatchers(ws); err == nil { - break + // mark all substreams as resuming + if len(w.substreams)+len(w.resuming) > 0 { + close(w.resumec) + w.resumec = make(chan struct{}) + w.joinSubstreams() + for _, ws := range w.substreams { + ws.id = -1 + w.resuming = append(w.resuming, ws) + } + for _, ws := range w.resuming { + if ws == nil || ws.closing { + continue + } + ws.donec = make(chan struct{}) + go w.serveSubstream(ws, w.resumec) + } + } + w.substreams = make(map[int64]*watcherStream) + // receive data from new grpc stream + go w.serveWatchClient(wc) + return wc, nil +} + +// joinSubstream waits for all substream goroutines to complete +func (w *watchGrpcStream) joinSubstreams() { + for _, ws := range w.substreams { + <-ws.donec + } + for _, ws := range w.resuming { + if ws != nil { + <-ws.donec } } - return ws, v3rpc.Error(err) } // openWatchClient retries opening a watchclient until retryConnection fails func (w *watchGrpcStream) openWatchClient() (ws pb.Watch_WatchClient, err error) { for { - w.mu.Lock() - stopc := w.stopc - w.mu.Unlock() - if stopc == nil { + select { + case <-w.stopc: if err == nil { - err = context.Canceled + return nil, context.Canceled } return nil, err + default: } if ws, err = w.remote.Watch(w.ctx, grpc.FailFast(false)); ws != nil && err == nil { break @@ -667,63 +669,6 @@ func (w *watchGrpcStream) openWatchClient() (ws pb.Watch_WatchClient, err error) return ws, nil } -// resumeWatchers rebuilds every registered watcher on a new client -func (w *watchGrpcStream) resumeWatchers(wc pb.Watch_WatchClient) error { - w.mu.RLock() - streams := make([]*watcherStream, 0, len(w.streams)) - for _, ws := range w.streams { - streams = append(streams, ws) - } - w.mu.RUnlock() - - for _, ws := range streams { - // drain recvc so no old WatchResponses (e.g., Created messages) - // are processed while resuming - ws.drain() - - // pause serveStream - ws.resumec <- -1 - - // reconstruct watcher from initial request - if ws.lastRev != 0 { - ws.initReq.rev = ws.lastRev - } - if err := wc.Send(ws.initReq.toPB()); err != nil { - return err - } - - // wait for request ack - resp, err := wc.Recv() - if err != nil { - return err - } else if len(resp.Events) != 0 || !resp.Created { - return fmt.Errorf("watcher: unexpected response (%+v)", resp) - } - - // id may be different since new remote watcher; update map - w.mu.Lock() - delete(w.streams, ws.id) - ws.id = resp.WatchId - w.streams[ws.id] = ws - w.mu.Unlock() - - // unpause serveStream - ws.resumec <- ws.lastRev - } - return nil -} - -// drain removes all buffered WatchResponses from the stream's receive channel. -func (ws *watcherStream) drain() { - for { - select { - case <-ws.recvc: - default: - return - } - } -} - // toPB converts an internal watch request structure to its protobuf messagefunc (wr *watchRequest) func (wr *watchRequest) toPB() *pb.WatchRequest { req := &pb.WatchCreateRequest{ @@ -731,6 +676,7 @@ func (wr *watchRequest) toPB() *pb.WatchRequest { Key: []byte(wr.key), RangeEnd: []byte(wr.end), ProgressNotify: wr.progressNotify, + PrevKv: wr.prevKV, } cr := &pb.WatchRequest_CreateRequest{CreateRequest: req} return &pb.WatchRequest{RequestUnion: cr} diff --git a/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/watch.go b/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/watch.go index dba0646795b..0565aa4516d 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/watch.go +++ b/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/watch.go @@ -32,7 +32,7 @@ type watchServer struct { clusterID int64 memberID int64 raftTimer etcdserver.RaftTimer - watchable mvcc.Watchable + watchable mvcc.WatchableKV } func NewWatchServer(s *etcdserver.EtcdServer) pb.WatchServer { @@ -82,6 +82,8 @@ type serverWatchStream struct { memberID int64 raftTimer etcdserver.RaftTimer + watchable mvcc.WatchableKV + gRPCStream pb.Watch_WatchServer watchStream mvcc.WatchStream ctrlStream chan *pb.WatchResponse @@ -91,6 +93,7 @@ type serverWatchStream struct { // progress tracks the watchID that stream might need to send // progress to. progress map[mvcc.WatchID]bool + prevKV map[mvcc.WatchID]bool // closec indicates the stream is closed. closec chan struct{} @@ -101,14 +104,18 @@ type serverWatchStream struct { func (ws *watchServer) Watch(stream pb.Watch_WatchServer) (err error) { sws := serverWatchStream{ - clusterID: ws.clusterID, - memberID: ws.memberID, - raftTimer: ws.raftTimer, + clusterID: ws.clusterID, + memberID: ws.memberID, + raftTimer: ws.raftTimer, + + watchable: ws.watchable, + gRPCStream: stream, watchStream: ws.watchable.NewWatchStream(), // chan for sending control response like watcher created and canceled. ctrlStream: make(chan *pb.WatchResponse, ctrlStreamBufLen), progress: make(map[mvcc.WatchID]bool), + prevKV: make(map[mvcc.WatchID]bool), closec: make(chan struct{}), } @@ -170,9 +177,14 @@ func (sws *serverWatchStream) recvLoop() error { rev = wsrev + 1 } id := sws.watchStream.Watch(creq.Key, creq.RangeEnd, rev) - if id != -1 && creq.ProgressNotify { + if id != -1 { sws.mu.Lock() - sws.progress[id] = true + if creq.ProgressNotify { + sws.progress[id] = true + } + if creq.PrevKv { + sws.prevKV[id] = true + } sws.mu.Unlock() } wr := &pb.WatchResponse{ @@ -198,6 +210,7 @@ func (sws *serverWatchStream) recvLoop() error { } sws.mu.Lock() delete(sws.progress, mvcc.WatchID(id)) + delete(sws.prevKV, mvcc.WatchID(id)) sws.mu.Unlock() } } @@ -244,8 +257,19 @@ func (sws *serverWatchStream) sendLoop() { // or define protocol buffer with []mvccpb.Event. evs := wresp.Events events := make([]*mvccpb.Event, len(evs)) + sws.mu.Lock() + needPrevKV := sws.prevKV[wresp.WatchID] + sws.mu.Unlock() for i := range evs { events[i] = &evs[i] + + if needPrevKV { + opt := mvcc.RangeOptions{Rev: evs[i].Kv.ModRevision - 1} + r, err := sws.watchable.Range(evs[i].Kv.Key, nil, opt) + if err == nil && len(r.KVs) != 0 { + events[i].PrevKv = &(r.KVs[0]) + } + } } wr := &pb.WatchResponse{ diff --git a/vendor/github.com/coreos/etcd/etcdserver/apply.go b/vendor/github.com/coreos/etcd/etcdserver/apply.go index 820b4fc527e..ed2027c82e2 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/apply.go +++ b/vendor/github.com/coreos/etcd/etcdserver/apply.go @@ -159,6 +159,22 @@ func (a *applierV3backend) Put(txnID int64, p *pb.PutRequest) (*pb.PutResponse, rev int64 err error ) + + var rr *mvcc.RangeResult + if p.PrevKv { + if txnID != noTxn { + rr, err = a.s.KV().TxnRange(txnID, p.Key, nil, mvcc.RangeOptions{}) + if err != nil { + return nil, err + } + } else { + rr, err = a.s.KV().Range(p.Key, nil, mvcc.RangeOptions{}) + if err != nil { + return nil, err + } + } + } + if txnID != noTxn { rev, err = a.s.KV().TxnPut(txnID, p.Key, p.Value, lease.LeaseID(p.Lease)) if err != nil { @@ -174,6 +190,9 @@ func (a *applierV3backend) Put(txnID int64, p *pb.PutRequest) (*pb.PutResponse, rev = a.s.KV().Put(p.Key, p.Value, leaseID) } resp.Header.Revision = rev + if rr != nil && len(rr.KVs) != 0 { + resp.PrevKv = &rr.KVs[0] + } return resp, nil } @@ -191,6 +210,21 @@ func (a *applierV3backend) DeleteRange(txnID int64, dr *pb.DeleteRangeRequest) ( dr.RangeEnd = []byte{} } + var rr *mvcc.RangeResult + if dr.PrevKv { + if txnID != noTxn { + rr, err = a.s.KV().TxnRange(txnID, dr.Key, dr.RangeEnd, mvcc.RangeOptions{}) + if err != nil { + return nil, err + } + } else { + rr, err = a.s.KV().Range(dr.Key, dr.RangeEnd, mvcc.RangeOptions{}) + if err != nil { + return nil, err + } + } + } + if txnID != noTxn { n, rev, err = a.s.KV().TxnDeleteRange(txnID, dr.Key, dr.RangeEnd) if err != nil { @@ -201,6 +235,11 @@ func (a *applierV3backend) DeleteRange(txnID int64, dr *pb.DeleteRangeRequest) ( } resp.Deleted = n + if rr != nil { + for i := range rr.KVs { + resp.PrevKvs = append(resp.PrevKvs, &rr.KVs[i]) + } + } resp.Header.Revision = rev return resp, nil } diff --git a/vendor/github.com/coreos/etcd/etcdserver/apply_auth.go b/vendor/github.com/coreos/etcd/etcdserver/apply_auth.go index 1a45788950e..38bf2b407eb 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/apply_auth.go +++ b/vendor/github.com/coreos/etcd/etcdserver/apply_auth.go @@ -56,6 +56,9 @@ func (aa *authApplierV3) Put(txnID int64, r *pb.PutRequest) (*pb.PutResponse, er if !aa.as.IsPutPermitted(aa.user, r.Key) { return nil, auth.ErrPermissionDenied } + if r.PrevKv && !aa.as.IsRangePermitted(aa.user, r.Key, nil) { + return nil, auth.ErrPermissionDenied + } return aa.applierV3.Put(txnID, r) } @@ -70,6 +73,9 @@ func (aa *authApplierV3) DeleteRange(txnID int64, r *pb.DeleteRangeRequest) (*pb if !aa.as.IsDeleteRangePermitted(aa.user, r.Key, r.RangeEnd) { return nil, auth.ErrPermissionDenied } + if r.PrevKv && !aa.as.IsRangePermitted(aa.user, r.Key, r.RangeEnd) { + return nil, auth.ErrPermissionDenied + } return aa.applierV3.DeleteRange(txnID, r) } @@ -99,7 +105,7 @@ func (aa *authApplierV3) checkTxnReqsPermission(reqs []*pb.RequestOp) bool { continue } - if !aa.as.IsDeleteRangePermitted(aa.user, tv.RequestDeleteRange.Key, tv.RequestDeleteRange.RangeEnd) { + if tv.RequestDeleteRange.PrevKv && !aa.as.IsRangePermitted(aa.user, tv.RequestDeleteRange.Key, tv.RequestDeleteRange.RangeEnd) { return false } } diff --git a/vendor/github.com/coreos/etcd/etcdserver/etcdserverpb/etcdserver.pb.go b/vendor/github.com/coreos/etcd/etcdserver/etcdserverpb/etcdserver.pb.go index 746e9a116a0..ac4be4f6c57 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/etcdserverpb/etcdserver.pb.go +++ b/vendor/github.com/coreos/etcd/etcdserver/etcdserverpb/etcdserver.pb.go @@ -102,9 +102,9 @@ import ( proto "github.com/golang/protobuf/proto" math "math" -) -import io "io" + io "io" +) // Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal diff --git a/vendor/github.com/coreos/etcd/etcdserver/etcdserverpb/raft_internal.pb.go b/vendor/github.com/coreos/etcd/etcdserver/etcdserverpb/raft_internal.pb.go index 068aefff0b9..a82e2b23507 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/etcdserverpb/raft_internal.pb.go +++ b/vendor/github.com/coreos/etcd/etcdserver/etcdserverpb/raft_internal.pb.go @@ -10,9 +10,9 @@ import ( proto "github.com/golang/protobuf/proto" math "math" -) -import io "io" + io "io" +) // Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal diff --git a/vendor/github.com/coreos/etcd/etcdserver/etcdserverpb/rpc.pb.go b/vendor/github.com/coreos/etcd/etcdserver/etcdserverpb/rpc.pb.go index 213d5442682..1bc62c2eb69 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/etcdserverpb/rpc.pb.go +++ b/vendor/github.com/coreos/etcd/etcdserver/etcdserverpb/rpc.pb.go @@ -11,16 +11,15 @@ import ( math "math" + mvccpb "github.com/coreos/etcd/mvcc/mvccpb" + authpb "github.com/coreos/etcd/auth/authpb" - io "io" -) - -import mvccpb "github.com/coreos/etcd/mvcc/mvccpb" - -import ( context "golang.org/x/net/context" + grpc "google.golang.org/grpc" + + io "io" ) // Reference imports to suppress errors if they are not otherwise used. @@ -271,6 +270,9 @@ type PutRequest struct { // lease is the lease ID to associate with the key in the key-value store. A lease // value of 0 indicates no lease. Lease int64 `protobuf:"varint,3,opt,name=lease,proto3" json:"lease,omitempty"` + // If prev_kv is set, etcd gets the previous key-value pair before changing it. + // The previous key-value pair will be returned in the put response. + PrevKv bool `protobuf:"varint,4,opt,name=prev_kv,json=prevKv,proto3" json:"prev_kv,omitempty"` } func (m *PutRequest) Reset() { *m = PutRequest{} } @@ -280,6 +282,8 @@ func (*PutRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []in type PutResponse struct { Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"` + // if prev_kv is set in the request, the previous key-value pair will be returned. + PrevKv *mvccpb.KeyValue `protobuf:"bytes,2,opt,name=prev_kv,json=prevKv" json:"prev_kv,omitempty"` } func (m *PutResponse) Reset() { *m = PutResponse{} } @@ -294,6 +298,13 @@ func (m *PutResponse) GetHeader() *ResponseHeader { return nil } +func (m *PutResponse) GetPrevKv() *mvccpb.KeyValue { + if m != nil { + return m.PrevKv + } + return nil +} + type DeleteRangeRequest struct { // key is the first key to delete in the range. Key []byte `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` @@ -301,6 +312,9 @@ type DeleteRangeRequest struct { // If range_end is not given, the range is defined to contain only the key argument. // If range_end is '\0', the range is all keys greater than or equal to the key argument. RangeEnd []byte `protobuf:"bytes,2,opt,name=range_end,json=rangeEnd,proto3" json:"range_end,omitempty"` + // If prev_kv is set, etcd gets the previous key-value pairs before deleting it. + // The previous key-value pairs will be returned in the delte response. + PrevKv bool `protobuf:"varint,3,opt,name=prev_kv,json=prevKv,proto3" json:"prev_kv,omitempty"` } func (m *DeleteRangeRequest) Reset() { *m = DeleteRangeRequest{} } @@ -312,6 +326,8 @@ type DeleteRangeResponse struct { Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"` // deleted is the number of keys deleted by the delete range request. Deleted int64 `protobuf:"varint,2,opt,name=deleted,proto3" json:"deleted,omitempty"` + // if prev_kv is set in the request, the previous key-value pairs will be returned. + PrevKvs []*mvccpb.KeyValue `protobuf:"bytes,3,rep,name=prev_kvs,json=prevKvs" json:"prev_kvs,omitempty"` } func (m *DeleteRangeResponse) Reset() { *m = DeleteRangeResponse{} } @@ -326,6 +342,13 @@ func (m *DeleteRangeResponse) GetHeader() *ResponseHeader { return nil } +func (m *DeleteRangeResponse) GetPrevKvs() []*mvccpb.KeyValue { + if m != nil { + return m.PrevKvs + } + return nil +} + type RequestOp struct { // request is a union of request types accepted by a transaction. // @@ -1119,6 +1142,9 @@ type WatchCreateRequest struct { // wish to recover a disconnected watcher starting from a recent known revision. // The etcd server may decide how often it will send notifications based on current load. ProgressNotify bool `protobuf:"varint,4,opt,name=progress_notify,json=progressNotify,proto3" json:"progress_notify,omitempty"` + // If prev_kv is set, created watcher gets the previous KV before the event happens. + // If the previous KV is already compacted, nothing will be returned. + PrevKv bool `protobuf:"varint,6,opt,name=prev_kv,json=prevKv,proto3" json:"prev_kv,omitempty"` } func (m *WatchCreateRequest) Reset() { *m = WatchCreateRequest{} } @@ -3765,6 +3791,16 @@ func (m *PutRequest) MarshalTo(data []byte) (int, error) { i++ i = encodeVarintRpc(data, i, uint64(m.Lease)) } + if m.PrevKv { + data[i] = 0x20 + i++ + if m.PrevKv { + data[i] = 1 + } else { + data[i] = 0 + } + i++ + } return i, nil } @@ -3793,6 +3829,16 @@ func (m *PutResponse) MarshalTo(data []byte) (int, error) { } i += n2 } + if m.PrevKv != nil { + data[i] = 0x12 + i++ + i = encodeVarintRpc(data, i, uint64(m.PrevKv.Size())) + n3, err := m.PrevKv.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += n3 + } return i, nil } @@ -3823,6 +3869,16 @@ func (m *DeleteRangeRequest) MarshalTo(data []byte) (int, error) { i = encodeVarintRpc(data, i, uint64(len(m.RangeEnd))) i += copy(data[i:], m.RangeEnd) } + if m.PrevKv { + data[i] = 0x18 + i++ + if m.PrevKv { + data[i] = 1 + } else { + data[i] = 0 + } + i++ + } return i, nil } @@ -3845,17 +3901,29 @@ func (m *DeleteRangeResponse) MarshalTo(data []byte) (int, error) { data[i] = 0xa i++ i = encodeVarintRpc(data, i, uint64(m.Header.Size())) - n3, err := m.Header.MarshalTo(data[i:]) + n4, err := m.Header.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n3 + i += n4 } if m.Deleted != 0 { data[i] = 0x10 i++ i = encodeVarintRpc(data, i, uint64(m.Deleted)) } + if len(m.PrevKvs) > 0 { + for _, msg := range m.PrevKvs { + data[i] = 0x1a + i++ + i = encodeVarintRpc(data, i, uint64(msg.Size())) + n, err := msg.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += n + } + } return i, nil } @@ -3875,11 +3943,11 @@ func (m *RequestOp) MarshalTo(data []byte) (int, error) { var l int _ = l if m.Request != nil { - nn4, err := m.Request.MarshalTo(data[i:]) + nn5, err := m.Request.MarshalTo(data[i:]) if err != nil { return 0, err } - i += nn4 + i += nn5 } return i, nil } @@ -3890,11 +3958,11 @@ func (m *RequestOp_RequestRange) MarshalTo(data []byte) (int, error) { data[i] = 0xa i++ i = encodeVarintRpc(data, i, uint64(m.RequestRange.Size())) - n5, err := m.RequestRange.MarshalTo(data[i:]) + n6, err := m.RequestRange.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n5 + i += n6 } return i, nil } @@ -3904,11 +3972,11 @@ func (m *RequestOp_RequestPut) MarshalTo(data []byte) (int, error) { data[i] = 0x12 i++ i = encodeVarintRpc(data, i, uint64(m.RequestPut.Size())) - n6, err := m.RequestPut.MarshalTo(data[i:]) + n7, err := m.RequestPut.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n6 + i += n7 } return i, nil } @@ -3918,11 +3986,11 @@ func (m *RequestOp_RequestDeleteRange) MarshalTo(data []byte) (int, error) { data[i] = 0x1a i++ i = encodeVarintRpc(data, i, uint64(m.RequestDeleteRange.Size())) - n7, err := m.RequestDeleteRange.MarshalTo(data[i:]) + n8, err := m.RequestDeleteRange.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n7 + i += n8 } return i, nil } @@ -3942,11 +4010,11 @@ func (m *ResponseOp) MarshalTo(data []byte) (int, error) { var l int _ = l if m.Response != nil { - nn8, err := m.Response.MarshalTo(data[i:]) + nn9, err := m.Response.MarshalTo(data[i:]) if err != nil { return 0, err } - i += nn8 + i += nn9 } return i, nil } @@ -3957,11 +4025,11 @@ func (m *ResponseOp_ResponseRange) MarshalTo(data []byte) (int, error) { data[i] = 0xa i++ i = encodeVarintRpc(data, i, uint64(m.ResponseRange.Size())) - n9, err := m.ResponseRange.MarshalTo(data[i:]) + n10, err := m.ResponseRange.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n9 + i += n10 } return i, nil } @@ -3971,11 +4039,11 @@ func (m *ResponseOp_ResponsePut) MarshalTo(data []byte) (int, error) { data[i] = 0x12 i++ i = encodeVarintRpc(data, i, uint64(m.ResponsePut.Size())) - n10, err := m.ResponsePut.MarshalTo(data[i:]) + n11, err := m.ResponsePut.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n10 + i += n11 } return i, nil } @@ -3985,11 +4053,11 @@ func (m *ResponseOp_ResponseDeleteRange) MarshalTo(data []byte) (int, error) { data[i] = 0x1a i++ i = encodeVarintRpc(data, i, uint64(m.ResponseDeleteRange.Size())) - n11, err := m.ResponseDeleteRange.MarshalTo(data[i:]) + n12, err := m.ResponseDeleteRange.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n11 + i += n12 } return i, nil } @@ -4025,11 +4093,11 @@ func (m *Compare) MarshalTo(data []byte) (int, error) { i += copy(data[i:], m.Key) } if m.TargetUnion != nil { - nn12, err := m.TargetUnion.MarshalTo(data[i:]) + nn13, err := m.TargetUnion.MarshalTo(data[i:]) if err != nil { return 0, err } - i += nn12 + i += nn13 } return i, nil } @@ -4138,11 +4206,11 @@ func (m *TxnResponse) MarshalTo(data []byte) (int, error) { data[i] = 0xa i++ i = encodeVarintRpc(data, i, uint64(m.Header.Size())) - n13, err := m.Header.MarshalTo(data[i:]) + n14, err := m.Header.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n13 + i += n14 } if m.Succeeded { data[i] = 0x10 @@ -4221,11 +4289,11 @@ func (m *CompactionResponse) MarshalTo(data []byte) (int, error) { data[i] = 0xa i++ i = encodeVarintRpc(data, i, uint64(m.Header.Size())) - n14, err := m.Header.MarshalTo(data[i:]) + n15, err := m.Header.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n14 + i += n15 } return i, nil } @@ -4267,11 +4335,11 @@ func (m *HashResponse) MarshalTo(data []byte) (int, error) { data[i] = 0xa i++ i = encodeVarintRpc(data, i, uint64(m.Header.Size())) - n15, err := m.Header.MarshalTo(data[i:]) + n16, err := m.Header.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n15 + i += n16 } if m.Hash != 0 { data[i] = 0x10 @@ -4318,11 +4386,11 @@ func (m *SnapshotResponse) MarshalTo(data []byte) (int, error) { data[i] = 0xa i++ i = encodeVarintRpc(data, i, uint64(m.Header.Size())) - n16, err := m.Header.MarshalTo(data[i:]) + n17, err := m.Header.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n16 + i += n17 } if m.RemainingBytes != 0 { data[i] = 0x10 @@ -4354,11 +4422,11 @@ func (m *WatchRequest) MarshalTo(data []byte) (int, error) { var l int _ = l if m.RequestUnion != nil { - nn17, err := m.RequestUnion.MarshalTo(data[i:]) + nn18, err := m.RequestUnion.MarshalTo(data[i:]) if err != nil { return 0, err } - i += nn17 + i += nn18 } return i, nil } @@ -4369,11 +4437,11 @@ func (m *WatchRequest_CreateRequest) MarshalTo(data []byte) (int, error) { data[i] = 0xa i++ i = encodeVarintRpc(data, i, uint64(m.CreateRequest.Size())) - n18, err := m.CreateRequest.MarshalTo(data[i:]) + n19, err := m.CreateRequest.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n18 + i += n19 } return i, nil } @@ -4383,11 +4451,11 @@ func (m *WatchRequest_CancelRequest) MarshalTo(data []byte) (int, error) { data[i] = 0x12 i++ i = encodeVarintRpc(data, i, uint64(m.CancelRequest.Size())) - n19, err := m.CancelRequest.MarshalTo(data[i:]) + n20, err := m.CancelRequest.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n19 + i += n20 } return i, nil } @@ -4433,6 +4501,16 @@ func (m *WatchCreateRequest) MarshalTo(data []byte) (int, error) { } i++ } + if m.PrevKv { + data[i] = 0x30 + i++ + if m.PrevKv { + data[i] = 1 + } else { + data[i] = 0 + } + i++ + } return i, nil } @@ -4478,11 +4556,11 @@ func (m *WatchResponse) MarshalTo(data []byte) (int, error) { data[i] = 0xa i++ i = encodeVarintRpc(data, i, uint64(m.Header.Size())) - n20, err := m.Header.MarshalTo(data[i:]) + n21, err := m.Header.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n20 + i += n21 } if m.WatchId != 0 { data[i] = 0x10 @@ -4576,11 +4654,11 @@ func (m *LeaseGrantResponse) MarshalTo(data []byte) (int, error) { data[i] = 0xa i++ i = encodeVarintRpc(data, i, uint64(m.Header.Size())) - n21, err := m.Header.MarshalTo(data[i:]) + n22, err := m.Header.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n21 + i += n22 } if m.ID != 0 { data[i] = 0x10 @@ -4643,11 +4721,11 @@ func (m *LeaseRevokeResponse) MarshalTo(data []byte) (int, error) { data[i] = 0xa i++ i = encodeVarintRpc(data, i, uint64(m.Header.Size())) - n22, err := m.Header.MarshalTo(data[i:]) + n23, err := m.Header.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n22 + i += n23 } return i, nil } @@ -4694,11 +4772,11 @@ func (m *LeaseKeepAliveResponse) MarshalTo(data []byte) (int, error) { data[i] = 0xa i++ i = encodeVarintRpc(data, i, uint64(m.Header.Size())) - n23, err := m.Header.MarshalTo(data[i:]) + n24, err := m.Header.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n23 + i += n24 } if m.ID != 0 { data[i] = 0x10 @@ -4824,21 +4902,21 @@ func (m *MemberAddResponse) MarshalTo(data []byte) (int, error) { data[i] = 0xa i++ i = encodeVarintRpc(data, i, uint64(m.Header.Size())) - n24, err := m.Header.MarshalTo(data[i:]) + n25, err := m.Header.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n24 + i += n25 } if m.Member != nil { data[i] = 0x12 i++ i = encodeVarintRpc(data, i, uint64(m.Member.Size())) - n25, err := m.Member.MarshalTo(data[i:]) + n26, err := m.Member.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n25 + i += n26 } return i, nil } @@ -4885,11 +4963,11 @@ func (m *MemberRemoveResponse) MarshalTo(data []byte) (int, error) { data[i] = 0xa i++ i = encodeVarintRpc(data, i, uint64(m.Header.Size())) - n26, err := m.Header.MarshalTo(data[i:]) + n27, err := m.Header.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n26 + i += n27 } return i, nil } @@ -4951,11 +5029,11 @@ func (m *MemberUpdateResponse) MarshalTo(data []byte) (int, error) { data[i] = 0xa i++ i = encodeVarintRpc(data, i, uint64(m.Header.Size())) - n27, err := m.Header.MarshalTo(data[i:]) + n28, err := m.Header.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n27 + i += n28 } return i, nil } @@ -4997,11 +5075,11 @@ func (m *MemberListResponse) MarshalTo(data []byte) (int, error) { data[i] = 0xa i++ i = encodeVarintRpc(data, i, uint64(m.Header.Size())) - n28, err := m.Header.MarshalTo(data[i:]) + n29, err := m.Header.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n28 + i += n29 } if len(m.Members) > 0 { for _, msg := range m.Members { @@ -5055,11 +5133,11 @@ func (m *DefragmentResponse) MarshalTo(data []byte) (int, error) { data[i] = 0xa i++ i = encodeVarintRpc(data, i, uint64(m.Header.Size())) - n29, err := m.Header.MarshalTo(data[i:]) + n30, err := m.Header.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n29 + i += n30 } return i, nil } @@ -5144,11 +5222,11 @@ func (m *AlarmResponse) MarshalTo(data []byte) (int, error) { data[i] = 0xa i++ i = encodeVarintRpc(data, i, uint64(m.Header.Size())) - n30, err := m.Header.MarshalTo(data[i:]) + n31, err := m.Header.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n30 + i += n31 } if len(m.Alarms) > 0 { for _, msg := range m.Alarms { @@ -5202,11 +5280,11 @@ func (m *StatusResponse) MarshalTo(data []byte) (int, error) { data[i] = 0xa i++ i = encodeVarintRpc(data, i, uint64(m.Header.Size())) - n31, err := m.Header.MarshalTo(data[i:]) + n32, err := m.Header.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n31 + i += n32 } if len(m.Version) > 0 { data[i] = 0x12 @@ -5604,11 +5682,11 @@ func (m *AuthRoleGrantPermissionRequest) MarshalTo(data []byte) (int, error) { data[i] = 0x12 i++ i = encodeVarintRpc(data, i, uint64(m.Perm.Size())) - n32, err := m.Perm.MarshalTo(data[i:]) + n33, err := m.Perm.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n32 + i += n33 } return i, nil } @@ -5668,11 +5746,11 @@ func (m *AuthEnableResponse) MarshalTo(data []byte) (int, error) { data[i] = 0xa i++ i = encodeVarintRpc(data, i, uint64(m.Header.Size())) - n33, err := m.Header.MarshalTo(data[i:]) + n34, err := m.Header.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n33 + i += n34 } return i, nil } @@ -5696,11 +5774,11 @@ func (m *AuthDisableResponse) MarshalTo(data []byte) (int, error) { data[i] = 0xa i++ i = encodeVarintRpc(data, i, uint64(m.Header.Size())) - n34, err := m.Header.MarshalTo(data[i:]) + n35, err := m.Header.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n34 + i += n35 } return i, nil } @@ -5724,11 +5802,11 @@ func (m *AuthenticateResponse) MarshalTo(data []byte) (int, error) { data[i] = 0xa i++ i = encodeVarintRpc(data, i, uint64(m.Header.Size())) - n35, err := m.Header.MarshalTo(data[i:]) + n36, err := m.Header.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n35 + i += n36 } if len(m.Token) > 0 { data[i] = 0x12 @@ -5758,11 +5836,11 @@ func (m *AuthUserAddResponse) MarshalTo(data []byte) (int, error) { data[i] = 0xa i++ i = encodeVarintRpc(data, i, uint64(m.Header.Size())) - n36, err := m.Header.MarshalTo(data[i:]) + n37, err := m.Header.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n36 + i += n37 } return i, nil } @@ -5786,11 +5864,11 @@ func (m *AuthUserGetResponse) MarshalTo(data []byte) (int, error) { data[i] = 0xa i++ i = encodeVarintRpc(data, i, uint64(m.Header.Size())) - n37, err := m.Header.MarshalTo(data[i:]) + n38, err := m.Header.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n37 + i += n38 } if len(m.Roles) > 0 { for _, s := range m.Roles { @@ -5829,11 +5907,11 @@ func (m *AuthUserDeleteResponse) MarshalTo(data []byte) (int, error) { data[i] = 0xa i++ i = encodeVarintRpc(data, i, uint64(m.Header.Size())) - n38, err := m.Header.MarshalTo(data[i:]) + n39, err := m.Header.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n38 + i += n39 } return i, nil } @@ -5857,11 +5935,11 @@ func (m *AuthUserChangePasswordResponse) MarshalTo(data []byte) (int, error) { data[i] = 0xa i++ i = encodeVarintRpc(data, i, uint64(m.Header.Size())) - n39, err := m.Header.MarshalTo(data[i:]) + n40, err := m.Header.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n39 + i += n40 } return i, nil } @@ -5885,11 +5963,11 @@ func (m *AuthUserGrantRoleResponse) MarshalTo(data []byte) (int, error) { data[i] = 0xa i++ i = encodeVarintRpc(data, i, uint64(m.Header.Size())) - n40, err := m.Header.MarshalTo(data[i:]) + n41, err := m.Header.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n40 + i += n41 } return i, nil } @@ -5913,11 +5991,11 @@ func (m *AuthUserRevokeRoleResponse) MarshalTo(data []byte) (int, error) { data[i] = 0xa i++ i = encodeVarintRpc(data, i, uint64(m.Header.Size())) - n41, err := m.Header.MarshalTo(data[i:]) + n42, err := m.Header.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n41 + i += n42 } return i, nil } @@ -5941,11 +6019,11 @@ func (m *AuthRoleAddResponse) MarshalTo(data []byte) (int, error) { data[i] = 0xa i++ i = encodeVarintRpc(data, i, uint64(m.Header.Size())) - n42, err := m.Header.MarshalTo(data[i:]) + n43, err := m.Header.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n42 + i += n43 } return i, nil } @@ -5969,11 +6047,11 @@ func (m *AuthRoleGetResponse) MarshalTo(data []byte) (int, error) { data[i] = 0xa i++ i = encodeVarintRpc(data, i, uint64(m.Header.Size())) - n43, err := m.Header.MarshalTo(data[i:]) + n44, err := m.Header.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n43 + i += n44 } if len(m.Perm) > 0 { for _, msg := range m.Perm { @@ -6009,11 +6087,11 @@ func (m *AuthRoleListResponse) MarshalTo(data []byte) (int, error) { data[i] = 0xa i++ i = encodeVarintRpc(data, i, uint64(m.Header.Size())) - n44, err := m.Header.MarshalTo(data[i:]) + n45, err := m.Header.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n44 + i += n45 } if len(m.Roles) > 0 { for _, s := range m.Roles { @@ -6052,11 +6130,11 @@ func (m *AuthUserListResponse) MarshalTo(data []byte) (int, error) { data[i] = 0xa i++ i = encodeVarintRpc(data, i, uint64(m.Header.Size())) - n45, err := m.Header.MarshalTo(data[i:]) + n46, err := m.Header.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n45 + i += n46 } if len(m.Users) > 0 { for _, s := range m.Users { @@ -6095,11 +6173,11 @@ func (m *AuthRoleDeleteResponse) MarshalTo(data []byte) (int, error) { data[i] = 0xa i++ i = encodeVarintRpc(data, i, uint64(m.Header.Size())) - n46, err := m.Header.MarshalTo(data[i:]) + n47, err := m.Header.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n46 + i += n47 } return i, nil } @@ -6123,11 +6201,11 @@ func (m *AuthRoleGrantPermissionResponse) MarshalTo(data []byte) (int, error) { data[i] = 0xa i++ i = encodeVarintRpc(data, i, uint64(m.Header.Size())) - n47, err := m.Header.MarshalTo(data[i:]) + n48, err := m.Header.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n47 + i += n48 } return i, nil } @@ -6151,11 +6229,11 @@ func (m *AuthRoleRevokePermissionResponse) MarshalTo(data []byte) (int, error) { data[i] = 0xa i++ i = encodeVarintRpc(data, i, uint64(m.Header.Size())) - n48, err := m.Header.MarshalTo(data[i:]) + n49, err := m.Header.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n48 + i += n49 } return i, nil } @@ -6276,6 +6354,9 @@ func (m *PutRequest) Size() (n int) { if m.Lease != 0 { n += 1 + sovRpc(uint64(m.Lease)) } + if m.PrevKv { + n += 2 + } return n } @@ -6286,6 +6367,10 @@ func (m *PutResponse) Size() (n int) { l = m.Header.Size() n += 1 + l + sovRpc(uint64(l)) } + if m.PrevKv != nil { + l = m.PrevKv.Size() + n += 1 + l + sovRpc(uint64(l)) + } return n } @@ -6300,6 +6385,9 @@ func (m *DeleteRangeRequest) Size() (n int) { if l > 0 { n += 1 + l + sovRpc(uint64(l)) } + if m.PrevKv { + n += 2 + } return n } @@ -6313,6 +6401,12 @@ func (m *DeleteRangeResponse) Size() (n int) { if m.Deleted != 0 { n += 1 + sovRpc(uint64(m.Deleted)) } + if len(m.PrevKvs) > 0 { + for _, e := range m.PrevKvs { + l = e.Size() + n += 1 + l + sovRpc(uint64(l)) + } + } return n } @@ -6585,6 +6679,9 @@ func (m *WatchCreateRequest) Size() (n int) { if m.ProgressNotify { n += 2 } + if m.PrevKv { + n += 2 + } return n } @@ -7923,6 +8020,26 @@ func (m *PutRequest) Unmarshal(data []byte) error { break } } + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field PrevKv", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.PrevKv = bool(v != 0) default: iNdEx = preIndex skippy, err := skipRpc(data[iNdEx:]) @@ -8006,6 +8123,39 @@ func (m *PutResponse) Unmarshal(data []byte) error { return err } iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PrevKv", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthRpc + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.PrevKv == nil { + m.PrevKv = &mvccpb.KeyValue{} + } + if err := m.PrevKv.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipRpc(data[iNdEx:]) @@ -8118,6 +8268,26 @@ func (m *DeleteRangeRequest) Unmarshal(data []byte) error { m.RangeEnd = []byte{} } iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field PrevKv", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.PrevKv = bool(v != 0) default: iNdEx = preIndex skippy, err := skipRpc(data[iNdEx:]) @@ -8220,6 +8390,37 @@ func (m *DeleteRangeResponse) Unmarshal(data []byte) error { break } } + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PrevKvs", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthRpc + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.PrevKvs = append(m.PrevKvs, &mvccpb.KeyValue{}) + if err := m.PrevKvs[len(m.PrevKvs)-1].Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipRpc(data[iNdEx:]) @@ -9770,6 +9971,26 @@ func (m *WatchCreateRequest) Unmarshal(data []byte) error { } } m.ProgressNotify = bool(v != 0) + case 6: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field PrevKv", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.PrevKv = bool(v != 0) default: iNdEx = preIndex skippy, err := skipRpc(data[iNdEx:]) @@ -15125,203 +15346,206 @@ var ( ) var fileDescriptorRpc = []byte{ - // 3154 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xb4, 0x5a, 0xcd, 0x72, 0xe3, 0xc6, - 0xf1, 0x17, 0x48, 0x4a, 0x14, 0x9b, 0x14, 0xc5, 0x1d, 0x69, 0xd7, 0x14, 0x56, 0xab, 0xd5, 0xce, - 0x7e, 0xc9, 0x6b, 0x5b, 0xb4, 0x65, 0xff, 0xff, 0x87, 0x4d, 0xca, 0x55, 0x92, 0xc8, 0xac, 0x64, - 0xc9, 0xd2, 0x1a, 0xd2, 0xca, 0x4e, 0x55, 0x2a, 0x2a, 0x88, 0x9c, 0x25, 0x59, 0x22, 0x01, 0x1a, - 0x00, 0xb9, 0x2b, 0x27, 0xa9, 0x4a, 0xb9, 0xe2, 0x43, 0x72, 0xf5, 0x21, 0x5f, 0xc7, 0x3c, 0x43, - 0x6e, 0x79, 0x80, 0x54, 0x2e, 0x71, 0x55, 0x5e, 0x20, 0xb5, 0xc9, 0x21, 0x87, 0xdc, 0x53, 0x39, - 0xa4, 0x92, 0x9a, 0x2f, 0x60, 0x00, 0x02, 0x94, 0x1c, 0xc4, 0x17, 0x09, 0xd3, 0xd3, 0xd3, 0xbf, - 0x9e, 0x9e, 0xe9, 0x46, 0x77, 0x83, 0x50, 0x70, 0x06, 0xcd, 0xf5, 0x81, 0x63, 0x7b, 0x36, 0x2a, - 0x11, 0xaf, 0xd9, 0x72, 0x89, 0x33, 0x22, 0xce, 0xe0, 0x4c, 0x5f, 0x6c, 0xdb, 0x6d, 0x9b, 0x4d, - 0xd4, 0xe8, 0x13, 0xe7, 0xd1, 0x97, 0x28, 0x4f, 0xad, 0x3f, 0x6a, 0x36, 0xd9, 0x9f, 0xc1, 0x59, - 0xed, 0x7c, 0x24, 0xa6, 0x6e, 0xb2, 0x29, 0x73, 0xe8, 0x75, 0xd8, 0x9f, 0xc1, 0x19, 0xfb, 0x27, - 0x26, 0x97, 0xdb, 0xb6, 0xdd, 0xee, 0x91, 0x9a, 0x39, 0xe8, 0xd6, 0x4c, 0xcb, 0xb2, 0x3d, 0xd3, - 0xeb, 0xda, 0x96, 0xcb, 0x67, 0xf1, 0x17, 0x1a, 0x94, 0x0d, 0xe2, 0x0e, 0x6c, 0xcb, 0x25, 0x3b, - 0xc4, 0x6c, 0x11, 0x07, 0xdd, 0x02, 0x68, 0xf6, 0x86, 0xae, 0x47, 0x9c, 0xd3, 0x6e, 0xab, 0xaa, - 0xad, 0x6a, 0x6b, 0x39, 0xa3, 0x20, 0x28, 0xbb, 0x2d, 0x74, 0x13, 0x0a, 0x7d, 0xd2, 0x3f, 0xe3, - 0xb3, 0x19, 0x36, 0x3b, 0xcb, 0x09, 0xbb, 0x2d, 0xa4, 0xc3, 0xac, 0x43, 0x46, 0x5d, 0xb7, 0x6b, - 0x5b, 0xd5, 0xec, 0xaa, 0xb6, 0x96, 0x35, 0xfc, 0x31, 0x5d, 0xe8, 0x98, 0xcf, 0xbd, 0x53, 0x8f, - 0x38, 0xfd, 0x6a, 0x8e, 0x2f, 0xa4, 0x84, 0x63, 0xe2, 0xf4, 0xf1, 0x57, 0x59, 0x28, 0x19, 0xa6, - 0xd5, 0x26, 0x06, 0xf9, 0x74, 0x48, 0x5c, 0x0f, 0x55, 0x20, 0x7b, 0x4e, 0x2e, 0x18, 0x7c, 0xc9, - 0xa0, 0x8f, 0x7c, 0xbd, 0xd5, 0x26, 0xa7, 0xc4, 0xe2, 0xc0, 0x25, 0xba, 0xde, 0x6a, 0x93, 0x86, - 0xd5, 0x42, 0x8b, 0x30, 0xdd, 0xeb, 0xf6, 0xbb, 0x9e, 0x40, 0xe5, 0x83, 0x90, 0x3a, 0xb9, 0x88, - 0x3a, 0xdb, 0x00, 0xae, 0xed, 0x78, 0xa7, 0xb6, 0xd3, 0x22, 0x4e, 0x75, 0x7a, 0x55, 0x5b, 0x2b, - 0x6f, 0xdc, 0x5b, 0x57, 0x0f, 0x62, 0x5d, 0x55, 0x68, 0xfd, 0xc8, 0x76, 0xbc, 0x43, 0xca, 0x6b, - 0x14, 0x5c, 0xf9, 0x88, 0xbe, 0x03, 0x45, 0x26, 0xc4, 0x33, 0x9d, 0x36, 0xf1, 0xaa, 0x33, 0x4c, - 0xca, 0xfd, 0x4b, 0xa4, 0x1c, 0x33, 0x66, 0x83, 0xc1, 0xf3, 0x67, 0x84, 0xa1, 0xe4, 0x12, 0xa7, - 0x6b, 0xf6, 0xba, 0x9f, 0x99, 0x67, 0x3d, 0x52, 0xcd, 0xaf, 0x6a, 0x6b, 0xb3, 0x46, 0x88, 0x46, - 0xf7, 0x7f, 0x4e, 0x2e, 0xdc, 0x53, 0xdb, 0xea, 0x5d, 0x54, 0x67, 0x19, 0xc3, 0x2c, 0x25, 0x1c, - 0x5a, 0xbd, 0x0b, 0x76, 0x68, 0xf6, 0xd0, 0xf2, 0xf8, 0x6c, 0x81, 0xcd, 0x16, 0x18, 0x85, 0x4e, - 0xe3, 0x75, 0x28, 0xf8, 0xfa, 0xa3, 0x59, 0xc8, 0x1d, 0x1c, 0x1e, 0x34, 0x2a, 0x53, 0x08, 0x60, - 0x66, 0xf3, 0x68, 0xbb, 0x71, 0x50, 0xaf, 0x68, 0xa8, 0x08, 0xf9, 0x7a, 0x83, 0x0f, 0x32, 0x78, - 0x0b, 0x20, 0xd0, 0x14, 0xe5, 0x21, 0xbb, 0xd7, 0xf8, 0x6e, 0x65, 0x8a, 0xf2, 0x9c, 0x34, 0x8c, - 0xa3, 0xdd, 0xc3, 0x83, 0x8a, 0x46, 0x17, 0x6f, 0x1b, 0x8d, 0xcd, 0xe3, 0x46, 0x25, 0x43, 0x39, - 0x3e, 0x3c, 0xac, 0x57, 0xb2, 0xa8, 0x00, 0xd3, 0x27, 0x9b, 0xfb, 0xcf, 0x1a, 0x95, 0x1c, 0xfe, - 0x52, 0x83, 0x39, 0xb1, 0x77, 0x7e, 0xbf, 0xd0, 0x7b, 0x30, 0xd3, 0x61, 0x77, 0x8c, 0x1d, 0x6b, - 0x71, 0x63, 0x39, 0x62, 0xa8, 0xd0, 0x3d, 0x34, 0x04, 0x2f, 0xc2, 0x90, 0x3d, 0x1f, 0xb9, 0xd5, - 0xcc, 0x6a, 0x76, 0xad, 0xb8, 0x51, 0x59, 0xe7, 0x97, 0x7f, 0x7d, 0x8f, 0x5c, 0x9c, 0x98, 0xbd, - 0x21, 0x31, 0xe8, 0x24, 0x42, 0x90, 0xeb, 0xdb, 0x0e, 0x61, 0xa7, 0x3f, 0x6b, 0xb0, 0x67, 0x7a, - 0x25, 0x98, 0x01, 0xc4, 0xc9, 0xf3, 0x01, 0xfe, 0x00, 0xe0, 0xe9, 0xd0, 0x4b, 0xbe, 0x65, 0x8b, - 0x30, 0x3d, 0xa2, 0x72, 0xc5, 0x0d, 0xe3, 0x03, 0x76, 0xbd, 0x88, 0xe9, 0x12, 0xff, 0x7a, 0xd1, - 0x01, 0xde, 0x86, 0x22, 0x93, 0x95, 0x66, 0x7b, 0x78, 0x1b, 0x50, 0x9d, 0xf4, 0x88, 0x47, 0x52, - 0x5c, 0x7f, 0x4c, 0x60, 0x21, 0x24, 0x24, 0x95, 0xc1, 0xab, 0x90, 0x6f, 0x31, 0x61, 0x1c, 0x27, - 0x6b, 0xc8, 0x21, 0xfe, 0xbb, 0x06, 0x05, 0xa1, 0xe1, 0xe1, 0x00, 0x6d, 0xc2, 0x9c, 0xc3, 0x07, - 0xa7, 0x4c, 0x11, 0x01, 0xa2, 0x27, 0x5f, 0xff, 0x9d, 0x29, 0xa3, 0x24, 0x96, 0x30, 0x32, 0xfa, - 0x16, 0x14, 0xa5, 0x88, 0xc1, 0xd0, 0x63, 0x70, 0xc5, 0x8d, 0x6a, 0x58, 0x40, 0x70, 0x5c, 0x3b, - 0x53, 0x06, 0x08, 0xf6, 0xa7, 0x43, 0x0f, 0x1d, 0xc3, 0xa2, 0x5c, 0xcc, 0x15, 0x14, 0x6a, 0x64, - 0x99, 0x94, 0xd5, 0xb0, 0x94, 0x71, 0x1b, 0xef, 0x4c, 0x19, 0x48, 0xac, 0x57, 0x26, 0xb7, 0x0a, - 0x90, 0x17, 0x54, 0xfc, 0x0f, 0x0d, 0x40, 0xda, 0xe8, 0x70, 0x80, 0xea, 0x50, 0x76, 0xc4, 0x28, - 0xb4, 0xe1, 0x9b, 0xb1, 0x1b, 0x16, 0xa6, 0x9d, 0x32, 0xe6, 0xe4, 0x22, 0xbe, 0xe5, 0xf7, 0xa1, - 0xe4, 0x4b, 0x09, 0xf6, 0xbc, 0x14, 0xb3, 0x67, 0x5f, 0x42, 0x51, 0x2e, 0xa0, 0xbb, 0xfe, 0x18, - 0xae, 0xfb, 0xeb, 0x63, 0xb6, 0x7d, 0x67, 0xc2, 0xb6, 0x7d, 0x81, 0x0b, 0x52, 0x82, 0xba, 0x71, - 0xa0, 0xc1, 0x92, 0x93, 0xf1, 0xaf, 0xb2, 0x90, 0xdf, 0xb6, 0xfb, 0x03, 0xd3, 0xa1, 0x67, 0x34, - 0xe3, 0x10, 0x77, 0xd8, 0xf3, 0xd8, 0x76, 0xcb, 0x1b, 0x77, 0xc3, 0x08, 0x82, 0x4d, 0xfe, 0x37, - 0x18, 0xab, 0x21, 0x96, 0xd0, 0xc5, 0x22, 0x36, 0x66, 0xae, 0xb0, 0x58, 0x44, 0x46, 0xb1, 0x44, - 0x3a, 0x41, 0x36, 0x70, 0x02, 0x1d, 0xf2, 0x23, 0xe2, 0x04, 0xf1, 0x7c, 0x67, 0xca, 0x90, 0x04, - 0xf4, 0x3a, 0xcc, 0x37, 0x1d, 0x62, 0x52, 0x7b, 0xc8, 0x98, 0x3f, 0x2d, 0x78, 0xca, 0x7c, 0xc2, - 0x90, 0xb1, 0xff, 0x2e, 0x94, 0xfa, 0x76, 0x2b, 0xe0, 0x9b, 0x11, 0x7c, 0xc5, 0xbe, 0xdd, 0xf2, - 0x99, 0x6e, 0xc8, 0x48, 0x40, 0x83, 0x71, 0x69, 0x67, 0x4a, 0xc4, 0x02, 0xfc, 0x0e, 0xcc, 0x85, - 0xf6, 0x4a, 0x63, 0x5e, 0xe3, 0xa3, 0x67, 0x9b, 0xfb, 0x3c, 0x40, 0x3e, 0x61, 0x31, 0xd1, 0xa8, - 0x68, 0x34, 0xce, 0xee, 0x37, 0x8e, 0x8e, 0x2a, 0x19, 0xfc, 0x6d, 0x7f, 0x89, 0x88, 0xa8, 0x4a, - 0x20, 0x9d, 0x52, 0x02, 0xa9, 0x26, 0x03, 0x69, 0x26, 0x08, 0xa4, 0xd9, 0xad, 0x32, 0x94, 0xb8, - 0x41, 0x4e, 0x87, 0x56, 0xd7, 0xb6, 0xf0, 0x6f, 0x34, 0x80, 0xe3, 0x97, 0x96, 0x0c, 0x15, 0x35, - 0xc8, 0x37, 0xb9, 0xf0, 0xaa, 0xc6, 0x62, 0xe4, 0xf5, 0x58, 0x1b, 0x1b, 0x92, 0x0b, 0xbd, 0x03, - 0x79, 0x77, 0xd8, 0x6c, 0x12, 0x57, 0x06, 0xd5, 0xd7, 0xa2, 0x61, 0x41, 0x78, 0xb8, 0x21, 0xf9, - 0xe8, 0x92, 0xe7, 0x66, 0xb7, 0x37, 0x64, 0x21, 0x76, 0xf2, 0x12, 0xc1, 0x87, 0x7f, 0xa9, 0x41, - 0x91, 0x69, 0x99, 0x2a, 0x16, 0x2d, 0x43, 0x81, 0xe9, 0x40, 0x5a, 0x22, 0x1a, 0xcd, 0x1a, 0x01, - 0x01, 0xfd, 0x3f, 0x14, 0xe4, 0x95, 0x75, 0x85, 0x62, 0xd5, 0x78, 0xb1, 0x87, 0x03, 0x23, 0x60, - 0xc5, 0x7b, 0x70, 0x8d, 0x59, 0xa5, 0x49, 0x53, 0x21, 0x69, 0x47, 0x35, 0x59, 0xd0, 0x22, 0xc9, - 0x82, 0x0e, 0xb3, 0x83, 0xce, 0x85, 0xdb, 0x6d, 0x9a, 0x3d, 0xa1, 0x85, 0x3f, 0xc6, 0x1f, 0x00, - 0x52, 0x85, 0xa5, 0x7a, 0x19, 0xcc, 0x41, 0x71, 0xc7, 0x74, 0x3b, 0x42, 0x25, 0xfc, 0x09, 0x94, - 0xf8, 0x30, 0x95, 0x0d, 0x11, 0xe4, 0x3a, 0xa6, 0xdb, 0x61, 0x8a, 0xcf, 0x19, 0xec, 0x19, 0x5f, - 0x83, 0xf9, 0x23, 0xcb, 0x1c, 0xb8, 0x1d, 0x5b, 0x06, 0x57, 0x9a, 0x0a, 0x56, 0x02, 0x5a, 0x2a, - 0xc4, 0x87, 0x30, 0xef, 0x90, 0xbe, 0xd9, 0xb5, 0xba, 0x56, 0xfb, 0xf4, 0xec, 0xc2, 0x23, 0xae, - 0xc8, 0x14, 0xcb, 0x3e, 0x79, 0x8b, 0x52, 0xa9, 0x6a, 0x67, 0x3d, 0xfb, 0x4c, 0xb8, 0x38, 0x7b, - 0xc6, 0xbf, 0xd5, 0xa0, 0xf4, 0xb1, 0xe9, 0x35, 0xa5, 0x15, 0xd0, 0x2e, 0x94, 0x7d, 0xc7, 0x66, - 0x14, 0xa1, 0x4b, 0x24, 0xc2, 0xb3, 0x35, 0xdb, 0xc2, 0xd1, 0x65, 0x84, 0x9f, 0x6b, 0xaa, 0x04, - 0x26, 0xca, 0xb4, 0x9a, 0xa4, 0xe7, 0x8b, 0xca, 0x24, 0x8b, 0x62, 0x8c, 0xaa, 0x28, 0x95, 0xb0, - 0x35, 0x1f, 0xbc, 0xfd, 0xb8, 0x5b, 0x7e, 0xa9, 0x01, 0x1a, 0xd7, 0xe1, 0xeb, 0x26, 0xb2, 0xf7, - 0xa1, 0xec, 0x7a, 0xa6, 0xe3, 0x9d, 0x46, 0xf2, 0xe8, 0x39, 0x46, 0xf5, 0x83, 0xd3, 0x43, 0x98, - 0x1f, 0x38, 0x76, 0xdb, 0x21, 0xae, 0x7b, 0x6a, 0xd9, 0x5e, 0xf7, 0xf9, 0x05, 0x0b, 0x88, 0xb3, - 0x46, 0x59, 0x92, 0x0f, 0x18, 0x15, 0xd7, 0xa4, 0x52, 0xaa, 0xf2, 0x68, 0x09, 0x66, 0x5f, 0x50, - 0xaa, 0xcc, 0xf0, 0xb3, 0x46, 0x9e, 0x8d, 0x77, 0x5b, 0xf8, 0x6f, 0x1a, 0xcc, 0x09, 0xf3, 0xa7, - 0xba, 0x03, 0x2a, 0x44, 0x26, 0x04, 0x41, 0x13, 0x0c, 0x7e, 0x2c, 0x2d, 0x91, 0xb0, 0xc9, 0x21, - 0xf5, 0x33, 0x6e, 0x65, 0xd2, 0x12, 0xfb, 0xf1, 0xc7, 0xe8, 0x75, 0xa8, 0x34, 0xb9, 0x9f, 0x45, - 0x02, 0xbc, 0x31, 0x2f, 0xe8, 0xbe, 0x75, 0xee, 0xc3, 0x0c, 0x19, 0x11, 0xcb, 0x73, 0xab, 0x45, - 0x16, 0x14, 0xe6, 0x64, 0xd6, 0xd8, 0xa0, 0x54, 0x43, 0x4c, 0xe2, 0xff, 0x83, 0x6b, 0xfb, 0x34, - 0x91, 0x7b, 0xe2, 0x98, 0x96, 0x9a, 0x12, 0x1e, 0x1f, 0xef, 0x0b, 0xab, 0x64, 0xbd, 0xe3, 0x7d, - 0x54, 0x86, 0xcc, 0x6e, 0x5d, 0xec, 0x21, 0xd3, 0xad, 0xe3, 0xcf, 0x35, 0x40, 0xea, 0xba, 0x54, - 0x66, 0x8a, 0x08, 0x97, 0xf0, 0xd9, 0x00, 0x7e, 0x11, 0xa6, 0x89, 0xe3, 0xd8, 0x0e, 0x33, 0x48, - 0xc1, 0xe0, 0x03, 0x7c, 0x4f, 0xe8, 0x60, 0x90, 0x91, 0x7d, 0xee, 0x5f, 0x36, 0x2e, 0x4d, 0xf3, - 0x55, 0xdd, 0x83, 0x85, 0x10, 0x57, 0xaa, 0xe0, 0xf4, 0x10, 0xae, 0x33, 0x61, 0x7b, 0x84, 0x0c, - 0x36, 0x7b, 0xdd, 0x51, 0x22, 0xea, 0x00, 0x6e, 0x44, 0x19, 0xbf, 0x59, 0x1b, 0xe1, 0x0e, 0xcc, - 0x7c, 0xc8, 0x6a, 0x50, 0x45, 0x97, 0x1c, 0xe3, 0x45, 0x90, 0xb3, 0xcc, 0x3e, 0x4f, 0xe7, 0x0b, - 0x06, 0x7b, 0x66, 0xd1, 0x9c, 0x10, 0xe7, 0x99, 0xb1, 0xcf, 0xdf, 0x1a, 0x05, 0xc3, 0x1f, 0xa3, - 0x15, 0x5a, 0xfd, 0x76, 0x89, 0xe5, 0xb1, 0xd9, 0x1c, 0x9b, 0x55, 0x28, 0x78, 0x1d, 0x2a, 0x1c, - 0x69, 0xb3, 0xd5, 0x52, 0xde, 0x1c, 0xbe, 0x3c, 0x2d, 0x2c, 0x0f, 0xbf, 0x80, 0x6b, 0x0a, 0x7f, - 0x2a, 0x33, 0xbc, 0x09, 0x33, 0xbc, 0xd0, 0x16, 0x41, 0x6b, 0x31, 0xbc, 0x8a, 0xc3, 0x18, 0x82, - 0x07, 0xdf, 0x87, 0x05, 0x41, 0x21, 0x7d, 0x3b, 0xee, 0xac, 0x98, 0x7d, 0xf0, 0x3e, 0x2c, 0x86, - 0xd9, 0x52, 0x5d, 0x91, 0x4d, 0x09, 0xfa, 0x6c, 0xd0, 0x52, 0x62, 0x60, 0xf4, 0x50, 0x54, 0x83, - 0x65, 0x22, 0x06, 0xf3, 0x15, 0x92, 0x22, 0x52, 0x29, 0xb4, 0x20, 0xcd, 0xbf, 0xdf, 0x75, 0xfd, - 0x37, 0xdd, 0x67, 0x80, 0x54, 0x62, 0xaa, 0x43, 0x59, 0x87, 0x3c, 0x37, 0xb8, 0x4c, 0xa6, 0xe2, - 0x4f, 0x45, 0x32, 0x51, 0x85, 0xea, 0xe4, 0xb9, 0x63, 0xb6, 0xfb, 0xc4, 0x8f, 0x39, 0x34, 0x85, - 0x50, 0x89, 0xa9, 0x76, 0xfc, 0x47, 0x0d, 0x4a, 0x9b, 0x3d, 0xd3, 0xe9, 0x4b, 0xe3, 0xbf, 0x0f, - 0x33, 0x3c, 0x37, 0x11, 0xf9, 0xfb, 0x83, 0xb0, 0x18, 0x95, 0x97, 0x0f, 0x36, 0x79, 0x26, 0x23, - 0x56, 0xd1, 0xc3, 0x12, 0xfd, 0x9d, 0x7a, 0xa4, 0xdf, 0x53, 0x47, 0x6f, 0xc1, 0xb4, 0x49, 0x97, - 0x30, 0x5f, 0x2c, 0x47, 0xb3, 0x42, 0x26, 0xed, 0xf8, 0x62, 0x40, 0x0c, 0xce, 0x85, 0xdf, 0x83, - 0xa2, 0x82, 0x40, 0x93, 0xdd, 0x27, 0x8d, 0xe3, 0xca, 0x14, 0x2a, 0xc1, 0xec, 0xe6, 0xf6, 0xf1, - 0xee, 0x09, 0xcf, 0x81, 0xcb, 0x00, 0xf5, 0x86, 0x3f, 0xce, 0xe0, 0x4f, 0xc4, 0x2a, 0xe1, 0xe1, - 0xaa, 0x3e, 0x5a, 0x92, 0x3e, 0x99, 0x2b, 0xe9, 0xf3, 0x12, 0xe6, 0xc4, 0xf6, 0x53, 0xdd, 0x81, - 0x77, 0x60, 0x86, 0xc9, 0x93, 0x57, 0x60, 0x29, 0x06, 0x56, 0x7a, 0x27, 0x67, 0xc4, 0xf3, 0x30, - 0x77, 0xe4, 0x99, 0xde, 0xd0, 0x95, 0x57, 0xe0, 0x0f, 0x1a, 0x94, 0x25, 0x25, 0x6d, 0xf5, 0x2e, - 0x4b, 0x24, 0x1e, 0xf3, 0xfc, 0x02, 0xe9, 0x06, 0xcc, 0xb4, 0xce, 0x8e, 0xba, 0x9f, 0xc9, 0x2e, - 0x86, 0x18, 0x51, 0x7a, 0x8f, 0xe3, 0xf0, 0xae, 0x9c, 0x18, 0xd1, 0xdc, 0xdb, 0x31, 0x9f, 0x7b, - 0xbb, 0x56, 0x8b, 0xbc, 0x64, 0x6f, 0xda, 0x9c, 0x11, 0x10, 0x58, 0xba, 0x2c, 0xba, 0x77, 0xac, - 0x7e, 0x52, 0xbb, 0x79, 0x0b, 0x70, 0x6d, 0x73, 0xe8, 0x75, 0x1a, 0x96, 0x79, 0xd6, 0x93, 0x41, - 0x00, 0x2f, 0x02, 0xa2, 0xc4, 0x7a, 0xd7, 0x55, 0xa9, 0x0d, 0x58, 0xa0, 0x54, 0x62, 0x79, 0xdd, - 0xa6, 0x12, 0x31, 0x64, 0xd8, 0xd6, 0x22, 0x61, 0xdb, 0x74, 0xdd, 0x17, 0xb6, 0xd3, 0x12, 0x5b, - 0xf3, 0xc7, 0xb8, 0xce, 0x85, 0x3f, 0x73, 0x43, 0x81, 0xf9, 0xeb, 0x4a, 0x59, 0x0b, 0xa4, 0x3c, - 0x21, 0xde, 0x04, 0x29, 0xf8, 0x0d, 0xb8, 0x2e, 0x39, 0x45, 0x0d, 0x3d, 0x81, 0xf9, 0x10, 0x6e, - 0x49, 0xe6, 0xed, 0x0e, 0x4d, 0xf4, 0x9e, 0x0a, 0xc0, 0xff, 0x56, 0xcf, 0x2d, 0xa8, 0xfa, 0x7a, - 0xb2, 0x1c, 0xc4, 0xee, 0xa9, 0x0a, 0x0c, 0x5d, 0x71, 0x67, 0x0a, 0x06, 0x7b, 0xa6, 0x34, 0xc7, - 0xee, 0xf9, 0x2f, 0x41, 0xfa, 0x8c, 0xb7, 0x61, 0x49, 0xca, 0x10, 0xd9, 0x41, 0x58, 0xc8, 0x98, - 0x42, 0x71, 0x42, 0x84, 0xc1, 0xe8, 0xd2, 0xc9, 0x66, 0x57, 0x39, 0xc3, 0xa6, 0x65, 0x32, 0x35, - 0x45, 0xe6, 0x75, 0x7e, 0x23, 0xa8, 0x62, 0x6a, 0xd0, 0x16, 0x64, 0x2a, 0x40, 0x25, 0x8b, 0x83, - 0xa0, 0xe4, 0xb1, 0x83, 0x18, 0x13, 0xfd, 0x3d, 0x58, 0xf1, 0x95, 0xa0, 0x76, 0x7b, 0x4a, 0x9c, - 0x7e, 0xd7, 0x75, 0x95, 0x22, 0x30, 0x6e, 0xe3, 0x0f, 0x20, 0x37, 0x20, 0x22, 0xa6, 0x14, 0x37, - 0xd0, 0x3a, 0xef, 0xb1, 0xaf, 0x2b, 0x8b, 0xd9, 0x3c, 0x6e, 0xc1, 0x6d, 0x29, 0x9d, 0x5b, 0x34, - 0x56, 0x7c, 0x54, 0x29, 0x59, 0x20, 0x70, 0xb3, 0x8e, 0x17, 0x08, 0x59, 0x7e, 0xf6, 0x7e, 0xab, - 0xef, 0x03, 0x6e, 0x48, 0xe9, 0x5b, 0xa9, 0xde, 0x15, 0x7b, 0xdc, 0xa6, 0xbe, 0x4b, 0xa6, 0x12, - 0x76, 0x06, 0x8b, 0x61, 0x4f, 0x4e, 0x15, 0xc6, 0x16, 0x61, 0xda, 0xb3, 0xcf, 0x89, 0x0c, 0x62, - 0x7c, 0x20, 0x15, 0xf6, 0xdd, 0x3c, 0x95, 0xc2, 0x66, 0x20, 0x8c, 0x5d, 0xc9, 0xb4, 0xfa, 0xd2, - 0xd3, 0x94, 0xf9, 0x0c, 0x1f, 0xe0, 0x03, 0xb8, 0x11, 0x0d, 0x13, 0xa9, 0x54, 0x3e, 0xe1, 0x17, - 0x38, 0x2e, 0x92, 0xa4, 0x92, 0xfb, 0x51, 0x10, 0x0c, 0x94, 0x80, 0x92, 0x4a, 0xa4, 0x01, 0x7a, - 0x5c, 0x7c, 0xf9, 0x5f, 0xdc, 0x57, 0x3f, 0xdc, 0xa4, 0x12, 0xe6, 0x06, 0xc2, 0xd2, 0x1f, 0x7f, - 0x10, 0x23, 0xb2, 0x13, 0x63, 0x84, 0x70, 0x92, 0x20, 0x8a, 0x7d, 0x03, 0x97, 0x4e, 0x60, 0x04, - 0x01, 0x34, 0x2d, 0x06, 0x7d, 0x87, 0xf8, 0x18, 0x6c, 0x20, 0x2f, 0xb6, 0x1a, 0x76, 0x53, 0x1d, - 0xc6, 0xc7, 0x41, 0xec, 0x1c, 0x8b, 0xcc, 0xa9, 0x04, 0x7f, 0x02, 0xab, 0xc9, 0x41, 0x39, 0x8d, - 0xe4, 0x47, 0x18, 0x0a, 0x7e, 0x42, 0xa9, 0x7c, 0x53, 0x2b, 0x42, 0xfe, 0xe0, 0xf0, 0xe8, 0xe9, - 0xe6, 0x76, 0xa3, 0xa2, 0x6d, 0xfc, 0x2b, 0x0b, 0x99, 0xbd, 0x13, 0xf4, 0x7d, 0x98, 0xe6, 0xcd, - 0xff, 0x09, 0xdf, 0x46, 0xf4, 0x49, 0x9f, 0x11, 0xf0, 0xf2, 0xe7, 0x7f, 0xfa, 0xeb, 0x97, 0x99, - 0x1b, 0xf8, 0x5a, 0x6d, 0xf4, 0xae, 0xd9, 0x1b, 0x74, 0xcc, 0xda, 0xf9, 0xa8, 0xc6, 0xde, 0x09, - 0x8f, 0xb5, 0x47, 0xe8, 0x04, 0xb2, 0x4f, 0x87, 0x1e, 0x4a, 0xfc, 0x70, 0xa2, 0x27, 0x7f, 0x5e, - 0xc0, 0x3a, 0x93, 0xbc, 0x88, 0xe7, 0x55, 0xc9, 0x83, 0xa1, 0x47, 0xe5, 0x8e, 0xa0, 0xa8, 0x7c, - 0x21, 0x40, 0x97, 0x7e, 0x52, 0xd1, 0x2f, 0xff, 0xfa, 0x80, 0x31, 0xc3, 0x5b, 0xc6, 0xaf, 0xa9, - 0x78, 0xfc, 0x43, 0x86, 0xba, 0x9f, 0xe3, 0x97, 0x56, 0x74, 0x3f, 0x41, 0xcf, 0x3b, 0xba, 0x1f, - 0xa5, 0xcf, 0x1c, 0xbf, 0x1f, 0xef, 0xa5, 0x45, 0xe5, 0xda, 0xe2, 0xab, 0x46, 0xd3, 0x43, 0xb7, - 0x63, 0x9a, 0xe4, 0x6a, 0x3b, 0x58, 0x5f, 0x4d, 0x66, 0x10, 0x48, 0x77, 0x18, 0xd2, 0x4d, 0x7c, - 0x43, 0x45, 0x6a, 0xfa, 0x7c, 0x8f, 0xb5, 0x47, 0x1b, 0x1d, 0x98, 0x66, 0xbd, 0x34, 0x74, 0x2a, - 0x1f, 0xf4, 0x98, 0x4e, 0x63, 0xc2, 0x0d, 0x08, 0x75, 0xe1, 0xf0, 0x12, 0x43, 0x5b, 0xc0, 0x65, - 0x1f, 0x8d, 0xb5, 0xd3, 0x1e, 0x6b, 0x8f, 0xd6, 0xb4, 0xb7, 0xb5, 0x8d, 0x7f, 0x66, 0x60, 0x9a, - 0x35, 0x5d, 0xd0, 0x00, 0x20, 0xe8, 0x4e, 0x45, 0xf7, 0x39, 0xd6, 0xef, 0x8a, 0xee, 0x73, 0xbc, - 0xb1, 0x85, 0x6f, 0x33, 0xe4, 0x25, 0xbc, 0xe8, 0x23, 0xb3, 0xcf, 0x9f, 0xb5, 0x36, 0xe5, 0xa2, - 0x66, 0x7d, 0x01, 0x45, 0xa5, 0xcb, 0x84, 0xe2, 0x24, 0x86, 0xda, 0x54, 0xd1, 0x6b, 0x12, 0xd3, - 0xa2, 0xc2, 0x77, 0x19, 0xe8, 0x2d, 0x5c, 0x55, 0x8d, 0xcb, 0x71, 0x1d, 0xc6, 0x49, 0x81, 0x7f, - 0xa2, 0x41, 0x39, 0xdc, 0x69, 0x42, 0x77, 0x63, 0x44, 0x47, 0x1b, 0x56, 0xfa, 0xbd, 0xc9, 0x4c, - 0x89, 0x2a, 0x70, 0xfc, 0x73, 0x42, 0x06, 0x26, 0xe5, 0x94, 0xb6, 0xff, 0x77, 0x16, 0xf2, 0xdb, - 0xfc, 0x07, 0x12, 0xc8, 0x83, 0x82, 0xdf, 0xef, 0x41, 0x2b, 0x71, 0xbd, 0x80, 0x20, 0x51, 0xd6, - 0x6f, 0x27, 0xce, 0x0b, 0x15, 0x1e, 0x30, 0x15, 0x56, 0xf1, 0x4d, 0x5f, 0x05, 0xf1, 0x43, 0x8c, - 0x1a, 0x2f, 0x79, 0x6b, 0x66, 0xab, 0x45, 0x0d, 0xf1, 0x63, 0x0d, 0x4a, 0x6a, 0x1b, 0x07, 0xdd, - 0x89, 0xed, 0x42, 0xa8, 0x9d, 0x20, 0x1d, 0x4f, 0x62, 0x11, 0xf8, 0xaf, 0x33, 0xfc, 0xbb, 0x78, - 0x25, 0x09, 0xdf, 0x61, 0xfc, 0x61, 0x15, 0x78, 0xe3, 0x26, 0x5e, 0x85, 0x50, 0x5f, 0x28, 0x5e, - 0x85, 0x70, 0xdf, 0xe7, 0x72, 0x15, 0x86, 0x8c, 0x9f, 0xaa, 0xf0, 0x12, 0x20, 0xe8, 0xeb, 0xa0, - 0x58, 0xe3, 0x2a, 0xa5, 0x43, 0xf4, 0xe6, 0x8f, 0xb7, 0x84, 0xf0, 0x43, 0x86, 0x7d, 0x07, 0x2f, - 0x27, 0x61, 0xf7, 0xba, 0x2e, 0xf5, 0x80, 0x8d, 0xdf, 0xe5, 0xa0, 0xf8, 0xa1, 0xd9, 0xb5, 0x3c, - 0x62, 0x99, 0x56, 0x93, 0xa0, 0x36, 0x4c, 0xb3, 0x77, 0x43, 0xd4, 0xdd, 0xd5, 0x66, 0x4b, 0xd4, - 0xdd, 0x43, 0x9d, 0x08, 0x7c, 0x9f, 0x41, 0xdf, 0xc6, 0xba, 0x0f, 0xdd, 0x0f, 0xe4, 0xd7, 0x58, - 0x17, 0x81, 0x6e, 0xf9, 0x1c, 0x66, 0x78, 0xd7, 0x00, 0x45, 0xa4, 0x85, 0xba, 0x0b, 0xfa, 0x72, - 0xfc, 0x64, 0xe2, 0x2d, 0x53, 0xb1, 0x5c, 0xc6, 0x4c, 0xc1, 0x7e, 0x00, 0x10, 0xb4, 0xa9, 0xa2, - 0xf6, 0x1d, 0xeb, 0x6a, 0xe9, 0xab, 0xc9, 0x0c, 0x02, 0xf8, 0x11, 0x03, 0xbe, 0x87, 0x6f, 0xc7, - 0x02, 0xb7, 0xfc, 0x05, 0x14, 0xbc, 0x09, 0xb9, 0x1d, 0xd3, 0xed, 0xa0, 0x48, 0xe8, 0x57, 0x3e, - 0x97, 0xe9, 0x7a, 0xdc, 0x94, 0x80, 0xba, 0xc7, 0xa0, 0x56, 0xf0, 0x52, 0x2c, 0x54, 0xc7, 0x74, - 0x69, 0x24, 0x45, 0x43, 0x98, 0x95, 0x9f, 0xc0, 0xd0, 0xad, 0x88, 0xcd, 0xc2, 0x9f, 0xcb, 0xf4, - 0x95, 0xa4, 0x69, 0x01, 0xb8, 0xc6, 0x00, 0x31, 0xbe, 0x15, 0x6f, 0x54, 0xc1, 0xfe, 0x58, 0x7b, - 0xf4, 0xb6, 0xb6, 0xf1, 0xb3, 0x0a, 0xe4, 0x68, 0x96, 0x42, 0x63, 0x77, 0x50, 0xdc, 0x45, 0x2d, - 0x3c, 0xd6, 0x52, 0x89, 0x5a, 0x78, 0xbc, 0x2e, 0x8c, 0x89, 0xdd, 0xec, 0x67, 0x62, 0x84, 0x71, - 0xd1, 0x1d, 0x7b, 0x50, 0x54, 0x4a, 0x40, 0x14, 0x23, 0x31, 0xdc, 0xb0, 0x89, 0xc6, 0xee, 0x98, - 0xfa, 0x11, 0xaf, 0x32, 0x50, 0x1d, 0x5f, 0x0f, 0x83, 0xb6, 0x38, 0x1b, 0x45, 0xfd, 0x21, 0x94, - 0xd4, 0x5a, 0x11, 0xc5, 0x08, 0x8d, 0x74, 0x84, 0xa2, 0xb1, 0x22, 0xae, 0xd4, 0x8c, 0x71, 0x1a, - 0xff, 0x47, 0x71, 0x92, 0x97, 0xa2, 0x7f, 0x0a, 0x79, 0x51, 0x41, 0xc6, 0xed, 0x37, 0xdc, 0x43, - 0x8a, 0xdb, 0x6f, 0xa4, 0xfc, 0x8c, 0x49, 0x04, 0x18, 0x2c, 0xcd, 0x94, 0x65, 0x80, 0x16, 0x90, - 0x4f, 0x88, 0x97, 0x04, 0x19, 0x74, 0x45, 0x92, 0x20, 0x95, 0x2a, 0x65, 0x22, 0x64, 0x9b, 0x78, - 0xe2, 0x2e, 0xcb, 0x12, 0x00, 0x25, 0x48, 0x54, 0xa3, 0x21, 0x9e, 0xc4, 0x92, 0x98, 0xbb, 0x05, - 0xa8, 0x22, 0x14, 0xa2, 0x1f, 0x01, 0x04, 0xe5, 0x6e, 0xf4, 0x75, 0x1c, 0xdb, 0x33, 0x8b, 0xbe, - 0x8e, 0xe3, 0x2b, 0xe6, 0x18, 0x0f, 0x0e, 0xc0, 0x79, 0xfe, 0x48, 0xe1, 0x7f, 0xae, 0x01, 0x1a, - 0x2f, 0x8f, 0xd1, 0x1b, 0xf1, 0x10, 0xb1, 0xed, 0x38, 0xfd, 0xcd, 0xab, 0x31, 0x27, 0x46, 0xcf, - 0x40, 0xaf, 0x26, 0x5b, 0x32, 0x78, 0x41, 0x35, 0xfb, 0x42, 0x83, 0xb9, 0x50, 0x81, 0x8d, 0x1e, - 0x24, 0x9c, 0x73, 0xa4, 0xa5, 0xa7, 0x3f, 0xbc, 0x94, 0x2f, 0x31, 0x63, 0x51, 0x6e, 0x85, 0xcc, - 0xd6, 0x7e, 0xaa, 0x41, 0x39, 0x5c, 0x95, 0xa3, 0x04, 0x80, 0xb1, 0xbe, 0xa0, 0xbe, 0x76, 0x39, - 0xe3, 0x15, 0x4e, 0x2b, 0x48, 0xe0, 0x3e, 0x85, 0xbc, 0x28, 0xe6, 0xe3, 0xdc, 0x22, 0xdc, 0x56, - 0x8c, 0x73, 0x8b, 0x48, 0x27, 0x20, 0xc9, 0x2d, 0x68, 0x5d, 0xac, 0x78, 0xa2, 0x28, 0xf9, 0x93, - 0x20, 0x27, 0x7b, 0x62, 0xa4, 0x5f, 0x30, 0x11, 0x32, 0xf0, 0x44, 0x59, 0xf0, 0xa3, 0x04, 0x89, - 0x97, 0x78, 0x62, 0xb4, 0x5f, 0x90, 0xe4, 0x89, 0x0c, 0x55, 0xf1, 0xc4, 0xa0, 0x3e, 0x8f, 0xf3, - 0xc4, 0xb1, 0xa6, 0x69, 0x9c, 0x27, 0x8e, 0x97, 0xf8, 0x49, 0x67, 0xcb, 0xc0, 0x43, 0x9e, 0xb8, - 0x10, 0x53, 0xcf, 0xa3, 0x37, 0x13, 0x6c, 0x1a, 0xdb, 0x90, 0xd5, 0xdf, 0xba, 0x22, 0xf7, 0x64, - 0x0f, 0xe0, 0xa7, 0x21, 0x3d, 0xe0, 0xd7, 0x1a, 0x2c, 0xc6, 0x35, 0x04, 0x50, 0x02, 0x58, 0x42, - 0x37, 0x57, 0x5f, 0xbf, 0x2a, 0xfb, 0x15, 0xec, 0xe6, 0xfb, 0xc4, 0x56, 0xe5, 0xf7, 0xaf, 0x56, - 0xb4, 0xaf, 0x5e, 0xad, 0x68, 0x7f, 0x7e, 0xb5, 0xa2, 0xfd, 0xe2, 0x2f, 0x2b, 0x53, 0x67, 0x33, - 0xec, 0xb7, 0xda, 0xef, 0xfe, 0x27, 0x00, 0x00, 0xff, 0xff, 0x45, 0x26, 0x54, 0x69, 0x32, 0x2e, - 0x00, 0x00, + // 3206 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xb4, 0x5a, 0xcd, 0x73, 0x1b, 0xc7, + 0xb1, 0xe7, 0x02, 0x20, 0x3e, 0x1a, 0x20, 0x08, 0x0d, 0x29, 0x19, 0x5c, 0x49, 0x14, 0x35, 0xfa, + 0xa2, 0x64, 0x9b, 0xb0, 0x69, 0xbf, 0x77, 0xd0, 0x7b, 0xe5, 0x2a, 0x8a, 0xc4, 0x13, 0xf9, 0x48, + 0x93, 0xf2, 0x92, 0xa2, 0x9d, 0x2a, 0x57, 0x58, 0x4b, 0x60, 0x04, 0xa0, 0x08, 0xec, 0xc2, 0xbb, + 0x0b, 0x48, 0x74, 0x92, 0xaa, 0x94, 0x2b, 0x3e, 0x24, 0xc7, 0xf8, 0x90, 0xaf, 0x63, 0xae, 0xb9, + 0xe6, 0x96, 0x3f, 0x20, 0x95, 0x4b, 0x5c, 0x95, 0x7f, 0x20, 0xe5, 0xe4, 0x90, 0x43, 0xee, 0xa9, + 0x1c, 0x52, 0x49, 0xcd, 0xd7, 0xee, 0xec, 0x62, 0x17, 0xa4, 0xb3, 0xf1, 0x85, 0xdc, 0xe9, 0xe9, + 0xe9, 0x5f, 0x77, 0xcf, 0x74, 0x6f, 0x4f, 0x2f, 0xa0, 0xe4, 0x0c, 0x5b, 0x6b, 0x43, 0xc7, 0xf6, + 0x6c, 0x54, 0x21, 0x5e, 0xab, 0xed, 0x12, 0x67, 0x4c, 0x9c, 0xe1, 0xa9, 0xbe, 0xd8, 0xb1, 0x3b, + 0x36, 0x9b, 0x68, 0xd0, 0x27, 0xce, 0xa3, 0x2f, 0x51, 0x9e, 0xc6, 0x60, 0xdc, 0x6a, 0xb1, 0x3f, + 0xc3, 0xd3, 0xc6, 0xd9, 0x58, 0x4c, 0x5d, 0x67, 0x53, 0xe6, 0xc8, 0xeb, 0xb2, 0x3f, 0xc3, 0x53, + 0xf6, 0x4f, 0x4c, 0xde, 0xe8, 0xd8, 0x76, 0xa7, 0x4f, 0x1a, 0xe6, 0xb0, 0xd7, 0x30, 0x2d, 0xcb, + 0xf6, 0x4c, 0xaf, 0x67, 0x5b, 0x2e, 0x9f, 0xc5, 0x9f, 0x6b, 0x50, 0x35, 0x88, 0x3b, 0xb4, 0x2d, + 0x97, 0x6c, 0x13, 0xb3, 0x4d, 0x1c, 0x74, 0x13, 0xa0, 0xd5, 0x1f, 0xb9, 0x1e, 0x71, 0x4e, 0x7a, + 0xed, 0xba, 0xb6, 0xa2, 0xad, 0xe6, 0x8c, 0x92, 0xa0, 0xec, 0xb4, 0xd1, 0x75, 0x28, 0x0d, 0xc8, + 0xe0, 0x94, 0xcf, 0x66, 0xd8, 0x6c, 0x91, 0x13, 0x76, 0xda, 0x48, 0x87, 0xa2, 0x43, 0xc6, 0x3d, + 0xb7, 0x67, 0x5b, 0xf5, 0xec, 0x8a, 0xb6, 0x9a, 0x35, 0xfc, 0x31, 0x5d, 0xe8, 0x98, 0x2f, 0xbc, + 0x13, 0x8f, 0x38, 0x83, 0x7a, 0x8e, 0x2f, 0xa4, 0x84, 0x23, 0xe2, 0x0c, 0xf0, 0x97, 0x59, 0xa8, + 0x18, 0xa6, 0xd5, 0x21, 0x06, 0xf9, 0x64, 0x44, 0x5c, 0x0f, 0xd5, 0x20, 0x7b, 0x46, 0xce, 0x19, + 0x7c, 0xc5, 0xa0, 0x8f, 0x7c, 0xbd, 0xd5, 0x21, 0x27, 0xc4, 0xe2, 0xc0, 0x15, 0xba, 0xde, 0xea, + 0x90, 0xa6, 0xd5, 0x46, 0x8b, 0x30, 0xdb, 0xef, 0x0d, 0x7a, 0x9e, 0x40, 0xe5, 0x83, 0x90, 0x3a, + 0xb9, 0x88, 0x3a, 0x9b, 0x00, 0xae, 0xed, 0x78, 0x27, 0xb6, 0xd3, 0x26, 0x4e, 0x7d, 0x76, 0x45, + 0x5b, 0xad, 0xae, 0xdf, 0x5d, 0x53, 0x37, 0x62, 0x4d, 0x55, 0x68, 0xed, 0xd0, 0x76, 0xbc, 0x03, + 0xca, 0x6b, 0x94, 0x5c, 0xf9, 0x88, 0xfe, 0x0f, 0xca, 0x4c, 0x88, 0x67, 0x3a, 0x1d, 0xe2, 0xd5, + 0xf3, 0x4c, 0xca, 0xbd, 0x0b, 0xa4, 0x1c, 0x31, 0x66, 0x83, 0xc1, 0xf3, 0x67, 0x84, 0xa1, 0xe2, + 0x12, 0xa7, 0x67, 0xf6, 0x7b, 0x9f, 0x9a, 0xa7, 0x7d, 0x52, 0x2f, 0xac, 0x68, 0xab, 0x45, 0x23, + 0x44, 0xa3, 0xf6, 0x9f, 0x91, 0x73, 0xf7, 0xc4, 0xb6, 0xfa, 0xe7, 0xf5, 0x22, 0x63, 0x28, 0x52, + 0xc2, 0x81, 0xd5, 0x3f, 0x67, 0x9b, 0x66, 0x8f, 0x2c, 0x8f, 0xcf, 0x96, 0xd8, 0x6c, 0x89, 0x51, + 0xe8, 0x34, 0x5e, 0x83, 0x92, 0xaf, 0x3f, 0x2a, 0x42, 0x6e, 0xff, 0x60, 0xbf, 0x59, 0x9b, 0x41, + 0x00, 0xf9, 0x8d, 0xc3, 0xcd, 0xe6, 0xfe, 0x56, 0x4d, 0x43, 0x65, 0x28, 0x6c, 0x35, 0xf9, 0x20, + 0x83, 0x9f, 0x00, 0x04, 0x9a, 0xa2, 0x02, 0x64, 0x77, 0x9b, 0xdf, 0xaa, 0xcd, 0x50, 0x9e, 0xe3, + 0xa6, 0x71, 0xb8, 0x73, 0xb0, 0x5f, 0xd3, 0xe8, 0xe2, 0x4d, 0xa3, 0xb9, 0x71, 0xd4, 0xac, 0x65, + 0x28, 0xc7, 0xfb, 0x07, 0x5b, 0xb5, 0x2c, 0x2a, 0xc1, 0xec, 0xf1, 0xc6, 0xde, 0xf3, 0x66, 0x2d, + 0x87, 0xbf, 0xd0, 0x60, 0x4e, 0xd8, 0xce, 0xcf, 0x17, 0x7a, 0x17, 0xf2, 0x5d, 0x76, 0xc6, 0xd8, + 0xb6, 0x96, 0xd7, 0x6f, 0x44, 0x1c, 0x15, 0x3a, 0x87, 0x86, 0xe0, 0x45, 0x18, 0xb2, 0x67, 0x63, + 0xb7, 0x9e, 0x59, 0xc9, 0xae, 0x96, 0xd7, 0x6b, 0x6b, 0xfc, 0xf0, 0xaf, 0xed, 0x92, 0xf3, 0x63, + 0xb3, 0x3f, 0x22, 0x06, 0x9d, 0x44, 0x08, 0x72, 0x03, 0xdb, 0x21, 0x6c, 0xf7, 0x8b, 0x06, 0x7b, + 0xa6, 0x47, 0x82, 0x39, 0x40, 0xec, 0x3c, 0x1f, 0xe0, 0x16, 0xc0, 0xb3, 0x91, 0x97, 0x7c, 0xca, + 0x16, 0x61, 0x76, 0x4c, 0xe5, 0x8a, 0x13, 0xc6, 0x07, 0xec, 0x78, 0x11, 0xd3, 0x25, 0xfe, 0xf1, + 0xa2, 0x03, 0xf4, 0x1a, 0x14, 0x86, 0x0e, 0x19, 0x9f, 0x9c, 0x8d, 0x19, 0x46, 0xd1, 0xc8, 0xd3, + 0xe1, 0xee, 0x18, 0x5b, 0x50, 0x66, 0x20, 0xa9, 0xec, 0x7e, 0x18, 0x48, 0xcf, 0xb0, 0x65, 0x93, + 0xb6, 0x4b, 0xbc, 0x8f, 0x01, 0x6d, 0x91, 0x3e, 0xf1, 0x48, 0x9a, 0x10, 0x52, 0xac, 0xc9, 0x86, + 0xac, 0xf9, 0xb1, 0x06, 0x0b, 0x21, 0xf1, 0xa9, 0xcc, 0xaa, 0x43, 0xa1, 0xcd, 0x84, 0x71, 0x0d, + 0xb2, 0x86, 0x1c, 0xa2, 0xd7, 0xa1, 0x28, 0x14, 0x70, 0xeb, 0xd9, 0x84, 0xdd, 0x2e, 0x70, 0x9d, + 0x5c, 0xfc, 0x57, 0x0d, 0x4a, 0xc2, 0xd0, 0x83, 0x21, 0xda, 0x80, 0x39, 0x87, 0x0f, 0x4e, 0x98, + 0x3d, 0x42, 0x23, 0x3d, 0x39, 0x12, 0xb7, 0x67, 0x8c, 0x8a, 0x58, 0xc2, 0xc8, 0xe8, 0x7f, 0xa0, + 0x2c, 0x45, 0x0c, 0x47, 0x9e, 0x70, 0x79, 0x3d, 0x2c, 0x20, 0x38, 0x39, 0xdb, 0x33, 0x06, 0x08, + 0xf6, 0x67, 0x23, 0x0f, 0x1d, 0xc1, 0xa2, 0x5c, 0xcc, 0xad, 0x11, 0x6a, 0x64, 0x99, 0x94, 0x95, + 0xb0, 0x94, 0xc9, 0xad, 0xda, 0x9e, 0x31, 0x90, 0x58, 0xaf, 0x4c, 0x3e, 0x29, 0x41, 0x41, 0x50, + 0xf1, 0xdf, 0x34, 0x00, 0xe9, 0xd0, 0x83, 0x21, 0xda, 0x82, 0xaa, 0x23, 0x46, 0x21, 0x83, 0xaf, + 0xc7, 0x1a, 0x2c, 0xf6, 0x61, 0xc6, 0x98, 0x93, 0x8b, 0xb8, 0xc9, 0xef, 0x41, 0xc5, 0x97, 0x12, + 0xd8, 0xbc, 0x14, 0x63, 0xb3, 0x2f, 0xa1, 0x2c, 0x17, 0x50, 0xab, 0x3f, 0x84, 0xab, 0xfe, 0xfa, + 0x18, 0xb3, 0x6f, 0x4f, 0x31, 0xdb, 0x17, 0xb8, 0x20, 0x25, 0xa8, 0x86, 0x03, 0xcd, 0xdb, 0x9c, + 0x8c, 0x7f, 0x9e, 0x85, 0xc2, 0xa6, 0x3d, 0x18, 0x9a, 0x0e, 0xdd, 0xa3, 0xbc, 0x43, 0xdc, 0x51, + 0xdf, 0x63, 0xe6, 0x56, 0xd7, 0xef, 0x84, 0x11, 0x04, 0x9b, 0xfc, 0x6f, 0x30, 0x56, 0x43, 0x2c, + 0xa1, 0x8b, 0x45, 0x9a, 0xce, 0x5c, 0x62, 0xb1, 0x48, 0xd2, 0x62, 0x89, 0x8c, 0xa5, 0x6c, 0x10, + 0x4b, 0x3a, 0x14, 0xc6, 0xc4, 0x09, 0x5e, 0x2d, 0xdb, 0x33, 0x86, 0x24, 0xa0, 0x87, 0x30, 0xdf, + 0x72, 0x88, 0x49, 0xfd, 0x21, 0x5f, 0x3f, 0xb3, 0x82, 0xa7, 0xca, 0x27, 0x0c, 0xf9, 0x1a, 0xba, + 0x03, 0x95, 0x81, 0xdd, 0x0e, 0xf8, 0xf2, 0x82, 0xaf, 0x3c, 0xb0, 0xdb, 0x3e, 0xd3, 0x35, 0x99, + 0x94, 0xe8, 0x7b, 0xa1, 0xb2, 0x3d, 0x23, 0xd2, 0x12, 0x7e, 0x1b, 0xe6, 0x42, 0xb6, 0xd2, 0xf4, + 0xdb, 0xfc, 0xe0, 0xf9, 0xc6, 0x1e, 0xcf, 0xd5, 0x4f, 0x59, 0x7a, 0x36, 0x6a, 0x1a, 0x4d, 0xf9, + 0x7b, 0xcd, 0xc3, 0xc3, 0x5a, 0x06, 0xff, 0xaf, 0xbf, 0x44, 0x24, 0x77, 0x25, 0xa7, 0xcf, 0x28, + 0x39, 0x5d, 0x93, 0x39, 0x3d, 0x13, 0xe4, 0xf4, 0xec, 0x93, 0x2a, 0x54, 0xb8, 0x43, 0x4e, 0x46, + 0x56, 0xcf, 0xb6, 0xf0, 0x2f, 0x35, 0x80, 0xa3, 0x57, 0x96, 0xcc, 0x38, 0x0d, 0x28, 0xb4, 0xb8, + 0xf0, 0xba, 0xc6, 0x02, 0xf8, 0x6a, 0xac, 0x8f, 0x0d, 0xc9, 0x85, 0xde, 0x86, 0x82, 0x3b, 0x6a, + 0xb5, 0x88, 0x2b, 0xf3, 0xfb, 0x6b, 0xd1, 0x1c, 0x22, 0x22, 0xdc, 0x90, 0x7c, 0x74, 0xc9, 0x0b, + 0xb3, 0xd7, 0x1f, 0xb1, 0x6c, 0x3f, 0x7d, 0x89, 0xe0, 0xc3, 0x3f, 0xd3, 0xa0, 0xcc, 0xb4, 0x4c, + 0x95, 0xb8, 0x6e, 0x40, 0x89, 0xe9, 0x40, 0xda, 0x22, 0x75, 0x15, 0x8d, 0x80, 0x80, 0xfe, 0x1b, + 0x4a, 0xf2, 0xc8, 0xca, 0xec, 0x55, 0x8f, 0x17, 0x7b, 0x30, 0x34, 0x02, 0x56, 0xbc, 0x0b, 0x57, + 0x98, 0x57, 0x5a, 0xb4, 0x2a, 0x93, 0x7e, 0x54, 0xeb, 0x16, 0x2d, 0x52, 0xb7, 0xe8, 0x50, 0x1c, + 0x76, 0xcf, 0xdd, 0x5e, 0xcb, 0xec, 0x0b, 0x2d, 0xfc, 0x31, 0xfe, 0x7f, 0x40, 0xaa, 0xb0, 0x34, + 0xe6, 0xe2, 0x39, 0x28, 0x6f, 0x9b, 0x6e, 0x57, 0xa8, 0x84, 0x3f, 0x82, 0x0a, 0x1f, 0xa6, 0xf2, + 0x21, 0x82, 0x5c, 0xd7, 0x74, 0xbb, 0x4c, 0xf1, 0x39, 0x83, 0x3d, 0xe3, 0x2b, 0x30, 0x7f, 0x68, + 0x99, 0x43, 0xb7, 0x6b, 0xcb, 0xe4, 0x4a, 0xab, 0xd2, 0x5a, 0x40, 0x4b, 0x85, 0xf8, 0x00, 0xe6, + 0x1d, 0x32, 0x30, 0x7b, 0x56, 0xcf, 0xea, 0x9c, 0x9c, 0x9e, 0x7b, 0xc4, 0x15, 0x45, 0x6b, 0xd5, + 0x27, 0x3f, 0xa1, 0x54, 0xaa, 0xda, 0x69, 0xdf, 0x3e, 0x15, 0x21, 0xce, 0x9e, 0xf1, 0xaf, 0x35, + 0xa8, 0x7c, 0x68, 0x7a, 0x2d, 0xe9, 0x05, 0xb4, 0x03, 0x55, 0x3f, 0xb0, 0x19, 0x45, 0xe8, 0x12, + 0xc9, 0xf0, 0x6c, 0xcd, 0xa6, 0x08, 0x74, 0x99, 0xe1, 0xe7, 0x5a, 0x2a, 0x81, 0x89, 0x32, 0xad, + 0x16, 0xe9, 0xfb, 0xa2, 0x32, 0xc9, 0xa2, 0x18, 0xa3, 0x2a, 0x4a, 0x25, 0x3c, 0x99, 0x0f, 0xde, + 0x7e, 0x3c, 0x2c, 0x7f, 0xa5, 0x01, 0x9a, 0xd4, 0xe1, 0xeb, 0x16, 0x04, 0xf7, 0xa0, 0xea, 0x7a, + 0xa6, 0xe3, 0x9d, 0x44, 0x4a, 0xfa, 0x39, 0x46, 0xf5, 0x93, 0xd3, 0x03, 0x98, 0x1f, 0x3a, 0x76, + 0xc7, 0x21, 0xae, 0x7b, 0x62, 0xd9, 0x5e, 0xef, 0xc5, 0xb9, 0xa8, 0x86, 0xaa, 0x92, 0xbc, 0xcf, + 0xa8, 0x6a, 0x81, 0x91, 0x0f, 0x15, 0x18, 0x0d, 0xa9, 0xad, 0x6a, 0x15, 0x5a, 0x82, 0xe2, 0x4b, + 0x4a, 0x95, 0xb7, 0x90, 0xac, 0x51, 0x60, 0xe3, 0x9d, 0x36, 0xfe, 0x8b, 0x06, 0x73, 0x62, 0x5f, + 0x52, 0x1d, 0x0e, 0x15, 0x22, 0x13, 0x82, 0xa0, 0x65, 0x0a, 0xdf, 0xaf, 0xb6, 0xa8, 0x86, 0xe4, + 0x90, 0x06, 0x20, 0x77, 0x3f, 0x69, 0x0b, 0x43, 0xfd, 0x31, 0x7a, 0x08, 0xb5, 0x16, 0x0f, 0xc0, + 0x48, 0xe6, 0x37, 0xe6, 0x05, 0xdd, 0x77, 0xdb, 0x3d, 0xc8, 0x93, 0x31, 0xb1, 0x3c, 0xb7, 0x5e, + 0x66, 0xd9, 0x62, 0x4e, 0xd6, 0x3a, 0x4d, 0x4a, 0x35, 0xc4, 0x24, 0xfe, 0x2f, 0xb8, 0xb2, 0x47, + 0x8b, 0xcd, 0xa7, 0x8e, 0x69, 0xa9, 0x65, 0xeb, 0xd1, 0xd1, 0x9e, 0xf0, 0x4a, 0xd6, 0x3b, 0xda, + 0x43, 0x55, 0xc8, 0xec, 0x6c, 0x09, 0x1b, 0x32, 0xbd, 0x2d, 0xfc, 0x99, 0x06, 0x48, 0x5d, 0x97, + 0xca, 0x4d, 0x11, 0xe1, 0x12, 0x3e, 0x1b, 0xc0, 0x2f, 0xc2, 0x2c, 0x71, 0x1c, 0xdb, 0x61, 0x0e, + 0x29, 0x19, 0x7c, 0x80, 0xef, 0x0a, 0x1d, 0x0c, 0x32, 0xb6, 0xcf, 0xfc, 0x53, 0xc8, 0xa5, 0x69, + 0xbe, 0xaa, 0xbb, 0xb0, 0x10, 0xe2, 0x4a, 0x95, 0xb5, 0x1e, 0xc0, 0x55, 0x26, 0x6c, 0x97, 0x90, + 0xe1, 0x46, 0xbf, 0x37, 0x4e, 0x44, 0x1d, 0xc2, 0xb5, 0x28, 0xe3, 0x37, 0xeb, 0x23, 0xdc, 0x85, + 0xfc, 0xfb, 0xec, 0x9e, 0xac, 0xe8, 0x92, 0x63, 0xbc, 0x08, 0x72, 0x96, 0x39, 0xe0, 0x57, 0x8e, + 0x92, 0xc1, 0x9e, 0x59, 0x9a, 0x27, 0xc4, 0x79, 0x6e, 0xec, 0xf1, 0xd7, 0x49, 0xc9, 0xf0, 0xc7, + 0x68, 0x99, 0xde, 0xd0, 0x7b, 0xc4, 0xf2, 0xd8, 0x6c, 0x8e, 0xcd, 0x2a, 0x14, 0xbc, 0x06, 0x35, + 0x8e, 0xb4, 0xd1, 0x6e, 0x2b, 0xaf, 0x14, 0x5f, 0x9e, 0x16, 0x96, 0x87, 0x5f, 0xc2, 0x15, 0x85, + 0x3f, 0x95, 0x1b, 0xde, 0x80, 0x3c, 0x6f, 0x06, 0x88, 0x6c, 0xb6, 0x18, 0x5e, 0xc5, 0x61, 0x0c, + 0xc1, 0x83, 0xef, 0xc1, 0x82, 0xa0, 0x90, 0x81, 0x1d, 0xb7, 0x57, 0xcc, 0x3f, 0x78, 0x0f, 0x16, + 0xc3, 0x6c, 0xa9, 0x8e, 0xc8, 0x86, 0x04, 0x7d, 0x3e, 0x6c, 0x2b, 0xc9, 0x31, 0xba, 0x29, 0xaa, + 0xc3, 0x32, 0x11, 0x87, 0xf9, 0x0a, 0x49, 0x11, 0xa9, 0x14, 0x5a, 0x90, 0xee, 0xdf, 0xeb, 0xb9, + 0xfe, 0x2b, 0xf0, 0x53, 0x40, 0x2a, 0x31, 0xd5, 0xa6, 0xac, 0x41, 0x81, 0x3b, 0x5c, 0x56, 0x59, + 0xf1, 0xbb, 0x22, 0x99, 0xa8, 0x42, 0x5b, 0xe4, 0x85, 0x63, 0x76, 0x06, 0xc4, 0xcf, 0x39, 0xb4, + 0xb6, 0x50, 0x89, 0xa9, 0x2c, 0xfe, 0xbd, 0x06, 0x95, 0x8d, 0xbe, 0xe9, 0x0c, 0xa4, 0xf3, 0xdf, + 0x83, 0x3c, 0x2f, 0x5a, 0x44, 0x61, 0x7f, 0x3f, 0x2c, 0x46, 0xe5, 0xe5, 0x83, 0x0d, 0x5e, 0xe2, + 0x88, 0x55, 0x74, 0xb3, 0x44, 0x0f, 0x6a, 0x2b, 0xd2, 0x93, 0xda, 0x42, 0x6f, 0xc2, 0xac, 0x49, + 0x97, 0xb0, 0x58, 0xac, 0x46, 0xcb, 0x45, 0x26, 0xed, 0xe8, 0x7c, 0x48, 0x0c, 0xce, 0x85, 0xdf, + 0x85, 0xb2, 0x82, 0x40, 0xab, 0xe0, 0xa7, 0xcd, 0xa3, 0xda, 0x0c, 0xaa, 0x40, 0x71, 0x63, 0xf3, + 0x68, 0xe7, 0x98, 0x17, 0xc7, 0x55, 0x80, 0xad, 0xa6, 0x3f, 0xce, 0xe0, 0x8f, 0xc4, 0x2a, 0x11, + 0xe1, 0xaa, 0x3e, 0x5a, 0x92, 0x3e, 0x99, 0x4b, 0xe9, 0xf3, 0x0a, 0xe6, 0x84, 0xf9, 0xa9, 0xce, + 0xc0, 0xdb, 0x90, 0x67, 0xf2, 0xe4, 0x11, 0x58, 0x8a, 0x81, 0x95, 0xd1, 0xc9, 0x19, 0xf1, 0x3c, + 0xcc, 0x1d, 0x7a, 0xa6, 0x37, 0x72, 0xe5, 0x11, 0xf8, 0x9d, 0x06, 0x55, 0x49, 0x49, 0xdb, 0x03, + 0x90, 0x77, 0x27, 0x9e, 0xf3, 0xfc, 0x9b, 0xd3, 0x35, 0xc8, 0xb7, 0x4f, 0x0f, 0x7b, 0x9f, 0xca, + 0x4e, 0x8b, 0x18, 0x51, 0x7a, 0x9f, 0xe3, 0xf0, 0xce, 0xa1, 0x18, 0xd1, 0xa2, 0xdc, 0x31, 0x5f, + 0x78, 0x3b, 0x56, 0x9b, 0xbc, 0x62, 0x6f, 0xda, 0x9c, 0x11, 0x10, 0x58, 0x1d, 0x2d, 0x3a, 0x8c, + 0xac, 0xe4, 0x50, 0x3b, 0x8e, 0x0b, 0x70, 0x65, 0x63, 0xe4, 0x75, 0x9b, 0x96, 0x79, 0xda, 0x97, + 0x49, 0x00, 0x2f, 0x02, 0xa2, 0xc4, 0xad, 0x9e, 0xab, 0x52, 0x9b, 0xb0, 0x40, 0xa9, 0xc4, 0xf2, + 0x7a, 0x2d, 0x25, 0x63, 0xc8, 0xb4, 0xad, 0x45, 0xd2, 0xb6, 0xe9, 0xba, 0x2f, 0x6d, 0xa7, 0x2d, + 0x4c, 0xf3, 0xc7, 0x78, 0x8b, 0x0b, 0x7f, 0xee, 0x86, 0x12, 0xf3, 0xd7, 0x95, 0xb2, 0x1a, 0x48, + 0x79, 0x4a, 0xbc, 0x29, 0x52, 0xf0, 0xeb, 0x70, 0x55, 0x72, 0x8a, 0xcb, 0xf5, 0x14, 0xe6, 0x03, + 0xb8, 0x29, 0x99, 0x37, 0xbb, 0xb4, 0x02, 0x7c, 0x26, 0x00, 0xff, 0x5d, 0x3d, 0x9f, 0x40, 0xdd, + 0xd7, 0x93, 0xd5, 0x20, 0x76, 0x5f, 0x55, 0x60, 0xe4, 0x8a, 0x33, 0x53, 0x32, 0xd8, 0x33, 0xa5, + 0x39, 0x76, 0xdf, 0x7f, 0x09, 0xd2, 0x67, 0xbc, 0x09, 0x4b, 0x52, 0x86, 0xa8, 0x0e, 0xc2, 0x42, + 0x26, 0x14, 0x8a, 0x13, 0x22, 0x1c, 0x46, 0x97, 0x4e, 0x77, 0xbb, 0xca, 0x19, 0x76, 0x2d, 0x93, + 0xa9, 0x29, 0x32, 0xaf, 0xf2, 0x13, 0x41, 0x15, 0x53, 0x93, 0xb6, 0x20, 0x53, 0x01, 0x2a, 0x59, + 0x6c, 0x04, 0x25, 0x4f, 0x6c, 0xc4, 0x84, 0xe8, 0x8f, 0x61, 0xd9, 0x57, 0x82, 0xfa, 0xed, 0x19, + 0x71, 0x06, 0x3d, 0xd7, 0x55, 0x6e, 0x87, 0x71, 0x86, 0xdf, 0x87, 0xdc, 0x90, 0x88, 0x9c, 0x52, + 0x5e, 0x47, 0x6b, 0xfc, 0x3b, 0xc0, 0x9a, 0xb2, 0x98, 0xcd, 0xe3, 0x36, 0xdc, 0x92, 0xd2, 0xb9, + 0x47, 0x63, 0xc5, 0x47, 0x95, 0x92, 0x37, 0x07, 0xee, 0xd6, 0xc9, 0x9b, 0x43, 0x96, 0xef, 0xbd, + 0xbc, 0x39, 0xd0, 0x77, 0x85, 0x1a, 0x5b, 0xa9, 0xde, 0x15, 0xbb, 0xdc, 0xa7, 0x7e, 0x48, 0xa6, + 0x12, 0x76, 0x0a, 0x8b, 0xe1, 0x48, 0x4e, 0x95, 0xc6, 0x16, 0x61, 0xd6, 0xb3, 0xcf, 0x88, 0x4c, + 0x62, 0x7c, 0x20, 0x15, 0xf6, 0xc3, 0x3c, 0x95, 0xc2, 0x66, 0x20, 0x8c, 0x1d, 0xc9, 0xb4, 0xfa, + 0xd2, 0xdd, 0x94, 0xf5, 0x0c, 0x1f, 0xe0, 0x7d, 0xb8, 0x16, 0x4d, 0x13, 0xa9, 0x54, 0x3e, 0xe6, + 0x07, 0x38, 0x2e, 0x93, 0xa4, 0x92, 0xfb, 0x41, 0x90, 0x0c, 0x94, 0x84, 0x92, 0x4a, 0xa4, 0x01, + 0x7a, 0x5c, 0x7e, 0xf9, 0x4f, 0x9c, 0x57, 0x3f, 0xdd, 0xa4, 0x12, 0xe6, 0x06, 0xc2, 0xd2, 0x6f, + 0x7f, 0x90, 0x23, 0xb2, 0x53, 0x73, 0x84, 0x08, 0x92, 0x20, 0x8b, 0x7d, 0x03, 0x87, 0x4e, 0x60, + 0x04, 0x09, 0x34, 0x2d, 0x06, 0x7d, 0x87, 0xf8, 0x18, 0x6c, 0x20, 0x0f, 0xb6, 0x9a, 0x76, 0x53, + 0x6d, 0xc6, 0x87, 0x41, 0xee, 0x9c, 0xc8, 0xcc, 0xa9, 0x04, 0x7f, 0x04, 0x2b, 0xc9, 0x49, 0x39, + 0x8d, 0xe4, 0x47, 0x18, 0x4a, 0x7e, 0x41, 0xa9, 0x7c, 0xf7, 0x2b, 0x43, 0x61, 0xff, 0xe0, 0xf0, + 0xd9, 0xc6, 0x66, 0xb3, 0xa6, 0xad, 0xff, 0x23, 0x0b, 0x99, 0xdd, 0x63, 0xf4, 0x6d, 0x98, 0xe5, + 0x5f, 0x05, 0xa6, 0x7c, 0x34, 0xd1, 0xa7, 0x7d, 0x5f, 0xc0, 0x37, 0x3e, 0xfb, 0xc3, 0x9f, 0xbf, + 0xc8, 0x5c, 0xc3, 0x57, 0x1a, 0xe3, 0x77, 0xcc, 0xfe, 0xb0, 0x6b, 0x36, 0xce, 0xc6, 0x0d, 0xf6, + 0x4e, 0x78, 0xac, 0x3d, 0x42, 0xc7, 0x90, 0x7d, 0x36, 0xf2, 0x50, 0xe2, 0x17, 0x15, 0x3d, 0xf9, + 0xbb, 0x03, 0xd6, 0x99, 0xe4, 0x45, 0x3c, 0xaf, 0x4a, 0x1e, 0x8e, 0x3c, 0x2a, 0x77, 0x0c, 0x65, + 0xe5, 0xd3, 0x01, 0xba, 0xf0, 0x5b, 0x8b, 0x7e, 0xf1, 0x67, 0x09, 0x8c, 0x19, 0xde, 0x0d, 0xfc, + 0x9a, 0x8a, 0xc7, 0xbf, 0x70, 0xa8, 0xf6, 0x1c, 0xbd, 0xb2, 0xa2, 0xf6, 0x04, 0xcd, 0xf0, 0xa8, + 0x3d, 0x4a, 0x03, 0x3a, 0xde, 0x1e, 0xef, 0x95, 0x45, 0xe5, 0xda, 0xe2, 0x73, 0x47, 0xcb, 0x43, + 0xb7, 0x62, 0xba, 0xe7, 0x6a, 0x9f, 0x58, 0x5f, 0x49, 0x66, 0x10, 0x48, 0xb7, 0x19, 0xd2, 0x75, + 0x7c, 0x4d, 0x45, 0x6a, 0xf9, 0x7c, 0x8f, 0xb5, 0x47, 0xeb, 0x5d, 0x98, 0x65, 0xbd, 0x34, 0x74, + 0x22, 0x1f, 0xf4, 0x98, 0x16, 0x64, 0xc2, 0x09, 0x08, 0x75, 0xe1, 0xf0, 0x12, 0x43, 0x5b, 0xc0, + 0x55, 0x1f, 0x8d, 0xb5, 0xd3, 0x1e, 0x6b, 0x8f, 0x56, 0xb5, 0xb7, 0xb4, 0xf5, 0xbf, 0x67, 0x60, + 0x96, 0x35, 0x5d, 0xd0, 0x10, 0x20, 0xe8, 0x4e, 0x45, 0xed, 0x9c, 0xe8, 0x77, 0x45, 0xed, 0x9c, + 0x6c, 0x6c, 0xe1, 0x5b, 0x0c, 0x79, 0x09, 0x2f, 0xfa, 0xc8, 0xec, 0x13, 0x6d, 0xa3, 0x43, 0xb9, + 0xa8, 0x5b, 0x5f, 0x42, 0x59, 0xe9, 0x32, 0xa1, 0x38, 0x89, 0xa1, 0x36, 0x55, 0xf4, 0x98, 0xc4, + 0xb4, 0xa8, 0xf0, 0x1d, 0x06, 0x7a, 0x13, 0xd7, 0x55, 0xe7, 0x72, 0x5c, 0x87, 0x71, 0x52, 0xe0, + 0x1f, 0x68, 0x50, 0x0d, 0x77, 0x9a, 0xd0, 0x9d, 0x18, 0xd1, 0xd1, 0x86, 0x95, 0x7e, 0x77, 0x3a, + 0x53, 0xa2, 0x0a, 0x1c, 0xff, 0x8c, 0x90, 0xa1, 0x49, 0x39, 0xa5, 0xef, 0xff, 0x99, 0x85, 0xc2, + 0x26, 0xff, 0x11, 0x07, 0xf2, 0xa0, 0xe4, 0xf7, 0x7b, 0xd0, 0x72, 0x5c, 0x2f, 0x20, 0x28, 0x94, + 0xf5, 0x5b, 0x89, 0xf3, 0x42, 0x85, 0xfb, 0x4c, 0x85, 0x15, 0x7c, 0xdd, 0x57, 0x41, 0xfc, 0x58, + 0xa4, 0xc1, 0xaf, 0xbc, 0x0d, 0xb3, 0xdd, 0xa6, 0x8e, 0xf8, 0xbe, 0x06, 0x15, 0xb5, 0x8d, 0x83, + 0x6e, 0xc7, 0x76, 0x21, 0xd4, 0x4e, 0x90, 0x8e, 0xa7, 0xb1, 0x08, 0xfc, 0x87, 0x0c, 0xff, 0x0e, + 0x5e, 0x4e, 0xc2, 0x77, 0x18, 0x7f, 0x58, 0x05, 0xde, 0xb8, 0x89, 0x57, 0x21, 0xd4, 0x17, 0x8a, + 0x57, 0x21, 0xdc, 0xf7, 0xb9, 0x58, 0x85, 0x11, 0xe3, 0xa7, 0x2a, 0xbc, 0x02, 0x08, 0xfa, 0x3a, + 0x28, 0xd6, 0xb9, 0xca, 0xd5, 0x21, 0x7a, 0xf2, 0x27, 0x5b, 0x42, 0xf8, 0x01, 0xc3, 0xbe, 0x8d, + 0x6f, 0x24, 0x61, 0xf7, 0x7b, 0x2e, 0x8d, 0x80, 0xf5, 0xdf, 0xe4, 0xa0, 0xfc, 0xbe, 0xd9, 0xb3, + 0x3c, 0x62, 0x99, 0x56, 0x8b, 0xa0, 0x0e, 0xcc, 0xb2, 0x77, 0x43, 0x34, 0xdc, 0xd5, 0x66, 0x4b, + 0x34, 0xdc, 0x43, 0x9d, 0x08, 0x7c, 0x8f, 0x41, 0xdf, 0xc2, 0xba, 0x0f, 0x3d, 0x08, 0xe4, 0x37, + 0x58, 0x17, 0x81, 0x9a, 0x7c, 0x06, 0x79, 0xde, 0x35, 0x40, 0x11, 0x69, 0xa1, 0xee, 0x82, 0x7e, + 0x23, 0x7e, 0x32, 0xf1, 0x94, 0xa9, 0x58, 0x2e, 0x63, 0xa6, 0x60, 0xdf, 0x01, 0x08, 0xda, 0x54, + 0x51, 0xff, 0x4e, 0x74, 0xb5, 0xf4, 0x95, 0x64, 0x06, 0x01, 0xfc, 0x88, 0x01, 0xdf, 0xc5, 0xb7, + 0x62, 0x81, 0xdb, 0xfe, 0x02, 0x0a, 0xde, 0x82, 0xdc, 0xb6, 0xe9, 0x76, 0x51, 0x24, 0xf5, 0x2b, + 0xdf, 0xd1, 0x74, 0x3d, 0x6e, 0x4a, 0x40, 0xdd, 0x65, 0x50, 0xcb, 0x78, 0x29, 0x16, 0xaa, 0x6b, + 0xba, 0x34, 0x93, 0xa2, 0x11, 0x14, 0xe5, 0xb7, 0x31, 0x74, 0x33, 0xe2, 0xb3, 0xf0, 0x77, 0x34, + 0x7d, 0x39, 0x69, 0x5a, 0x00, 0xae, 0x32, 0x40, 0x8c, 0x6f, 0xc6, 0x3b, 0x55, 0xb0, 0x3f, 0xd6, + 0x1e, 0xbd, 0xa5, 0xad, 0xff, 0xa8, 0x06, 0x39, 0x5a, 0xa5, 0xd0, 0xdc, 0x1d, 0x5c, 0xee, 0xa2, + 0x1e, 0x9e, 0x68, 0xa9, 0x44, 0x3d, 0x3c, 0x79, 0x2f, 0x8c, 0xc9, 0xdd, 0xec, 0xa7, 0x6c, 0x84, + 0x71, 0x51, 0x8b, 0x3d, 0x28, 0x2b, 0x57, 0x40, 0x14, 0x23, 0x31, 0xdc, 0xb0, 0x89, 0xe6, 0xee, + 0x98, 0xfb, 0x23, 0x5e, 0x61, 0xa0, 0x3a, 0xbe, 0x1a, 0x06, 0x6d, 0x73, 0x36, 0x8a, 0xfa, 0x5d, + 0xa8, 0xa8, 0x77, 0x45, 0x14, 0x23, 0x34, 0xd2, 0x11, 0x8a, 0xe6, 0x8a, 0xb8, 0xab, 0x66, 0x4c, + 0xd0, 0xf8, 0x3f, 0xdc, 0x93, 0xbc, 0x14, 0xfd, 0x13, 0x28, 0x88, 0x1b, 0x64, 0x9c, 0xbd, 0xe1, + 0x1e, 0x52, 0x9c, 0xbd, 0x91, 0xeb, 0x67, 0x4c, 0x21, 0xc0, 0x60, 0x69, 0xa5, 0x2c, 0x13, 0xb4, + 0x80, 0x7c, 0x4a, 0xbc, 0x24, 0xc8, 0xa0, 0x2b, 0x92, 0x04, 0xa9, 0xdc, 0x52, 0xa6, 0x42, 0x76, + 0x88, 0x27, 0xce, 0xb2, 0xbc, 0x02, 0xa0, 0x04, 0x89, 0x6a, 0x36, 0xc4, 0xd3, 0x58, 0x12, 0x6b, + 0xb7, 0x00, 0x55, 0xa4, 0x42, 0xf4, 0x3d, 0x80, 0xe0, 0xba, 0x1b, 0x7d, 0x1d, 0xc7, 0xf6, 0xcc, + 0xa2, 0xaf, 0xe3, 0xf8, 0x1b, 0x73, 0x4c, 0x04, 0x07, 0xe0, 0xbc, 0x7e, 0xa4, 0xf0, 0x3f, 0xd1, + 0x00, 0x4d, 0x5e, 0x8f, 0xd1, 0xeb, 0xf1, 0x10, 0xb1, 0xed, 0x38, 0xfd, 0x8d, 0xcb, 0x31, 0x27, + 0x66, 0xcf, 0x40, 0xaf, 0x16, 0x5b, 0x32, 0x7c, 0x49, 0x35, 0xfb, 0x5c, 0x83, 0xb9, 0xd0, 0x05, + 0x1b, 0xdd, 0x4f, 0xd8, 0xe7, 0x48, 0x4b, 0x4f, 0x7f, 0x70, 0x21, 0x5f, 0x62, 0xc5, 0xa2, 0x9c, + 0x0a, 0x59, 0xad, 0xfd, 0x50, 0x83, 0x6a, 0xf8, 0x56, 0x8e, 0x12, 0x00, 0x26, 0xfa, 0x82, 0xfa, + 0xea, 0xc5, 0x8c, 0x97, 0xd8, 0xad, 0xa0, 0x80, 0xfb, 0x04, 0x0a, 0xe2, 0x32, 0x1f, 0x17, 0x16, + 0xe1, 0xb6, 0x62, 0x5c, 0x58, 0x44, 0x3a, 0x01, 0x49, 0x61, 0x41, 0xef, 0xc5, 0x4a, 0x24, 0x8a, + 0x2b, 0x7f, 0x12, 0xe4, 0xf4, 0x48, 0x8c, 0xf4, 0x0b, 0xa6, 0x42, 0x06, 0x91, 0x28, 0x2f, 0xfc, + 0x28, 0x41, 0xe2, 0x05, 0x91, 0x18, 0xed, 0x17, 0x24, 0x45, 0x22, 0x43, 0x55, 0x22, 0x31, 0xb8, + 0x9f, 0xc7, 0x45, 0xe2, 0x44, 0xd3, 0x34, 0x2e, 0x12, 0x27, 0xaf, 0xf8, 0x49, 0x7b, 0xcb, 0xc0, + 0x43, 0x91, 0xb8, 0x10, 0x73, 0x9f, 0x47, 0x6f, 0x24, 0xf8, 0x34, 0xb6, 0x21, 0xab, 0xbf, 0x79, + 0x49, 0xee, 0xe9, 0x11, 0xc0, 0x77, 0x43, 0x46, 0xc0, 0x2f, 0x34, 0x58, 0x8c, 0x6b, 0x08, 0xa0, + 0x04, 0xb0, 0x84, 0x6e, 0xae, 0xbe, 0x76, 0x59, 0xf6, 0x4b, 0xf8, 0xcd, 0x8f, 0x89, 0x27, 0xb5, + 0xdf, 0x7e, 0xb5, 0xac, 0x7d, 0xf9, 0xd5, 0xb2, 0xf6, 0xc7, 0xaf, 0x96, 0xb5, 0x9f, 0xfe, 0x69, + 0x79, 0xe6, 0x34, 0xcf, 0x7e, 0x4f, 0xfe, 0xce, 0xbf, 0x02, 0x00, 0x00, 0xff, 0xff, 0x2c, 0x72, + 0x99, 0x38, 0xd6, 0x2e, 0x00, 0x00, } diff --git a/vendor/github.com/coreos/etcd/etcdserver/etcdserverpb/rpc.proto b/vendor/github.com/coreos/etcd/etcdserver/etcdserverpb/rpc.proto index 04f08cb564f..5c04ccb8e90 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/etcdserverpb/rpc.proto +++ b/vendor/github.com/coreos/etcd/etcdserver/etcdserverpb/rpc.proto @@ -396,10 +396,16 @@ message PutRequest { // lease is the lease ID to associate with the key in the key-value store. A lease // value of 0 indicates no lease. int64 lease = 3; + + // If prev_kv is set, etcd gets the previous key-value pair before changing it. + // The previous key-value pair will be returned in the put response. + bool prev_kv = 4; } message PutResponse { ResponseHeader header = 1; + // if prev_kv is set in the request, the previous key-value pair will be returned. + mvccpb.KeyValue prev_kv = 2; } message DeleteRangeRequest { @@ -409,12 +415,17 @@ message DeleteRangeRequest { // If range_end is not given, the range is defined to contain only the key argument. // If range_end is '\0', the range is all keys greater than or equal to the key argument. bytes range_end = 2; + // If prev_kv is set, etcd gets the previous key-value pairs before deleting it. + // The previous key-value pairs will be returned in the delte response. + bool prev_kv = 3; } message DeleteRangeResponse { ResponseHeader header = 1; // deleted is the number of keys deleted by the delete range request. int64 deleted = 2; + // if prev_kv is set in the request, the previous key-value pairs will be returned. + repeated mvccpb.KeyValue prev_kvs = 3; } message RequestOp { @@ -563,6 +574,9 @@ message WatchCreateRequest { // wish to recover a disconnected watcher starting from a recent known revision. // The etcd server may decide how often it will send notifications based on current load. bool progress_notify = 4; + // If prev_kv is set, created watcher gets the previous KV before the event happens. + // If the previous KV is already compacted, nothing will be returned. + bool prev_kv = 6; } message WatchCancelRequest { diff --git a/vendor/github.com/coreos/etcd/etcdserver/v3_server.go b/vendor/github.com/coreos/etcd/etcdserver/v3_server.go index 12e7eda7033..dcd0f0d8a48 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/v3_server.go +++ b/vendor/github.com/coreos/etcd/etcdserver/v3_server.go @@ -551,4 +551,4 @@ func (s *EtcdServer) processInternalRaftRequest(ctx context.Context, r pb.Intern } // Watchable returns a watchable interface attached to the etcdserver. -func (s *EtcdServer) Watchable() mvcc.Watchable { return s.KV() } +func (s *EtcdServer) Watchable() mvcc.WatchableKV { return s.KV() } diff --git a/vendor/github.com/coreos/etcd/lease/leasepb/lease.pb.go b/vendor/github.com/coreos/etcd/lease/leasepb/lease.pb.go index 62115a3c995..dde5f286ea8 100644 --- a/vendor/github.com/coreos/etcd/lease/leasepb/lease.pb.go +++ b/vendor/github.com/coreos/etcd/lease/leasepb/lease.pb.go @@ -19,9 +19,9 @@ import ( proto "github.com/golang/protobuf/proto" math "math" -) -import io "io" + io "io" +) // Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal diff --git a/vendor/github.com/coreos/etcd/mvcc/mvccpb/kv.pb.go b/vendor/github.com/coreos/etcd/mvcc/mvccpb/kv.pb.go index 2ab97270cf0..12c03832856 100644 --- a/vendor/github.com/coreos/etcd/mvcc/mvccpb/kv.pb.go +++ b/vendor/github.com/coreos/etcd/mvcc/mvccpb/kv.pb.go @@ -20,9 +20,9 @@ import ( proto "github.com/golang/protobuf/proto" math "math" -) -import io "io" + io "io" +) // Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal @@ -89,6 +89,8 @@ type Event struct { // A DELETE/EXPIRE event contains the deleted key with // its modification revision set to the revision of deletion. Kv *KeyValue `protobuf:"bytes,2,opt,name=kv" json:"kv,omitempty"` + // prev_kv holds the key-value pair before the event happens. + PrevKv *KeyValue `protobuf:"bytes,3,opt,name=prev_kv,json=prevKv" json:"prev_kv,omitempty"` } func (m *Event) Reset() { *m = Event{} } @@ -181,6 +183,16 @@ func (m *Event) MarshalTo(data []byte) (int, error) { } i += n1 } + if m.PrevKv != nil { + data[i] = 0x1a + i++ + i = encodeVarintKv(data, i, uint64(m.PrevKv.Size())) + n2, err := m.PrevKv.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += n2 + } return i, nil } @@ -247,6 +259,10 @@ func (m *Event) Size() (n int) { l = m.Kv.Size() n += 1 + l + sovKv(uint64(l)) } + if m.PrevKv != nil { + l = m.PrevKv.Size() + n += 1 + l + sovKv(uint64(l)) + } return n } @@ -532,6 +548,39 @@ func (m *Event) Unmarshal(data []byte) error { return err } iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PrevKv", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowKv + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthKv + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.PrevKv == nil { + m.PrevKv = &KeyValue{} + } + if err := m.PrevKv.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipKv(data[iNdEx:]) @@ -659,23 +708,24 @@ var ( ) var fileDescriptorKv = []byte{ - // 285 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x44, 0x90, 0x41, 0x4a, 0xc3, 0x40, - 0x14, 0x86, 0x33, 0x4d, 0x9b, 0xd6, 0xd7, 0x52, 0xc3, 0x50, 0x70, 0x70, 0x31, 0xc4, 0x6e, 0x2c, - 0x08, 0x11, 0xea, 0x0d, 0xc4, 0xac, 0x74, 0x21, 0x21, 0xba, 0x95, 0x34, 0x7d, 0x94, 0x92, 0xa6, - 0x13, 0xd2, 0x38, 0x98, 0x9b, 0x78, 0x0a, 0xcf, 0xd1, 0x65, 0x8f, 0x60, 0xe3, 0x45, 0x24, 0x6f, - 0x4c, 0xdd, 0x0c, 0xef, 0xff, 0xff, 0x6f, 0x98, 0xff, 0x0d, 0x0c, 0x52, 0xed, 0xe7, 0x85, 0x2a, - 0x15, 0x77, 0x32, 0x9d, 0x24, 0xf9, 0xe2, 0x72, 0xb2, 0x52, 0x2b, 0x45, 0xd6, 0x6d, 0x33, 0x99, - 0x74, 0xfa, 0xc5, 0x60, 0xf0, 0x88, 0xd5, 0x6b, 0xbc, 0x79, 0x47, 0xee, 0x82, 0x9d, 0x62, 0x25, - 0x98, 0xc7, 0x66, 0xa3, 0xb0, 0x19, 0xf9, 0x35, 0x9c, 0x27, 0x05, 0xc6, 0x25, 0xbe, 0x15, 0xa8, - 0xd7, 0xbb, 0xb5, 0xda, 0x8a, 0x8e, 0xc7, 0x66, 0x76, 0x38, 0x36, 0x76, 0xf8, 0xe7, 0xf2, 0x2b, - 0x18, 0x65, 0x6a, 0xf9, 0x4f, 0xd9, 0x44, 0x0d, 0x33, 0xb5, 0x3c, 0x21, 0x02, 0xfa, 0x1a, 0x0b, - 0x4a, 0xbb, 0x94, 0xb6, 0x92, 0x4f, 0xa0, 0xa7, 0x9b, 0x02, 0xa2, 0x47, 0x2f, 0x1b, 0xd1, 0xb8, - 0x1b, 0x8c, 0x77, 0x28, 0x1c, 0xa2, 0x8d, 0x98, 0x7e, 0x40, 0x2f, 0xd0, 0xb8, 0x2d, 0xf9, 0x0d, - 0x74, 0xcb, 0x2a, 0x47, 0x6a, 0x3b, 0x9e, 0x5f, 0xf8, 0x66, 0x4d, 0x9f, 0x42, 0x73, 0x46, 0x55, - 0x8e, 0x21, 0x41, 0xdc, 0x83, 0x4e, 0xaa, 0xa9, 0xfa, 0x70, 0xee, 0xb6, 0x68, 0xbb, 0x77, 0xd8, - 0x49, 0xf5, 0xd4, 0x83, 0xb3, 0xd3, 0x25, 0xde, 0x07, 0xfb, 0xf9, 0x25, 0x72, 0x2d, 0x0e, 0xe0, - 0x3c, 0x04, 0x4f, 0x41, 0x14, 0xb8, 0xec, 0x5e, 0xec, 0x8f, 0xd2, 0x3a, 0x1c, 0xa5, 0xb5, 0xaf, - 0x25, 0x3b, 0xd4, 0x92, 0x7d, 0xd7, 0x92, 0x7d, 0xfe, 0x48, 0x6b, 0xe1, 0xd0, 0x5f, 0xde, 0xfd, - 0x06, 0x00, 0x00, 0xff, 0xff, 0xd6, 0x21, 0x8f, 0x2c, 0x75, 0x01, 0x00, 0x00, + // 303 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x6c, 0x90, 0x41, 0x4e, 0xc2, 0x40, + 0x14, 0x86, 0x3b, 0x14, 0x0a, 0x3e, 0x08, 0x36, 0x13, 0x12, 0x27, 0x2e, 0x26, 0x95, 0x8d, 0x18, + 0x13, 0x4c, 0xf0, 0x06, 0xc6, 0xae, 0x70, 0x61, 0x1a, 0x74, 0x4b, 0x4a, 0x79, 0x21, 0xa4, 0x94, + 0x69, 0x4a, 0x9d, 0xa4, 0x37, 0x71, 0xef, 0xde, 0x73, 0xb0, 0xe4, 0x08, 0x52, 0x2f, 0x62, 0xfa, + 0xc6, 0xe2, 0xc6, 0xcd, 0xe4, 0xfd, 0xff, 0xff, 0x65, 0xe6, 0x7f, 0x03, 0x9d, 0x58, 0x8f, 0xd3, + 0x4c, 0xe5, 0x8a, 0x3b, 0x89, 0x8e, 0xa2, 0x74, 0x71, 0x39, 0x58, 0xa9, 0x95, 0x22, 0xeb, 0xae, + 0x9a, 0x4c, 0x3a, 0xfc, 0x64, 0xd0, 0x99, 0x62, 0xf1, 0x1a, 0x6e, 0xde, 0x90, 0xbb, 0x60, 0xc7, + 0x58, 0x08, 0xe6, 0xb1, 0x51, 0x2f, 0xa8, 0x46, 0x7e, 0x0d, 0xe7, 0x51, 0x86, 0x61, 0x8e, 0xf3, + 0x0c, 0xf5, 0x7a, 0xb7, 0x56, 0x5b, 0xd1, 0xf0, 0xd8, 0xc8, 0x0e, 0xfa, 0xc6, 0x0e, 0x7e, 0x5d, + 0x7e, 0x05, 0xbd, 0x44, 0x2d, 0xff, 0x28, 0x9b, 0xa8, 0x6e, 0xa2, 0x96, 0x27, 0x44, 0x40, 0x5b, + 0x63, 0x46, 0x69, 0x93, 0xd2, 0x5a, 0xf2, 0x01, 0xb4, 0x74, 0x55, 0x40, 0xb4, 0xe8, 0x65, 0x23, + 0x2a, 0x77, 0x83, 0xe1, 0x0e, 0x85, 0x43, 0xb4, 0x11, 0xc3, 0x0f, 0x06, 0x2d, 0x5f, 0xe3, 0x36, + 0xe7, 0xb7, 0xd0, 0xcc, 0x8b, 0x14, 0xa9, 0x6e, 0x7f, 0x72, 0x31, 0x36, 0x7b, 0x8e, 0x29, 0x34, + 0xe7, 0xac, 0x48, 0x31, 0x20, 0x88, 0x7b, 0xd0, 0x88, 0x35, 0x75, 0xef, 0x4e, 0xdc, 0x1a, 0xad, + 0x17, 0x0f, 0x1a, 0xb1, 0xe6, 0x37, 0xd0, 0x4e, 0x33, 0xd4, 0xf3, 0x58, 0x53, 0xf9, 0xff, 0x30, + 0xa7, 0x02, 0xa6, 0x7a, 0xe8, 0xc1, 0xd9, 0xe9, 0x7e, 0xde, 0x06, 0xfb, 0xf9, 0x65, 0xe6, 0x5a, + 0x1c, 0xc0, 0x79, 0xf4, 0x9f, 0xfc, 0x99, 0xef, 0xb2, 0x07, 0xb1, 0x3f, 0x4a, 0xeb, 0x70, 0x94, + 0xd6, 0xbe, 0x94, 0xec, 0x50, 0x4a, 0xf6, 0x55, 0x4a, 0xf6, 0xfe, 0x2d, 0xad, 0x85, 0x43, 0xff, + 0x7e, 0xff, 0x13, 0x00, 0x00, 0xff, 0xff, 0xb5, 0x45, 0x92, 0x5d, 0xa1, 0x01, 0x00, 0x00, } diff --git a/vendor/github.com/coreos/etcd/mvcc/mvccpb/kv.proto b/vendor/github.com/coreos/etcd/mvcc/mvccpb/kv.proto index f0c82b57cd4..f150d26c757 100644 --- a/vendor/github.com/coreos/etcd/mvcc/mvccpb/kv.proto +++ b/vendor/github.com/coreos/etcd/mvcc/mvccpb/kv.proto @@ -43,4 +43,6 @@ message Event { // A DELETE/EXPIRE event contains the deleted key with // its modification revision set to the revision of deletion. KeyValue kv = 2; + // prev_kv holds the key-value pair before the event happens. + KeyValue prev_kv = 3; } diff --git a/vendor/github.com/coreos/etcd/pkg/ioutil/pagewriter.go b/vendor/github.com/coreos/etcd/pkg/ioutil/pagewriter.go index ed22d942011..72de1593d3a 100644 --- a/vendor/github.com/coreos/etcd/pkg/ioutil/pagewriter.go +++ b/vendor/github.com/coreos/etcd/pkg/ioutil/pagewriter.go @@ -38,9 +38,12 @@ type PageWriter struct { bufWatermarkBytes int } -func NewPageWriter(w io.Writer, pageBytes int) *PageWriter { +// NewPageWriter creates a new PageWriter. pageBytes is the number of bytes +// to write per page. pageOffset is the starting offset of io.Writer. +func NewPageWriter(w io.Writer, pageBytes, pageOffset int) *PageWriter { return &PageWriter{ w: w, + pageOffset: pageOffset, pageBytes: pageBytes, buf: make([]byte, defaultBufferBytes+pageBytes), bufWatermarkBytes: defaultBufferBytes, diff --git a/vendor/github.com/coreos/etcd/raft/raftpb/raft.pb.go b/vendor/github.com/coreos/etcd/raft/raftpb/raft.pb.go index 6199ee81659..664b5b8289c 100644 --- a/vendor/github.com/coreos/etcd/raft/raftpb/raft.pb.go +++ b/vendor/github.com/coreos/etcd/raft/raftpb/raft.pb.go @@ -25,9 +25,9 @@ import ( proto "github.com/golang/protobuf/proto" math "math" -) -import io "io" + io "io" +) // Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal diff --git a/vendor/github.com/coreos/etcd/snap/snappb/snap.pb.go b/vendor/github.com/coreos/etcd/snap/snappb/snap.pb.go index 11c86dfeaed..f9ef5077dd4 100644 --- a/vendor/github.com/coreos/etcd/snap/snappb/snap.pb.go +++ b/vendor/github.com/coreos/etcd/snap/snappb/snap.pb.go @@ -19,9 +19,9 @@ import ( proto "github.com/golang/protobuf/proto" math "math" -) -import io "io" + io "io" +) // Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal diff --git a/vendor/github.com/coreos/etcd/version/version.go b/vendor/github.com/coreos/etcd/version/version.go index bb884db9184..6934905ba05 100644 --- a/vendor/github.com/coreos/etcd/version/version.go +++ b/vendor/github.com/coreos/etcd/version/version.go @@ -29,7 +29,7 @@ import ( var ( // MinClusterVersion is the min cluster version this etcd binary is compatible with. MinClusterVersion = "2.3.0" - Version = "3.0.10" + Version = "3.0.12" // Git SHA Value will be set during build GitSHA = "Not provided (use ./build instead of go build)" diff --git a/vendor/github.com/coreos/etcd/wal/encoder.go b/vendor/github.com/coreos/etcd/wal/encoder.go index edbd1785ab8..cc3eeebcc7d 100644 --- a/vendor/github.com/coreos/etcd/wal/encoder.go +++ b/vendor/github.com/coreos/etcd/wal/encoder.go @@ -18,6 +18,7 @@ import ( "encoding/binary" "hash" "io" + "os" "sync" "github.com/coreos/etcd/pkg/crc" @@ -39,9 +40,9 @@ type encoder struct { uint64buf []byte } -func newEncoder(w io.Writer, prevCrc uint32) *encoder { +func newEncoder(w io.Writer, prevCrc uint32, pageOffset int) *encoder { return &encoder{ - bw: ioutil.NewPageWriter(w, walPageBytes), + bw: ioutil.NewPageWriter(w, walPageBytes, pageOffset), crc: crc.New(prevCrc, crcTable), // 1MB buffer buf: make([]byte, 1024*1024), @@ -49,6 +50,15 @@ func newEncoder(w io.Writer, prevCrc uint32) *encoder { } } +// newFileEncoder creates a new encoder with current file offset for the page writer. +func newFileEncoder(f *os.File, prevCrc uint32) (*encoder, error) { + offset, err := f.Seek(0, os.SEEK_CUR) + if err != nil { + return nil, err + } + return newEncoder(f, prevCrc, int(offset)), nil +} + func (e *encoder) encode(rec *walpb.Record) error { e.mu.Lock() defer e.mu.Unlock() diff --git a/vendor/github.com/coreos/etcd/wal/wal.go b/vendor/github.com/coreos/etcd/wal/wal.go index 7169a575237..2e4e0ba0e8e 100644 --- a/vendor/github.com/coreos/etcd/wal/wal.go +++ b/vendor/github.com/coreos/etcd/wal/wal.go @@ -120,7 +120,10 @@ func Create(dirpath string, metadata []byte) (*WAL, error) { w := &WAL{ dir: dirpath, metadata: metadata, - encoder: newEncoder(f, 0), + } + w.encoder, err = newFileEncoder(f.File, 0) + if err != nil { + return nil, err } w.locks = append(w.locks, f) if err = w.saveCrc(0); err != nil { @@ -341,7 +344,10 @@ func (w *WAL) ReadAll() (metadata []byte, state raftpb.HardState, ents []raftpb. if w.tail() != nil { // create encoder (chain crc with the decoder), enable appending - w.encoder = newEncoder(w.tail(), w.decoder.lastCRC()) + w.encoder, err = newFileEncoder(w.tail().File, w.decoder.lastCRC()) + if err != nil { + return + } } w.decoder = nil @@ -375,7 +381,10 @@ func (w *WAL) cut() error { // update writer and save the previous crc w.locks = append(w.locks, newTail) prevCrc := w.encoder.crc.Sum32() - w.encoder = newEncoder(w.tail(), prevCrc) + w.encoder, err = newFileEncoder(w.tail().File, prevCrc) + if err != nil { + return err + } if err = w.saveCrc(prevCrc); err != nil { return err } @@ -414,7 +423,10 @@ func (w *WAL) cut() error { w.locks[len(w.locks)-1] = newTail prevCrc = w.encoder.crc.Sum32() - w.encoder = newEncoder(w.tail(), prevCrc) + w.encoder, err = newFileEncoder(w.tail().File, prevCrc) + if err != nil { + return err + } plog.Infof("segmented wal file %v is created", fpath) return nil diff --git a/vendor/github.com/coreos/etcd/wal/walpb/record.pb.go b/vendor/github.com/coreos/etcd/wal/walpb/record.pb.go index bc715a818e5..0e86f363e57 100644 --- a/vendor/github.com/coreos/etcd/wal/walpb/record.pb.go +++ b/vendor/github.com/coreos/etcd/wal/walpb/record.pb.go @@ -20,9 +20,9 @@ import ( proto "github.com/golang/protobuf/proto" math "math" -) -import io "io" + io "io" +) // Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal diff --git a/vendor/github.com/xiang90/probing/prober.go b/vendor/github.com/xiang90/probing/prober.go index 9f04f86025c..c917cfd9d19 100644 --- a/vendor/github.com/xiang90/probing/prober.go +++ b/vendor/github.com/xiang90/probing/prober.go @@ -61,7 +61,7 @@ func (p *prober) AddHTTP(id string, probingInterval time.Duration, endpoints []s } resp, err := p.tr.RoundTrip(req) if err != nil { - s.recordFailure() + s.recordFailure(err) pinned = (pinned + 1) % len(endpoints) continue } @@ -71,7 +71,7 @@ func (p *prober) AddHTTP(id string, probingInterval time.Duration, endpoints []s err = d.Decode(&hh) resp.Body.Close() if err != nil || !hh.OK { - s.recordFailure() + s.recordFailure(err) pinned = (pinned + 1) % len(endpoints) continue } diff --git a/vendor/github.com/xiang90/probing/status.go b/vendor/github.com/xiang90/probing/status.go index bdfab2761c2..bb5f6599fc8 100644 --- a/vendor/github.com/xiang90/probing/status.go +++ b/vendor/github.com/xiang90/probing/status.go @@ -14,6 +14,7 @@ type Status interface { Total() int64 Loss() int64 Health() bool + Err() error // Estimated smoothed round trip time SRTT() time.Duration // Estimated clock difference @@ -27,6 +28,7 @@ type status struct { total int64 loss int64 health bool + err error clockdiff time.Duration stopC chan struct{} } @@ -56,6 +58,12 @@ func (s *status) Health() bool { return s.health } +func (s *status) Err() error { + s.mu.Lock() + defer s.mu.Unlock() + return s.err +} + func (s *status) ClockDiff() time.Duration { s.mu.Lock() defer s.mu.Unlock() @@ -74,15 +82,17 @@ func (s *status) record(rtt time.Duration, when time.Time) { s.health = true s.srtt = time.Duration((1-α)*float64(s.srtt) + α*float64(rtt)) s.clockdiff = time.Now().Sub(when) - s.srtt/2 + s.err = nil } -func (s *status) recordFailure() { +func (s *status) recordFailure(err error) { s.mu.Lock() defer s.mu.Unlock() s.total++ s.health = false s.loss += 1 + s.err = err } func (s *status) reset() { @@ -91,6 +101,8 @@ func (s *status) reset() { s.srtt = 0 s.total = 0 + s.loss = 0 s.health = false s.clockdiff = 0 + s.err = nil }