From 2308857ad3b8b18abf74ff734853973eda9da94d Mon Sep 17 00:00:00 2001 From: Kubernetes Publisher Date: Wed, 12 Apr 2017 20:36:01 +0000 Subject: [PATCH] sync: resync vendor folder --- Godeps/Godeps.json | 1017 +++ .../coreos/etcd/auth/authpb/auth.pb.go | 186 +- .../coreos/etcd/auth/range_perm_cache.go | 49 +- .../coreos/etcd/auth/simple_token.go | 89 + vendor/github.com/coreos/etcd/auth/store.go | 341 +- .../github.com/coreos/etcd/client/README.md | 2 +- .../github.com/coreos/etcd/client/client.go | 147 +- .../coreos/etcd/client/cluster_error.go | 6 +- .../coreos/etcd/client/keys.generated.go | 675 +- vendor/github.com/coreos/etcd/client/keys.go | 32 +- vendor/github.com/coreos/etcd/client/util.go | 30 + .../github.com/coreos/etcd/clientv3/README.md | 4 + .../github.com/coreos/etcd/clientv3/auth.go | 5 +- .../coreos/etcd/clientv3/balancer.go | 76 +- .../github.com/coreos/etcd/clientv3/client.go | 198 +- .../coreos/etcd/clientv3/cluster.go | 2 +- .../coreos/etcd/clientv3/compare.go | 2 + .../github.com/coreos/etcd/clientv3/config.go | 13 +- vendor/github.com/coreos/etcd/clientv3/doc.go | 2 +- vendor/github.com/coreos/etcd/clientv3/kv.go | 23 +- .../github.com/coreos/etcd/clientv3/lease.go | 83 +- .../github.com/coreos/etcd/clientv3/logger.go | 40 +- vendor/github.com/coreos/etcd/clientv3/op.go | 145 +- .../github.com/coreos/etcd/clientv3/retry.go | 120 +- vendor/github.com/coreos/etcd/clientv3/txn.go | 8 +- .../github.com/coreos/etcd/clientv3/watch.go | 83 +- .../coreos/etcd/compactor/compactor.go | 2 +- .../coreos/etcd/discovery/discovery.go | 16 +- .../github.com/coreos/etcd/discovery/srv.go | 33 +- .../coreos/etcd/etcdserver/api/capability.go | 5 +- .../etcd/etcdserver/api/v2http/client.go | 104 +- .../coreos/etcd/etcdserver/api/v2http/http.go | 4 +- .../etcdserver/api/v2http/httptypes/errors.go | 2 +- .../coreos/etcd/etcdserver/api/v2http/peer.go | 9 +- .../coreos/etcd/etcdserver/api/v3rpc/grpc.go | 3 +- .../etcd/etcdserver/api/v3rpc/interceptor.go | 42 +- .../coreos/etcd/etcdserver/api/v3rpc/key.go | 10 +- .../coreos/etcd/etcdserver/api/v3rpc/lease.go | 20 +- .../etcd/etcdserver/api/v3rpc/maintenance.go | 54 +- .../etcd/etcdserver/api/v3rpc/member.go | 34 +- .../etcd/etcdserver/api/v3rpc/metrics.go | 29 - .../etcdserver/api/v3rpc/rpctypes/error.go | 45 +- .../coreos/etcd/etcdserver/api/v3rpc/util.go | 30 +- .../coreos/etcd/etcdserver/api/v3rpc/watch.go | 36 +- .../coreos/etcd/etcdserver/apply.go | 100 +- .../coreos/etcd/etcdserver/apply_auth.go | 100 +- .../coreos/etcd/etcdserver/auth/auth.go | 96 +- .../etcd/etcdserver/auth/auth_requests.go | 10 +- .../coreos/etcd/etcdserver/cluster_util.go | 11 +- .../coreos/etcd/etcdserver/config.go | 59 +- .../coreos/etcd/etcdserver/errors.go | 4 +- .../etcdserver/etcdserverpb/etcdserver.pb.go | 340 +- .../etcdserverpb/raft_internal.pb.go | 608 +- .../etcdserverpb/raft_internal.proto | 2 + .../etcd/etcdserver/etcdserverpb/rpc.pb.go | 5435 ++++++++++------- .../etcd/etcdserver/etcdserverpb/rpc.pb.gw.go | 45 + .../etcd/etcdserver/etcdserverpb/rpc.proto | 60 +- .../etcd/etcdserver/membership/cluster.go | 7 +- .../etcd/etcdserver/membership/member.go | 2 +- .../coreos/etcd/etcdserver/metrics.go | 2 +- .../github.com/coreos/etcd/etcdserver/raft.go | 132 +- .../coreos/etcd/etcdserver/server.go | 530 +- .../coreos/etcd/etcdserver/snapshot_merge.go | 8 +- .../coreos/etcd/etcdserver/stats/server.go | 13 +- .../coreos/etcd/etcdserver/stats/stats.go | 2 +- .../coreos/etcd/etcdserver/storage.go | 42 - .../github.com/coreos/etcd/etcdserver/util.go | 69 +- .../coreos/etcd/etcdserver/v2_server.go | 2 +- .../coreos/etcd/etcdserver/v3_server.go | 440 +- .../coreos/etcd/integration/bridge.go | 3 +- .../coreos/etcd/integration/cluster.go | 118 +- .../coreos/etcd/integration/cluster_direct.go | 37 + .../coreos/etcd/integration/cluster_proxy.go | 89 + .../coreos/etcd/lease/leasehttp/http.go | 186 +- .../coreos/etcd/lease/leasepb/lease.pb.go | 375 +- .../coreos/etcd/lease/leasepb/lease.proto | 9 + vendor/github.com/coreos/etcd/lease/lessor.go | 189 +- .../coreos/etcd/mvcc/backend/backend.go | 9 +- .../coreos/etcd/mvcc/backend/batch_tx.go | 17 +- vendor/github.com/coreos/etcd/mvcc/index.go | 23 +- vendor/github.com/coreos/etcd/mvcc/kvstore.go | 89 +- .../coreos/etcd/mvcc/mvccpb/kv.pb.go | 160 +- .../coreos/etcd/mvcc/mvccpb/kv.proto | 1 + .../coreos/etcd/mvcc/watchable_store.go | 63 +- vendor/github.com/coreos/etcd/mvcc/watcher.go | 9 +- .../coreos/etcd/mvcc/watcher_group.go | 4 + .../coreos/etcd/pkg/adt/interval_tree.go | 3 + .../github.com/coreos/etcd/pkg/cpuutil/doc.go | 16 + .../coreos/etcd/pkg/cpuutil/endian.go | 36 + .../coreos/etcd/pkg/fileutil/fileutil.go | 6 +- .../coreos/etcd/pkg/fileutil/purge.go | 4 +- .../coreos/etcd/pkg/httputil/httputil.go | 2 +- .../coreos/etcd/pkg/monotime/issue15006.s | 6 + .../coreos/etcd/pkg/monotime/monotime.go | 26 + .../coreos/etcd/pkg/monotime/nanotime.go | 24 + .../coreos/etcd/pkg/netutil/isolate_linux.go | 32 +- .../coreos/etcd/pkg/netutil/netutil.go | 60 +- .../coreos/etcd/pkg/netutil/routes.go | 33 + .../coreos/etcd/pkg/netutil/routes_linux.go | 250 + .../coreos/etcd/pkg/pbutil/pbutil.go | 2 +- .../coreos/etcd/pkg/testutil/leak.go | 2 + .../coreos/etcd/pkg/testutil/testutil.go | 2 +- .../coreos/etcd/pkg/transport/listener.go | 46 +- .../etcd/pkg/transport/timeout_listener.go | 10 +- .../etcd/pkg/transport/timeout_transport.go | 2 +- .../coreos/etcd/pkg/transport/transport.go | 5 +- .../github.com/coreos/etcd/pkg/wait/wait.go | 11 + .../coreos/etcd/pkg/wait/wait_time.go | 44 +- .../coreos/etcd/proxy/grpcproxy/auth.go | 110 + .../etcd/proxy/grpcproxy/cache/store.go | 168 + .../coreos/etcd/proxy/grpcproxy/cluster.go | 52 + .../coreos/etcd/proxy/grpcproxy/doc.go | 16 + .../coreos/etcd/proxy/grpcproxy/kv.go | 210 + .../etcd/proxy/grpcproxy/kv_client_adapter.go | 47 + .../coreos/etcd/proxy/grpcproxy/lease.go | 87 + .../etcd/proxy/grpcproxy/maintenance.go | 74 + .../coreos/etcd/proxy/grpcproxy/metrics.go | 51 + .../coreos/etcd/proxy/grpcproxy/watch.go | 267 + .../etcd/proxy/grpcproxy/watch_broadcast.go | 158 + .../etcd/proxy/grpcproxy/watch_broadcasts.go | 135 + .../proxy/grpcproxy/watch_client_adapter.go | 196 + .../etcd/proxy/grpcproxy/watch_ranges.go | 69 + .../coreos/etcd/proxy/grpcproxy/watcher.go | 127 + vendor/github.com/coreos/etcd/raft/README.md | 65 +- vendor/github.com/coreos/etcd/raft/doc.go | 6 + vendor/github.com/coreos/etcd/raft/log.go | 6 +- .../coreos/etcd/raft/log_unstable.go | 16 +- vendor/github.com/coreos/etcd/raft/node.go | 60 +- .../github.com/coreos/etcd/raft/progress.go | 57 +- vendor/github.com/coreos/etcd/raft/raft.go | 456 +- .../coreos/etcd/raft/raftpb/raft.pb.go | 576 +- .../coreos/etcd/raft/raftpb/raft.proto | 5 + vendor/github.com/coreos/etcd/raft/rawnode.go | 33 +- .../github.com/coreos/etcd/raft/read_only.go | 118 + vendor/github.com/coreos/etcd/raft/storage.go | 13 +- vendor/github.com/coreos/etcd/raft/util.go | 16 +- .../github.com/coreos/etcd/rafthttp/coder.go | 2 +- .../github.com/coreos/etcd/rafthttp/http.go | 6 + .../coreos/etcd/rafthttp/metrics.go | 21 +- .../coreos/etcd/rafthttp/msg_codec.go | 13 +- .../coreos/etcd/rafthttp/msgappv2_codec.go | 4 +- .../github.com/coreos/etcd/rafthttp/peer.go | 2 - .../coreos/etcd/rafthttp/pipeline.go | 3 +- .../coreos/etcd/rafthttp/probing_status.go | 10 +- .../github.com/coreos/etcd/rafthttp/remote.go | 8 + .../coreos/etcd/rafthttp/snapshot_sender.go | 5 +- .../github.com/coreos/etcd/rafthttp/stream.go | 42 +- .../coreos/etcd/rafthttp/transport.go | 30 + vendor/github.com/coreos/etcd/snap/db.go | 6 +- .../coreos/etcd/snap/snappb/snap.pb.go | 92 +- .../coreos/etcd/snap/snapshotter.go | 10 +- .../coreos/etcd/store/event_history.go | 8 +- vendor/github.com/coreos/etcd/store/store.go | 10 +- .../github.com/coreos/etcd/version/version.go | 55 +- vendor/github.com/coreos/etcd/wal/doc.go | 2 +- vendor/github.com/coreos/etcd/wal/encoder.go | 4 +- .../coreos/etcd/wal/file_pipeline.go | 4 +- vendor/github.com/coreos/etcd/wal/repair.go | 4 +- vendor/github.com/coreos/etcd/wal/wal.go | 39 +- vendor/github.com/coreos/etcd/wal/wal_unix.go | 2 +- .../coreos/etcd/wal/walpb/record.pb.go | 132 +- vendor/github.com/gogo/protobuf/AUTHORS | 14 + vendor/github.com/gogo/protobuf/CONTRIBUTORS | 3 + vendor/github.com/gogo/protobuf/LICENSE | 6 +- .../github.com/gogo/protobuf/proto/Makefile | 2 +- .../github.com/gogo/protobuf/proto/clone.go | 14 +- .../github.com/gogo/protobuf/proto/decode.go | 137 +- .../gogo/protobuf/proto/decode_gogo.go | 11 +- .../gogo/protobuf/proto/duration.go | 100 + .../gogo/protobuf/proto/duration_gogo.go | 203 + .../github.com/gogo/protobuf/proto/encode.go | 73 +- .../gogo/protobuf/proto/encode_gogo.go | 22 +- .../github.com/gogo/protobuf/proto/equal.go | 34 +- .../gogo/protobuf/proto/extensions.go | 413 +- .../gogo/protobuf/proto/extensions_gogo.go | 88 +- vendor/github.com/gogo/protobuf/proto/lib.go | 6 +- .../gogo/protobuf/proto/lib_gogo.go | 6 +- .../gogo/protobuf/proto/message_set.go | 43 +- .../gogo/protobuf/proto/pointer_reflect.go | 7 +- .../protobuf/proto/pointer_reflect_gogo.go | 85 + .../gogo/protobuf/proto/pointer_unsafe.go | 6 +- .../protobuf/proto/pointer_unsafe_gogo.go | 44 +- .../gogo/protobuf/proto/properties.go | 93 +- .../gogo/protobuf/proto/properties_gogo.go | 51 +- .../gogo/protobuf/proto/skip_gogo.go | 6 +- vendor/github.com/gogo/protobuf/proto/text.go | 213 +- .../gogo/protobuf/proto/text_gogo.go | 12 +- .../gogo/protobuf/proto/text_parser.go | 270 +- .../gogo/protobuf/proto/timestamp.go | 113 + .../gogo/protobuf/proto/timestamp_gogo.go | 229 + .../gogo/protobuf/sortkeys/sortkeys.go | 4 +- .../golang/protobuf/jsonpb/jsonpb.go | 68 +- .../golang/protobuf/proto/decode.go | 117 +- .../golang/protobuf/proto/encode.go | 14 +- .../github.com/golang/protobuf/proto/equal.go | 8 +- .../golang/protobuf/proto/extensions.go | 31 + .../github.com/golang/protobuf/proto/lib.go | 2 +- .../golang/protobuf/proto/properties.go | 10 +- .../github.com/golang/protobuf/proto/text.go | 2 +- .../golang/protobuf/proto/text_parser.go | 23 +- .../go-grpc-prometheus/.gitignore | 198 + .../go-grpc-prometheus/.travis.yml | 18 + .../grpc-ecosystem/go-grpc-prometheus/LICENSE | 201 + .../go-grpc-prometheus/README.md | 247 + .../go-grpc-prometheus/client.go | 72 + .../go-grpc-prometheus/client_reporter.go | 111 + .../go-grpc-prometheus/server.go | 74 + .../go-grpc-prometheus/server_reporter.go | 157 + .../go-grpc-prometheus/test_all.sh | 14 + .../grpc-ecosystem/go-grpc-prometheus/util.go | 27 + .../grpc-gateway/runtime/context.go | 12 +- .../grpc-gateway/runtime/errors.go | 4 +- .../grpc-gateway/runtime/handler.go | 6 +- .../runtime/internal/stream_chunk.pb.go | 26 +- .../grpc-gateway/runtime/marshal_jsonpb.go | 6 +- vendor/github.com/karlseguin/ccache/Makefile | 5 + vendor/github.com/karlseguin/ccache/bucket.go | 41 + vendor/github.com/karlseguin/ccache/cache.go | 227 + .../karlseguin/ccache/configuration.go | 94 + vendor/github.com/karlseguin/ccache/item.go | 103 + .../karlseguin/ccache/layeredbucket.go | 82 + .../karlseguin/ccache/layeredcache.go | 237 + .../github.com/karlseguin/ccache/license.txt | 19 + vendor/github.com/karlseguin/ccache/readme.md | 172 + .../karlseguin/ccache/secondarycache.go | 72 + .../x/net/http2/client_conn_pool.go | 9 +- vendor/golang.org/x/net/http2/errors.go | 8 + vendor/golang.org/x/net/http2/frame.go | 71 +- vendor/golang.org/x/net/http2/go17.go | 12 + vendor/golang.org/x/net/http2/go17_not18.go | 36 + vendor/golang.org/x/net/http2/go18.go | 50 + vendor/golang.org/x/net/http2/hpack/hpack.go | 2 +- vendor/golang.org/x/net/http2/http2.go | 52 +- vendor/golang.org/x/net/http2/not_go17.go | 38 +- vendor/golang.org/x/net/http2/not_go18.go | 27 + vendor/golang.org/x/net/http2/server.go | 1184 ++-- vendor/golang.org/x/net/http2/transport.go | 613 +- vendor/golang.org/x/net/http2/write.go | 176 +- vendor/golang.org/x/net/http2/writesched.go | 429 +- .../x/net/http2/writesched_priority.go | 452 ++ .../x/net/http2/writesched_random.go | 72 + .../golang.org/x/net/lex/httplex/httplex.go | 39 + vendor/golang.org/x/net/trace/events.go | 20 +- vendor/golang.org/x/net/trace/histogram.go | 15 +- vendor/golang.org/x/net/trace/trace.go | 46 +- vendor/golang.org/x/net/websocket/client.go | 15 +- vendor/golang.org/x/net/websocket/dial.go | 24 + .../golang.org/x/net/websocket/websocket.go | 39 +- vendor/golang.org/x/time/AUTHORS | 3 + vendor/golang.org/x/time/CONTRIBUTORS | 3 + vendor/golang.org/x/time/LICENSE | 27 + vendor/golang.org/x/time/PATENTS | 22 + vendor/golang.org/x/time/rate/rate.go | 371 ++ vendor/google.golang.org/grpc/.travis.yml | 12 +- vendor/google.golang.org/grpc/README.md | 4 +- vendor/google.golang.org/grpc/backoff.go | 2 +- vendor/google.golang.org/grpc/balancer.go | 23 +- vendor/google.golang.org/grpc/call.go | 18 +- vendor/google.golang.org/grpc/clientconn.go | 135 +- .../grpc/credentials/credentials.go | 49 +- vendor/google.golang.org/grpc/interceptor.go | 16 + .../grpc/metadata/metadata.go | 13 +- vendor/google.golang.org/grpc/rpc_util.go | 8 +- vendor/google.golang.org/grpc/server.go | 96 +- vendor/google.golang.org/grpc/stream.go | 53 +- .../grpc/transport/handler_server.go | 4 +- .../grpc/transport/http2_client.go | 121 +- .../grpc/transport/http2_server.go | 53 +- .../grpc/transport/http_util.go | 13 +- .../grpc/transport/transport.go | 61 +- 270 files changed, 20303 insertions(+), 6727 deletions(-) create mode 100644 vendor/github.com/coreos/etcd/integration/cluster_direct.go create mode 100644 vendor/github.com/coreos/etcd/integration/cluster_proxy.go create mode 100644 vendor/github.com/coreos/etcd/pkg/cpuutil/doc.go create mode 100644 vendor/github.com/coreos/etcd/pkg/cpuutil/endian.go create mode 100644 vendor/github.com/coreos/etcd/pkg/monotime/issue15006.s create mode 100644 vendor/github.com/coreos/etcd/pkg/monotime/monotime.go create mode 100644 vendor/github.com/coreos/etcd/pkg/monotime/nanotime.go create mode 100644 vendor/github.com/coreos/etcd/pkg/netutil/routes.go create mode 100644 vendor/github.com/coreos/etcd/pkg/netutil/routes_linux.go create mode 100644 vendor/github.com/coreos/etcd/proxy/grpcproxy/auth.go create mode 100644 vendor/github.com/coreos/etcd/proxy/grpcproxy/cache/store.go create mode 100644 vendor/github.com/coreos/etcd/proxy/grpcproxy/cluster.go create mode 100644 vendor/github.com/coreos/etcd/proxy/grpcproxy/doc.go create mode 100644 vendor/github.com/coreos/etcd/proxy/grpcproxy/kv.go create mode 100644 vendor/github.com/coreos/etcd/proxy/grpcproxy/kv_client_adapter.go create mode 100644 vendor/github.com/coreos/etcd/proxy/grpcproxy/lease.go create mode 100644 vendor/github.com/coreos/etcd/proxy/grpcproxy/maintenance.go create mode 100644 vendor/github.com/coreos/etcd/proxy/grpcproxy/metrics.go create mode 100644 vendor/github.com/coreos/etcd/proxy/grpcproxy/watch.go create mode 100644 vendor/github.com/coreos/etcd/proxy/grpcproxy/watch_broadcast.go create mode 100644 vendor/github.com/coreos/etcd/proxy/grpcproxy/watch_broadcasts.go create mode 100644 vendor/github.com/coreos/etcd/proxy/grpcproxy/watch_client_adapter.go create mode 100644 vendor/github.com/coreos/etcd/proxy/grpcproxy/watch_ranges.go create mode 100644 vendor/github.com/coreos/etcd/proxy/grpcproxy/watcher.go create mode 100644 vendor/github.com/coreos/etcd/raft/read_only.go create mode 100644 vendor/github.com/gogo/protobuf/AUTHORS create mode 100644 vendor/github.com/gogo/protobuf/proto/duration.go create mode 100644 vendor/github.com/gogo/protobuf/proto/duration_gogo.go create mode 100644 vendor/github.com/gogo/protobuf/proto/pointer_reflect_gogo.go create mode 100644 vendor/github.com/gogo/protobuf/proto/timestamp.go create mode 100644 vendor/github.com/gogo/protobuf/proto/timestamp_gogo.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-prometheus/.gitignore create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-prometheus/.travis.yml create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-prometheus/LICENSE create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-prometheus/README.md create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-prometheus/client.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-prometheus/client_reporter.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-prometheus/server.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-prometheus/server_reporter.go create mode 100755 vendor/github.com/grpc-ecosystem/go-grpc-prometheus/test_all.sh create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-prometheus/util.go create mode 100644 vendor/github.com/karlseguin/ccache/Makefile create mode 100644 vendor/github.com/karlseguin/ccache/bucket.go create mode 100644 vendor/github.com/karlseguin/ccache/cache.go create mode 100644 vendor/github.com/karlseguin/ccache/configuration.go create mode 100644 vendor/github.com/karlseguin/ccache/item.go create mode 100644 vendor/github.com/karlseguin/ccache/layeredbucket.go create mode 100644 vendor/github.com/karlseguin/ccache/layeredcache.go create mode 100644 vendor/github.com/karlseguin/ccache/license.txt create mode 100644 vendor/github.com/karlseguin/ccache/readme.md create mode 100644 vendor/github.com/karlseguin/ccache/secondarycache.go create mode 100644 vendor/golang.org/x/net/http2/go17_not18.go create mode 100644 vendor/golang.org/x/net/http2/go18.go create mode 100644 vendor/golang.org/x/net/http2/not_go18.go create mode 100644 vendor/golang.org/x/net/http2/writesched_priority.go create mode 100644 vendor/golang.org/x/net/http2/writesched_random.go create mode 100644 vendor/golang.org/x/net/websocket/dial.go create mode 100644 vendor/golang.org/x/time/AUTHORS create mode 100644 vendor/golang.org/x/time/CONTRIBUTORS create mode 100644 vendor/golang.org/x/time/LICENSE create mode 100644 vendor/golang.org/x/time/PATENTS create mode 100644 vendor/golang.org/x/time/rate/rate.go diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json index 8c8d538e1..c624db7d8 100644 --- a/Godeps/Godeps.json +++ b/Godeps/Godeps.json @@ -8,10 +8,12 @@ "Deps": [ { "ImportPath": "bitbucket.org/ww/goautoneg", + "Comment": "null-5", "Rev": "75cd24fc2f2c2a2088577d12123ddee5f54e0675" }, { "ImportPath": "github.com/PuerkitoBio/purell", + "Comment": "v1.0.0", "Rev": "8a290539e2e8629dbc4e6bad948158f790ec31f4" }, { @@ -24,230 +26,287 @@ }, { "ImportPath": "github.com/boltdb/bolt", + "Comment": "v1.3.0", "Rev": "583e8937c61f1af6513608ccc75c97b6abdf4ff9" }, { "ImportPath": "github.com/coreos/etcd/alarm", + "Comment": "v3.1.5", "Rev": "20490caaf0dcd96bb4a95e40625559def8ef5b04" }, { "ImportPath": "github.com/coreos/etcd/auth", + "Comment": "v3.1.5", "Rev": "20490caaf0dcd96bb4a95e40625559def8ef5b04" }, { "ImportPath": "github.com/coreos/etcd/auth/authpb", + "Comment": "v3.1.5", "Rev": "20490caaf0dcd96bb4a95e40625559def8ef5b04" }, { "ImportPath": "github.com/coreos/etcd/client", + "Comment": "v3.1.5", "Rev": "20490caaf0dcd96bb4a95e40625559def8ef5b04" }, { "ImportPath": "github.com/coreos/etcd/clientv3", + "Comment": "v3.1.5", "Rev": "20490caaf0dcd96bb4a95e40625559def8ef5b04" }, { "ImportPath": "github.com/coreos/etcd/compactor", + "Comment": "v3.1.5", "Rev": "20490caaf0dcd96bb4a95e40625559def8ef5b04" }, { "ImportPath": "github.com/coreos/etcd/discovery", + "Comment": "v3.1.5", "Rev": "20490caaf0dcd96bb4a95e40625559def8ef5b04" }, { "ImportPath": "github.com/coreos/etcd/error", + "Comment": "v3.1.5", "Rev": "20490caaf0dcd96bb4a95e40625559def8ef5b04" }, { "ImportPath": "github.com/coreos/etcd/etcdserver", + "Comment": "v3.1.5", "Rev": "20490caaf0dcd96bb4a95e40625559def8ef5b04" }, { "ImportPath": "github.com/coreos/etcd/etcdserver/api", + "Comment": "v3.1.5", "Rev": "20490caaf0dcd96bb4a95e40625559def8ef5b04" }, { "ImportPath": "github.com/coreos/etcd/etcdserver/api/v2http", + "Comment": "v3.1.5", "Rev": "20490caaf0dcd96bb4a95e40625559def8ef5b04" }, { "ImportPath": "github.com/coreos/etcd/etcdserver/api/v2http/httptypes", + "Comment": "v3.1.5", "Rev": "20490caaf0dcd96bb4a95e40625559def8ef5b04" }, { "ImportPath": "github.com/coreos/etcd/etcdserver/api/v3rpc", + "Comment": "v3.1.5", "Rev": "20490caaf0dcd96bb4a95e40625559def8ef5b04" }, { "ImportPath": "github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes", + "Comment": "v3.1.5", "Rev": "20490caaf0dcd96bb4a95e40625559def8ef5b04" }, { "ImportPath": "github.com/coreos/etcd/etcdserver/auth", + "Comment": "v3.1.5", "Rev": "20490caaf0dcd96bb4a95e40625559def8ef5b04" }, { "ImportPath": "github.com/coreos/etcd/etcdserver/etcdserverpb", + "Comment": "v3.1.5", "Rev": "20490caaf0dcd96bb4a95e40625559def8ef5b04" }, { "ImportPath": "github.com/coreos/etcd/etcdserver/membership", + "Comment": "v3.1.5", "Rev": "20490caaf0dcd96bb4a95e40625559def8ef5b04" }, { "ImportPath": "github.com/coreos/etcd/etcdserver/stats", + "Comment": "v3.1.5", "Rev": "20490caaf0dcd96bb4a95e40625559def8ef5b04" }, { "ImportPath": "github.com/coreos/etcd/integration", + "Comment": "v3.1.5", "Rev": "20490caaf0dcd96bb4a95e40625559def8ef5b04" }, { "ImportPath": "github.com/coreos/etcd/lease", + "Comment": "v3.1.5", "Rev": "20490caaf0dcd96bb4a95e40625559def8ef5b04" }, { "ImportPath": "github.com/coreos/etcd/lease/leasehttp", + "Comment": "v3.1.5", "Rev": "20490caaf0dcd96bb4a95e40625559def8ef5b04" }, { "ImportPath": "github.com/coreos/etcd/lease/leasepb", + "Comment": "v3.1.5", "Rev": "20490caaf0dcd96bb4a95e40625559def8ef5b04" }, { "ImportPath": "github.com/coreos/etcd/mvcc", + "Comment": "v3.1.5", "Rev": "20490caaf0dcd96bb4a95e40625559def8ef5b04" }, { "ImportPath": "github.com/coreos/etcd/mvcc/backend", + "Comment": "v3.1.5", "Rev": "20490caaf0dcd96bb4a95e40625559def8ef5b04" }, { "ImportPath": "github.com/coreos/etcd/mvcc/mvccpb", + "Comment": "v3.1.5", "Rev": "20490caaf0dcd96bb4a95e40625559def8ef5b04" }, { "ImportPath": "github.com/coreos/etcd/pkg/adt", + "Comment": "v3.1.5", "Rev": "20490caaf0dcd96bb4a95e40625559def8ef5b04" }, { "ImportPath": "github.com/coreos/etcd/pkg/contention", + "Comment": "v3.1.5", "Rev": "20490caaf0dcd96bb4a95e40625559def8ef5b04" }, { "ImportPath": "github.com/coreos/etcd/pkg/cpuutil", + "Comment": "v3.1.5", "Rev": "20490caaf0dcd96bb4a95e40625559def8ef5b04" }, { "ImportPath": "github.com/coreos/etcd/pkg/crc", + "Comment": "v3.1.5", "Rev": "20490caaf0dcd96bb4a95e40625559def8ef5b04" }, { "ImportPath": "github.com/coreos/etcd/pkg/fileutil", + "Comment": "v3.1.5", "Rev": "20490caaf0dcd96bb4a95e40625559def8ef5b04" }, { "ImportPath": "github.com/coreos/etcd/pkg/httputil", + "Comment": "v3.1.5", "Rev": "20490caaf0dcd96bb4a95e40625559def8ef5b04" }, { "ImportPath": "github.com/coreos/etcd/pkg/idutil", + "Comment": "v3.1.5", "Rev": "20490caaf0dcd96bb4a95e40625559def8ef5b04" }, { "ImportPath": "github.com/coreos/etcd/pkg/ioutil", + "Comment": "v3.1.5", "Rev": "20490caaf0dcd96bb4a95e40625559def8ef5b04" }, { "ImportPath": "github.com/coreos/etcd/pkg/logutil", + "Comment": "v3.1.5", "Rev": "20490caaf0dcd96bb4a95e40625559def8ef5b04" }, { "ImportPath": "github.com/coreos/etcd/pkg/monotime", + "Comment": "v3.1.5", "Rev": "20490caaf0dcd96bb4a95e40625559def8ef5b04" }, { "ImportPath": "github.com/coreos/etcd/pkg/netutil", + "Comment": "v3.1.5", "Rev": "20490caaf0dcd96bb4a95e40625559def8ef5b04" }, { "ImportPath": "github.com/coreos/etcd/pkg/pathutil", + "Comment": "v3.1.5", "Rev": "20490caaf0dcd96bb4a95e40625559def8ef5b04" }, { "ImportPath": "github.com/coreos/etcd/pkg/pbutil", + "Comment": "v3.1.5", "Rev": "20490caaf0dcd96bb4a95e40625559def8ef5b04" }, { "ImportPath": "github.com/coreos/etcd/pkg/runtime", + "Comment": "v3.1.5", "Rev": "20490caaf0dcd96bb4a95e40625559def8ef5b04" }, { "ImportPath": "github.com/coreos/etcd/pkg/schedule", + "Comment": "v3.1.5", "Rev": "20490caaf0dcd96bb4a95e40625559def8ef5b04" }, { "ImportPath": "github.com/coreos/etcd/pkg/testutil", + "Comment": "v3.1.5", "Rev": "20490caaf0dcd96bb4a95e40625559def8ef5b04" }, { "ImportPath": "github.com/coreos/etcd/pkg/tlsutil", + "Comment": "v3.1.5", "Rev": "20490caaf0dcd96bb4a95e40625559def8ef5b04" }, { "ImportPath": "github.com/coreos/etcd/pkg/transport", + "Comment": "v3.1.5", "Rev": "20490caaf0dcd96bb4a95e40625559def8ef5b04" }, { "ImportPath": "github.com/coreos/etcd/pkg/types", + "Comment": "v3.1.5", "Rev": "20490caaf0dcd96bb4a95e40625559def8ef5b04" }, { "ImportPath": "github.com/coreos/etcd/pkg/wait", + "Comment": "v3.1.5", "Rev": "20490caaf0dcd96bb4a95e40625559def8ef5b04" }, { "ImportPath": "github.com/coreos/etcd/proxy/grpcproxy", + "Comment": "v3.1.5", "Rev": "20490caaf0dcd96bb4a95e40625559def8ef5b04" }, { "ImportPath": "github.com/coreos/etcd/proxy/grpcproxy/cache", + "Comment": "v3.1.5", "Rev": "20490caaf0dcd96bb4a95e40625559def8ef5b04" }, { "ImportPath": "github.com/coreos/etcd/raft", + "Comment": "v3.1.5", "Rev": "20490caaf0dcd96bb4a95e40625559def8ef5b04" }, { "ImportPath": "github.com/coreos/etcd/raft/raftpb", + "Comment": "v3.1.5", "Rev": "20490caaf0dcd96bb4a95e40625559def8ef5b04" }, { "ImportPath": "github.com/coreos/etcd/rafthttp", + "Comment": "v3.1.5", "Rev": "20490caaf0dcd96bb4a95e40625559def8ef5b04" }, { "ImportPath": "github.com/coreos/etcd/snap", + "Comment": "v3.1.5", "Rev": "20490caaf0dcd96bb4a95e40625559def8ef5b04" }, { "ImportPath": "github.com/coreos/etcd/snap/snappb", + "Comment": "v3.1.5", "Rev": "20490caaf0dcd96bb4a95e40625559def8ef5b04" }, { "ImportPath": "github.com/coreos/etcd/store", + "Comment": "v3.1.5", "Rev": "20490caaf0dcd96bb4a95e40625559def8ef5b04" }, { "ImportPath": "github.com/coreos/etcd/version", + "Comment": "v3.1.5", "Rev": "20490caaf0dcd96bb4a95e40625559def8ef5b04" }, { "ImportPath": "github.com/coreos/etcd/wal", + "Comment": "v3.1.5", "Rev": "20490caaf0dcd96bb4a95e40625559def8ef5b04" }, { "ImportPath": "github.com/coreos/etcd/wal/walpb", + "Comment": "v3.1.5", "Rev": "20490caaf0dcd96bb4a95e40625559def8ef5b04" }, { @@ -276,26 +335,32 @@ }, { "ImportPath": "github.com/coreos/go-systemd/daemon", + "Comment": "v14", "Rev": "48702e0da86bd25e76cfef347e2adeb434a0d0a6" }, { "ImportPath": "github.com/coreos/go-systemd/journal", + "Comment": "v14", "Rev": "48702e0da86bd25e76cfef347e2adeb434a0d0a6" }, { "ImportPath": "github.com/coreos/pkg/capnslog", + "Comment": "v2-8-gfa29b1d", "Rev": "fa29b1d70f0beaddd4c7021607cc3c3be8ce94b8" }, { "ImportPath": "github.com/coreos/pkg/health", + "Comment": "v2-8-gfa29b1d", "Rev": "fa29b1d70f0beaddd4c7021607cc3c3be8ce94b8" }, { "ImportPath": "github.com/coreos/pkg/httputil", + "Comment": "v2-8-gfa29b1d", "Rev": "fa29b1d70f0beaddd4c7021607cc3c3be8ce94b8" }, { "ImportPath": "github.com/coreos/pkg/timeutil", + "Comment": "v2-8-gfa29b1d", "Rev": "fa29b1d70f0beaddd4c7021607cc3c3be8ce94b8" }, { @@ -304,10 +369,12 @@ }, { "ImportPath": "github.com/docker/distribution/digest", + "Comment": "v2.4.0-rc.1-38-gcd27f17", "Rev": "cd27f179f2c10c5d300e6d09025b538c475b0d51" }, { "ImportPath": "github.com/docker/distribution/reference", + "Comment": "v2.4.0-rc.1-38-gcd27f17", "Rev": "cd27f179f2c10c5d300e6d09025b538c475b0d51" }, { @@ -316,14 +383,17 @@ }, { "ImportPath": "github.com/emicklei/go-restful", + "Comment": "v1.2-96-g09691a3", "Rev": "09691a3b6378b740595c1002f40c34dd5f218a22" }, { "ImportPath": "github.com/emicklei/go-restful/log", + "Comment": "v1.2-96-g09691a3", "Rev": "09691a3b6378b740595c1002f40c34dd5f218a22" }, { "ImportPath": "github.com/emicklei/go-restful/swagger", + "Comment": "v1.2-96-g09691a3", "Rev": "09691a3b6378b740595c1002f40c34dd5f218a22" }, { @@ -352,10 +422,12 @@ }, { "ImportPath": "github.com/gogo/protobuf/proto", + "Comment": "v0.4-3-gc0656ed", "Rev": "c0656edd0d9eab7c66d1eb0c568f9039345796f7" }, { "ImportPath": "github.com/gogo/protobuf/sortkeys", + "Comment": "v0.4-3-gc0656ed", "Rev": "c0656edd0d9eab7c66d1eb0c568f9039345796f7" }, { @@ -412,18 +484,22 @@ }, { "ImportPath": "github.com/grpc-ecosystem/go-grpc-prometheus", + "Comment": "v1.1-4-g2500245", "Rev": "2500245aa6110c562d17020fb31a2c133d737799" }, { "ImportPath": "github.com/grpc-ecosystem/grpc-gateway/runtime", + "Comment": "v1.1.0-25-g84398b9", "Rev": "84398b94e188ee336f307779b57b3aa91af7063c" }, { "ImportPath": "github.com/grpc-ecosystem/grpc-gateway/runtime/internal", + "Comment": "v1.1.0-25-g84398b9", "Rev": "84398b94e188ee336f307779b57b3aa91af7063c" }, { "ImportPath": "github.com/grpc-ecosystem/grpc-gateway/utilities", + "Comment": "v1.1.0-25-g84398b9", "Rev": "84398b94e188ee336f307779b57b3aa91af7063c" }, { @@ -432,6 +508,7 @@ }, { "ImportPath": "github.com/imdario/mergo", + "Comment": "0.1.3-8-g6633656", "Rev": "6633656539c1639d9d78127b7d47c622b5d7b6dc" }, { @@ -444,6 +521,7 @@ }, { "ImportPath": "github.com/karlseguin/ccache", + "Comment": "v2.0.2-5-g3ba9789", "Rev": "3ba9789cfd2cb7b4fb4657efc994cc1c599a648c" }, { @@ -472,6 +550,7 @@ }, { "ImportPath": "github.com/pkg/errors", + "Comment": "v0.7.0-13-ga221380", "Rev": "a22138067af1c4942683050411a841ade67fe1eb" }, { @@ -480,10 +559,12 @@ }, { "ImportPath": "github.com/prometheus/client_golang/prometheus", + "Comment": "0.7.0-52-ge51041b", "Rev": "e51041b3fa41cece0dca035740ba6411905be473" }, { "ImportPath": "github.com/prometheus/client_model/go", + "Comment": "model-0.0.2-12-gfa8ad6f", "Rev": "fa8ad6fec33561be4280a8f0514318c79d7f6cb6" }, { @@ -504,10 +585,12 @@ }, { "ImportPath": "github.com/stretchr/testify/assert", + "Comment": "v1.0-88-ge3a8ff8", "Rev": "e3a8ff8ce36581f87a15341206f205b1da467059" }, { "ImportPath": "github.com/stretchr/testify/require", + "Comment": "v1.0-88-ge3a8ff8", "Rev": "e3a8ff8ce36581f87a15341206f205b1da467059" }, { @@ -620,51 +703,985 @@ }, { "ImportPath": "google.golang.org/grpc", + "Comment": "v1.0.4", "Rev": "777daa17ff9b5daef1cfdf915088a2ada3332bf0" }, { "ImportPath": "google.golang.org/grpc/codes", + "Comment": "v1.0.4", "Rev": "777daa17ff9b5daef1cfdf915088a2ada3332bf0" }, { "ImportPath": "google.golang.org/grpc/credentials", + "Comment": "v1.0.4", "Rev": "777daa17ff9b5daef1cfdf915088a2ada3332bf0" }, { "ImportPath": "google.golang.org/grpc/grpclog", + "Comment": "v1.0.4", "Rev": "777daa17ff9b5daef1cfdf915088a2ada3332bf0" }, { "ImportPath": "google.golang.org/grpc/internal", + "Comment": "v1.0.4", "Rev": "777daa17ff9b5daef1cfdf915088a2ada3332bf0" }, { "ImportPath": "google.golang.org/grpc/metadata", + "Comment": "v1.0.4", "Rev": "777daa17ff9b5daef1cfdf915088a2ada3332bf0" }, { "ImportPath": "google.golang.org/grpc/naming", + "Comment": "v1.0.4", "Rev": "777daa17ff9b5daef1cfdf915088a2ada3332bf0" }, { "ImportPath": "google.golang.org/grpc/peer", + "Comment": "v1.0.4", "Rev": "777daa17ff9b5daef1cfdf915088a2ada3332bf0" }, { "ImportPath": "google.golang.org/grpc/transport", + "Comment": "v1.0.4", "Rev": "777daa17ff9b5daef1cfdf915088a2ada3332bf0" }, { "ImportPath": "gopkg.in/inf.v0", + "Comment": "v0.9.0", "Rev": "3887ee99ecf07df5b447e9b00d9c0b2adaa9f3e4" }, { "ImportPath": "gopkg.in/natefinch/lumberjack.v2", + "Comment": "v1.0-16-g20b71e5", "Rev": "20b71e5b60d756d3d2f80def009790325acc2b23" }, { "ImportPath": "gopkg.in/yaml.v2", "Rev": "53feefa2559fb8dfa8d81baad31be332c97d6c77" + }, + { + "ImportPath": "k8s.io/apimachinery/pkg/api/equality", + "Rev": "fbd6803372f831e58b86c78d07421637a64ad768" + }, + { + "ImportPath": "k8s.io/apimachinery/pkg/api/errors", + "Rev": "fbd6803372f831e58b86c78d07421637a64ad768" + }, + { + "ImportPath": "k8s.io/apimachinery/pkg/api/meta", + "Rev": "fbd6803372f831e58b86c78d07421637a64ad768" + }, + { + "ImportPath": "k8s.io/apimachinery/pkg/api/resource", + "Rev": "fbd6803372f831e58b86c78d07421637a64ad768" + }, + { + "ImportPath": "k8s.io/apimachinery/pkg/api/testing", + "Rev": "fbd6803372f831e58b86c78d07421637a64ad768" + }, + { + "ImportPath": "k8s.io/apimachinery/pkg/api/validation", + "Rev": "fbd6803372f831e58b86c78d07421637a64ad768" + }, + { + "ImportPath": "k8s.io/apimachinery/pkg/api/validation/path", + "Rev": "fbd6803372f831e58b86c78d07421637a64ad768" + }, + { + "ImportPath": "k8s.io/apimachinery/pkg/apimachinery", + "Rev": "fbd6803372f831e58b86c78d07421637a64ad768" + }, + { + "ImportPath": "k8s.io/apimachinery/pkg/apimachinery/announced", + "Rev": "fbd6803372f831e58b86c78d07421637a64ad768" + }, + { + "ImportPath": "k8s.io/apimachinery/pkg/apimachinery/registered", + "Rev": "fbd6803372f831e58b86c78d07421637a64ad768" + }, + { + "ImportPath": "k8s.io/apimachinery/pkg/apis/meta/internalversion", + "Rev": "fbd6803372f831e58b86c78d07421637a64ad768" + }, + { + "ImportPath": "k8s.io/apimachinery/pkg/apis/meta/v1", + "Rev": "fbd6803372f831e58b86c78d07421637a64ad768" + }, + { + "ImportPath": "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured", + "Rev": "fbd6803372f831e58b86c78d07421637a64ad768" + }, + { + "ImportPath": "k8s.io/apimachinery/pkg/apis/meta/v1/validation", + "Rev": "fbd6803372f831e58b86c78d07421637a64ad768" + }, + { + "ImportPath": "k8s.io/apimachinery/pkg/conversion", + "Rev": "fbd6803372f831e58b86c78d07421637a64ad768" + }, + { + "ImportPath": "k8s.io/apimachinery/pkg/conversion/queryparams", + "Rev": "fbd6803372f831e58b86c78d07421637a64ad768" + }, + { + "ImportPath": "k8s.io/apimachinery/pkg/conversion/unstructured", + "Rev": "fbd6803372f831e58b86c78d07421637a64ad768" + }, + { + "ImportPath": "k8s.io/apimachinery/pkg/fields", + "Rev": "fbd6803372f831e58b86c78d07421637a64ad768" + }, + { + "ImportPath": "k8s.io/apimachinery/pkg/labels", + "Rev": "fbd6803372f831e58b86c78d07421637a64ad768" + }, + { + "ImportPath": "k8s.io/apimachinery/pkg/openapi", + "Rev": "fbd6803372f831e58b86c78d07421637a64ad768" + }, + { + "ImportPath": "k8s.io/apimachinery/pkg/runtime", + "Rev": "fbd6803372f831e58b86c78d07421637a64ad768" + }, + { + "ImportPath": "k8s.io/apimachinery/pkg/runtime/schema", + "Rev": "fbd6803372f831e58b86c78d07421637a64ad768" + }, + { + "ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer", + "Rev": "fbd6803372f831e58b86c78d07421637a64ad768" + }, + { + "ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer/json", + "Rev": "fbd6803372f831e58b86c78d07421637a64ad768" + }, + { + "ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer/protobuf", + "Rev": "fbd6803372f831e58b86c78d07421637a64ad768" + }, + { + "ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer/recognizer", + "Rev": "fbd6803372f831e58b86c78d07421637a64ad768" + }, + { + "ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer/streaming", + "Rev": "fbd6803372f831e58b86c78d07421637a64ad768" + }, + { + "ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer/versioning", + "Rev": "fbd6803372f831e58b86c78d07421637a64ad768" + }, + { + "ImportPath": "k8s.io/apimachinery/pkg/selection", + "Rev": "fbd6803372f831e58b86c78d07421637a64ad768" + }, + { + "ImportPath": "k8s.io/apimachinery/pkg/types", + "Rev": "fbd6803372f831e58b86c78d07421637a64ad768" + }, + { + "ImportPath": "k8s.io/apimachinery/pkg/util/diff", + "Rev": "fbd6803372f831e58b86c78d07421637a64ad768" + }, + { + "ImportPath": "k8s.io/apimachinery/pkg/util/errors", + "Rev": "fbd6803372f831e58b86c78d07421637a64ad768" + }, + { + "ImportPath": "k8s.io/apimachinery/pkg/util/framer", + "Rev": "fbd6803372f831e58b86c78d07421637a64ad768" + }, + { + "ImportPath": "k8s.io/apimachinery/pkg/util/httpstream", + "Rev": "fbd6803372f831e58b86c78d07421637a64ad768" + }, + { + "ImportPath": "k8s.io/apimachinery/pkg/util/intstr", + "Rev": "fbd6803372f831e58b86c78d07421637a64ad768" + }, + { + "ImportPath": "k8s.io/apimachinery/pkg/util/json", + "Rev": "fbd6803372f831e58b86c78d07421637a64ad768" + }, + { + "ImportPath": "k8s.io/apimachinery/pkg/util/mergepatch", + "Rev": "fbd6803372f831e58b86c78d07421637a64ad768" + }, + { + "ImportPath": "k8s.io/apimachinery/pkg/util/net", + "Rev": "fbd6803372f831e58b86c78d07421637a64ad768" + }, + { + "ImportPath": "k8s.io/apimachinery/pkg/util/rand", + "Rev": "fbd6803372f831e58b86c78d07421637a64ad768" + }, + { + "ImportPath": "k8s.io/apimachinery/pkg/util/runtime", + "Rev": "fbd6803372f831e58b86c78d07421637a64ad768" + }, + { + "ImportPath": "k8s.io/apimachinery/pkg/util/sets", + "Rev": "fbd6803372f831e58b86c78d07421637a64ad768" + }, + { + "ImportPath": "k8s.io/apimachinery/pkg/util/strategicpatch", + "Rev": "fbd6803372f831e58b86c78d07421637a64ad768" + }, + { + "ImportPath": "k8s.io/apimachinery/pkg/util/uuid", + "Rev": "fbd6803372f831e58b86c78d07421637a64ad768" + }, + { + "ImportPath": "k8s.io/apimachinery/pkg/util/validation", + "Rev": "fbd6803372f831e58b86c78d07421637a64ad768" + }, + { + "ImportPath": "k8s.io/apimachinery/pkg/util/validation/field", + "Rev": "fbd6803372f831e58b86c78d07421637a64ad768" + }, + { + "ImportPath": "k8s.io/apimachinery/pkg/util/wait", + "Rev": "fbd6803372f831e58b86c78d07421637a64ad768" + }, + { + "ImportPath": "k8s.io/apimachinery/pkg/util/yaml", + "Rev": "fbd6803372f831e58b86c78d07421637a64ad768" + }, + { + "ImportPath": "k8s.io/apimachinery/pkg/version", + "Rev": "fbd6803372f831e58b86c78d07421637a64ad768" + }, + { + "ImportPath": "k8s.io/apimachinery/pkg/watch", + "Rev": "fbd6803372f831e58b86c78d07421637a64ad768" + }, + { + "ImportPath": "k8s.io/apimachinery/third_party/forked/golang/json", + "Rev": "fbd6803372f831e58b86c78d07421637a64ad768" + }, + { + "ImportPath": "k8s.io/apimachinery/third_party/forked/golang/netutil", + "Rev": "fbd6803372f831e58b86c78d07421637a64ad768" + }, + { + "ImportPath": "k8s.io/apimachinery/third_party/forked/golang/reflect", + "Rev": "fbd6803372f831e58b86c78d07421637a64ad768" + }, + { + "ImportPath": "k8s.io/client-go/discovery", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/discovery/fake", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/informers", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/informers/apps", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/informers/apps/v1beta1", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/informers/autoscaling", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/informers/autoscaling/v1", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/informers/autoscaling/v2alpha1", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/informers/batch", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/informers/batch/v1", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/informers/batch/v2alpha1", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/informers/certificates", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/informers/certificates/v1beta1", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/informers/core", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/informers/core/v1", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/informers/extensions", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/informers/extensions/v1beta1", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/informers/internalinterfaces", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/informers/policy", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/informers/policy/v1beta1", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/informers/rbac", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/informers/rbac/v1alpha1", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/informers/rbac/v1beta1", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/informers/settings", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/informers/settings/v1alpha1", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/informers/storage", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/informers/storage/v1", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/informers/storage/v1beta1", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/kubernetes", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/kubernetes/fake", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/kubernetes/scheme", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/kubernetes/typed/apps/v1beta1", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/kubernetes/typed/apps/v1beta1/fake", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/kubernetes/typed/authentication/v1", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/kubernetes/typed/authentication/v1/fake", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/kubernetes/typed/authentication/v1beta1", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/kubernetes/typed/authentication/v1beta1/fake", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/kubernetes/typed/authorization/v1", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/kubernetes/typed/authorization/v1/fake", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/kubernetes/typed/authorization/v1beta1", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/kubernetes/typed/authorization/v1beta1/fake", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/kubernetes/typed/autoscaling/v1", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/kubernetes/typed/autoscaling/v1/fake", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/kubernetes/typed/autoscaling/v2alpha1", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/kubernetes/typed/autoscaling/v2alpha1/fake", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/kubernetes/typed/batch/v1", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/kubernetes/typed/batch/v1/fake", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/kubernetes/typed/batch/v2alpha1", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/kubernetes/typed/batch/v2alpha1/fake", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/kubernetes/typed/certificates/v1beta1", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/kubernetes/typed/certificates/v1beta1/fake", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/kubernetes/typed/core/v1", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/kubernetes/typed/core/v1/fake", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/kubernetes/typed/extensions/v1beta1", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/kubernetes/typed/extensions/v1beta1/fake", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/kubernetes/typed/policy/v1beta1", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/kubernetes/typed/policy/v1beta1/fake", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/kubernetes/typed/rbac/v1alpha1", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/kubernetes/typed/rbac/v1alpha1/fake", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/kubernetes/typed/rbac/v1beta1", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/kubernetes/typed/rbac/v1beta1/fake", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/kubernetes/typed/settings/v1alpha1", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/kubernetes/typed/settings/v1alpha1/fake", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/kubernetes/typed/storage/v1", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/kubernetes/typed/storage/v1/fake", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/kubernetes/typed/storage/v1beta1", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/kubernetes/typed/storage/v1beta1/fake", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/listers/apps/v1beta1", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/listers/autoscaling/v1", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/listers/autoscaling/v2alpha1", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/listers/batch/v1", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/listers/batch/v2alpha1", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/listers/certificates/v1beta1", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/listers/core/v1", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/listers/extensions/v1beta1", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/listers/policy/v1beta1", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/listers/rbac/v1alpha1", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/listers/rbac/v1beta1", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/listers/settings/v1alpha1", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/listers/storage/v1", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/listers/storage/v1beta1", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/pkg/api", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/pkg/api/helper", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/pkg/api/install", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/pkg/api/v1", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/pkg/apis/apps", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/pkg/apis/apps/install", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/pkg/apis/apps/v1beta1", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/pkg/apis/authentication", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/pkg/apis/authentication/install", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/pkg/apis/authentication/v1", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/pkg/apis/authentication/v1beta1", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/pkg/apis/authorization", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/pkg/apis/authorization/install", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/pkg/apis/authorization/v1", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/pkg/apis/authorization/v1beta1", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/pkg/apis/autoscaling", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/pkg/apis/autoscaling/install", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/pkg/apis/autoscaling/v1", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/pkg/apis/autoscaling/v2alpha1", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/pkg/apis/batch", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/pkg/apis/batch/install", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/pkg/apis/batch/v1", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/pkg/apis/batch/v2alpha1", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/pkg/apis/certificates", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/pkg/apis/certificates/install", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/pkg/apis/certificates/v1beta1", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/pkg/apis/extensions", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/pkg/apis/extensions/install", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/pkg/apis/extensions/v1beta1", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/pkg/apis/policy", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/pkg/apis/policy/install", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/pkg/apis/policy/v1beta1", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/pkg/apis/rbac", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/pkg/apis/rbac/install", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/pkg/apis/rbac/v1alpha1", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/pkg/apis/rbac/v1beta1", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/pkg/apis/settings", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/pkg/apis/settings/install", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/pkg/apis/settings/v1alpha1", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/pkg/apis/storage", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/pkg/apis/storage/install", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/pkg/apis/storage/v1", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/pkg/apis/storage/v1beta1", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/pkg/util", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/pkg/util/parsers", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/pkg/version", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/rest", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/rest/watch", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/testing", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/tools/auth", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/tools/cache", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/tools/clientcmd", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/tools/clientcmd/api", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/tools/clientcmd/api/latest", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/tools/clientcmd/api/v1", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/tools/metrics", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/transport", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/util/cert", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/util/clock", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/util/flowcontrol", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/util/homedir", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" + }, + { + "ImportPath": "k8s.io/client-go/util/integer", + "Comment": "v2.0.0-alpha.0-165-g5b0e11b", + "Rev": "5b0e11b577b35539f05523c47e94ed96a17f992b" } ] } 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 bafa775d5..c6e2a12a7 100644 --- a/vendor/github.com/coreos/etcd/auth/authpb/auth.pb.go +++ b/vendor/github.com/coreos/etcd/auth/authpb/auth.pb.go @@ -32,7 +32,9 @@ var _ = math.Inf // This is a compile-time assertion to ensure that this generated file // is compatible with the proto package it is being compiled against. -const _ = proto.ProtoPackageIsVersion1 +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package type Permission_Type int32 @@ -99,113 +101,113 @@ func init() { proto.RegisterType((*Role)(nil), "authpb.Role") proto.RegisterEnum("authpb.Permission_Type", Permission_Type_name, Permission_Type_value) } -func (m *User) Marshal() (data []byte, err error) { +func (m *User) Marshal() (dAtA []byte, err error) { size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) if err != nil { return nil, err } - return data[:n], nil + return dAtA[:n], nil } -func (m *User) MarshalTo(data []byte) (int, error) { +func (m *User) MarshalTo(dAtA []byte) (int, error) { var i int _ = i var l int _ = l if len(m.Name) > 0 { - data[i] = 0xa + dAtA[i] = 0xa i++ - i = encodeVarintAuth(data, i, uint64(len(m.Name))) - i += copy(data[i:], m.Name) + i = encodeVarintAuth(dAtA, i, uint64(len(m.Name))) + i += copy(dAtA[i:], m.Name) } if len(m.Password) > 0 { - data[i] = 0x12 + dAtA[i] = 0x12 i++ - i = encodeVarintAuth(data, i, uint64(len(m.Password))) - i += copy(data[i:], m.Password) + i = encodeVarintAuth(dAtA, i, uint64(len(m.Password))) + i += copy(dAtA[i:], m.Password) } if len(m.Roles) > 0 { for _, s := range m.Roles { - data[i] = 0x1a + dAtA[i] = 0x1a i++ l = len(s) for l >= 1<<7 { - data[i] = uint8(uint64(l)&0x7f | 0x80) + dAtA[i] = uint8(uint64(l)&0x7f | 0x80) l >>= 7 i++ } - data[i] = uint8(l) + dAtA[i] = uint8(l) i++ - i += copy(data[i:], s) + i += copy(dAtA[i:], s) } } return i, nil } -func (m *Permission) Marshal() (data []byte, err error) { +func (m *Permission) Marshal() (dAtA []byte, err error) { size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) if err != nil { return nil, err } - return data[:n], nil + return dAtA[:n], nil } -func (m *Permission) MarshalTo(data []byte) (int, error) { +func (m *Permission) MarshalTo(dAtA []byte) (int, error) { var i int _ = i var l int _ = l if m.PermType != 0 { - data[i] = 0x8 + dAtA[i] = 0x8 i++ - i = encodeVarintAuth(data, i, uint64(m.PermType)) + i = encodeVarintAuth(dAtA, i, uint64(m.PermType)) } if len(m.Key) > 0 { - data[i] = 0x12 + dAtA[i] = 0x12 i++ - i = encodeVarintAuth(data, i, uint64(len(m.Key))) - i += copy(data[i:], m.Key) + i = encodeVarintAuth(dAtA, i, uint64(len(m.Key))) + i += copy(dAtA[i:], m.Key) } if len(m.RangeEnd) > 0 { - data[i] = 0x1a + dAtA[i] = 0x1a i++ - i = encodeVarintAuth(data, i, uint64(len(m.RangeEnd))) - i += copy(data[i:], m.RangeEnd) + i = encodeVarintAuth(dAtA, i, uint64(len(m.RangeEnd))) + i += copy(dAtA[i:], m.RangeEnd) } return i, nil } -func (m *Role) Marshal() (data []byte, err error) { +func (m *Role) Marshal() (dAtA []byte, err error) { size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) if err != nil { return nil, err } - return data[:n], nil + return dAtA[:n], nil } -func (m *Role) MarshalTo(data []byte) (int, error) { +func (m *Role) MarshalTo(dAtA []byte) (int, error) { var i int _ = i var l int _ = l if len(m.Name) > 0 { - data[i] = 0xa + dAtA[i] = 0xa i++ - i = encodeVarintAuth(data, i, uint64(len(m.Name))) - i += copy(data[i:], m.Name) + i = encodeVarintAuth(dAtA, i, uint64(len(m.Name))) + i += copy(dAtA[i:], m.Name) } if len(m.KeyPermission) > 0 { for _, msg := range m.KeyPermission { - data[i] = 0x12 + dAtA[i] = 0x12 i++ - i = encodeVarintAuth(data, i, uint64(msg.Size())) - n, err := msg.MarshalTo(data[i:]) + i = encodeVarintAuth(dAtA, i, uint64(msg.Size())) + n, err := msg.MarshalTo(dAtA[i:]) if err != nil { return 0, err } @@ -215,31 +217,31 @@ func (m *Role) MarshalTo(data []byte) (int, error) { return i, nil } -func encodeFixed64Auth(data []byte, offset int, v uint64) int { - data[offset] = uint8(v) - data[offset+1] = uint8(v >> 8) - data[offset+2] = uint8(v >> 16) - data[offset+3] = uint8(v >> 24) - data[offset+4] = uint8(v >> 32) - data[offset+5] = uint8(v >> 40) - data[offset+6] = uint8(v >> 48) - data[offset+7] = uint8(v >> 56) +func encodeFixed64Auth(dAtA []byte, offset int, v uint64) int { + dAtA[offset] = uint8(v) + dAtA[offset+1] = uint8(v >> 8) + dAtA[offset+2] = uint8(v >> 16) + dAtA[offset+3] = uint8(v >> 24) + dAtA[offset+4] = uint8(v >> 32) + dAtA[offset+5] = uint8(v >> 40) + dAtA[offset+6] = uint8(v >> 48) + dAtA[offset+7] = uint8(v >> 56) return offset + 8 } -func encodeFixed32Auth(data []byte, offset int, v uint32) int { - data[offset] = uint8(v) - data[offset+1] = uint8(v >> 8) - data[offset+2] = uint8(v >> 16) - data[offset+3] = uint8(v >> 24) +func encodeFixed32Auth(dAtA []byte, offset int, v uint32) int { + dAtA[offset] = uint8(v) + dAtA[offset+1] = uint8(v >> 8) + dAtA[offset+2] = uint8(v >> 16) + dAtA[offset+3] = uint8(v >> 24) return offset + 4 } -func encodeVarintAuth(data []byte, offset int, v uint64) int { +func encodeVarintAuth(dAtA []byte, offset int, v uint64) int { for v >= 1<<7 { - data[offset] = uint8(v&0x7f | 0x80) + dAtA[offset] = uint8(v&0x7f | 0x80) v >>= 7 offset++ } - data[offset] = uint8(v) + dAtA[offset] = uint8(v) return offset + 1 } func (m *User) Size() (n int) { @@ -308,8 +310,8 @@ func sovAuth(x uint64) (n int) { func sozAuth(x uint64) (n int) { return sovAuth(uint64((x << 1) ^ uint64((int64(x) >> 63)))) } -func (m *User) Unmarshal(data []byte) error { - l := len(data) +func (m *User) Unmarshal(dAtA []byte) error { + l := len(dAtA) iNdEx := 0 for iNdEx < l { preIndex := iNdEx @@ -321,7 +323,7 @@ func (m *User) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -349,7 +351,7 @@ func (m *User) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ byteLen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -363,7 +365,7 @@ func (m *User) Unmarshal(data []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Name = append(m.Name[:0], data[iNdEx:postIndex]...) + m.Name = append(m.Name[:0], dAtA[iNdEx:postIndex]...) if m.Name == nil { m.Name = []byte{} } @@ -380,7 +382,7 @@ func (m *User) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ byteLen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -394,7 +396,7 @@ func (m *User) Unmarshal(data []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Password = append(m.Password[:0], data[iNdEx:postIndex]...) + m.Password = append(m.Password[:0], dAtA[iNdEx:postIndex]...) if m.Password == nil { m.Password = []byte{} } @@ -411,7 +413,7 @@ func (m *User) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ stringLen |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -426,11 +428,11 @@ func (m *User) Unmarshal(data []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Roles = append(m.Roles, string(data[iNdEx:postIndex])) + m.Roles = append(m.Roles, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skipAuth(data[iNdEx:]) + skippy, err := skipAuth(dAtA[iNdEx:]) if err != nil { return err } @@ -449,8 +451,8 @@ func (m *User) Unmarshal(data []byte) error { } return nil } -func (m *Permission) Unmarshal(data []byte) error { - l := len(data) +func (m *Permission) Unmarshal(dAtA []byte) error { + l := len(dAtA) iNdEx := 0 for iNdEx < l { preIndex := iNdEx @@ -462,7 +464,7 @@ func (m *Permission) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -490,7 +492,7 @@ func (m *Permission) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ m.PermType |= (Permission_Type(b) & 0x7F) << shift if b < 0x80 { @@ -509,7 +511,7 @@ func (m *Permission) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ byteLen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -523,7 +525,7 @@ func (m *Permission) Unmarshal(data []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Key = append(m.Key[:0], data[iNdEx:postIndex]...) + m.Key = append(m.Key[:0], dAtA[iNdEx:postIndex]...) if m.Key == nil { m.Key = []byte{} } @@ -540,7 +542,7 @@ func (m *Permission) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ byteLen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -554,14 +556,14 @@ func (m *Permission) Unmarshal(data []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.RangeEnd = append(m.RangeEnd[:0], data[iNdEx:postIndex]...) + m.RangeEnd = append(m.RangeEnd[:0], dAtA[iNdEx:postIndex]...) if m.RangeEnd == nil { m.RangeEnd = []byte{} } iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skipAuth(data[iNdEx:]) + skippy, err := skipAuth(dAtA[iNdEx:]) if err != nil { return err } @@ -580,8 +582,8 @@ func (m *Permission) Unmarshal(data []byte) error { } return nil } -func (m *Role) Unmarshal(data []byte) error { - l := len(data) +func (m *Role) Unmarshal(dAtA []byte) error { + l := len(dAtA) iNdEx := 0 for iNdEx < l { preIndex := iNdEx @@ -593,7 +595,7 @@ func (m *Role) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -621,7 +623,7 @@ func (m *Role) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ byteLen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -635,7 +637,7 @@ func (m *Role) Unmarshal(data []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Name = append(m.Name[:0], data[iNdEx:postIndex]...) + m.Name = append(m.Name[:0], dAtA[iNdEx:postIndex]...) if m.Name == nil { m.Name = []byte{} } @@ -652,7 +654,7 @@ func (m *Role) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ msglen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -667,13 +669,13 @@ func (m *Role) Unmarshal(data []byte) error { return io.ErrUnexpectedEOF } m.KeyPermission = append(m.KeyPermission, &Permission{}) - if err := m.KeyPermission[len(m.KeyPermission)-1].Unmarshal(data[iNdEx:postIndex]); err != nil { + if err := m.KeyPermission[len(m.KeyPermission)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skipAuth(data[iNdEx:]) + skippy, err := skipAuth(dAtA[iNdEx:]) if err != nil { return err } @@ -692,8 +694,8 @@ func (m *Role) Unmarshal(data []byte) error { } return nil } -func skipAuth(data []byte) (n int, err error) { - l := len(data) +func skipAuth(dAtA []byte) (n int, err error) { + l := len(dAtA) iNdEx := 0 for iNdEx < l { var wire uint64 @@ -704,7 +706,7 @@ func skipAuth(data []byte) (n int, err error) { if iNdEx >= l { return 0, io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -722,7 +724,7 @@ func skipAuth(data []byte) (n int, err error) { return 0, io.ErrUnexpectedEOF } iNdEx++ - if data[iNdEx-1] < 0x80 { + if dAtA[iNdEx-1] < 0x80 { break } } @@ -739,7 +741,7 @@ func skipAuth(data []byte) (n int, err error) { if iNdEx >= l { return 0, io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ length |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -762,7 +764,7 @@ func skipAuth(data []byte) (n int, err error) { if iNdEx >= l { return 0, io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ innerWire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -773,7 +775,7 @@ func skipAuth(data []byte) (n int, err error) { if innerWireType == 4 { break } - next, err := skipAuth(data[start:]) + next, err := skipAuth(dAtA[start:]) if err != nil { return 0, err } @@ -797,6 +799,8 @@ var ( ErrIntOverflowAuth = fmt.Errorf("proto: integer overflow") ) +func init() { proto.RegisterFile("auth.proto", fileDescriptorAuth) } + var fileDescriptorAuth = []byte{ // 288 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x6c, 0x90, 0xc1, 0x4a, 0xc3, 0x30, diff --git a/vendor/github.com/coreos/etcd/auth/range_perm_cache.go b/vendor/github.com/coreos/etcd/auth/range_perm_cache.go index 23db3a5a4..3cd1ad2a4 100644 --- a/vendor/github.com/coreos/etcd/auth/range_perm_cache.go +++ b/vendor/github.com/coreos/etcd/auth/range_perm_cache.go @@ -49,46 +49,37 @@ func isRangeEqual(a, b *rangePerm) bool { // removeSubsetRangePerms removes any rangePerms that are subsets of other rangePerms. // If there are equal ranges, removeSubsetRangePerms only keeps one of them. -func removeSubsetRangePerms(perms []*rangePerm) []*rangePerm { - // TODO(mitake): currently it is O(n^2), we need a better algorithm - newp := make([]*rangePerm, 0) - +// It returns a sorted rangePerm slice. +func removeSubsetRangePerms(perms []*rangePerm) (newp []*rangePerm) { + sort.Sort(RangePermSliceByBegin(perms)) + var prev *rangePerm for i := range perms { - skip := false - - for j := range perms { - if i == j { - continue - } - - if isRangeEqual(perms[i], perms[j]) { - // if ranges are equal, we only keep the first range. - if i > j { - skip = true - break - } - } else if isSubset(perms[i], perms[j]) { - // if a range is a strict subset of the other one, we skip the subset. - skip = true - break - } - } - - if skip { + if i == 0 { + prev = perms[i] + newp = append(newp, perms[i]) continue } - + if isRangeEqual(perms[i], prev) { + continue + } + if isSubset(perms[i], prev) { + continue + } + if isSubset(prev, perms[i]) { + prev = perms[i] + newp[len(newp)-1] = perms[i] + continue + } + prev = perms[i] newp = append(newp, perms[i]) } - return newp } // mergeRangePerms merges adjacent rangePerms. func mergeRangePerms(perms []*rangePerm) []*rangePerm { - merged := make([]*rangePerm, 0) + var merged []*rangePerm perms = removeSubsetRangePerms(perms) - sort.Sort(RangePermSliceByBegin(perms)) i := 0 for i < len(perms) { diff --git a/vendor/github.com/coreos/etcd/auth/simple_token.go b/vendor/github.com/coreos/etcd/auth/simple_token.go index df2a78e2a..16bb85b19 100644 --- a/vendor/github.com/coreos/etcd/auth/simple_token.go +++ b/vendor/github.com/coreos/etcd/auth/simple_token.go @@ -20,6 +20,9 @@ package auth import ( "crypto/rand" "math/big" + "strings" + "sync" + "time" ) const ( @@ -27,6 +30,73 @@ const ( defaultSimpleTokenLength = 16 ) +// var for testing purposes +var ( + simpleTokenTTL = 5 * time.Minute + simpleTokenTTLResolution = 1 * time.Second +) + +type simpleTokenTTLKeeper struct { + tokensMu sync.Mutex + tokens map[string]time.Time + stopCh chan chan struct{} + deleteTokenFunc func(string) +} + +func NewSimpleTokenTTLKeeper(deletefunc func(string)) *simpleTokenTTLKeeper { + stk := &simpleTokenTTLKeeper{ + tokens: make(map[string]time.Time), + stopCh: make(chan chan struct{}), + deleteTokenFunc: deletefunc, + } + go stk.run() + return stk +} + +func (tm *simpleTokenTTLKeeper) stop() { + waitCh := make(chan struct{}) + tm.stopCh <- waitCh + <-waitCh + close(tm.stopCh) +} + +func (tm *simpleTokenTTLKeeper) addSimpleToken(token string) { + tm.tokens[token] = time.Now().Add(simpleTokenTTL) +} + +func (tm *simpleTokenTTLKeeper) resetSimpleToken(token string) { + if _, ok := tm.tokens[token]; ok { + tm.tokens[token] = time.Now().Add(simpleTokenTTL) + } +} + +func (tm *simpleTokenTTLKeeper) deleteSimpleToken(token string) { + delete(tm.tokens, token) +} + +func (tm *simpleTokenTTLKeeper) run() { + tokenTicker := time.NewTicker(simpleTokenTTLResolution) + defer tokenTicker.Stop() + for { + select { + case <-tokenTicker.C: + nowtime := time.Now() + tm.tokensMu.Lock() + for t, tokenendtime := range tm.tokens { + if nowtime.After(tokenendtime) { + tm.deleteTokenFunc(t) + delete(tm.tokens, t) + } + } + tm.tokensMu.Unlock() + case waitCh := <-tm.stopCh: + tm.tokens = make(map[string]time.Time) + waitCh <- struct{}{} + return + } + } +} + func (as *authStore) GenSimpleToken() (string, error) { ret := make([]byte, defaultSimpleTokenLength) @@ -43,6 +113,7 @@ func (as *authStore) GenSimpleToken() (string, error) { } func (as *authStore) assignSimpleTokenToUser(username, token string) { + as.simpleTokenKeeper.tokensMu.Lock() as.simpleTokensMu.Lock() _, ok := as.simpleTokens[token] @@ -51,5 +122,23 @@ func (as *authStore) assignSimpleTokenToUser(username, token string) { } as.simpleTokens[token] = username + as.simpleTokenKeeper.addSimpleToken(token) as.simpleTokensMu.Unlock() + as.simpleTokenKeeper.tokensMu.Unlock() +} + +func (as *authStore) invalidateUser(username string) { + if as.simpleTokenKeeper == nil { + return + } + as.simpleTokenKeeper.tokensMu.Lock() + as.simpleTokensMu.Lock() + for token, name := range as.simpleTokens { + if strings.Compare(name, username) == 0 { + delete(as.simpleTokens, token) + as.simpleTokenKeeper.deleteSimpleToken(token) + } + } + as.simpleTokensMu.Unlock() + as.simpleTokenKeeper.tokensMu.Unlock() } diff --git a/vendor/github.com/coreos/etcd/auth/store.go b/vendor/github.com/coreos/etcd/auth/store.go index 0c210acb0..5f97db84e 100644 --- a/vendor/github.com/coreos/etcd/auth/store.go +++ b/vendor/github.com/coreos/etcd/auth/store.go @@ -16,9 +16,11 @@ package auth import ( "bytes" + "encoding/binary" "errors" "fmt" "sort" + "strconv" "strings" "sync" @@ -28,6 +30,7 @@ import ( "github.com/coreos/pkg/capnslog" "golang.org/x/crypto/bcrypt" "golang.org/x/net/context" + "google.golang.org/grpc/metadata" ) var ( @@ -35,6 +38,8 @@ var ( authEnabled = []byte{1} authDisabled = []byte{0} + revisionKey = []byte("authRevision") + authBucketName = []byte("auth") authUsersBucketName = []byte("authUsers") authRolesBucketName = []byte("authRoles") @@ -44,6 +49,7 @@ var ( ErrRootUserNotExist = errors.New("auth: root user does not exist") ErrRootRoleNotExist = errors.New("auth: root user does not have root role") ErrUserAlreadyExist = errors.New("auth: user already exists") + ErrUserEmpty = errors.New("auth: user name is empty") ErrUserNotFound = errors.New("auth: user not found") ErrRoleAlreadyExist = errors.New("auth: role already exists") ErrRoleNotFound = errors.New("auth: role not found") @@ -51,13 +57,26 @@ var ( ErrPermissionDenied = errors.New("auth: permission denied") ErrRoleNotGranted = errors.New("auth: role is not granted to the user") ErrPermissionNotGranted = errors.New("auth: permission is not granted to the role") + ErrAuthNotEnabled = errors.New("auth: authentication is not enabled") + ErrAuthOldRevision = errors.New("auth: revision in header is old") + ErrInvalidAuthToken = errors.New("auth: invalid auth token") + + // BcryptCost is the algorithm cost / strength for hashing auth passwords + BcryptCost = bcrypt.DefaultCost ) const ( rootUser = "root" rootRole = "root" + + revBytesLen = 8 ) +type AuthInfo struct { + Username string + Revision uint64 +} + type AuthStore interface { // AuthEnable turns on the authentication feature AuthEnable() error @@ -110,23 +129,36 @@ type AuthStore interface { // RoleList gets a list of all roles RoleList(r *pb.AuthRoleListRequest) (*pb.AuthRoleListResponse, error) - // UsernameFromToken gets a username from the given Token - UsernameFromToken(token string) (string, bool) + // AuthInfoFromToken gets a username from the given Token and current revision number + // (The revision number is used for preventing the TOCTOU problem) + AuthInfoFromToken(token string) (*AuthInfo, bool) // IsPutPermitted checks put permission of the user - IsPutPermitted(username string, key []byte) bool + IsPutPermitted(authInfo *AuthInfo, key []byte) error // IsRangePermitted checks range permission of the user - IsRangePermitted(username string, key, rangeEnd []byte) bool + IsRangePermitted(authInfo *AuthInfo, key, rangeEnd []byte) error // IsDeleteRangePermitted checks delete-range permission of the user - IsDeleteRangePermitted(username string, key, rangeEnd []byte) bool + IsDeleteRangePermitted(authInfo *AuthInfo, key, rangeEnd []byte) error // IsAdminPermitted checks admin permission of the user - IsAdminPermitted(username string) bool + IsAdminPermitted(authInfo *AuthInfo) error // GenSimpleToken produces a simple random string GenSimpleToken() (string, error) + + // Revision gets current revision of authStore + Revision() uint64 + + // CheckPassword checks a given pair of username and password is correct + CheckPassword(username, password string) (uint64, error) + + // Close does cleanup of AuthStore + Close() error + + // AuthInfoFromCtx gets AuthInfo from gRPC's context + AuthInfoFromCtx(ctx context.Context) (*AuthInfo, error) } type authStore struct { @@ -136,11 +168,33 @@ type authStore struct { rangePermCache map[string]*unifiedRangePermissions // username -> unifiedRangePermissions - simpleTokensMu sync.RWMutex - simpleTokens map[string]string // token -> username + revision uint64 + + // tokenSimple in v3.2+ + indexWaiter func(uint64) <-chan struct{} + simpleTokenKeeper *simpleTokenTTLKeeper + simpleTokensMu sync.Mutex + simpleTokens map[string]string // token -> username +} + +func newDeleterFunc(as *authStore) func(string) { + return func(t string) { + as.simpleTokensMu.Lock() + defer as.simpleTokensMu.Unlock() + if username, ok := as.simpleTokens[t]; ok { + plog.Infof("deleting token %s for user %s", t, username) + delete(as.simpleTokens, t) + } + } } func (as *authStore) AuthEnable() error { + as.enabledMu.Lock() + defer as.enabledMu.Unlock() + if as.enabled { + plog.Noticef("Authentication already enabled") + return nil + } b := as.be tx := b.BatchTx() tx.Lock() @@ -160,33 +214,64 @@ func (as *authStore) AuthEnable() error { tx.UnsafePut(authBucketName, enableFlagKey, authEnabled) - as.enabledMu.Lock() as.enabled = true - as.enabledMu.Unlock() + + as.simpleTokenKeeper = NewSimpleTokenTTLKeeper(newDeleterFunc(as)) as.rangePermCache = make(map[string]*unifiedRangePermissions) + as.revision = getRevision(tx) + plog.Noticef("Authentication enabled") return nil } func (as *authStore) AuthDisable() { + as.enabledMu.Lock() + defer as.enabledMu.Unlock() + if !as.enabled { + return + } b := as.be tx := b.BatchTx() tx.Lock() tx.UnsafePut(authBucketName, enableFlagKey, authDisabled) + as.commitRevision(tx) tx.Unlock() b.ForceCommit() - as.enabledMu.Lock() as.enabled = false - as.enabledMu.Unlock() + + as.simpleTokensMu.Lock() + as.simpleTokens = make(map[string]string) // invalidate all tokens + as.simpleTokensMu.Unlock() + if as.simpleTokenKeeper != nil { + as.simpleTokenKeeper.stop() + as.simpleTokenKeeper = nil + } plog.Noticef("Authentication disabled") } +func (as *authStore) Close() error { + as.enabledMu.Lock() + defer as.enabledMu.Unlock() + if !as.enabled { + return nil + } + if as.simpleTokenKeeper != nil { + as.simpleTokenKeeper.stop() + as.simpleTokenKeeper = nil + } + return nil +} + func (as *authStore) Authenticate(ctx context.Context, username, password string) (*pb.AuthenticateResponse, error) { + if !as.isAuthEnabled() { + return nil, ErrAuthNotEnabled + } + // TODO(mitake): after adding jwt support, branching based on values of ctx is required index := ctx.Value("index").(uint64) simpleToken := ctx.Value("simpleToken").(string) @@ -200,11 +285,6 @@ func (as *authStore) Authenticate(ctx context.Context, username, password string return nil, ErrAuthFailed } - if bcrypt.CompareHashAndPassword(user.Password, []byte(password)) != nil { - plog.Noticef("authentication failed, invalid password for user %s", username) - return &pb.AuthenticateResponse{}, ErrAuthFailed - } - token := fmt.Sprintf("%s.%d", simpleToken, index) as.assignSimpleTokenToUser(username, token) @@ -212,6 +292,24 @@ func (as *authStore) Authenticate(ctx context.Context, username, password string return &pb.AuthenticateResponse{Token: token}, nil } +func (as *authStore) CheckPassword(username, password string) (uint64, error) { + tx := as.be.BatchTx() + tx.Lock() + defer tx.Unlock() + + user := getUser(tx, username) + if user == nil { + return 0, ErrAuthFailed + } + + if bcrypt.CompareHashAndPassword(user.Password, []byte(password)) != nil { + plog.Noticef("authentication failed, invalid password for user %s", username) + return 0, ErrAuthFailed + } + + return getRevision(tx), nil +} + func (as *authStore) Recover(be backend.Backend) { enabled := false as.be = be @@ -223,6 +321,9 @@ func (as *authStore) Recover(be backend.Backend) { enabled = true } } + + as.revision = getRevision(tx) + tx.Unlock() as.enabledMu.Lock() @@ -231,7 +332,11 @@ func (as *authStore) Recover(be backend.Backend) { } func (as *authStore) UserAdd(r *pb.AuthUserAddRequest) (*pb.AuthUserAddResponse, error) { - hashed, err := bcrypt.GenerateFromPassword([]byte(r.Password), bcrypt.DefaultCost) + if len(r.Name) == 0 { + return nil, ErrUserEmpty + } + + hashed, err := bcrypt.GenerateFromPassword([]byte(r.Password), BcryptCost) if err != nil { plog.Errorf("failed to hash password: %s", err) return nil, err @@ -253,6 +358,8 @@ func (as *authStore) UserAdd(r *pb.AuthUserAddRequest) (*pb.AuthUserAddResponse, putUser(tx, newUser) + as.commitRevision(tx) + plog.Noticef("added a new user: %s", r.Name) return &pb.AuthUserAddResponse{}, nil @@ -270,6 +377,11 @@ func (as *authStore) UserDelete(r *pb.AuthUserDeleteRequest) (*pb.AuthUserDelete delUser(tx, r.Name) + as.commitRevision(tx) + + as.invalidateCachedPerm(r.Name) + as.invalidateUser(r.Name) + plog.Noticef("deleted a user: %s", r.Name) return &pb.AuthUserDeleteResponse{}, nil @@ -278,7 +390,7 @@ func (as *authStore) UserDelete(r *pb.AuthUserDeleteRequest) (*pb.AuthUserDelete func (as *authStore) UserChangePassword(r *pb.AuthUserChangePasswordRequest) (*pb.AuthUserChangePasswordResponse, error) { // TODO(mitake): measure the cost of bcrypt.GenerateFromPassword() // If the cost is too high, we should move the encryption to outside of the raft - hashed, err := bcrypt.GenerateFromPassword([]byte(r.Password), bcrypt.DefaultCost) + hashed, err := bcrypt.GenerateFromPassword([]byte(r.Password), BcryptCost) if err != nil { plog.Errorf("failed to hash password: %s", err) return nil, err @@ -301,6 +413,11 @@ func (as *authStore) UserChangePassword(r *pb.AuthUserChangePasswordRequest) (*p putUser(tx, updatedUser) + as.commitRevision(tx) + + as.invalidateCachedPerm(r.Name) + as.invalidateUser(r.Name) + plog.Noticef("changed a password of a user: %s", r.Name) return &pb.AuthUserChangePasswordResponse{}, nil @@ -336,6 +453,8 @@ func (as *authStore) UserGrantRole(r *pb.AuthUserGrantRoleRequest) (*pb.AuthUser as.invalidateCachedPerm(r.User) + as.commitRevision(tx) + plog.Noticef("granted role %s to user %s", r.Role, r.User) return &pb.AuthUserGrantRoleResponse{}, nil } @@ -351,11 +470,7 @@ func (as *authStore) UserGet(r *pb.AuthUserGetRequest) (*pb.AuthUserGetResponse, if user == nil { return nil, ErrUserNotFound } - - for _, role := range user.Roles { - resp.Roles = append(resp.Roles, role) - } - + resp.Roles = append(resp.Roles, user.Roles...) return &resp, nil } @@ -404,6 +519,8 @@ func (as *authStore) UserRevokeRole(r *pb.AuthUserRevokeRoleRequest) (*pb.AuthUs as.invalidateCachedPerm(r.Name) + as.commitRevision(tx) + plog.Noticef("revoked role %s from user %s", r.Role, r.Name) return &pb.AuthUserRevokeRoleResponse{}, nil } @@ -419,11 +536,7 @@ func (as *authStore) RoleGet(r *pb.AuthRoleGetRequest) (*pb.AuthRoleGetResponse, if role == nil { return nil, ErrRoleNotFound } - - for _, perm := range role.KeyPermission { - resp.Perm = append(resp.Perm, perm) - } - + resp.Perm = append(resp.Perm, role.KeyPermission...) return &resp, nil } @@ -473,6 +586,8 @@ func (as *authStore) RoleRevokePermission(r *pb.AuthRoleRevokePermissionRequest) // It should be optimized. as.clearCachedPerm() + as.commitRevision(tx) + plog.Noticef("revoked key %s from role %s", r.Key, r.Role) return &pb.AuthRoleRevokePermissionResponse{}, nil } @@ -501,6 +616,8 @@ func (as *authStore) RoleDelete(r *pb.AuthRoleDeleteRequest) (*pb.AuthRoleDelete delRole(tx, r.Role) + as.commitRevision(tx) + plog.Noticef("deleted role %s", r.Role) return &pb.AuthRoleDeleteResponse{}, nil } @@ -521,16 +638,24 @@ func (as *authStore) RoleAdd(r *pb.AuthRoleAddRequest) (*pb.AuthRoleAddResponse, putRole(tx, newRole) + as.commitRevision(tx) + plog.Noticef("Role %s is created", r.Name) return &pb.AuthRoleAddResponse{}, nil } -func (as *authStore) UsernameFromToken(token string) (string, bool) { - as.simpleTokensMu.RLock() - defer as.simpleTokensMu.RUnlock() - t, ok := as.simpleTokens[token] - return t, ok +func (as *authStore) AuthInfoFromToken(token string) (*AuthInfo, bool) { + // same as '(t *tokenSimple) info' in v3.2+ + as.simpleTokenKeeper.tokensMu.Lock() + as.simpleTokensMu.Lock() + username, ok := as.simpleTokens[token] + if ok { + as.simpleTokenKeeper.resetSimpleToken(token) + } + as.simpleTokensMu.Unlock() + as.simpleTokenKeeper.tokensMu.Unlock() + return &AuthInfo{Username: username, Revision: as.revision}, ok } type permSlice []*authpb.Permission @@ -582,15 +707,26 @@ func (as *authStore) RoleGrantPermission(r *pb.AuthRoleGrantPermissionRequest) ( // It should be optimized. as.clearCachedPerm() + as.commitRevision(tx) + plog.Noticef("role %s's permission of key %s is updated as %s", r.Name, r.Perm.Key, authpb.Permission_Type_name[int32(r.Perm.PermType)]) return &pb.AuthRoleGrantPermissionResponse{}, nil } -func (as *authStore) isOpPermitted(userName string, key, rangeEnd []byte, permTyp authpb.Permission_Type) bool { +func (as *authStore) isOpPermitted(userName string, revision uint64, key, rangeEnd []byte, permTyp authpb.Permission_Type) error { // TODO(mitake): this function would be costly so we need a caching mechanism if !as.isAuthEnabled() { - return true + return nil + } + + // only gets rev == 0 when passed AuthInfo{}; no user given + if revision == 0 { + return ErrUserEmpty + } + + if revision < as.revision { + return ErrAuthOldRevision } tx := as.be.BatchTx() @@ -600,48 +736,55 @@ func (as *authStore) isOpPermitted(userName string, key, rangeEnd []byte, permTy user := getUser(tx, userName) if user == nil { plog.Errorf("invalid user name %s for permission checking", userName) - return false + return ErrPermissionDenied } // root role should have permission on all ranges if hasRootRole(user) { - return true + return nil } if as.isRangeOpPermitted(tx, userName, key, rangeEnd, permTyp) { - return true + return nil } - return false + return ErrPermissionDenied } -func (as *authStore) IsPutPermitted(username string, key []byte) bool { - return as.isOpPermitted(username, key, nil, authpb.WRITE) +func (as *authStore) IsPutPermitted(authInfo *AuthInfo, key []byte) error { + return as.isOpPermitted(authInfo.Username, authInfo.Revision, key, nil, authpb.WRITE) } -func (as *authStore) IsRangePermitted(username string, key, rangeEnd []byte) bool { - return as.isOpPermitted(username, key, rangeEnd, authpb.READ) +func (as *authStore) IsRangePermitted(authInfo *AuthInfo, key, rangeEnd []byte) error { + return as.isOpPermitted(authInfo.Username, authInfo.Revision, key, rangeEnd, authpb.READ) } -func (as *authStore) IsDeleteRangePermitted(username string, key, rangeEnd []byte) bool { - return as.isOpPermitted(username, key, rangeEnd, authpb.WRITE) +func (as *authStore) IsDeleteRangePermitted(authInfo *AuthInfo, key, rangeEnd []byte) error { + return as.isOpPermitted(authInfo.Username, authInfo.Revision, key, rangeEnd, authpb.WRITE) } -func (as *authStore) IsAdminPermitted(username string) bool { +func (as *authStore) IsAdminPermitted(authInfo *AuthInfo) error { if !as.isAuthEnabled() { - return true + return nil + } + if authInfo == nil { + return ErrUserEmpty } tx := as.be.BatchTx() tx.Lock() defer tx.Unlock() - u := getUser(tx, username) + u := getUser(tx, authInfo.Username) if u == nil { - return false + return ErrUserNotFound } - return hasRootRole(u) + if !hasRootRole(u) { + return ErrPermissionDenied + } + + return nil } func getUser(tx backend.BatchTx, username string) *authpb.User { @@ -745,7 +888,7 @@ func (as *authStore) isAuthEnabled() bool { return as.enabled } -func NewAuthStore(be backend.Backend) *authStore { +func NewAuthStore(be backend.Backend, indexWaiter func(uint64) <-chan struct{}) *authStore { tx := be.BatchTx() tx.Lock() @@ -753,13 +896,35 @@ func NewAuthStore(be backend.Backend) *authStore { tx.UnsafeCreateBucket(authUsersBucketName) tx.UnsafeCreateBucket(authRolesBucketName) + enabled := false + _, vs := tx.UnsafeRange(authBucketName, enableFlagKey, nil, 0) + if len(vs) == 1 { + if bytes.Equal(vs[0], authEnabled) { + enabled = true + } + } + + as := &authStore{ + be: be, + simpleTokens: make(map[string]string), + revision: getRevision(tx), + indexWaiter: indexWaiter, + enabled: enabled, + rangePermCache: make(map[string]*unifiedRangePermissions), + } + + if enabled { + as.simpleTokenKeeper = NewSimpleTokenTTLKeeper(newDeleterFunc(as)) + } + + if as.revision == 0 { + as.commitRevision(tx) + } + tx.Unlock() be.ForceCommit() - return &authStore{ - be: be, - simpleTokens: make(map[string]string), - } + return as } func hasRootRole(u *authpb.User) bool { @@ -770,3 +935,67 @@ func hasRootRole(u *authpb.User) bool { } return false } + +func (as *authStore) commitRevision(tx backend.BatchTx) { + as.revision++ + revBytes := make([]byte, revBytesLen) + binary.BigEndian.PutUint64(revBytes, as.revision) + tx.UnsafePut(authBucketName, revisionKey, revBytes) +} + +func getRevision(tx backend.BatchTx) uint64 { + _, vs := tx.UnsafeRange(authBucketName, []byte(revisionKey), nil, 0) + if len(vs) != 1 { + // this can happen in the initialization phase + return 0 + } + + return binary.BigEndian.Uint64(vs[0]) +} + +func (as *authStore) Revision() uint64 { + return as.revision +} + +func (as *authStore) isValidSimpleToken(token string, ctx context.Context) bool { + splitted := strings.Split(token, ".") + if len(splitted) != 2 { + return false + } + index, err := strconv.Atoi(splitted[1]) + if err != nil { + return false + } + + select { + case <-as.indexWaiter(uint64(index)): + return true + case <-ctx.Done(): + } + + return false +} + +func (as *authStore) AuthInfoFromCtx(ctx context.Context) (*AuthInfo, error) { + md, ok := metadata.FromContext(ctx) + if !ok { + return nil, nil + } + + ts, tok := md["token"] + if !tok { + return nil, nil + } + + token := ts[0] + if !as.isValidSimpleToken(token, ctx) { + return nil, ErrInvalidAuthToken + } + + authInfo, uok := as.AuthInfoFromToken(token) + if !uok { + plog.Warningf("invalid auth token: %s", token) + return nil, ErrInvalidAuthToken + } + return authInfo, nil +} diff --git a/vendor/github.com/coreos/etcd/client/README.md b/vendor/github.com/coreos/etcd/client/README.md index 0bab9589c..c0ec81901 100644 --- a/vendor/github.com/coreos/etcd/client/README.md +++ b/vendor/github.com/coreos/etcd/client/README.md @@ -114,4 +114,4 @@ if err != nil { 3. Default etcd/client cannot handle the case that the remote server is SIGSTOPed now. TCP keepalive mechanism doesn't help in this scenario because operating system may still send TCP keep-alive packets. Over time we'd like to improve this functionality, but solving this issue isn't high priority because a real-life case in which a server is stopped, but the connection is kept alive, hasn't been brought to our attention. -4. etcd/client cannot detect whether the member in use is healthy when doing read requests. If the member is isolated from the cluster, etcd/client may retrieve outdated data. As a workaround, users could monitor experimental /health endpoint for member healthy information. We are improving it at [#3265](https://github.com/coreos/etcd/issues/3265). +4. etcd/client cannot detect whether a member is healthy with watches and non-quorum read requests. If the member is isolated from the cluster, etcd/client may retrieve outdated data. Instead, users can either issue quorum read requests or monitor the /health endpoint for member health information. diff --git a/vendor/github.com/coreos/etcd/client/client.go b/vendor/github.com/coreos/etcd/client/client.go index eeeb8b57a..f9131b472 100644 --- a/vendor/github.com/coreos/etcd/client/client.go +++ b/vendor/github.com/coreos/etcd/client/client.go @@ -22,7 +22,6 @@ import ( "net" "net/http" "net/url" - "reflect" "sort" "strconv" "sync" @@ -261,53 +260,67 @@ type httpClusterClient struct { selectionMode EndpointSelectionMode } -func (c *httpClusterClient) getLeaderEndpoint() (string, error) { - mAPI := NewMembersAPI(c) - leader, err := mAPI.Leader(context.Background()) +func (c *httpClusterClient) getLeaderEndpoint(ctx context.Context, eps []url.URL) (string, error) { + ceps := make([]url.URL, len(eps)) + copy(ceps, eps) + + // To perform a lookup on the new endpoint list without using the current + // client, we'll copy it + clientCopy := &httpClusterClient{ + clientFactory: c.clientFactory, + credentials: c.credentials, + rand: c.rand, + + pinned: 0, + endpoints: ceps, + } + + mAPI := NewMembersAPI(clientCopy) + leader, err := mAPI.Leader(ctx) if err != nil { return "", err } + if len(leader.ClientURLs) == 0 { + return "", ErrNoLeaderEndpoint + } return leader.ClientURLs[0], nil // TODO: how to handle multiple client URLs? } -func (c *httpClusterClient) SetEndpoints(eps []string) error { +func (c *httpClusterClient) parseEndpoints(eps []string) ([]url.URL, error) { if len(eps) == 0 { - return ErrNoEndpoints + return []url.URL{}, ErrNoEndpoints } neps := make([]url.URL, len(eps)) for i, ep := range eps { u, err := url.Parse(ep) if err != nil { - return err + return []url.URL{}, err } neps[i] = *u } + return neps, nil +} - switch c.selectionMode { - case EndpointSelectionRandom: - c.endpoints = shuffleEndpoints(c.rand, neps) - c.pinned = 0 - case EndpointSelectionPrioritizeLeader: - c.endpoints = neps - lep, err := c.getLeaderEndpoint() - if err != nil { - return ErrNoLeaderEndpoint - } - - for i := range c.endpoints { - if c.endpoints[i].String() == lep { - c.pinned = i - break - } - } - // If endpoints doesn't have the lu, just keep c.pinned = 0. - // Forwarding between follower and leader would be required but it works. - default: - return errors.New(fmt.Sprintf("invalid endpoint selection mode: %d", c.selectionMode)) +func (c *httpClusterClient) SetEndpoints(eps []string) error { + neps, err := c.parseEndpoints(eps) + if err != nil { + return err } + c.Lock() + defer c.Unlock() + + c.endpoints = shuffleEndpoints(c.rand, neps) + // We're not doing anything for PrioritizeLeader here. This is + // due to not having a context meaning we can't call getLeaderEndpoint + // However, if you're using PrioritizeLeader, you've already been told + // to regularly call sync, where we do have a ctx, and can figure the + // leader. PrioritizeLeader is also quite a loose guarantee, so deal + // with it + c.pinned = 0 + return nil } @@ -401,27 +414,51 @@ func (c *httpClusterClient) Sync(ctx context.Context) error { return err } - c.Lock() - defer c.Unlock() - - eps := make([]string, 0) + var eps []string for _, m := range ms { eps = append(eps, m.ClientURLs...) } - sort.Sort(sort.StringSlice(eps)) - ceps := make([]string, len(c.endpoints)) - for i, cep := range c.endpoints { - ceps[i] = cep.String() - } - sort.Sort(sort.StringSlice(ceps)) - // fast path if no change happens - // this helps client to pin the endpoint when no cluster change - if reflect.DeepEqual(eps, ceps) { - return nil + neps, err := c.parseEndpoints(eps) + if err != nil { + return err } - return c.SetEndpoints(eps) + npin := 0 + + switch c.selectionMode { + case EndpointSelectionRandom: + c.RLock() + eq := endpointsEqual(c.endpoints, neps) + c.RUnlock() + + if eq { + return nil + } + // When items in the endpoint list changes, we choose a new pin + neps = shuffleEndpoints(c.rand, neps) + case EndpointSelectionPrioritizeLeader: + nle, err := c.getLeaderEndpoint(ctx, neps) + if err != nil { + return ErrNoLeaderEndpoint + } + + for i, n := range neps { + if n.String() == nle { + npin = i + break + } + } + default: + return fmt.Errorf("invalid endpoint selection mode: %d", c.selectionMode) + } + + c.Lock() + defer c.Unlock() + c.endpoints = neps + c.pinned = npin + + return nil } func (c *httpClusterClient) AutoSync(ctx context.Context, interval time.Duration) error { @@ -607,3 +644,27 @@ func shuffleEndpoints(r *rand.Rand, eps []url.URL) []url.URL { } return neps } + +func endpointsEqual(left, right []url.URL) bool { + if len(left) != len(right) { + return false + } + + sLeft := make([]string, len(left)) + sRight := make([]string, len(right)) + for i, l := range left { + sLeft[i] = l.String() + } + for i, r := range right { + sRight[i] = r.String() + } + + sort.Strings(sLeft) + sort.Strings(sRight) + for i := range sLeft { + if sLeft[i] != sRight[i] { + return false + } + } + return true +} diff --git a/vendor/github.com/coreos/etcd/client/cluster_error.go b/vendor/github.com/coreos/etcd/client/cluster_error.go index aef5bf755..34618cdbd 100644 --- a/vendor/github.com/coreos/etcd/client/cluster_error.go +++ b/vendor/github.com/coreos/etcd/client/cluster_error.go @@ -21,7 +21,11 @@ type ClusterError struct { } func (ce *ClusterError) Error() string { - return ErrClusterUnavailable.Error() + s := ErrClusterUnavailable.Error() + for i, e := range ce.Errors { + s += fmt.Sprintf("; error #%d: %s\n", i, e) + } + return s } func (ce *ClusterError) Detail() string { diff --git a/vendor/github.com/coreos/etcd/client/keys.generated.go b/vendor/github.com/coreos/etcd/client/keys.generated.go index 748283aa9..216139c9c 100644 --- a/vendor/github.com/coreos/etcd/client/keys.generated.go +++ b/vendor/github.com/coreos/etcd/client/keys.generated.go @@ -145,25 +145,25 @@ func (x *Response) CodecDecodeSelf(d *codec1978.Decoder) { var h codecSelfer1819 z, r := codec1978.GenHelperDecoder(d) _, _, _ = h, z, r - yym8 := z.DecBinary() - _ = yym8 + yym1 := z.DecBinary() + _ = yym1 if false { } else if z.HasExtensions() && z.DecExt(x) { } else { - yyct9 := r.ContainerType() - if yyct9 == codecSelferValueTypeMap1819 { - yyl9 := r.ReadMapStart() - if yyl9 == 0 { + yyct2 := r.ContainerType() + if yyct2 == codecSelferValueTypeMap1819 { + yyl2 := r.ReadMapStart() + if yyl2 == 0 { z.DecSendContainerState(codecSelfer_containerMapEnd1819) } else { - x.codecDecodeSelfFromMap(yyl9, d) + x.codecDecodeSelfFromMap(yyl2, d) } - } else if yyct9 == codecSelferValueTypeArray1819 { - yyl9 := r.ReadArrayStart() - if yyl9 == 0 { + } else if yyct2 == codecSelferValueTypeArray1819 { + yyl2 := r.ReadArrayStart() + if yyl2 == 0 { z.DecSendContainerState(codecSelfer_containerArrayEnd1819) } else { - x.codecDecodeSelfFromArray(yyl9, d) + x.codecDecodeSelfFromArray(yyl2, d) } } else { panic(codecSelferOnlyMapOrArrayEncodeToStructErr1819) @@ -175,12 +175,12 @@ func (x *Response) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) { var h codecSelfer1819 z, r := codec1978.GenHelperDecoder(d) _, _, _ = h, z, r - var yys10Slc = z.DecScratchBuffer() // default slice to decode into - _ = yys10Slc - var yyhl10 bool = l >= 0 - for yyj10 := 0; ; yyj10++ { - if yyhl10 { - if yyj10 >= l { + var yys3Slc = z.DecScratchBuffer() // default slice to decode into + _ = yys3Slc + var yyhl3 bool = l >= 0 + for yyj3 := 0; ; yyj3++ { + if yyhl3 { + if yyj3 >= l { break } } else { @@ -189,15 +189,21 @@ func (x *Response) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) { } } z.DecSendContainerState(codecSelfer_containerMapKey1819) - yys10Slc = r.DecodeBytes(yys10Slc, true, true) - yys10 := string(yys10Slc) + yys3Slc = r.DecodeBytes(yys3Slc, true, true) + yys3 := string(yys3Slc) z.DecSendContainerState(codecSelfer_containerMapValue1819) - switch yys10 { + switch yys3 { case "action": if r.TryDecodeAsNil() { x.Action = "" } else { - x.Action = string(r.DecodeString()) + yyv4 := &x.Action + yym5 := z.DecBinary() + _ = yym5 + if false { + } else { + *((*string)(yyv4)) = r.DecodeString() + } } case "node": if r.TryDecodeAsNil() { @@ -222,9 +228,9 @@ func (x *Response) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) { x.PrevNode.CodecDecodeSelf(d) } default: - z.DecStructFieldNotFound(-1, yys10) - } // end switch yys10 - } // end for yyj10 + z.DecStructFieldNotFound(-1, yys3) + } // end switch yys3 + } // end for yyj3 z.DecSendContainerState(codecSelfer_containerMapEnd1819) } @@ -232,16 +238,16 @@ func (x *Response) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { var h codecSelfer1819 z, r := codec1978.GenHelperDecoder(d) _, _, _ = h, z, r - var yyj14 int - var yyb14 bool - var yyhl14 bool = l >= 0 - yyj14++ - if yyhl14 { - yyb14 = yyj14 > l + var yyj8 int + var yyb8 bool + var yyhl8 bool = l >= 0 + yyj8++ + if yyhl8 { + yyb8 = yyj8 > l } else { - yyb14 = r.CheckBreak() + yyb8 = r.CheckBreak() } - if yyb14 { + if yyb8 { z.DecSendContainerState(codecSelfer_containerArrayEnd1819) return } @@ -249,15 +255,21 @@ func (x *Response) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { if r.TryDecodeAsNil() { x.Action = "" } else { - x.Action = string(r.DecodeString()) + yyv9 := &x.Action + yym10 := z.DecBinary() + _ = yym10 + if false { + } else { + *((*string)(yyv9)) = r.DecodeString() + } } - yyj14++ - if yyhl14 { - yyb14 = yyj14 > l + yyj8++ + if yyhl8 { + yyb8 = yyj8 > l } else { - yyb14 = r.CheckBreak() + yyb8 = r.CheckBreak() } - if yyb14 { + if yyb8 { z.DecSendContainerState(codecSelfer_containerArrayEnd1819) return } @@ -272,13 +284,13 @@ func (x *Response) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { } x.Node.CodecDecodeSelf(d) } - yyj14++ - if yyhl14 { - yyb14 = yyj14 > l + yyj8++ + if yyhl8 { + yyb8 = yyj8 > l } else { - yyb14 = r.CheckBreak() + yyb8 = r.CheckBreak() } - if yyb14 { + if yyb8 { z.DecSendContainerState(codecSelfer_containerArrayEnd1819) return } @@ -294,17 +306,17 @@ func (x *Response) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { x.PrevNode.CodecDecodeSelf(d) } for { - yyj14++ - if yyhl14 { - yyb14 = yyj14 > l + yyj8++ + if yyhl8 { + yyb8 = yyj8 > l } else { - yyb14 = r.CheckBreak() + yyb8 = r.CheckBreak() } - if yyb14 { + if yyb8 { break } z.DecSendContainerState(codecSelfer_containerArrayElem1819) - z.DecStructFieldNotFound(yyj14-1, "") + z.DecStructFieldNotFound(yyj8-1, "") } z.DecSendContainerState(codecSelfer_containerArrayEnd1819) } @@ -316,36 +328,36 @@ func (x *Node) CodecEncodeSelf(e *codec1978.Encoder) { if x == nil { r.EncodeNil() } else { - yym18 := z.EncBinary() - _ = yym18 + yym1 := z.EncBinary() + _ = yym1 if false { } else if z.HasExtensions() && z.EncExt(x) { } else { - yysep19 := !z.EncBinary() - yy2arr19 := z.EncBasicHandle().StructToArray - var yyq19 [8]bool - _, _, _ = yysep19, yyq19, yy2arr19 - const yyr19 bool = false - yyq19[1] = x.Dir != false - yyq19[6] = x.Expiration != nil - yyq19[7] = x.TTL != 0 - var yynn19 int - if yyr19 || yy2arr19 { + yysep2 := !z.EncBinary() + yy2arr2 := z.EncBasicHandle().StructToArray + var yyq2 [8]bool + _, _, _ = yysep2, yyq2, yy2arr2 + const yyr2 bool = false + yyq2[1] = x.Dir != false + yyq2[6] = x.Expiration != nil + yyq2[7] = x.TTL != 0 + var yynn2 int + if yyr2 || yy2arr2 { r.EncodeArrayStart(8) } else { - yynn19 = 5 - for _, b := range yyq19 { + yynn2 = 5 + for _, b := range yyq2 { if b { - yynn19++ + yynn2++ } } - r.EncodeMapStart(yynn19) - yynn19 = 0 + r.EncodeMapStart(yynn2) + yynn2 = 0 } - if yyr19 || yy2arr19 { + if yyr2 || yy2arr2 { z.EncSendContainerState(codecSelfer_containerArrayElem1819) - yym21 := z.EncBinary() - _ = yym21 + yym4 := z.EncBinary() + _ = yym4 if false { } else { r.EncodeString(codecSelferC_UTF81819, string(x.Key)) @@ -354,18 +366,18 @@ func (x *Node) CodecEncodeSelf(e *codec1978.Encoder) { z.EncSendContainerState(codecSelfer_containerMapKey1819) r.EncodeString(codecSelferC_UTF81819, string("key")) z.EncSendContainerState(codecSelfer_containerMapValue1819) - yym22 := z.EncBinary() - _ = yym22 + yym5 := z.EncBinary() + _ = yym5 if false { } else { r.EncodeString(codecSelferC_UTF81819, string(x.Key)) } } - if yyr19 || yy2arr19 { + if yyr2 || yy2arr2 { z.EncSendContainerState(codecSelfer_containerArrayElem1819) - if yyq19[1] { - yym24 := z.EncBinary() - _ = yym24 + if yyq2[1] { + yym7 := z.EncBinary() + _ = yym7 if false { } else { r.EncodeBool(bool(x.Dir)) @@ -374,22 +386,22 @@ func (x *Node) CodecEncodeSelf(e *codec1978.Encoder) { r.EncodeBool(false) } } else { - if yyq19[1] { + if yyq2[1] { z.EncSendContainerState(codecSelfer_containerMapKey1819) r.EncodeString(codecSelferC_UTF81819, string("dir")) z.EncSendContainerState(codecSelfer_containerMapValue1819) - yym25 := z.EncBinary() - _ = yym25 + yym8 := z.EncBinary() + _ = yym8 if false { } else { r.EncodeBool(bool(x.Dir)) } } } - if yyr19 || yy2arr19 { + if yyr2 || yy2arr2 { z.EncSendContainerState(codecSelfer_containerArrayElem1819) - yym27 := z.EncBinary() - _ = yym27 + yym10 := z.EncBinary() + _ = yym10 if false { } else { r.EncodeString(codecSelferC_UTF81819, string(x.Value)) @@ -398,14 +410,14 @@ func (x *Node) CodecEncodeSelf(e *codec1978.Encoder) { z.EncSendContainerState(codecSelfer_containerMapKey1819) r.EncodeString(codecSelferC_UTF81819, string("value")) z.EncSendContainerState(codecSelfer_containerMapValue1819) - yym28 := z.EncBinary() - _ = yym28 + yym11 := z.EncBinary() + _ = yym11 if false { } else { r.EncodeString(codecSelferC_UTF81819, string(x.Value)) } } - if yyr19 || yy2arr19 { + if yyr2 || yy2arr2 { z.EncSendContainerState(codecSelfer_containerArrayElem1819) if x.Nodes == nil { r.EncodeNil() @@ -422,10 +434,10 @@ func (x *Node) CodecEncodeSelf(e *codec1978.Encoder) { x.Nodes.CodecEncodeSelf(e) } } - if yyr19 || yy2arr19 { + if yyr2 || yy2arr2 { z.EncSendContainerState(codecSelfer_containerArrayElem1819) - yym31 := z.EncBinary() - _ = yym31 + yym16 := z.EncBinary() + _ = yym16 if false { } else { r.EncodeUint(uint64(x.CreatedIndex)) @@ -434,17 +446,17 @@ func (x *Node) CodecEncodeSelf(e *codec1978.Encoder) { z.EncSendContainerState(codecSelfer_containerMapKey1819) r.EncodeString(codecSelferC_UTF81819, string("createdIndex")) z.EncSendContainerState(codecSelfer_containerMapValue1819) - yym32 := z.EncBinary() - _ = yym32 + yym17 := z.EncBinary() + _ = yym17 if false { } else { r.EncodeUint(uint64(x.CreatedIndex)) } } - if yyr19 || yy2arr19 { + if yyr2 || yy2arr2 { z.EncSendContainerState(codecSelfer_containerArrayElem1819) - yym34 := z.EncBinary() - _ = yym34 + yym19 := z.EncBinary() + _ = yym19 if false { } else { r.EncodeUint(uint64(x.ModifiedIndex)) @@ -453,28 +465,28 @@ func (x *Node) CodecEncodeSelf(e *codec1978.Encoder) { z.EncSendContainerState(codecSelfer_containerMapKey1819) r.EncodeString(codecSelferC_UTF81819, string("modifiedIndex")) z.EncSendContainerState(codecSelfer_containerMapValue1819) - yym35 := z.EncBinary() - _ = yym35 + yym20 := z.EncBinary() + _ = yym20 if false { } else { r.EncodeUint(uint64(x.ModifiedIndex)) } } - if yyr19 || yy2arr19 { + if yyr2 || yy2arr2 { z.EncSendContainerState(codecSelfer_containerArrayElem1819) - if yyq19[6] { + if yyq2[6] { if x.Expiration == nil { r.EncodeNil() } else { - yym37 := z.EncBinary() - _ = yym37 + yym22 := z.EncBinary() + _ = yym22 if false { - } else if yym38 := z.TimeRtidIfBinc(); yym38 != 0 { - r.EncodeBuiltin(yym38, x.Expiration) + } else if yym23 := z.TimeRtidIfBinc(); yym23 != 0 { + r.EncodeBuiltin(yym23, x.Expiration) } else if z.HasExtensions() && z.EncExt(x.Expiration) { - } else if yym37 { + } else if yym22 { z.EncBinaryMarshal(x.Expiration) - } else if !yym37 && z.IsJSONHandle() { + } else if !yym22 && z.IsJSONHandle() { z.EncJSONMarshal(x.Expiration) } else { z.EncFallback(x.Expiration) @@ -484,22 +496,22 @@ func (x *Node) CodecEncodeSelf(e *codec1978.Encoder) { r.EncodeNil() } } else { - if yyq19[6] { + if yyq2[6] { z.EncSendContainerState(codecSelfer_containerMapKey1819) r.EncodeString(codecSelferC_UTF81819, string("expiration")) z.EncSendContainerState(codecSelfer_containerMapValue1819) if x.Expiration == nil { r.EncodeNil() } else { - yym39 := z.EncBinary() - _ = yym39 + yym24 := z.EncBinary() + _ = yym24 if false { - } else if yym40 := z.TimeRtidIfBinc(); yym40 != 0 { - r.EncodeBuiltin(yym40, x.Expiration) + } else if yym25 := z.TimeRtidIfBinc(); yym25 != 0 { + r.EncodeBuiltin(yym25, x.Expiration) } else if z.HasExtensions() && z.EncExt(x.Expiration) { - } else if yym39 { + } else if yym24 { z.EncBinaryMarshal(x.Expiration) - } else if !yym39 && z.IsJSONHandle() { + } else if !yym24 && z.IsJSONHandle() { z.EncJSONMarshal(x.Expiration) } else { z.EncFallback(x.Expiration) @@ -507,11 +519,11 @@ func (x *Node) CodecEncodeSelf(e *codec1978.Encoder) { } } } - if yyr19 || yy2arr19 { + if yyr2 || yy2arr2 { z.EncSendContainerState(codecSelfer_containerArrayElem1819) - if yyq19[7] { - yym42 := z.EncBinary() - _ = yym42 + if yyq2[7] { + yym27 := z.EncBinary() + _ = yym27 if false { } else { r.EncodeInt(int64(x.TTL)) @@ -520,19 +532,19 @@ func (x *Node) CodecEncodeSelf(e *codec1978.Encoder) { r.EncodeInt(0) } } else { - if yyq19[7] { + if yyq2[7] { z.EncSendContainerState(codecSelfer_containerMapKey1819) r.EncodeString(codecSelferC_UTF81819, string("ttl")) z.EncSendContainerState(codecSelfer_containerMapValue1819) - yym43 := z.EncBinary() - _ = yym43 + yym28 := z.EncBinary() + _ = yym28 if false { } else { r.EncodeInt(int64(x.TTL)) } } } - if yyr19 || yy2arr19 { + if yyr2 || yy2arr2 { z.EncSendContainerState(codecSelfer_containerArrayEnd1819) } else { z.EncSendContainerState(codecSelfer_containerMapEnd1819) @@ -545,25 +557,25 @@ func (x *Node) CodecDecodeSelf(d *codec1978.Decoder) { var h codecSelfer1819 z, r := codec1978.GenHelperDecoder(d) _, _, _ = h, z, r - yym44 := z.DecBinary() - _ = yym44 + yym1 := z.DecBinary() + _ = yym1 if false { } else if z.HasExtensions() && z.DecExt(x) { } else { - yyct45 := r.ContainerType() - if yyct45 == codecSelferValueTypeMap1819 { - yyl45 := r.ReadMapStart() - if yyl45 == 0 { + yyct2 := r.ContainerType() + if yyct2 == codecSelferValueTypeMap1819 { + yyl2 := r.ReadMapStart() + if yyl2 == 0 { z.DecSendContainerState(codecSelfer_containerMapEnd1819) } else { - x.codecDecodeSelfFromMap(yyl45, d) + x.codecDecodeSelfFromMap(yyl2, d) } - } else if yyct45 == codecSelferValueTypeArray1819 { - yyl45 := r.ReadArrayStart() - if yyl45 == 0 { + } else if yyct2 == codecSelferValueTypeArray1819 { + yyl2 := r.ReadArrayStart() + if yyl2 == 0 { z.DecSendContainerState(codecSelfer_containerArrayEnd1819) } else { - x.codecDecodeSelfFromArray(yyl45, d) + x.codecDecodeSelfFromArray(yyl2, d) } } else { panic(codecSelferOnlyMapOrArrayEncodeToStructErr1819) @@ -575,12 +587,12 @@ func (x *Node) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) { var h codecSelfer1819 z, r := codec1978.GenHelperDecoder(d) _, _, _ = h, z, r - var yys46Slc = z.DecScratchBuffer() // default slice to decode into - _ = yys46Slc - var yyhl46 bool = l >= 0 - for yyj46 := 0; ; yyj46++ { - if yyhl46 { - if yyj46 >= l { + var yys3Slc = z.DecScratchBuffer() // default slice to decode into + _ = yys3Slc + var yyhl3 bool = l >= 0 + for yyj3 := 0; ; yyj3++ { + if yyhl3 { + if yyj3 >= l { break } } else { @@ -589,46 +601,76 @@ func (x *Node) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) { } } z.DecSendContainerState(codecSelfer_containerMapKey1819) - yys46Slc = r.DecodeBytes(yys46Slc, true, true) - yys46 := string(yys46Slc) + yys3Slc = r.DecodeBytes(yys3Slc, true, true) + yys3 := string(yys3Slc) z.DecSendContainerState(codecSelfer_containerMapValue1819) - switch yys46 { + switch yys3 { case "key": if r.TryDecodeAsNil() { x.Key = "" } else { - x.Key = string(r.DecodeString()) + yyv4 := &x.Key + yym5 := z.DecBinary() + _ = yym5 + if false { + } else { + *((*string)(yyv4)) = r.DecodeString() + } } case "dir": if r.TryDecodeAsNil() { x.Dir = false } else { - x.Dir = bool(r.DecodeBool()) + yyv6 := &x.Dir + yym7 := z.DecBinary() + _ = yym7 + if false { + } else { + *((*bool)(yyv6)) = r.DecodeBool() + } } case "value": if r.TryDecodeAsNil() { x.Value = "" } else { - x.Value = string(r.DecodeString()) + yyv8 := &x.Value + yym9 := z.DecBinary() + _ = yym9 + if false { + } else { + *((*string)(yyv8)) = r.DecodeString() + } } case "nodes": if r.TryDecodeAsNil() { x.Nodes = nil } else { - yyv50 := &x.Nodes - yyv50.CodecDecodeSelf(d) + yyv10 := &x.Nodes + yyv10.CodecDecodeSelf(d) } case "createdIndex": if r.TryDecodeAsNil() { x.CreatedIndex = 0 } else { - x.CreatedIndex = uint64(r.DecodeUint(64)) + yyv11 := &x.CreatedIndex + yym12 := z.DecBinary() + _ = yym12 + if false { + } else { + *((*uint64)(yyv11)) = uint64(r.DecodeUint(64)) + } } case "modifiedIndex": if r.TryDecodeAsNil() { x.ModifiedIndex = 0 } else { - x.ModifiedIndex = uint64(r.DecodeUint(64)) + yyv13 := &x.ModifiedIndex + yym14 := z.DecBinary() + _ = yym14 + if false { + } else { + *((*uint64)(yyv13)) = uint64(r.DecodeUint(64)) + } } case "expiration": if r.TryDecodeAsNil() { @@ -639,15 +681,15 @@ func (x *Node) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) { if x.Expiration == nil { x.Expiration = new(time.Time) } - yym54 := z.DecBinary() - _ = yym54 + yym16 := z.DecBinary() + _ = yym16 if false { - } else if yym55 := z.TimeRtidIfBinc(); yym55 != 0 { - r.DecodeBuiltin(yym55, x.Expiration) + } else if yym17 := z.TimeRtidIfBinc(); yym17 != 0 { + r.DecodeBuiltin(yym17, x.Expiration) } else if z.HasExtensions() && z.DecExt(x.Expiration) { - } else if yym54 { + } else if yym16 { z.DecBinaryUnmarshal(x.Expiration) - } else if !yym54 && z.IsJSONHandle() { + } else if !yym16 && z.IsJSONHandle() { z.DecJSONUnmarshal(x.Expiration) } else { z.DecFallback(x.Expiration, false) @@ -657,12 +699,18 @@ func (x *Node) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) { if r.TryDecodeAsNil() { x.TTL = 0 } else { - x.TTL = int64(r.DecodeInt(64)) + yyv18 := &x.TTL + yym19 := z.DecBinary() + _ = yym19 + if false { + } else { + *((*int64)(yyv18)) = int64(r.DecodeInt(64)) + } } default: - z.DecStructFieldNotFound(-1, yys46) - } // end switch yys46 - } // end for yyj46 + z.DecStructFieldNotFound(-1, yys3) + } // end switch yys3 + } // end for yyj3 z.DecSendContainerState(codecSelfer_containerMapEnd1819) } @@ -670,16 +718,16 @@ func (x *Node) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { var h codecSelfer1819 z, r := codec1978.GenHelperDecoder(d) _, _, _ = h, z, r - var yyj57 int - var yyb57 bool - var yyhl57 bool = l >= 0 - yyj57++ - if yyhl57 { - yyb57 = yyj57 > l + var yyj20 int + var yyb20 bool + var yyhl20 bool = l >= 0 + yyj20++ + if yyhl20 { + yyb20 = yyj20 > l } else { - yyb57 = r.CheckBreak() + yyb20 = r.CheckBreak() } - if yyb57 { + if yyb20 { z.DecSendContainerState(codecSelfer_containerArrayEnd1819) return } @@ -687,15 +735,21 @@ func (x *Node) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { if r.TryDecodeAsNil() { x.Key = "" } else { - x.Key = string(r.DecodeString()) + yyv21 := &x.Key + yym22 := z.DecBinary() + _ = yym22 + if false { + } else { + *((*string)(yyv21)) = r.DecodeString() + } } - yyj57++ - if yyhl57 { - yyb57 = yyj57 > l + yyj20++ + if yyhl20 { + yyb20 = yyj20 > l } else { - yyb57 = r.CheckBreak() + yyb20 = r.CheckBreak() } - if yyb57 { + if yyb20 { z.DecSendContainerState(codecSelfer_containerArrayEnd1819) return } @@ -703,15 +757,21 @@ func (x *Node) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { if r.TryDecodeAsNil() { x.Dir = false } else { - x.Dir = bool(r.DecodeBool()) + yyv23 := &x.Dir + yym24 := z.DecBinary() + _ = yym24 + if false { + } else { + *((*bool)(yyv23)) = r.DecodeBool() + } } - yyj57++ - if yyhl57 { - yyb57 = yyj57 > l + yyj20++ + if yyhl20 { + yyb20 = yyj20 > l } else { - yyb57 = r.CheckBreak() + yyb20 = r.CheckBreak() } - if yyb57 { + if yyb20 { z.DecSendContainerState(codecSelfer_containerArrayEnd1819) return } @@ -719,15 +779,21 @@ func (x *Node) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { if r.TryDecodeAsNil() { x.Value = "" } else { - x.Value = string(r.DecodeString()) + yyv25 := &x.Value + yym26 := z.DecBinary() + _ = yym26 + if false { + } else { + *((*string)(yyv25)) = r.DecodeString() + } } - yyj57++ - if yyhl57 { - yyb57 = yyj57 > l + yyj20++ + if yyhl20 { + yyb20 = yyj20 > l } else { - yyb57 = r.CheckBreak() + yyb20 = r.CheckBreak() } - if yyb57 { + if yyb20 { z.DecSendContainerState(codecSelfer_containerArrayEnd1819) return } @@ -735,16 +801,16 @@ func (x *Node) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { if r.TryDecodeAsNil() { x.Nodes = nil } else { - yyv61 := &x.Nodes - yyv61.CodecDecodeSelf(d) + yyv27 := &x.Nodes + yyv27.CodecDecodeSelf(d) } - yyj57++ - if yyhl57 { - yyb57 = yyj57 > l + yyj20++ + if yyhl20 { + yyb20 = yyj20 > l } else { - yyb57 = r.CheckBreak() + yyb20 = r.CheckBreak() } - if yyb57 { + if yyb20 { z.DecSendContainerState(codecSelfer_containerArrayEnd1819) return } @@ -752,15 +818,21 @@ func (x *Node) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { if r.TryDecodeAsNil() { x.CreatedIndex = 0 } else { - x.CreatedIndex = uint64(r.DecodeUint(64)) + yyv28 := &x.CreatedIndex + yym29 := z.DecBinary() + _ = yym29 + if false { + } else { + *((*uint64)(yyv28)) = uint64(r.DecodeUint(64)) + } } - yyj57++ - if yyhl57 { - yyb57 = yyj57 > l + yyj20++ + if yyhl20 { + yyb20 = yyj20 > l } else { - yyb57 = r.CheckBreak() + yyb20 = r.CheckBreak() } - if yyb57 { + if yyb20 { z.DecSendContainerState(codecSelfer_containerArrayEnd1819) return } @@ -768,15 +840,21 @@ func (x *Node) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { if r.TryDecodeAsNil() { x.ModifiedIndex = 0 } else { - x.ModifiedIndex = uint64(r.DecodeUint(64)) + yyv30 := &x.ModifiedIndex + yym31 := z.DecBinary() + _ = yym31 + if false { + } else { + *((*uint64)(yyv30)) = uint64(r.DecodeUint(64)) + } } - yyj57++ - if yyhl57 { - yyb57 = yyj57 > l + yyj20++ + if yyhl20 { + yyb20 = yyj20 > l } else { - yyb57 = r.CheckBreak() + yyb20 = r.CheckBreak() } - if yyb57 { + if yyb20 { z.DecSendContainerState(codecSelfer_containerArrayEnd1819) return } @@ -789,27 +867,27 @@ func (x *Node) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { if x.Expiration == nil { x.Expiration = new(time.Time) } - yym65 := z.DecBinary() - _ = yym65 + yym33 := z.DecBinary() + _ = yym33 if false { - } else if yym66 := z.TimeRtidIfBinc(); yym66 != 0 { - r.DecodeBuiltin(yym66, x.Expiration) + } else if yym34 := z.TimeRtidIfBinc(); yym34 != 0 { + r.DecodeBuiltin(yym34, x.Expiration) } else if z.HasExtensions() && z.DecExt(x.Expiration) { - } else if yym65 { + } else if yym33 { z.DecBinaryUnmarshal(x.Expiration) - } else if !yym65 && z.IsJSONHandle() { + } else if !yym33 && z.IsJSONHandle() { z.DecJSONUnmarshal(x.Expiration) } else { z.DecFallback(x.Expiration, false) } } - yyj57++ - if yyhl57 { - yyb57 = yyj57 > l + yyj20++ + if yyhl20 { + yyb20 = yyj20 > l } else { - yyb57 = r.CheckBreak() + yyb20 = r.CheckBreak() } - if yyb57 { + if yyb20 { z.DecSendContainerState(codecSelfer_containerArrayEnd1819) return } @@ -817,20 +895,26 @@ func (x *Node) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { if r.TryDecodeAsNil() { x.TTL = 0 } else { - x.TTL = int64(r.DecodeInt(64)) + yyv35 := &x.TTL + yym36 := z.DecBinary() + _ = yym36 + if false { + } else { + *((*int64)(yyv35)) = int64(r.DecodeInt(64)) + } } for { - yyj57++ - if yyhl57 { - yyb57 = yyj57 > l + yyj20++ + if yyhl20 { + yyb20 = yyj20 > l } else { - yyb57 = r.CheckBreak() + yyb20 = r.CheckBreak() } - if yyb57 { + if yyb20 { break } z.DecSendContainerState(codecSelfer_containerArrayElem1819) - z.DecStructFieldNotFound(yyj57-1, "") + z.DecStructFieldNotFound(yyj20-1, "") } z.DecSendContainerState(codecSelfer_containerArrayEnd1819) } @@ -842,8 +926,8 @@ func (x Nodes) CodecEncodeSelf(e *codec1978.Encoder) { if x == nil { r.EncodeNil() } else { - yym68 := z.EncBinary() - _ = yym68 + yym1 := z.EncBinary() + _ = yym1 if false { } else if z.HasExtensions() && z.EncExt(x) { } else { @@ -856,8 +940,8 @@ func (x *Nodes) CodecDecodeSelf(d *codec1978.Decoder) { var h codecSelfer1819 z, r := codec1978.GenHelperDecoder(d) _, _, _ = h, z, r - yym69 := z.DecBinary() - _ = yym69 + yym1 := z.DecBinary() + _ = yym1 if false { } else if z.HasExtensions() && z.DecExt(x) { } else { @@ -870,12 +954,12 @@ func (x codecSelfer1819) encNodes(v Nodes, e *codec1978.Encoder) { z, r := codec1978.GenHelperEncoder(e) _, _, _ = h, z, r r.EncodeArrayStart(len(v)) - for _, yyv70 := range v { + for _, yyv1 := range v { z.EncSendContainerState(codecSelfer_containerArrayElem1819) - if yyv70 == nil { + if yyv1 == nil { r.EncodeNil() } else { - yyv70.CodecEncodeSelf(e) + yyv1.CodecEncodeSelf(e) } } z.EncSendContainerState(codecSelfer_containerArrayEnd1819) @@ -886,98 +970,101 @@ func (x codecSelfer1819) decNodes(v *Nodes, d *codec1978.Decoder) { z, r := codec1978.GenHelperDecoder(d) _, _, _ = h, z, r - yyv71 := *v - yyh71, yyl71 := z.DecSliceHelperStart() - var yyc71 bool - if yyl71 == 0 { - if yyv71 == nil { - yyv71 = []*Node{} - yyc71 = true - } else if len(yyv71) != 0 { - yyv71 = yyv71[:0] - yyc71 = true + yyv1 := *v + yyh1, yyl1 := z.DecSliceHelperStart() + var yyc1 bool + _ = yyc1 + if yyl1 == 0 { + if yyv1 == nil { + yyv1 = []*Node{} + yyc1 = true + } else if len(yyv1) != 0 { + yyv1 = yyv1[:0] + yyc1 = true } - } else if yyl71 > 0 { - var yyrr71, yyrl71 int - var yyrt71 bool - if yyl71 > cap(yyv71) { + } else if yyl1 > 0 { + var yyrr1, yyrl1 int + var yyrt1 bool + _, _ = yyrl1, yyrt1 + yyrr1 = yyl1 // len(yyv1) + if yyl1 > cap(yyv1) { - yyrg71 := len(yyv71) > 0 - yyv271 := yyv71 - yyrl71, yyrt71 = z.DecInferLen(yyl71, z.DecBasicHandle().MaxInitLen, 8) - if yyrt71 { - if yyrl71 <= cap(yyv71) { - yyv71 = yyv71[:yyrl71] + yyrg1 := len(yyv1) > 0 + yyv21 := yyv1 + yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 8) + if yyrt1 { + if yyrl1 <= cap(yyv1) { + yyv1 = yyv1[:yyrl1] } else { - yyv71 = make([]*Node, yyrl71) + yyv1 = make([]*Node, yyrl1) } } else { - yyv71 = make([]*Node, yyrl71) + yyv1 = make([]*Node, yyrl1) } - yyc71 = true - yyrr71 = len(yyv71) - if yyrg71 { - copy(yyv71, yyv271) + yyc1 = true + yyrr1 = len(yyv1) + if yyrg1 { + copy(yyv1, yyv21) } - } else if yyl71 != len(yyv71) { - yyv71 = yyv71[:yyl71] - yyc71 = true + } else if yyl1 != len(yyv1) { + yyv1 = yyv1[:yyl1] + yyc1 = true } - yyj71 := 0 - for ; yyj71 < yyrr71; yyj71++ { - yyh71.ElemContainerState(yyj71) + yyj1 := 0 + for ; yyj1 < yyrr1; yyj1++ { + yyh1.ElemContainerState(yyj1) if r.TryDecodeAsNil() { - if yyv71[yyj71] != nil { - *yyv71[yyj71] = Node{} + if yyv1[yyj1] != nil { + *yyv1[yyj1] = Node{} } } else { - if yyv71[yyj71] == nil { - yyv71[yyj71] = new(Node) + if yyv1[yyj1] == nil { + yyv1[yyj1] = new(Node) } - yyw72 := yyv71[yyj71] - yyw72.CodecDecodeSelf(d) + yyw2 := yyv1[yyj1] + yyw2.CodecDecodeSelf(d) } } - if yyrt71 { - for ; yyj71 < yyl71; yyj71++ { - yyv71 = append(yyv71, nil) - yyh71.ElemContainerState(yyj71) + if yyrt1 { + for ; yyj1 < yyl1; yyj1++ { + yyv1 = append(yyv1, nil) + yyh1.ElemContainerState(yyj1) if r.TryDecodeAsNil() { - if yyv71[yyj71] != nil { - *yyv71[yyj71] = Node{} + if yyv1[yyj1] != nil { + *yyv1[yyj1] = Node{} } } else { - if yyv71[yyj71] == nil { - yyv71[yyj71] = new(Node) + if yyv1[yyj1] == nil { + yyv1[yyj1] = new(Node) } - yyw73 := yyv71[yyj71] - yyw73.CodecDecodeSelf(d) + yyw3 := yyv1[yyj1] + yyw3.CodecDecodeSelf(d) } } } } else { - yyj71 := 0 - for ; !r.CheckBreak(); yyj71++ { + yyj1 := 0 + for ; !r.CheckBreak(); yyj1++ { - if yyj71 >= len(yyv71) { - yyv71 = append(yyv71, nil) // var yyz71 *Node - yyc71 = true + if yyj1 >= len(yyv1) { + yyv1 = append(yyv1, nil) // var yyz1 *Node + yyc1 = true } - yyh71.ElemContainerState(yyj71) - if yyj71 < len(yyv71) { + yyh1.ElemContainerState(yyj1) + if yyj1 < len(yyv1) { if r.TryDecodeAsNil() { - if yyv71[yyj71] != nil { - *yyv71[yyj71] = Node{} + if yyv1[yyj1] != nil { + *yyv1[yyj1] = Node{} } } else { - if yyv71[yyj71] == nil { - yyv71[yyj71] = new(Node) + if yyv1[yyj1] == nil { + yyv1[yyj1] = new(Node) } - yyw74 := yyv71[yyj71] - yyw74.CodecDecodeSelf(d) + yyw4 := yyv1[yyj1] + yyw4.CodecDecodeSelf(d) } } else { @@ -985,16 +1072,16 @@ func (x codecSelfer1819) decNodes(v *Nodes, d *codec1978.Decoder) { } } - if yyj71 < len(yyv71) { - yyv71 = yyv71[:yyj71] - yyc71 = true - } else if yyj71 == 0 && yyv71 == nil { - yyv71 = []*Node{} - yyc71 = true + if yyj1 < len(yyv1) { + yyv1 = yyv1[:yyj1] + yyc1 = true + } else if yyj1 == 0 && yyv1 == nil { + yyv1 = []*Node{} + yyc1 = true } } - yyh71.End() - if yyc71 { - *v = yyv71 + yyh1.End() + if yyc1 { + *v = yyv1 } } diff --git a/vendor/github.com/coreos/etcd/client/keys.go b/vendor/github.com/coreos/etcd/client/keys.go index 62d5d506e..4a6c41a78 100644 --- a/vendor/github.com/coreos/etcd/client/keys.go +++ b/vendor/github.com/coreos/etcd/client/keys.go @@ -191,6 +191,10 @@ type SetOptions struct { // Dir specifies whether or not this Node should be created as a directory. Dir bool + + // NoValueOnSuccess specifies whether the response contains the current value of the Node. + // If set, the response will only contain the current value when the request fails. + NoValueOnSuccess bool } type GetOptions struct { @@ -268,6 +272,10 @@ type Response struct { // Index holds the cluster-level index at the time the Response was generated. // This index is not tied to the Node(s) contained in this Response. Index uint64 `json:"-"` + + // ClusterID holds the cluster-level ID reported by the server. This + // should be different for different etcd clusters. + ClusterID string `json:"-"` } type Node struct { @@ -335,6 +343,7 @@ func (k *httpKeysAPI) Set(ctx context.Context, key, val string, opts *SetOptions act.TTL = opts.TTL act.Refresh = opts.Refresh act.Dir = opts.Dir + act.NoValueOnSuccess = opts.NoValueOnSuccess } doCtx := ctx @@ -523,15 +532,16 @@ func (w *waitAction) HTTPRequest(ep url.URL) *http.Request { } type setAction struct { - Prefix string - Key string - Value string - PrevValue string - PrevIndex uint64 - PrevExist PrevExistType - TTL time.Duration - Refresh bool - Dir bool + Prefix string + Key string + Value string + PrevValue string + PrevIndex uint64 + PrevExist PrevExistType + TTL time.Duration + Refresh bool + Dir bool + NoValueOnSuccess bool } func (a *setAction) HTTPRequest(ep url.URL) *http.Request { @@ -565,6 +575,9 @@ func (a *setAction) HTTPRequest(ep url.URL) *http.Request { if a.Refresh { form.Add("refresh", "true") } + if a.NoValueOnSuccess { + params.Set("noValueOnSuccess", strconv.FormatBool(a.NoValueOnSuccess)) + } u.RawQuery = params.Encode() body := strings.NewReader(form.Encode()) @@ -656,6 +669,7 @@ func unmarshalSuccessfulKeysResponse(header http.Header, body []byte) (*Response return nil, err } } + res.ClusterID = header.Get("X-Etcd-Cluster-ID") return &res, nil } diff --git a/vendor/github.com/coreos/etcd/client/util.go b/vendor/github.com/coreos/etcd/client/util.go index 198bff965..15a8babff 100644 --- a/vendor/github.com/coreos/etcd/client/util.go +++ b/vendor/github.com/coreos/etcd/client/util.go @@ -14,6 +14,20 @@ package client +import ( + "regexp" +) + +var ( + roleNotFoundRegExp *regexp.Regexp + userNotFoundRegExp *regexp.Regexp +) + +func init() { + roleNotFoundRegExp = regexp.MustCompile("auth: Role .* does not exist.") + userNotFoundRegExp = regexp.MustCompile("auth: User .* does not exist.") +} + // IsKeyNotFound returns true if the error code is ErrorCodeKeyNotFound. func IsKeyNotFound(err error) bool { if cErr, ok := err.(Error); ok { @@ -21,3 +35,19 @@ func IsKeyNotFound(err error) bool { } return false } + +// IsRoleNotFound returns true if the error means role not found of v2 API. +func IsRoleNotFound(err error) bool { + if ae, ok := err.(authError); ok { + return roleNotFoundRegExp.MatchString(ae.Message) + } + return false +} + +// IsUserNotFound returns true if the error means user not found of v2 API. +func IsUserNotFound(err error) bool { + if ae, ok := err.(authError); ok { + return userNotFoundRegExp.MatchString(ae.Message) + } + return false +} diff --git a/vendor/github.com/coreos/etcd/clientv3/README.md b/vendor/github.com/coreos/etcd/clientv3/README.md index e434f9994..87c32d1a8 100644 --- a/vendor/github.com/coreos/etcd/clientv3/README.md +++ b/vendor/github.com/coreos/etcd/clientv3/README.md @@ -72,6 +72,10 @@ if err != nil { } ``` +## Metrics + +The etcd client optionally exposes RPC metrics through [go-grpc-prometheus](https://github.com/grpc-ecosystem/go-grpc-prometheus). See the [examples](https://github.com/coreos/etcd/blob/master/clientv3/example_metrics_test.go). + ## Examples More code examples can be found at [GoDoc](https://godoc.org/github.com/coreos/etcd/clientv3). diff --git a/vendor/github.com/coreos/etcd/clientv3/auth.go b/vendor/github.com/coreos/etcd/clientv3/auth.go index 8c3c047f4..b995bce8e 100644 --- a/vendor/github.com/coreos/etcd/clientv3/auth.go +++ b/vendor/github.com/coreos/etcd/clientv3/auth.go @@ -43,6 +43,7 @@ type ( AuthRoleListResponse pb.AuthRoleListResponse PermissionType authpb.Permission_Type + Permission authpb.Permission ) const ( @@ -115,12 +116,12 @@ func NewAuth(c *Client) Auth { } func (auth *auth) AuthEnable(ctx context.Context) (*AuthEnableResponse, error) { - resp, err := auth.remote.AuthEnable(ctx, &pb.AuthEnableRequest{}) + resp, err := auth.remote.AuthEnable(ctx, &pb.AuthEnableRequest{}, grpc.FailFast(false)) return (*AuthEnableResponse)(resp), toErr(ctx, err) } func (auth *auth) AuthDisable(ctx context.Context) (*AuthDisableResponse, error) { - resp, err := auth.remote.AuthDisable(ctx, &pb.AuthDisableRequest{}) + resp, err := auth.remote.AuthDisable(ctx, &pb.AuthDisableRequest{}, grpc.FailFast(false)) return (*AuthDisableResponse)(resp), toErr(ctx, err) } diff --git a/vendor/github.com/coreos/etcd/clientv3/balancer.go b/vendor/github.com/coreos/etcd/clientv3/balancer.go index 7e8d957f9..0fef9c549 100644 --- a/vendor/github.com/coreos/etcd/clientv3/balancer.go +++ b/vendor/github.com/coreos/etcd/clientv3/balancer.go @@ -21,8 +21,14 @@ import ( "golang.org/x/net/context" "google.golang.org/grpc" + "google.golang.org/grpc/codes" ) +// ErrNoAddrAvilable is returned by Get() when the balancer does not have +// any active connection to endpoints at the time. +// This error is returned only when opts.BlockingWait is true. +var ErrNoAddrAvilable = grpc.Errorf(codes.Unavailable, "there is no address available") + // simpleBalancer does the bare minimum to expose multiple eps // to the grpc reconnection code path type simpleBalancer struct { @@ -42,6 +48,11 @@ type simpleBalancer struct { // upc closes when upEps transitions from empty to non-zero or the balancer closes. upc chan struct{} + // grpc issues TLS cert checks using the string passed into dial so + // that string must be the host. To recover the full scheme://host URL, + // have a map from hosts to the original endpoint. + host2ep map[string]string + // pinAddr is the currently pinned address; set to the empty string on // intialization and shutdown. pinAddr string @@ -62,11 +73,12 @@ func newSimpleBalancer(eps []string) *simpleBalancer { readyc: make(chan struct{}), upEps: make(map[string]struct{}), upc: make(chan struct{}), + host2ep: getHost2ep(eps), } return sb } -func (b *simpleBalancer) Start(target string) error { return nil } +func (b *simpleBalancer) Start(target string, config grpc.BalancerConfig) error { return nil } func (b *simpleBalancer) ConnectNotify() <-chan struct{} { b.mu.Lock() @@ -74,6 +86,49 @@ func (b *simpleBalancer) ConnectNotify() <-chan struct{} { return b.upc } +func (b *simpleBalancer) getEndpoint(host string) string { + b.mu.Lock() + defer b.mu.Unlock() + return b.host2ep[host] +} + +func getHost2ep(eps []string) map[string]string { + hm := make(map[string]string, len(eps)) + for i := range eps { + _, host, _ := parseEndpoint(eps[i]) + hm[host] = eps[i] + } + return hm +} + +func (b *simpleBalancer) updateAddrs(eps []string) { + np := getHost2ep(eps) + + b.mu.Lock() + defer b.mu.Unlock() + + match := len(np) == len(b.host2ep) + for k, v := range np { + if b.host2ep[k] != v { + match = false + break + } + } + if match { + // same endpoints, so no need to update address + return + } + + b.host2ep = np + + addrs := make([]grpc.Address, 0, len(eps)) + for i := range eps { + addrs = append(addrs, grpc.Address{Addr: getHost(eps[i])}) + } + b.addrs = addrs + b.notifyCh <- addrs +} + func (b *simpleBalancer) Up(addr grpc.Address) func(error) { b.mu.Lock() defer b.mu.Unlock() @@ -113,6 +168,25 @@ func (b *simpleBalancer) Up(addr grpc.Address) func(error) { func (b *simpleBalancer) Get(ctx context.Context, opts grpc.BalancerGetOptions) (grpc.Address, func(), error) { var addr string + + // If opts.BlockingWait is false (for fail-fast RPCs), it should return + // an address it has notified via Notify immediately instead of blocking. + if !opts.BlockingWait { + b.mu.RLock() + closed := b.closed + addr = b.pinAddr + upEps := len(b.upEps) + b.mu.RUnlock() + if closed { + return grpc.Address{Addr: ""}, nil, grpc.ErrClientConnClosing + } + + if upEps == 0 { + return grpc.Address{Addr: ""}, nil, ErrNoAddrAvilable + } + return grpc.Address{Addr: addr}, func() {}, nil + } + for { b.mu.RLock() ch := b.upc diff --git a/vendor/github.com/coreos/etcd/clientv3/client.go b/vendor/github.com/coreos/etcd/clientv3/client.go index e6903fc2f..368323f73 100644 --- a/vendor/github.com/coreos/etcd/clientv3/client.go +++ b/vendor/github.com/coreos/etcd/clientv3/client.go @@ -18,17 +18,18 @@ import ( "crypto/tls" "errors" "fmt" - "io/ioutil" - "log" "net" "net/url" "strings" + "sync" "time" "github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes" + prometheus "github.com/grpc-ecosystem/go-grpc-prometheus" "golang.org/x/net/context" "google.golang.org/grpc" + "google.golang.org/grpc/codes" "google.golang.org/grpc/credentials" "google.golang.org/grpc/metadata" ) @@ -46,11 +47,12 @@ type Client struct { Auth Maintenance - conn *grpc.ClientConn - cfg Config - creds *credentials.TransportCredentials - balancer *simpleBalancer - retryWrapper retryRpcFunc + conn *grpc.ClientConn + cfg Config + creds *credentials.TransportCredentials + balancer *simpleBalancer + retryWrapper retryRpcFunc + retryAuthWrapper retryRpcFunc ctx context.Context cancel context.CancelFunc @@ -59,6 +61,8 @@ type Client struct { Username string // Password is a password for authentication Password string + // tokenCred is an instance of WithPerRPCCredentials()'s argument + tokenCred *authTokenCredential } // New creates a new etcdv3 client from a given configuration. @@ -87,6 +91,8 @@ func NewFromConfigFile(path string) (*Client, error) { // Close shuts down the client's etcd connections. func (c *Client) Close() error { c.cancel() + c.Watcher.Close() + c.Lease.Close() return toErr(c.ctx, c.conn.Close()) } @@ -96,10 +102,54 @@ func (c *Client) Close() error { func (c *Client) Ctx() context.Context { return c.ctx } // Endpoints lists the registered endpoints for the client. -func (c *Client) Endpoints() []string { return c.cfg.Endpoints } +func (c *Client) Endpoints() (eps []string) { + // copy the slice; protect original endpoints from being changed + eps = make([]string, len(c.cfg.Endpoints)) + copy(eps, c.cfg.Endpoints) + return +} + +// SetEndpoints updates client's endpoints. +func (c *Client) SetEndpoints(eps ...string) { + c.cfg.Endpoints = eps + c.balancer.updateAddrs(eps) +} + +// Sync synchronizes client's endpoints with the known endpoints from the etcd membership. +func (c *Client) Sync(ctx context.Context) error { + mresp, err := c.MemberList(ctx) + if err != nil { + return err + } + var eps []string + for _, m := range mresp.Members { + eps = append(eps, m.ClientURLs...) + } + c.SetEndpoints(eps...) + return nil +} + +func (c *Client) autoSync() { + if c.cfg.AutoSyncInterval == time.Duration(0) { + return + } + + for { + select { + case <-c.ctx.Done(): + return + case <-time.After(c.cfg.AutoSyncInterval): + ctx, _ := context.WithTimeout(c.ctx, 5*time.Second) + if err := c.Sync(ctx); err != nil && err != c.ctx.Err() { + logger.Println("Auto sync endpoints failed:", err) + } + } + } +} type authTokenCredential struct { - token string + token string + tokenMu *sync.RWMutex } func (cred authTokenCredential) RequireTransportSecurity() bool { @@ -107,24 +157,38 @@ func (cred authTokenCredential) RequireTransportSecurity() bool { } func (cred authTokenCredential) GetRequestMetadata(ctx context.Context, s ...string) (map[string]string, error) { + cred.tokenMu.RLock() + defer cred.tokenMu.RUnlock() return map[string]string{ "token": cred.token, }, nil } -func (c *Client) dialTarget(endpoint string) (proto string, host string, creds *credentials.TransportCredentials) { +func parseEndpoint(endpoint string) (proto string, host string, scheme string) { proto = "tcp" host = endpoint - creds = c.creds url, uerr := url.Parse(endpoint) if uerr != nil || !strings.Contains(endpoint, "://") { return } + scheme = url.Scheme + // strip scheme:// prefix since grpc dials by host host = url.Host switch url.Scheme { + case "http", "https": case "unix": proto = "unix" + default: + proto, host = "", "" + } + return +} + +func (c *Client) processCreds(scheme string) (creds *credentials.TransportCredentials) { + creds = c.creds + switch scheme { + case "unix": case "http": creds = nil case "https": @@ -135,7 +199,7 @@ func (c *Client) dialTarget(endpoint string) (proto string, host string, creds * emptyCreds := credentials.NewTLS(tlsconfig) creds = &emptyCreds default: - return "", "", nil + creds = nil } return } @@ -147,17 +211,8 @@ func (c *Client) dialSetupOpts(endpoint string, dopts ...grpc.DialOption) (opts } opts = append(opts, dopts...) - // grpc issues TLS cert checks using the string passed into dial so - // that string must be the host. To recover the full scheme://host URL, - // have a map from hosts to the original endpoint. - host2ep := make(map[string]string) - for i := range c.cfg.Endpoints { - _, host, _ := c.dialTarget(c.cfg.Endpoints[i]) - host2ep[host] = c.cfg.Endpoints[i] - } - f := func(host string, t time.Duration) (net.Conn, error) { - proto, host, _ := c.dialTarget(host2ep[host]) + proto, host, _ := parseEndpoint(c.balancer.getEndpoint(host)) if proto == "" { return nil, fmt.Errorf("unknown scheme for %q", host) } @@ -166,11 +221,15 @@ func (c *Client) dialSetupOpts(endpoint string, dopts ...grpc.DialOption) (opts return nil, c.ctx.Err() default: } - return net.DialTimeout(proto, host, t) + dialer := &net.Dialer{Timeout: t} + return dialer.DialContext(c.ctx, proto, host) } opts = append(opts, grpc.WithDialer(f)) - _, _, creds := c.dialTarget(endpoint) + creds := c.creds + if _, _, scheme := parseEndpoint(endpoint); len(scheme) != 0 { + creds = c.processCreds(scheme) + } if creds != nil { opts = append(opts, grpc.WithTransportCredentials(*creds)) } else { @@ -185,24 +244,56 @@ func (c *Client) Dial(endpoint string) (*grpc.ClientConn, error) { return c.dial(endpoint) } +func (c *Client) getToken(ctx context.Context) error { + var err error // return last error in a case of fail + var auth *authenticator + + for i := 0; i < len(c.cfg.Endpoints); i++ { + endpoint := c.cfg.Endpoints[i] + host := getHost(endpoint) + // use dial options without dopts to avoid reusing the client balancer + auth, err = newAuthenticator(host, c.dialSetupOpts(endpoint)) + if err != nil { + continue + } + defer auth.close() + + var resp *AuthenticateResponse + resp, err = auth.authenticate(ctx, c.Username, c.Password) + if err != nil { + continue + } + + c.tokenCred.tokenMu.Lock() + c.tokenCred.token = resp.Token + c.tokenCred.tokenMu.Unlock() + + return nil + } + + return err +} + func (c *Client) dial(endpoint string, dopts ...grpc.DialOption) (*grpc.ClientConn, error) { opts := c.dialSetupOpts(endpoint, dopts...) host := getHost(endpoint) if c.Username != "" && c.Password != "" { - // use dial options without dopts to avoid reusing the client balancer - auth, err := newAuthenticator(host, c.dialSetupOpts(endpoint)) - if err != nil { - return nil, err + c.tokenCred = &authTokenCredential{ + tokenMu: &sync.RWMutex{}, } - defer auth.close() - resp, err := auth.authenticate(c.ctx, c.Username, c.Password) + err := c.getToken(context.TODO()) if err != nil { return nil, err } - opts = append(opts, grpc.WithPerRPCCredentials(authTokenCredential{token: resp.Token})) + + opts = append(opts, grpc.WithPerRPCCredentials(c.tokenCred)) } + // add metrics options + opts = append(opts, grpc.WithUnaryInterceptor(prometheus.UnaryClientInterceptor)) + opts = append(opts, grpc.WithStreamInterceptor(prometheus.StreamClientInterceptor)) + conn, err := grpc.Dial(host, opts...) if err != nil { return nil, err @@ -248,6 +339,7 @@ func newClient(cfg *Config) (*Client, error) { } client.conn = conn client.retryWrapper = client.newRetryWrapper() + client.retryAuthWrapper = client.newAuthRetryWrapper() // wait for a connection if cfg.DialTimeout > 0 { @@ -272,13 +364,8 @@ func newClient(cfg *Config) (*Client, error) { client.Watcher = NewWatcher(client) client.Auth = NewAuth(client) client.Maintenance = NewMaintenance(client) - if cfg.Logger != nil { - logger.Set(cfg.Logger) - } else { - // disable client side grpc by default - logger.Set(log.New(ioutil.Discard, "", 0)) - } + go client.autoSync() return client, nil } @@ -294,17 +381,14 @@ func isHaltErr(ctx context.Context, err error) bool { if err == nil { return false } - eErr := rpctypes.Error(err) - if _, ok := eErr.(rpctypes.EtcdError); ok { - return eErr != rpctypes.ErrStopped && eErr != rpctypes.ErrNoLeader - } - // treat etcdserver errors not recognized by the client as halting - return isConnClosing(err) || strings.Contains(err.Error(), "etcdserver:") -} - -// isConnClosing returns true if the error matches a grpc client closing error -func isConnClosing(err error) bool { - return strings.Contains(err.Error(), grpc.ErrClientConnClosing.Error()) + code := grpc.Code(err) + // Unavailable codes mean the system will be right back. + // (e.g., can't connect, lost leader) + // Treat Internal codes as if something failed, leaving the + // system in an inconsistent state, but retrying could make progress. + // (e.g., failed in middle of send, corrupted frame) + // TODO: are permanent Internal errors possible from grpc? + return code != codes.Unavailable && code != codes.Internal } func toErr(ctx context.Context, err error) error { @@ -312,12 +396,20 @@ func toErr(ctx context.Context, err error) error { return nil } err = rpctypes.Error(err) - switch { - case ctx.Err() != nil && strings.Contains(err.Error(), "context"): - err = ctx.Err() - case strings.Contains(err.Error(), ErrNoAvailableEndpoints.Error()): + if _, ok := err.(rpctypes.EtcdError); ok { + return err + } + code := grpc.Code(err) + switch code { + case codes.DeadlineExceeded: + fallthrough + case codes.Canceled: + if ctx.Err() != nil { + err = ctx.Err() + } + case codes.Unavailable: err = ErrNoAvailableEndpoints - case strings.Contains(err.Error(), grpc.ErrClientConnClosing.Error()): + case codes.FailedPrecondition: err = grpc.ErrClientConnClosing } return err diff --git a/vendor/github.com/coreos/etcd/clientv3/cluster.go b/vendor/github.com/coreos/etcd/clientv3/cluster.go index 8b981171b..b9bff626b 100644 --- a/vendor/github.com/coreos/etcd/clientv3/cluster.go +++ b/vendor/github.com/coreos/etcd/clientv3/cluster.go @@ -78,7 +78,7 @@ func (c *cluster) MemberUpdate(ctx context.Context, id uint64, peerAddrs []strin // it is safe to retry on update. for { r := &pb.MemberUpdateRequest{ID: id, PeerURLs: peerAddrs} - resp, err := c.remote.MemberUpdate(ctx, r) + resp, err := c.remote.MemberUpdate(ctx, r, grpc.FailFast(false)) if err == nil { return (*MemberUpdateResponse)(resp), nil } diff --git a/vendor/github.com/coreos/etcd/clientv3/compare.go b/vendor/github.com/coreos/etcd/clientv3/compare.go index 601349431..f89ffb52c 100644 --- a/vendor/github.com/coreos/etcd/clientv3/compare.go +++ b/vendor/github.com/coreos/etcd/clientv3/compare.go @@ -36,6 +36,8 @@ func Compare(cmp Cmp, result string, v interface{}) Cmp { switch result { case "=": r = pb.Compare_EQUAL + case "!=": + r = pb.Compare_NOT_EQUAL case ">": r = pb.Compare_GREATER case "<": diff --git a/vendor/github.com/coreos/etcd/clientv3/config.go b/vendor/github.com/coreos/etcd/clientv3/config.go index 066b41ece..d1d5f4090 100644 --- a/vendor/github.com/coreos/etcd/clientv3/config.go +++ b/vendor/github.com/coreos/etcd/clientv3/config.go @@ -28,15 +28,16 @@ type Config struct { // Endpoints is a list of URLs Endpoints []string + // AutoSyncInterval is the interval to update endpoints with its latest members. + // 0 disables auto-sync. By default auto-sync is disabled. + AutoSyncInterval time.Duration + // DialTimeout is the timeout for failing to establish a connection. DialTimeout time.Duration // TLS holds the client secure credentials, if any. TLS *tls.Config - // Logger is the logger used by client library. - Logger Logger - // Username is a username for authentication Username string @@ -46,6 +47,7 @@ type Config struct { type yamlConfig struct { Endpoints []string `json:"endpoints"` + AutoSyncInterval time.Duration `json:"auto-sync-interval"` DialTimeout time.Duration `json:"dial-timeout"` InsecureTransport bool `json:"insecure-transport"` InsecureSkipTLSVerify bool `json:"insecure-skip-tls-verify"` @@ -68,8 +70,9 @@ func configFromFile(fpath string) (*Config, error) { } cfg := &Config{ - Endpoints: yc.Endpoints, - DialTimeout: yc.DialTimeout, + Endpoints: yc.Endpoints, + AutoSyncInterval: yc.AutoSyncInterval, + DialTimeout: yc.DialTimeout, } if yc.InsecureTransport { diff --git a/vendor/github.com/coreos/etcd/clientv3/doc.go b/vendor/github.com/coreos/etcd/clientv3/doc.go index 9ce84aa57..470ca4dc4 100644 --- a/vendor/github.com/coreos/etcd/clientv3/doc.go +++ b/vendor/github.com/coreos/etcd/clientv3/doc.go @@ -44,7 +44,7 @@ // etcd client returns 2 types of errors: // // 1. context error: canceled or deadline exceeded. -// 2. gRPC error: see https://github.com/coreos/etcd/blob/master/etcdserver/api/v3rpc/error.go. +// 2. gRPC error: see https://github.com/coreos/etcd/blob/master/etcdserver/api/v3rpc/rpctypes/error.go // // Here is the example code to handle client errors: // diff --git a/vendor/github.com/coreos/etcd/clientv3/kv.go b/vendor/github.com/coreos/etcd/clientv3/kv.go index 584912985..c8350f926 100644 --- a/vendor/github.com/coreos/etcd/clientv3/kv.go +++ b/vendor/github.com/coreos/etcd/clientv3/kv.go @@ -85,6 +85,10 @@ func NewKV(c *Client) KV { return &kv{remote: RetryKVClient(c)} } +func NewKVFromKVClient(remote pb.KVClient) KV { + return &kv{remote: remote} +} + func (kv *kv) Put(ctx context.Context, key, val string, opts ...OpOption) (*PutResponse, error) { r, err := kv.Do(ctx, OpPut(key, val, opts...)) return r.put, toErr(ctx, err) @@ -101,7 +105,7 @@ func (kv *kv) Delete(ctx context.Context, key string, opts ...OpOption) (*Delete } func (kv *kv) Compact(ctx context.Context, rev int64, opts ...CompactOption) (*CompactResponse, error) { - resp, err := kv.remote.Compact(ctx, OpCompact(rev, opts...).toRequest(), grpc.FailFast(false)) + resp, err := kv.remote.Compact(ctx, OpCompact(rev, opts...).toRequest()) if err != nil { return nil, toErr(ctx, err) } @@ -121,6 +125,7 @@ func (kv *kv) Do(ctx context.Context, op Op) (OpResponse, error) { if err == nil { return resp, nil } + if isHaltErr(ctx, err) { return resp, toErr(ctx, err) } @@ -137,21 +142,7 @@ func (kv *kv) do(ctx context.Context, op Op) (OpResponse, error) { // TODO: handle other ops case tRange: var resp *pb.RangeResponse - r := &pb.RangeRequest{ - Key: op.key, - RangeEnd: op.end, - Limit: op.limit, - Revision: op.rev, - Serializable: op.serializable, - KeysOnly: op.keysOnly, - CountOnly: op.countOnly, - } - if op.sort != nil { - r.SortOrder = pb.RangeRequest_SortOrder(op.sort.Order) - r.SortTarget = pb.RangeRequest_SortTarget(op.sort.Target) - } - - resp, err = kv.remote.Range(ctx, r, grpc.FailFast(false)) + resp, err = kv.remote.Range(ctx, op.toRangeRequest(), grpc.FailFast(false)) if err == nil { return OpResponse{get: (*GetResponse)(resp)}, nil } diff --git a/vendor/github.com/coreos/etcd/clientv3/lease.go b/vendor/github.com/coreos/etcd/clientv3/lease.go index cf7c9ba8b..10d3dd0b2 100644 --- a/vendor/github.com/coreos/etcd/clientv3/lease.go +++ b/vendor/github.com/coreos/etcd/clientv3/lease.go @@ -44,6 +44,21 @@ type LeaseKeepAliveResponse struct { TTL int64 } +// LeaseTimeToLiveResponse is used to convert the protobuf lease timetolive response. +type LeaseTimeToLiveResponse struct { + *pb.ResponseHeader + ID LeaseID `json:"id"` + + // TTL is the remaining TTL in seconds for the lease; the lease will expire in under TTL+1 seconds. + TTL int64 `json:"ttl"` + + // GrantedTTL is the initial granted time in seconds upon lease creation/renewal. + GrantedTTL int64 `json:"granted-ttl"` + + // Keys is the list of keys attached to this lease. + Keys [][]byte `json:"keys"` +} + const ( // defaultTTL is the assumed lease TTL used for the first keepalive // deadline before the actual TTL is known to the client. @@ -54,6 +69,21 @@ const ( NoLease LeaseID = 0 ) +// ErrKeepAliveHalted is returned if client keep alive loop halts with an unexpected error. +// +// This usually means that automatic lease renewal via KeepAlive is broken, but KeepAliveOnce will still work as expected. +type ErrKeepAliveHalted struct { + Reason error +} + +func (e ErrKeepAliveHalted) Error() string { + s := "etcdclient: leases keep alive halted" + if e.Reason != nil { + s += ": " + e.Reason.Error() + } + return s +} + type Lease interface { // Grant creates a new lease. Grant(ctx context.Context, ttl int64) (*LeaseGrantResponse, error) @@ -61,6 +91,9 @@ type Lease interface { // Revoke revokes the given lease. Revoke(ctx context.Context, id LeaseID) (*LeaseRevokeResponse, error) + // TimeToLive retrieves the lease information of the given lease ID. + TimeToLive(ctx context.Context, id LeaseID, opts ...LeaseOption) (*LeaseTimeToLiveResponse, error) + // KeepAlive keeps the given lease alive forever. KeepAlive(ctx context.Context, id LeaseID) (<-chan *LeaseKeepAliveResponse, error) @@ -76,8 +109,9 @@ type Lease interface { type lessor struct { mu sync.Mutex // guards all fields - // donec is closed when recvKeepAliveLoop stops - donec chan struct{} + // donec is closed and loopErr is set when recvKeepAliveLoop stops + donec chan struct{} + loopErr error remote pb.LeaseClient @@ -141,7 +175,7 @@ func (l *lessor) Grant(ctx context.Context, ttl int64) (*LeaseGrantResponse, err return gresp, nil } if isHaltErr(cctx, err) { - return nil, toErr(ctx, err) + return nil, toErr(cctx, err) } } } @@ -164,10 +198,43 @@ func (l *lessor) Revoke(ctx context.Context, id LeaseID) (*LeaseRevokeResponse, } } +func (l *lessor) TimeToLive(ctx context.Context, id LeaseID, opts ...LeaseOption) (*LeaseTimeToLiveResponse, error) { + cctx, cancel := context.WithCancel(ctx) + done := cancelWhenStop(cancel, l.stopCtx.Done()) + defer close(done) + + for { + r := toLeaseTimeToLiveRequest(id, opts...) + resp, err := l.remote.LeaseTimeToLive(cctx, r, grpc.FailFast(false)) + if err == nil { + gresp := &LeaseTimeToLiveResponse{ + ResponseHeader: resp.GetHeader(), + ID: LeaseID(resp.ID), + TTL: resp.TTL, + GrantedTTL: resp.GrantedTTL, + Keys: resp.Keys, + } + return gresp, nil + } + if isHaltErr(cctx, err) { + return nil, toErr(cctx, err) + } + } +} + func (l *lessor) KeepAlive(ctx context.Context, id LeaseID) (<-chan *LeaseKeepAliveResponse, error) { ch := make(chan *LeaseKeepAliveResponse, leaseResponseChSize) l.mu.Lock() + // ensure that recvKeepAliveLoop is still running + select { + case <-l.donec: + err := l.loopErr + l.mu.Unlock() + close(ch) + return ch, ErrKeepAliveHalted{Reason: err} + default: + } ka, ok := l.keepAlives[id] if !ok { // create fresh keep alive @@ -275,10 +342,11 @@ func (l *lessor) keepAliveOnce(ctx context.Context, id LeaseID) (*LeaseKeepAlive return karesp, nil } -func (l *lessor) recvKeepAliveLoop() { +func (l *lessor) recvKeepAliveLoop() (gerr error) { defer func() { l.mu.Lock() close(l.donec) + l.loopErr = gerr for _, ka := range l.keepAlives { ka.Close() } @@ -291,13 +359,14 @@ func (l *lessor) recvKeepAliveLoop() { resp, err := stream.Recv() if err != nil { if isHaltErr(l.stopCtx, err) { - return + return err } stream, serr = l.resetRecv() continue } l.recvKeepAlive(resp) } + return serr } // resetRecv opens a new lease stream and starts sending LeaseKeepAliveRequests @@ -347,7 +416,7 @@ func (l *lessor) recvKeepAlive(resp *pb.LeaseKeepAliveResponse) { } // send update to all channels - nextKeepAlive := time.Now().Add(1 + time.Duration(karesp.TTL/3)*time.Second) + nextKeepAlive := time.Now().Add((time.Duration(karesp.TTL) * time.Second) / 3.0) ka.deadline = time.Now().Add(time.Duration(karesp.TTL) * time.Second) for _, ch := range ka.chs { select { @@ -393,7 +462,7 @@ func (l *lessor) sendKeepAliveLoop(stream pb.Lease_LeaseKeepAliveClient) { return } - tosend := make([]LeaseID, 0) + var tosend []LeaseID now := time.Now() l.mu.Lock() diff --git a/vendor/github.com/coreos/etcd/clientv3/logger.go b/vendor/github.com/coreos/etcd/clientv3/logger.go index 6e57c4e7c..519db45d8 100644 --- a/vendor/github.com/coreos/etcd/clientv3/logger.go +++ b/vendor/github.com/coreos/etcd/clientv3/logger.go @@ -15,13 +15,15 @@ package clientv3 import ( + "io/ioutil" "log" - "os" "sync" "google.golang.org/grpc/grpclog" ) +// Logger is the logger used by client library. +// It implements grpclog.Logger interface. type Logger grpclog.Logger var ( @@ -34,20 +36,36 @@ type settableLogger struct { } func init() { - // use go's standard logger by default like grpc + // disable client side logs by default logger.mu.Lock() - logger.l = log.New(os.Stderr, "", log.LstdFlags) + logger.l = log.New(ioutil.Discard, "", 0) + + // logger has to override the grpclog at initialization so that + // any changes to the grpclog go through logger with locking + // instead of through SetLogger + // + // now updates only happen through settableLogger.set grpclog.SetLogger(&logger) logger.mu.Unlock() } -func (s *settableLogger) Set(l Logger) { +// SetLogger sets client-side Logger. By default, logs are disabled. +func SetLogger(l Logger) { + logger.set(l) +} + +// GetLogger returns the current logger. +func GetLogger() Logger { + return logger.get() +} + +func (s *settableLogger) set(l Logger) { s.mu.Lock() logger.l = l s.mu.Unlock() } -func (s *settableLogger) Get() Logger { +func (s *settableLogger) get() Logger { s.mu.RLock() l := logger.l s.mu.RUnlock() @@ -56,9 +74,9 @@ func (s *settableLogger) Get() Logger { // implement the grpclog.Logger interface -func (s *settableLogger) Fatal(args ...interface{}) { s.Get().Fatal(args...) } -func (s *settableLogger) Fatalf(format string, args ...interface{}) { s.Get().Fatalf(format, args...) } -func (s *settableLogger) Fatalln(args ...interface{}) { s.Get().Fatalln(args...) } -func (s *settableLogger) Print(args ...interface{}) { s.Get().Print(args...) } -func (s *settableLogger) Printf(format string, args ...interface{}) { s.Get().Printf(format, args...) } -func (s *settableLogger) Println(args ...interface{}) { s.Get().Println(args...) } +func (s *settableLogger) Fatal(args ...interface{}) { s.get().Fatal(args...) } +func (s *settableLogger) Fatalf(format string, args ...interface{}) { s.get().Fatalf(format, args...) } +func (s *settableLogger) Fatalln(args ...interface{}) { s.get().Fatalln(args...) } +func (s *settableLogger) Print(args ...interface{}) { s.get().Print(args...) } +func (s *settableLogger) Printf(format string, args ...interface{}) { s.get().Printf(format, args...) } +func (s *settableLogger) Println(args ...interface{}) { s.get().Println(args...) } diff --git a/vendor/github.com/coreos/etcd/clientv3/op.go b/vendor/github.com/coreos/etcd/clientv3/op.go index d3ed55b62..6e2600766 100644 --- a/vendor/github.com/coreos/etcd/clientv3/op.go +++ b/vendor/github.com/coreos/etcd/clientv3/op.go @@ -14,9 +14,7 @@ package clientv3 -import ( - pb "github.com/coreos/etcd/etcdserver/etcdserverpb" -) +import pb "github.com/coreos/etcd/etcdserver/etcdserverpb" type opType int @@ -43,6 +41,10 @@ type Op struct { serializable bool keysOnly bool countOnly bool + minModRev int64 + maxModRev int64 + minCreateRev int64 + maxCreateRev int64 // for range, watch rev int64 @@ -52,29 +54,45 @@ type Op struct { // progressNotify is for progress updates. progressNotify bool + // createdNotify is for created event + createdNotify bool + // filters for watchers + filterPut bool + filterDelete bool // for put val []byte leaseID LeaseID } +func (op Op) toRangeRequest() *pb.RangeRequest { + if op.t != tRange { + panic("op.t != tRange") + } + r := &pb.RangeRequest{ + Key: op.key, + RangeEnd: op.end, + Limit: op.limit, + Revision: op.rev, + Serializable: op.serializable, + KeysOnly: op.keysOnly, + CountOnly: op.countOnly, + MinModRevision: op.minModRev, + MaxModRevision: op.maxModRev, + MinCreateRevision: op.minCreateRev, + MaxCreateRevision: op.maxCreateRev, + } + if op.sort != nil { + r.SortOrder = pb.RangeRequest_SortOrder(op.sort.Order) + r.SortTarget = pb.RangeRequest_SortTarget(op.sort.Target) + } + return r +} + func (op Op) toRequestOp() *pb.RequestOp { switch op.t { case tRange: - r := &pb.RangeRequest{ - Key: op.key, - RangeEnd: op.end, - Limit: op.limit, - Revision: op.rev, - Serializable: op.serializable, - KeysOnly: op.keysOnly, - CountOnly: op.countOnly, - } - if op.sort != nil { - r.SortOrder = pb.RangeRequest_SortOrder(op.sort.Order) - r.SortTarget = pb.RangeRequest_SortTarget(op.sort.Target) - } - return &pb.RequestOp{Request: &pb.RequestOp_RequestRange{RequestRange: r}} + return &pb.RequestOp{Request: &pb.RequestOp_RequestRange{RequestRange: op.toRangeRequest()}} case tPut: 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}} @@ -112,6 +130,14 @@ func OpDelete(key string, opts ...OpOption) Op { panic("unexpected serializable in delete") case ret.countOnly: panic("unexpected countOnly in delete") + case ret.minModRev != 0, ret.maxModRev != 0: + panic("unexpected mod revision filter in delete") + case ret.minCreateRev != 0, ret.maxCreateRev != 0: + panic("unexpected create revision filter in delete") + case ret.filterDelete, ret.filterPut: + panic("unexpected filter in delete") + case ret.createdNotify: + panic("unexpected createdNotify in delete") } return ret } @@ -131,7 +157,15 @@ func OpPut(key, val string, opts ...OpOption) Op { case ret.serializable: panic("unexpected serializable in put") case ret.countOnly: - panic("unexpected countOnly in delete") + panic("unexpected countOnly in put") + case ret.minModRev != 0, ret.maxModRev != 0: + panic("unexpected mod revision filter in put") + case ret.minCreateRev != 0, ret.maxCreateRev != 0: + panic("unexpected create revision filter in put") + case ret.filterDelete, ret.filterPut: + panic("unexpected filter in put") + case ret.createdNotify: + panic("unexpected createdNotify in put") } return ret } @@ -149,7 +183,11 @@ func opWatch(key string, opts ...OpOption) Op { case ret.serializable: panic("unexpected serializable in watch") case ret.countOnly: - panic("unexpected countOnly in delete") + panic("unexpected countOnly in watch") + case ret.minModRev != 0, ret.maxModRev != 0: + panic("unexpected mod revision filter in watch") + case ret.minCreateRev != 0, ret.maxCreateRev != 0: + panic("unexpected create revision filter in watch") } return ret } @@ -181,6 +219,14 @@ func WithRev(rev int64) OpOption { return func(op *Op) { op.rev = rev } } // 'order' can be either 'SortNone', 'SortAscend', 'SortDescend'. func WithSort(target SortTarget, order SortOrder) OpOption { return func(op *Op) { + if target == SortByKey && order == SortAscend { + // If order != SortNone, server fetches the entire key-space, + // and then applies the sort and limit, if provided. + // Since current mvcc.Range implementation returns results + // sorted by keys in lexicographically ascending order, + // client should ignore SortOrder if the target is SortByKey. + order = SortNone + } op.sort = &SortOption{target, order} } } @@ -245,6 +291,18 @@ func WithCountOnly() OpOption { return func(op *Op) { op.countOnly = true } } +// WithMinModRev filters out keys for Get with modification revisions less than the given revision. +func WithMinModRev(rev int64) OpOption { return func(op *Op) { op.minModRev = rev } } + +// WithMaxModRev filters out keys for Get with modification revisions greater than the given revision. +func WithMaxModRev(rev int64) OpOption { return func(op *Op) { op.maxModRev = rev } } + +// WithMinCreateRev filters out keys for Get with creation revisions less than the given revision. +func WithMinCreateRev(rev int64) OpOption { return func(op *Op) { op.minCreateRev = rev } } + +// WithMaxCreateRev filters out keys for Get with creation revisions greater than the given revision. +func WithMaxCreateRev(rev int64) OpOption { return func(op *Op) { op.maxCreateRev = rev } } + // WithFirstCreate gets the key with the oldest creation revision in the request range. func WithFirstCreate() []OpOption { return withTop(SortByCreateRevision, SortAscend) } @@ -268,7 +326,8 @@ func withTop(target SortTarget, order SortOrder) []OpOption { return []OpOption{WithPrefix(), WithSort(target, order), WithLimit(1)} } -// WithProgressNotify makes watch server send periodic progress updates. +// WithProgressNotify makes watch server send periodic progress updates +// every 10 minutes when there is no incoming events. // Progress updates have zero events in WatchResponse. func WithProgressNotify() OpOption { return func(op *Op) { @@ -276,6 +335,23 @@ func WithProgressNotify() OpOption { } } +// WithCreatedNotify makes watch server sends the created event. +func WithCreatedNotify() OpOption { + return func(op *Op) { + op.createdNotify = true + } +} + +// WithFilterPut discards PUT events from the watcher. +func WithFilterPut() OpOption { + return func(op *Op) { op.filterPut = true } +} + +// WithFilterDelete discards DELETE events from the watcher. +func WithFilterDelete() OpOption { + return func(op *Op) { op.filterDelete = 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 { @@ -283,3 +359,32 @@ func WithPrevKV() OpOption { op.prevKV = true } } + +// LeaseOp represents an Operation that lease can execute. +type LeaseOp struct { + id LeaseID + + // for TimeToLive + attachedKeys bool +} + +// LeaseOption configures lease operations. +type LeaseOption func(*LeaseOp) + +func (op *LeaseOp) applyOpts(opts []LeaseOption) { + for _, opt := range opts { + opt(op) + } +} + +// WithAttachedKeys requests lease timetolive API to return +// attached keys of given lease ID. +func WithAttachedKeys() LeaseOption { + return func(op *LeaseOp) { op.attachedKeys = true } +} + +func toLeaseTimeToLiveRequest(id LeaseID, opts ...LeaseOption) *pb.LeaseTimeToLiveRequest { + ret := &LeaseOp{id: id} + ret.applyOpts(opts) + return &pb.LeaseTimeToLiveRequest{ID: int64(id), Keys: ret.attachedKeys} +} diff --git a/vendor/github.com/coreos/etcd/clientv3/retry.go b/vendor/github.com/coreos/etcd/clientv3/retry.go index 3029ed8ea..78f31a8c4 100644 --- a/vendor/github.com/coreos/etcd/clientv3/retry.go +++ b/vendor/github.com/coreos/etcd/clientv3/retry.go @@ -15,68 +15,117 @@ package clientv3 import ( + "github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes" pb "github.com/coreos/etcd/etcdserver/etcdserverpb" "golang.org/x/net/context" "google.golang.org/grpc" + "google.golang.org/grpc/codes" ) type rpcFunc func(ctx context.Context) error -type retryRpcFunc func(context.Context, rpcFunc) +type retryRpcFunc func(context.Context, rpcFunc) error func (c *Client) newRetryWrapper() retryRpcFunc { - return func(rpcCtx context.Context, f rpcFunc) { + return func(rpcCtx context.Context, f rpcFunc) error { for { err := f(rpcCtx) - // ignore grpc conn closing on fail-fast calls; they are transient errors - if err == nil || !isConnClosing(err) { - return + if err == nil { + return nil } + + eErr := rpctypes.Error(err) + // always stop retry on etcd errors + if _, ok := eErr.(rpctypes.EtcdError); ok { + return err + } + + // only retry if unavailable + if grpc.Code(err) != codes.Unavailable { + return err + } + select { case <-c.balancer.ConnectNotify(): case <-rpcCtx.Done(): + return rpcCtx.Err() case <-c.ctx.Done(): - return + return c.ctx.Err() } } } } -type retryKVClient struct { - pb.KVClient - retryf retryRpcFunc +func (c *Client) newAuthRetryWrapper() retryRpcFunc { + return func(rpcCtx context.Context, f rpcFunc) error { + for { + err := f(rpcCtx) + if err == nil { + return nil + } + + // always stop retry on etcd errors other than invalid auth token + if rpctypes.Error(err) == rpctypes.ErrInvalidAuthToken { + gterr := c.getToken(rpcCtx) + if gterr != nil { + return err // return the original error for simplicity + } + continue + } + + return err + } + } } // RetryKVClient implements a KVClient that uses the client's FailFast retry policy. func RetryKVClient(c *Client) pb.KVClient { - return &retryKVClient{pb.NewKVClient(c.conn), c.retryWrapper} + retryWrite := &retryWriteKVClient{pb.NewKVClient(c.conn), c.retryWrapper} + return &retryKVClient{&retryWriteKVClient{retryWrite, c.retryAuthWrapper}} } -func (rkv *retryKVClient) Put(ctx context.Context, in *pb.PutRequest, opts ...grpc.CallOption) (resp *pb.PutResponse, err error) { - rkv.retryf(ctx, func(rctx context.Context) error { +type retryKVClient struct { + *retryWriteKVClient +} + +func (rkv *retryKVClient) Range(ctx context.Context, in *pb.RangeRequest, opts ...grpc.CallOption) (resp *pb.RangeResponse, err error) { + err = rkv.retryf(ctx, func(rctx context.Context) error { + resp, err = rkv.retryWriteKVClient.Range(rctx, in, opts...) + return err + }) + return resp, err +} + +type retryWriteKVClient struct { + pb.KVClient + retryf retryRpcFunc +} + +func (rkv *retryWriteKVClient) Put(ctx context.Context, in *pb.PutRequest, opts ...grpc.CallOption) (resp *pb.PutResponse, err error) { + err = rkv.retryf(ctx, func(rctx context.Context) error { resp, err = rkv.KVClient.Put(rctx, in, opts...) return err }) return resp, err } -func (rkv *retryKVClient) DeleteRange(ctx context.Context, in *pb.DeleteRangeRequest, opts ...grpc.CallOption) (resp *pb.DeleteRangeResponse, err error) { - rkv.retryf(ctx, func(rctx context.Context) error { +func (rkv *retryWriteKVClient) DeleteRange(ctx context.Context, in *pb.DeleteRangeRequest, opts ...grpc.CallOption) (resp *pb.DeleteRangeResponse, err error) { + err = rkv.retryf(ctx, func(rctx context.Context) error { resp, err = rkv.KVClient.DeleteRange(rctx, in, opts...) return err }) return resp, err } -func (rkv *retryKVClient) Txn(ctx context.Context, in *pb.TxnRequest, opts ...grpc.CallOption) (resp *pb.TxnResponse, err error) { - rkv.retryf(ctx, func(rctx context.Context) error { +func (rkv *retryWriteKVClient) Txn(ctx context.Context, in *pb.TxnRequest, opts ...grpc.CallOption) (resp *pb.TxnResponse, err error) { + err = rkv.retryf(ctx, func(rctx context.Context) error { resp, err = rkv.KVClient.Txn(rctx, in, opts...) return err }) return resp, err } -func (rkv *retryKVClient) Compact(ctx context.Context, in *pb.CompactionRequest, opts ...grpc.CallOption) (resp *pb.CompactionResponse, err error) { - rkv.retryf(ctx, func(rctx context.Context) error { +func (rkv *retryWriteKVClient) Compact(ctx context.Context, in *pb.CompactionRequest, opts ...grpc.CallOption) (resp *pb.CompactionResponse, err error) { + err = rkv.retryf(ctx, func(rctx context.Context) error { resp, err = rkv.KVClient.Compact(rctx, in, opts...) return err }) @@ -90,11 +139,12 @@ type retryLeaseClient struct { // RetryLeaseClient implements a LeaseClient that uses the client's FailFast retry policy. func RetryLeaseClient(c *Client) pb.LeaseClient { - return &retryLeaseClient{pb.NewLeaseClient(c.conn), c.retryWrapper} + retry := &retryLeaseClient{pb.NewLeaseClient(c.conn), c.retryWrapper} + return &retryLeaseClient{retry, c.retryAuthWrapper} } func (rlc *retryLeaseClient) LeaseGrant(ctx context.Context, in *pb.LeaseGrantRequest, opts ...grpc.CallOption) (resp *pb.LeaseGrantResponse, err error) { - rlc.retryf(ctx, func(rctx context.Context) error { + err = rlc.retryf(ctx, func(rctx context.Context) error { resp, err = rlc.LeaseClient.LeaseGrant(rctx, in, opts...) return err }) @@ -103,7 +153,7 @@ func (rlc *retryLeaseClient) LeaseGrant(ctx context.Context, in *pb.LeaseGrantRe } func (rlc *retryLeaseClient) LeaseRevoke(ctx context.Context, in *pb.LeaseRevokeRequest, opts ...grpc.CallOption) (resp *pb.LeaseRevokeResponse, err error) { - rlc.retryf(ctx, func(rctx context.Context) error { + err = rlc.retryf(ctx, func(rctx context.Context) error { resp, err = rlc.LeaseClient.LeaseRevoke(rctx, in, opts...) return err }) @@ -121,7 +171,7 @@ func RetryClusterClient(c *Client) pb.ClusterClient { } func (rcc *retryClusterClient) MemberAdd(ctx context.Context, in *pb.MemberAddRequest, opts ...grpc.CallOption) (resp *pb.MemberAddResponse, err error) { - rcc.retryf(ctx, func(rctx context.Context) error { + err = rcc.retryf(ctx, func(rctx context.Context) error { resp, err = rcc.ClusterClient.MemberAdd(rctx, in, opts...) return err }) @@ -129,7 +179,7 @@ func (rcc *retryClusterClient) MemberAdd(ctx context.Context, in *pb.MemberAddRe } func (rcc *retryClusterClient) MemberRemove(ctx context.Context, in *pb.MemberRemoveRequest, opts ...grpc.CallOption) (resp *pb.MemberRemoveResponse, err error) { - rcc.retryf(ctx, func(rctx context.Context) error { + err = rcc.retryf(ctx, func(rctx context.Context) error { resp, err = rcc.ClusterClient.MemberRemove(rctx, in, opts...) return err }) @@ -137,7 +187,7 @@ func (rcc *retryClusterClient) MemberRemove(ctx context.Context, in *pb.MemberRe } func (rcc *retryClusterClient) MemberUpdate(ctx context.Context, in *pb.MemberUpdateRequest, opts ...grpc.CallOption) (resp *pb.MemberUpdateResponse, err error) { - rcc.retryf(ctx, func(rctx context.Context) error { + err = rcc.retryf(ctx, func(rctx context.Context) error { resp, err = rcc.ClusterClient.MemberUpdate(rctx, in, opts...) return err }) @@ -155,7 +205,7 @@ func RetryAuthClient(c *Client) pb.AuthClient { } func (rac *retryAuthClient) AuthEnable(ctx context.Context, in *pb.AuthEnableRequest, opts ...grpc.CallOption) (resp *pb.AuthEnableResponse, err error) { - rac.retryf(ctx, func(rctx context.Context) error { + err = rac.retryf(ctx, func(rctx context.Context) error { resp, err = rac.AuthClient.AuthEnable(rctx, in, opts...) return err }) @@ -163,7 +213,7 @@ func (rac *retryAuthClient) AuthEnable(ctx context.Context, in *pb.AuthEnableReq } func (rac *retryAuthClient) AuthDisable(ctx context.Context, in *pb.AuthDisableRequest, opts ...grpc.CallOption) (resp *pb.AuthDisableResponse, err error) { - rac.retryf(ctx, func(rctx context.Context) error { + err = rac.retryf(ctx, func(rctx context.Context) error { resp, err = rac.AuthClient.AuthDisable(rctx, in, opts...) return err }) @@ -171,7 +221,7 @@ func (rac *retryAuthClient) AuthDisable(ctx context.Context, in *pb.AuthDisableR } func (rac *retryAuthClient) UserAdd(ctx context.Context, in *pb.AuthUserAddRequest, opts ...grpc.CallOption) (resp *pb.AuthUserAddResponse, err error) { - rac.retryf(ctx, func(rctx context.Context) error { + err = rac.retryf(ctx, func(rctx context.Context) error { resp, err = rac.AuthClient.UserAdd(rctx, in, opts...) return err }) @@ -179,7 +229,7 @@ func (rac *retryAuthClient) UserAdd(ctx context.Context, in *pb.AuthUserAddReque } func (rac *retryAuthClient) UserDelete(ctx context.Context, in *pb.AuthUserDeleteRequest, opts ...grpc.CallOption) (resp *pb.AuthUserDeleteResponse, err error) { - rac.retryf(ctx, func(rctx context.Context) error { + err = rac.retryf(ctx, func(rctx context.Context) error { resp, err = rac.AuthClient.UserDelete(rctx, in, opts...) return err }) @@ -187,7 +237,7 @@ func (rac *retryAuthClient) UserDelete(ctx context.Context, in *pb.AuthUserDelet } func (rac *retryAuthClient) UserChangePassword(ctx context.Context, in *pb.AuthUserChangePasswordRequest, opts ...grpc.CallOption) (resp *pb.AuthUserChangePasswordResponse, err error) { - rac.retryf(ctx, func(rctx context.Context) error { + err = rac.retryf(ctx, func(rctx context.Context) error { resp, err = rac.AuthClient.UserChangePassword(rctx, in, opts...) return err }) @@ -195,7 +245,7 @@ func (rac *retryAuthClient) UserChangePassword(ctx context.Context, in *pb.AuthU } func (rac *retryAuthClient) UserGrantRole(ctx context.Context, in *pb.AuthUserGrantRoleRequest, opts ...grpc.CallOption) (resp *pb.AuthUserGrantRoleResponse, err error) { - rac.retryf(ctx, func(rctx context.Context) error { + err = rac.retryf(ctx, func(rctx context.Context) error { resp, err = rac.AuthClient.UserGrantRole(rctx, in, opts...) return err }) @@ -203,7 +253,7 @@ func (rac *retryAuthClient) UserGrantRole(ctx context.Context, in *pb.AuthUserGr } func (rac *retryAuthClient) UserRevokeRole(ctx context.Context, in *pb.AuthUserRevokeRoleRequest, opts ...grpc.CallOption) (resp *pb.AuthUserRevokeRoleResponse, err error) { - rac.retryf(ctx, func(rctx context.Context) error { + err = rac.retryf(ctx, func(rctx context.Context) error { resp, err = rac.AuthClient.UserRevokeRole(rctx, in, opts...) return err }) @@ -211,7 +261,7 @@ func (rac *retryAuthClient) UserRevokeRole(ctx context.Context, in *pb.AuthUserR } func (rac *retryAuthClient) RoleAdd(ctx context.Context, in *pb.AuthRoleAddRequest, opts ...grpc.CallOption) (resp *pb.AuthRoleAddResponse, err error) { - rac.retryf(ctx, func(rctx context.Context) error { + err = rac.retryf(ctx, func(rctx context.Context) error { resp, err = rac.AuthClient.RoleAdd(rctx, in, opts...) return err }) @@ -219,7 +269,7 @@ func (rac *retryAuthClient) RoleAdd(ctx context.Context, in *pb.AuthRoleAddReque } func (rac *retryAuthClient) RoleDelete(ctx context.Context, in *pb.AuthRoleDeleteRequest, opts ...grpc.CallOption) (resp *pb.AuthRoleDeleteResponse, err error) { - rac.retryf(ctx, func(rctx context.Context) error { + err = rac.retryf(ctx, func(rctx context.Context) error { resp, err = rac.AuthClient.RoleDelete(rctx, in, opts...) return err }) @@ -227,7 +277,7 @@ func (rac *retryAuthClient) RoleDelete(ctx context.Context, in *pb.AuthRoleDelet } func (rac *retryAuthClient) RoleGrantPermission(ctx context.Context, in *pb.AuthRoleGrantPermissionRequest, opts ...grpc.CallOption) (resp *pb.AuthRoleGrantPermissionResponse, err error) { - rac.retryf(ctx, func(rctx context.Context) error { + err = rac.retryf(ctx, func(rctx context.Context) error { resp, err = rac.AuthClient.RoleGrantPermission(rctx, in, opts...) return err }) @@ -235,7 +285,7 @@ func (rac *retryAuthClient) RoleGrantPermission(ctx context.Context, in *pb.Auth } func (rac *retryAuthClient) RoleRevokePermission(ctx context.Context, in *pb.AuthRoleRevokePermissionRequest, opts ...grpc.CallOption) (resp *pb.AuthRoleRevokePermissionResponse, err error) { - rac.retryf(ctx, func(rctx context.Context) error { + err = rac.retryf(ctx, func(rctx context.Context) error { resp, err = rac.AuthClient.RoleRevokePermission(rctx, in, opts...) return err }) diff --git a/vendor/github.com/coreos/etcd/clientv3/txn.go b/vendor/github.com/coreos/etcd/clientv3/txn.go index a451e33ac..a61decd64 100644 --- a/vendor/github.com/coreos/etcd/clientv3/txn.go +++ b/vendor/github.com/coreos/etcd/clientv3/txn.go @@ -19,6 +19,7 @@ import ( pb "github.com/coreos/etcd/etcdserver/etcdserverpb" "golang.org/x/net/context" + "google.golang.org/grpc" ) // Txn is the interface that wraps mini-transactions. @@ -152,7 +153,12 @@ func (txn *txn) Commit() (*TxnResponse, error) { func (txn *txn) commit() (*TxnResponse, error) { r := &pb.TxnRequest{Compare: txn.cmps, Success: txn.sus, Failure: txn.fas} - resp, err := txn.kv.remote.Txn(txn.ctx, r) + + var opts []grpc.CallOption + if !txn.isWrite { + opts = []grpc.CallOption{grpc.FailFast(false)} + } + resp, err := txn.kv.remote.Txn(txn.ctx, r, opts...) if err != nil { return nil, err } diff --git a/vendor/github.com/coreos/etcd/clientv3/watch.go b/vendor/github.com/coreos/etcd/clientv3/watch.go index f6e45f9bf..5e00e163f 100644 --- a/vendor/github.com/coreos/etcd/clientv3/watch.go +++ b/vendor/github.com/coreos/etcd/clientv3/watch.go @@ -61,8 +61,8 @@ 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 + // Created is used to indicate the creation of the watcher. + Created bool closeErr error } @@ -92,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 && !wr.created && wr.CompactRevision == 0 && wr.Header.Revision != 0 + return len(wr.Events) == 0 && !wr.Canceled && !wr.Created && wr.CompactRevision == 0 && wr.Header.Revision != 0 } // watcher implements the Watcher interface @@ -101,6 +101,7 @@ type watcher struct { // mu protects the grpc streams map mu sync.RWMutex + // streams holds all the active grpc streams keyed by ctx value. streams map[string]*watchGrpcStream } @@ -131,6 +132,8 @@ type watchGrpcStream struct { errc chan error // closingc gets the watcherStream of closing watchers closingc chan *watcherStream + // wg is Done when all substream goroutines have exited + wg sync.WaitGroup // resumec closes to signal that all substreams should begin resuming resumec chan struct{} @@ -144,8 +147,12 @@ type watchRequest struct { key string end string rev int64 - // progressNotify is for progress updates. + // send created notification event if this field is true + createdNotify bool + // progressNotify is for progress updates progressNotify bool + // filters is the list of events to filter out + filters []pb.WatchCreateRequest_FilterType // get the previous key-value pair before the event happens prevKV bool // retc receives a chan WatchResponse once the watcher is established @@ -173,8 +180,12 @@ type watcherStream struct { } func NewWatcher(c *Client) Watcher { + return NewWatchFromWatchClient(pb.NewWatchClient(c.conn)) +} + +func NewWatchFromWatchClient(wc pb.WatchClient) Watcher { return &watcher{ - remote: pb.NewWatchClient(c.conn), + remote: wc, streams: make(map[string]*watchGrpcStream), } } @@ -215,12 +226,22 @@ func (w *watcher) newWatcherGrpcStream(inctx context.Context) *watchGrpcStream { func (w *watcher) Watch(ctx context.Context, key string, opts ...OpOption) WatchChan { ow := opWatch(key, opts...) + var filters []pb.WatchCreateRequest_FilterType + if ow.filterPut { + filters = append(filters, pb.WatchCreateRequest_NOPUT) + } + if ow.filterDelete { + filters = append(filters, pb.WatchCreateRequest_NODELETE) + } + wr := &watchRequest{ ctx: ctx, + createdNotify: ow.createdNotify, key: string(ow.key), end: string(ow.end), rev: ow.rev, progressNotify: ow.progressNotify, + filters: filters, prevKV: ow.prevKV, retc: make(chan chan WatchResponse, 1), } @@ -374,18 +395,20 @@ func (w *watchGrpcStream) run() { for _, ws := range w.substreams { if _, ok := closing[ws]; !ok { close(ws.recvc) + closing[ws] = struct{}{} } } for _, ws := range w.resuming { if _, ok := closing[ws]; ws != nil && !ok { close(ws.recvc) + closing[ws] = struct{}{} } } w.joinSubstreams() - for toClose := len(w.substreams) + len(w.resuming); toClose > 0; toClose-- { + for range closing { w.closeSubstream(<-w.closingc) } - + w.wg.Wait() w.owner.closeStream(w) }() @@ -410,6 +433,7 @@ func (w *watchGrpcStream) run() { } ws.donec = make(chan struct{}) + w.wg.Add(1) go w.serveSubstream(ws, w.resumec) // queue up for watcher creation/resume @@ -458,7 +482,7 @@ func (w *watchGrpcStream) run() { } // watch client failed to recv; spawn another if possible case err := <-w.errc: - if toErr(w.ctx, err) == v3rpc.ErrNoLeader { + if isHaltErr(w.ctx, err) || toErr(w.ctx, err) == v3rpc.ErrNoLeader { closeErr = err return } @@ -508,7 +532,7 @@ func (w *watchGrpcStream) dispatchEvent(pbresp *pb.WatchResponse) bool { Header: *pbresp.Header, Events: events, CompactRevision: pbresp.CompactRevision, - created: pbresp.Created, + Created: pbresp.Created, Canceled: pbresp.Canceled, } select { @@ -555,6 +579,7 @@ func (w *watchGrpcStream) serveSubstream(ws *watcherStream, resumec chan struct{ if !resuming { w.closingc <- ws } + w.wg.Done() }() emptyWr := &WatchResponse{} @@ -562,14 +587,6 @@ func (w *watchGrpcStream) serveSubstream(ws *watcherStream, resumec chan struct{ curWr := emptyWr outc := ws.outc - 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 { @@ -587,13 +604,35 @@ func (w *watchGrpcStream) serveSubstream(ws *watcherStream, resumec chan struct{ // shutdown from closeSubstream return } - // TODO pause channel if buffer gets too large - ws.buf = append(ws.buf, wr) + + if wr.Created { + if ws.initReq.retc != nil { + ws.initReq.retc <- ws.outc + // to prevent next write from taking the slot in buffered channel + // and posting duplicate create events + ws.initReq.retc = nil + + // send first creation event only if requested + if ws.initReq.createdNotify { + ws.outc <- *wr + } + } + } + nextRev = wr.Header.Revision if len(wr.Events) > 0 { nextRev = wr.Events[len(wr.Events)-1].Kv.ModRevision + 1 } ws.initReq.rev = nextRev + + // created event is already sent above, + // watcher should not post duplicate events + if wr.Created { + continue + } + + // TODO pause channel if buffer gets too large + ws.buf = append(ws.buf, wr) case <-w.ctx.Done(): return case <-ws.initReq.ctx.Done(): @@ -639,6 +678,7 @@ func (w *watchGrpcStream) newWatchClient() (pb.Watch_WatchClient, error) { continue } ws.donec = make(chan struct{}) + w.wg.Add(1) go w.serveSubstream(ws, w.resumec) } @@ -659,6 +699,10 @@ func (w *watchGrpcStream) waitCancelSubstreams(stopc <-chan struct{}) <-chan str go func(ws *watcherStream) { defer wg.Done() if ws.closing { + if ws.initReq.ctx.Err() != nil && ws.outc != nil { + close(ws.outc) + ws.outc = nil + } return } select { @@ -719,6 +763,7 @@ func (wr *watchRequest) toPB() *pb.WatchRequest { Key: []byte(wr.key), RangeEnd: []byte(wr.end), ProgressNotify: wr.progressNotify, + Filters: wr.filters, PrevKv: wr.prevKV, } cr := &pb.WatchRequest_CreateRequest{CreateRequest: req} diff --git a/vendor/github.com/coreos/etcd/compactor/compactor.go b/vendor/github.com/coreos/etcd/compactor/compactor.go index ad9be6e31..322a09870 100644 --- a/vendor/github.com/coreos/etcd/compactor/compactor.go +++ b/vendor/github.com/coreos/etcd/compactor/compactor.go @@ -26,7 +26,7 @@ import ( ) var ( - plog = capnslog.NewPackageLogger("github.com/coreos/etcd", "etcdserver") + plog = capnslog.NewPackageLogger("github.com/coreos/etcd", "compactor") ) const ( diff --git a/vendor/github.com/coreos/etcd/discovery/discovery.go b/vendor/github.com/coreos/etcd/discovery/discovery.go index d53c46114..edc842ffb 100644 --- a/vendor/github.com/coreos/etcd/discovery/discovery.go +++ b/vendor/github.com/coreos/etcd/discovery/discovery.go @@ -52,7 +52,8 @@ var ( var ( // Number of retries discovery will attempt before giving up and erroring out. - nRetries = uint(math.MaxUint32) + nRetries = uint(math.MaxUint32) + maxExpoentialRetries = uint(8) ) // JoinCluster will connect to the discovery service at the given url, and @@ -243,7 +244,7 @@ func (d *discovery) checkCluster() ([]*client.Node, int, uint64, error) { } return nil, 0, 0, err } - nodes := make([]*client.Node, 0) + var nodes []*client.Node // append non-config keys to nodes for _, n := range resp.Node.Nodes { if !(path.Base(n.Key) == path.Base(configKey)) { @@ -268,9 +269,14 @@ func (d *discovery) checkCluster() ([]*client.Node, int, uint64, error) { func (d *discovery) logAndBackoffForRetry(step string) { d.retries++ - retryTime := time.Second * (0x1 << d.retries) - plog.Infof("%s: error connecting to %s, retrying in %s", step, d.url, retryTime) - d.clock.Sleep(retryTime) + // logAndBackoffForRetry stops exponential backoff when the retries are more than maxExpoentialRetries and is set to a constant backoff afterward. + retries := d.retries + if retries > maxExpoentialRetries { + retries = maxExpoentialRetries + } + retryTimeInSecond := time.Duration(0x1< index { - w.WriteHeader(http.StatusOK) - w.Write([]byte(`{"health": "true"}`)) - return - } + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + if _, err := server.Do(ctx, etcdserverpb.Request{Method: "QGET"}); err != nil { + http.Error(w, `{"health": "false"}`, http.StatusServiceUnavailable) + return } - - http.Error(w, `{"health": "false"}`, http.StatusServiceUnavailable) - return + w.WriteHeader(http.StatusOK) + w.Write([]byte(`{"health": "true"}`)) } } @@ -449,19 +421,20 @@ func logHandleFunc(w http.ResponseWriter, r *http.Request) { // parseKeyRequest converts a received http.Request on keysPrefix to // a server Request, performing validation of supplied fields as appropriate. // If any validation fails, an empty Request and non-nil error is returned. -func parseKeyRequest(r *http.Request, clock clockwork.Clock) (etcdserverpb.Request, error) { +func parseKeyRequest(r *http.Request, clock clockwork.Clock) (etcdserverpb.Request, bool, error) { + noValueOnSuccess := false emptyReq := etcdserverpb.Request{} err := r.ParseForm() if err != nil { - return emptyReq, etcdErr.NewRequestError( + return emptyReq, false, etcdErr.NewRequestError( etcdErr.EcodeInvalidForm, err.Error(), ) } if !strings.HasPrefix(r.URL.Path, keysPrefix) { - return emptyReq, etcdErr.NewRequestError( + return emptyReq, false, etcdErr.NewRequestError( etcdErr.EcodeInvalidForm, "incorrect key prefix", ) @@ -470,13 +443,13 @@ func parseKeyRequest(r *http.Request, clock clockwork.Clock) (etcdserverpb.Reque var pIdx, wIdx uint64 if pIdx, err = getUint64(r.Form, "prevIndex"); err != nil { - return emptyReq, etcdErr.NewRequestError( + return emptyReq, false, etcdErr.NewRequestError( etcdErr.EcodeIndexNaN, `invalid value for "prevIndex"`, ) } if wIdx, err = getUint64(r.Form, "waitIndex"); err != nil { - return emptyReq, etcdErr.NewRequestError( + return emptyReq, false, etcdErr.NewRequestError( etcdErr.EcodeIndexNaN, `invalid value for "waitIndex"`, ) @@ -484,45 +457,45 @@ func parseKeyRequest(r *http.Request, clock clockwork.Clock) (etcdserverpb.Reque var rec, sort, wait, dir, quorum, stream bool if rec, err = getBool(r.Form, "recursive"); err != nil { - return emptyReq, etcdErr.NewRequestError( + return emptyReq, false, etcdErr.NewRequestError( etcdErr.EcodeInvalidField, `invalid value for "recursive"`, ) } if sort, err = getBool(r.Form, "sorted"); err != nil { - return emptyReq, etcdErr.NewRequestError( + return emptyReq, false, etcdErr.NewRequestError( etcdErr.EcodeInvalidField, `invalid value for "sorted"`, ) } if wait, err = getBool(r.Form, "wait"); err != nil { - return emptyReq, etcdErr.NewRequestError( + return emptyReq, false, etcdErr.NewRequestError( etcdErr.EcodeInvalidField, `invalid value for "wait"`, ) } // TODO(jonboulle): define what parameters dir is/isn't compatible with? if dir, err = getBool(r.Form, "dir"); err != nil { - return emptyReq, etcdErr.NewRequestError( + return emptyReq, false, etcdErr.NewRequestError( etcdErr.EcodeInvalidField, `invalid value for "dir"`, ) } if quorum, err = getBool(r.Form, "quorum"); err != nil { - return emptyReq, etcdErr.NewRequestError( + return emptyReq, false, etcdErr.NewRequestError( etcdErr.EcodeInvalidField, `invalid value for "quorum"`, ) } if stream, err = getBool(r.Form, "stream"); err != nil { - return emptyReq, etcdErr.NewRequestError( + return emptyReq, false, etcdErr.NewRequestError( etcdErr.EcodeInvalidField, `invalid value for "stream"`, ) } if wait && r.Method != "GET" { - return emptyReq, etcdErr.NewRequestError( + return emptyReq, false, etcdErr.NewRequestError( etcdErr.EcodeInvalidField, `"wait" can only be used with GET requests`, ) @@ -530,19 +503,26 @@ func parseKeyRequest(r *http.Request, clock clockwork.Clock) (etcdserverpb.Reque pV := r.FormValue("prevValue") if _, ok := r.Form["prevValue"]; ok && pV == "" { - return emptyReq, etcdErr.NewRequestError( + return emptyReq, false, etcdErr.NewRequestError( etcdErr.EcodePrevValueRequired, `"prevValue" cannot be empty`, ) } + if noValueOnSuccess, err = getBool(r.Form, "noValueOnSuccess"); err != nil { + return emptyReq, false, etcdErr.NewRequestError( + etcdErr.EcodeInvalidField, + `invalid value for "noValueOnSuccess"`, + ) + } + // TTL is nullable, so leave it null if not specified // or an empty string var ttl *uint64 if len(r.FormValue("ttl")) > 0 { i, err := getUint64(r.Form, "ttl") if err != nil { - return emptyReq, etcdErr.NewRequestError( + return emptyReq, false, etcdErr.NewRequestError( etcdErr.EcodeTTLNaN, `invalid value for "ttl"`, ) @@ -555,7 +535,7 @@ func parseKeyRequest(r *http.Request, clock clockwork.Clock) (etcdserverpb.Reque if _, ok := r.Form["prevExist"]; ok { bv, err := getBool(r.Form, "prevExist") if err != nil { - return emptyReq, etcdErr.NewRequestError( + return emptyReq, false, etcdErr.NewRequestError( etcdErr.EcodeInvalidField, "invalid value for prevExist", ) @@ -568,7 +548,7 @@ func parseKeyRequest(r *http.Request, clock clockwork.Clock) (etcdserverpb.Reque if _, ok := r.Form["refresh"]; ok { bv, err := getBool(r.Form, "refresh") if err != nil { - return emptyReq, etcdErr.NewRequestError( + return emptyReq, false, etcdErr.NewRequestError( etcdErr.EcodeInvalidField, "invalid value for refresh", ) @@ -577,13 +557,13 @@ func parseKeyRequest(r *http.Request, clock clockwork.Clock) (etcdserverpb.Reque if refresh != nil && *refresh { val := r.FormValue("value") if _, ok := r.Form["value"]; ok && val != "" { - return emptyReq, etcdErr.NewRequestError( + return emptyReq, false, etcdErr.NewRequestError( etcdErr.EcodeRefreshValue, `A value was provided on a refresh`, ) } if ttl == nil { - return emptyReq, etcdErr.NewRequestError( + return emptyReq, false, etcdErr.NewRequestError( etcdErr.EcodeRefreshTTLRequired, `No TTL value set`, ) @@ -621,13 +601,13 @@ func parseKeyRequest(r *http.Request, clock clockwork.Clock) (etcdserverpb.Reque rr.Expiration = clock.Now().Add(expr).UnixNano() } - return rr, nil + return rr, noValueOnSuccess, nil } // writeKeyEvent trims the prefix of key path in a single Event under // StoreKeysPrefix, serializes it and writes the resulting JSON to the given // ResponseWriter, along with the appropriate headers. -func writeKeyEvent(w http.ResponseWriter, ev *store.Event, rt etcdserver.RaftTimer) error { +func writeKeyEvent(w http.ResponseWriter, ev *store.Event, noValueOnSuccess bool, rt etcdserver.RaftTimer) error { if ev == nil { return errors.New("cannot write empty Event!") } @@ -641,6 +621,12 @@ func writeKeyEvent(w http.ResponseWriter, ev *store.Event, rt etcdserver.RaftTim } ev = trimEventPrefix(ev, etcdserver.StoreKeysPrefix) + if noValueOnSuccess && + (ev.Action == store.Set || ev.Action == store.CompareAndSwap || + ev.Action == store.Create || ev.Action == store.Update) { + ev.Node = nil + ev.PrevNode = nil + } return json.NewEncoder(w).Encode(ev) } @@ -747,6 +733,10 @@ func trimErrorPrefix(err error, prefix string) error { func unmarshalRequest(r *http.Request, req json.Unmarshaler, w http.ResponseWriter) bool { ctype := r.Header.Get("Content-Type") + semicolonPosition := strings.Index(ctype, ";") + if semicolonPosition != -1 { + ctype = strings.TrimSpace(strings.ToLower(ctype[0:semicolonPosition])) + } if ctype != "application/json" { writeError(w, r, httptypes.NewHTTPError(http.StatusUnsupportedMediaType, fmt.Sprintf("Bad Content-Type %s, accept application/json", ctype))) return false diff --git a/vendor/github.com/coreos/etcd/etcdserver/api/v2http/http.go b/vendor/github.com/coreos/etcd/etcdserver/api/v2http/http.go index cad9ec80d..62c99e19d 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/api/v2http/http.go +++ b/vendor/github.com/coreos/etcd/etcdserver/api/v2http/http.go @@ -35,7 +35,7 @@ const ( ) var ( - plog = capnslog.NewPackageLogger("github.com/coreos/etcd/etcdserver/api", "v2http") + plog = capnslog.NewPackageLogger("github.com/coreos/etcd", "etcdserver/api/v2http") mlog = logutil.NewMergeLogger(plog) ) @@ -60,7 +60,7 @@ func writeError(w http.ResponseWriter, r *http.Request, err error) { } default: switch err { - case etcdserver.ErrTimeoutDueToLeaderFail, etcdserver.ErrTimeoutDueToConnectionLost, etcdserver.ErrNotEnoughStartedMembers: + case etcdserver.ErrTimeoutDueToLeaderFail, etcdserver.ErrTimeoutDueToConnectionLost, etcdserver.ErrNotEnoughStartedMembers, etcdserver.ErrUnhealthy: mlog.MergeError(err) default: mlog.MergeErrorf("got unexpected response error (%v)", err) diff --git a/vendor/github.com/coreos/etcd/etcdserver/api/v2http/httptypes/errors.go b/vendor/github.com/coreos/etcd/etcdserver/api/v2http/httptypes/errors.go index a6c0f6d0b..0657604ca 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/api/v2http/httptypes/errors.go +++ b/vendor/github.com/coreos/etcd/etcdserver/api/v2http/httptypes/errors.go @@ -22,7 +22,7 @@ import ( ) var ( - plog = capnslog.NewPackageLogger("github.com/coreos/etcd/etcdserver/api/v2http", "httptypes") + plog = capnslog.NewPackageLogger("github.com/coreos/etcd", "etcdserver/api/v2http/httptypes") ) type HTTPError struct { diff --git a/vendor/github.com/coreos/etcd/etcdserver/api/v2http/peer.go b/vendor/github.com/coreos/etcd/etcdserver/api/v2http/peer.go index e8fa3b60a..a1abadba8 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/api/v2http/peer.go +++ b/vendor/github.com/coreos/etcd/etcdserver/api/v2http/peer.go @@ -26,14 +26,14 @@ import ( const ( peerMembersPrefix = "/members" - leasesPrefix = "/leases" ) // NewPeerHandler generates an http.Handler to handle etcd peer requests. func NewPeerHandler(s *etcdserver.EtcdServer) http.Handler { var lh http.Handler - if l := s.Lessor(); l != nil { - lh = leasehttp.NewHandler(l) + l := s.Lessor() + if l != nil { + lh = leasehttp.NewHandler(l, func() <-chan struct{} { return s.ApplyWait() }) } return newPeerHandler(s.Cluster(), s.RaftHandler(), lh) } @@ -49,7 +49,8 @@ func newPeerHandler(cluster api.Cluster, raftHandler http.Handler, leaseHandler mux.Handle(rafthttp.RaftPrefix+"/", raftHandler) mux.Handle(peerMembersPrefix, mh) if leaseHandler != nil { - mux.Handle(leasesPrefix, leaseHandler) + mux.Handle(leasehttp.LeasePrefix, leaseHandler) + mux.Handle(leasehttp.LeaseInternalPrefix, leaseHandler) } mux.HandleFunc(versionPath, versionHandler(cluster, serveVersion)) return mux diff --git a/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/grpc.go b/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/grpc.go index 07c65320b..88174e3ba 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/grpc.go +++ b/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/grpc.go @@ -19,14 +19,13 @@ import ( "github.com/coreos/etcd/etcdserver" pb "github.com/coreos/etcd/etcdserver/etcdserverpb" - "github.com/coreos/pkg/capnslog" "google.golang.org/grpc" "google.golang.org/grpc/credentials" "google.golang.org/grpc/grpclog" ) func init() { - grpclog.SetLogger(capnslog.NewPackageLogger("github.com/coreos/etcd/etcdserver", "v3rpc/grpc")) + grpclog.SetLogger(plog) } func Server(s *etcdserver.EtcdServer, tls *tls.Config) *grpc.Server { diff --git a/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/interceptor.go b/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/interceptor.go index f18f13626..29aef2914 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/interceptor.go +++ b/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/interceptor.go @@ -15,7 +15,6 @@ package v3rpc import ( - "strings" "sync" "time" @@ -25,6 +24,7 @@ import ( "github.com/coreos/etcd/pkg/types" "github.com/coreos/etcd/raft" + prometheus "github.com/grpc-ecosystem/go-grpc-prometheus" "golang.org/x/net/context" "google.golang.org/grpc" "google.golang.org/grpc/metadata" @@ -53,7 +53,8 @@ func newUnaryInterceptor(s *etcdserver.EtcdServer) grpc.UnaryServerInterceptor { } } } - return metricsUnaryInterceptor(ctx, req, info, handler) + + return prometheus.UnaryServerInterceptor(ctx, req, info, handler) } } @@ -88,44 +89,11 @@ func newStreamInterceptor(s *etcdserver.EtcdServer) grpc.StreamServerInterceptor } } - return metricsStreamInterceptor(srv, ss, info, handler) + + return prometheus.StreamServerInterceptor(srv, ss, info, handler) } } -func metricsUnaryInterceptor(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp interface{}, err error) { - service, method := splitMethodName(info.FullMethod) - receivedCounter.WithLabelValues(service, method).Inc() - - start := time.Now() - resp, err = handler(ctx, req) - if err != nil { - failedCounter.WithLabelValues(service, method, grpc.Code(err).String()).Inc() - } - handlingDuration.WithLabelValues(service, method).Observe(time.Since(start).Seconds()) - - return resp, err -} - -func metricsStreamInterceptor(srv interface{}, ss grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error { - service, method := splitMethodName(info.FullMethod) - receivedCounter.WithLabelValues(service, method).Inc() - - err := handler(srv, ss) - if err != nil { - failedCounter.WithLabelValues(service, method, grpc.Code(err).String()).Inc() - } - - return err -} - -func splitMethodName(fullMethodName string) (string, string) { - fullMethodName = strings.TrimPrefix(fullMethodName, "/") // remove leading slash - if i := strings.Index(fullMethodName, "/"); i >= 0 { - return fullMethodName[:i], fullMethodName[i+1:] - } - return "unknown", "unknown" -} - type serverStreamWithCtx struct { grpc.ServerStream ctx context.Context diff --git a/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/key.go b/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/key.go index 94875ff2b..6ea7bbacd 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/key.go +++ b/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/key.go @@ -26,7 +26,7 @@ import ( ) var ( - plog = capnslog.NewPackageLogger("github.com/coreos/etcd/etcdserver/api", "v3rpc") + plog = capnslog.NewPackageLogger("github.com/coreos/etcd", "etcdserver/api/v3rpc") // Max operations per txn list. For example, Txn.Success can have at most 128 operations, // and Txn.Failure can have at most 128 operations. @@ -56,7 +56,7 @@ func (s *kvServer) Range(ctx context.Context, r *pb.RangeRequest) (*pb.RangeResp plog.Panic("unexpected nil resp.Header") } s.hdr.fill(resp.Header) - return resp, err + return resp, nil } func (s *kvServer) Put(ctx context.Context, r *pb.PutRequest) (*pb.PutResponse, error) { @@ -73,7 +73,7 @@ func (s *kvServer) Put(ctx context.Context, r *pb.PutRequest) (*pb.PutResponse, plog.Panic("unexpected nil resp.Header") } s.hdr.fill(resp.Header) - return resp, err + return resp, nil } func (s *kvServer) DeleteRange(ctx context.Context, r *pb.DeleteRangeRequest) (*pb.DeleteRangeResponse, error) { @@ -90,7 +90,7 @@ func (s *kvServer) DeleteRange(ctx context.Context, r *pb.DeleteRangeRequest) (* plog.Panic("unexpected nil resp.Header") } s.hdr.fill(resp.Header) - return resp, err + return resp, nil } func (s *kvServer) Txn(ctx context.Context, r *pb.TxnRequest) (*pb.TxnResponse, error) { @@ -107,7 +107,7 @@ func (s *kvServer) Txn(ctx context.Context, r *pb.TxnRequest) (*pb.TxnResponse, plog.Panic("unexpected nil resp.Header") } s.hdr.fill(resp.Header) - return resp, err + return resp, nil } func (s *kvServer) Compact(ctx context.Context, r *pb.CompactionRequest) (*pb.CompactionResponse, error) { diff --git a/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/lease.go b/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/lease.go index c761f79c3..be6e20b97 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/lease.go +++ b/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/lease.go @@ -18,7 +18,6 @@ import ( "io" "github.com/coreos/etcd/etcdserver" - "github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes" pb "github.com/coreos/etcd/etcdserver/etcdserverpb" "github.com/coreos/etcd/lease" "golang.org/x/net/context" @@ -35,20 +34,27 @@ func NewLeaseServer(s *etcdserver.EtcdServer) pb.LeaseServer { func (ls *LeaseServer) LeaseGrant(ctx context.Context, cr *pb.LeaseGrantRequest) (*pb.LeaseGrantResponse, error) { resp, err := ls.le.LeaseGrant(ctx, cr) - if err == lease.ErrLeaseExists { - return nil, rpctypes.ErrGRPCLeaseExist - } + if err != nil { - return nil, err + return nil, togRPCError(err) } ls.hdr.fill(resp.Header) - return resp, err + return resp, nil } func (ls *LeaseServer) LeaseRevoke(ctx context.Context, rr *pb.LeaseRevokeRequest) (*pb.LeaseRevokeResponse, error) { resp, err := ls.le.LeaseRevoke(ctx, rr) if err != nil { - return nil, rpctypes.ErrGRPCLeaseNotFound + return nil, togRPCError(err) + } + ls.hdr.fill(resp.Header) + return resp, nil +} + +func (ls *LeaseServer) LeaseTimeToLive(ctx context.Context, rr *pb.LeaseTimeToLiveRequest) (*pb.LeaseTimeToLiveResponse, error) { + resp, err := ls.le.LeaseTimeToLive(ctx, rr) + if err != nil { + return nil, togRPCError(err) } ls.hdr.fill(resp.Header) return resp, nil diff --git a/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/maintenance.go b/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/maintenance.go index 20af20fc3..a59e6f9a0 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/maintenance.go +++ b/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/maintenance.go @@ -18,6 +18,7 @@ import ( "crypto/sha256" "io" + "github.com/coreos/etcd/auth" "github.com/coreos/etcd/etcdserver" pb "github.com/coreos/etcd/etcdserver/etcdserverpb" "github.com/coreos/etcd/mvcc" @@ -45,6 +46,10 @@ type RaftStatusGetter interface { Leader() types.ID } +type AuthGetter interface { + AuthStore() auth.AuthStore +} + type maintenanceServer struct { rg RaftStatusGetter kg KVGetter @@ -54,7 +59,8 @@ type maintenanceServer struct { } func NewMaintenanceServer(s *etcdserver.EtcdServer) pb.MaintenanceServer { - return &maintenanceServer{rg: s, kg: s, bg: s, a: s, hdr: newHeader(s)} + srv := &maintenanceServer{rg: s, kg: s, bg: s, a: s, hdr: newHeader(s)} + return &authMaintenanceServer{srv, s} } func (ms *maintenanceServer) Defragment(ctx context.Context, sr *pb.DefragmentRequest) (*pb.DefragmentResponse, error) { @@ -139,3 +145,49 @@ func (ms *maintenanceServer) Status(ctx context.Context, ar *pb.StatusRequest) ( ms.hdr.fill(resp.Header) return resp, nil } + +type authMaintenanceServer struct { + *maintenanceServer + ag AuthGetter +} + +func (ams *authMaintenanceServer) isAuthenticated(ctx context.Context) error { + authInfo, err := ams.ag.AuthStore().AuthInfoFromCtx(ctx) + if err != nil { + return err + } + + return ams.ag.AuthStore().IsAdminPermitted(authInfo) +} + +func (ams *authMaintenanceServer) Defragment(ctx context.Context, sr *pb.DefragmentRequest) (*pb.DefragmentResponse, error) { + if err := ams.isAuthenticated(ctx); err != nil { + return nil, err + } + + return ams.maintenanceServer.Defragment(ctx, sr) +} + +func (ams *authMaintenanceServer) Snapshot(sr *pb.SnapshotRequest, srv pb.Maintenance_SnapshotServer) error { + if err := ams.isAuthenticated(srv.Context()); err != nil { + return err + } + + return ams.maintenanceServer.Snapshot(sr, srv) +} + +func (ams *authMaintenanceServer) Hash(ctx context.Context, r *pb.HashRequest) (*pb.HashResponse, error) { + if err := ams.isAuthenticated(ctx); err != nil { + return nil, err + } + + return ams.maintenanceServer.Hash(ctx, r) +} + +func (ams *authMaintenanceServer) Status(ctx context.Context, ar *pb.StatusRequest) (*pb.StatusResponse, error) { + if err := ams.isAuthenticated(ctx); err != nil { + return nil, err + } + + return ams.maintenanceServer.Status(ctx, ar) +} diff --git a/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/member.go b/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/member.go index e5e769236..bcd5dac51 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/member.go +++ b/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/member.go @@ -24,8 +24,6 @@ import ( "github.com/coreos/etcd/etcdserver/membership" "github.com/coreos/etcd/pkg/types" "golang.org/x/net/context" - "google.golang.org/grpc" - "google.golang.org/grpc/codes" ) type ClusterServer struct { @@ -50,14 +48,8 @@ func (cs *ClusterServer) MemberAdd(ctx context.Context, r *pb.MemberAddRequest) now := time.Now() m := membership.NewMember("", urls, "", &now) - err = cs.server.AddMember(ctx, *m) - switch { - case err == membership.ErrIDExists: - return nil, rpctypes.ErrGRPCMemberExist - case err == membership.ErrPeerURLexists: - return nil, rpctypes.ErrGRPCPeerURLExist - case err != nil: - return nil, grpc.Errorf(codes.Internal, err.Error()) + if err = cs.server.AddMember(ctx, *m); err != nil { + return nil, togRPCError(err) } return &pb.MemberAddResponse{ @@ -67,16 +59,9 @@ func (cs *ClusterServer) MemberAdd(ctx context.Context, r *pb.MemberAddRequest) } func (cs *ClusterServer) MemberRemove(ctx context.Context, r *pb.MemberRemoveRequest) (*pb.MemberRemoveResponse, error) { - err := cs.server.RemoveMember(ctx, r.ID) - switch { - case err == membership.ErrIDRemoved: - fallthrough - case err == membership.ErrIDNotFound: - return nil, rpctypes.ErrGRPCMemberNotFound - case err != nil: - return nil, grpc.Errorf(codes.Internal, err.Error()) + if err := cs.server.RemoveMember(ctx, r.ID); err != nil { + return nil, togRPCError(err) } - return &pb.MemberRemoveResponse{Header: cs.header()}, nil } @@ -85,16 +70,9 @@ func (cs *ClusterServer) MemberUpdate(ctx context.Context, r *pb.MemberUpdateReq ID: types.ID(r.ID), RaftAttributes: membership.RaftAttributes{PeerURLs: r.PeerURLs}, } - err := cs.server.UpdateMember(ctx, m) - switch { - case err == membership.ErrPeerURLexists: - return nil, rpctypes.ErrGRPCPeerURLExist - case err == membership.ErrIDNotFound: - return nil, rpctypes.ErrGRPCMemberNotFound - case err != nil: - return nil, grpc.Errorf(codes.Internal, err.Error()) + if err := cs.server.UpdateMember(ctx, m); err != nil { + return nil, togRPCError(err) } - return &pb.MemberUpdateResponse{Header: cs.header()}, nil } diff --git a/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/metrics.go b/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/metrics.go index cce80b435..6cb41a61e 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/metrics.go +++ b/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/metrics.go @@ -17,31 +17,6 @@ package v3rpc import "github.com/prometheus/client_golang/prometheus" var ( - receivedCounter = prometheus.NewCounterVec( - prometheus.CounterOpts{ - Namespace: "etcd", - Subsystem: "grpc", - Name: "requests_total", - Help: "Counter of received requests.", - }, []string{"grpc_service", "grpc_method"}) - - failedCounter = prometheus.NewCounterVec( - prometheus.CounterOpts{ - Namespace: "etcd", - Subsystem: "grpc", - Name: "requests_failed_total", - Help: "Counter of failed requests.", - }, []string{"grpc_service", "grpc_method", "grpc_code"}) - - handlingDuration = prometheus.NewHistogramVec( - prometheus.HistogramOpts{ - Namespace: "etcd", - Subsystem: "grpc", - Name: "unary_requests_duration_seconds", - Help: "Bucketed histogram of processing time (s) of handled unary (non-stream) requests.", - Buckets: prometheus.ExponentialBuckets(0.0005, 2, 13), - }, []string{"grpc_service", "grpc_method"}) - sentBytes = prometheus.NewCounter(prometheus.CounterOpts{ Namespace: "etcd", Subsystem: "network", @@ -58,10 +33,6 @@ var ( ) func init() { - prometheus.MustRegister(receivedCounter) - prometheus.MustRegister(failedCounter) - prometheus.MustRegister(handlingDuration) - prometheus.MustRegister(sentBytes) prometheus.MustRegister(receivedBytes) } diff --git a/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes/error.go b/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes/error.go index 97c75620e..5a3cfc0a0 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes/error.go +++ b/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes/error.go @@ -31,23 +31,28 @@ var ( ErrGRPCLeaseNotFound = grpc.Errorf(codes.NotFound, "etcdserver: requested lease not found") ErrGRPCLeaseExist = grpc.Errorf(codes.FailedPrecondition, "etcdserver: lease already exists") - ErrGRPCMemberExist = grpc.Errorf(codes.FailedPrecondition, "etcdserver: member ID already exist") - ErrGRPCPeerURLExist = grpc.Errorf(codes.FailedPrecondition, "etcdserver: Peer URLs already exists") - ErrGRPCMemberBadURLs = grpc.Errorf(codes.InvalidArgument, "etcdserver: given member URLs are invalid") - ErrGRPCMemberNotFound = grpc.Errorf(codes.NotFound, "etcdserver: member not found") + ErrGRPCMemberExist = grpc.Errorf(codes.FailedPrecondition, "etcdserver: member ID already exist") + ErrGRPCPeerURLExist = grpc.Errorf(codes.FailedPrecondition, "etcdserver: Peer URLs already exists") + ErrGRPCMemberNotEnoughStarted = grpc.Errorf(codes.FailedPrecondition, "etcdserver: re-configuration failed due to not enough started members") + ErrGRPCMemberBadURLs = grpc.Errorf(codes.InvalidArgument, "etcdserver: given member URLs are invalid") + ErrGRPCMemberNotFound = grpc.Errorf(codes.NotFound, "etcdserver: member not found") - ErrGRPCRequestTooLarge = grpc.Errorf(codes.InvalidArgument, "etcdserver: request is too large") + ErrGRPCRequestTooLarge = grpc.Errorf(codes.InvalidArgument, "etcdserver: request is too large") + ErrGRPCRequestTooManyRequests = grpc.Errorf(codes.ResourceExhausted, "etcdserver: too many requests") ErrGRPCRootUserNotExist = grpc.Errorf(codes.FailedPrecondition, "etcdserver: root user does not exist") ErrGRPCRootRoleNotExist = grpc.Errorf(codes.FailedPrecondition, "etcdserver: root user does not have root role") ErrGRPCUserAlreadyExist = grpc.Errorf(codes.FailedPrecondition, "etcdserver: user name already exists") + ErrGRPCUserEmpty = grpc.Errorf(codes.InvalidArgument, "etcdserver: user name is empty") ErrGRPCUserNotFound = grpc.Errorf(codes.FailedPrecondition, "etcdserver: user name not found") ErrGRPCRoleAlreadyExist = grpc.Errorf(codes.FailedPrecondition, "etcdserver: role name already exists") ErrGRPCRoleNotFound = grpc.Errorf(codes.FailedPrecondition, "etcdserver: role name not found") ErrGRPCAuthFailed = grpc.Errorf(codes.InvalidArgument, "etcdserver: authentication failed, invalid user ID or password") - ErrGRPCPermissionDenied = grpc.Errorf(codes.FailedPrecondition, "etcdserver: permission denied") + ErrGRPCPermissionDenied = grpc.Errorf(codes.PermissionDenied, "etcdserver: permission denied") ErrGRPCRoleNotGranted = grpc.Errorf(codes.FailedPrecondition, "etcdserver: role is not granted to the user") ErrGRPCPermissionNotGranted = grpc.Errorf(codes.FailedPrecondition, "etcdserver: permission is not granted to the role") + ErrGRPCAuthNotEnabled = grpc.Errorf(codes.FailedPrecondition, "etcdserver: authentication is not enabled") + ErrGRPCInvalidAuthToken = grpc.Errorf(codes.Unauthenticated, "etcdserver: invalid auth token") ErrGRPCNoLeader = grpc.Errorf(codes.Unavailable, "etcdserver: no leader") ErrGRPCNotCapable = grpc.Errorf(codes.Unavailable, "etcdserver: not capable") @@ -68,16 +73,19 @@ var ( grpc.ErrorDesc(ErrGRPCLeaseNotFound): ErrGRPCLeaseNotFound, grpc.ErrorDesc(ErrGRPCLeaseExist): ErrGRPCLeaseExist, - grpc.ErrorDesc(ErrGRPCMemberExist): ErrGRPCMemberExist, - grpc.ErrorDesc(ErrGRPCPeerURLExist): ErrGRPCPeerURLExist, - grpc.ErrorDesc(ErrGRPCMemberBadURLs): ErrGRPCMemberBadURLs, - grpc.ErrorDesc(ErrGRPCMemberNotFound): ErrGRPCMemberNotFound, + grpc.ErrorDesc(ErrGRPCMemberExist): ErrGRPCMemberExist, + grpc.ErrorDesc(ErrGRPCPeerURLExist): ErrGRPCPeerURLExist, + grpc.ErrorDesc(ErrGRPCMemberNotEnoughStarted): ErrGRPCMemberNotEnoughStarted, + grpc.ErrorDesc(ErrGRPCMemberBadURLs): ErrGRPCMemberBadURLs, + grpc.ErrorDesc(ErrGRPCMemberNotFound): ErrGRPCMemberNotFound, - grpc.ErrorDesc(ErrGRPCRequestTooLarge): ErrGRPCRequestTooLarge, + grpc.ErrorDesc(ErrGRPCRequestTooLarge): ErrGRPCRequestTooLarge, + grpc.ErrorDesc(ErrGRPCRequestTooManyRequests): ErrGRPCRequestTooManyRequests, grpc.ErrorDesc(ErrGRPCRootUserNotExist): ErrGRPCRootUserNotExist, grpc.ErrorDesc(ErrGRPCRootRoleNotExist): ErrGRPCRootRoleNotExist, grpc.ErrorDesc(ErrGRPCUserAlreadyExist): ErrGRPCUserAlreadyExist, + grpc.ErrorDesc(ErrGRPCUserEmpty): ErrGRPCUserEmpty, grpc.ErrorDesc(ErrGRPCUserNotFound): ErrGRPCUserNotFound, grpc.ErrorDesc(ErrGRPCRoleAlreadyExist): ErrGRPCRoleAlreadyExist, grpc.ErrorDesc(ErrGRPCRoleNotFound): ErrGRPCRoleNotFound, @@ -85,6 +93,8 @@ var ( grpc.ErrorDesc(ErrGRPCPermissionDenied): ErrGRPCPermissionDenied, grpc.ErrorDesc(ErrGRPCRoleNotGranted): ErrGRPCRoleNotGranted, grpc.ErrorDesc(ErrGRPCPermissionNotGranted): ErrGRPCPermissionNotGranted, + grpc.ErrorDesc(ErrGRPCAuthNotEnabled): ErrGRPCAuthNotEnabled, + grpc.ErrorDesc(ErrGRPCInvalidAuthToken): ErrGRPCInvalidAuthToken, grpc.ErrorDesc(ErrGRPCNoLeader): ErrGRPCNoLeader, grpc.ErrorDesc(ErrGRPCNotCapable): ErrGRPCNotCapable, @@ -106,16 +116,19 @@ var ( ErrLeaseNotFound = Error(ErrGRPCLeaseNotFound) ErrLeaseExist = Error(ErrGRPCLeaseExist) - ErrMemberExist = Error(ErrGRPCMemberExist) - ErrPeerURLExist = Error(ErrGRPCPeerURLExist) - ErrMemberBadURLs = Error(ErrGRPCMemberBadURLs) - ErrMemberNotFound = Error(ErrGRPCMemberNotFound) + ErrMemberExist = Error(ErrGRPCMemberExist) + ErrPeerURLExist = Error(ErrGRPCPeerURLExist) + ErrMemberNotEnoughStarted = Error(ErrGRPCMemberNotEnoughStarted) + ErrMemberBadURLs = Error(ErrGRPCMemberBadURLs) + ErrMemberNotFound = Error(ErrGRPCMemberNotFound) ErrRequestTooLarge = Error(ErrGRPCRequestTooLarge) + ErrTooManyRequests = Error(ErrGRPCRequestTooManyRequests) ErrRootUserNotExist = Error(ErrGRPCRootUserNotExist) ErrRootRoleNotExist = Error(ErrGRPCRootRoleNotExist) ErrUserAlreadyExist = Error(ErrGRPCUserAlreadyExist) + ErrUserEmpty = Error(ErrGRPCUserEmpty) ErrUserNotFound = Error(ErrGRPCUserNotFound) ErrRoleAlreadyExist = Error(ErrGRPCRoleAlreadyExist) ErrRoleNotFound = Error(ErrGRPCRoleNotFound) @@ -123,6 +136,8 @@ var ( ErrPermissionDenied = Error(ErrGRPCPermissionDenied) ErrRoleNotGranted = Error(ErrGRPCRoleNotGranted) ErrPermissionNotGranted = Error(ErrGRPCPermissionNotGranted) + ErrAuthNotEnabled = Error(ErrGRPCAuthNotEnabled) + ErrInvalidAuthToken = Error(ErrGRPCInvalidAuthToken) ErrNoLeader = Error(ErrGRPCNoLeader) ErrNotCapable = Error(ErrGRPCNotCapable) diff --git a/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/util.go b/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/util.go index 47f7e85f0..5a057ed04 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/util.go +++ b/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/util.go @@ -18,6 +18,7 @@ import ( "github.com/coreos/etcd/auth" "github.com/coreos/etcd/etcdserver" "github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes" + "github.com/coreos/etcd/etcdserver/membership" "github.com/coreos/etcd/lease" "github.com/coreos/etcd/mvcc" "google.golang.org/grpc" @@ -26,17 +27,29 @@ import ( func togRPCError(err error) error { switch err { + case membership.ErrIDRemoved: + return rpctypes.ErrGRPCMemberNotFound + case membership.ErrIDNotFound: + return rpctypes.ErrGRPCMemberNotFound + case membership.ErrIDExists: + return rpctypes.ErrGRPCMemberExist + case membership.ErrPeerURLexists: + return rpctypes.ErrGRPCPeerURLExist + case etcdserver.ErrNotEnoughStartedMembers: + return rpctypes.ErrMemberNotEnoughStarted + case mvcc.ErrCompacted: return rpctypes.ErrGRPCCompacted case mvcc.ErrFutureRev: return rpctypes.ErrGRPCFutureRev case lease.ErrLeaseNotFound: return rpctypes.ErrGRPCLeaseNotFound - // TODO: handle error from raft and timeout case etcdserver.ErrRequestTooLarge: return rpctypes.ErrGRPCRequestTooLarge case etcdserver.ErrNoSpace: return rpctypes.ErrGRPCNoSpace + case etcdserver.ErrTooManyRequests: + return rpctypes.ErrTooManyRequests case etcdserver.ErrNoLeader: return rpctypes.ErrGRPCNoLeader @@ -48,6 +61,13 @@ func togRPCError(err error) error { return rpctypes.ErrGRPCTimeoutDueToLeaderFail case etcdserver.ErrTimeoutDueToConnectionLost: return rpctypes.ErrGRPCTimeoutDueToConnectionLost + case etcdserver.ErrUnhealthy: + return rpctypes.ErrGRPCUnhealthy + + case lease.ErrLeaseNotFound: + return rpctypes.ErrGRPCLeaseNotFound + case lease.ErrLeaseExists: + return rpctypes.ErrGRPCLeaseExist case auth.ErrRootUserNotExist: return rpctypes.ErrGRPCRootUserNotExist @@ -55,6 +75,8 @@ func togRPCError(err error) error { return rpctypes.ErrGRPCRootRoleNotExist case auth.ErrUserAlreadyExist: return rpctypes.ErrGRPCUserAlreadyExist + case auth.ErrUserEmpty: + return rpctypes.ErrGRPCUserEmpty case auth.ErrUserNotFound: return rpctypes.ErrGRPCUserNotFound case auth.ErrRoleAlreadyExist: @@ -69,7 +91,11 @@ func togRPCError(err error) error { return rpctypes.ErrGRPCRoleNotGranted case auth.ErrPermissionNotGranted: return rpctypes.ErrGRPCPermissionNotGranted + case auth.ErrAuthNotEnabled: + return rpctypes.ErrGRPCAuthNotEnabled + case auth.ErrInvalidAuthToken: + return rpctypes.ErrGRPCInvalidAuthToken default: - return grpc.Errorf(codes.Internal, err.Error()) + return grpc.Errorf(codes.Unknown, err.Error()) } } 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 0565aa451..f0215531d 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/watch.go +++ b/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/watch.go @@ -92,6 +92,7 @@ type serverWatchStream struct { mu sync.Mutex // progress tracks the watchID that stream might need to send // progress to. + // TODO: combine progress and prevKV into a single struct? progress map[mvcc.WatchID]bool prevKV map[mvcc.WatchID]bool @@ -130,10 +131,14 @@ func (ws *watchServer) Watch(stream pb.Watch_WatchServer) (err error) { // but when stream.Context().Done() is closed, the stream's recv // may continue to block since it uses a different context, leading to // deadlock when calling sws.close(). - go func() { errc <- sws.recvLoop() }() - + go func() { + if rerr := sws.recvLoop(); rerr != nil { + errc <- rerr + } + }() select { case err = <-errc: + close(sws.ctrlStream) case <-stream.Context().Done(): err = stream.Context().Err() // the only server-side cancellation is noleader for now. @@ -146,7 +151,6 @@ func (ws *watchServer) Watch(stream pb.Watch_WatchServer) (err error) { } func (sws *serverWatchStream) recvLoop() error { - defer close(sws.ctrlStream) for { req, err := sws.gRPCStream.Recv() if err == io.EOF { @@ -171,12 +175,14 @@ func (sws *serverWatchStream) recvLoop() error { // support >= key queries creq.RangeEnd = []byte{} } + filters := FiltersFromRequest(creq) + wsrev := sws.watchStream.Rev() rev := creq.StartRevision if rev == 0 { rev = wsrev + 1 } - id := sws.watchStream.Watch(creq.Key, creq.RangeEnd, rev) + id := sws.watchStream.Watch(creq.Key, creq.RangeEnd, rev, filters...) if id != -1 { sws.mu.Lock() if creq.ProgressNotify { @@ -353,3 +359,25 @@ func (sws *serverWatchStream) newResponseHeader(rev int64) *pb.ResponseHeader { RaftTerm: sws.raftTimer.Term(), } } + +func filterNoDelete(e mvccpb.Event) bool { + return e.Type == mvccpb.DELETE +} + +func filterNoPut(e mvccpb.Event) bool { + return e.Type == mvccpb.PUT +} + +func FiltersFromRequest(creq *pb.WatchCreateRequest) []mvcc.FilterFunc { + filters := make([]mvcc.FilterFunc, 0, len(creq.Filters)) + for _, ft := range creq.Filters { + switch ft { + case pb.WatchCreateRequest_NOPUT: + filters = append(filters, filterNoPut) + case pb.WatchCreateRequest_NODELETE: + filters = append(filters, filterNoDelete) + default: + } + } + return filters +} diff --git a/vendor/github.com/coreos/etcd/etcdserver/apply.go b/vendor/github.com/coreos/etcd/etcdserver/apply.go index ed2027c82..e665c8bb8 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/apply.go +++ b/vendor/github.com/coreos/etcd/etcdserver/apply.go @@ -35,7 +35,7 @@ const ( // to apply functions instead of a valid txn ID. noTxn = -1 - warnApplyDuration = 10 * time.Millisecond + warnApplyDuration = 100 * time.Millisecond ) type applyResult struct { @@ -258,7 +258,9 @@ func (a *applierV3backend) Range(txnID int64, r *pb.RangeRequest) (*pb.RangeResp } limit := r.Limit - if r.SortOrder != pb.RangeRequest_NONE { + if r.SortOrder != pb.RangeRequest_NONE || + r.MinModRevision != 0 || r.MaxModRevision != 0 || + r.MinCreateRevision != 0 || r.MaxCreateRevision != 0 { // fetch everything; sort and truncate afterwards limit = 0 } @@ -285,7 +287,31 @@ func (a *applierV3backend) Range(txnID int64, r *pb.RangeRequest) (*pb.RangeResp } } - if r.SortOrder != pb.RangeRequest_NONE { + if r.MaxModRevision != 0 { + f := func(kv *mvccpb.KeyValue) bool { return kv.ModRevision > r.MaxModRevision } + pruneKVs(rr, f) + } + if r.MinModRevision != 0 { + f := func(kv *mvccpb.KeyValue) bool { return kv.ModRevision < r.MinModRevision } + pruneKVs(rr, f) + } + if r.MaxCreateRevision != 0 { + f := func(kv *mvccpb.KeyValue) bool { return kv.CreateRevision > r.MaxCreateRevision } + pruneKVs(rr, f) + } + if r.MinCreateRevision != 0 { + f := func(kv *mvccpb.KeyValue) bool { return kv.CreateRevision < r.MinCreateRevision } + pruneKVs(rr, f) + } + + sortOrder := r.SortOrder + if r.SortTarget != pb.RangeRequest_KEY && sortOrder == pb.RangeRequest_NONE { + // Since current mvcc.Range implementation returns results + // sorted by keys in lexiographically ascending order, + // sort ASCEND by default only when target is not 'KEY' + sortOrder = pb.RangeRequest_ASCEND + } + if sortOrder != pb.RangeRequest_NONE { var sorter sort.Interface switch { case r.SortTarget == pb.RangeRequest_KEY: @@ -300,9 +326,9 @@ func (a *applierV3backend) Range(txnID int64, r *pb.RangeRequest) (*pb.RangeResp sorter = &kvSortByValue{&kvSort{rr.KVs}} } switch { - case r.SortOrder == pb.RangeRequest_ASCEND: + case sortOrder == pb.RangeRequest_ASCEND: sort.Sort(sorter) - case r.SortOrder == pb.RangeRequest_DESCEND: + case sortOrder == pb.RangeRequest_DESCEND: sort.Sort(sort.Reverse(sorter)) } } @@ -345,34 +371,23 @@ func (a *applierV3backend) Txn(rt *pb.TxnRequest) (*pb.TxnResponse, error) { return nil, err } - revision := a.s.KV().Rev() - // When executing the operations of txn, we need to hold the txn lock. // So the reader will not see any intermediate results. txnID := a.s.KV().TxnBegin() - defer func() { - err := a.s.KV().TxnEnd(txnID) - if err != nil { - panic(fmt.Sprint("unexpected error when closing txn", txnID)) - } - }() resps := make([]*pb.ResponseOp, len(reqs)) - changedKV := false for i := range reqs { - if reqs[i].GetRequestRange() == nil { - changedKV = true - } resps[i] = a.applyUnion(txnID, reqs[i]) } - if changedKV { - revision += 1 + err := a.s.KV().TxnEnd(txnID) + if err != nil { + panic(fmt.Sprint("unexpected error when closing txn", txnID)) } txnResp := &pb.TxnResponse{} txnResp.Header = &pb.ResponseHeader{} - txnResp.Header.Revision = revision + txnResp.Header.Revision = a.s.KV().Rev() txnResp.Responses = resps txnResp.Succeeded = ok return txnResp, nil @@ -436,6 +451,10 @@ func (a *applierV3backend) applyCompare(c *pb.Compare) (int64, bool) { if result != 0 { return rev, false } + case pb.Compare_NOT_EQUAL: + if result == 0 { + return rev, false + } case pb.Compare_GREATER: if result != 1 { return rev, false @@ -454,7 +473,7 @@ func (a *applierV3backend) applyUnion(txnID int64, union *pb.RequestOp) *pb.Resp if tv.RequestRange != nil { resp, err := a.Range(txnID, tv.RequestRange) if err != nil { - panic("unexpected error during txn") + plog.Panicf("unexpected error during txn: %v", err) } return &pb.ResponseOp{Response: &pb.ResponseOp_ResponseRange{ResponseRange: resp}} } @@ -462,7 +481,7 @@ func (a *applierV3backend) applyUnion(txnID int64, union *pb.RequestOp) *pb.Resp if tv.RequestPut != nil { resp, err := a.Put(txnID, tv.RequestPut) if err != nil { - panic("unexpected error during txn") + plog.Panicf("unexpected error during txn: %v", err) } return &pb.ResponseOp{Response: &pb.ResponseOp_ResponsePut{ResponsePut: resp}} } @@ -470,7 +489,7 @@ func (a *applierV3backend) applyUnion(txnID int64, union *pb.RequestOp) *pb.Resp if tv.RequestDeleteRange != nil { resp, err := a.DeleteRange(txnID, tv.RequestDeleteRange) if err != nil { - panic("unexpected error during txn") + plog.Panicf("unexpected error during txn: %v", err) } return &pb.ResponseOp{Response: &pb.ResponseOp_ResponseDeleteRange{ResponseDeleteRange: resp}} } @@ -500,7 +519,7 @@ func (a *applierV3backend) LeaseGrant(lc *pb.LeaseGrantRequest) (*pb.LeaseGrantR resp := &pb.LeaseGrantResponse{} if err == nil { resp.ID = int64(l.ID) - resp.TTL = l.TTL + resp.TTL = l.TTL() resp.Header = &pb.ResponseHeader{Revision: a.s.KV().Rev()} } @@ -784,3 +803,36 @@ func compareInt64(a, b int64) int { func isGteRange(rangeEnd []byte) bool { return len(rangeEnd) == 1 && rangeEnd[0] == 0 } + +func noSideEffect(r *pb.InternalRaftRequest) bool { + return r.Range != nil || r.AuthUserGet != nil || r.AuthRoleGet != nil +} + +func removeNeedlessRangeReqs(txn *pb.TxnRequest) { + f := func(ops []*pb.RequestOp) []*pb.RequestOp { + j := 0 + for i := 0; i < len(ops); i++ { + if _, ok := ops[i].Request.(*pb.RequestOp_RequestRange); ok { + continue + } + ops[j] = ops[i] + j++ + } + + return ops[:j] + } + + txn.Success = f(txn.Success) + txn.Failure = f(txn.Failure) +} + +func pruneKVs(rr *mvcc.RangeResult, isPrunable func(*mvccpb.KeyValue) bool) { + j := 0 + for i := range rr.KVs { + rr.KVs[j] = rr.KVs[i] + if !isPrunable(&rr.KVs[i]) { + j++ + } + } + rr.KVs = rr.KVs[:j] +} diff --git a/vendor/github.com/coreos/etcd/etcdserver/apply_auth.go b/vendor/github.com/coreos/etcd/etcdserver/apply_auth.go index 38bf2b407..4868e855c 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/apply_auth.go +++ b/vendor/github.com/coreos/etcd/etcdserver/apply_auth.go @@ -27,8 +27,9 @@ type authApplierV3 struct { // mu serializes Apply so that user isn't corrupted and so that // serialized requests don't leak data from TOCTOU errors - mu sync.Mutex - user string + mu sync.Mutex + + authInfo auth.AuthInfo } func newAuthApplierV3(as auth.AuthStore, base applierV3) *authApplierV3 { @@ -41,45 +42,57 @@ func (aa *authApplierV3) Apply(r *pb.InternalRaftRequest) *applyResult { if r.Header != nil { // backward-compatible with pre-3.0 releases when internalRaftRequest // does not have header field - aa.user = r.Header.Username + aa.authInfo.Username = r.Header.Username + aa.authInfo.Revision = r.Header.AuthRevision } - if needAdminPermission(r) && !aa.as.IsAdminPermitted(aa.user) { - aa.user = "" - return &applyResult{err: auth.ErrPermissionDenied} + if needAdminPermission(r) { + if err := aa.as.IsAdminPermitted(&aa.authInfo); err != nil { + aa.authInfo.Username = "" + aa.authInfo.Revision = 0 + return &applyResult{err: err} + } } ret := aa.applierV3.Apply(r) - aa.user = "" + aa.authInfo.Username = "" + aa.authInfo.Revision = 0 return ret } func (aa *authApplierV3) Put(txnID int64, r *pb.PutRequest) (*pb.PutResponse, error) { - if !aa.as.IsPutPermitted(aa.user, r.Key) { - return nil, auth.ErrPermissionDenied + if err := aa.as.IsPutPermitted(&aa.authInfo, r.Key); err != nil { + return nil, err } - if r.PrevKv && !aa.as.IsRangePermitted(aa.user, r.Key, nil) { - return nil, auth.ErrPermissionDenied + if r.PrevKv { + err := aa.as.IsRangePermitted(&aa.authInfo, r.Key, nil) + if err != nil { + return nil, err + } } return aa.applierV3.Put(txnID, r) } func (aa *authApplierV3) Range(txnID int64, r *pb.RangeRequest) (*pb.RangeResponse, error) { - if !aa.as.IsRangePermitted(aa.user, r.Key, r.RangeEnd) { - return nil, auth.ErrPermissionDenied + if err := aa.as.IsRangePermitted(&aa.authInfo, r.Key, r.RangeEnd); err != nil { + return nil, err } return aa.applierV3.Range(txnID, r) } func (aa *authApplierV3) DeleteRange(txnID int64, r *pb.DeleteRangeRequest) (*pb.DeleteRangeResponse, error) { - if !aa.as.IsDeleteRangePermitted(aa.user, r.Key, r.RangeEnd) { - return nil, auth.ErrPermissionDenied + if err := aa.as.IsDeleteRangePermitted(&aa.authInfo, r.Key, r.RangeEnd); err != nil { + return nil, err } - if r.PrevKv && !aa.as.IsRangePermitted(aa.user, r.Key, r.RangeEnd) { - return nil, auth.ErrPermissionDenied + if r.PrevKv { + err := aa.as.IsRangePermitted(&aa.authInfo, r.Key, r.RangeEnd) + if err != nil { + return nil, err + } } + return aa.applierV3.DeleteRange(txnID, r) } -func (aa *authApplierV3) checkTxnReqsPermission(reqs []*pb.RequestOp) bool { +func checkTxnReqsPermission(as auth.AuthStore, ai *auth.AuthInfo, reqs []*pb.RequestOp) error { for _, requ := range reqs { switch tv := requ.Request.(type) { case *pb.RequestOp_RequestRange: @@ -87,8 +100,8 @@ func (aa *authApplierV3) checkTxnReqsPermission(reqs []*pb.RequestOp) bool { continue } - if !aa.as.IsRangePermitted(aa.user, tv.RequestRange.Key, tv.RequestRange.RangeEnd) { - return false + if err := as.IsRangePermitted(ai, tv.RequestRange.Key, tv.RequestRange.RangeEnd); err != nil { + return err } case *pb.RequestOp_RequestPut: @@ -96,8 +109,8 @@ func (aa *authApplierV3) checkTxnReqsPermission(reqs []*pb.RequestOp) bool { continue } - if !aa.as.IsPutPermitted(aa.user, tv.RequestPut.Key) { - return false + if err := as.IsPutPermitted(ai, tv.RequestPut.Key); err != nil { + return err } case *pb.RequestOp_RequestDeleteRange: @@ -105,29 +118,42 @@ func (aa *authApplierV3) checkTxnReqsPermission(reqs []*pb.RequestOp) bool { continue } - if tv.RequestDeleteRange.PrevKv && !aa.as.IsRangePermitted(aa.user, tv.RequestDeleteRange.Key, tv.RequestDeleteRange.RangeEnd) { - return false + if tv.RequestDeleteRange.PrevKv { + err := as.IsRangePermitted(ai, tv.RequestDeleteRange.Key, tv.RequestDeleteRange.RangeEnd) + if err != nil { + return err + } + } + + err := as.IsDeleteRangePermitted(ai, tv.RequestDeleteRange.Key, tv.RequestDeleteRange.RangeEnd) + if err != nil { + return err } } } - return true + return nil +} + +func checkTxnAuth(as auth.AuthStore, ai *auth.AuthInfo, rt *pb.TxnRequest) error { + for _, c := range rt.Compare { + if err := as.IsRangePermitted(ai, c.Key, nil); err != nil { + return err + } + } + if err := checkTxnReqsPermission(as, ai, rt.Success); err != nil { + return err + } + if err := checkTxnReqsPermission(as, ai, rt.Failure); err != nil { + return err + } + return nil } func (aa *authApplierV3) Txn(rt *pb.TxnRequest) (*pb.TxnResponse, error) { - for _, c := range rt.Compare { - if !aa.as.IsRangePermitted(aa.user, c.Key, nil) { - return nil, auth.ErrPermissionDenied - } + if err := checkTxnAuth(aa.as, &aa.authInfo, rt); err != nil { + return nil, err } - - if !aa.checkTxnReqsPermission(rt.Success) { - return nil, auth.ErrPermissionDenied - } - if !aa.checkTxnReqsPermission(rt.Failure) { - return nil, auth.ErrPermissionDenied - } - return aa.applierV3.Txn(rt) } diff --git a/vendor/github.com/coreos/etcd/etcdserver/auth/auth.go b/vendor/github.com/coreos/etcd/etcdserver/auth/auth.go index d747ba0fc..19e96d57c 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/auth/auth.go +++ b/vendor/github.com/coreos/etcd/etcdserver/auth/auth.go @@ -46,7 +46,7 @@ const ( ) var ( - plog = capnslog.NewPackageLogger("github.com/coreos/etcd/etcdserver", "auth") + plog = capnslog.NewPackageLogger("github.com/coreos/etcd", "etcdserver/auth") ) var rootRole = Role{ @@ -167,7 +167,7 @@ func (_ passwordStore) HashPassword(password string) (string, error) { } func (s *store) AllUsers() ([]string, error) { - resp, err := s.requestResource("/users/", false) + resp, err := s.requestResource("/users/", false, false) if err != nil { if e, ok := err.(*etcderr.Error); ok { if e.ErrorCode == etcderr.EcodeKeyNotFound { @@ -185,33 +185,13 @@ func (s *store) AllUsers() ([]string, error) { return nodes, nil } -func (s *store) GetUser(name string) (User, error) { - resp, err := s.requestResource("/users/"+name, false) - if err != nil { - if e, ok := err.(*etcderr.Error); ok { - if e.ErrorCode == etcderr.EcodeKeyNotFound { - return User{}, authErr(http.StatusNotFound, "User %s does not exist.", name) - } - } - return User{}, err - } - var u User - err = json.Unmarshal([]byte(*resp.Event.Node.Value), &u) - if err != nil { - return u, err - } - // Attach root role to root user. - if u.User == "root" { - u = attachRootRole(u) - } - return u, nil -} +func (s *store) GetUser(name string) (User, error) { return s.getUser(name, false) } // CreateOrUpdateUser should be only used for creating the new user or when you are not // sure if it is a create or update. (When only password is passed in, we are not sure // if it is a update or create) func (s *store) CreateOrUpdateUser(user User) (out User, created bool, err error) { - _, err = s.GetUser(user.User) + _, err = s.getUser(user.User, true) if err == nil { out, err = s.UpdateUser(user) return out, false, err @@ -271,7 +251,7 @@ func (s *store) DeleteUser(name string) error { } func (s *store) UpdateUser(user User) (User, error) { - old, err := s.GetUser(user.User) + old, err := s.getUser(user.User, true) if err != nil { if e, ok := err.(*etcderr.Error); ok { if e.ErrorCode == etcderr.EcodeKeyNotFound { @@ -297,7 +277,7 @@ func (s *store) UpdateUser(user User) (User, error) { func (s *store) AllRoles() ([]string, error) { nodes := []string{RootRoleName} - resp, err := s.requestResource("/roles/", false) + resp, err := s.requestResource("/roles/", false, false) if err != nil { if e, ok := err.(*etcderr.Error); ok { if e.ErrorCode == etcderr.EcodeKeyNotFound { @@ -314,23 +294,7 @@ func (s *store) AllRoles() ([]string, error) { return nodes, nil } -func (s *store) GetRole(name string) (Role, error) { - if name == RootRoleName { - return rootRole, nil - } - resp, err := s.requestResource("/roles/"+name, false) - if err != nil { - if e, ok := err.(*etcderr.Error); ok { - if e.ErrorCode == etcderr.EcodeKeyNotFound { - return Role{}, authErr(http.StatusNotFound, "Role %s does not exist.", name) - } - } - return Role{}, err - } - var r Role - err = json.Unmarshal([]byte(*resp.Event.Node.Value), &r) - return r, err -} +func (s *store) GetRole(name string) (Role, error) { return s.getRole(name, false) } func (s *store) CreateRole(role Role) error { if role.Role == RootRoleName { @@ -372,7 +336,7 @@ func (s *store) UpdateRole(role Role) (Role, error) { if role.Role == RootRoleName { return Role{}, authErr(http.StatusForbidden, "Cannot modify role %s: is root role.", role.Role) } - old, err := s.GetRole(role.Role) + old, err := s.getRole(role.Role, true) if err != nil { if e, ok := err.(*etcderr.Error); ok { if e.ErrorCode == etcderr.EcodeKeyNotFound { @@ -404,10 +368,10 @@ func (s *store) EnableAuth() error { return authErr(http.StatusConflict, "already enabled") } - if _, err := s.GetUser("root"); err != nil { + if _, err := s.getUser("root", true); err != nil { return authErr(http.StatusConflict, "No root user available, please create one") } - if _, err := s.GetRole(GuestRoleName); err != nil { + if _, err := s.getRole(GuestRoleName, true); err != nil { plog.Printf("no guest role access found, creating default") if err := s.CreateRole(guestRole); err != nil { plog.Errorf("error creating guest role. aborting auth enable.") @@ -641,3 +605,43 @@ func attachRootRole(u User) User { } return u } + +func (s *store) getUser(name string, quorum bool) (User, error) { + resp, err := s.requestResource("/users/"+name, false, quorum) + if err != nil { + if e, ok := err.(*etcderr.Error); ok { + if e.ErrorCode == etcderr.EcodeKeyNotFound { + return User{}, authErr(http.StatusNotFound, "User %s does not exist.", name) + } + } + return User{}, err + } + var u User + err = json.Unmarshal([]byte(*resp.Event.Node.Value), &u) + if err != nil { + return u, err + } + // Attach root role to root user. + if u.User == "root" { + u = attachRootRole(u) + } + return u, nil +} + +func (s *store) getRole(name string, quorum bool) (Role, error) { + if name == RootRoleName { + return rootRole, nil + } + resp, err := s.requestResource("/roles/"+name, false, quorum) + if err != nil { + if e, ok := err.(*etcderr.Error); ok { + if e.ErrorCode == etcderr.EcodeKeyNotFound { + return Role{}, authErr(http.StatusNotFound, "Role %s does not exist.", name) + } + } + return Role{}, err + } + var r Role + err = json.Unmarshal([]byte(*resp.Event.Node.Value), &r) + return r, err +} diff --git a/vendor/github.com/coreos/etcd/etcdserver/auth/auth_requests.go b/vendor/github.com/coreos/etcd/etcdserver/auth/auth_requests.go index 36bed20d0..eec700acc 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/auth/auth_requests.go +++ b/vendor/github.com/coreos/etcd/etcdserver/auth/auth_requests.go @@ -85,7 +85,7 @@ func (s *store) detectAuth() bool { if s.server == nil { return false } - value, err := s.requestResource("/enabled", false) + value, err := s.requestResource("/enabled", false, false) if err != nil { if e, ok := err.(*etcderr.Error); ok { if e.ErrorCode == etcderr.EcodeKeyNotFound { @@ -105,12 +105,16 @@ func (s *store) detectAuth() bool { return u } -func (s *store) requestResource(res string, dir bool) (etcdserver.Response, error) { +func (s *store) requestResource(res string, dir, quorum bool) (etcdserver.Response, error) { ctx, cancel := context.WithTimeout(context.Background(), s.timeout) defer cancel() p := path.Join(StorePermsPrefix, res) + method := "GET" + if quorum { + method = "QGET" + } rr := etcdserverpb.Request{ - Method: "GET", + Method: method, Path: p, Dir: dir, } diff --git a/vendor/github.com/coreos/etcd/etcdserver/cluster_util.go b/vendor/github.com/coreos/etcd/etcdserver/cluster_util.go index e70f104a2..fa84ffae6 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/cluster_util.go +++ b/vendor/github.com/coreos/etcd/etcdserver/cluster_util.go @@ -94,7 +94,16 @@ func getClusterFromRemotePeers(urls []string, timeout time.Duration, logerr bool } continue } - return membership.NewClusterFromMembers("", id, membs), nil + + // check the length of membership members + // if the membership members are present then prepare and return raft cluster + // if membership members are not present then the raft cluster formed will be + // an invalid empty cluster hence return failed to get raft cluster member(s) from the given urls error + if len(membs) > 0 { + return membership.NewClusterFromMembers("", id, membs), nil + } + + return nil, fmt.Errorf("failed to get raft cluster member(s) from the given urls.") } return nil, fmt.Errorf("could not retrieve cluster information from the given urls") } diff --git a/vendor/github.com/coreos/etcd/etcdserver/config.go b/vendor/github.com/coreos/etcd/etcdserver/config.go index b66a63323..9bcac0f07 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/config.go +++ b/vendor/github.com/coreos/etcd/etcdserver/config.go @@ -16,11 +16,13 @@ package etcdserver import ( "fmt" - "path" + "path/filepath" "sort" "strings" "time" + "golang.org/x/net/context" + "github.com/coreos/etcd/pkg/netutil" "github.com/coreos/etcd/pkg/transport" "github.com/coreos/etcd/pkg/types" @@ -55,8 +57,6 @@ type ServerConfig struct { StrictReconfigCheck bool - EnablePprof bool - // ClientCertAuthEnabled is true when cert has been signed by the client CA. ClientCertAuthEnabled bool } @@ -64,7 +64,10 @@ type ServerConfig struct { // VerifyBootstrap sanity-checks the initial config for bootstrap case // and returns an error for things that should never happen. func (c *ServerConfig) VerifyBootstrap() error { - if err := c.verifyLocalMember(true); err != nil { + if err := c.hasLocalMember(); err != nil { + return err + } + if err := c.advertiseMatchesCluster(); err != nil { return err } if checkDuplicateURL(c.InitialPeerURLsMap) { @@ -79,10 +82,9 @@ func (c *ServerConfig) VerifyBootstrap() error { // VerifyJoinExisting sanity-checks the initial config for join existing cluster // case and returns an error for things that should never happen. func (c *ServerConfig) VerifyJoinExisting() error { - // no need for strict checking since the member have announced its - // peer urls to the cluster before starting and do not have to set - // it in the configuration again. - if err := c.verifyLocalMember(false); err != nil { + // The member has announced its peer urls to the cluster before starting; no need to + // set the configuration again. + if err := c.hasLocalMember(); err != nil { return err } if checkDuplicateURL(c.InitialPeerURLsMap) { @@ -94,39 +96,38 @@ func (c *ServerConfig) VerifyJoinExisting() error { return nil } -// verifyLocalMember verifies the configured member is in configured -// cluster. If strict is set, it also verifies the configured member -// has the same peer urls as configured advertised peer urls. -func (c *ServerConfig) verifyLocalMember(strict bool) error { - urls := c.InitialPeerURLsMap[c.Name] - // Make sure the cluster at least contains the local server. - if urls == nil { +// hasLocalMember checks that the cluster at least contains the local server. +func (c *ServerConfig) hasLocalMember() error { + if urls := c.InitialPeerURLsMap[c.Name]; urls == nil { return fmt.Errorf("couldn't find local name %q in the initial cluster configuration", c.Name) } - - // Advertised peer URLs must match those in the cluster peer list - apurls := c.PeerURLs.StringSlice() - sort.Strings(apurls) - urls.Sort() - if strict { - if !netutil.URLStringsEqual(apurls, urls.StringSlice()) { - umap := map[string]types.URLs{c.Name: c.PeerURLs} - return fmt.Errorf("--initial-cluster must include %s given --initial-advertise-peer-urls=%s", types.URLsMap(umap).String(), strings.Join(apurls, ",")) - } - } return nil } -func (c *ServerConfig) MemberDir() string { return path.Join(c.DataDir, "member") } +// advertiseMatchesCluster confirms peer URLs match those in the cluster peer list. +func (c *ServerConfig) advertiseMatchesCluster() error { + urls, apurls := c.InitialPeerURLsMap[c.Name], c.PeerURLs.StringSlice() + urls.Sort() + sort.Strings(apurls) + ctx, cancel := context.WithTimeout(context.TODO(), 30*time.Second) + defer cancel() + if !netutil.URLStringsEqual(ctx, apurls, urls.StringSlice()) { + umap := map[string]types.URLs{c.Name: c.PeerURLs} + return fmt.Errorf("--initial-cluster must include %s given --initial-advertise-peer-urls=%s", types.URLsMap(umap).String(), strings.Join(apurls, ",")) + } + return nil +} + +func (c *ServerConfig) MemberDir() string { return filepath.Join(c.DataDir, "member") } func (c *ServerConfig) WALDir() string { if c.DedicatedWALDir != "" { return c.DedicatedWALDir } - return path.Join(c.MemberDir(), "wal") + return filepath.Join(c.MemberDir(), "wal") } -func (c *ServerConfig) SnapDir() string { return path.Join(c.MemberDir(), "snap") } +func (c *ServerConfig) SnapDir() string { return filepath.Join(c.MemberDir(), "snap") } func (c *ServerConfig) ShouldDiscover() bool { return c.DiscoveryURL != "" } diff --git a/vendor/github.com/coreos/etcd/etcdserver/errors.go b/vendor/github.com/coreos/etcd/etcdserver/errors.go index 1b9789fc8..5edc15562 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/errors.go +++ b/vendor/github.com/coreos/etcd/etcdserver/errors.go @@ -26,11 +26,13 @@ var ( ErrTimeout = errors.New("etcdserver: request timed out") ErrTimeoutDueToLeaderFail = errors.New("etcdserver: request timed out, possibly due to previous leader failure") ErrTimeoutDueToConnectionLost = errors.New("etcdserver: request timed out, possibly due to connection lost") + ErrTimeoutLeaderTransfer = errors.New("etcdserver: request timed out, leader transfer took too long") ErrNotEnoughStartedMembers = errors.New("etcdserver: re-configuration failed due to not enough started members") ErrNoLeader = errors.New("etcdserver: no leader") ErrRequestTooLarge = errors.New("etcdserver: request is too large") ErrNoSpace = errors.New("etcdserver: no space") - ErrInvalidAuthToken = errors.New("etcdserver: invalid auth token") + ErrTooManyRequests = errors.New("etcdserver: too many requests") + ErrUnhealthy = errors.New("etcdserver: unhealthy cluster") ) type DiscoveryError struct { 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 ac4be4f6c..f34bedf3e 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/etcdserverpb/etcdserver.pb.go +++ b/vendor/github.com/coreos/etcd/etcdserver/etcdserverpb/etcdserver.pb.go @@ -45,6 +45,8 @@ LeaseRevokeResponse LeaseKeepAliveRequest LeaseKeepAliveResponse + LeaseTimeToLiveRequest + LeaseTimeToLiveResponse Member MemberAddRequest MemberAddResponse @@ -113,26 +115,28 @@ var _ = math.Inf // This is a compile-time assertion to ensure that this generated file // is compatible with the proto package it is being compiled against. -const _ = proto.ProtoPackageIsVersion1 +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package type Request struct { - ID uint64 `protobuf:"varint,1,opt,name=ID,json=iD" json:"ID"` - Method string `protobuf:"bytes,2,opt,name=Method,json=method" json:"Method"` - Path string `protobuf:"bytes,3,opt,name=Path,json=path" json:"Path"` - Val string `protobuf:"bytes,4,opt,name=Val,json=val" json:"Val"` - Dir bool `protobuf:"varint,5,opt,name=Dir,json=dir" json:"Dir"` - PrevValue string `protobuf:"bytes,6,opt,name=PrevValue,json=prevValue" json:"PrevValue"` - PrevIndex uint64 `protobuf:"varint,7,opt,name=PrevIndex,json=prevIndex" json:"PrevIndex"` - PrevExist *bool `protobuf:"varint,8,opt,name=PrevExist,json=prevExist" json:"PrevExist,omitempty"` - Expiration int64 `protobuf:"varint,9,opt,name=Expiration,json=expiration" json:"Expiration"` - Wait bool `protobuf:"varint,10,opt,name=Wait,json=wait" json:"Wait"` - Since uint64 `protobuf:"varint,11,opt,name=Since,json=since" json:"Since"` - Recursive bool `protobuf:"varint,12,opt,name=Recursive,json=recursive" json:"Recursive"` - Sorted bool `protobuf:"varint,13,opt,name=Sorted,json=sorted" json:"Sorted"` - Quorum bool `protobuf:"varint,14,opt,name=Quorum,json=quorum" json:"Quorum"` - Time int64 `protobuf:"varint,15,opt,name=Time,json=time" json:"Time"` - Stream bool `protobuf:"varint,16,opt,name=Stream,json=stream" json:"Stream"` - Refresh *bool `protobuf:"varint,17,opt,name=Refresh,json=refresh" json:"Refresh,omitempty"` + ID uint64 `protobuf:"varint,1,opt,name=ID" json:"ID"` + Method string `protobuf:"bytes,2,opt,name=Method" json:"Method"` + Path string `protobuf:"bytes,3,opt,name=Path" json:"Path"` + Val string `protobuf:"bytes,4,opt,name=Val" json:"Val"` + Dir bool `protobuf:"varint,5,opt,name=Dir" json:"Dir"` + PrevValue string `protobuf:"bytes,6,opt,name=PrevValue" json:"PrevValue"` + PrevIndex uint64 `protobuf:"varint,7,opt,name=PrevIndex" json:"PrevIndex"` + PrevExist *bool `protobuf:"varint,8,opt,name=PrevExist" json:"PrevExist,omitempty"` + Expiration int64 `protobuf:"varint,9,opt,name=Expiration" json:"Expiration"` + Wait bool `protobuf:"varint,10,opt,name=Wait" json:"Wait"` + Since uint64 `protobuf:"varint,11,opt,name=Since" json:"Since"` + Recursive bool `protobuf:"varint,12,opt,name=Recursive" json:"Recursive"` + Sorted bool `protobuf:"varint,13,opt,name=Sorted" json:"Sorted"` + Quorum bool `protobuf:"varint,14,opt,name=Quorum" json:"Quorum"` + Time int64 `protobuf:"varint,15,opt,name=Time" json:"Time"` + Stream bool `protobuf:"varint,16,opt,name=Stream" json:"Stream"` + Refresh *bool `protobuf:"varint,17,opt,name=Refresh" json:"Refresh,omitempty"` XXX_unrecognized []byte `json:"-"` } @@ -142,8 +146,8 @@ func (*Request) ProtoMessage() {} func (*Request) Descriptor() ([]byte, []int) { return fileDescriptorEtcdserver, []int{0} } type Metadata struct { - NodeID uint64 `protobuf:"varint,1,opt,name=NodeID,json=nodeID" json:"NodeID"` - ClusterID uint64 `protobuf:"varint,2,opt,name=ClusterID,json=clusterID" json:"ClusterID"` + NodeID uint64 `protobuf:"varint,1,opt,name=NodeID" json:"NodeID"` + ClusterID uint64 `protobuf:"varint,2,opt,name=ClusterID" json:"ClusterID"` XXX_unrecognized []byte `json:"-"` } @@ -156,182 +160,182 @@ func init() { proto.RegisterType((*Request)(nil), "etcdserverpb.Request") proto.RegisterType((*Metadata)(nil), "etcdserverpb.Metadata") } -func (m *Request) Marshal() (data []byte, err error) { +func (m *Request) Marshal() (dAtA []byte, err error) { size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) if err != nil { return nil, err } - return data[:n], nil + return dAtA[:n], nil } -func (m *Request) MarshalTo(data []byte) (int, error) { +func (m *Request) MarshalTo(dAtA []byte) (int, error) { var i int _ = i var l int _ = l - data[i] = 0x8 + dAtA[i] = 0x8 i++ - i = encodeVarintEtcdserver(data, i, uint64(m.ID)) - data[i] = 0x12 + i = encodeVarintEtcdserver(dAtA, i, uint64(m.ID)) + dAtA[i] = 0x12 i++ - i = encodeVarintEtcdserver(data, i, uint64(len(m.Method))) - i += copy(data[i:], m.Method) - data[i] = 0x1a + i = encodeVarintEtcdserver(dAtA, i, uint64(len(m.Method))) + i += copy(dAtA[i:], m.Method) + dAtA[i] = 0x1a i++ - i = encodeVarintEtcdserver(data, i, uint64(len(m.Path))) - i += copy(data[i:], m.Path) - data[i] = 0x22 + i = encodeVarintEtcdserver(dAtA, i, uint64(len(m.Path))) + i += copy(dAtA[i:], m.Path) + dAtA[i] = 0x22 i++ - i = encodeVarintEtcdserver(data, i, uint64(len(m.Val))) - i += copy(data[i:], m.Val) - data[i] = 0x28 + i = encodeVarintEtcdserver(dAtA, i, uint64(len(m.Val))) + i += copy(dAtA[i:], m.Val) + dAtA[i] = 0x28 i++ if m.Dir { - data[i] = 1 + dAtA[i] = 1 } else { - data[i] = 0 + dAtA[i] = 0 } i++ - data[i] = 0x32 + dAtA[i] = 0x32 i++ - i = encodeVarintEtcdserver(data, i, uint64(len(m.PrevValue))) - i += copy(data[i:], m.PrevValue) - data[i] = 0x38 + i = encodeVarintEtcdserver(dAtA, i, uint64(len(m.PrevValue))) + i += copy(dAtA[i:], m.PrevValue) + dAtA[i] = 0x38 i++ - i = encodeVarintEtcdserver(data, i, uint64(m.PrevIndex)) + i = encodeVarintEtcdserver(dAtA, i, uint64(m.PrevIndex)) if m.PrevExist != nil { - data[i] = 0x40 + dAtA[i] = 0x40 i++ if *m.PrevExist { - data[i] = 1 + dAtA[i] = 1 } else { - data[i] = 0 + dAtA[i] = 0 } i++ } - data[i] = 0x48 + dAtA[i] = 0x48 i++ - i = encodeVarintEtcdserver(data, i, uint64(m.Expiration)) - data[i] = 0x50 + i = encodeVarintEtcdserver(dAtA, i, uint64(m.Expiration)) + dAtA[i] = 0x50 i++ if m.Wait { - data[i] = 1 + dAtA[i] = 1 } else { - data[i] = 0 + dAtA[i] = 0 } i++ - data[i] = 0x58 + dAtA[i] = 0x58 i++ - i = encodeVarintEtcdserver(data, i, uint64(m.Since)) - data[i] = 0x60 + i = encodeVarintEtcdserver(dAtA, i, uint64(m.Since)) + dAtA[i] = 0x60 i++ if m.Recursive { - data[i] = 1 + dAtA[i] = 1 } else { - data[i] = 0 + dAtA[i] = 0 } i++ - data[i] = 0x68 + dAtA[i] = 0x68 i++ if m.Sorted { - data[i] = 1 + dAtA[i] = 1 } else { - data[i] = 0 + dAtA[i] = 0 } i++ - data[i] = 0x70 + dAtA[i] = 0x70 i++ if m.Quorum { - data[i] = 1 + dAtA[i] = 1 } else { - data[i] = 0 + dAtA[i] = 0 } i++ - data[i] = 0x78 + dAtA[i] = 0x78 i++ - i = encodeVarintEtcdserver(data, i, uint64(m.Time)) - data[i] = 0x80 + i = encodeVarintEtcdserver(dAtA, i, uint64(m.Time)) + dAtA[i] = 0x80 i++ - data[i] = 0x1 + dAtA[i] = 0x1 i++ if m.Stream { - data[i] = 1 + dAtA[i] = 1 } else { - data[i] = 0 + dAtA[i] = 0 } i++ if m.Refresh != nil { - data[i] = 0x88 + dAtA[i] = 0x88 i++ - data[i] = 0x1 + dAtA[i] = 0x1 i++ if *m.Refresh { - data[i] = 1 + dAtA[i] = 1 } else { - data[i] = 0 + dAtA[i] = 0 } i++ } if m.XXX_unrecognized != nil { - i += copy(data[i:], m.XXX_unrecognized) + i += copy(dAtA[i:], m.XXX_unrecognized) } return i, nil } -func (m *Metadata) Marshal() (data []byte, err error) { +func (m *Metadata) Marshal() (dAtA []byte, err error) { size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) if err != nil { return nil, err } - return data[:n], nil + return dAtA[:n], nil } -func (m *Metadata) MarshalTo(data []byte) (int, error) { +func (m *Metadata) MarshalTo(dAtA []byte) (int, error) { var i int _ = i var l int _ = l - data[i] = 0x8 + dAtA[i] = 0x8 i++ - i = encodeVarintEtcdserver(data, i, uint64(m.NodeID)) - data[i] = 0x10 + i = encodeVarintEtcdserver(dAtA, i, uint64(m.NodeID)) + dAtA[i] = 0x10 i++ - i = encodeVarintEtcdserver(data, i, uint64(m.ClusterID)) + i = encodeVarintEtcdserver(dAtA, i, uint64(m.ClusterID)) if m.XXX_unrecognized != nil { - i += copy(data[i:], m.XXX_unrecognized) + i += copy(dAtA[i:], m.XXX_unrecognized) } return i, nil } -func encodeFixed64Etcdserver(data []byte, offset int, v uint64) int { - data[offset] = uint8(v) - data[offset+1] = uint8(v >> 8) - data[offset+2] = uint8(v >> 16) - data[offset+3] = uint8(v >> 24) - data[offset+4] = uint8(v >> 32) - data[offset+5] = uint8(v >> 40) - data[offset+6] = uint8(v >> 48) - data[offset+7] = uint8(v >> 56) +func encodeFixed64Etcdserver(dAtA []byte, offset int, v uint64) int { + dAtA[offset] = uint8(v) + dAtA[offset+1] = uint8(v >> 8) + dAtA[offset+2] = uint8(v >> 16) + dAtA[offset+3] = uint8(v >> 24) + dAtA[offset+4] = uint8(v >> 32) + dAtA[offset+5] = uint8(v >> 40) + dAtA[offset+6] = uint8(v >> 48) + dAtA[offset+7] = uint8(v >> 56) return offset + 8 } -func encodeFixed32Etcdserver(data []byte, offset int, v uint32) int { - data[offset] = uint8(v) - data[offset+1] = uint8(v >> 8) - data[offset+2] = uint8(v >> 16) - data[offset+3] = uint8(v >> 24) +func encodeFixed32Etcdserver(dAtA []byte, offset int, v uint32) int { + dAtA[offset] = uint8(v) + dAtA[offset+1] = uint8(v >> 8) + dAtA[offset+2] = uint8(v >> 16) + dAtA[offset+3] = uint8(v >> 24) return offset + 4 } -func encodeVarintEtcdserver(data []byte, offset int, v uint64) int { +func encodeVarintEtcdserver(dAtA []byte, offset int, v uint64) int { for v >= 1<<7 { - data[offset] = uint8(v&0x7f | 0x80) + dAtA[offset] = uint8(v&0x7f | 0x80) v >>= 7 offset++ } - data[offset] = uint8(v) + dAtA[offset] = uint8(v) return offset + 1 } func (m *Request) Size() (n int) { @@ -392,8 +396,8 @@ func sovEtcdserver(x uint64) (n int) { func sozEtcdserver(x uint64) (n int) { return sovEtcdserver(uint64((x << 1) ^ uint64((int64(x) >> 63)))) } -func (m *Request) Unmarshal(data []byte) error { - l := len(data) +func (m *Request) Unmarshal(dAtA []byte) error { + l := len(dAtA) iNdEx := 0 for iNdEx < l { preIndex := iNdEx @@ -405,7 +409,7 @@ func (m *Request) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -433,7 +437,7 @@ func (m *Request) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ m.ID |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -452,7 +456,7 @@ func (m *Request) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ stringLen |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -467,7 +471,7 @@ func (m *Request) Unmarshal(data []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Method = string(data[iNdEx:postIndex]) + m.Method = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 3: if wireType != 2 { @@ -481,7 +485,7 @@ func (m *Request) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ stringLen |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -496,7 +500,7 @@ func (m *Request) Unmarshal(data []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Path = string(data[iNdEx:postIndex]) + m.Path = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 4: if wireType != 2 { @@ -510,7 +514,7 @@ func (m *Request) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ stringLen |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -525,7 +529,7 @@ func (m *Request) Unmarshal(data []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Val = string(data[iNdEx:postIndex]) + m.Val = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 5: if wireType != 0 { @@ -539,7 +543,7 @@ func (m *Request) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ v |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -559,7 +563,7 @@ func (m *Request) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ stringLen |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -574,7 +578,7 @@ func (m *Request) Unmarshal(data []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.PrevValue = string(data[iNdEx:postIndex]) + m.PrevValue = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 7: if wireType != 0 { @@ -588,7 +592,7 @@ func (m *Request) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ m.PrevIndex |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -607,7 +611,7 @@ func (m *Request) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ v |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -628,7 +632,7 @@ func (m *Request) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ m.Expiration |= (int64(b) & 0x7F) << shift if b < 0x80 { @@ -647,7 +651,7 @@ func (m *Request) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ v |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -667,7 +671,7 @@ func (m *Request) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ m.Since |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -686,7 +690,7 @@ func (m *Request) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ v |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -706,7 +710,7 @@ func (m *Request) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ v |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -726,7 +730,7 @@ func (m *Request) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ v |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -746,7 +750,7 @@ func (m *Request) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ m.Time |= (int64(b) & 0x7F) << shift if b < 0x80 { @@ -765,7 +769,7 @@ func (m *Request) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ v |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -785,7 +789,7 @@ func (m *Request) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ v |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -796,7 +800,7 @@ func (m *Request) Unmarshal(data []byte) error { m.Refresh = &b default: iNdEx = preIndex - skippy, err := skipEtcdserver(data[iNdEx:]) + skippy, err := skipEtcdserver(dAtA[iNdEx:]) if err != nil { return err } @@ -806,7 +810,7 @@ func (m *Request) Unmarshal(data []byte) error { if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF } - m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) iNdEx += skippy } } @@ -816,8 +820,8 @@ func (m *Request) Unmarshal(data []byte) error { } return nil } -func (m *Metadata) Unmarshal(data []byte) error { - l := len(data) +func (m *Metadata) Unmarshal(dAtA []byte) error { + l := len(dAtA) iNdEx := 0 for iNdEx < l { preIndex := iNdEx @@ -829,7 +833,7 @@ func (m *Metadata) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -857,7 +861,7 @@ func (m *Metadata) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ m.NodeID |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -876,7 +880,7 @@ func (m *Metadata) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ m.ClusterID |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -885,7 +889,7 @@ func (m *Metadata) Unmarshal(data []byte) error { } default: iNdEx = preIndex - skippy, err := skipEtcdserver(data[iNdEx:]) + skippy, err := skipEtcdserver(dAtA[iNdEx:]) if err != nil { return err } @@ -895,7 +899,7 @@ func (m *Metadata) Unmarshal(data []byte) error { if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF } - m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) iNdEx += skippy } } @@ -905,8 +909,8 @@ func (m *Metadata) Unmarshal(data []byte) error { } return nil } -func skipEtcdserver(data []byte) (n int, err error) { - l := len(data) +func skipEtcdserver(dAtA []byte) (n int, err error) { + l := len(dAtA) iNdEx := 0 for iNdEx < l { var wire uint64 @@ -917,7 +921,7 @@ func skipEtcdserver(data []byte) (n int, err error) { if iNdEx >= l { return 0, io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -935,7 +939,7 @@ func skipEtcdserver(data []byte) (n int, err error) { return 0, io.ErrUnexpectedEOF } iNdEx++ - if data[iNdEx-1] < 0x80 { + if dAtA[iNdEx-1] < 0x80 { break } } @@ -952,7 +956,7 @@ func skipEtcdserver(data []byte) (n int, err error) { if iNdEx >= l { return 0, io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ length |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -975,7 +979,7 @@ func skipEtcdserver(data []byte) (n int, err error) { if iNdEx >= l { return 0, io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ innerWire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -986,7 +990,7 @@ func skipEtcdserver(data []byte) (n int, err error) { if innerWireType == 4 { break } - next, err := skipEtcdserver(data[start:]) + next, err := skipEtcdserver(dAtA[start:]) if err != nil { return 0, err } @@ -1010,32 +1014,32 @@ var ( ErrIntOverflowEtcdserver = fmt.Errorf("proto: integer overflow") ) +func init() { proto.RegisterFile("etcdserver.proto", fileDescriptorEtcdserver) } + var fileDescriptorEtcdserver = []byte{ - // 404 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x5c, 0x92, 0x41, 0x6e, 0x13, 0x31, - 0x14, 0x86, 0xe3, 0xc4, 0x99, 0x64, 0x4c, 0x81, 0x62, 0x45, 0xe8, 0xa9, 0x42, 0x43, 0x14, 0xb1, - 0xc8, 0x0a, 0xee, 0x50, 0xd2, 0x45, 0x24, 0x8a, 0x4a, 0x8a, 0xca, 0xda, 0x64, 0x1e, 0x8d, 0xa5, - 0xcc, 0x78, 0x6a, 0xbf, 0x19, 0x72, 0x03, 0xae, 0xc0, 0x91, 0xb2, 0xe4, 0x04, 0x08, 0xc2, 0x45, - 0x90, 0x3d, 0x9d, 0x60, 0xba, 0xb3, 0xbe, 0xff, 0xf7, 0xef, 0xdf, 0xf6, 0x13, 0xa7, 0x48, 0xeb, - 0xdc, 0xa1, 0x6d, 0xd0, 0xbe, 0xae, 0xac, 0x21, 0x23, 0x4f, 0xfe, 0x91, 0xea, 0xf3, 0xd9, 0xe4, - 0xd6, 0xdc, 0x9a, 0x20, 0xbc, 0xf1, 0xab, 0xd6, 0x33, 0xfb, 0xc6, 0xc5, 0x68, 0x85, 0x77, 0x35, - 0x3a, 0x92, 0x13, 0xd1, 0x5f, 0x2e, 0x80, 0x4d, 0xd9, 0x9c, 0x9f, 0xf3, 0xfd, 0xcf, 0x97, 0xbd, - 0x55, 0x5f, 0x2f, 0xe4, 0x0b, 0x91, 0x5c, 0x22, 0x6d, 0x4c, 0x0e, 0xfd, 0x29, 0x9b, 0xa7, 0xf7, - 0x4a, 0x52, 0x04, 0x26, 0x41, 0xf0, 0x2b, 0x45, 0x1b, 0x18, 0x44, 0x1a, 0xaf, 0x14, 0x6d, 0xe4, - 0x73, 0x31, 0xb8, 0x51, 0x5b, 0xe0, 0x91, 0x30, 0x68, 0xd4, 0xd6, 0xf3, 0x85, 0xb6, 0x30, 0x9c, - 0xb2, 0xf9, 0xb8, 0xe3, 0xb9, 0xb6, 0x72, 0x26, 0xd2, 0x2b, 0x8b, 0xcd, 0x8d, 0xda, 0xd6, 0x08, - 0x49, 0xb4, 0x2b, 0xad, 0x3a, 0xdc, 0x79, 0x96, 0x65, 0x8e, 0x3b, 0x18, 0x45, 0x45, 0x83, 0x27, - 0xe0, 0xce, 0x73, 0xb1, 0xd3, 0x8e, 0x60, 0x7c, 0x3c, 0x85, 0xb5, 0x9e, 0x80, 0xe5, 0x2b, 0x21, - 0x2e, 0x76, 0x95, 0xb6, 0x8a, 0xb4, 0x29, 0x21, 0x9d, 0xb2, 0xf9, 0xe0, 0x3e, 0x48, 0xe0, 0x91, - 0xfb, 0xbb, 0x7d, 0x52, 0x9a, 0x40, 0x44, 0x55, 0xf9, 0x57, 0xa5, 0x49, 0x9e, 0x89, 0xe1, 0xb5, - 0x2e, 0xd7, 0x08, 0x8f, 0xa2, 0x0e, 0x43, 0xe7, 0x91, 0x3f, 0x7f, 0x85, 0xeb, 0xda, 0x3a, 0xdd, - 0x20, 0x9c, 0x44, 0x5b, 0x53, 0xdb, 0x61, 0xff, 0xa6, 0xd7, 0xc6, 0x12, 0xe6, 0xf0, 0x38, 0x32, - 0x24, 0x2e, 0x30, 0xaf, 0x7e, 0xa8, 0x8d, 0xad, 0x0b, 0x78, 0x12, 0xab, 0x77, 0x81, 0xf9, 0x56, - 0x1f, 0x75, 0x81, 0xf0, 0x34, 0x6a, 0xcd, 0x49, 0x17, 0x6d, 0x2a, 0x59, 0x54, 0x05, 0x9c, 0xfe, - 0x97, 0x1a, 0x98, 0xcc, 0xfc, 0x47, 0x7f, 0xb1, 0xe8, 0x36, 0xf0, 0x2c, 0x7a, 0x95, 0x91, 0x6d, - 0xe1, 0xec, 0x9d, 0x18, 0x5f, 0x22, 0xa9, 0x5c, 0x91, 0xf2, 0x49, 0xef, 0x4d, 0x8e, 0x0f, 0xa6, - 0x21, 0x29, 0x03, 0xf3, 0x37, 0x7c, 0xbb, 0xad, 0x1d, 0xa1, 0x5d, 0x2e, 0xc2, 0x50, 0x1c, 0x7f, - 0x61, 0xdd, 0xe1, 0xf3, 0xc9, 0xfe, 0x77, 0xd6, 0xdb, 0x1f, 0x32, 0xf6, 0xe3, 0x90, 0xb1, 0x5f, - 0x87, 0x8c, 0x7d, 0xff, 0x93, 0xf5, 0xfe, 0x06, 0x00, 0x00, 0xff, 0xff, 0x80, 0x62, 0xfc, 0x40, - 0xa4, 0x02, 0x00, 0x00, + // 380 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x5c, 0xd2, 0xdd, 0x6e, 0xda, 0x30, + 0x14, 0x07, 0x70, 0x0c, 0xe1, 0xcb, 0x63, 0x1b, 0xb3, 0xd0, 0x74, 0x84, 0xa6, 0x2c, 0x42, 0xbb, + 0xc8, 0xd5, 0xf6, 0x0e, 0x2c, 0x5c, 0x44, 0x2a, 0x15, 0x0d, 0x15, 0xbd, 0x76, 0xc9, 0x29, 0x58, + 0x02, 0x4c, 0x1d, 0x07, 0xf1, 0x06, 0x7d, 0x85, 0x3e, 0x12, 0x97, 0x7d, 0x82, 0xaa, 0xa5, 0x2f, + 0x52, 0x39, 0x24, 0xc4, 0xed, 0x5d, 0xf4, 0xfb, 0x9f, 0x1c, 0x1f, 0x7f, 0xd0, 0x2e, 0xea, 0x79, + 0x9c, 0xa0, 0xda, 0xa1, 0xfa, 0xbb, 0x55, 0x52, 0x4b, 0xd6, 0x29, 0x65, 0x7b, 0xdb, 0xef, 0x2d, + 0xe4, 0x42, 0x66, 0xc1, 0x3f, 0xf3, 0x75, 0xaa, 0x19, 0x3c, 0x38, 0xb4, 0x19, 0xe1, 0x7d, 0x8a, + 0x89, 0x66, 0x3d, 0x5a, 0x0d, 0x03, 0x20, 0x1e, 0xf1, 0x9d, 0xa1, 0x73, 0x78, 0xfe, 0x5d, 0x89, + 0xaa, 0x61, 0xc0, 0x7e, 0xd1, 0xc6, 0x18, 0xf5, 0x52, 0xc6, 0x50, 0xf5, 0x88, 0xdf, 0xce, 0x93, + 0xdc, 0x18, 0x50, 0x67, 0xc2, 0xf5, 0x12, 0x6a, 0x56, 0x96, 0x09, 0xfb, 0x49, 0x6b, 0x33, 0xbe, + 0x02, 0xc7, 0x0a, 0x0c, 0x18, 0x0f, 0x84, 0x82, 0xba, 0x47, 0xfc, 0x56, 0xe1, 0x81, 0x50, 0x6c, + 0x40, 0xdb, 0x13, 0x85, 0xbb, 0x19, 0x5f, 0xa5, 0x08, 0x0d, 0xeb, 0xaf, 0x92, 0x8b, 0x9a, 0x70, + 0x13, 0xe3, 0x1e, 0x9a, 0xd6, 0xa0, 0x25, 0x17, 0x35, 0xa3, 0xbd, 0x48, 0x34, 0xb4, 0xce, 0xab, + 0x90, 0xa8, 0x64, 0xf6, 0x87, 0xd2, 0xd1, 0x7e, 0x2b, 0x14, 0xd7, 0x42, 0x6e, 0xa0, 0xed, 0x11, + 0xbf, 0x96, 0x37, 0xb2, 0xdc, 0xec, 0xed, 0x86, 0x0b, 0x0d, 0xd4, 0x1a, 0x35, 0x13, 0xd6, 0xa7, + 0xf5, 0xa9, 0xd8, 0xcc, 0x11, 0xbe, 0x58, 0x33, 0x9c, 0xc8, 0xac, 0x1f, 0xe1, 0x3c, 0x55, 0x89, + 0xd8, 0x21, 0x74, 0xac, 0x5f, 0x4b, 0x36, 0x67, 0x3a, 0x95, 0x4a, 0x63, 0x0c, 0x5f, 0xad, 0x82, + 0xdc, 0x4c, 0x7a, 0x95, 0x4a, 0x95, 0xae, 0xe1, 0x9b, 0x9d, 0x9e, 0xcc, 0x4c, 0x75, 0x2d, 0xd6, + 0x08, 0xdf, 0xad, 0xa9, 0x33, 0xc9, 0xba, 0x6a, 0x85, 0x7c, 0x0d, 0xdd, 0x0f, 0x5d, 0x33, 0x63, + 0xae, 0xb9, 0xe8, 0x3b, 0x85, 0xc9, 0x12, 0x7e, 0x58, 0xa7, 0x52, 0xe0, 0xe0, 0x82, 0xb6, 0xc6, + 0xa8, 0x79, 0xcc, 0x35, 0x37, 0x9d, 0x2e, 0x65, 0x8c, 0x9f, 0x5e, 0x43, 0x6e, 0x66, 0x87, 0xff, + 0x57, 0x69, 0xa2, 0x51, 0x85, 0x41, 0xf6, 0x28, 0xce, 0xb7, 0x70, 0xe6, 0x61, 0xef, 0xf0, 0xea, + 0x56, 0x0e, 0x47, 0x97, 0x3c, 0x1d, 0x5d, 0xf2, 0x72, 0x74, 0xc9, 0xe3, 0x9b, 0x5b, 0x79, 0x0f, + 0x00, 0x00, 0xff, 0xff, 0xee, 0x40, 0xba, 0xd6, 0xa4, 0x02, 0x00, 0x00, } 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 a82e2b235..66890c93c 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 @@ -20,9 +20,11 @@ var _ = fmt.Errorf var _ = math.Inf type RequestHeader struct { - ID uint64 `protobuf:"varint,1,opt,name=ID,json=iD,proto3" json:"ID,omitempty"` + ID uint64 `protobuf:"varint,1,opt,name=ID,proto3" json:"ID,omitempty"` // username is a username that is associated with an auth token of gRPC connection Username string `protobuf:"bytes,2,opt,name=username,proto3" json:"username,omitempty"` + // auth_revision is a revision number of auth.authStore. It is not related to mvcc + AuthRevision uint64 `protobuf:"varint,3,opt,name=auth_revision,json=authRevision,proto3" json:"auth_revision,omitempty"` } func (m *RequestHeader) Reset() { *m = RequestHeader{} } @@ -34,7 +36,7 @@ func (*RequestHeader) Descriptor() ([]byte, []int) { return fileDescriptorRaftIn // sent via raft. type InternalRaftRequest struct { Header *RequestHeader `protobuf:"bytes,100,opt,name=header" json:"header,omitempty"` - ID uint64 `protobuf:"varint,1,opt,name=ID,json=iD,proto3" json:"ID,omitempty"` + ID uint64 `protobuf:"varint,1,opt,name=ID,proto3" json:"ID,omitempty"` V2 *Request `protobuf:"bytes,2,opt,name=v2" json:"v2,omitempty"` Range *RangeRequest `protobuf:"bytes,3,opt,name=range" json:"range,omitempty"` Put *PutRequest `protobuf:"bytes,4,opt,name=put" json:"put,omitempty"` @@ -98,344 +100,349 @@ func init() { proto.RegisterType((*EmptyResponse)(nil), "etcdserverpb.EmptyResponse") proto.RegisterType((*InternalAuthenticateRequest)(nil), "etcdserverpb.InternalAuthenticateRequest") } -func (m *RequestHeader) Marshal() (data []byte, err error) { +func (m *RequestHeader) Marshal() (dAtA []byte, err error) { size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) if err != nil { return nil, err } - return data[:n], nil + return dAtA[:n], nil } -func (m *RequestHeader) MarshalTo(data []byte) (int, error) { +func (m *RequestHeader) MarshalTo(dAtA []byte) (int, error) { var i int _ = i var l int _ = l if m.ID != 0 { - data[i] = 0x8 + dAtA[i] = 0x8 i++ - i = encodeVarintRaftInternal(data, i, uint64(m.ID)) + i = encodeVarintRaftInternal(dAtA, i, uint64(m.ID)) } if len(m.Username) > 0 { - data[i] = 0x12 + dAtA[i] = 0x12 i++ - i = encodeVarintRaftInternal(data, i, uint64(len(m.Username))) - i += copy(data[i:], m.Username) + i = encodeVarintRaftInternal(dAtA, i, uint64(len(m.Username))) + i += copy(dAtA[i:], m.Username) + } + if m.AuthRevision != 0 { + dAtA[i] = 0x18 + i++ + i = encodeVarintRaftInternal(dAtA, i, uint64(m.AuthRevision)) } return i, nil } -func (m *InternalRaftRequest) Marshal() (data []byte, err error) { +func (m *InternalRaftRequest) Marshal() (dAtA []byte, err error) { size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) if err != nil { return nil, err } - return data[:n], nil + return dAtA[:n], nil } -func (m *InternalRaftRequest) MarshalTo(data []byte) (int, error) { +func (m *InternalRaftRequest) MarshalTo(dAtA []byte) (int, error) { var i int _ = i var l int _ = l if m.ID != 0 { - data[i] = 0x8 + dAtA[i] = 0x8 i++ - i = encodeVarintRaftInternal(data, i, uint64(m.ID)) + i = encodeVarintRaftInternal(dAtA, i, uint64(m.ID)) } if m.V2 != nil { - data[i] = 0x12 + dAtA[i] = 0x12 i++ - i = encodeVarintRaftInternal(data, i, uint64(m.V2.Size())) - n1, err := m.V2.MarshalTo(data[i:]) + i = encodeVarintRaftInternal(dAtA, i, uint64(m.V2.Size())) + n1, err := m.V2.MarshalTo(dAtA[i:]) if err != nil { return 0, err } i += n1 } if m.Range != nil { - data[i] = 0x1a + dAtA[i] = 0x1a i++ - i = encodeVarintRaftInternal(data, i, uint64(m.Range.Size())) - n2, err := m.Range.MarshalTo(data[i:]) + i = encodeVarintRaftInternal(dAtA, i, uint64(m.Range.Size())) + n2, err := m.Range.MarshalTo(dAtA[i:]) if err != nil { return 0, err } i += n2 } if m.Put != nil { - data[i] = 0x22 + dAtA[i] = 0x22 i++ - i = encodeVarintRaftInternal(data, i, uint64(m.Put.Size())) - n3, err := m.Put.MarshalTo(data[i:]) + i = encodeVarintRaftInternal(dAtA, i, uint64(m.Put.Size())) + n3, err := m.Put.MarshalTo(dAtA[i:]) if err != nil { return 0, err } i += n3 } if m.DeleteRange != nil { - data[i] = 0x2a + dAtA[i] = 0x2a i++ - i = encodeVarintRaftInternal(data, i, uint64(m.DeleteRange.Size())) - n4, err := m.DeleteRange.MarshalTo(data[i:]) + i = encodeVarintRaftInternal(dAtA, i, uint64(m.DeleteRange.Size())) + n4, err := m.DeleteRange.MarshalTo(dAtA[i:]) if err != nil { return 0, err } i += n4 } if m.Txn != nil { - data[i] = 0x32 + dAtA[i] = 0x32 i++ - i = encodeVarintRaftInternal(data, i, uint64(m.Txn.Size())) - n5, err := m.Txn.MarshalTo(data[i:]) + i = encodeVarintRaftInternal(dAtA, i, uint64(m.Txn.Size())) + n5, err := m.Txn.MarshalTo(dAtA[i:]) if err != nil { return 0, err } i += n5 } if m.Compaction != nil { - data[i] = 0x3a + dAtA[i] = 0x3a i++ - i = encodeVarintRaftInternal(data, i, uint64(m.Compaction.Size())) - n6, err := m.Compaction.MarshalTo(data[i:]) + i = encodeVarintRaftInternal(dAtA, i, uint64(m.Compaction.Size())) + n6, err := m.Compaction.MarshalTo(dAtA[i:]) if err != nil { return 0, err } i += n6 } if m.LeaseGrant != nil { - data[i] = 0x42 + dAtA[i] = 0x42 i++ - i = encodeVarintRaftInternal(data, i, uint64(m.LeaseGrant.Size())) - n7, err := m.LeaseGrant.MarshalTo(data[i:]) + i = encodeVarintRaftInternal(dAtA, i, uint64(m.LeaseGrant.Size())) + n7, err := m.LeaseGrant.MarshalTo(dAtA[i:]) if err != nil { return 0, err } i += n7 } if m.LeaseRevoke != nil { - data[i] = 0x4a + dAtA[i] = 0x4a i++ - i = encodeVarintRaftInternal(data, i, uint64(m.LeaseRevoke.Size())) - n8, err := m.LeaseRevoke.MarshalTo(data[i:]) + i = encodeVarintRaftInternal(dAtA, i, uint64(m.LeaseRevoke.Size())) + n8, err := m.LeaseRevoke.MarshalTo(dAtA[i:]) if err != nil { return 0, err } i += n8 } if m.Alarm != nil { - data[i] = 0x52 + dAtA[i] = 0x52 i++ - i = encodeVarintRaftInternal(data, i, uint64(m.Alarm.Size())) - n9, err := m.Alarm.MarshalTo(data[i:]) + i = encodeVarintRaftInternal(dAtA, i, uint64(m.Alarm.Size())) + n9, err := m.Alarm.MarshalTo(dAtA[i:]) if err != nil { return 0, err } i += n9 } if m.Header != nil { - data[i] = 0xa2 + dAtA[i] = 0xa2 i++ - data[i] = 0x6 + dAtA[i] = 0x6 i++ - i = encodeVarintRaftInternal(data, i, uint64(m.Header.Size())) - n10, err := m.Header.MarshalTo(data[i:]) + i = encodeVarintRaftInternal(dAtA, i, uint64(m.Header.Size())) + n10, err := m.Header.MarshalTo(dAtA[i:]) if err != nil { return 0, err } i += n10 } if m.AuthEnable != nil { - data[i] = 0xc2 + dAtA[i] = 0xc2 i++ - data[i] = 0x3e + dAtA[i] = 0x3e i++ - i = encodeVarintRaftInternal(data, i, uint64(m.AuthEnable.Size())) - n11, err := m.AuthEnable.MarshalTo(data[i:]) + i = encodeVarintRaftInternal(dAtA, i, uint64(m.AuthEnable.Size())) + n11, err := m.AuthEnable.MarshalTo(dAtA[i:]) if err != nil { return 0, err } i += n11 } if m.AuthDisable != nil { - data[i] = 0x9a + dAtA[i] = 0x9a i++ - data[i] = 0x3f + dAtA[i] = 0x3f i++ - i = encodeVarintRaftInternal(data, i, uint64(m.AuthDisable.Size())) - n12, err := m.AuthDisable.MarshalTo(data[i:]) + i = encodeVarintRaftInternal(dAtA, i, uint64(m.AuthDisable.Size())) + n12, err := m.AuthDisable.MarshalTo(dAtA[i:]) if err != nil { return 0, err } i += n12 } if m.Authenticate != nil { - data[i] = 0xa2 + dAtA[i] = 0xa2 i++ - data[i] = 0x3f + dAtA[i] = 0x3f i++ - i = encodeVarintRaftInternal(data, i, uint64(m.Authenticate.Size())) - n13, err := m.Authenticate.MarshalTo(data[i:]) + i = encodeVarintRaftInternal(dAtA, i, uint64(m.Authenticate.Size())) + n13, err := m.Authenticate.MarshalTo(dAtA[i:]) if err != nil { return 0, err } i += n13 } if m.AuthUserAdd != nil { - data[i] = 0xe2 + dAtA[i] = 0xe2 i++ - data[i] = 0x44 + dAtA[i] = 0x44 i++ - i = encodeVarintRaftInternal(data, i, uint64(m.AuthUserAdd.Size())) - n14, err := m.AuthUserAdd.MarshalTo(data[i:]) + i = encodeVarintRaftInternal(dAtA, i, uint64(m.AuthUserAdd.Size())) + n14, err := m.AuthUserAdd.MarshalTo(dAtA[i:]) if err != nil { return 0, err } i += n14 } if m.AuthUserDelete != nil { - data[i] = 0xea + dAtA[i] = 0xea i++ - data[i] = 0x44 + dAtA[i] = 0x44 i++ - i = encodeVarintRaftInternal(data, i, uint64(m.AuthUserDelete.Size())) - n15, err := m.AuthUserDelete.MarshalTo(data[i:]) + i = encodeVarintRaftInternal(dAtA, i, uint64(m.AuthUserDelete.Size())) + n15, err := m.AuthUserDelete.MarshalTo(dAtA[i:]) if err != nil { return 0, err } i += n15 } if m.AuthUserGet != nil { - data[i] = 0xf2 + dAtA[i] = 0xf2 i++ - data[i] = 0x44 + dAtA[i] = 0x44 i++ - i = encodeVarintRaftInternal(data, i, uint64(m.AuthUserGet.Size())) - n16, err := m.AuthUserGet.MarshalTo(data[i:]) + i = encodeVarintRaftInternal(dAtA, i, uint64(m.AuthUserGet.Size())) + n16, err := m.AuthUserGet.MarshalTo(dAtA[i:]) if err != nil { return 0, err } i += n16 } if m.AuthUserChangePassword != nil { - data[i] = 0xfa + dAtA[i] = 0xfa i++ - data[i] = 0x44 + dAtA[i] = 0x44 i++ - i = encodeVarintRaftInternal(data, i, uint64(m.AuthUserChangePassword.Size())) - n17, err := m.AuthUserChangePassword.MarshalTo(data[i:]) + i = encodeVarintRaftInternal(dAtA, i, uint64(m.AuthUserChangePassword.Size())) + n17, err := m.AuthUserChangePassword.MarshalTo(dAtA[i:]) if err != nil { return 0, err } i += n17 } if m.AuthUserGrantRole != nil { - data[i] = 0x82 + dAtA[i] = 0x82 i++ - data[i] = 0x45 + dAtA[i] = 0x45 i++ - i = encodeVarintRaftInternal(data, i, uint64(m.AuthUserGrantRole.Size())) - n18, err := m.AuthUserGrantRole.MarshalTo(data[i:]) + i = encodeVarintRaftInternal(dAtA, i, uint64(m.AuthUserGrantRole.Size())) + n18, err := m.AuthUserGrantRole.MarshalTo(dAtA[i:]) if err != nil { return 0, err } i += n18 } if m.AuthUserRevokeRole != nil { - data[i] = 0x8a + dAtA[i] = 0x8a i++ - data[i] = 0x45 + dAtA[i] = 0x45 i++ - i = encodeVarintRaftInternal(data, i, uint64(m.AuthUserRevokeRole.Size())) - n19, err := m.AuthUserRevokeRole.MarshalTo(data[i:]) + i = encodeVarintRaftInternal(dAtA, i, uint64(m.AuthUserRevokeRole.Size())) + n19, err := m.AuthUserRevokeRole.MarshalTo(dAtA[i:]) if err != nil { return 0, err } i += n19 } if m.AuthUserList != nil { - data[i] = 0x92 + dAtA[i] = 0x92 i++ - data[i] = 0x45 + dAtA[i] = 0x45 i++ - i = encodeVarintRaftInternal(data, i, uint64(m.AuthUserList.Size())) - n20, err := m.AuthUserList.MarshalTo(data[i:]) + i = encodeVarintRaftInternal(dAtA, i, uint64(m.AuthUserList.Size())) + n20, err := m.AuthUserList.MarshalTo(dAtA[i:]) if err != nil { return 0, err } i += n20 } if m.AuthRoleList != nil { - data[i] = 0x9a + dAtA[i] = 0x9a i++ - data[i] = 0x45 + dAtA[i] = 0x45 i++ - i = encodeVarintRaftInternal(data, i, uint64(m.AuthRoleList.Size())) - n21, err := m.AuthRoleList.MarshalTo(data[i:]) + i = encodeVarintRaftInternal(dAtA, i, uint64(m.AuthRoleList.Size())) + n21, err := m.AuthRoleList.MarshalTo(dAtA[i:]) if err != nil { return 0, err } i += n21 } if m.AuthRoleAdd != nil { - data[i] = 0x82 + dAtA[i] = 0x82 i++ - data[i] = 0x4b + dAtA[i] = 0x4b i++ - i = encodeVarintRaftInternal(data, i, uint64(m.AuthRoleAdd.Size())) - n22, err := m.AuthRoleAdd.MarshalTo(data[i:]) + i = encodeVarintRaftInternal(dAtA, i, uint64(m.AuthRoleAdd.Size())) + n22, err := m.AuthRoleAdd.MarshalTo(dAtA[i:]) if err != nil { return 0, err } i += n22 } if m.AuthRoleDelete != nil { - data[i] = 0x8a + dAtA[i] = 0x8a i++ - data[i] = 0x4b + dAtA[i] = 0x4b i++ - i = encodeVarintRaftInternal(data, i, uint64(m.AuthRoleDelete.Size())) - n23, err := m.AuthRoleDelete.MarshalTo(data[i:]) + i = encodeVarintRaftInternal(dAtA, i, uint64(m.AuthRoleDelete.Size())) + n23, err := m.AuthRoleDelete.MarshalTo(dAtA[i:]) if err != nil { return 0, err } i += n23 } if m.AuthRoleGet != nil { - data[i] = 0x92 + dAtA[i] = 0x92 i++ - data[i] = 0x4b + dAtA[i] = 0x4b i++ - i = encodeVarintRaftInternal(data, i, uint64(m.AuthRoleGet.Size())) - n24, err := m.AuthRoleGet.MarshalTo(data[i:]) + i = encodeVarintRaftInternal(dAtA, i, uint64(m.AuthRoleGet.Size())) + n24, err := m.AuthRoleGet.MarshalTo(dAtA[i:]) if err != nil { return 0, err } i += n24 } if m.AuthRoleGrantPermission != nil { - data[i] = 0x9a + dAtA[i] = 0x9a i++ - data[i] = 0x4b + dAtA[i] = 0x4b i++ - i = encodeVarintRaftInternal(data, i, uint64(m.AuthRoleGrantPermission.Size())) - n25, err := m.AuthRoleGrantPermission.MarshalTo(data[i:]) + i = encodeVarintRaftInternal(dAtA, i, uint64(m.AuthRoleGrantPermission.Size())) + n25, err := m.AuthRoleGrantPermission.MarshalTo(dAtA[i:]) if err != nil { return 0, err } i += n25 } if m.AuthRoleRevokePermission != nil { - data[i] = 0xa2 + dAtA[i] = 0xa2 i++ - data[i] = 0x4b + dAtA[i] = 0x4b i++ - i = encodeVarintRaftInternal(data, i, uint64(m.AuthRoleRevokePermission.Size())) - n26, err := m.AuthRoleRevokePermission.MarshalTo(data[i:]) + i = encodeVarintRaftInternal(dAtA, i, uint64(m.AuthRoleRevokePermission.Size())) + n26, err := m.AuthRoleRevokePermission.MarshalTo(dAtA[i:]) if err != nil { return 0, err } @@ -444,17 +451,17 @@ func (m *InternalRaftRequest) MarshalTo(data []byte) (int, error) { return i, nil } -func (m *EmptyResponse) Marshal() (data []byte, err error) { +func (m *EmptyResponse) Marshal() (dAtA []byte, err error) { size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) if err != nil { return nil, err } - return data[:n], nil + return dAtA[:n], nil } -func (m *EmptyResponse) MarshalTo(data []byte) (int, error) { +func (m *EmptyResponse) MarshalTo(dAtA []byte) (int, error) { var i int _ = i var l int @@ -462,67 +469,67 @@ func (m *EmptyResponse) MarshalTo(data []byte) (int, error) { return i, nil } -func (m *InternalAuthenticateRequest) Marshal() (data []byte, err error) { +func (m *InternalAuthenticateRequest) Marshal() (dAtA []byte, err error) { size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) if err != nil { return nil, err } - return data[:n], nil + return dAtA[:n], nil } -func (m *InternalAuthenticateRequest) MarshalTo(data []byte) (int, error) { +func (m *InternalAuthenticateRequest) MarshalTo(dAtA []byte) (int, error) { var i int _ = i var l int _ = l if len(m.Name) > 0 { - data[i] = 0xa + dAtA[i] = 0xa i++ - i = encodeVarintRaftInternal(data, i, uint64(len(m.Name))) - i += copy(data[i:], m.Name) + i = encodeVarintRaftInternal(dAtA, i, uint64(len(m.Name))) + i += copy(dAtA[i:], m.Name) } if len(m.Password) > 0 { - data[i] = 0x12 + dAtA[i] = 0x12 i++ - i = encodeVarintRaftInternal(data, i, uint64(len(m.Password))) - i += copy(data[i:], m.Password) + i = encodeVarintRaftInternal(dAtA, i, uint64(len(m.Password))) + i += copy(dAtA[i:], m.Password) } if len(m.SimpleToken) > 0 { - data[i] = 0x1a + dAtA[i] = 0x1a i++ - i = encodeVarintRaftInternal(data, i, uint64(len(m.SimpleToken))) - i += copy(data[i:], m.SimpleToken) + i = encodeVarintRaftInternal(dAtA, i, uint64(len(m.SimpleToken))) + i += copy(dAtA[i:], m.SimpleToken) } return i, nil } -func encodeFixed64RaftInternal(data []byte, offset int, v uint64) int { - data[offset] = uint8(v) - data[offset+1] = uint8(v >> 8) - data[offset+2] = uint8(v >> 16) - data[offset+3] = uint8(v >> 24) - data[offset+4] = uint8(v >> 32) - data[offset+5] = uint8(v >> 40) - data[offset+6] = uint8(v >> 48) - data[offset+7] = uint8(v >> 56) +func encodeFixed64RaftInternal(dAtA []byte, offset int, v uint64) int { + dAtA[offset] = uint8(v) + dAtA[offset+1] = uint8(v >> 8) + dAtA[offset+2] = uint8(v >> 16) + dAtA[offset+3] = uint8(v >> 24) + dAtA[offset+4] = uint8(v >> 32) + dAtA[offset+5] = uint8(v >> 40) + dAtA[offset+6] = uint8(v >> 48) + dAtA[offset+7] = uint8(v >> 56) return offset + 8 } -func encodeFixed32RaftInternal(data []byte, offset int, v uint32) int { - data[offset] = uint8(v) - data[offset+1] = uint8(v >> 8) - data[offset+2] = uint8(v >> 16) - data[offset+3] = uint8(v >> 24) +func encodeFixed32RaftInternal(dAtA []byte, offset int, v uint32) int { + dAtA[offset] = uint8(v) + dAtA[offset+1] = uint8(v >> 8) + dAtA[offset+2] = uint8(v >> 16) + dAtA[offset+3] = uint8(v >> 24) return offset + 4 } -func encodeVarintRaftInternal(data []byte, offset int, v uint64) int { +func encodeVarintRaftInternal(dAtA []byte, offset int, v uint64) int { for v >= 1<<7 { - data[offset] = uint8(v&0x7f | 0x80) + dAtA[offset] = uint8(v&0x7f | 0x80) v >>= 7 offset++ } - data[offset] = uint8(v) + dAtA[offset] = uint8(v) return offset + 1 } func (m *RequestHeader) Size() (n int) { @@ -535,6 +542,9 @@ func (m *RequestHeader) Size() (n int) { if l > 0 { n += 1 + l + sovRaftInternal(uint64(l)) } + if m.AuthRevision != 0 { + n += 1 + sovRaftInternal(uint64(m.AuthRevision)) + } return n } @@ -688,8 +698,8 @@ func sovRaftInternal(x uint64) (n int) { func sozRaftInternal(x uint64) (n int) { return sovRaftInternal(uint64((x << 1) ^ uint64((int64(x) >> 63)))) } -func (m *RequestHeader) Unmarshal(data []byte) error { - l := len(data) +func (m *RequestHeader) Unmarshal(dAtA []byte) error { + l := len(dAtA) iNdEx := 0 for iNdEx < l { preIndex := iNdEx @@ -701,7 +711,7 @@ func (m *RequestHeader) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -729,7 +739,7 @@ func (m *RequestHeader) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ m.ID |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -748,7 +758,7 @@ func (m *RequestHeader) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ stringLen |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -763,11 +773,30 @@ func (m *RequestHeader) Unmarshal(data []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Username = string(data[iNdEx:postIndex]) + m.Username = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field AuthRevision", wireType) + } + m.AuthRevision = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRaftInternal + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.AuthRevision |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex - skippy, err := skipRaftInternal(data[iNdEx:]) + skippy, err := skipRaftInternal(dAtA[iNdEx:]) if err != nil { return err } @@ -786,8 +815,8 @@ func (m *RequestHeader) Unmarshal(data []byte) error { } return nil } -func (m *InternalRaftRequest) Unmarshal(data []byte) error { - l := len(data) +func (m *InternalRaftRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) iNdEx := 0 for iNdEx < l { preIndex := iNdEx @@ -799,7 +828,7 @@ func (m *InternalRaftRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -827,7 +856,7 @@ func (m *InternalRaftRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ m.ID |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -846,7 +875,7 @@ func (m *InternalRaftRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ msglen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -863,7 +892,7 @@ func (m *InternalRaftRequest) Unmarshal(data []byte) error { if m.V2 == nil { m.V2 = &Request{} } - if err := m.V2.Unmarshal(data[iNdEx:postIndex]); err != nil { + if err := m.V2.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -879,7 +908,7 @@ func (m *InternalRaftRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ msglen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -896,7 +925,7 @@ func (m *InternalRaftRequest) Unmarshal(data []byte) error { if m.Range == nil { m.Range = &RangeRequest{} } - if err := m.Range.Unmarshal(data[iNdEx:postIndex]); err != nil { + if err := m.Range.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -912,7 +941,7 @@ func (m *InternalRaftRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ msglen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -929,7 +958,7 @@ func (m *InternalRaftRequest) Unmarshal(data []byte) error { if m.Put == nil { m.Put = &PutRequest{} } - if err := m.Put.Unmarshal(data[iNdEx:postIndex]); err != nil { + if err := m.Put.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -945,7 +974,7 @@ func (m *InternalRaftRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ msglen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -962,7 +991,7 @@ func (m *InternalRaftRequest) Unmarshal(data []byte) error { if m.DeleteRange == nil { m.DeleteRange = &DeleteRangeRequest{} } - if err := m.DeleteRange.Unmarshal(data[iNdEx:postIndex]); err != nil { + if err := m.DeleteRange.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -978,7 +1007,7 @@ func (m *InternalRaftRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ msglen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -995,7 +1024,7 @@ func (m *InternalRaftRequest) Unmarshal(data []byte) error { if m.Txn == nil { m.Txn = &TxnRequest{} } - if err := m.Txn.Unmarshal(data[iNdEx:postIndex]); err != nil { + if err := m.Txn.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -1011,7 +1040,7 @@ func (m *InternalRaftRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ msglen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -1028,7 +1057,7 @@ func (m *InternalRaftRequest) Unmarshal(data []byte) error { if m.Compaction == nil { m.Compaction = &CompactionRequest{} } - if err := m.Compaction.Unmarshal(data[iNdEx:postIndex]); err != nil { + if err := m.Compaction.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -1044,7 +1073,7 @@ func (m *InternalRaftRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ msglen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -1061,7 +1090,7 @@ func (m *InternalRaftRequest) Unmarshal(data []byte) error { if m.LeaseGrant == nil { m.LeaseGrant = &LeaseGrantRequest{} } - if err := m.LeaseGrant.Unmarshal(data[iNdEx:postIndex]); err != nil { + if err := m.LeaseGrant.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -1077,7 +1106,7 @@ func (m *InternalRaftRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ msglen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -1094,7 +1123,7 @@ func (m *InternalRaftRequest) Unmarshal(data []byte) error { if m.LeaseRevoke == nil { m.LeaseRevoke = &LeaseRevokeRequest{} } - if err := m.LeaseRevoke.Unmarshal(data[iNdEx:postIndex]); err != nil { + if err := m.LeaseRevoke.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -1110,7 +1139,7 @@ func (m *InternalRaftRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ msglen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -1127,7 +1156,7 @@ func (m *InternalRaftRequest) Unmarshal(data []byte) error { if m.Alarm == nil { m.Alarm = &AlarmRequest{} } - if err := m.Alarm.Unmarshal(data[iNdEx:postIndex]); err != nil { + if err := m.Alarm.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -1143,7 +1172,7 @@ func (m *InternalRaftRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ msglen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -1160,7 +1189,7 @@ func (m *InternalRaftRequest) Unmarshal(data []byte) error { if m.Header == nil { m.Header = &RequestHeader{} } - if err := m.Header.Unmarshal(data[iNdEx:postIndex]); err != nil { + if err := m.Header.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -1176,7 +1205,7 @@ func (m *InternalRaftRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ msglen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -1193,7 +1222,7 @@ func (m *InternalRaftRequest) Unmarshal(data []byte) error { if m.AuthEnable == nil { m.AuthEnable = &AuthEnableRequest{} } - if err := m.AuthEnable.Unmarshal(data[iNdEx:postIndex]); err != nil { + if err := m.AuthEnable.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -1209,7 +1238,7 @@ func (m *InternalRaftRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ msglen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -1226,7 +1255,7 @@ func (m *InternalRaftRequest) Unmarshal(data []byte) error { if m.AuthDisable == nil { m.AuthDisable = &AuthDisableRequest{} } - if err := m.AuthDisable.Unmarshal(data[iNdEx:postIndex]); err != nil { + if err := m.AuthDisable.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -1242,7 +1271,7 @@ func (m *InternalRaftRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ msglen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -1259,7 +1288,7 @@ func (m *InternalRaftRequest) Unmarshal(data []byte) error { if m.Authenticate == nil { m.Authenticate = &InternalAuthenticateRequest{} } - if err := m.Authenticate.Unmarshal(data[iNdEx:postIndex]); err != nil { + if err := m.Authenticate.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -1275,7 +1304,7 @@ func (m *InternalRaftRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ msglen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -1292,7 +1321,7 @@ func (m *InternalRaftRequest) Unmarshal(data []byte) error { if m.AuthUserAdd == nil { m.AuthUserAdd = &AuthUserAddRequest{} } - if err := m.AuthUserAdd.Unmarshal(data[iNdEx:postIndex]); err != nil { + if err := m.AuthUserAdd.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -1308,7 +1337,7 @@ func (m *InternalRaftRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ msglen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -1325,7 +1354,7 @@ func (m *InternalRaftRequest) Unmarshal(data []byte) error { if m.AuthUserDelete == nil { m.AuthUserDelete = &AuthUserDeleteRequest{} } - if err := m.AuthUserDelete.Unmarshal(data[iNdEx:postIndex]); err != nil { + if err := m.AuthUserDelete.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -1341,7 +1370,7 @@ func (m *InternalRaftRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ msglen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -1358,7 +1387,7 @@ func (m *InternalRaftRequest) Unmarshal(data []byte) error { if m.AuthUserGet == nil { m.AuthUserGet = &AuthUserGetRequest{} } - if err := m.AuthUserGet.Unmarshal(data[iNdEx:postIndex]); err != nil { + if err := m.AuthUserGet.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -1374,7 +1403,7 @@ func (m *InternalRaftRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ msglen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -1391,7 +1420,7 @@ func (m *InternalRaftRequest) Unmarshal(data []byte) error { if m.AuthUserChangePassword == nil { m.AuthUserChangePassword = &AuthUserChangePasswordRequest{} } - if err := m.AuthUserChangePassword.Unmarshal(data[iNdEx:postIndex]); err != nil { + if err := m.AuthUserChangePassword.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -1407,7 +1436,7 @@ func (m *InternalRaftRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ msglen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -1424,7 +1453,7 @@ func (m *InternalRaftRequest) Unmarshal(data []byte) error { if m.AuthUserGrantRole == nil { m.AuthUserGrantRole = &AuthUserGrantRoleRequest{} } - if err := m.AuthUserGrantRole.Unmarshal(data[iNdEx:postIndex]); err != nil { + if err := m.AuthUserGrantRole.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -1440,7 +1469,7 @@ func (m *InternalRaftRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ msglen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -1457,7 +1486,7 @@ func (m *InternalRaftRequest) Unmarshal(data []byte) error { if m.AuthUserRevokeRole == nil { m.AuthUserRevokeRole = &AuthUserRevokeRoleRequest{} } - if err := m.AuthUserRevokeRole.Unmarshal(data[iNdEx:postIndex]); err != nil { + if err := m.AuthUserRevokeRole.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -1473,7 +1502,7 @@ func (m *InternalRaftRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ msglen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -1490,7 +1519,7 @@ func (m *InternalRaftRequest) Unmarshal(data []byte) error { if m.AuthUserList == nil { m.AuthUserList = &AuthUserListRequest{} } - if err := m.AuthUserList.Unmarshal(data[iNdEx:postIndex]); err != nil { + if err := m.AuthUserList.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -1506,7 +1535,7 @@ func (m *InternalRaftRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ msglen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -1523,7 +1552,7 @@ func (m *InternalRaftRequest) Unmarshal(data []byte) error { if m.AuthRoleList == nil { m.AuthRoleList = &AuthRoleListRequest{} } - if err := m.AuthRoleList.Unmarshal(data[iNdEx:postIndex]); err != nil { + if err := m.AuthRoleList.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -1539,7 +1568,7 @@ func (m *InternalRaftRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ msglen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -1556,7 +1585,7 @@ func (m *InternalRaftRequest) Unmarshal(data []byte) error { if m.AuthRoleAdd == nil { m.AuthRoleAdd = &AuthRoleAddRequest{} } - if err := m.AuthRoleAdd.Unmarshal(data[iNdEx:postIndex]); err != nil { + if err := m.AuthRoleAdd.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -1572,7 +1601,7 @@ func (m *InternalRaftRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ msglen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -1589,7 +1618,7 @@ func (m *InternalRaftRequest) Unmarshal(data []byte) error { if m.AuthRoleDelete == nil { m.AuthRoleDelete = &AuthRoleDeleteRequest{} } - if err := m.AuthRoleDelete.Unmarshal(data[iNdEx:postIndex]); err != nil { + if err := m.AuthRoleDelete.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -1605,7 +1634,7 @@ func (m *InternalRaftRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ msglen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -1622,7 +1651,7 @@ func (m *InternalRaftRequest) Unmarshal(data []byte) error { if m.AuthRoleGet == nil { m.AuthRoleGet = &AuthRoleGetRequest{} } - if err := m.AuthRoleGet.Unmarshal(data[iNdEx:postIndex]); err != nil { + if err := m.AuthRoleGet.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -1638,7 +1667,7 @@ func (m *InternalRaftRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ msglen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -1655,7 +1684,7 @@ func (m *InternalRaftRequest) Unmarshal(data []byte) error { if m.AuthRoleGrantPermission == nil { m.AuthRoleGrantPermission = &AuthRoleGrantPermissionRequest{} } - if err := m.AuthRoleGrantPermission.Unmarshal(data[iNdEx:postIndex]); err != nil { + if err := m.AuthRoleGrantPermission.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -1671,7 +1700,7 @@ func (m *InternalRaftRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ msglen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -1688,13 +1717,13 @@ func (m *InternalRaftRequest) Unmarshal(data []byte) error { if m.AuthRoleRevokePermission == nil { m.AuthRoleRevokePermission = &AuthRoleRevokePermissionRequest{} } - if err := m.AuthRoleRevokePermission.Unmarshal(data[iNdEx:postIndex]); err != nil { + if err := m.AuthRoleRevokePermission.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skipRaftInternal(data[iNdEx:]) + skippy, err := skipRaftInternal(dAtA[iNdEx:]) if err != nil { return err } @@ -1713,8 +1742,8 @@ func (m *InternalRaftRequest) Unmarshal(data []byte) error { } return nil } -func (m *EmptyResponse) Unmarshal(data []byte) error { - l := len(data) +func (m *EmptyResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) iNdEx := 0 for iNdEx < l { preIndex := iNdEx @@ -1726,7 +1755,7 @@ func (m *EmptyResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -1744,7 +1773,7 @@ func (m *EmptyResponse) Unmarshal(data []byte) error { switch fieldNum { default: iNdEx = preIndex - skippy, err := skipRaftInternal(data[iNdEx:]) + skippy, err := skipRaftInternal(dAtA[iNdEx:]) if err != nil { return err } @@ -1763,8 +1792,8 @@ func (m *EmptyResponse) Unmarshal(data []byte) error { } return nil } -func (m *InternalAuthenticateRequest) Unmarshal(data []byte) error { - l := len(data) +func (m *InternalAuthenticateRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) iNdEx := 0 for iNdEx < l { preIndex := iNdEx @@ -1776,7 +1805,7 @@ func (m *InternalAuthenticateRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -1804,7 +1833,7 @@ func (m *InternalAuthenticateRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ stringLen |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -1819,7 +1848,7 @@ func (m *InternalAuthenticateRequest) Unmarshal(data []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Name = string(data[iNdEx:postIndex]) + m.Name = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: if wireType != 2 { @@ -1833,7 +1862,7 @@ func (m *InternalAuthenticateRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ stringLen |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -1848,7 +1877,7 @@ func (m *InternalAuthenticateRequest) Unmarshal(data []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Password = string(data[iNdEx:postIndex]) + m.Password = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 3: if wireType != 2 { @@ -1862,7 +1891,7 @@ func (m *InternalAuthenticateRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ stringLen |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -1877,11 +1906,11 @@ func (m *InternalAuthenticateRequest) Unmarshal(data []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.SimpleToken = string(data[iNdEx:postIndex]) + m.SimpleToken = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skipRaftInternal(data[iNdEx:]) + skippy, err := skipRaftInternal(dAtA[iNdEx:]) if err != nil { return err } @@ -1900,8 +1929,8 @@ func (m *InternalAuthenticateRequest) Unmarshal(data []byte) error { } return nil } -func skipRaftInternal(data []byte) (n int, err error) { - l := len(data) +func skipRaftInternal(dAtA []byte) (n int, err error) { + l := len(dAtA) iNdEx := 0 for iNdEx < l { var wire uint64 @@ -1912,7 +1941,7 @@ func skipRaftInternal(data []byte) (n int, err error) { if iNdEx >= l { return 0, io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -1930,7 +1959,7 @@ func skipRaftInternal(data []byte) (n int, err error) { return 0, io.ErrUnexpectedEOF } iNdEx++ - if data[iNdEx-1] < 0x80 { + if dAtA[iNdEx-1] < 0x80 { break } } @@ -1947,7 +1976,7 @@ func skipRaftInternal(data []byte) (n int, err error) { if iNdEx >= l { return 0, io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ length |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -1970,7 +1999,7 @@ func skipRaftInternal(data []byte) (n int, err error) { if iNdEx >= l { return 0, io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ innerWire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -1981,7 +2010,7 @@ func skipRaftInternal(data []byte) (n int, err error) { if innerWireType == 4 { break } - next, err := skipRaftInternal(data[start:]) + next, err := skipRaftInternal(dAtA[start:]) if err != nil { return 0, err } @@ -2005,58 +2034,61 @@ var ( ErrIntOverflowRaftInternal = fmt.Errorf("proto: integer overflow") ) +func init() { proto.RegisterFile("raft_internal.proto", fileDescriptorRaftInternal) } + var fileDescriptorRaftInternal = []byte{ - // 824 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x7c, 0x96, 0xdd, 0x4e, 0xdb, 0x48, - 0x14, 0xc7, 0x49, 0xf8, 0xcc, 0x24, 0x64, 0xd9, 0x01, 0x76, 0x67, 0x83, 0x94, 0x85, 0xac, 0x76, - 0x97, 0x7e, 0xd1, 0x0a, 0x2e, 0x7b, 0xd1, 0xa6, 0x04, 0x01, 0x12, 0x42, 0xc8, 0xa2, 0x52, 0xa5, - 0x5e, 0x58, 0x43, 0x7c, 0x48, 0x5c, 0x1c, 0xdb, 0xb5, 0x27, 0x29, 0x7d, 0x93, 0x3e, 0x46, 0xbf, - 0x1e, 0x82, 0x8b, 0x7e, 0xd0, 0xf6, 0x05, 0x5a, 0x7a, 0xd3, 0xab, 0xde, 0xb4, 0x0f, 0x50, 0xcd, - 0x87, 0xc7, 0x71, 0x32, 0xe1, 0xce, 0x3e, 0xe7, 0x7f, 0x7e, 0xe7, 0x4c, 0xe6, 0x3f, 0x9e, 0xa0, - 0xf9, 0x88, 0x1e, 0x33, 0xdb, 0xf5, 0x19, 0x44, 0x3e, 0xf5, 0xd6, 0xc2, 0x28, 0x60, 0x01, 0x2e, - 0x01, 0x6b, 0x3a, 0x31, 0x44, 0x3d, 0x88, 0xc2, 0xa3, 0xca, 0x42, 0x2b, 0x68, 0x05, 0x22, 0x71, - 0x93, 0x3f, 0x49, 0x4d, 0x65, 0x2e, 0xd5, 0xa8, 0x48, 0x21, 0x0a, 0x9b, 0xf2, 0xb1, 0x76, 0x1b, - 0xcd, 0x5a, 0xf0, 0xb8, 0x0b, 0x31, 0xdb, 0x01, 0xea, 0x40, 0x84, 0xcb, 0x28, 0xbf, 0xdb, 0x20, - 0xb9, 0xe5, 0xdc, 0xea, 0x84, 0x95, 0x77, 0x1b, 0xb8, 0x82, 0x66, 0xba, 0x31, 0x6f, 0xd9, 0x01, - 0x92, 0x5f, 0xce, 0xad, 0x16, 0x2c, 0xfd, 0x5e, 0xfb, 0x5e, 0x46, 0xf3, 0xbb, 0x6a, 0x20, 0x8b, - 0x1e, 0x33, 0x45, 0x1a, 0x62, 0xfc, 0x8b, 0xf2, 0xbd, 0x75, 0x51, 0x5d, 0x5c, 0x5f, 0x5c, 0xeb, - 0x1f, 0x79, 0x4d, 0x95, 0x58, 0xf9, 0xde, 0x3a, 0xbe, 0x85, 0x26, 0x23, 0xea, 0xb7, 0x80, 0x8c, - 0x0b, 0x65, 0x65, 0x40, 0xc9, 0x53, 0x89, 0x5c, 0x0a, 0xf1, 0x55, 0x34, 0x1e, 0x76, 0x19, 0x99, - 0x10, 0x7a, 0x92, 0xd5, 0x1f, 0x74, 0x93, 0x79, 0x2c, 0x2e, 0xc2, 0x9b, 0xa8, 0xe4, 0x80, 0x07, - 0x0c, 0x6c, 0xd9, 0x64, 0x52, 0x14, 0x2d, 0x67, 0x8b, 0x1a, 0x42, 0x91, 0x69, 0x55, 0x74, 0xd2, - 0x18, 0x6f, 0xc8, 0x4e, 0x7d, 0x32, 0x65, 0x6a, 0x78, 0x78, 0xea, 0xeb, 0x86, 0xec, 0xd4, 0xc7, - 0x77, 0x10, 0x6a, 0x06, 0x9d, 0x90, 0x36, 0x99, 0x1b, 0xf8, 0x64, 0x5a, 0x94, 0xfc, 0x9d, 0x2d, - 0xd9, 0xd4, 0xf9, 0xa4, 0xb2, 0xaf, 0x04, 0xdf, 0x45, 0x45, 0x0f, 0x68, 0x0c, 0x76, 0x2b, 0xa2, - 0x3e, 0x23, 0x33, 0x26, 0xc2, 0x1e, 0x17, 0x6c, 0xf3, 0xbc, 0x26, 0x78, 0x3a, 0xc4, 0xd7, 0x2c, - 0x09, 0x11, 0xf4, 0x82, 0x13, 0x20, 0x05, 0xd3, 0x9a, 0x05, 0xc2, 0x12, 0x02, 0xbd, 0x66, 0x2f, - 0x8d, 0xf1, 0x6d, 0xa1, 0x1e, 0x8d, 0x3a, 0x04, 0x99, 0xb6, 0xa5, 0xce, 0x53, 0x7a, 0x5b, 0x84, - 0x10, 0x6f, 0xa0, 0xa9, 0xb6, 0x70, 0x13, 0x71, 0x44, 0xc9, 0x92, 0x71, 0xcf, 0xa5, 0xe1, 0x2c, - 0x25, 0xc5, 0x75, 0x54, 0xa4, 0x5d, 0xd6, 0xb6, 0xc1, 0xa7, 0x47, 0x1e, 0x90, 0x6f, 0xc6, 0x1f, - 0xac, 0xde, 0x65, 0xed, 0x2d, 0x21, 0xd0, 0xcb, 0xa5, 0x3a, 0x84, 0x1b, 0xa8, 0x24, 0x10, 0x8e, - 0x1b, 0x0b, 0xc6, 0x8f, 0x69, 0xd3, 0x7a, 0x39, 0xa3, 0x21, 0x15, 0x7a, 0xbd, 0x34, 0x8d, 0xe1, - 0x7d, 0x49, 0x01, 0x9f, 0xb9, 0x4d, 0xca, 0x80, 0xfc, 0x94, 0x94, 0x2b, 0x59, 0x4a, 0xe2, 0xfb, - 0x7a, 0x9f, 0x34, 0xc1, 0x65, 0xea, 0xf1, 0x16, 0x9a, 0x15, 0x53, 0xf1, 0x63, 0x63, 0x53, 0xc7, - 0x21, 0x6f, 0x66, 0x46, 0x8d, 0x75, 0x3f, 0x86, 0xa8, 0xee, 0x38, 0x99, 0xb1, 0x54, 0x0c, 0xef, - 0xa3, 0xb9, 0x14, 0x23, 0x3d, 0x49, 0xde, 0x4a, 0xd2, 0x3f, 0x66, 0x92, 0x32, 0xb3, 0x82, 0x95, - 0x69, 0x26, 0x9c, 0x1d, 0xab, 0x05, 0x8c, 0xbc, 0xbb, 0x74, 0xac, 0x6d, 0x60, 0x43, 0x63, 0x6d, - 0x03, 0xc3, 0x2d, 0xf4, 0x57, 0x8a, 0x69, 0xb6, 0xf9, 0x29, 0xb1, 0x43, 0x1a, 0xc7, 0x4f, 0x82, - 0xc8, 0x21, 0xef, 0x25, 0xf2, 0x9a, 0x19, 0xb9, 0x29, 0xd4, 0x07, 0x4a, 0x9c, 0xd0, 0xff, 0xa0, - 0xc6, 0x34, 0x7e, 0x80, 0x16, 0xfa, 0xe6, 0xe5, 0xf6, 0xb6, 0xa3, 0xc0, 0x03, 0x72, 0x2e, 0x7b, - 0xfc, 0x37, 0x62, 0x6c, 0x71, 0x34, 0x82, 0x74, 0xab, 0x7f, 0xa7, 0x83, 0x19, 0xfc, 0x10, 0x2d, - 0xa6, 0x64, 0x79, 0x52, 0x24, 0xfa, 0x83, 0x44, 0xff, 0x6f, 0x46, 0xab, 0x23, 0xd3, 0xc7, 0xc6, - 0x74, 0x28, 0x85, 0x77, 0x50, 0x39, 0x85, 0x7b, 0x6e, 0xcc, 0xc8, 0x47, 0x49, 0x5d, 0x31, 0x53, - 0xf7, 0xdc, 0x98, 0x65, 0x7c, 0x94, 0x04, 0x35, 0x89, 0x8f, 0x26, 0x49, 0x9f, 0x46, 0x92, 0x78, - 0xeb, 0x21, 0x52, 0x12, 0xd4, 0x5b, 0x2f, 0x48, 0xdc, 0x91, 0xcf, 0x0b, 0xa3, 0xb6, 0x9e, 0xd7, - 0x0c, 0x3a, 0x52, 0xc5, 0xb4, 0x23, 0x05, 0x46, 0x39, 0xf2, 0x45, 0x61, 0x94, 0x23, 0x79, 0x95, - 0xc1, 0x91, 0x69, 0x38, 0x3b, 0x16, 0x77, 0xe4, 0xcb, 0x4b, 0xc7, 0x1a, 0x74, 0xa4, 0x8a, 0xe1, - 0x47, 0xa8, 0xd2, 0x87, 0x11, 0x46, 0x09, 0x21, 0xea, 0xb8, 0x71, 0xcc, 0xbf, 0xc3, 0xaf, 0x24, - 0xf3, 0xfa, 0x08, 0x26, 0x97, 0x1f, 0x68, 0x75, 0xc2, 0xff, 0x93, 0x9a, 0xf3, 0xb8, 0x83, 0x96, - 0xd2, 0x5e, 0xca, 0x3a, 0x7d, 0xcd, 0x5e, 0xcb, 0x66, 0x37, 0xcc, 0xcd, 0xa4, 0x4b, 0x86, 0xbb, - 0x11, 0x3a, 0x42, 0x50, 0xfb, 0x0d, 0xcd, 0x6e, 0x75, 0x42, 0xf6, 0xd4, 0x82, 0x38, 0x0c, 0xfc, - 0x18, 0x6a, 0x21, 0x5a, 0xba, 0xe4, 0x43, 0x84, 0x31, 0x9a, 0x10, 0x17, 0x77, 0x4e, 0x5c, 0xdc, - 0xe2, 0x99, 0x5f, 0xe8, 0xfa, 0x7c, 0xaa, 0x0b, 0x3d, 0x79, 0xc7, 0x2b, 0xa8, 0x14, 0xbb, 0x9d, - 0xd0, 0x03, 0x9b, 0x05, 0x27, 0xe0, 0x8b, 0x8b, 0xb8, 0x60, 0x15, 0x65, 0xec, 0x90, 0x87, 0xee, - 0x2d, 0x9c, 0x7d, 0xa9, 0x8e, 0x9d, 0x5d, 0x54, 0x73, 0xe7, 0x17, 0xd5, 0xdc, 0xe7, 0x8b, 0x6a, - 0xee, 0xd9, 0xd7, 0xea, 0xd8, 0xd1, 0x94, 0xf8, 0x37, 0xb1, 0xf1, 0x2b, 0x00, 0x00, 0xff, 0xff, - 0x54, 0x8c, 0x4a, 0x7f, 0xa5, 0x08, 0x00, 0x00, + // 837 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x7c, 0x96, 0xdd, 0x52, 0xd3, 0x40, + 0x14, 0xc7, 0x69, 0xf9, 0xec, 0xb6, 0x54, 0x5c, 0x40, 0xd7, 0x32, 0x53, 0xa1, 0x8c, 0x8a, 0x5f, + 0xe8, 0x94, 0x07, 0xd0, 0x4a, 0x19, 0x60, 0x86, 0x61, 0x98, 0x0c, 0xce, 0x38, 0xe3, 0x45, 0x5c, + 0x9a, 0x43, 0x1b, 0x49, 0x93, 0xb8, 0xd9, 0x56, 0x7c, 0x13, 0x1f, 0xc3, 0xaf, 0x87, 0xe0, 0xc2, + 0x0f, 0xd4, 0x17, 0x50, 0xbc, 0xf1, 0xca, 0x1b, 0x7d, 0x00, 0x67, 0x3f, 0x92, 0x34, 0x6d, 0xca, + 0x5d, 0x72, 0xce, 0xff, 0xfc, 0xce, 0xd9, 0xec, 0x7f, 0xbb, 0x45, 0xb3, 0x8c, 0x1e, 0x72, 0xd3, + 0x76, 0x39, 0x30, 0x97, 0x3a, 0xab, 0x3e, 0xf3, 0xb8, 0x87, 0x0b, 0xc0, 0x1b, 0x56, 0x00, 0xac, + 0x0b, 0xcc, 0x3f, 0x28, 0xcd, 0x35, 0xbd, 0xa6, 0x27, 0x13, 0xf7, 0xc4, 0x93, 0xd2, 0x94, 0x66, + 0x62, 0x8d, 0x8e, 0xe4, 0x98, 0xdf, 0x50, 0x8f, 0x95, 0x67, 0x68, 0xda, 0x80, 0x17, 0x1d, 0x08, + 0xf8, 0x16, 0x50, 0x0b, 0x18, 0x2e, 0xa2, 0xec, 0x76, 0x9d, 0x64, 0x16, 0x33, 0x2b, 0x63, 0x46, + 0x76, 0xbb, 0x8e, 0x4b, 0x68, 0xaa, 0x13, 0x88, 0x96, 0x6d, 0x20, 0xd9, 0xc5, 0xcc, 0x4a, 0xce, + 0x88, 0xde, 0xf1, 0x32, 0x9a, 0xa6, 0x1d, 0xde, 0x32, 0x19, 0x74, 0xed, 0xc0, 0xf6, 0x5c, 0x32, + 0x2a, 0xcb, 0x0a, 0x22, 0x68, 0xe8, 0x58, 0xe5, 0x4f, 0x11, 0xcd, 0x6e, 0xeb, 0xa9, 0x0d, 0x7a, + 0xc8, 0x75, 0xbb, 0x81, 0x46, 0xd7, 0x50, 0xb6, 0x5b, 0x95, 0x2d, 0xf2, 0xd5, 0xf9, 0xd5, 0xde, + 0x75, 0xad, 0xea, 0x12, 0x23, 0xdb, 0xad, 0xe2, 0xfb, 0x68, 0x9c, 0x51, 0xb7, 0x09, 0xb2, 0x57, + 0xbe, 0x5a, 0xea, 0x53, 0x8a, 0x54, 0x28, 0x57, 0x42, 0x7c, 0x0b, 0x8d, 0xfa, 0x1d, 0x4e, 0xc6, + 0xa4, 0x9e, 0x24, 0xf5, 0x7b, 0x9d, 0x70, 0x1e, 0x43, 0x88, 0xf0, 0x3a, 0x2a, 0x58, 0xe0, 0x00, + 0x07, 0x53, 0x35, 0x19, 0x97, 0x45, 0x8b, 0xc9, 0xa2, 0xba, 0x54, 0x24, 0x5a, 0xe5, 0xad, 0x38, + 0x26, 0x1a, 0xf2, 0x63, 0x97, 0x4c, 0xa4, 0x35, 0xdc, 0x3f, 0x76, 0xa3, 0x86, 0xfc, 0xd8, 0xc5, + 0x0f, 0x10, 0x6a, 0x78, 0x6d, 0x9f, 0x36, 0xb8, 0xf8, 0x7e, 0x93, 0xb2, 0xe4, 0x6a, 0xb2, 0x64, + 0x3d, 0xca, 0x87, 0x95, 0x3d, 0x25, 0xf8, 0x21, 0xca, 0x3b, 0x40, 0x03, 0x30, 0x9b, 0x8c, 0xba, + 0x9c, 0x4c, 0xa5, 0x11, 0x76, 0x84, 0x60, 0x53, 0xe4, 0x23, 0x82, 0x13, 0x85, 0xc4, 0x9a, 0x15, + 0x81, 0x41, 0xd7, 0x3b, 0x02, 0x92, 0x4b, 0x5b, 0xb3, 0x44, 0x18, 0x52, 0x10, 0xad, 0xd9, 0x89, + 0x63, 0x62, 0x5b, 0xa8, 0x43, 0x59, 0x9b, 0xa0, 0xb4, 0x6d, 0xa9, 0x89, 0x54, 0xb4, 0x2d, 0x52, + 0x88, 0xd7, 0xd0, 0x44, 0x4b, 0x5a, 0x8e, 0x58, 0xb2, 0x64, 0x21, 0x75, 0xcf, 0x95, 0x2b, 0x0d, + 0x2d, 0xc5, 0x35, 0x94, 0x97, 0x8e, 0x03, 0x97, 0x1e, 0x38, 0x40, 0x7e, 0xa7, 0x7e, 0xb0, 0x5a, + 0x87, 0xb7, 0x36, 0xa4, 0x20, 0x5a, 0x2e, 0x8d, 0x42, 0xb8, 0x8e, 0xa4, 0x3f, 0x4d, 0xcb, 0x0e, + 0x24, 0xe3, 0xef, 0x64, 0xda, 0x7a, 0x05, 0xa3, 0xae, 0x14, 0xd1, 0x7a, 0x69, 0x1c, 0xc3, 0xbb, + 0x8a, 0x02, 0x2e, 0xb7, 0x1b, 0x94, 0x03, 0xf9, 0xa7, 0x28, 0x37, 0x93, 0x94, 0xd0, 0xf7, 0xb5, + 0x1e, 0x69, 0x88, 0x4b, 0xd4, 0xe3, 0x0d, 0x7d, 0x94, 0xc4, 0xd9, 0x32, 0xa9, 0x65, 0x91, 0x8f, + 0x53, 0xc3, 0xc6, 0x7a, 0x1c, 0x00, 0xab, 0x59, 0x56, 0x62, 0x2c, 0x1d, 0xc3, 0xbb, 0x68, 0x26, + 0xc6, 0x28, 0x4f, 0x92, 0x4f, 0x8a, 0xb4, 0x9c, 0x4e, 0xd2, 0x66, 0xd6, 0xb0, 0x22, 0x4d, 0x84, + 0x93, 0x63, 0x35, 0x81, 0x93, 0xcf, 0xe7, 0x8e, 0xb5, 0x09, 0x7c, 0x60, 0xac, 0x4d, 0xe0, 0xb8, + 0x89, 0xae, 0xc4, 0x98, 0x46, 0x4b, 0x9c, 0x12, 0xd3, 0xa7, 0x41, 0xf0, 0xd2, 0x63, 0x16, 0xf9, + 0xa2, 0x90, 0xb7, 0xd3, 0x91, 0xeb, 0x52, 0xbd, 0xa7, 0xc5, 0x21, 0xfd, 0x12, 0x4d, 0x4d, 0xe3, + 0x27, 0x68, 0xae, 0x67, 0x5e, 0x61, 0x6f, 0x93, 0x79, 0x0e, 0x90, 0x53, 0xd5, 0xe3, 0xfa, 0x90, + 0xb1, 0xe5, 0xd1, 0xf0, 0xe2, 0xad, 0xbe, 0x48, 0xfb, 0x33, 0xf8, 0x29, 0x9a, 0x8f, 0xc9, 0xea, + 0xa4, 0x28, 0xf4, 0x57, 0x85, 0xbe, 0x91, 0x8e, 0xd6, 0x47, 0xa6, 0x87, 0x8d, 0xe9, 0x40, 0x0a, + 0x6f, 0xa1, 0x62, 0x0c, 0x77, 0xec, 0x80, 0x93, 0x6f, 0x8a, 0xba, 0x94, 0x4e, 0xdd, 0xb1, 0x03, + 0x9e, 0xf0, 0x51, 0x18, 0x8c, 0x48, 0x62, 0x34, 0x45, 0xfa, 0x3e, 0x94, 0x24, 0x5a, 0x0f, 0x90, + 0xc2, 0x60, 0xb4, 0xf5, 0x92, 0x24, 0x1c, 0xf9, 0x26, 0x37, 0x6c, 0xeb, 0x45, 0x4d, 0xbf, 0x23, + 0x75, 0x2c, 0x72, 0xa4, 0xc4, 0x68, 0x47, 0xbe, 0xcd, 0x0d, 0x73, 0xa4, 0xa8, 0x4a, 0x71, 0x64, + 0x1c, 0x4e, 0x8e, 0x25, 0x1c, 0xf9, 0xee, 0xdc, 0xb1, 0xfa, 0x1d, 0xa9, 0x63, 0xf8, 0x39, 0x2a, + 0xf5, 0x60, 0xa4, 0x51, 0x7c, 0x60, 0x6d, 0x3b, 0x90, 0xf7, 0xd8, 0x7b, 0xc5, 0xbc, 0x33, 0x84, + 0x29, 0xe4, 0x7b, 0x91, 0x3a, 0xe4, 0x5f, 0xa6, 0xe9, 0x79, 0xdc, 0x46, 0x0b, 0x71, 0x2f, 0x6d, + 0x9d, 0x9e, 0x66, 0x1f, 0x54, 0xb3, 0xbb, 0xe9, 0xcd, 0x94, 0x4b, 0x06, 0xbb, 0x11, 0x3a, 0x44, + 0x50, 0xb9, 0x80, 0xa6, 0x37, 0xda, 0x3e, 0x7f, 0x65, 0x40, 0xe0, 0x7b, 0x6e, 0x00, 0x15, 0x1f, + 0x2d, 0x9c, 0xf3, 0x43, 0x84, 0x31, 0x1a, 0x93, 0xb7, 0x7b, 0x46, 0xde, 0xee, 0xf2, 0x59, 0xdc, + 0xfa, 0xd1, 0xf9, 0xd4, 0xb7, 0x7e, 0xf8, 0x8e, 0x97, 0x50, 0x21, 0xb0, 0xdb, 0xbe, 0x03, 0x26, + 0xf7, 0x8e, 0x40, 0x5d, 0xfa, 0x39, 0x23, 0xaf, 0x62, 0xfb, 0x22, 0xf4, 0x68, 0xee, 0xe4, 0x67, + 0x79, 0xe4, 0xe4, 0xac, 0x9c, 0x39, 0x3d, 0x2b, 0x67, 0x7e, 0x9c, 0x95, 0x33, 0xaf, 0x7f, 0x95, + 0x47, 0x0e, 0x26, 0xe4, 0x5f, 0x8e, 0xb5, 0xff, 0x01, 0x00, 0x00, 0xff, 0xff, 0xff, 0xc9, 0xfc, + 0x0e, 0xca, 0x08, 0x00, 0x00, } diff --git a/vendor/github.com/coreos/etcd/etcdserver/etcdserverpb/raft_internal.proto b/vendor/github.com/coreos/etcd/etcdserver/etcdserverpb/raft_internal.proto index 3ad0d1b37..25d45d3c4 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/etcdserverpb/raft_internal.proto +++ b/vendor/github.com/coreos/etcd/etcdserver/etcdserverpb/raft_internal.proto @@ -14,6 +14,8 @@ message RequestHeader { uint64 ID = 1; // username is a username that is associated with an auth token of gRPC connection string username = 2; + // auth_revision is a revision number of auth.authStore. It is not related to mvcc + uint64 auth_revision = 3; } // An InternalRaftRequest is the union of all requests which can be 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 1bc62c2eb..b28f2e50e 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/etcdserverpb/rpc.pb.go +++ b/vendor/github.com/coreos/etcd/etcdserver/etcdserverpb/rpc.pb.go @@ -105,20 +105,23 @@ func (RangeRequest_SortTarget) EnumDescriptor() ([]byte, []int) { return fileDes type Compare_CompareResult int32 const ( - Compare_EQUAL Compare_CompareResult = 0 - Compare_GREATER Compare_CompareResult = 1 - Compare_LESS Compare_CompareResult = 2 + Compare_EQUAL Compare_CompareResult = 0 + Compare_GREATER Compare_CompareResult = 1 + Compare_LESS Compare_CompareResult = 2 + Compare_NOT_EQUAL Compare_CompareResult = 3 ) var Compare_CompareResult_name = map[int32]string{ 0: "EQUAL", 1: "GREATER", 2: "LESS", + 3: "NOT_EQUAL", } var Compare_CompareResult_value = map[string]int32{ - "EQUAL": 0, - "GREATER": 1, - "LESS": 2, + "EQUAL": 0, + "GREATER": 1, + "LESS": 2, + "NOT_EQUAL": 3, } func (x Compare_CompareResult) String() string { @@ -153,6 +156,31 @@ func (x Compare_CompareTarget) String() string { } func (Compare_CompareTarget) EnumDescriptor() ([]byte, []int) { return fileDescriptorRpc, []int{9, 1} } +type WatchCreateRequest_FilterType int32 + +const ( + // filter out put event. + WatchCreateRequest_NOPUT WatchCreateRequest_FilterType = 0 + // filter out delete event. + WatchCreateRequest_NODELETE WatchCreateRequest_FilterType = 1 +) + +var WatchCreateRequest_FilterType_name = map[int32]string{ + 0: "NOPUT", + 1: "NODELETE", +} +var WatchCreateRequest_FilterType_value = map[string]int32{ + "NOPUT": 0, + "NODELETE": 1, +} + +func (x WatchCreateRequest_FilterType) String() string { + return proto.EnumName(WatchCreateRequest_FilterType_name, int32(x)) +} +func (WatchCreateRequest_FilterType) EnumDescriptor() ([]byte, []int) { + return fileDescriptorRpc, []int{19, 0} +} + type AlarmRequest_AlarmAction int32 const ( @@ -176,7 +204,7 @@ func (x AlarmRequest_AlarmAction) String() string { return proto.EnumName(AlarmRequest_AlarmAction_name, int32(x)) } func (AlarmRequest_AlarmAction) EnumDescriptor() ([]byte, []int) { - return fileDescriptorRpc, []int{39, 0} + return fileDescriptorRpc, []int{41, 0} } type ResponseHeader struct { @@ -225,6 +253,18 @@ type RangeRequest struct { KeysOnly bool `protobuf:"varint,8,opt,name=keys_only,json=keysOnly,proto3" json:"keys_only,omitempty"` // count_only when set returns only the count of the keys in the range. CountOnly bool `protobuf:"varint,9,opt,name=count_only,json=countOnly,proto3" json:"count_only,omitempty"` + // min_mod_revision is the lower bound for returned key mod revisions; all keys with + // lesser mod revisions will be filtered away. + MinModRevision int64 `protobuf:"varint,10,opt,name=min_mod_revision,json=minModRevision,proto3" json:"min_mod_revision,omitempty"` + // max_mod_revision is the upper bound for returned key mod revisions; all keys with + // greater mod revisions will be filtered away. + MaxModRevision int64 `protobuf:"varint,11,opt,name=max_mod_revision,json=maxModRevision,proto3" json:"max_mod_revision,omitempty"` + // min_create_revision is the lower bound for returned key create revisions; all keys with + // lesser create trevisions will be filtered away. + MinCreateRevision int64 `protobuf:"varint,12,opt,name=min_create_revision,json=minCreateRevision,proto3" json:"min_create_revision,omitempty"` + // max_create_revision is the upper bound for returned key create revisions; all keys with + // greater create revisions will be filtered away. + MaxCreateRevision int64 `protobuf:"varint,13,opt,name=max_create_revision,json=maxCreateRevision,proto3" json:"max_create_revision,omitempty"` } func (m *RangeRequest) Reset() { *m = RangeRequest{} } @@ -310,6 +350,8 @@ type DeleteRangeRequest struct { Key []byte `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` // range_end is the key following the last key to delete for the range [key, range_end). // If range_end is not given, the range is defined to contain only the key argument. + // If range_end is one bit larger than the given key, then the range is all + // the all keys with the prefix (the given key). // 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. @@ -1134,6 +1176,8 @@ type WatchCreateRequest struct { // range_end is the end of the range [key, range_end) to watch. If range_end is not given, // only the key argument is watched. If range_end is equal to '\0', all keys greater than // or equal to the key argument are watched. + // If the range_end is one bit larger than the given key, + // then all keys with the prefix (the given key) will be watched. RangeEnd []byte `protobuf:"bytes,2,opt,name=range_end,json=rangeEnd,proto3" json:"range_end,omitempty"` // start_revision is an optional revision to watch from (inclusive). No start_revision is "now". StartRevision int64 `protobuf:"varint,3,opt,name=start_revision,json=startRevision,proto3" json:"start_revision,omitempty"` @@ -1142,6 +1186,8 @@ 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"` + // filters filter the events at server side before it sends back to the watcher. + Filters []WatchCreateRequest_FilterType `protobuf:"varint,5,rep,packed,name=filters,enum=etcdserverpb.WatchCreateRequest_FilterType" json:"filters,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"` @@ -1207,9 +1253,9 @@ func (m *WatchResponse) GetEvents() []*mvccpb.Event { type LeaseGrantRequest struct { // TTL is the advisory time-to-live in seconds. - TTL int64 `protobuf:"varint,1,opt,name=TTL,json=tTL,proto3" json:"TTL,omitempty"` + TTL int64 `protobuf:"varint,1,opt,name=TTL,proto3" json:"TTL,omitempty"` // ID is the requested ID for the lease. If ID is set to 0, the lessor chooses an ID. - ID int64 `protobuf:"varint,2,opt,name=ID,json=iD,proto3" json:"ID,omitempty"` + ID int64 `protobuf:"varint,2,opt,name=ID,proto3" json:"ID,omitempty"` } func (m *LeaseGrantRequest) Reset() { *m = LeaseGrantRequest{} } @@ -1220,9 +1266,9 @@ func (*LeaseGrantRequest) Descriptor() ([]byte, []int) { return fileDescriptorRp type LeaseGrantResponse struct { Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"` // ID is the lease ID for the granted lease. - ID int64 `protobuf:"varint,2,opt,name=ID,json=iD,proto3" json:"ID,omitempty"` + ID int64 `protobuf:"varint,2,opt,name=ID,proto3" json:"ID,omitempty"` // TTL is the server chosen lease time-to-live in seconds. - TTL int64 `protobuf:"varint,3,opt,name=TTL,json=tTL,proto3" json:"TTL,omitempty"` + TTL int64 `protobuf:"varint,3,opt,name=TTL,proto3" json:"TTL,omitempty"` Error string `protobuf:"bytes,4,opt,name=error,proto3" json:"error,omitempty"` } @@ -1240,7 +1286,7 @@ func (m *LeaseGrantResponse) GetHeader() *ResponseHeader { type LeaseRevokeRequest struct { // ID is the lease ID to revoke. When the ID is revoked, all associated keys will be deleted. - ID int64 `protobuf:"varint,1,opt,name=ID,json=iD,proto3" json:"ID,omitempty"` + ID int64 `protobuf:"varint,1,opt,name=ID,proto3" json:"ID,omitempty"` } func (m *LeaseRevokeRequest) Reset() { *m = LeaseRevokeRequest{} } @@ -1266,7 +1312,7 @@ func (m *LeaseRevokeResponse) GetHeader() *ResponseHeader { type LeaseKeepAliveRequest struct { // ID is the lease ID for the lease to keep alive. - ID int64 `protobuf:"varint,1,opt,name=ID,json=iD,proto3" json:"ID,omitempty"` + ID int64 `protobuf:"varint,1,opt,name=ID,proto3" json:"ID,omitempty"` } func (m *LeaseKeepAliveRequest) Reset() { *m = LeaseKeepAliveRequest{} } @@ -1277,9 +1323,9 @@ func (*LeaseKeepAliveRequest) Descriptor() ([]byte, []int) { return fileDescript type LeaseKeepAliveResponse struct { Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"` // ID is the lease ID from the keep alive request. - ID int64 `protobuf:"varint,2,opt,name=ID,json=iD,proto3" json:"ID,omitempty"` + ID int64 `protobuf:"varint,2,opt,name=ID,proto3" json:"ID,omitempty"` // TTL is the new time-to-live for the lease. - TTL int64 `protobuf:"varint,3,opt,name=TTL,json=tTL,proto3" json:"TTL,omitempty"` + TTL int64 `protobuf:"varint,3,opt,name=TTL,proto3" json:"TTL,omitempty"` } func (m *LeaseKeepAliveResponse) Reset() { *m = LeaseKeepAliveResponse{} } @@ -1294,9 +1340,45 @@ func (m *LeaseKeepAliveResponse) GetHeader() *ResponseHeader { return nil } +type LeaseTimeToLiveRequest struct { + // ID is the lease ID for the lease. + ID int64 `protobuf:"varint,1,opt,name=ID,proto3" json:"ID,omitempty"` + // keys is true to query all the keys attached to this lease. + Keys bool `protobuf:"varint,2,opt,name=keys,proto3" json:"keys,omitempty"` +} + +func (m *LeaseTimeToLiveRequest) Reset() { *m = LeaseTimeToLiveRequest{} } +func (m *LeaseTimeToLiveRequest) String() string { return proto.CompactTextString(m) } +func (*LeaseTimeToLiveRequest) ProtoMessage() {} +func (*LeaseTimeToLiveRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{28} } + +type LeaseTimeToLiveResponse struct { + Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"` + // ID is the lease ID from the keep alive request. + ID int64 `protobuf:"varint,2,opt,name=ID,proto3" json:"ID,omitempty"` + // TTL is the remaining TTL in seconds for the lease; the lease will expire in under TTL+1 seconds. + TTL int64 `protobuf:"varint,3,opt,name=TTL,proto3" json:"TTL,omitempty"` + // GrantedTTL is the initial granted time in seconds upon lease creation/renewal. + GrantedTTL int64 `protobuf:"varint,4,opt,name=grantedTTL,proto3" json:"grantedTTL,omitempty"` + // Keys is the list of keys attached to this lease. + Keys [][]byte `protobuf:"bytes,5,rep,name=keys" json:"keys,omitempty"` +} + +func (m *LeaseTimeToLiveResponse) Reset() { *m = LeaseTimeToLiveResponse{} } +func (m *LeaseTimeToLiveResponse) String() string { return proto.CompactTextString(m) } +func (*LeaseTimeToLiveResponse) ProtoMessage() {} +func (*LeaseTimeToLiveResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{29} } + +func (m *LeaseTimeToLiveResponse) GetHeader() *ResponseHeader { + if m != nil { + return m.Header + } + return nil +} + type Member struct { // ID is the member ID for this member. - ID uint64 `protobuf:"varint,1,opt,name=ID,json=iD,proto3" json:"ID,omitempty"` + ID uint64 `protobuf:"varint,1,opt,name=ID,proto3" json:"ID,omitempty"` // name is the human-readable name of the member. If the member is not started, the name will be an empty string. Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` // peerURLs is the list of URLs the member exposes to the cluster for communication. @@ -1308,7 +1390,7 @@ type Member struct { func (m *Member) Reset() { *m = Member{} } func (m *Member) String() string { return proto.CompactTextString(m) } func (*Member) ProtoMessage() {} -func (*Member) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{28} } +func (*Member) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{30} } type MemberAddRequest struct { // peerURLs is the list of URLs the added member will use to communicate with the cluster. @@ -1318,7 +1400,7 @@ type MemberAddRequest struct { func (m *MemberAddRequest) Reset() { *m = MemberAddRequest{} } func (m *MemberAddRequest) String() string { return proto.CompactTextString(m) } func (*MemberAddRequest) ProtoMessage() {} -func (*MemberAddRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{29} } +func (*MemberAddRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{31} } type MemberAddResponse struct { Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"` @@ -1329,7 +1411,7 @@ type MemberAddResponse struct { func (m *MemberAddResponse) Reset() { *m = MemberAddResponse{} } func (m *MemberAddResponse) String() string { return proto.CompactTextString(m) } func (*MemberAddResponse) ProtoMessage() {} -func (*MemberAddResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{30} } +func (*MemberAddResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{32} } func (m *MemberAddResponse) GetHeader() *ResponseHeader { if m != nil { @@ -1347,13 +1429,13 @@ func (m *MemberAddResponse) GetMember() *Member { type MemberRemoveRequest struct { // ID is the member ID of the member to remove. - ID uint64 `protobuf:"varint,1,opt,name=ID,json=iD,proto3" json:"ID,omitempty"` + ID uint64 `protobuf:"varint,1,opt,name=ID,proto3" json:"ID,omitempty"` } func (m *MemberRemoveRequest) Reset() { *m = MemberRemoveRequest{} } func (m *MemberRemoveRequest) String() string { return proto.CompactTextString(m) } func (*MemberRemoveRequest) ProtoMessage() {} -func (*MemberRemoveRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{31} } +func (*MemberRemoveRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{33} } type MemberRemoveResponse struct { Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"` @@ -1362,7 +1444,7 @@ type MemberRemoveResponse struct { func (m *MemberRemoveResponse) Reset() { *m = MemberRemoveResponse{} } func (m *MemberRemoveResponse) String() string { return proto.CompactTextString(m) } func (*MemberRemoveResponse) ProtoMessage() {} -func (*MemberRemoveResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{32} } +func (*MemberRemoveResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{34} } func (m *MemberRemoveResponse) GetHeader() *ResponseHeader { if m != nil { @@ -1373,7 +1455,7 @@ func (m *MemberRemoveResponse) GetHeader() *ResponseHeader { type MemberUpdateRequest struct { // ID is the member ID of the member to update. - ID uint64 `protobuf:"varint,1,opt,name=ID,json=iD,proto3" json:"ID,omitempty"` + ID uint64 `protobuf:"varint,1,opt,name=ID,proto3" json:"ID,omitempty"` // peerURLs is the new list of URLs the member will use to communicate with the cluster. PeerURLs []string `protobuf:"bytes,2,rep,name=peerURLs" json:"peerURLs,omitempty"` } @@ -1381,7 +1463,7 @@ type MemberUpdateRequest struct { func (m *MemberUpdateRequest) Reset() { *m = MemberUpdateRequest{} } func (m *MemberUpdateRequest) String() string { return proto.CompactTextString(m) } func (*MemberUpdateRequest) ProtoMessage() {} -func (*MemberUpdateRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{33} } +func (*MemberUpdateRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{35} } type MemberUpdateResponse struct { Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"` @@ -1390,7 +1472,7 @@ type MemberUpdateResponse struct { func (m *MemberUpdateResponse) Reset() { *m = MemberUpdateResponse{} } func (m *MemberUpdateResponse) String() string { return proto.CompactTextString(m) } func (*MemberUpdateResponse) ProtoMessage() {} -func (*MemberUpdateResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{34} } +func (*MemberUpdateResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{36} } func (m *MemberUpdateResponse) GetHeader() *ResponseHeader { if m != nil { @@ -1405,7 +1487,7 @@ type MemberListRequest struct { func (m *MemberListRequest) Reset() { *m = MemberListRequest{} } func (m *MemberListRequest) String() string { return proto.CompactTextString(m) } func (*MemberListRequest) ProtoMessage() {} -func (*MemberListRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{35} } +func (*MemberListRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{37} } type MemberListResponse struct { Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"` @@ -1416,7 +1498,7 @@ type MemberListResponse struct { func (m *MemberListResponse) Reset() { *m = MemberListResponse{} } func (m *MemberListResponse) String() string { return proto.CompactTextString(m) } func (*MemberListResponse) ProtoMessage() {} -func (*MemberListResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{36} } +func (*MemberListResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{38} } func (m *MemberListResponse) GetHeader() *ResponseHeader { if m != nil { @@ -1438,7 +1520,7 @@ type DefragmentRequest struct { func (m *DefragmentRequest) Reset() { *m = DefragmentRequest{} } func (m *DefragmentRequest) String() string { return proto.CompactTextString(m) } func (*DefragmentRequest) ProtoMessage() {} -func (*DefragmentRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{37} } +func (*DefragmentRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{39} } type DefragmentResponse struct { Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"` @@ -1447,7 +1529,7 @@ type DefragmentResponse struct { func (m *DefragmentResponse) Reset() { *m = DefragmentResponse{} } func (m *DefragmentResponse) String() string { return proto.CompactTextString(m) } func (*DefragmentResponse) ProtoMessage() {} -func (*DefragmentResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{38} } +func (*DefragmentResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{40} } func (m *DefragmentResponse) GetHeader() *ResponseHeader { if m != nil { @@ -1471,7 +1553,7 @@ type AlarmRequest struct { func (m *AlarmRequest) Reset() { *m = AlarmRequest{} } func (m *AlarmRequest) String() string { return proto.CompactTextString(m) } func (*AlarmRequest) ProtoMessage() {} -func (*AlarmRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{39} } +func (*AlarmRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{41} } type AlarmMember struct { // memberID is the ID of the member associated with the raised alarm. @@ -1483,7 +1565,7 @@ type AlarmMember struct { func (m *AlarmMember) Reset() { *m = AlarmMember{} } func (m *AlarmMember) String() string { return proto.CompactTextString(m) } func (*AlarmMember) ProtoMessage() {} -func (*AlarmMember) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{40} } +func (*AlarmMember) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{42} } type AlarmResponse struct { Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"` @@ -1494,7 +1576,7 @@ type AlarmResponse struct { func (m *AlarmResponse) Reset() { *m = AlarmResponse{} } func (m *AlarmResponse) String() string { return proto.CompactTextString(m) } func (*AlarmResponse) ProtoMessage() {} -func (*AlarmResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{41} } +func (*AlarmResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{43} } func (m *AlarmResponse) GetHeader() *ResponseHeader { if m != nil { @@ -1516,7 +1598,7 @@ type StatusRequest struct { func (m *StatusRequest) Reset() { *m = StatusRequest{} } func (m *StatusRequest) String() string { return proto.CompactTextString(m) } func (*StatusRequest) ProtoMessage() {} -func (*StatusRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{42} } +func (*StatusRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{44} } type StatusResponse struct { Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"` @@ -1535,7 +1617,7 @@ type StatusResponse struct { func (m *StatusResponse) Reset() { *m = StatusResponse{} } func (m *StatusResponse) String() string { return proto.CompactTextString(m) } func (*StatusResponse) ProtoMessage() {} -func (*StatusResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{43} } +func (*StatusResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{45} } func (m *StatusResponse) GetHeader() *ResponseHeader { if m != nil { @@ -1550,7 +1632,7 @@ type AuthEnableRequest struct { func (m *AuthEnableRequest) Reset() { *m = AuthEnableRequest{} } func (m *AuthEnableRequest) String() string { return proto.CompactTextString(m) } func (*AuthEnableRequest) ProtoMessage() {} -func (*AuthEnableRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{44} } +func (*AuthEnableRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{46} } type AuthDisableRequest struct { } @@ -1558,7 +1640,7 @@ type AuthDisableRequest struct { func (m *AuthDisableRequest) Reset() { *m = AuthDisableRequest{} } func (m *AuthDisableRequest) String() string { return proto.CompactTextString(m) } func (*AuthDisableRequest) ProtoMessage() {} -func (*AuthDisableRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{45} } +func (*AuthDisableRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{47} } type AuthenticateRequest struct { Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` @@ -1568,7 +1650,7 @@ type AuthenticateRequest struct { func (m *AuthenticateRequest) Reset() { *m = AuthenticateRequest{} } func (m *AuthenticateRequest) String() string { return proto.CompactTextString(m) } func (*AuthenticateRequest) ProtoMessage() {} -func (*AuthenticateRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{46} } +func (*AuthenticateRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{48} } type AuthUserAddRequest struct { Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` @@ -1578,7 +1660,7 @@ type AuthUserAddRequest struct { func (m *AuthUserAddRequest) Reset() { *m = AuthUserAddRequest{} } func (m *AuthUserAddRequest) String() string { return proto.CompactTextString(m) } func (*AuthUserAddRequest) ProtoMessage() {} -func (*AuthUserAddRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{47} } +func (*AuthUserAddRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{49} } type AuthUserGetRequest struct { Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` @@ -1587,7 +1669,7 @@ type AuthUserGetRequest struct { func (m *AuthUserGetRequest) Reset() { *m = AuthUserGetRequest{} } func (m *AuthUserGetRequest) String() string { return proto.CompactTextString(m) } func (*AuthUserGetRequest) ProtoMessage() {} -func (*AuthUserGetRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{48} } +func (*AuthUserGetRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{50} } type AuthUserDeleteRequest struct { // name is the name of the user to delete. @@ -1597,7 +1679,7 @@ type AuthUserDeleteRequest struct { func (m *AuthUserDeleteRequest) Reset() { *m = AuthUserDeleteRequest{} } func (m *AuthUserDeleteRequest) String() string { return proto.CompactTextString(m) } func (*AuthUserDeleteRequest) ProtoMessage() {} -func (*AuthUserDeleteRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{49} } +func (*AuthUserDeleteRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{51} } type AuthUserChangePasswordRequest struct { // name is the name of the user whose password is being changed. @@ -1610,7 +1692,7 @@ func (m *AuthUserChangePasswordRequest) Reset() { *m = AuthUserChangePas func (m *AuthUserChangePasswordRequest) String() string { return proto.CompactTextString(m) } func (*AuthUserChangePasswordRequest) ProtoMessage() {} func (*AuthUserChangePasswordRequest) Descriptor() ([]byte, []int) { - return fileDescriptorRpc, []int{50} + return fileDescriptorRpc, []int{52} } type AuthUserGrantRoleRequest struct { @@ -1623,7 +1705,7 @@ type AuthUserGrantRoleRequest struct { func (m *AuthUserGrantRoleRequest) Reset() { *m = AuthUserGrantRoleRequest{} } func (m *AuthUserGrantRoleRequest) String() string { return proto.CompactTextString(m) } func (*AuthUserGrantRoleRequest) ProtoMessage() {} -func (*AuthUserGrantRoleRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{51} } +func (*AuthUserGrantRoleRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{53} } type AuthUserRevokeRoleRequest struct { Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` @@ -1633,7 +1715,7 @@ type AuthUserRevokeRoleRequest struct { func (m *AuthUserRevokeRoleRequest) Reset() { *m = AuthUserRevokeRoleRequest{} } func (m *AuthUserRevokeRoleRequest) String() string { return proto.CompactTextString(m) } func (*AuthUserRevokeRoleRequest) ProtoMessage() {} -func (*AuthUserRevokeRoleRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{52} } +func (*AuthUserRevokeRoleRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{54} } type AuthRoleAddRequest struct { // name is the name of the role to add to the authentication system. @@ -1643,7 +1725,7 @@ type AuthRoleAddRequest struct { func (m *AuthRoleAddRequest) Reset() { *m = AuthRoleAddRequest{} } func (m *AuthRoleAddRequest) String() string { return proto.CompactTextString(m) } func (*AuthRoleAddRequest) ProtoMessage() {} -func (*AuthRoleAddRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{53} } +func (*AuthRoleAddRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{55} } type AuthRoleGetRequest struct { Role string `protobuf:"bytes,1,opt,name=role,proto3" json:"role,omitempty"` @@ -1652,7 +1734,7 @@ type AuthRoleGetRequest struct { func (m *AuthRoleGetRequest) Reset() { *m = AuthRoleGetRequest{} } func (m *AuthRoleGetRequest) String() string { return proto.CompactTextString(m) } func (*AuthRoleGetRequest) ProtoMessage() {} -func (*AuthRoleGetRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{54} } +func (*AuthRoleGetRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{56} } type AuthUserListRequest struct { } @@ -1660,7 +1742,7 @@ type AuthUserListRequest struct { func (m *AuthUserListRequest) Reset() { *m = AuthUserListRequest{} } func (m *AuthUserListRequest) String() string { return proto.CompactTextString(m) } func (*AuthUserListRequest) ProtoMessage() {} -func (*AuthUserListRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{55} } +func (*AuthUserListRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{57} } type AuthRoleListRequest struct { } @@ -1668,7 +1750,7 @@ type AuthRoleListRequest struct { func (m *AuthRoleListRequest) Reset() { *m = AuthRoleListRequest{} } func (m *AuthRoleListRequest) String() string { return proto.CompactTextString(m) } func (*AuthRoleListRequest) ProtoMessage() {} -func (*AuthRoleListRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{56} } +func (*AuthRoleListRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{58} } type AuthRoleDeleteRequest struct { Role string `protobuf:"bytes,1,opt,name=role,proto3" json:"role,omitempty"` @@ -1677,7 +1759,7 @@ type AuthRoleDeleteRequest struct { func (m *AuthRoleDeleteRequest) Reset() { *m = AuthRoleDeleteRequest{} } func (m *AuthRoleDeleteRequest) String() string { return proto.CompactTextString(m) } func (*AuthRoleDeleteRequest) ProtoMessage() {} -func (*AuthRoleDeleteRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{57} } +func (*AuthRoleDeleteRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{59} } type AuthRoleGrantPermissionRequest struct { // name is the name of the role which will be granted the permission. @@ -1690,7 +1772,7 @@ func (m *AuthRoleGrantPermissionRequest) Reset() { *m = AuthRoleGrantPer func (m *AuthRoleGrantPermissionRequest) String() string { return proto.CompactTextString(m) } func (*AuthRoleGrantPermissionRequest) ProtoMessage() {} func (*AuthRoleGrantPermissionRequest) Descriptor() ([]byte, []int) { - return fileDescriptorRpc, []int{58} + return fileDescriptorRpc, []int{60} } func (m *AuthRoleGrantPermissionRequest) GetPerm() *authpb.Permission { @@ -1710,7 +1792,7 @@ func (m *AuthRoleRevokePermissionRequest) Reset() { *m = AuthRoleRevokeP func (m *AuthRoleRevokePermissionRequest) String() string { return proto.CompactTextString(m) } func (*AuthRoleRevokePermissionRequest) ProtoMessage() {} func (*AuthRoleRevokePermissionRequest) Descriptor() ([]byte, []int) { - return fileDescriptorRpc, []int{59} + return fileDescriptorRpc, []int{61} } type AuthEnableResponse struct { @@ -1720,7 +1802,7 @@ type AuthEnableResponse struct { func (m *AuthEnableResponse) Reset() { *m = AuthEnableResponse{} } func (m *AuthEnableResponse) String() string { return proto.CompactTextString(m) } func (*AuthEnableResponse) ProtoMessage() {} -func (*AuthEnableResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{60} } +func (*AuthEnableResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{62} } func (m *AuthEnableResponse) GetHeader() *ResponseHeader { if m != nil { @@ -1736,7 +1818,7 @@ type AuthDisableResponse struct { func (m *AuthDisableResponse) Reset() { *m = AuthDisableResponse{} } func (m *AuthDisableResponse) String() string { return proto.CompactTextString(m) } func (*AuthDisableResponse) ProtoMessage() {} -func (*AuthDisableResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{61} } +func (*AuthDisableResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{63} } func (m *AuthDisableResponse) GetHeader() *ResponseHeader { if m != nil { @@ -1754,7 +1836,7 @@ type AuthenticateResponse struct { func (m *AuthenticateResponse) Reset() { *m = AuthenticateResponse{} } func (m *AuthenticateResponse) String() string { return proto.CompactTextString(m) } func (*AuthenticateResponse) ProtoMessage() {} -func (*AuthenticateResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{62} } +func (*AuthenticateResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{64} } func (m *AuthenticateResponse) GetHeader() *ResponseHeader { if m != nil { @@ -1770,7 +1852,7 @@ type AuthUserAddResponse struct { func (m *AuthUserAddResponse) Reset() { *m = AuthUserAddResponse{} } func (m *AuthUserAddResponse) String() string { return proto.CompactTextString(m) } func (*AuthUserAddResponse) ProtoMessage() {} -func (*AuthUserAddResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{63} } +func (*AuthUserAddResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{65} } func (m *AuthUserAddResponse) GetHeader() *ResponseHeader { if m != nil { @@ -1787,7 +1869,7 @@ type AuthUserGetResponse struct { func (m *AuthUserGetResponse) Reset() { *m = AuthUserGetResponse{} } func (m *AuthUserGetResponse) String() string { return proto.CompactTextString(m) } func (*AuthUserGetResponse) ProtoMessage() {} -func (*AuthUserGetResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{64} } +func (*AuthUserGetResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{66} } func (m *AuthUserGetResponse) GetHeader() *ResponseHeader { if m != nil { @@ -1803,7 +1885,7 @@ type AuthUserDeleteResponse struct { func (m *AuthUserDeleteResponse) Reset() { *m = AuthUserDeleteResponse{} } func (m *AuthUserDeleteResponse) String() string { return proto.CompactTextString(m) } func (*AuthUserDeleteResponse) ProtoMessage() {} -func (*AuthUserDeleteResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{65} } +func (*AuthUserDeleteResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{67} } func (m *AuthUserDeleteResponse) GetHeader() *ResponseHeader { if m != nil { @@ -1820,7 +1902,7 @@ func (m *AuthUserChangePasswordResponse) Reset() { *m = AuthUserChangePa func (m *AuthUserChangePasswordResponse) String() string { return proto.CompactTextString(m) } func (*AuthUserChangePasswordResponse) ProtoMessage() {} func (*AuthUserChangePasswordResponse) Descriptor() ([]byte, []int) { - return fileDescriptorRpc, []int{66} + return fileDescriptorRpc, []int{68} } func (m *AuthUserChangePasswordResponse) GetHeader() *ResponseHeader { @@ -1837,7 +1919,7 @@ type AuthUserGrantRoleResponse struct { func (m *AuthUserGrantRoleResponse) Reset() { *m = AuthUserGrantRoleResponse{} } func (m *AuthUserGrantRoleResponse) String() string { return proto.CompactTextString(m) } func (*AuthUserGrantRoleResponse) ProtoMessage() {} -func (*AuthUserGrantRoleResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{67} } +func (*AuthUserGrantRoleResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{69} } func (m *AuthUserGrantRoleResponse) GetHeader() *ResponseHeader { if m != nil { @@ -1853,7 +1935,7 @@ type AuthUserRevokeRoleResponse struct { func (m *AuthUserRevokeRoleResponse) Reset() { *m = AuthUserRevokeRoleResponse{} } func (m *AuthUserRevokeRoleResponse) String() string { return proto.CompactTextString(m) } func (*AuthUserRevokeRoleResponse) ProtoMessage() {} -func (*AuthUserRevokeRoleResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{68} } +func (*AuthUserRevokeRoleResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{70} } func (m *AuthUserRevokeRoleResponse) GetHeader() *ResponseHeader { if m != nil { @@ -1869,7 +1951,7 @@ type AuthRoleAddResponse struct { func (m *AuthRoleAddResponse) Reset() { *m = AuthRoleAddResponse{} } func (m *AuthRoleAddResponse) String() string { return proto.CompactTextString(m) } func (*AuthRoleAddResponse) ProtoMessage() {} -func (*AuthRoleAddResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{69} } +func (*AuthRoleAddResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{71} } func (m *AuthRoleAddResponse) GetHeader() *ResponseHeader { if m != nil { @@ -1886,7 +1968,7 @@ type AuthRoleGetResponse struct { func (m *AuthRoleGetResponse) Reset() { *m = AuthRoleGetResponse{} } func (m *AuthRoleGetResponse) String() string { return proto.CompactTextString(m) } func (*AuthRoleGetResponse) ProtoMessage() {} -func (*AuthRoleGetResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{70} } +func (*AuthRoleGetResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{72} } func (m *AuthRoleGetResponse) GetHeader() *ResponseHeader { if m != nil { @@ -1910,7 +1992,7 @@ type AuthRoleListResponse struct { func (m *AuthRoleListResponse) Reset() { *m = AuthRoleListResponse{} } func (m *AuthRoleListResponse) String() string { return proto.CompactTextString(m) } func (*AuthRoleListResponse) ProtoMessage() {} -func (*AuthRoleListResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{71} } +func (*AuthRoleListResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{73} } func (m *AuthRoleListResponse) GetHeader() *ResponseHeader { if m != nil { @@ -1927,7 +2009,7 @@ type AuthUserListResponse struct { func (m *AuthUserListResponse) Reset() { *m = AuthUserListResponse{} } func (m *AuthUserListResponse) String() string { return proto.CompactTextString(m) } func (*AuthUserListResponse) ProtoMessage() {} -func (*AuthUserListResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{72} } +func (*AuthUserListResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{74} } func (m *AuthUserListResponse) GetHeader() *ResponseHeader { if m != nil { @@ -1943,7 +2025,7 @@ type AuthRoleDeleteResponse struct { func (m *AuthRoleDeleteResponse) Reset() { *m = AuthRoleDeleteResponse{} } func (m *AuthRoleDeleteResponse) String() string { return proto.CompactTextString(m) } func (*AuthRoleDeleteResponse) ProtoMessage() {} -func (*AuthRoleDeleteResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{73} } +func (*AuthRoleDeleteResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{75} } func (m *AuthRoleDeleteResponse) GetHeader() *ResponseHeader { if m != nil { @@ -1960,7 +2042,7 @@ func (m *AuthRoleGrantPermissionResponse) Reset() { *m = AuthRoleGrantPe func (m *AuthRoleGrantPermissionResponse) String() string { return proto.CompactTextString(m) } func (*AuthRoleGrantPermissionResponse) ProtoMessage() {} func (*AuthRoleGrantPermissionResponse) Descriptor() ([]byte, []int) { - return fileDescriptorRpc, []int{74} + return fileDescriptorRpc, []int{76} } func (m *AuthRoleGrantPermissionResponse) GetHeader() *ResponseHeader { @@ -1978,7 +2060,7 @@ func (m *AuthRoleRevokePermissionResponse) Reset() { *m = AuthRoleRevoke func (m *AuthRoleRevokePermissionResponse) String() string { return proto.CompactTextString(m) } func (*AuthRoleRevokePermissionResponse) ProtoMessage() {} func (*AuthRoleRevokePermissionResponse) Descriptor() ([]byte, []int) { - return fileDescriptorRpc, []int{75} + return fileDescriptorRpc, []int{77} } func (m *AuthRoleRevokePermissionResponse) GetHeader() *ResponseHeader { @@ -2017,6 +2099,8 @@ func init() { proto.RegisterType((*LeaseRevokeResponse)(nil), "etcdserverpb.LeaseRevokeResponse") proto.RegisterType((*LeaseKeepAliveRequest)(nil), "etcdserverpb.LeaseKeepAliveRequest") proto.RegisterType((*LeaseKeepAliveResponse)(nil), "etcdserverpb.LeaseKeepAliveResponse") + proto.RegisterType((*LeaseTimeToLiveRequest)(nil), "etcdserverpb.LeaseTimeToLiveRequest") + proto.RegisterType((*LeaseTimeToLiveResponse)(nil), "etcdserverpb.LeaseTimeToLiveResponse") proto.RegisterType((*Member)(nil), "etcdserverpb.Member") proto.RegisterType((*MemberAddRequest)(nil), "etcdserverpb.MemberAddRequest") proto.RegisterType((*MemberAddResponse)(nil), "etcdserverpb.MemberAddResponse") @@ -2070,6 +2154,7 @@ func init() { proto.RegisterEnum("etcdserverpb.RangeRequest_SortTarget", RangeRequest_SortTarget_name, RangeRequest_SortTarget_value) proto.RegisterEnum("etcdserverpb.Compare_CompareResult", Compare_CompareResult_name, Compare_CompareResult_value) proto.RegisterEnum("etcdserverpb.Compare_CompareTarget", Compare_CompareTarget_name, Compare_CompareTarget_value) + proto.RegisterEnum("etcdserverpb.WatchCreateRequest_FilterType", WatchCreateRequest_FilterType_name, WatchCreateRequest_FilterType_value) proto.RegisterEnum("etcdserverpb.AlarmRequest_AlarmAction", AlarmRequest_AlarmAction_name, AlarmRequest_AlarmAction_value) } @@ -2079,7 +2164,7 @@ var _ grpc.ClientConn // This is a compile-time assertion to ensure that this generated file // is compatible with the grpc package it is being compiled against. -const _ = grpc.SupportPackageIsVersion3 +const _ = grpc.SupportPackageIsVersion4 // Client API for KV service @@ -2302,7 +2387,7 @@ var _KV_serviceDesc = grpc.ServiceDesc{ }, }, Streams: []grpc.StreamDesc{}, - Metadata: fileDescriptorRpc, + Metadata: "rpc.proto", } // Client API for Watch service @@ -2408,7 +2493,7 @@ var _Watch_serviceDesc = grpc.ServiceDesc{ ClientStreams: true, }, }, - Metadata: fileDescriptorRpc, + Metadata: "rpc.proto", } // Client API for Lease service @@ -2423,6 +2508,8 @@ type LeaseClient interface { // LeaseKeepAlive keeps the lease alive by streaming keep alive requests from the client // to the server and streaming keep alive responses from the server to the client. LeaseKeepAlive(ctx context.Context, opts ...grpc.CallOption) (Lease_LeaseKeepAliveClient, error) + // LeaseTimeToLive retrieves lease information. + LeaseTimeToLive(ctx context.Context, in *LeaseTimeToLiveRequest, opts ...grpc.CallOption) (*LeaseTimeToLiveResponse, error) } type leaseClient struct { @@ -2482,6 +2569,15 @@ func (x *leaseLeaseKeepAliveClient) Recv() (*LeaseKeepAliveResponse, error) { return m, nil } +func (c *leaseClient) LeaseTimeToLive(ctx context.Context, in *LeaseTimeToLiveRequest, opts ...grpc.CallOption) (*LeaseTimeToLiveResponse, error) { + out := new(LeaseTimeToLiveResponse) + err := grpc.Invoke(ctx, "/etcdserverpb.Lease/LeaseTimeToLive", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // Server API for Lease service type LeaseServer interface { @@ -2494,6 +2590,8 @@ type LeaseServer interface { // LeaseKeepAlive keeps the lease alive by streaming keep alive requests from the client // to the server and streaming keep alive responses from the server to the client. LeaseKeepAlive(Lease_LeaseKeepAliveServer) error + // LeaseTimeToLive retrieves lease information. + LeaseTimeToLive(context.Context, *LeaseTimeToLiveRequest) (*LeaseTimeToLiveResponse, error) } func RegisterLeaseServer(s *grpc.Server, srv LeaseServer) { @@ -2562,6 +2660,24 @@ func (x *leaseLeaseKeepAliveServer) Recv() (*LeaseKeepAliveRequest, error) { return m, nil } +func _Lease_LeaseTimeToLive_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(LeaseTimeToLiveRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(LeaseServer).LeaseTimeToLive(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/etcdserverpb.Lease/LeaseTimeToLive", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(LeaseServer).LeaseTimeToLive(ctx, req.(*LeaseTimeToLiveRequest)) + } + return interceptor(ctx, in, info, handler) +} + var _Lease_serviceDesc = grpc.ServiceDesc{ ServiceName: "etcdserverpb.Lease", HandlerType: (*LeaseServer)(nil), @@ -2574,6 +2690,10 @@ var _Lease_serviceDesc = grpc.ServiceDesc{ MethodName: "LeaseRevoke", Handler: _Lease_LeaseRevoke_Handler, }, + { + MethodName: "LeaseTimeToLive", + Handler: _Lease_LeaseTimeToLive_Handler, + }, }, Streams: []grpc.StreamDesc{ { @@ -2583,7 +2703,7 @@ var _Lease_serviceDesc = grpc.ServiceDesc{ ClientStreams: true, }, }, - Metadata: fileDescriptorRpc, + Metadata: "rpc.proto", } // Client API for Cluster service @@ -2754,7 +2874,7 @@ var _Cluster_serviceDesc = grpc.ServiceDesc{ }, }, Streams: []grpc.StreamDesc{}, - Metadata: fileDescriptorRpc, + Metadata: "rpc.proto", } // Client API for Maintenance service @@ -2992,7 +3112,7 @@ var _Maintenance_serviceDesc = grpc.ServiceDesc{ ServerStreams: true, }, }, - Metadata: fileDescriptorRpc, + Metadata: "rpc.proto", } // Client API for Auth service @@ -3583,147 +3703,167 @@ var _Auth_serviceDesc = grpc.ServiceDesc{ }, }, Streams: []grpc.StreamDesc{}, - Metadata: fileDescriptorRpc, + Metadata: "rpc.proto", } -func (m *ResponseHeader) Marshal() (data []byte, err error) { +func (m *ResponseHeader) Marshal() (dAtA []byte, err error) { size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) if err != nil { return nil, err } - return data[:n], nil + return dAtA[:n], nil } -func (m *ResponseHeader) MarshalTo(data []byte) (int, error) { +func (m *ResponseHeader) MarshalTo(dAtA []byte) (int, error) { var i int _ = i var l int _ = l if m.ClusterId != 0 { - data[i] = 0x8 + dAtA[i] = 0x8 i++ - i = encodeVarintRpc(data, i, uint64(m.ClusterId)) + i = encodeVarintRpc(dAtA, i, uint64(m.ClusterId)) } if m.MemberId != 0 { - data[i] = 0x10 + dAtA[i] = 0x10 i++ - i = encodeVarintRpc(data, i, uint64(m.MemberId)) + i = encodeVarintRpc(dAtA, i, uint64(m.MemberId)) } if m.Revision != 0 { - data[i] = 0x18 + dAtA[i] = 0x18 i++ - i = encodeVarintRpc(data, i, uint64(m.Revision)) + i = encodeVarintRpc(dAtA, i, uint64(m.Revision)) } if m.RaftTerm != 0 { - data[i] = 0x20 + dAtA[i] = 0x20 i++ - i = encodeVarintRpc(data, i, uint64(m.RaftTerm)) + i = encodeVarintRpc(dAtA, i, uint64(m.RaftTerm)) } return i, nil } -func (m *RangeRequest) Marshal() (data []byte, err error) { +func (m *RangeRequest) Marshal() (dAtA []byte, err error) { size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) if err != nil { return nil, err } - return data[:n], nil + return dAtA[:n], nil } -func (m *RangeRequest) MarshalTo(data []byte) (int, error) { +func (m *RangeRequest) MarshalTo(dAtA []byte) (int, error) { var i int _ = i var l int _ = l if len(m.Key) > 0 { - data[i] = 0xa + dAtA[i] = 0xa i++ - i = encodeVarintRpc(data, i, uint64(len(m.Key))) - i += copy(data[i:], m.Key) + i = encodeVarintRpc(dAtA, i, uint64(len(m.Key))) + i += copy(dAtA[i:], m.Key) } if len(m.RangeEnd) > 0 { - data[i] = 0x12 + dAtA[i] = 0x12 i++ - i = encodeVarintRpc(data, i, uint64(len(m.RangeEnd))) - i += copy(data[i:], m.RangeEnd) + i = encodeVarintRpc(dAtA, i, uint64(len(m.RangeEnd))) + i += copy(dAtA[i:], m.RangeEnd) } if m.Limit != 0 { - data[i] = 0x18 + dAtA[i] = 0x18 i++ - i = encodeVarintRpc(data, i, uint64(m.Limit)) + i = encodeVarintRpc(dAtA, i, uint64(m.Limit)) } if m.Revision != 0 { - data[i] = 0x20 + dAtA[i] = 0x20 i++ - i = encodeVarintRpc(data, i, uint64(m.Revision)) + i = encodeVarintRpc(dAtA, i, uint64(m.Revision)) } if m.SortOrder != 0 { - data[i] = 0x28 + dAtA[i] = 0x28 i++ - i = encodeVarintRpc(data, i, uint64(m.SortOrder)) + i = encodeVarintRpc(dAtA, i, uint64(m.SortOrder)) } if m.SortTarget != 0 { - data[i] = 0x30 + dAtA[i] = 0x30 i++ - i = encodeVarintRpc(data, i, uint64(m.SortTarget)) + i = encodeVarintRpc(dAtA, i, uint64(m.SortTarget)) } if m.Serializable { - data[i] = 0x38 + dAtA[i] = 0x38 i++ if m.Serializable { - data[i] = 1 + dAtA[i] = 1 } else { - data[i] = 0 + dAtA[i] = 0 } i++ } if m.KeysOnly { - data[i] = 0x40 + dAtA[i] = 0x40 i++ if m.KeysOnly { - data[i] = 1 + dAtA[i] = 1 } else { - data[i] = 0 + dAtA[i] = 0 } i++ } if m.CountOnly { - data[i] = 0x48 + dAtA[i] = 0x48 i++ if m.CountOnly { - data[i] = 1 + dAtA[i] = 1 } else { - data[i] = 0 + dAtA[i] = 0 } i++ } + if m.MinModRevision != 0 { + dAtA[i] = 0x50 + i++ + i = encodeVarintRpc(dAtA, i, uint64(m.MinModRevision)) + } + if m.MaxModRevision != 0 { + dAtA[i] = 0x58 + i++ + i = encodeVarintRpc(dAtA, i, uint64(m.MaxModRevision)) + } + if m.MinCreateRevision != 0 { + dAtA[i] = 0x60 + i++ + i = encodeVarintRpc(dAtA, i, uint64(m.MinCreateRevision)) + } + if m.MaxCreateRevision != 0 { + dAtA[i] = 0x68 + i++ + i = encodeVarintRpc(dAtA, i, uint64(m.MaxCreateRevision)) + } return i, nil } -func (m *RangeResponse) Marshal() (data []byte, err error) { +func (m *RangeResponse) Marshal() (dAtA []byte, err error) { size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) if err != nil { return nil, err } - return data[:n], nil + return dAtA[:n], nil } -func (m *RangeResponse) MarshalTo(data []byte) (int, error) { +func (m *RangeResponse) MarshalTo(dAtA []byte) (int, error) { var i int _ = i var l int _ = l if m.Header != nil { - data[i] = 0xa + dAtA[i] = 0xa i++ - i = encodeVarintRpc(data, i, uint64(m.Header.Size())) - n1, err := m.Header.MarshalTo(data[i:]) + i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size())) + n1, err := m.Header.MarshalTo(dAtA[i:]) if err != nil { return 0, err } @@ -3731,10 +3871,10 @@ func (m *RangeResponse) MarshalTo(data []byte) (int, error) { } if len(m.Kvs) > 0 { for _, msg := range m.Kvs { - data[i] = 0x12 + dAtA[i] = 0x12 i++ - i = encodeVarintRpc(data, i, uint64(msg.Size())) - n, err := msg.MarshalTo(data[i:]) + i = encodeVarintRpc(dAtA, i, uint64(msg.Size())) + n, err := msg.MarshalTo(dAtA[i:]) if err != nil { return 0, err } @@ -3742,98 +3882,98 @@ func (m *RangeResponse) MarshalTo(data []byte) (int, error) { } } if m.More { - data[i] = 0x18 + dAtA[i] = 0x18 i++ if m.More { - data[i] = 1 + dAtA[i] = 1 } else { - data[i] = 0 + dAtA[i] = 0 } i++ } if m.Count != 0 { - data[i] = 0x20 + dAtA[i] = 0x20 i++ - i = encodeVarintRpc(data, i, uint64(m.Count)) + i = encodeVarintRpc(dAtA, i, uint64(m.Count)) } return i, nil } -func (m *PutRequest) Marshal() (data []byte, err error) { +func (m *PutRequest) Marshal() (dAtA []byte, err error) { size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) if err != nil { return nil, err } - return data[:n], nil + return dAtA[:n], nil } -func (m *PutRequest) MarshalTo(data []byte) (int, error) { +func (m *PutRequest) MarshalTo(dAtA []byte) (int, error) { var i int _ = i var l int _ = l if len(m.Key) > 0 { - data[i] = 0xa + dAtA[i] = 0xa i++ - i = encodeVarintRpc(data, i, uint64(len(m.Key))) - i += copy(data[i:], m.Key) + i = encodeVarintRpc(dAtA, i, uint64(len(m.Key))) + i += copy(dAtA[i:], m.Key) } if len(m.Value) > 0 { - data[i] = 0x12 + dAtA[i] = 0x12 i++ - i = encodeVarintRpc(data, i, uint64(len(m.Value))) - i += copy(data[i:], m.Value) + i = encodeVarintRpc(dAtA, i, uint64(len(m.Value))) + i += copy(dAtA[i:], m.Value) } if m.Lease != 0 { - data[i] = 0x18 + dAtA[i] = 0x18 i++ - i = encodeVarintRpc(data, i, uint64(m.Lease)) + i = encodeVarintRpc(dAtA, i, uint64(m.Lease)) } if m.PrevKv { - data[i] = 0x20 + dAtA[i] = 0x20 i++ if m.PrevKv { - data[i] = 1 + dAtA[i] = 1 } else { - data[i] = 0 + dAtA[i] = 0 } i++ } return i, nil } -func (m *PutResponse) Marshal() (data []byte, err error) { +func (m *PutResponse) Marshal() (dAtA []byte, err error) { size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) if err != nil { return nil, err } - return data[:n], nil + return dAtA[:n], nil } -func (m *PutResponse) MarshalTo(data []byte) (int, error) { +func (m *PutResponse) MarshalTo(dAtA []byte) (int, error) { var i int _ = i var l int _ = l if m.Header != nil { - data[i] = 0xa + dAtA[i] = 0xa i++ - i = encodeVarintRpc(data, i, uint64(m.Header.Size())) - n2, err := m.Header.MarshalTo(data[i:]) + i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size())) + n2, err := m.Header.MarshalTo(dAtA[i:]) if err != nil { return 0, err } i += n2 } if m.PrevKv != nil { - data[i] = 0x12 + dAtA[i] = 0x12 i++ - i = encodeVarintRpc(data, i, uint64(m.PrevKv.Size())) - n3, err := m.PrevKv.MarshalTo(data[i:]) + i = encodeVarintRpc(dAtA, i, uint64(m.PrevKv.Size())) + n3, err := m.PrevKv.MarshalTo(dAtA[i:]) if err != nil { return 0, err } @@ -3842,82 +3982,82 @@ func (m *PutResponse) MarshalTo(data []byte) (int, error) { return i, nil } -func (m *DeleteRangeRequest) Marshal() (data []byte, err error) { +func (m *DeleteRangeRequest) Marshal() (dAtA []byte, err error) { size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) if err != nil { return nil, err } - return data[:n], nil + return dAtA[:n], nil } -func (m *DeleteRangeRequest) MarshalTo(data []byte) (int, error) { +func (m *DeleteRangeRequest) MarshalTo(dAtA []byte) (int, error) { var i int _ = i var l int _ = l if len(m.Key) > 0 { - data[i] = 0xa + dAtA[i] = 0xa i++ - i = encodeVarintRpc(data, i, uint64(len(m.Key))) - i += copy(data[i:], m.Key) + i = encodeVarintRpc(dAtA, i, uint64(len(m.Key))) + i += copy(dAtA[i:], m.Key) } if len(m.RangeEnd) > 0 { - data[i] = 0x12 + dAtA[i] = 0x12 i++ - i = encodeVarintRpc(data, i, uint64(len(m.RangeEnd))) - i += copy(data[i:], m.RangeEnd) + i = encodeVarintRpc(dAtA, i, uint64(len(m.RangeEnd))) + i += copy(dAtA[i:], m.RangeEnd) } if m.PrevKv { - data[i] = 0x18 + dAtA[i] = 0x18 i++ if m.PrevKv { - data[i] = 1 + dAtA[i] = 1 } else { - data[i] = 0 + dAtA[i] = 0 } i++ } return i, nil } -func (m *DeleteRangeResponse) Marshal() (data []byte, err error) { +func (m *DeleteRangeResponse) Marshal() (dAtA []byte, err error) { size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) if err != nil { return nil, err } - return data[:n], nil + return dAtA[:n], nil } -func (m *DeleteRangeResponse) MarshalTo(data []byte) (int, error) { +func (m *DeleteRangeResponse) MarshalTo(dAtA []byte) (int, error) { var i int _ = i var l int _ = l if m.Header != nil { - data[i] = 0xa + dAtA[i] = 0xa i++ - i = encodeVarintRpc(data, i, uint64(m.Header.Size())) - n4, err := m.Header.MarshalTo(data[i:]) + i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size())) + n4, err := m.Header.MarshalTo(dAtA[i:]) if err != nil { return 0, err } i += n4 } if m.Deleted != 0 { - data[i] = 0x10 + dAtA[i] = 0x10 i++ - i = encodeVarintRpc(data, i, uint64(m.Deleted)) + i = encodeVarintRpc(dAtA, i, uint64(m.Deleted)) } if len(m.PrevKvs) > 0 { for _, msg := range m.PrevKvs { - data[i] = 0x1a + dAtA[i] = 0x1a i++ - i = encodeVarintRpc(data, i, uint64(msg.Size())) - n, err := msg.MarshalTo(data[i:]) + i = encodeVarintRpc(dAtA, i, uint64(msg.Size())) + n, err := msg.MarshalTo(dAtA[i:]) if err != nil { return 0, err } @@ -3927,23 +4067,23 @@ func (m *DeleteRangeResponse) MarshalTo(data []byte) (int, error) { return i, nil } -func (m *RequestOp) Marshal() (data []byte, err error) { +func (m *RequestOp) Marshal() (dAtA []byte, err error) { size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) if err != nil { return nil, err } - return data[:n], nil + return dAtA[:n], nil } -func (m *RequestOp) MarshalTo(data []byte) (int, error) { +func (m *RequestOp) MarshalTo(dAtA []byte) (int, error) { var i int _ = i var l int _ = l if m.Request != nil { - nn5, err := m.Request.MarshalTo(data[i:]) + nn5, err := m.Request.MarshalTo(dAtA[i:]) if err != nil { return 0, err } @@ -3952,13 +4092,13 @@ func (m *RequestOp) MarshalTo(data []byte) (int, error) { return i, nil } -func (m *RequestOp_RequestRange) MarshalTo(data []byte) (int, error) { +func (m *RequestOp_RequestRange) MarshalTo(dAtA []byte) (int, error) { i := 0 if m.RequestRange != nil { - data[i] = 0xa + dAtA[i] = 0xa i++ - i = encodeVarintRpc(data, i, uint64(m.RequestRange.Size())) - n6, err := m.RequestRange.MarshalTo(data[i:]) + i = encodeVarintRpc(dAtA, i, uint64(m.RequestRange.Size())) + n6, err := m.RequestRange.MarshalTo(dAtA[i:]) if err != nil { return 0, err } @@ -3966,13 +4106,13 @@ func (m *RequestOp_RequestRange) MarshalTo(data []byte) (int, error) { } return i, nil } -func (m *RequestOp_RequestPut) MarshalTo(data []byte) (int, error) { +func (m *RequestOp_RequestPut) MarshalTo(dAtA []byte) (int, error) { i := 0 if m.RequestPut != nil { - data[i] = 0x12 + dAtA[i] = 0x12 i++ - i = encodeVarintRpc(data, i, uint64(m.RequestPut.Size())) - n7, err := m.RequestPut.MarshalTo(data[i:]) + i = encodeVarintRpc(dAtA, i, uint64(m.RequestPut.Size())) + n7, err := m.RequestPut.MarshalTo(dAtA[i:]) if err != nil { return 0, err } @@ -3980,13 +4120,13 @@ func (m *RequestOp_RequestPut) MarshalTo(data []byte) (int, error) { } return i, nil } -func (m *RequestOp_RequestDeleteRange) MarshalTo(data []byte) (int, error) { +func (m *RequestOp_RequestDeleteRange) MarshalTo(dAtA []byte) (int, error) { i := 0 if m.RequestDeleteRange != nil { - data[i] = 0x1a + dAtA[i] = 0x1a i++ - i = encodeVarintRpc(data, i, uint64(m.RequestDeleteRange.Size())) - n8, err := m.RequestDeleteRange.MarshalTo(data[i:]) + i = encodeVarintRpc(dAtA, i, uint64(m.RequestDeleteRange.Size())) + n8, err := m.RequestDeleteRange.MarshalTo(dAtA[i:]) if err != nil { return 0, err } @@ -3994,23 +4134,23 @@ func (m *RequestOp_RequestDeleteRange) MarshalTo(data []byte) (int, error) { } return i, nil } -func (m *ResponseOp) Marshal() (data []byte, err error) { +func (m *ResponseOp) Marshal() (dAtA []byte, err error) { size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) if err != nil { return nil, err } - return data[:n], nil + return dAtA[:n], nil } -func (m *ResponseOp) MarshalTo(data []byte) (int, error) { +func (m *ResponseOp) MarshalTo(dAtA []byte) (int, error) { var i int _ = i var l int _ = l if m.Response != nil { - nn9, err := m.Response.MarshalTo(data[i:]) + nn9, err := m.Response.MarshalTo(dAtA[i:]) if err != nil { return 0, err } @@ -4019,13 +4159,13 @@ func (m *ResponseOp) MarshalTo(data []byte) (int, error) { return i, nil } -func (m *ResponseOp_ResponseRange) MarshalTo(data []byte) (int, error) { +func (m *ResponseOp_ResponseRange) MarshalTo(dAtA []byte) (int, error) { i := 0 if m.ResponseRange != nil { - data[i] = 0xa + dAtA[i] = 0xa i++ - i = encodeVarintRpc(data, i, uint64(m.ResponseRange.Size())) - n10, err := m.ResponseRange.MarshalTo(data[i:]) + i = encodeVarintRpc(dAtA, i, uint64(m.ResponseRange.Size())) + n10, err := m.ResponseRange.MarshalTo(dAtA[i:]) if err != nil { return 0, err } @@ -4033,13 +4173,13 @@ func (m *ResponseOp_ResponseRange) MarshalTo(data []byte) (int, error) { } return i, nil } -func (m *ResponseOp_ResponsePut) MarshalTo(data []byte) (int, error) { +func (m *ResponseOp_ResponsePut) MarshalTo(dAtA []byte) (int, error) { i := 0 if m.ResponsePut != nil { - data[i] = 0x12 + dAtA[i] = 0x12 i++ - i = encodeVarintRpc(data, i, uint64(m.ResponsePut.Size())) - n11, err := m.ResponsePut.MarshalTo(data[i:]) + i = encodeVarintRpc(dAtA, i, uint64(m.ResponsePut.Size())) + n11, err := m.ResponsePut.MarshalTo(dAtA[i:]) if err != nil { return 0, err } @@ -4047,13 +4187,13 @@ func (m *ResponseOp_ResponsePut) MarshalTo(data []byte) (int, error) { } return i, nil } -func (m *ResponseOp_ResponseDeleteRange) MarshalTo(data []byte) (int, error) { +func (m *ResponseOp_ResponseDeleteRange) MarshalTo(dAtA []byte) (int, error) { i := 0 if m.ResponseDeleteRange != nil { - data[i] = 0x1a + dAtA[i] = 0x1a i++ - i = encodeVarintRpc(data, i, uint64(m.ResponseDeleteRange.Size())) - n12, err := m.ResponseDeleteRange.MarshalTo(data[i:]) + i = encodeVarintRpc(dAtA, i, uint64(m.ResponseDeleteRange.Size())) + n12, err := m.ResponseDeleteRange.MarshalTo(dAtA[i:]) if err != nil { return 0, err } @@ -4061,39 +4201,39 @@ func (m *ResponseOp_ResponseDeleteRange) MarshalTo(data []byte) (int, error) { } return i, nil } -func (m *Compare) Marshal() (data []byte, err error) { +func (m *Compare) Marshal() (dAtA []byte, err error) { size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) if err != nil { return nil, err } - return data[:n], nil + return dAtA[:n], nil } -func (m *Compare) MarshalTo(data []byte) (int, error) { +func (m *Compare) MarshalTo(dAtA []byte) (int, error) { var i int _ = i var l int _ = l if m.Result != 0 { - data[i] = 0x8 + dAtA[i] = 0x8 i++ - i = encodeVarintRpc(data, i, uint64(m.Result)) + i = encodeVarintRpc(dAtA, i, uint64(m.Result)) } if m.Target != 0 { - data[i] = 0x10 + dAtA[i] = 0x10 i++ - i = encodeVarintRpc(data, i, uint64(m.Target)) + i = encodeVarintRpc(dAtA, i, uint64(m.Target)) } if len(m.Key) > 0 { - data[i] = 0x1a + dAtA[i] = 0x1a i++ - i = encodeVarintRpc(data, i, uint64(len(m.Key))) - i += copy(data[i:], m.Key) + i = encodeVarintRpc(dAtA, i, uint64(len(m.Key))) + i += copy(dAtA[i:], m.Key) } if m.TargetUnion != nil { - nn13, err := m.TargetUnion.MarshalTo(data[i:]) + nn13, err := m.TargetUnion.MarshalTo(dAtA[i:]) if err != nil { return 0, err } @@ -4102,58 +4242,58 @@ func (m *Compare) MarshalTo(data []byte) (int, error) { return i, nil } -func (m *Compare_Version) MarshalTo(data []byte) (int, error) { +func (m *Compare_Version) MarshalTo(dAtA []byte) (int, error) { i := 0 - data[i] = 0x20 + dAtA[i] = 0x20 i++ - i = encodeVarintRpc(data, i, uint64(m.Version)) + i = encodeVarintRpc(dAtA, i, uint64(m.Version)) return i, nil } -func (m *Compare_CreateRevision) MarshalTo(data []byte) (int, error) { +func (m *Compare_CreateRevision) MarshalTo(dAtA []byte) (int, error) { i := 0 - data[i] = 0x28 + dAtA[i] = 0x28 i++ - i = encodeVarintRpc(data, i, uint64(m.CreateRevision)) + i = encodeVarintRpc(dAtA, i, uint64(m.CreateRevision)) return i, nil } -func (m *Compare_ModRevision) MarshalTo(data []byte) (int, error) { +func (m *Compare_ModRevision) MarshalTo(dAtA []byte) (int, error) { i := 0 - data[i] = 0x30 + dAtA[i] = 0x30 i++ - i = encodeVarintRpc(data, i, uint64(m.ModRevision)) + i = encodeVarintRpc(dAtA, i, uint64(m.ModRevision)) return i, nil } -func (m *Compare_Value) MarshalTo(data []byte) (int, error) { +func (m *Compare_Value) MarshalTo(dAtA []byte) (int, error) { i := 0 if m.Value != nil { - data[i] = 0x3a + dAtA[i] = 0x3a i++ - i = encodeVarintRpc(data, i, uint64(len(m.Value))) - i += copy(data[i:], m.Value) + i = encodeVarintRpc(dAtA, i, uint64(len(m.Value))) + i += copy(dAtA[i:], m.Value) } return i, nil } -func (m *TxnRequest) Marshal() (data []byte, err error) { +func (m *TxnRequest) Marshal() (dAtA []byte, err error) { size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) if err != nil { return nil, err } - return data[:n], nil + return dAtA[:n], nil } -func (m *TxnRequest) MarshalTo(data []byte) (int, error) { +func (m *TxnRequest) MarshalTo(dAtA []byte) (int, error) { var i int _ = i var l int _ = l if len(m.Compare) > 0 { for _, msg := range m.Compare { - data[i] = 0xa + dAtA[i] = 0xa i++ - i = encodeVarintRpc(data, i, uint64(msg.Size())) - n, err := msg.MarshalTo(data[i:]) + i = encodeVarintRpc(dAtA, i, uint64(msg.Size())) + n, err := msg.MarshalTo(dAtA[i:]) if err != nil { return 0, err } @@ -4162,10 +4302,10 @@ func (m *TxnRequest) MarshalTo(data []byte) (int, error) { } if len(m.Success) > 0 { for _, msg := range m.Success { - data[i] = 0x12 + dAtA[i] = 0x12 i++ - i = encodeVarintRpc(data, i, uint64(msg.Size())) - n, err := msg.MarshalTo(data[i:]) + i = encodeVarintRpc(dAtA, i, uint64(msg.Size())) + n, err := msg.MarshalTo(dAtA[i:]) if err != nil { return 0, err } @@ -4174,10 +4314,10 @@ func (m *TxnRequest) MarshalTo(data []byte) (int, error) { } if len(m.Failure) > 0 { for _, msg := range m.Failure { - data[i] = 0x1a + dAtA[i] = 0x1a i++ - i = encodeVarintRpc(data, i, uint64(msg.Size())) - n, err := msg.MarshalTo(data[i:]) + i = encodeVarintRpc(dAtA, i, uint64(msg.Size())) + n, err := msg.MarshalTo(dAtA[i:]) if err != nil { return 0, err } @@ -4187,47 +4327,47 @@ func (m *TxnRequest) MarshalTo(data []byte) (int, error) { return i, nil } -func (m *TxnResponse) Marshal() (data []byte, err error) { +func (m *TxnResponse) Marshal() (dAtA []byte, err error) { size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) if err != nil { return nil, err } - return data[:n], nil + return dAtA[:n], nil } -func (m *TxnResponse) MarshalTo(data []byte) (int, error) { +func (m *TxnResponse) MarshalTo(dAtA []byte) (int, error) { var i int _ = i var l int _ = l if m.Header != nil { - data[i] = 0xa + dAtA[i] = 0xa i++ - i = encodeVarintRpc(data, i, uint64(m.Header.Size())) - n14, err := m.Header.MarshalTo(data[i:]) + i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size())) + n14, err := m.Header.MarshalTo(dAtA[i:]) if err != nil { return 0, err } i += n14 } if m.Succeeded { - data[i] = 0x10 + dAtA[i] = 0x10 i++ if m.Succeeded { - data[i] = 1 + dAtA[i] = 1 } else { - data[i] = 0 + dAtA[i] = 0 } i++ } if len(m.Responses) > 0 { for _, msg := range m.Responses { - data[i] = 0x1a + dAtA[i] = 0x1a i++ - i = encodeVarintRpc(data, i, uint64(msg.Size())) - n, err := msg.MarshalTo(data[i:]) + i = encodeVarintRpc(dAtA, i, uint64(msg.Size())) + n, err := msg.MarshalTo(dAtA[i:]) if err != nil { return 0, err } @@ -4237,59 +4377,59 @@ func (m *TxnResponse) MarshalTo(data []byte) (int, error) { return i, nil } -func (m *CompactionRequest) Marshal() (data []byte, err error) { +func (m *CompactionRequest) Marshal() (dAtA []byte, err error) { size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) if err != nil { return nil, err } - return data[:n], nil + return dAtA[:n], nil } -func (m *CompactionRequest) MarshalTo(data []byte) (int, error) { +func (m *CompactionRequest) MarshalTo(dAtA []byte) (int, error) { var i int _ = i var l int _ = l if m.Revision != 0 { - data[i] = 0x8 + dAtA[i] = 0x8 i++ - i = encodeVarintRpc(data, i, uint64(m.Revision)) + i = encodeVarintRpc(dAtA, i, uint64(m.Revision)) } if m.Physical { - data[i] = 0x10 + dAtA[i] = 0x10 i++ if m.Physical { - data[i] = 1 + dAtA[i] = 1 } else { - data[i] = 0 + dAtA[i] = 0 } i++ } return i, nil } -func (m *CompactionResponse) Marshal() (data []byte, err error) { +func (m *CompactionResponse) Marshal() (dAtA []byte, err error) { size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) if err != nil { return nil, err } - return data[:n], nil + return dAtA[:n], nil } -func (m *CompactionResponse) MarshalTo(data []byte) (int, error) { +func (m *CompactionResponse) MarshalTo(dAtA []byte) (int, error) { var i int _ = i var l int _ = l if m.Header != nil { - data[i] = 0xa + dAtA[i] = 0xa i++ - i = encodeVarintRpc(data, i, uint64(m.Header.Size())) - n15, err := m.Header.MarshalTo(data[i:]) + i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size())) + n15, err := m.Header.MarshalTo(dAtA[i:]) if err != nil { return 0, err } @@ -4298,17 +4438,17 @@ func (m *CompactionResponse) MarshalTo(data []byte) (int, error) { return i, nil } -func (m *HashRequest) Marshal() (data []byte, err error) { +func (m *HashRequest) Marshal() (dAtA []byte, err error) { size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) if err != nil { return nil, err } - return data[:n], nil + return dAtA[:n], nil } -func (m *HashRequest) MarshalTo(data []byte) (int, error) { +func (m *HashRequest) MarshalTo(dAtA []byte) (int, error) { var i int _ = i var l int @@ -4316,50 +4456,50 @@ func (m *HashRequest) MarshalTo(data []byte) (int, error) { return i, nil } -func (m *HashResponse) Marshal() (data []byte, err error) { +func (m *HashResponse) Marshal() (dAtA []byte, err error) { size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) if err != nil { return nil, err } - return data[:n], nil + return dAtA[:n], nil } -func (m *HashResponse) MarshalTo(data []byte) (int, error) { +func (m *HashResponse) MarshalTo(dAtA []byte) (int, error) { var i int _ = i var l int _ = l if m.Header != nil { - data[i] = 0xa + dAtA[i] = 0xa i++ - i = encodeVarintRpc(data, i, uint64(m.Header.Size())) - n16, err := m.Header.MarshalTo(data[i:]) + i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size())) + n16, err := m.Header.MarshalTo(dAtA[i:]) if err != nil { return 0, err } i += n16 } if m.Hash != 0 { - data[i] = 0x10 + dAtA[i] = 0x10 i++ - i = encodeVarintRpc(data, i, uint64(m.Hash)) + i = encodeVarintRpc(dAtA, i, uint64(m.Hash)) } return i, nil } -func (m *SnapshotRequest) Marshal() (data []byte, err error) { +func (m *SnapshotRequest) Marshal() (dAtA []byte, err error) { size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) if err != nil { return nil, err } - return data[:n], nil + return dAtA[:n], nil } -func (m *SnapshotRequest) MarshalTo(data []byte) (int, error) { +func (m *SnapshotRequest) MarshalTo(dAtA []byte) (int, error) { var i int _ = i var l int @@ -4367,62 +4507,62 @@ func (m *SnapshotRequest) MarshalTo(data []byte) (int, error) { return i, nil } -func (m *SnapshotResponse) Marshal() (data []byte, err error) { +func (m *SnapshotResponse) Marshal() (dAtA []byte, err error) { size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) if err != nil { return nil, err } - return data[:n], nil + return dAtA[:n], nil } -func (m *SnapshotResponse) MarshalTo(data []byte) (int, error) { +func (m *SnapshotResponse) MarshalTo(dAtA []byte) (int, error) { var i int _ = i var l int _ = l if m.Header != nil { - data[i] = 0xa + dAtA[i] = 0xa i++ - i = encodeVarintRpc(data, i, uint64(m.Header.Size())) - n17, err := m.Header.MarshalTo(data[i:]) + i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size())) + n17, err := m.Header.MarshalTo(dAtA[i:]) if err != nil { return 0, err } i += n17 } if m.RemainingBytes != 0 { - data[i] = 0x10 + dAtA[i] = 0x10 i++ - i = encodeVarintRpc(data, i, uint64(m.RemainingBytes)) + i = encodeVarintRpc(dAtA, i, uint64(m.RemainingBytes)) } if len(m.Blob) > 0 { - data[i] = 0x1a + dAtA[i] = 0x1a i++ - i = encodeVarintRpc(data, i, uint64(len(m.Blob))) - i += copy(data[i:], m.Blob) + i = encodeVarintRpc(dAtA, i, uint64(len(m.Blob))) + i += copy(dAtA[i:], m.Blob) } return i, nil } -func (m *WatchRequest) Marshal() (data []byte, err error) { +func (m *WatchRequest) Marshal() (dAtA []byte, err error) { size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) if err != nil { return nil, err } - return data[:n], nil + return dAtA[:n], nil } -func (m *WatchRequest) MarshalTo(data []byte) (int, error) { +func (m *WatchRequest) MarshalTo(dAtA []byte) (int, error) { var i int _ = i var l int _ = l if m.RequestUnion != nil { - nn18, err := m.RequestUnion.MarshalTo(data[i:]) + nn18, err := m.RequestUnion.MarshalTo(dAtA[i:]) if err != nil { return 0, err } @@ -4431,13 +4571,13 @@ func (m *WatchRequest) MarshalTo(data []byte) (int, error) { return i, nil } -func (m *WatchRequest_CreateRequest) MarshalTo(data []byte) (int, error) { +func (m *WatchRequest_CreateRequest) MarshalTo(dAtA []byte) (int, error) { i := 0 if m.CreateRequest != nil { - data[i] = 0xa + dAtA[i] = 0xa i++ - i = encodeVarintRpc(data, i, uint64(m.CreateRequest.Size())) - n19, err := m.CreateRequest.MarshalTo(data[i:]) + i = encodeVarintRpc(dAtA, i, uint64(m.CreateRequest.Size())) + n19, err := m.CreateRequest.MarshalTo(dAtA[i:]) if err != nil { return 0, err } @@ -4445,13 +4585,13 @@ func (m *WatchRequest_CreateRequest) MarshalTo(data []byte) (int, error) { } return i, nil } -func (m *WatchRequest_CancelRequest) MarshalTo(data []byte) (int, error) { +func (m *WatchRequest_CancelRequest) MarshalTo(dAtA []byte) (int, error) { i := 0 if m.CancelRequest != nil { - data[i] = 0x12 + dAtA[i] = 0x12 i++ - i = encodeVarintRpc(data, i, uint64(m.CancelRequest.Size())) - n20, err := m.CancelRequest.MarshalTo(data[i:]) + i = encodeVarintRpc(dAtA, i, uint64(m.CancelRequest.Size())) + n20, err := m.CancelRequest.MarshalTo(dAtA[i:]) if err != nil { return 0, err } @@ -4459,145 +4599,162 @@ func (m *WatchRequest_CancelRequest) MarshalTo(data []byte) (int, error) { } return i, nil } -func (m *WatchCreateRequest) Marshal() (data []byte, err error) { +func (m *WatchCreateRequest) Marshal() (dAtA []byte, err error) { size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) if err != nil { return nil, err } - return data[:n], nil + return dAtA[:n], nil } -func (m *WatchCreateRequest) MarshalTo(data []byte) (int, error) { +func (m *WatchCreateRequest) MarshalTo(dAtA []byte) (int, error) { var i int _ = i var l int _ = l if len(m.Key) > 0 { - data[i] = 0xa + dAtA[i] = 0xa i++ - i = encodeVarintRpc(data, i, uint64(len(m.Key))) - i += copy(data[i:], m.Key) + i = encodeVarintRpc(dAtA, i, uint64(len(m.Key))) + i += copy(dAtA[i:], m.Key) } if len(m.RangeEnd) > 0 { - data[i] = 0x12 + dAtA[i] = 0x12 i++ - i = encodeVarintRpc(data, i, uint64(len(m.RangeEnd))) - i += copy(data[i:], m.RangeEnd) + i = encodeVarintRpc(dAtA, i, uint64(len(m.RangeEnd))) + i += copy(dAtA[i:], m.RangeEnd) } if m.StartRevision != 0 { - data[i] = 0x18 + dAtA[i] = 0x18 i++ - i = encodeVarintRpc(data, i, uint64(m.StartRevision)) + i = encodeVarintRpc(dAtA, i, uint64(m.StartRevision)) } if m.ProgressNotify { - data[i] = 0x20 + dAtA[i] = 0x20 i++ if m.ProgressNotify { - data[i] = 1 + dAtA[i] = 1 } else { - data[i] = 0 + dAtA[i] = 0 } i++ } + if len(m.Filters) > 0 { + dAtA22 := make([]byte, len(m.Filters)*10) + var j21 int + for _, num := range m.Filters { + for num >= 1<<7 { + dAtA22[j21] = uint8(uint64(num)&0x7f | 0x80) + num >>= 7 + j21++ + } + dAtA22[j21] = uint8(num) + j21++ + } + dAtA[i] = 0x2a + i++ + i = encodeVarintRpc(dAtA, i, uint64(j21)) + i += copy(dAtA[i:], dAtA22[:j21]) + } if m.PrevKv { - data[i] = 0x30 + dAtA[i] = 0x30 i++ if m.PrevKv { - data[i] = 1 + dAtA[i] = 1 } else { - data[i] = 0 + dAtA[i] = 0 } i++ } return i, nil } -func (m *WatchCancelRequest) Marshal() (data []byte, err error) { +func (m *WatchCancelRequest) Marshal() (dAtA []byte, err error) { size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) if err != nil { return nil, err } - return data[:n], nil + return dAtA[:n], nil } -func (m *WatchCancelRequest) MarshalTo(data []byte) (int, error) { +func (m *WatchCancelRequest) MarshalTo(dAtA []byte) (int, error) { var i int _ = i var l int _ = l if m.WatchId != 0 { - data[i] = 0x8 + dAtA[i] = 0x8 i++ - i = encodeVarintRpc(data, i, uint64(m.WatchId)) + i = encodeVarintRpc(dAtA, i, uint64(m.WatchId)) } return i, nil } -func (m *WatchResponse) Marshal() (data []byte, err error) { +func (m *WatchResponse) Marshal() (dAtA []byte, err error) { size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) if err != nil { return nil, err } - return data[:n], nil + return dAtA[:n], nil } -func (m *WatchResponse) MarshalTo(data []byte) (int, error) { +func (m *WatchResponse) MarshalTo(dAtA []byte) (int, error) { var i int _ = i var l int _ = l if m.Header != nil { - data[i] = 0xa + dAtA[i] = 0xa i++ - i = encodeVarintRpc(data, i, uint64(m.Header.Size())) - n21, err := m.Header.MarshalTo(data[i:]) + i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size())) + n23, err := m.Header.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n21 + i += n23 } if m.WatchId != 0 { - data[i] = 0x10 + dAtA[i] = 0x10 i++ - i = encodeVarintRpc(data, i, uint64(m.WatchId)) + i = encodeVarintRpc(dAtA, i, uint64(m.WatchId)) } if m.Created { - data[i] = 0x18 + dAtA[i] = 0x18 i++ if m.Created { - data[i] = 1 + dAtA[i] = 1 } else { - data[i] = 0 + dAtA[i] = 0 } i++ } if m.Canceled { - data[i] = 0x20 + dAtA[i] = 0x20 i++ if m.Canceled { - data[i] = 1 + dAtA[i] = 1 } else { - data[i] = 0 + dAtA[i] = 0 } i++ } if m.CompactRevision != 0 { - data[i] = 0x28 + dAtA[i] = 0x28 i++ - i = encodeVarintRpc(data, i, uint64(m.CompactRevision)) + i = encodeVarintRpc(dAtA, i, uint64(m.CompactRevision)) } if len(m.Events) > 0 { for _, msg := range m.Events { - data[i] = 0x5a + dAtA[i] = 0x5a i++ - i = encodeVarintRpc(data, i, uint64(msg.Size())) - n, err := msg.MarshalTo(data[i:]) + i = encodeVarintRpc(dAtA, i, uint64(msg.Size())) + n, err := msg.MarshalTo(dAtA[i:]) if err != nil { return 0, err } @@ -4607,533 +4764,447 @@ func (m *WatchResponse) MarshalTo(data []byte) (int, error) { return i, nil } -func (m *LeaseGrantRequest) Marshal() (data []byte, err error) { +func (m *LeaseGrantRequest) Marshal() (dAtA []byte, err error) { size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) if err != nil { return nil, err } - return data[:n], nil + return dAtA[:n], nil } -func (m *LeaseGrantRequest) MarshalTo(data []byte) (int, error) { +func (m *LeaseGrantRequest) MarshalTo(dAtA []byte) (int, error) { var i int _ = i var l int _ = l if m.TTL != 0 { - data[i] = 0x8 + dAtA[i] = 0x8 i++ - i = encodeVarintRpc(data, i, uint64(m.TTL)) + i = encodeVarintRpc(dAtA, i, uint64(m.TTL)) } if m.ID != 0 { - data[i] = 0x10 + dAtA[i] = 0x10 i++ - i = encodeVarintRpc(data, i, uint64(m.ID)) + i = encodeVarintRpc(dAtA, i, uint64(m.ID)) } return i, nil } -func (m *LeaseGrantResponse) Marshal() (data []byte, err error) { +func (m *LeaseGrantResponse) Marshal() (dAtA []byte, err error) { size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) if err != nil { return nil, err } - return data[:n], nil + return dAtA[:n], nil } -func (m *LeaseGrantResponse) MarshalTo(data []byte) (int, error) { +func (m *LeaseGrantResponse) MarshalTo(dAtA []byte) (int, error) { var i int _ = i var l int _ = l if m.Header != nil { - data[i] = 0xa + dAtA[i] = 0xa i++ - i = encodeVarintRpc(data, i, uint64(m.Header.Size())) - n22, err := m.Header.MarshalTo(data[i:]) - if err != nil { - return 0, err - } - i += n22 - } - if m.ID != 0 { - data[i] = 0x10 - i++ - i = encodeVarintRpc(data, i, uint64(m.ID)) - } - if m.TTL != 0 { - data[i] = 0x18 - i++ - i = encodeVarintRpc(data, i, uint64(m.TTL)) - } - if len(m.Error) > 0 { - data[i] = 0x22 - i++ - i = encodeVarintRpc(data, i, uint64(len(m.Error))) - i += copy(data[i:], m.Error) - } - return i, nil -} - -func (m *LeaseRevokeRequest) Marshal() (data []byte, err error) { - size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) - if err != nil { - return nil, err - } - return data[:n], nil -} - -func (m *LeaseRevokeRequest) MarshalTo(data []byte) (int, error) { - var i int - _ = i - var l int - _ = l - if m.ID != 0 { - data[i] = 0x8 - i++ - i = encodeVarintRpc(data, i, uint64(m.ID)) - } - return i, nil -} - -func (m *LeaseRevokeResponse) Marshal() (data []byte, err error) { - size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) - if err != nil { - return nil, err - } - return data[:n], nil -} - -func (m *LeaseRevokeResponse) MarshalTo(data []byte) (int, error) { - var i int - _ = i - var l int - _ = l - if m.Header != nil { - data[i] = 0xa - i++ - i = encodeVarintRpc(data, i, uint64(m.Header.Size())) - n23, err := m.Header.MarshalTo(data[i:]) - if err != nil { - return 0, err - } - i += n23 - } - return i, nil -} - -func (m *LeaseKeepAliveRequest) Marshal() (data []byte, err error) { - size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) - if err != nil { - return nil, err - } - return data[:n], nil -} - -func (m *LeaseKeepAliveRequest) MarshalTo(data []byte) (int, error) { - var i int - _ = i - var l int - _ = l - if m.ID != 0 { - data[i] = 0x8 - i++ - i = encodeVarintRpc(data, i, uint64(m.ID)) - } - return i, nil -} - -func (m *LeaseKeepAliveResponse) Marshal() (data []byte, err error) { - size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) - if err != nil { - return nil, err - } - return data[:n], nil -} - -func (m *LeaseKeepAliveResponse) MarshalTo(data []byte) (int, error) { - var i int - _ = i - var l int - _ = l - if m.Header != nil { - data[i] = 0xa - i++ - i = encodeVarintRpc(data, i, uint64(m.Header.Size())) - n24, err := m.Header.MarshalTo(data[i:]) + i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size())) + n24, err := m.Header.MarshalTo(dAtA[i:]) if err != nil { return 0, err } i += n24 } if m.ID != 0 { - data[i] = 0x10 + dAtA[i] = 0x10 i++ - i = encodeVarintRpc(data, i, uint64(m.ID)) + i = encodeVarintRpc(dAtA, i, uint64(m.ID)) } if m.TTL != 0 { - data[i] = 0x18 + dAtA[i] = 0x18 i++ - i = encodeVarintRpc(data, i, uint64(m.TTL)) + i = encodeVarintRpc(dAtA, i, uint64(m.TTL)) + } + if len(m.Error) > 0 { + dAtA[i] = 0x22 + i++ + i = encodeVarintRpc(dAtA, i, uint64(len(m.Error))) + i += copy(dAtA[i:], m.Error) } return i, nil } -func (m *Member) Marshal() (data []byte, err error) { +func (m *LeaseRevokeRequest) Marshal() (dAtA []byte, err error) { size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) if err != nil { return nil, err } - return data[:n], nil + return dAtA[:n], nil } -func (m *Member) MarshalTo(data []byte) (int, error) { +func (m *LeaseRevokeRequest) MarshalTo(dAtA []byte) (int, error) { var i int _ = i var l int _ = l if m.ID != 0 { - data[i] = 0x8 + dAtA[i] = 0x8 i++ - i = encodeVarintRpc(data, i, uint64(m.ID)) - } - if len(m.Name) > 0 { - data[i] = 0x12 - i++ - i = encodeVarintRpc(data, i, uint64(len(m.Name))) - i += copy(data[i:], m.Name) - } - if len(m.PeerURLs) > 0 { - for _, s := range m.PeerURLs { - data[i] = 0x1a - i++ - l = len(s) - for l >= 1<<7 { - data[i] = uint8(uint64(l)&0x7f | 0x80) - l >>= 7 - i++ - } - data[i] = uint8(l) - i++ - i += copy(data[i:], s) - } - } - if len(m.ClientURLs) > 0 { - for _, s := range m.ClientURLs { - data[i] = 0x22 - i++ - l = len(s) - for l >= 1<<7 { - data[i] = uint8(uint64(l)&0x7f | 0x80) - l >>= 7 - i++ - } - data[i] = uint8(l) - i++ - i += copy(data[i:], s) - } + i = encodeVarintRpc(dAtA, i, uint64(m.ID)) } return i, nil } -func (m *MemberAddRequest) Marshal() (data []byte, err error) { +func (m *LeaseRevokeResponse) Marshal() (dAtA []byte, err error) { size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) if err != nil { return nil, err } - return data[:n], nil + return dAtA[:n], nil } -func (m *MemberAddRequest) MarshalTo(data []byte) (int, error) { - var i int - _ = i - var l int - _ = l - if len(m.PeerURLs) > 0 { - for _, s := range m.PeerURLs { - data[i] = 0xa - i++ - l = len(s) - for l >= 1<<7 { - data[i] = uint8(uint64(l)&0x7f | 0x80) - l >>= 7 - i++ - } - data[i] = uint8(l) - i++ - i += copy(data[i:], s) - } - } - return i, nil -} - -func (m *MemberAddResponse) Marshal() (data []byte, err error) { - size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) - if err != nil { - return nil, err - } - return data[:n], nil -} - -func (m *MemberAddResponse) MarshalTo(data []byte) (int, error) { +func (m *LeaseRevokeResponse) MarshalTo(dAtA []byte) (int, error) { var i int _ = i var l int _ = l if m.Header != nil { - data[i] = 0xa + dAtA[i] = 0xa i++ - i = encodeVarintRpc(data, i, uint64(m.Header.Size())) - n25, err := m.Header.MarshalTo(data[i:]) + i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size())) + n25, err := m.Header.MarshalTo(dAtA[i:]) if err != nil { return 0, err } i += n25 } - if m.Member != nil { - data[i] = 0x12 + return i, nil +} + +func (m *LeaseKeepAliveRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *LeaseKeepAliveRequest) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.ID != 0 { + dAtA[i] = 0x8 i++ - i = encodeVarintRpc(data, i, uint64(m.Member.Size())) - n26, err := m.Member.MarshalTo(data[i:]) + i = encodeVarintRpc(dAtA, i, uint64(m.ID)) + } + return i, nil +} + +func (m *LeaseKeepAliveResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *LeaseKeepAliveResponse) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Header != nil { + dAtA[i] = 0xa + i++ + i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size())) + n26, err := m.Header.MarshalTo(dAtA[i:]) if err != nil { return 0, err } i += n26 } + if m.ID != 0 { + dAtA[i] = 0x10 + i++ + i = encodeVarintRpc(dAtA, i, uint64(m.ID)) + } + if m.TTL != 0 { + dAtA[i] = 0x18 + i++ + i = encodeVarintRpc(dAtA, i, uint64(m.TTL)) + } return i, nil } -func (m *MemberRemoveRequest) Marshal() (data []byte, err error) { +func (m *LeaseTimeToLiveRequest) Marshal() (dAtA []byte, err error) { size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) if err != nil { return nil, err } - return data[:n], nil + return dAtA[:n], nil } -func (m *MemberRemoveRequest) MarshalTo(data []byte) (int, error) { +func (m *LeaseTimeToLiveRequest) MarshalTo(dAtA []byte) (int, error) { var i int _ = i var l int _ = l if m.ID != 0 { - data[i] = 0x8 + dAtA[i] = 0x8 + i++ + i = encodeVarintRpc(dAtA, i, uint64(m.ID)) + } + if m.Keys { + dAtA[i] = 0x10 + i++ + if m.Keys { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } i++ - i = encodeVarintRpc(data, i, uint64(m.ID)) } return i, nil } -func (m *MemberRemoveResponse) Marshal() (data []byte, err error) { +func (m *LeaseTimeToLiveResponse) Marshal() (dAtA []byte, err error) { size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) if err != nil { return nil, err } - return data[:n], nil + return dAtA[:n], nil } -func (m *MemberRemoveResponse) MarshalTo(data []byte) (int, error) { +func (m *LeaseTimeToLiveResponse) MarshalTo(dAtA []byte) (int, error) { var i int _ = i var l int _ = l if m.Header != nil { - data[i] = 0xa + dAtA[i] = 0xa i++ - i = encodeVarintRpc(data, i, uint64(m.Header.Size())) - n27, err := m.Header.MarshalTo(data[i:]) + i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size())) + n27, err := m.Header.MarshalTo(dAtA[i:]) if err != nil { return 0, err } i += n27 } + if m.ID != 0 { + dAtA[i] = 0x10 + i++ + i = encodeVarintRpc(dAtA, i, uint64(m.ID)) + } + if m.TTL != 0 { + dAtA[i] = 0x18 + i++ + i = encodeVarintRpc(dAtA, i, uint64(m.TTL)) + } + if m.GrantedTTL != 0 { + dAtA[i] = 0x20 + i++ + i = encodeVarintRpc(dAtA, i, uint64(m.GrantedTTL)) + } + if len(m.Keys) > 0 { + for _, b := range m.Keys { + dAtA[i] = 0x2a + i++ + i = encodeVarintRpc(dAtA, i, uint64(len(b))) + i += copy(dAtA[i:], b) + } + } return i, nil } -func (m *MemberUpdateRequest) Marshal() (data []byte, err error) { +func (m *Member) Marshal() (dAtA []byte, err error) { size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) if err != nil { return nil, err } - return data[:n], nil + return dAtA[:n], nil } -func (m *MemberUpdateRequest) MarshalTo(data []byte) (int, error) { +func (m *Member) MarshalTo(dAtA []byte) (int, error) { var i int _ = i var l int _ = l if m.ID != 0 { - data[i] = 0x8 + dAtA[i] = 0x8 i++ - i = encodeVarintRpc(data, i, uint64(m.ID)) + i = encodeVarintRpc(dAtA, i, uint64(m.ID)) + } + if len(m.Name) > 0 { + dAtA[i] = 0x12 + i++ + i = encodeVarintRpc(dAtA, i, uint64(len(m.Name))) + i += copy(dAtA[i:], m.Name) } if len(m.PeerURLs) > 0 { for _, s := range m.PeerURLs { - data[i] = 0x12 + dAtA[i] = 0x1a i++ l = len(s) for l >= 1<<7 { - data[i] = uint8(uint64(l)&0x7f | 0x80) + dAtA[i] = uint8(uint64(l)&0x7f | 0x80) l >>= 7 i++ } - data[i] = uint8(l) + dAtA[i] = uint8(l) i++ - i += copy(data[i:], s) + i += copy(dAtA[i:], s) + } + } + if len(m.ClientURLs) > 0 { + for _, s := range m.ClientURLs { + dAtA[i] = 0x22 + i++ + l = len(s) + for l >= 1<<7 { + dAtA[i] = uint8(uint64(l)&0x7f | 0x80) + l >>= 7 + i++ + } + dAtA[i] = uint8(l) + i++ + i += copy(dAtA[i:], s) } } return i, nil } -func (m *MemberUpdateResponse) Marshal() (data []byte, err error) { +func (m *MemberAddRequest) Marshal() (dAtA []byte, err error) { size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) if err != nil { return nil, err } - return data[:n], nil + return dAtA[:n], nil } -func (m *MemberUpdateResponse) MarshalTo(data []byte) (int, error) { +func (m *MemberAddRequest) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.PeerURLs) > 0 { + for _, s := range m.PeerURLs { + dAtA[i] = 0xa + i++ + l = len(s) + for l >= 1<<7 { + dAtA[i] = uint8(uint64(l)&0x7f | 0x80) + l >>= 7 + i++ + } + dAtA[i] = uint8(l) + i++ + i += copy(dAtA[i:], s) + } + } + return i, nil +} + +func (m *MemberAddResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MemberAddResponse) MarshalTo(dAtA []byte) (int, error) { var i int _ = i var l int _ = l if m.Header != nil { - data[i] = 0xa + dAtA[i] = 0xa i++ - i = encodeVarintRpc(data, i, uint64(m.Header.Size())) - n28, err := m.Header.MarshalTo(data[i:]) + i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size())) + n28, err := m.Header.MarshalTo(dAtA[i:]) if err != nil { return 0, err } i += n28 } - return i, nil -} - -func (m *MemberListRequest) Marshal() (data []byte, err error) { - size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) - if err != nil { - return nil, err - } - return data[:n], nil -} - -func (m *MemberListRequest) MarshalTo(data []byte) (int, error) { - var i int - _ = i - var l int - _ = l - return i, nil -} - -func (m *MemberListResponse) Marshal() (data []byte, err error) { - size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) - if err != nil { - return nil, err - } - return data[:n], nil -} - -func (m *MemberListResponse) MarshalTo(data []byte) (int, error) { - var i int - _ = i - var l int - _ = l - if m.Header != nil { - data[i] = 0xa + if m.Member != nil { + dAtA[i] = 0x12 i++ - i = encodeVarintRpc(data, i, uint64(m.Header.Size())) - n29, err := m.Header.MarshalTo(data[i:]) + i = encodeVarintRpc(dAtA, i, uint64(m.Member.Size())) + n29, err := m.Member.MarshalTo(dAtA[i:]) if err != nil { return 0, err } i += n29 } - if len(m.Members) > 0 { - for _, msg := range m.Members { - data[i] = 0x12 - 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 } -func (m *DefragmentRequest) Marshal() (data []byte, err error) { +func (m *MemberRemoveRequest) Marshal() (dAtA []byte, err error) { size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) if err != nil { return nil, err } - return data[:n], nil + return dAtA[:n], nil } -func (m *DefragmentRequest) MarshalTo(data []byte) (int, error) { +func (m *MemberRemoveRequest) MarshalTo(dAtA []byte) (int, error) { var i int _ = i var l int _ = l + if m.ID != 0 { + dAtA[i] = 0x8 + i++ + i = encodeVarintRpc(dAtA, i, uint64(m.ID)) + } return i, nil } -func (m *DefragmentResponse) Marshal() (data []byte, err error) { +func (m *MemberRemoveResponse) Marshal() (dAtA []byte, err error) { size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) if err != nil { return nil, err } - return data[:n], nil + return dAtA[:n], nil } -func (m *DefragmentResponse) MarshalTo(data []byte) (int, error) { +func (m *MemberRemoveResponse) MarshalTo(dAtA []byte) (int, error) { var i int _ = i var l int _ = l if m.Header != nil { - data[i] = 0xa + dAtA[i] = 0xa i++ - i = encodeVarintRpc(data, i, uint64(m.Header.Size())) - n30, err := m.Header.MarshalTo(data[i:]) + i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size())) + n30, err := m.Header.MarshalTo(dAtA[i:]) if err != nil { return 0, err } @@ -5142,98 +5213,121 @@ func (m *DefragmentResponse) MarshalTo(data []byte) (int, error) { return i, nil } -func (m *AlarmRequest) Marshal() (data []byte, err error) { +func (m *MemberUpdateRequest) Marshal() (dAtA []byte, err error) { size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) if err != nil { return nil, err } - return data[:n], nil + return dAtA[:n], nil } -func (m *AlarmRequest) MarshalTo(data []byte) (int, error) { +func (m *MemberUpdateRequest) MarshalTo(dAtA []byte) (int, error) { var i int _ = i var l int _ = l - if m.Action != 0 { - data[i] = 0x8 + if m.ID != 0 { + dAtA[i] = 0x8 i++ - i = encodeVarintRpc(data, i, uint64(m.Action)) + i = encodeVarintRpc(dAtA, i, uint64(m.ID)) } - if m.MemberID != 0 { - data[i] = 0x10 - i++ - i = encodeVarintRpc(data, i, uint64(m.MemberID)) - } - if m.Alarm != 0 { - data[i] = 0x18 - i++ - i = encodeVarintRpc(data, i, uint64(m.Alarm)) + if len(m.PeerURLs) > 0 { + for _, s := range m.PeerURLs { + dAtA[i] = 0x12 + i++ + l = len(s) + for l >= 1<<7 { + dAtA[i] = uint8(uint64(l)&0x7f | 0x80) + l >>= 7 + i++ + } + dAtA[i] = uint8(l) + i++ + i += copy(dAtA[i:], s) + } } return i, nil } -func (m *AlarmMember) Marshal() (data []byte, err error) { +func (m *MemberUpdateResponse) Marshal() (dAtA []byte, err error) { size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) if err != nil { return nil, err } - return data[:n], nil + return dAtA[:n], nil } -func (m *AlarmMember) MarshalTo(data []byte) (int, error) { - var i int - _ = i - var l int - _ = l - if m.MemberID != 0 { - data[i] = 0x8 - i++ - i = encodeVarintRpc(data, i, uint64(m.MemberID)) - } - if m.Alarm != 0 { - data[i] = 0x10 - i++ - i = encodeVarintRpc(data, i, uint64(m.Alarm)) - } - return i, nil -} - -func (m *AlarmResponse) Marshal() (data []byte, err error) { - size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) - if err != nil { - return nil, err - } - return data[:n], nil -} - -func (m *AlarmResponse) MarshalTo(data []byte) (int, error) { +func (m *MemberUpdateResponse) MarshalTo(dAtA []byte) (int, error) { var i int _ = i var l int _ = l if m.Header != nil { - data[i] = 0xa + dAtA[i] = 0xa i++ - i = encodeVarintRpc(data, i, uint64(m.Header.Size())) - n31, err := m.Header.MarshalTo(data[i:]) + i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size())) + n31, err := m.Header.MarshalTo(dAtA[i:]) if err != nil { return 0, err } i += n31 } - if len(m.Alarms) > 0 { - for _, msg := range m.Alarms { - data[i] = 0x12 + return i, nil +} + +func (m *MemberListRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MemberListRequest) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + return i, nil +} + +func (m *MemberListResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MemberListResponse) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Header != nil { + dAtA[i] = 0xa + i++ + i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size())) + n32, err := m.Header.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n32 + } + if len(m.Members) > 0 { + for _, msg := range m.Members { + dAtA[i] = 0x12 i++ - i = encodeVarintRpc(data, i, uint64(msg.Size())) - n, err := msg.MarshalTo(data[i:]) + i = encodeVarintRpc(dAtA, i, uint64(msg.Size())) + n, err := msg.MarshalTo(dAtA[i:]) if err != nil { return 0, err } @@ -5243,17 +5337,17 @@ func (m *AlarmResponse) MarshalTo(data []byte) (int, error) { return i, nil } -func (m *StatusRequest) Marshal() (data []byte, err error) { +func (m *DefragmentRequest) Marshal() (dAtA []byte, err error) { size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) if err != nil { return nil, err } - return data[:n], nil + return dAtA[:n], nil } -func (m *StatusRequest) MarshalTo(data []byte) (int, error) { +func (m *DefragmentRequest) MarshalTo(dAtA []byte) (int, error) { var i int _ = i var l int @@ -5261,428 +5355,26 @@ func (m *StatusRequest) MarshalTo(data []byte) (int, error) { return i, nil } -func (m *StatusResponse) Marshal() (data []byte, err error) { +func (m *DefragmentResponse) Marshal() (dAtA []byte, err error) { size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) if err != nil { return nil, err } - return data[:n], nil + return dAtA[:n], nil } -func (m *StatusResponse) MarshalTo(data []byte) (int, error) { +func (m *DefragmentResponse) MarshalTo(dAtA []byte) (int, error) { var i int _ = i var l int _ = l if m.Header != nil { - data[i] = 0xa + dAtA[i] = 0xa i++ - i = encodeVarintRpc(data, i, uint64(m.Header.Size())) - n32, err := m.Header.MarshalTo(data[i:]) - if err != nil { - return 0, err - } - i += n32 - } - if len(m.Version) > 0 { - data[i] = 0x12 - i++ - i = encodeVarintRpc(data, i, uint64(len(m.Version))) - i += copy(data[i:], m.Version) - } - if m.DbSize != 0 { - data[i] = 0x18 - i++ - i = encodeVarintRpc(data, i, uint64(m.DbSize)) - } - if m.Leader != 0 { - data[i] = 0x20 - i++ - i = encodeVarintRpc(data, i, uint64(m.Leader)) - } - if m.RaftIndex != 0 { - data[i] = 0x28 - i++ - i = encodeVarintRpc(data, i, uint64(m.RaftIndex)) - } - if m.RaftTerm != 0 { - data[i] = 0x30 - i++ - i = encodeVarintRpc(data, i, uint64(m.RaftTerm)) - } - return i, nil -} - -func (m *AuthEnableRequest) Marshal() (data []byte, err error) { - size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) - if err != nil { - return nil, err - } - return data[:n], nil -} - -func (m *AuthEnableRequest) MarshalTo(data []byte) (int, error) { - var i int - _ = i - var l int - _ = l - return i, nil -} - -func (m *AuthDisableRequest) Marshal() (data []byte, err error) { - size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) - if err != nil { - return nil, err - } - return data[:n], nil -} - -func (m *AuthDisableRequest) MarshalTo(data []byte) (int, error) { - var i int - _ = i - var l int - _ = l - return i, nil -} - -func (m *AuthenticateRequest) Marshal() (data []byte, err error) { - size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) - if err != nil { - return nil, err - } - return data[:n], nil -} - -func (m *AuthenticateRequest) MarshalTo(data []byte) (int, error) { - var i int - _ = i - var l int - _ = l - if len(m.Name) > 0 { - data[i] = 0xa - i++ - i = encodeVarintRpc(data, i, uint64(len(m.Name))) - i += copy(data[i:], m.Name) - } - if len(m.Password) > 0 { - data[i] = 0x12 - i++ - i = encodeVarintRpc(data, i, uint64(len(m.Password))) - i += copy(data[i:], m.Password) - } - return i, nil -} - -func (m *AuthUserAddRequest) Marshal() (data []byte, err error) { - size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) - if err != nil { - return nil, err - } - return data[:n], nil -} - -func (m *AuthUserAddRequest) MarshalTo(data []byte) (int, error) { - var i int - _ = i - var l int - _ = l - if len(m.Name) > 0 { - data[i] = 0xa - i++ - i = encodeVarintRpc(data, i, uint64(len(m.Name))) - i += copy(data[i:], m.Name) - } - if len(m.Password) > 0 { - data[i] = 0x12 - i++ - i = encodeVarintRpc(data, i, uint64(len(m.Password))) - i += copy(data[i:], m.Password) - } - return i, nil -} - -func (m *AuthUserGetRequest) Marshal() (data []byte, err error) { - size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) - if err != nil { - return nil, err - } - return data[:n], nil -} - -func (m *AuthUserGetRequest) MarshalTo(data []byte) (int, error) { - var i int - _ = i - var l int - _ = l - if len(m.Name) > 0 { - data[i] = 0xa - i++ - i = encodeVarintRpc(data, i, uint64(len(m.Name))) - i += copy(data[i:], m.Name) - } - return i, nil -} - -func (m *AuthUserDeleteRequest) Marshal() (data []byte, err error) { - size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) - if err != nil { - return nil, err - } - return data[:n], nil -} - -func (m *AuthUserDeleteRequest) MarshalTo(data []byte) (int, error) { - var i int - _ = i - var l int - _ = l - if len(m.Name) > 0 { - data[i] = 0xa - i++ - i = encodeVarintRpc(data, i, uint64(len(m.Name))) - i += copy(data[i:], m.Name) - } - return i, nil -} - -func (m *AuthUserChangePasswordRequest) Marshal() (data []byte, err error) { - size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) - if err != nil { - return nil, err - } - return data[:n], nil -} - -func (m *AuthUserChangePasswordRequest) MarshalTo(data []byte) (int, error) { - var i int - _ = i - var l int - _ = l - if len(m.Name) > 0 { - data[i] = 0xa - i++ - i = encodeVarintRpc(data, i, uint64(len(m.Name))) - i += copy(data[i:], m.Name) - } - if len(m.Password) > 0 { - data[i] = 0x12 - i++ - i = encodeVarintRpc(data, i, uint64(len(m.Password))) - i += copy(data[i:], m.Password) - } - return i, nil -} - -func (m *AuthUserGrantRoleRequest) Marshal() (data []byte, err error) { - size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) - if err != nil { - return nil, err - } - return data[:n], nil -} - -func (m *AuthUserGrantRoleRequest) MarshalTo(data []byte) (int, error) { - var i int - _ = i - var l int - _ = l - if len(m.User) > 0 { - data[i] = 0xa - i++ - i = encodeVarintRpc(data, i, uint64(len(m.User))) - i += copy(data[i:], m.User) - } - if len(m.Role) > 0 { - data[i] = 0x12 - i++ - i = encodeVarintRpc(data, i, uint64(len(m.Role))) - i += copy(data[i:], m.Role) - } - return i, nil -} - -func (m *AuthUserRevokeRoleRequest) Marshal() (data []byte, err error) { - size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) - if err != nil { - return nil, err - } - return data[:n], nil -} - -func (m *AuthUserRevokeRoleRequest) MarshalTo(data []byte) (int, error) { - var i int - _ = i - var l int - _ = l - if len(m.Name) > 0 { - data[i] = 0xa - i++ - i = encodeVarintRpc(data, i, uint64(len(m.Name))) - i += copy(data[i:], m.Name) - } - if len(m.Role) > 0 { - data[i] = 0x12 - i++ - i = encodeVarintRpc(data, i, uint64(len(m.Role))) - i += copy(data[i:], m.Role) - } - return i, nil -} - -func (m *AuthRoleAddRequest) Marshal() (data []byte, err error) { - size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) - if err != nil { - return nil, err - } - return data[:n], nil -} - -func (m *AuthRoleAddRequest) MarshalTo(data []byte) (int, error) { - var i int - _ = i - var l int - _ = l - if len(m.Name) > 0 { - data[i] = 0xa - i++ - i = encodeVarintRpc(data, i, uint64(len(m.Name))) - i += copy(data[i:], m.Name) - } - return i, nil -} - -func (m *AuthRoleGetRequest) Marshal() (data []byte, err error) { - size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) - if err != nil { - return nil, err - } - return data[:n], nil -} - -func (m *AuthRoleGetRequest) MarshalTo(data []byte) (int, error) { - var i int - _ = i - var l int - _ = l - if len(m.Role) > 0 { - data[i] = 0xa - i++ - i = encodeVarintRpc(data, i, uint64(len(m.Role))) - i += copy(data[i:], m.Role) - } - return i, nil -} - -func (m *AuthUserListRequest) Marshal() (data []byte, err error) { - size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) - if err != nil { - return nil, err - } - return data[:n], nil -} - -func (m *AuthUserListRequest) MarshalTo(data []byte) (int, error) { - var i int - _ = i - var l int - _ = l - return i, nil -} - -func (m *AuthRoleListRequest) Marshal() (data []byte, err error) { - size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) - if err != nil { - return nil, err - } - return data[:n], nil -} - -func (m *AuthRoleListRequest) MarshalTo(data []byte) (int, error) { - var i int - _ = i - var l int - _ = l - return i, nil -} - -func (m *AuthRoleDeleteRequest) Marshal() (data []byte, err error) { - size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) - if err != nil { - return nil, err - } - return data[:n], nil -} - -func (m *AuthRoleDeleteRequest) MarshalTo(data []byte) (int, error) { - var i int - _ = i - var l int - _ = l - if len(m.Role) > 0 { - data[i] = 0xa - i++ - i = encodeVarintRpc(data, i, uint64(len(m.Role))) - i += copy(data[i:], m.Role) - } - return i, nil -} - -func (m *AuthRoleGrantPermissionRequest) Marshal() (data []byte, err error) { - size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) - if err != nil { - return nil, err - } - return data[:n], nil -} - -func (m *AuthRoleGrantPermissionRequest) MarshalTo(data []byte) (int, error) { - var i int - _ = i - var l int - _ = l - if len(m.Name) > 0 { - data[i] = 0xa - i++ - i = encodeVarintRpc(data, i, uint64(len(m.Name))) - i += copy(data[i:], m.Name) - } - if m.Perm != nil { - data[i] = 0x12 - i++ - i = encodeVarintRpc(data, i, uint64(m.Perm.Size())) - n33, err := m.Perm.MarshalTo(data[i:]) + i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size())) + n33, err := m.Header.MarshalTo(dAtA[i:]) if err != nil { return 0, err } @@ -5691,374 +5383,98 @@ func (m *AuthRoleGrantPermissionRequest) MarshalTo(data []byte) (int, error) { return i, nil } -func (m *AuthRoleRevokePermissionRequest) Marshal() (data []byte, err error) { +func (m *AlarmRequest) Marshal() (dAtA []byte, err error) { size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) if err != nil { return nil, err } - return data[:n], nil + return dAtA[:n], nil } -func (m *AuthRoleRevokePermissionRequest) MarshalTo(data []byte) (int, error) { +func (m *AlarmRequest) MarshalTo(dAtA []byte) (int, error) { var i int _ = i var l int _ = l - if len(m.Role) > 0 { - data[i] = 0xa + if m.Action != 0 { + dAtA[i] = 0x8 i++ - i = encodeVarintRpc(data, i, uint64(len(m.Role))) - i += copy(data[i:], m.Role) + i = encodeVarintRpc(dAtA, i, uint64(m.Action)) } - if len(m.Key) > 0 { - data[i] = 0x12 + if m.MemberID != 0 { + dAtA[i] = 0x10 i++ - i = encodeVarintRpc(data, i, uint64(len(m.Key))) - i += copy(data[i:], m.Key) + i = encodeVarintRpc(dAtA, i, uint64(m.MemberID)) } - if len(m.RangeEnd) > 0 { - data[i] = 0x1a + if m.Alarm != 0 { + dAtA[i] = 0x18 i++ - i = encodeVarintRpc(data, i, uint64(len(m.RangeEnd))) - i += copy(data[i:], m.RangeEnd) + i = encodeVarintRpc(dAtA, i, uint64(m.Alarm)) } return i, nil } -func (m *AuthEnableResponse) Marshal() (data []byte, err error) { +func (m *AlarmMember) Marshal() (dAtA []byte, err error) { size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) if err != nil { return nil, err } - return data[:n], nil + return dAtA[:n], nil } -func (m *AuthEnableResponse) MarshalTo(data []byte) (int, error) { +func (m *AlarmMember) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.MemberID != 0 { + dAtA[i] = 0x8 + i++ + i = encodeVarintRpc(dAtA, i, uint64(m.MemberID)) + } + if m.Alarm != 0 { + dAtA[i] = 0x10 + i++ + i = encodeVarintRpc(dAtA, i, uint64(m.Alarm)) + } + return i, nil +} + +func (m *AlarmResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *AlarmResponse) MarshalTo(dAtA []byte) (int, error) { var i int _ = i var l int _ = l if m.Header != nil { - data[i] = 0xa + dAtA[i] = 0xa i++ - i = encodeVarintRpc(data, i, uint64(m.Header.Size())) - n34, err := m.Header.MarshalTo(data[i:]) + i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size())) + n34, err := m.Header.MarshalTo(dAtA[i:]) if err != nil { return 0, err } i += n34 } - return i, nil -} - -func (m *AuthDisableResponse) Marshal() (data []byte, err error) { - size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) - if err != nil { - return nil, err - } - return data[:n], nil -} - -func (m *AuthDisableResponse) MarshalTo(data []byte) (int, error) { - var i int - _ = i - var l int - _ = l - if m.Header != nil { - data[i] = 0xa - i++ - i = encodeVarintRpc(data, i, uint64(m.Header.Size())) - n35, err := m.Header.MarshalTo(data[i:]) - if err != nil { - return 0, err - } - i += n35 - } - return i, nil -} - -func (m *AuthenticateResponse) Marshal() (data []byte, err error) { - size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) - if err != nil { - return nil, err - } - return data[:n], nil -} - -func (m *AuthenticateResponse) MarshalTo(data []byte) (int, error) { - var i int - _ = i - var l int - _ = l - if m.Header != nil { - data[i] = 0xa - i++ - i = encodeVarintRpc(data, i, uint64(m.Header.Size())) - n36, err := m.Header.MarshalTo(data[i:]) - if err != nil { - return 0, err - } - i += n36 - } - if len(m.Token) > 0 { - data[i] = 0x12 - i++ - i = encodeVarintRpc(data, i, uint64(len(m.Token))) - i += copy(data[i:], m.Token) - } - return i, nil -} - -func (m *AuthUserAddResponse) Marshal() (data []byte, err error) { - size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) - if err != nil { - return nil, err - } - return data[:n], nil -} - -func (m *AuthUserAddResponse) MarshalTo(data []byte) (int, error) { - var i int - _ = i - var l int - _ = l - if m.Header != nil { - data[i] = 0xa - i++ - i = encodeVarintRpc(data, i, uint64(m.Header.Size())) - n37, err := m.Header.MarshalTo(data[i:]) - if err != nil { - return 0, err - } - i += n37 - } - return i, nil -} - -func (m *AuthUserGetResponse) Marshal() (data []byte, err error) { - size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) - if err != nil { - return nil, err - } - return data[:n], nil -} - -func (m *AuthUserGetResponse) MarshalTo(data []byte) (int, error) { - var i int - _ = i - var l int - _ = l - if m.Header != nil { - data[i] = 0xa - i++ - i = encodeVarintRpc(data, i, uint64(m.Header.Size())) - n38, err := m.Header.MarshalTo(data[i:]) - if err != nil { - return 0, err - } - i += n38 - } - if len(m.Roles) > 0 { - for _, s := range m.Roles { - data[i] = 0x12 + if len(m.Alarms) > 0 { + for _, msg := range m.Alarms { + dAtA[i] = 0x12 i++ - l = len(s) - for l >= 1<<7 { - data[i] = uint8(uint64(l)&0x7f | 0x80) - l >>= 7 - i++ - } - data[i] = uint8(l) - i++ - i += copy(data[i:], s) - } - } - return i, nil -} - -func (m *AuthUserDeleteResponse) Marshal() (data []byte, err error) { - size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) - if err != nil { - return nil, err - } - return data[:n], nil -} - -func (m *AuthUserDeleteResponse) MarshalTo(data []byte) (int, error) { - var i int - _ = i - var l int - _ = l - if m.Header != nil { - data[i] = 0xa - i++ - i = encodeVarintRpc(data, i, uint64(m.Header.Size())) - n39, err := m.Header.MarshalTo(data[i:]) - if err != nil { - return 0, err - } - i += n39 - } - return i, nil -} - -func (m *AuthUserChangePasswordResponse) Marshal() (data []byte, err error) { - size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) - if err != nil { - return nil, err - } - return data[:n], nil -} - -func (m *AuthUserChangePasswordResponse) MarshalTo(data []byte) (int, error) { - var i int - _ = i - var l int - _ = l - if m.Header != nil { - data[i] = 0xa - i++ - i = encodeVarintRpc(data, i, uint64(m.Header.Size())) - n40, err := m.Header.MarshalTo(data[i:]) - if err != nil { - return 0, err - } - i += n40 - } - return i, nil -} - -func (m *AuthUserGrantRoleResponse) Marshal() (data []byte, err error) { - size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) - if err != nil { - return nil, err - } - return data[:n], nil -} - -func (m *AuthUserGrantRoleResponse) MarshalTo(data []byte) (int, error) { - var i int - _ = i - var l int - _ = l - if m.Header != nil { - data[i] = 0xa - i++ - i = encodeVarintRpc(data, i, uint64(m.Header.Size())) - n41, err := m.Header.MarshalTo(data[i:]) - if err != nil { - return 0, err - } - i += n41 - } - return i, nil -} - -func (m *AuthUserRevokeRoleResponse) Marshal() (data []byte, err error) { - size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) - if err != nil { - return nil, err - } - return data[:n], nil -} - -func (m *AuthUserRevokeRoleResponse) MarshalTo(data []byte) (int, error) { - var i int - _ = i - var l int - _ = l - if m.Header != nil { - data[i] = 0xa - i++ - i = encodeVarintRpc(data, i, uint64(m.Header.Size())) - n42, err := m.Header.MarshalTo(data[i:]) - if err != nil { - return 0, err - } - i += n42 - } - return i, nil -} - -func (m *AuthRoleAddResponse) Marshal() (data []byte, err error) { - size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) - if err != nil { - return nil, err - } - return data[:n], nil -} - -func (m *AuthRoleAddResponse) MarshalTo(data []byte) (int, error) { - var i int - _ = i - var l int - _ = l - if m.Header != nil { - data[i] = 0xa - i++ - i = encodeVarintRpc(data, i, uint64(m.Header.Size())) - n43, err := m.Header.MarshalTo(data[i:]) - if err != nil { - return 0, err - } - i += n43 - } - return i, nil -} - -func (m *AuthRoleGetResponse) Marshal() (data []byte, err error) { - size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) - if err != nil { - return nil, err - } - return data[:n], nil -} - -func (m *AuthRoleGetResponse) MarshalTo(data []byte) (int, error) { - var i int - _ = i - var l int - _ = l - if m.Header != nil { - data[i] = 0xa - i++ - i = encodeVarintRpc(data, i, uint64(m.Header.Size())) - n44, err := m.Header.MarshalTo(data[i:]) - if err != nil { - return 0, err - } - i += n44 - } - if len(m.Perm) > 0 { - for _, msg := range m.Perm { - data[i] = 0x12 - i++ - i = encodeVarintRpc(data, i, uint64(msg.Size())) - n, err := msg.MarshalTo(data[i:]) + i = encodeVarintRpc(dAtA, i, uint64(msg.Size())) + n, err := msg.MarshalTo(dAtA[i:]) if err != nil { return 0, err } @@ -6068,201 +5484,1026 @@ func (m *AuthRoleGetResponse) MarshalTo(data []byte) (int, error) { return i, nil } -func (m *AuthRoleListResponse) Marshal() (data []byte, err error) { +func (m *StatusRequest) Marshal() (dAtA []byte, err error) { size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) if err != nil { return nil, err } - return data[:n], nil + return dAtA[:n], nil } -func (m *AuthRoleListResponse) MarshalTo(data []byte) (int, error) { +func (m *StatusRequest) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + return i, nil +} + +func (m *StatusResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *StatusResponse) MarshalTo(dAtA []byte) (int, error) { var i int _ = i var l int _ = l if m.Header != nil { - data[i] = 0xa + dAtA[i] = 0xa i++ - i = encodeVarintRpc(data, i, uint64(m.Header.Size())) - n45, err := m.Header.MarshalTo(data[i:]) + i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size())) + n35, err := m.Header.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n35 + } + if len(m.Version) > 0 { + dAtA[i] = 0x12 + i++ + i = encodeVarintRpc(dAtA, i, uint64(len(m.Version))) + i += copy(dAtA[i:], m.Version) + } + if m.DbSize != 0 { + dAtA[i] = 0x18 + i++ + i = encodeVarintRpc(dAtA, i, uint64(m.DbSize)) + } + if m.Leader != 0 { + dAtA[i] = 0x20 + i++ + i = encodeVarintRpc(dAtA, i, uint64(m.Leader)) + } + if m.RaftIndex != 0 { + dAtA[i] = 0x28 + i++ + i = encodeVarintRpc(dAtA, i, uint64(m.RaftIndex)) + } + if m.RaftTerm != 0 { + dAtA[i] = 0x30 + i++ + i = encodeVarintRpc(dAtA, i, uint64(m.RaftTerm)) + } + return i, nil +} + +func (m *AuthEnableRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *AuthEnableRequest) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + return i, nil +} + +func (m *AuthDisableRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *AuthDisableRequest) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + return i, nil +} + +func (m *AuthenticateRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *AuthenticateRequest) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Name) > 0 { + dAtA[i] = 0xa + i++ + i = encodeVarintRpc(dAtA, i, uint64(len(m.Name))) + i += copy(dAtA[i:], m.Name) + } + if len(m.Password) > 0 { + dAtA[i] = 0x12 + i++ + i = encodeVarintRpc(dAtA, i, uint64(len(m.Password))) + i += copy(dAtA[i:], m.Password) + } + return i, nil +} + +func (m *AuthUserAddRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *AuthUserAddRequest) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Name) > 0 { + dAtA[i] = 0xa + i++ + i = encodeVarintRpc(dAtA, i, uint64(len(m.Name))) + i += copy(dAtA[i:], m.Name) + } + if len(m.Password) > 0 { + dAtA[i] = 0x12 + i++ + i = encodeVarintRpc(dAtA, i, uint64(len(m.Password))) + i += copy(dAtA[i:], m.Password) + } + return i, nil +} + +func (m *AuthUserGetRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *AuthUserGetRequest) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Name) > 0 { + dAtA[i] = 0xa + i++ + i = encodeVarintRpc(dAtA, i, uint64(len(m.Name))) + i += copy(dAtA[i:], m.Name) + } + return i, nil +} + +func (m *AuthUserDeleteRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *AuthUserDeleteRequest) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Name) > 0 { + dAtA[i] = 0xa + i++ + i = encodeVarintRpc(dAtA, i, uint64(len(m.Name))) + i += copy(dAtA[i:], m.Name) + } + return i, nil +} + +func (m *AuthUserChangePasswordRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *AuthUserChangePasswordRequest) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Name) > 0 { + dAtA[i] = 0xa + i++ + i = encodeVarintRpc(dAtA, i, uint64(len(m.Name))) + i += copy(dAtA[i:], m.Name) + } + if len(m.Password) > 0 { + dAtA[i] = 0x12 + i++ + i = encodeVarintRpc(dAtA, i, uint64(len(m.Password))) + i += copy(dAtA[i:], m.Password) + } + return i, nil +} + +func (m *AuthUserGrantRoleRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *AuthUserGrantRoleRequest) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.User) > 0 { + dAtA[i] = 0xa + i++ + i = encodeVarintRpc(dAtA, i, uint64(len(m.User))) + i += copy(dAtA[i:], m.User) + } + if len(m.Role) > 0 { + dAtA[i] = 0x12 + i++ + i = encodeVarintRpc(dAtA, i, uint64(len(m.Role))) + i += copy(dAtA[i:], m.Role) + } + return i, nil +} + +func (m *AuthUserRevokeRoleRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *AuthUserRevokeRoleRequest) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Name) > 0 { + dAtA[i] = 0xa + i++ + i = encodeVarintRpc(dAtA, i, uint64(len(m.Name))) + i += copy(dAtA[i:], m.Name) + } + if len(m.Role) > 0 { + dAtA[i] = 0x12 + i++ + i = encodeVarintRpc(dAtA, i, uint64(len(m.Role))) + i += copy(dAtA[i:], m.Role) + } + return i, nil +} + +func (m *AuthRoleAddRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *AuthRoleAddRequest) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Name) > 0 { + dAtA[i] = 0xa + i++ + i = encodeVarintRpc(dAtA, i, uint64(len(m.Name))) + i += copy(dAtA[i:], m.Name) + } + return i, nil +} + +func (m *AuthRoleGetRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *AuthRoleGetRequest) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Role) > 0 { + dAtA[i] = 0xa + i++ + i = encodeVarintRpc(dAtA, i, uint64(len(m.Role))) + i += copy(dAtA[i:], m.Role) + } + return i, nil +} + +func (m *AuthUserListRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *AuthUserListRequest) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + return i, nil +} + +func (m *AuthRoleListRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *AuthRoleListRequest) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + return i, nil +} + +func (m *AuthRoleDeleteRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *AuthRoleDeleteRequest) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Role) > 0 { + dAtA[i] = 0xa + i++ + i = encodeVarintRpc(dAtA, i, uint64(len(m.Role))) + i += copy(dAtA[i:], m.Role) + } + return i, nil +} + +func (m *AuthRoleGrantPermissionRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *AuthRoleGrantPermissionRequest) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Name) > 0 { + dAtA[i] = 0xa + i++ + i = encodeVarintRpc(dAtA, i, uint64(len(m.Name))) + i += copy(dAtA[i:], m.Name) + } + if m.Perm != nil { + dAtA[i] = 0x12 + i++ + i = encodeVarintRpc(dAtA, i, uint64(m.Perm.Size())) + n36, err := m.Perm.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n36 + } + return i, nil +} + +func (m *AuthRoleRevokePermissionRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *AuthRoleRevokePermissionRequest) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Role) > 0 { + dAtA[i] = 0xa + i++ + i = encodeVarintRpc(dAtA, i, uint64(len(m.Role))) + i += copy(dAtA[i:], m.Role) + } + if len(m.Key) > 0 { + dAtA[i] = 0x12 + i++ + i = encodeVarintRpc(dAtA, i, uint64(len(m.Key))) + i += copy(dAtA[i:], m.Key) + } + if len(m.RangeEnd) > 0 { + dAtA[i] = 0x1a + i++ + i = encodeVarintRpc(dAtA, i, uint64(len(m.RangeEnd))) + i += copy(dAtA[i:], m.RangeEnd) + } + return i, nil +} + +func (m *AuthEnableResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *AuthEnableResponse) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Header != nil { + dAtA[i] = 0xa + i++ + i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size())) + n37, err := m.Header.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n37 + } + return i, nil +} + +func (m *AuthDisableResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *AuthDisableResponse) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Header != nil { + dAtA[i] = 0xa + i++ + i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size())) + n38, err := m.Header.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n38 + } + return i, nil +} + +func (m *AuthenticateResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *AuthenticateResponse) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Header != nil { + dAtA[i] = 0xa + i++ + i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size())) + n39, err := m.Header.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n39 + } + if len(m.Token) > 0 { + dAtA[i] = 0x12 + i++ + i = encodeVarintRpc(dAtA, i, uint64(len(m.Token))) + i += copy(dAtA[i:], m.Token) + } + return i, nil +} + +func (m *AuthUserAddResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *AuthUserAddResponse) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Header != nil { + dAtA[i] = 0xa + i++ + i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size())) + n40, err := m.Header.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n40 + } + return i, nil +} + +func (m *AuthUserGetResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *AuthUserGetResponse) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Header != nil { + dAtA[i] = 0xa + i++ + i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size())) + n41, err := m.Header.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n41 + } + if len(m.Roles) > 0 { + for _, s := range m.Roles { + dAtA[i] = 0x12 + i++ + l = len(s) + for l >= 1<<7 { + dAtA[i] = uint8(uint64(l)&0x7f | 0x80) + l >>= 7 + i++ + } + dAtA[i] = uint8(l) + i++ + i += copy(dAtA[i:], s) + } + } + return i, nil +} + +func (m *AuthUserDeleteResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *AuthUserDeleteResponse) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Header != nil { + dAtA[i] = 0xa + i++ + i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size())) + n42, err := m.Header.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n42 + } + return i, nil +} + +func (m *AuthUserChangePasswordResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *AuthUserChangePasswordResponse) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Header != nil { + dAtA[i] = 0xa + i++ + i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size())) + n43, err := m.Header.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n43 + } + return i, nil +} + +func (m *AuthUserGrantRoleResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *AuthUserGrantRoleResponse) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Header != nil { + dAtA[i] = 0xa + i++ + i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size())) + n44, err := m.Header.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n44 + } + return i, nil +} + +func (m *AuthUserRevokeRoleResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *AuthUserRevokeRoleResponse) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Header != nil { + dAtA[i] = 0xa + i++ + i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size())) + n45, err := m.Header.MarshalTo(dAtA[i:]) if err != nil { return 0, err } i += n45 } - if len(m.Roles) > 0 { - for _, s := range m.Roles { - data[i] = 0x12 - i++ - l = len(s) - for l >= 1<<7 { - data[i] = uint8(uint64(l)&0x7f | 0x80) - l >>= 7 - i++ - } - data[i] = uint8(l) - i++ - i += copy(data[i:], s) - } - } return i, nil } -func (m *AuthUserListResponse) Marshal() (data []byte, err error) { +func (m *AuthRoleAddResponse) Marshal() (dAtA []byte, err error) { size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) if err != nil { return nil, err } - return data[:n], nil + return dAtA[:n], nil } -func (m *AuthUserListResponse) MarshalTo(data []byte) (int, error) { +func (m *AuthRoleAddResponse) MarshalTo(dAtA []byte) (int, error) { var i int _ = i var l int _ = l if m.Header != nil { - data[i] = 0xa + dAtA[i] = 0xa i++ - i = encodeVarintRpc(data, i, uint64(m.Header.Size())) - n46, err := m.Header.MarshalTo(data[i:]) + i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size())) + n46, err := m.Header.MarshalTo(dAtA[i:]) if err != nil { return 0, err } i += n46 } - if len(m.Users) > 0 { - for _, s := range m.Users { - data[i] = 0x12 - i++ - l = len(s) - for l >= 1<<7 { - data[i] = uint8(uint64(l)&0x7f | 0x80) - l >>= 7 - i++ - } - data[i] = uint8(l) - i++ - i += copy(data[i:], s) - } - } return i, nil } -func (m *AuthRoleDeleteResponse) Marshal() (data []byte, err error) { +func (m *AuthRoleGetResponse) Marshal() (dAtA []byte, err error) { size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) if err != nil { return nil, err } - return data[:n], nil + return dAtA[:n], nil } -func (m *AuthRoleDeleteResponse) MarshalTo(data []byte) (int, error) { +func (m *AuthRoleGetResponse) MarshalTo(dAtA []byte) (int, error) { var i int _ = i var l int _ = l if m.Header != nil { - data[i] = 0xa + dAtA[i] = 0xa i++ - i = encodeVarintRpc(data, i, uint64(m.Header.Size())) - n47, err := m.Header.MarshalTo(data[i:]) + i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size())) + n47, err := m.Header.MarshalTo(dAtA[i:]) if err != nil { return 0, err } i += n47 } + if len(m.Perm) > 0 { + for _, msg := range m.Perm { + dAtA[i] = 0x12 + 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 } -func (m *AuthRoleGrantPermissionResponse) Marshal() (data []byte, err error) { +func (m *AuthRoleListResponse) Marshal() (dAtA []byte, err error) { size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) if err != nil { return nil, err } - return data[:n], nil + return dAtA[:n], nil } -func (m *AuthRoleGrantPermissionResponse) MarshalTo(data []byte) (int, error) { +func (m *AuthRoleListResponse) MarshalTo(dAtA []byte) (int, error) { var i int _ = i var l int _ = l if m.Header != nil { - data[i] = 0xa + dAtA[i] = 0xa i++ - i = encodeVarintRpc(data, i, uint64(m.Header.Size())) - n48, err := m.Header.MarshalTo(data[i:]) + i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size())) + n48, err := m.Header.MarshalTo(dAtA[i:]) if err != nil { return 0, err } i += n48 } + if len(m.Roles) > 0 { + for _, s := range m.Roles { + dAtA[i] = 0x12 + i++ + l = len(s) + for l >= 1<<7 { + dAtA[i] = uint8(uint64(l)&0x7f | 0x80) + l >>= 7 + i++ + } + dAtA[i] = uint8(l) + i++ + i += copy(dAtA[i:], s) + } + } return i, nil } -func (m *AuthRoleRevokePermissionResponse) Marshal() (data []byte, err error) { +func (m *AuthUserListResponse) Marshal() (dAtA []byte, err error) { size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) if err != nil { return nil, err } - return data[:n], nil + return dAtA[:n], nil } -func (m *AuthRoleRevokePermissionResponse) MarshalTo(data []byte) (int, error) { +func (m *AuthUserListResponse) MarshalTo(dAtA []byte) (int, error) { var i int _ = i var l int _ = l if m.Header != nil { - data[i] = 0xa + dAtA[i] = 0xa i++ - i = encodeVarintRpc(data, i, uint64(m.Header.Size())) - n49, err := m.Header.MarshalTo(data[i:]) + i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size())) + n49, err := m.Header.MarshalTo(dAtA[i:]) if err != nil { return 0, err } i += n49 } + if len(m.Users) > 0 { + for _, s := range m.Users { + dAtA[i] = 0x12 + i++ + l = len(s) + for l >= 1<<7 { + dAtA[i] = uint8(uint64(l)&0x7f | 0x80) + l >>= 7 + i++ + } + dAtA[i] = uint8(l) + i++ + i += copy(dAtA[i:], s) + } + } return i, nil } -func encodeFixed64Rpc(data []byte, offset int, v uint64) int { - data[offset] = uint8(v) - data[offset+1] = uint8(v >> 8) - data[offset+2] = uint8(v >> 16) - data[offset+3] = uint8(v >> 24) - data[offset+4] = uint8(v >> 32) - data[offset+5] = uint8(v >> 40) - data[offset+6] = uint8(v >> 48) - data[offset+7] = uint8(v >> 56) +func (m *AuthRoleDeleteResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *AuthRoleDeleteResponse) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Header != nil { + dAtA[i] = 0xa + i++ + i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size())) + n50, err := m.Header.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n50 + } + return i, nil +} + +func (m *AuthRoleGrantPermissionResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *AuthRoleGrantPermissionResponse) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Header != nil { + dAtA[i] = 0xa + i++ + i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size())) + n51, err := m.Header.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n51 + } + return i, nil +} + +func (m *AuthRoleRevokePermissionResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *AuthRoleRevokePermissionResponse) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Header != nil { + dAtA[i] = 0xa + i++ + i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size())) + n52, err := m.Header.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n52 + } + return i, nil +} + +func encodeFixed64Rpc(dAtA []byte, offset int, v uint64) int { + dAtA[offset] = uint8(v) + dAtA[offset+1] = uint8(v >> 8) + dAtA[offset+2] = uint8(v >> 16) + dAtA[offset+3] = uint8(v >> 24) + dAtA[offset+4] = uint8(v >> 32) + dAtA[offset+5] = uint8(v >> 40) + dAtA[offset+6] = uint8(v >> 48) + dAtA[offset+7] = uint8(v >> 56) return offset + 8 } -func encodeFixed32Rpc(data []byte, offset int, v uint32) int { - data[offset] = uint8(v) - data[offset+1] = uint8(v >> 8) - data[offset+2] = uint8(v >> 16) - data[offset+3] = uint8(v >> 24) +func encodeFixed32Rpc(dAtA []byte, offset int, v uint32) int { + dAtA[offset] = uint8(v) + dAtA[offset+1] = uint8(v >> 8) + dAtA[offset+2] = uint8(v >> 16) + dAtA[offset+3] = uint8(v >> 24) return offset + 4 } -func encodeVarintRpc(data []byte, offset int, v uint64) int { +func encodeVarintRpc(dAtA []byte, offset int, v uint64) int { for v >= 1<<7 { - data[offset] = uint8(v&0x7f | 0x80) + dAtA[offset] = uint8(v&0x7f | 0x80) v >>= 7 offset++ } - data[offset] = uint8(v) + dAtA[offset] = uint8(v) return offset + 1 } func (m *ResponseHeader) Size() (n int) { @@ -6315,6 +6556,18 @@ func (m *RangeRequest) Size() (n int) { if m.CountOnly { n += 2 } + if m.MinModRevision != 0 { + n += 1 + sovRpc(uint64(m.MinModRevision)) + } + if m.MaxModRevision != 0 { + n += 1 + sovRpc(uint64(m.MaxModRevision)) + } + if m.MinCreateRevision != 0 { + n += 1 + sovRpc(uint64(m.MinCreateRevision)) + } + if m.MaxCreateRevision != 0 { + n += 1 + sovRpc(uint64(m.MaxCreateRevision)) + } return n } @@ -6679,6 +6932,13 @@ func (m *WatchCreateRequest) Size() (n int) { if m.ProgressNotify { n += 2 } + if len(m.Filters) > 0 { + l = 0 + for _, e := range m.Filters { + l += sovRpc(uint64(e)) + } + n += 1 + sovRpc(uint64(l)) + l + } if m.PrevKv { n += 2 } @@ -6798,6 +7058,43 @@ func (m *LeaseKeepAliveResponse) Size() (n int) { return n } +func (m *LeaseTimeToLiveRequest) Size() (n int) { + var l int + _ = l + if m.ID != 0 { + n += 1 + sovRpc(uint64(m.ID)) + } + if m.Keys { + n += 2 + } + return n +} + +func (m *LeaseTimeToLiveResponse) Size() (n int) { + var l int + _ = l + if m.Header != nil { + l = m.Header.Size() + n += 1 + l + sovRpc(uint64(l)) + } + if m.ID != 0 { + n += 1 + sovRpc(uint64(m.ID)) + } + if m.TTL != 0 { + n += 1 + sovRpc(uint64(m.TTL)) + } + if m.GrantedTTL != 0 { + n += 1 + sovRpc(uint64(m.GrantedTTL)) + } + if len(m.Keys) > 0 { + for _, b := range m.Keys { + l = len(b) + n += 1 + l + sovRpc(uint64(l)) + } + } + return n +} + func (m *Member) Size() (n int) { var l int _ = l @@ -7383,8 +7680,8 @@ func sovRpc(x uint64) (n int) { func sozRpc(x uint64) (n int) { return sovRpc(uint64((x << 1) ^ uint64((int64(x) >> 63)))) } -func (m *ResponseHeader) Unmarshal(data []byte) error { - l := len(data) +func (m *ResponseHeader) Unmarshal(dAtA []byte) error { + l := len(dAtA) iNdEx := 0 for iNdEx < l { preIndex := iNdEx @@ -7396,7 +7693,7 @@ func (m *ResponseHeader) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -7424,7 +7721,7 @@ func (m *ResponseHeader) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ m.ClusterId |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -7443,7 +7740,7 @@ func (m *ResponseHeader) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ m.MemberId |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -7462,7 +7759,7 @@ func (m *ResponseHeader) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ m.Revision |= (int64(b) & 0x7F) << shift if b < 0x80 { @@ -7481,7 +7778,7 @@ func (m *ResponseHeader) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ m.RaftTerm |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -7490,7 +7787,7 @@ func (m *ResponseHeader) Unmarshal(data []byte) error { } default: iNdEx = preIndex - skippy, err := skipRpc(data[iNdEx:]) + skippy, err := skipRpc(dAtA[iNdEx:]) if err != nil { return err } @@ -7509,8 +7806,8 @@ func (m *ResponseHeader) Unmarshal(data []byte) error { } return nil } -func (m *RangeRequest) Unmarshal(data []byte) error { - l := len(data) +func (m *RangeRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) iNdEx := 0 for iNdEx < l { preIndex := iNdEx @@ -7522,7 +7819,7 @@ func (m *RangeRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -7550,7 +7847,7 @@ func (m *RangeRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ byteLen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -7564,7 +7861,7 @@ func (m *RangeRequest) Unmarshal(data []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Key = append(m.Key[:0], data[iNdEx:postIndex]...) + m.Key = append(m.Key[:0], dAtA[iNdEx:postIndex]...) if m.Key == nil { m.Key = []byte{} } @@ -7581,7 +7878,7 @@ func (m *RangeRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ byteLen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -7595,7 +7892,7 @@ func (m *RangeRequest) Unmarshal(data []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.RangeEnd = append(m.RangeEnd[:0], data[iNdEx:postIndex]...) + m.RangeEnd = append(m.RangeEnd[:0], dAtA[iNdEx:postIndex]...) if m.RangeEnd == nil { m.RangeEnd = []byte{} } @@ -7612,7 +7909,7 @@ func (m *RangeRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ m.Limit |= (int64(b) & 0x7F) << shift if b < 0x80 { @@ -7631,7 +7928,7 @@ func (m *RangeRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ m.Revision |= (int64(b) & 0x7F) << shift if b < 0x80 { @@ -7650,7 +7947,7 @@ func (m *RangeRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ m.SortOrder |= (RangeRequest_SortOrder(b) & 0x7F) << shift if b < 0x80 { @@ -7669,7 +7966,7 @@ func (m *RangeRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ m.SortTarget |= (RangeRequest_SortTarget(b) & 0x7F) << shift if b < 0x80 { @@ -7688,7 +7985,7 @@ func (m *RangeRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ v |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -7708,7 +8005,7 @@ func (m *RangeRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ v |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -7728,7 +8025,7 @@ func (m *RangeRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ v |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -7736,9 +8033,85 @@ func (m *RangeRequest) Unmarshal(data []byte) error { } } m.CountOnly = bool(v != 0) + case 10: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field MinModRevision", wireType) + } + m.MinModRevision = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.MinModRevision |= (int64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + case 11: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field MaxModRevision", wireType) + } + m.MaxModRevision = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.MaxModRevision |= (int64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + case 12: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field MinCreateRevision", wireType) + } + m.MinCreateRevision = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.MinCreateRevision |= (int64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + case 13: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field MaxCreateRevision", wireType) + } + m.MaxCreateRevision = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.MaxCreateRevision |= (int64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex - skippy, err := skipRpc(data[iNdEx:]) + skippy, err := skipRpc(dAtA[iNdEx:]) if err != nil { return err } @@ -7757,8 +8130,8 @@ func (m *RangeRequest) Unmarshal(data []byte) error { } return nil } -func (m *RangeResponse) Unmarshal(data []byte) error { - l := len(data) +func (m *RangeResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) iNdEx := 0 for iNdEx < l { preIndex := iNdEx @@ -7770,7 +8143,7 @@ func (m *RangeResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -7798,7 +8171,7 @@ func (m *RangeResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ msglen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -7815,7 +8188,7 @@ func (m *RangeResponse) Unmarshal(data []byte) error { if m.Header == nil { m.Header = &ResponseHeader{} } - if err := m.Header.Unmarshal(data[iNdEx:postIndex]); err != nil { + if err := m.Header.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -7831,7 +8204,7 @@ func (m *RangeResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ msglen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -7846,7 +8219,7 @@ func (m *RangeResponse) Unmarshal(data []byte) error { return io.ErrUnexpectedEOF } m.Kvs = append(m.Kvs, &mvccpb.KeyValue{}) - if err := m.Kvs[len(m.Kvs)-1].Unmarshal(data[iNdEx:postIndex]); err != nil { + if err := m.Kvs[len(m.Kvs)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -7862,7 +8235,7 @@ func (m *RangeResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ v |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -7882,7 +8255,7 @@ func (m *RangeResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ m.Count |= (int64(b) & 0x7F) << shift if b < 0x80 { @@ -7891,7 +8264,7 @@ func (m *RangeResponse) Unmarshal(data []byte) error { } default: iNdEx = preIndex - skippy, err := skipRpc(data[iNdEx:]) + skippy, err := skipRpc(dAtA[iNdEx:]) if err != nil { return err } @@ -7910,8 +8283,8 @@ func (m *RangeResponse) Unmarshal(data []byte) error { } return nil } -func (m *PutRequest) Unmarshal(data []byte) error { - l := len(data) +func (m *PutRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) iNdEx := 0 for iNdEx < l { preIndex := iNdEx @@ -7923,7 +8296,7 @@ func (m *PutRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -7951,7 +8324,7 @@ func (m *PutRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ byteLen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -7965,7 +8338,7 @@ func (m *PutRequest) Unmarshal(data []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Key = append(m.Key[:0], data[iNdEx:postIndex]...) + m.Key = append(m.Key[:0], dAtA[iNdEx:postIndex]...) if m.Key == nil { m.Key = []byte{} } @@ -7982,7 +8355,7 @@ func (m *PutRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ byteLen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -7996,7 +8369,7 @@ func (m *PutRequest) Unmarshal(data []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Value = append(m.Value[:0], data[iNdEx:postIndex]...) + m.Value = append(m.Value[:0], dAtA[iNdEx:postIndex]...) if m.Value == nil { m.Value = []byte{} } @@ -8013,7 +8386,7 @@ func (m *PutRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ m.Lease |= (int64(b) & 0x7F) << shift if b < 0x80 { @@ -8032,7 +8405,7 @@ func (m *PutRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ v |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -8042,7 +8415,7 @@ func (m *PutRequest) Unmarshal(data []byte) error { m.PrevKv = bool(v != 0) default: iNdEx = preIndex - skippy, err := skipRpc(data[iNdEx:]) + skippy, err := skipRpc(dAtA[iNdEx:]) if err != nil { return err } @@ -8061,8 +8434,8 @@ func (m *PutRequest) Unmarshal(data []byte) error { } return nil } -func (m *PutResponse) Unmarshal(data []byte) error { - l := len(data) +func (m *PutResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) iNdEx := 0 for iNdEx < l { preIndex := iNdEx @@ -8074,7 +8447,7 @@ func (m *PutResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -8102,7 +8475,7 @@ func (m *PutResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ msglen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -8119,7 +8492,7 @@ func (m *PutResponse) Unmarshal(data []byte) error { if m.Header == nil { m.Header = &ResponseHeader{} } - if err := m.Header.Unmarshal(data[iNdEx:postIndex]); err != nil { + if err := m.Header.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -8135,7 +8508,7 @@ func (m *PutResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ msglen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -8152,13 +8525,13 @@ func (m *PutResponse) Unmarshal(data []byte) error { if m.PrevKv == nil { m.PrevKv = &mvccpb.KeyValue{} } - if err := m.PrevKv.Unmarshal(data[iNdEx:postIndex]); err != nil { + if err := m.PrevKv.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skipRpc(data[iNdEx:]) + skippy, err := skipRpc(dAtA[iNdEx:]) if err != nil { return err } @@ -8177,8 +8550,8 @@ func (m *PutResponse) Unmarshal(data []byte) error { } return nil } -func (m *DeleteRangeRequest) Unmarshal(data []byte) error { - l := len(data) +func (m *DeleteRangeRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) iNdEx := 0 for iNdEx < l { preIndex := iNdEx @@ -8190,7 +8563,7 @@ func (m *DeleteRangeRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -8218,7 +8591,7 @@ func (m *DeleteRangeRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ byteLen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -8232,7 +8605,7 @@ func (m *DeleteRangeRequest) Unmarshal(data []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Key = append(m.Key[:0], data[iNdEx:postIndex]...) + m.Key = append(m.Key[:0], dAtA[iNdEx:postIndex]...) if m.Key == nil { m.Key = []byte{} } @@ -8249,7 +8622,7 @@ func (m *DeleteRangeRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ byteLen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -8263,7 +8636,7 @@ func (m *DeleteRangeRequest) Unmarshal(data []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.RangeEnd = append(m.RangeEnd[:0], data[iNdEx:postIndex]...) + m.RangeEnd = append(m.RangeEnd[:0], dAtA[iNdEx:postIndex]...) if m.RangeEnd == nil { m.RangeEnd = []byte{} } @@ -8280,7 +8653,7 @@ func (m *DeleteRangeRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ v |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -8290,7 +8663,7 @@ func (m *DeleteRangeRequest) Unmarshal(data []byte) error { m.PrevKv = bool(v != 0) default: iNdEx = preIndex - skippy, err := skipRpc(data[iNdEx:]) + skippy, err := skipRpc(dAtA[iNdEx:]) if err != nil { return err } @@ -8309,8 +8682,8 @@ func (m *DeleteRangeRequest) Unmarshal(data []byte) error { } return nil } -func (m *DeleteRangeResponse) Unmarshal(data []byte) error { - l := len(data) +func (m *DeleteRangeResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) iNdEx := 0 for iNdEx < l { preIndex := iNdEx @@ -8322,7 +8695,7 @@ func (m *DeleteRangeResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -8350,7 +8723,7 @@ func (m *DeleteRangeResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ msglen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -8367,7 +8740,7 @@ func (m *DeleteRangeResponse) Unmarshal(data []byte) error { if m.Header == nil { m.Header = &ResponseHeader{} } - if err := m.Header.Unmarshal(data[iNdEx:postIndex]); err != nil { + if err := m.Header.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -8383,7 +8756,7 @@ func (m *DeleteRangeResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ m.Deleted |= (int64(b) & 0x7F) << shift if b < 0x80 { @@ -8402,7 +8775,7 @@ func (m *DeleteRangeResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ msglen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -8417,13 +8790,13 @@ func (m *DeleteRangeResponse) Unmarshal(data []byte) error { return io.ErrUnexpectedEOF } m.PrevKvs = append(m.PrevKvs, &mvccpb.KeyValue{}) - if err := m.PrevKvs[len(m.PrevKvs)-1].Unmarshal(data[iNdEx:postIndex]); err != nil { + 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:]) + skippy, err := skipRpc(dAtA[iNdEx:]) if err != nil { return err } @@ -8442,8 +8815,8 @@ func (m *DeleteRangeResponse) Unmarshal(data []byte) error { } return nil } -func (m *RequestOp) Unmarshal(data []byte) error { - l := len(data) +func (m *RequestOp) Unmarshal(dAtA []byte) error { + l := len(dAtA) iNdEx := 0 for iNdEx < l { preIndex := iNdEx @@ -8455,7 +8828,7 @@ func (m *RequestOp) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -8483,7 +8856,7 @@ func (m *RequestOp) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ msglen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -8498,7 +8871,7 @@ func (m *RequestOp) Unmarshal(data []byte) error { return io.ErrUnexpectedEOF } v := &RangeRequest{} - if err := v.Unmarshal(data[iNdEx:postIndex]); err != nil { + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } m.Request = &RequestOp_RequestRange{v} @@ -8515,7 +8888,7 @@ func (m *RequestOp) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ msglen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -8530,7 +8903,7 @@ func (m *RequestOp) Unmarshal(data []byte) error { return io.ErrUnexpectedEOF } v := &PutRequest{} - if err := v.Unmarshal(data[iNdEx:postIndex]); err != nil { + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } m.Request = &RequestOp_RequestPut{v} @@ -8547,7 +8920,7 @@ func (m *RequestOp) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ msglen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -8562,14 +8935,14 @@ func (m *RequestOp) Unmarshal(data []byte) error { return io.ErrUnexpectedEOF } v := &DeleteRangeRequest{} - if err := v.Unmarshal(data[iNdEx:postIndex]); err != nil { + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } m.Request = &RequestOp_RequestDeleteRange{v} iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skipRpc(data[iNdEx:]) + skippy, err := skipRpc(dAtA[iNdEx:]) if err != nil { return err } @@ -8588,8 +8961,8 @@ func (m *RequestOp) Unmarshal(data []byte) error { } return nil } -func (m *ResponseOp) Unmarshal(data []byte) error { - l := len(data) +func (m *ResponseOp) Unmarshal(dAtA []byte) error { + l := len(dAtA) iNdEx := 0 for iNdEx < l { preIndex := iNdEx @@ -8601,7 +8974,7 @@ func (m *ResponseOp) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -8629,7 +9002,7 @@ func (m *ResponseOp) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ msglen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -8644,7 +9017,7 @@ func (m *ResponseOp) Unmarshal(data []byte) error { return io.ErrUnexpectedEOF } v := &RangeResponse{} - if err := v.Unmarshal(data[iNdEx:postIndex]); err != nil { + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } m.Response = &ResponseOp_ResponseRange{v} @@ -8661,7 +9034,7 @@ func (m *ResponseOp) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ msglen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -8676,7 +9049,7 @@ func (m *ResponseOp) Unmarshal(data []byte) error { return io.ErrUnexpectedEOF } v := &PutResponse{} - if err := v.Unmarshal(data[iNdEx:postIndex]); err != nil { + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } m.Response = &ResponseOp_ResponsePut{v} @@ -8693,7 +9066,7 @@ func (m *ResponseOp) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ msglen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -8708,14 +9081,14 @@ func (m *ResponseOp) Unmarshal(data []byte) error { return io.ErrUnexpectedEOF } v := &DeleteRangeResponse{} - if err := v.Unmarshal(data[iNdEx:postIndex]); err != nil { + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } m.Response = &ResponseOp_ResponseDeleteRange{v} iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skipRpc(data[iNdEx:]) + skippy, err := skipRpc(dAtA[iNdEx:]) if err != nil { return err } @@ -8734,8 +9107,8 @@ func (m *ResponseOp) Unmarshal(data []byte) error { } return nil } -func (m *Compare) Unmarshal(data []byte) error { - l := len(data) +func (m *Compare) Unmarshal(dAtA []byte) error { + l := len(dAtA) iNdEx := 0 for iNdEx < l { preIndex := iNdEx @@ -8747,7 +9120,7 @@ func (m *Compare) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -8775,7 +9148,7 @@ func (m *Compare) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ m.Result |= (Compare_CompareResult(b) & 0x7F) << shift if b < 0x80 { @@ -8794,7 +9167,7 @@ func (m *Compare) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ m.Target |= (Compare_CompareTarget(b) & 0x7F) << shift if b < 0x80 { @@ -8813,7 +9186,7 @@ func (m *Compare) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ byteLen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -8827,7 +9200,7 @@ func (m *Compare) Unmarshal(data []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Key = append(m.Key[:0], data[iNdEx:postIndex]...) + m.Key = append(m.Key[:0], dAtA[iNdEx:postIndex]...) if m.Key == nil { m.Key = []byte{} } @@ -8844,7 +9217,7 @@ func (m *Compare) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ v |= (int64(b) & 0x7F) << shift if b < 0x80 { @@ -8864,7 +9237,7 @@ func (m *Compare) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ v |= (int64(b) & 0x7F) << shift if b < 0x80 { @@ -8884,7 +9257,7 @@ func (m *Compare) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ v |= (int64(b) & 0x7F) << shift if b < 0x80 { @@ -8904,7 +9277,7 @@ func (m *Compare) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ byteLen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -8919,12 +9292,12 @@ func (m *Compare) Unmarshal(data []byte) error { return io.ErrUnexpectedEOF } v := make([]byte, postIndex-iNdEx) - copy(v, data[iNdEx:postIndex]) + copy(v, dAtA[iNdEx:postIndex]) m.TargetUnion = &Compare_Value{v} iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skipRpc(data[iNdEx:]) + skippy, err := skipRpc(dAtA[iNdEx:]) if err != nil { return err } @@ -8943,8 +9316,8 @@ func (m *Compare) Unmarshal(data []byte) error { } return nil } -func (m *TxnRequest) Unmarshal(data []byte) error { - l := len(data) +func (m *TxnRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) iNdEx := 0 for iNdEx < l { preIndex := iNdEx @@ -8956,7 +9329,7 @@ func (m *TxnRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -8984,7 +9357,7 @@ func (m *TxnRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ msglen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -8999,7 +9372,7 @@ func (m *TxnRequest) Unmarshal(data []byte) error { return io.ErrUnexpectedEOF } m.Compare = append(m.Compare, &Compare{}) - if err := m.Compare[len(m.Compare)-1].Unmarshal(data[iNdEx:postIndex]); err != nil { + if err := m.Compare[len(m.Compare)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -9015,7 +9388,7 @@ func (m *TxnRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ msglen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -9030,7 +9403,7 @@ func (m *TxnRequest) Unmarshal(data []byte) error { return io.ErrUnexpectedEOF } m.Success = append(m.Success, &RequestOp{}) - if err := m.Success[len(m.Success)-1].Unmarshal(data[iNdEx:postIndex]); err != nil { + if err := m.Success[len(m.Success)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -9046,7 +9419,7 @@ func (m *TxnRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ msglen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -9061,13 +9434,13 @@ func (m *TxnRequest) Unmarshal(data []byte) error { return io.ErrUnexpectedEOF } m.Failure = append(m.Failure, &RequestOp{}) - if err := m.Failure[len(m.Failure)-1].Unmarshal(data[iNdEx:postIndex]); err != nil { + if err := m.Failure[len(m.Failure)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skipRpc(data[iNdEx:]) + skippy, err := skipRpc(dAtA[iNdEx:]) if err != nil { return err } @@ -9086,8 +9459,8 @@ func (m *TxnRequest) Unmarshal(data []byte) error { } return nil } -func (m *TxnResponse) Unmarshal(data []byte) error { - l := len(data) +func (m *TxnResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) iNdEx := 0 for iNdEx < l { preIndex := iNdEx @@ -9099,7 +9472,7 @@ func (m *TxnResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -9127,7 +9500,7 @@ func (m *TxnResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ msglen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -9144,7 +9517,7 @@ func (m *TxnResponse) Unmarshal(data []byte) error { if m.Header == nil { m.Header = &ResponseHeader{} } - if err := m.Header.Unmarshal(data[iNdEx:postIndex]); err != nil { + if err := m.Header.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -9160,7 +9533,7 @@ func (m *TxnResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ v |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -9180,7 +9553,7 @@ func (m *TxnResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ msglen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -9195,13 +9568,13 @@ func (m *TxnResponse) Unmarshal(data []byte) error { return io.ErrUnexpectedEOF } m.Responses = append(m.Responses, &ResponseOp{}) - if err := m.Responses[len(m.Responses)-1].Unmarshal(data[iNdEx:postIndex]); err != nil { + if err := m.Responses[len(m.Responses)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skipRpc(data[iNdEx:]) + skippy, err := skipRpc(dAtA[iNdEx:]) if err != nil { return err } @@ -9220,8 +9593,8 @@ func (m *TxnResponse) Unmarshal(data []byte) error { } return nil } -func (m *CompactionRequest) Unmarshal(data []byte) error { - l := len(data) +func (m *CompactionRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) iNdEx := 0 for iNdEx < l { preIndex := iNdEx @@ -9233,7 +9606,7 @@ func (m *CompactionRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -9261,7 +9634,7 @@ func (m *CompactionRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ m.Revision |= (int64(b) & 0x7F) << shift if b < 0x80 { @@ -9280,7 +9653,7 @@ func (m *CompactionRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ v |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -9290,7 +9663,7 @@ func (m *CompactionRequest) Unmarshal(data []byte) error { m.Physical = bool(v != 0) default: iNdEx = preIndex - skippy, err := skipRpc(data[iNdEx:]) + skippy, err := skipRpc(dAtA[iNdEx:]) if err != nil { return err } @@ -9309,8 +9682,8 @@ func (m *CompactionRequest) Unmarshal(data []byte) error { } return nil } -func (m *CompactionResponse) Unmarshal(data []byte) error { - l := len(data) +func (m *CompactionResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) iNdEx := 0 for iNdEx < l { preIndex := iNdEx @@ -9322,7 +9695,7 @@ func (m *CompactionResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -9350,7 +9723,7 @@ func (m *CompactionResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ msglen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -9367,13 +9740,13 @@ func (m *CompactionResponse) Unmarshal(data []byte) error { if m.Header == nil { m.Header = &ResponseHeader{} } - if err := m.Header.Unmarshal(data[iNdEx:postIndex]); err != nil { + if err := m.Header.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skipRpc(data[iNdEx:]) + skippy, err := skipRpc(dAtA[iNdEx:]) if err != nil { return err } @@ -9392,8 +9765,8 @@ func (m *CompactionResponse) Unmarshal(data []byte) error { } return nil } -func (m *HashRequest) Unmarshal(data []byte) error { - l := len(data) +func (m *HashRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) iNdEx := 0 for iNdEx < l { preIndex := iNdEx @@ -9405,7 +9778,7 @@ func (m *HashRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -9423,7 +9796,7 @@ func (m *HashRequest) Unmarshal(data []byte) error { switch fieldNum { default: iNdEx = preIndex - skippy, err := skipRpc(data[iNdEx:]) + skippy, err := skipRpc(dAtA[iNdEx:]) if err != nil { return err } @@ -9442,8 +9815,8 @@ func (m *HashRequest) Unmarshal(data []byte) error { } return nil } -func (m *HashResponse) Unmarshal(data []byte) error { - l := len(data) +func (m *HashResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) iNdEx := 0 for iNdEx < l { preIndex := iNdEx @@ -9455,7 +9828,7 @@ func (m *HashResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -9483,7 +9856,7 @@ func (m *HashResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ msglen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -9500,7 +9873,7 @@ func (m *HashResponse) Unmarshal(data []byte) error { if m.Header == nil { m.Header = &ResponseHeader{} } - if err := m.Header.Unmarshal(data[iNdEx:postIndex]); err != nil { + if err := m.Header.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -9516,7 +9889,7 @@ func (m *HashResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ m.Hash |= (uint32(b) & 0x7F) << shift if b < 0x80 { @@ -9525,7 +9898,7 @@ func (m *HashResponse) Unmarshal(data []byte) error { } default: iNdEx = preIndex - skippy, err := skipRpc(data[iNdEx:]) + skippy, err := skipRpc(dAtA[iNdEx:]) if err != nil { return err } @@ -9544,8 +9917,8 @@ func (m *HashResponse) Unmarshal(data []byte) error { } return nil } -func (m *SnapshotRequest) Unmarshal(data []byte) error { - l := len(data) +func (m *SnapshotRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) iNdEx := 0 for iNdEx < l { preIndex := iNdEx @@ -9557,7 +9930,7 @@ func (m *SnapshotRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -9575,7 +9948,7 @@ func (m *SnapshotRequest) Unmarshal(data []byte) error { switch fieldNum { default: iNdEx = preIndex - skippy, err := skipRpc(data[iNdEx:]) + skippy, err := skipRpc(dAtA[iNdEx:]) if err != nil { return err } @@ -9594,8 +9967,8 @@ func (m *SnapshotRequest) Unmarshal(data []byte) error { } return nil } -func (m *SnapshotResponse) Unmarshal(data []byte) error { - l := len(data) +func (m *SnapshotResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) iNdEx := 0 for iNdEx < l { preIndex := iNdEx @@ -9607,7 +9980,7 @@ func (m *SnapshotResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -9635,7 +10008,7 @@ func (m *SnapshotResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ msglen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -9652,7 +10025,7 @@ func (m *SnapshotResponse) Unmarshal(data []byte) error { if m.Header == nil { m.Header = &ResponseHeader{} } - if err := m.Header.Unmarshal(data[iNdEx:postIndex]); err != nil { + if err := m.Header.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -9668,7 +10041,7 @@ func (m *SnapshotResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ m.RemainingBytes |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -9687,7 +10060,7 @@ func (m *SnapshotResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ byteLen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -9701,14 +10074,14 @@ func (m *SnapshotResponse) Unmarshal(data []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Blob = append(m.Blob[:0], data[iNdEx:postIndex]...) + m.Blob = append(m.Blob[:0], dAtA[iNdEx:postIndex]...) if m.Blob == nil { m.Blob = []byte{} } iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skipRpc(data[iNdEx:]) + skippy, err := skipRpc(dAtA[iNdEx:]) if err != nil { return err } @@ -9727,8 +10100,8 @@ func (m *SnapshotResponse) Unmarshal(data []byte) error { } return nil } -func (m *WatchRequest) Unmarshal(data []byte) error { - l := len(data) +func (m *WatchRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) iNdEx := 0 for iNdEx < l { preIndex := iNdEx @@ -9740,7 +10113,7 @@ func (m *WatchRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -9768,7 +10141,7 @@ func (m *WatchRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ msglen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -9783,7 +10156,7 @@ func (m *WatchRequest) Unmarshal(data []byte) error { return io.ErrUnexpectedEOF } v := &WatchCreateRequest{} - if err := v.Unmarshal(data[iNdEx:postIndex]); err != nil { + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } m.RequestUnion = &WatchRequest_CreateRequest{v} @@ -9800,7 +10173,7 @@ func (m *WatchRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ msglen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -9815,14 +10188,14 @@ func (m *WatchRequest) Unmarshal(data []byte) error { return io.ErrUnexpectedEOF } v := &WatchCancelRequest{} - if err := v.Unmarshal(data[iNdEx:postIndex]); err != nil { + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } m.RequestUnion = &WatchRequest_CancelRequest{v} iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skipRpc(data[iNdEx:]) + skippy, err := skipRpc(dAtA[iNdEx:]) if err != nil { return err } @@ -9841,8 +10214,8 @@ func (m *WatchRequest) Unmarshal(data []byte) error { } return nil } -func (m *WatchCreateRequest) Unmarshal(data []byte) error { - l := len(data) +func (m *WatchCreateRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) iNdEx := 0 for iNdEx < l { preIndex := iNdEx @@ -9854,7 +10227,7 @@ func (m *WatchCreateRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -9882,7 +10255,7 @@ func (m *WatchCreateRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ byteLen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -9896,7 +10269,7 @@ func (m *WatchCreateRequest) Unmarshal(data []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Key = append(m.Key[:0], data[iNdEx:postIndex]...) + m.Key = append(m.Key[:0], dAtA[iNdEx:postIndex]...) if m.Key == nil { m.Key = []byte{} } @@ -9913,7 +10286,7 @@ func (m *WatchCreateRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ byteLen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -9927,7 +10300,7 @@ func (m *WatchCreateRequest) Unmarshal(data []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.RangeEnd = append(m.RangeEnd[:0], data[iNdEx:postIndex]...) + m.RangeEnd = append(m.RangeEnd[:0], dAtA[iNdEx:postIndex]...) if m.RangeEnd == nil { m.RangeEnd = []byte{} } @@ -9944,7 +10317,7 @@ func (m *WatchCreateRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ m.StartRevision |= (int64(b) & 0x7F) << shift if b < 0x80 { @@ -9963,7 +10336,7 @@ func (m *WatchCreateRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ v |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -9971,6 +10344,68 @@ func (m *WatchCreateRequest) Unmarshal(data []byte) error { } } m.ProgressNotify = bool(v != 0) + case 5: + if wireType == 2 { + var packedLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + packedLen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if packedLen < 0 { + return ErrInvalidLengthRpc + } + postIndex := iNdEx + packedLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + for iNdEx < postIndex { + var v WatchCreateRequest_FilterType + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= (WatchCreateRequest_FilterType(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.Filters = append(m.Filters, v) + } + } else if wireType == 0 { + var v WatchCreateRequest_FilterType + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= (WatchCreateRequest_FilterType(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.Filters = append(m.Filters, v) + } else { + return fmt.Errorf("proto: wrong wireType = %d for field Filters", wireType) + } case 6: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field PrevKv", wireType) @@ -9983,7 +10418,7 @@ func (m *WatchCreateRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ v |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -9993,7 +10428,7 @@ func (m *WatchCreateRequest) Unmarshal(data []byte) error { m.PrevKv = bool(v != 0) default: iNdEx = preIndex - skippy, err := skipRpc(data[iNdEx:]) + skippy, err := skipRpc(dAtA[iNdEx:]) if err != nil { return err } @@ -10012,8 +10447,8 @@ func (m *WatchCreateRequest) Unmarshal(data []byte) error { } return nil } -func (m *WatchCancelRequest) Unmarshal(data []byte) error { - l := len(data) +func (m *WatchCancelRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) iNdEx := 0 for iNdEx < l { preIndex := iNdEx @@ -10025,7 +10460,7 @@ func (m *WatchCancelRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -10053,7 +10488,7 @@ func (m *WatchCancelRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ m.WatchId |= (int64(b) & 0x7F) << shift if b < 0x80 { @@ -10062,7 +10497,7 @@ func (m *WatchCancelRequest) Unmarshal(data []byte) error { } default: iNdEx = preIndex - skippy, err := skipRpc(data[iNdEx:]) + skippy, err := skipRpc(dAtA[iNdEx:]) if err != nil { return err } @@ -10081,8 +10516,8 @@ func (m *WatchCancelRequest) Unmarshal(data []byte) error { } return nil } -func (m *WatchResponse) Unmarshal(data []byte) error { - l := len(data) +func (m *WatchResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) iNdEx := 0 for iNdEx < l { preIndex := iNdEx @@ -10094,7 +10529,7 @@ func (m *WatchResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -10122,7 +10557,7 @@ func (m *WatchResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ msglen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -10139,7 +10574,7 @@ func (m *WatchResponse) Unmarshal(data []byte) error { if m.Header == nil { m.Header = &ResponseHeader{} } - if err := m.Header.Unmarshal(data[iNdEx:postIndex]); err != nil { + if err := m.Header.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -10155,7 +10590,7 @@ func (m *WatchResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ m.WatchId |= (int64(b) & 0x7F) << shift if b < 0x80 { @@ -10174,7 +10609,7 @@ func (m *WatchResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ v |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -10194,7 +10629,7 @@ func (m *WatchResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ v |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -10214,7 +10649,7 @@ func (m *WatchResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ m.CompactRevision |= (int64(b) & 0x7F) << shift if b < 0x80 { @@ -10233,7 +10668,7 @@ func (m *WatchResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ msglen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -10248,13 +10683,13 @@ func (m *WatchResponse) Unmarshal(data []byte) error { return io.ErrUnexpectedEOF } m.Events = append(m.Events, &mvccpb.Event{}) - if err := m.Events[len(m.Events)-1].Unmarshal(data[iNdEx:postIndex]); err != nil { + if err := m.Events[len(m.Events)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skipRpc(data[iNdEx:]) + skippy, err := skipRpc(dAtA[iNdEx:]) if err != nil { return err } @@ -10273,8 +10708,8 @@ func (m *WatchResponse) Unmarshal(data []byte) error { } return nil } -func (m *LeaseGrantRequest) Unmarshal(data []byte) error { - l := len(data) +func (m *LeaseGrantRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) iNdEx := 0 for iNdEx < l { preIndex := iNdEx @@ -10286,7 +10721,7 @@ func (m *LeaseGrantRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -10314,7 +10749,7 @@ func (m *LeaseGrantRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ m.TTL |= (int64(b) & 0x7F) << shift if b < 0x80 { @@ -10333,7 +10768,7 @@ func (m *LeaseGrantRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ m.ID |= (int64(b) & 0x7F) << shift if b < 0x80 { @@ -10342,7 +10777,7 @@ func (m *LeaseGrantRequest) Unmarshal(data []byte) error { } default: iNdEx = preIndex - skippy, err := skipRpc(data[iNdEx:]) + skippy, err := skipRpc(dAtA[iNdEx:]) if err != nil { return err } @@ -10361,8 +10796,8 @@ func (m *LeaseGrantRequest) Unmarshal(data []byte) error { } return nil } -func (m *LeaseGrantResponse) Unmarshal(data []byte) error { - l := len(data) +func (m *LeaseGrantResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) iNdEx := 0 for iNdEx < l { preIndex := iNdEx @@ -10374,7 +10809,7 @@ func (m *LeaseGrantResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -10402,7 +10837,7 @@ func (m *LeaseGrantResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ msglen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -10419,7 +10854,7 @@ func (m *LeaseGrantResponse) Unmarshal(data []byte) error { if m.Header == nil { m.Header = &ResponseHeader{} } - if err := m.Header.Unmarshal(data[iNdEx:postIndex]); err != nil { + if err := m.Header.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -10435,7 +10870,7 @@ func (m *LeaseGrantResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ m.ID |= (int64(b) & 0x7F) << shift if b < 0x80 { @@ -10454,7 +10889,7 @@ func (m *LeaseGrantResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ m.TTL |= (int64(b) & 0x7F) << shift if b < 0x80 { @@ -10473,7 +10908,7 @@ func (m *LeaseGrantResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ stringLen |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -10488,11 +10923,11 @@ func (m *LeaseGrantResponse) Unmarshal(data []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Error = string(data[iNdEx:postIndex]) + m.Error = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skipRpc(data[iNdEx:]) + skippy, err := skipRpc(dAtA[iNdEx:]) if err != nil { return err } @@ -10511,8 +10946,8 @@ func (m *LeaseGrantResponse) Unmarshal(data []byte) error { } return nil } -func (m *LeaseRevokeRequest) Unmarshal(data []byte) error { - l := len(data) +func (m *LeaseRevokeRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) iNdEx := 0 for iNdEx < l { preIndex := iNdEx @@ -10524,7 +10959,7 @@ func (m *LeaseRevokeRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -10552,7 +10987,7 @@ func (m *LeaseRevokeRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ m.ID |= (int64(b) & 0x7F) << shift if b < 0x80 { @@ -10561,7 +10996,7 @@ func (m *LeaseRevokeRequest) Unmarshal(data []byte) error { } default: iNdEx = preIndex - skippy, err := skipRpc(data[iNdEx:]) + skippy, err := skipRpc(dAtA[iNdEx:]) if err != nil { return err } @@ -10580,8 +11015,8 @@ func (m *LeaseRevokeRequest) Unmarshal(data []byte) error { } return nil } -func (m *LeaseRevokeResponse) Unmarshal(data []byte) error { - l := len(data) +func (m *LeaseRevokeResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) iNdEx := 0 for iNdEx < l { preIndex := iNdEx @@ -10593,7 +11028,7 @@ func (m *LeaseRevokeResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -10621,7 +11056,7 @@ func (m *LeaseRevokeResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ msglen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -10638,13 +11073,13 @@ func (m *LeaseRevokeResponse) Unmarshal(data []byte) error { if m.Header == nil { m.Header = &ResponseHeader{} } - if err := m.Header.Unmarshal(data[iNdEx:postIndex]); err != nil { + if err := m.Header.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skipRpc(data[iNdEx:]) + skippy, err := skipRpc(dAtA[iNdEx:]) if err != nil { return err } @@ -10663,8 +11098,8 @@ func (m *LeaseRevokeResponse) Unmarshal(data []byte) error { } return nil } -func (m *LeaseKeepAliveRequest) Unmarshal(data []byte) error { - l := len(data) +func (m *LeaseKeepAliveRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) iNdEx := 0 for iNdEx < l { preIndex := iNdEx @@ -10676,7 +11111,7 @@ func (m *LeaseKeepAliveRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -10704,7 +11139,7 @@ func (m *LeaseKeepAliveRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ m.ID |= (int64(b) & 0x7F) << shift if b < 0x80 { @@ -10713,7 +11148,7 @@ func (m *LeaseKeepAliveRequest) Unmarshal(data []byte) error { } default: iNdEx = preIndex - skippy, err := skipRpc(data[iNdEx:]) + skippy, err := skipRpc(dAtA[iNdEx:]) if err != nil { return err } @@ -10732,8 +11167,8 @@ func (m *LeaseKeepAliveRequest) Unmarshal(data []byte) error { } return nil } -func (m *LeaseKeepAliveResponse) Unmarshal(data []byte) error { - l := len(data) +func (m *LeaseKeepAliveResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) iNdEx := 0 for iNdEx < l { preIndex := iNdEx @@ -10745,7 +11180,7 @@ func (m *LeaseKeepAliveResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -10773,7 +11208,7 @@ func (m *LeaseKeepAliveResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ msglen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -10790,7 +11225,7 @@ func (m *LeaseKeepAliveResponse) Unmarshal(data []byte) error { if m.Header == nil { m.Header = &ResponseHeader{} } - if err := m.Header.Unmarshal(data[iNdEx:postIndex]); err != nil { + if err := m.Header.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -10806,7 +11241,7 @@ func (m *LeaseKeepAliveResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ m.ID |= (int64(b) & 0x7F) << shift if b < 0x80 { @@ -10825,7 +11260,7 @@ func (m *LeaseKeepAliveResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ m.TTL |= (int64(b) & 0x7F) << shift if b < 0x80 { @@ -10834,7 +11269,7 @@ func (m *LeaseKeepAliveResponse) Unmarshal(data []byte) error { } default: iNdEx = preIndex - skippy, err := skipRpc(data[iNdEx:]) + skippy, err := skipRpc(dAtA[iNdEx:]) if err != nil { return err } @@ -10853,8 +11288,8 @@ func (m *LeaseKeepAliveResponse) Unmarshal(data []byte) error { } return nil } -func (m *Member) Unmarshal(data []byte) error { - l := len(data) +func (m *LeaseTimeToLiveRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) iNdEx := 0 for iNdEx < l { preIndex := iNdEx @@ -10866,7 +11301,265 @@ func (m *Member) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: LeaseTimeToLiveRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: LeaseTimeToLiveRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ID", wireType) + } + m.ID = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ID |= (int64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Keys", 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.Keys = bool(v != 0) + default: + iNdEx = preIndex + skippy, err := skipRpc(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthRpc + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *LeaseTimeToLiveResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: LeaseTimeToLiveResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: LeaseTimeToLiveResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Header", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 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.Header == nil { + m.Header = &ResponseHeader{} + } + if err := m.Header.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ID", wireType) + } + m.ID = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ID |= (int64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field TTL", wireType) + } + m.TTL = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.TTL |= (int64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field GrantedTTL", wireType) + } + m.GrantedTTL = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.GrantedTTL |= (int64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Keys", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthRpc + } + postIndex := iNdEx + byteLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Keys = append(m.Keys, make([]byte, postIndex-iNdEx)) + copy(m.Keys[len(m.Keys)-1], dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipRpc(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthRpc + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Member) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -10894,7 +11587,7 @@ func (m *Member) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ m.ID |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -10913,7 +11606,7 @@ func (m *Member) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ stringLen |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -10928,7 +11621,7 @@ func (m *Member) Unmarshal(data []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Name = string(data[iNdEx:postIndex]) + m.Name = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 3: if wireType != 2 { @@ -10942,7 +11635,7 @@ func (m *Member) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ stringLen |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -10957,7 +11650,7 @@ func (m *Member) Unmarshal(data []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.PeerURLs = append(m.PeerURLs, string(data[iNdEx:postIndex])) + m.PeerURLs = append(m.PeerURLs, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex case 4: if wireType != 2 { @@ -10971,7 +11664,7 @@ func (m *Member) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ stringLen |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -10986,11 +11679,11 @@ func (m *Member) Unmarshal(data []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.ClientURLs = append(m.ClientURLs, string(data[iNdEx:postIndex])) + m.ClientURLs = append(m.ClientURLs, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skipRpc(data[iNdEx:]) + skippy, err := skipRpc(dAtA[iNdEx:]) if err != nil { return err } @@ -11009,8 +11702,8 @@ func (m *Member) Unmarshal(data []byte) error { } return nil } -func (m *MemberAddRequest) Unmarshal(data []byte) error { - l := len(data) +func (m *MemberAddRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) iNdEx := 0 for iNdEx < l { preIndex := iNdEx @@ -11022,7 +11715,7 @@ func (m *MemberAddRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -11050,7 +11743,7 @@ func (m *MemberAddRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ stringLen |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -11065,11 +11758,11 @@ func (m *MemberAddRequest) Unmarshal(data []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.PeerURLs = append(m.PeerURLs, string(data[iNdEx:postIndex])) + m.PeerURLs = append(m.PeerURLs, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skipRpc(data[iNdEx:]) + skippy, err := skipRpc(dAtA[iNdEx:]) if err != nil { return err } @@ -11088,8 +11781,8 @@ func (m *MemberAddRequest) Unmarshal(data []byte) error { } return nil } -func (m *MemberAddResponse) Unmarshal(data []byte) error { - l := len(data) +func (m *MemberAddResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) iNdEx := 0 for iNdEx < l { preIndex := iNdEx @@ -11101,7 +11794,7 @@ func (m *MemberAddResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -11129,7 +11822,7 @@ func (m *MemberAddResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ msglen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -11146,7 +11839,7 @@ func (m *MemberAddResponse) Unmarshal(data []byte) error { if m.Header == nil { m.Header = &ResponseHeader{} } - if err := m.Header.Unmarshal(data[iNdEx:postIndex]); err != nil { + if err := m.Header.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -11162,7 +11855,7 @@ func (m *MemberAddResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ msglen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -11179,13 +11872,13 @@ func (m *MemberAddResponse) Unmarshal(data []byte) error { if m.Member == nil { m.Member = &Member{} } - if err := m.Member.Unmarshal(data[iNdEx:postIndex]); err != nil { + if err := m.Member.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skipRpc(data[iNdEx:]) + skippy, err := skipRpc(dAtA[iNdEx:]) if err != nil { return err } @@ -11204,8 +11897,8 @@ func (m *MemberAddResponse) Unmarshal(data []byte) error { } return nil } -func (m *MemberRemoveRequest) Unmarshal(data []byte) error { - l := len(data) +func (m *MemberRemoveRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) iNdEx := 0 for iNdEx < l { preIndex := iNdEx @@ -11217,7 +11910,7 @@ func (m *MemberRemoveRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -11245,7 +11938,7 @@ func (m *MemberRemoveRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ m.ID |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -11254,7 +11947,7 @@ func (m *MemberRemoveRequest) Unmarshal(data []byte) error { } default: iNdEx = preIndex - skippy, err := skipRpc(data[iNdEx:]) + skippy, err := skipRpc(dAtA[iNdEx:]) if err != nil { return err } @@ -11273,8 +11966,8 @@ func (m *MemberRemoveRequest) Unmarshal(data []byte) error { } return nil } -func (m *MemberRemoveResponse) Unmarshal(data []byte) error { - l := len(data) +func (m *MemberRemoveResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) iNdEx := 0 for iNdEx < l { preIndex := iNdEx @@ -11286,7 +11979,7 @@ func (m *MemberRemoveResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -11314,7 +12007,7 @@ func (m *MemberRemoveResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ msglen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -11331,13 +12024,13 @@ func (m *MemberRemoveResponse) Unmarshal(data []byte) error { if m.Header == nil { m.Header = &ResponseHeader{} } - if err := m.Header.Unmarshal(data[iNdEx:postIndex]); err != nil { + if err := m.Header.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skipRpc(data[iNdEx:]) + skippy, err := skipRpc(dAtA[iNdEx:]) if err != nil { return err } @@ -11356,8 +12049,8 @@ func (m *MemberRemoveResponse) Unmarshal(data []byte) error { } return nil } -func (m *MemberUpdateRequest) Unmarshal(data []byte) error { - l := len(data) +func (m *MemberUpdateRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) iNdEx := 0 for iNdEx < l { preIndex := iNdEx @@ -11369,7 +12062,7 @@ func (m *MemberUpdateRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -11397,7 +12090,7 @@ func (m *MemberUpdateRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ m.ID |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -11416,7 +12109,7 @@ func (m *MemberUpdateRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ stringLen |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -11431,11 +12124,11 @@ func (m *MemberUpdateRequest) Unmarshal(data []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.PeerURLs = append(m.PeerURLs, string(data[iNdEx:postIndex])) + m.PeerURLs = append(m.PeerURLs, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skipRpc(data[iNdEx:]) + skippy, err := skipRpc(dAtA[iNdEx:]) if err != nil { return err } @@ -11454,8 +12147,8 @@ func (m *MemberUpdateRequest) Unmarshal(data []byte) error { } return nil } -func (m *MemberUpdateResponse) Unmarshal(data []byte) error { - l := len(data) +func (m *MemberUpdateResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) iNdEx := 0 for iNdEx < l { preIndex := iNdEx @@ -11467,7 +12160,7 @@ func (m *MemberUpdateResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -11495,7 +12188,7 @@ func (m *MemberUpdateResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ msglen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -11512,13 +12205,13 @@ func (m *MemberUpdateResponse) Unmarshal(data []byte) error { if m.Header == nil { m.Header = &ResponseHeader{} } - if err := m.Header.Unmarshal(data[iNdEx:postIndex]); err != nil { + if err := m.Header.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skipRpc(data[iNdEx:]) + skippy, err := skipRpc(dAtA[iNdEx:]) if err != nil { return err } @@ -11537,8 +12230,8 @@ func (m *MemberUpdateResponse) Unmarshal(data []byte) error { } return nil } -func (m *MemberListRequest) Unmarshal(data []byte) error { - l := len(data) +func (m *MemberListRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) iNdEx := 0 for iNdEx < l { preIndex := iNdEx @@ -11550,7 +12243,7 @@ func (m *MemberListRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -11568,7 +12261,7 @@ func (m *MemberListRequest) Unmarshal(data []byte) error { switch fieldNum { default: iNdEx = preIndex - skippy, err := skipRpc(data[iNdEx:]) + skippy, err := skipRpc(dAtA[iNdEx:]) if err != nil { return err } @@ -11587,8 +12280,8 @@ func (m *MemberListRequest) Unmarshal(data []byte) error { } return nil } -func (m *MemberListResponse) Unmarshal(data []byte) error { - l := len(data) +func (m *MemberListResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) iNdEx := 0 for iNdEx < l { preIndex := iNdEx @@ -11600,7 +12293,7 @@ func (m *MemberListResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -11628,7 +12321,7 @@ func (m *MemberListResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ msglen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -11645,7 +12338,7 @@ func (m *MemberListResponse) Unmarshal(data []byte) error { if m.Header == nil { m.Header = &ResponseHeader{} } - if err := m.Header.Unmarshal(data[iNdEx:postIndex]); err != nil { + if err := m.Header.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -11661,7 +12354,7 @@ func (m *MemberListResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ msglen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -11676,13 +12369,13 @@ func (m *MemberListResponse) Unmarshal(data []byte) error { return io.ErrUnexpectedEOF } m.Members = append(m.Members, &Member{}) - if err := m.Members[len(m.Members)-1].Unmarshal(data[iNdEx:postIndex]); err != nil { + if err := m.Members[len(m.Members)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skipRpc(data[iNdEx:]) + skippy, err := skipRpc(dAtA[iNdEx:]) if err != nil { return err } @@ -11701,8 +12394,8 @@ func (m *MemberListResponse) Unmarshal(data []byte) error { } return nil } -func (m *DefragmentRequest) Unmarshal(data []byte) error { - l := len(data) +func (m *DefragmentRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) iNdEx := 0 for iNdEx < l { preIndex := iNdEx @@ -11714,7 +12407,7 @@ func (m *DefragmentRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -11732,7 +12425,7 @@ func (m *DefragmentRequest) Unmarshal(data []byte) error { switch fieldNum { default: iNdEx = preIndex - skippy, err := skipRpc(data[iNdEx:]) + skippy, err := skipRpc(dAtA[iNdEx:]) if err != nil { return err } @@ -11751,8 +12444,8 @@ func (m *DefragmentRequest) Unmarshal(data []byte) error { } return nil } -func (m *DefragmentResponse) Unmarshal(data []byte) error { - l := len(data) +func (m *DefragmentResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) iNdEx := 0 for iNdEx < l { preIndex := iNdEx @@ -11764,7 +12457,7 @@ func (m *DefragmentResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -11792,7 +12485,7 @@ func (m *DefragmentResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ msglen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -11809,13 +12502,13 @@ func (m *DefragmentResponse) Unmarshal(data []byte) error { if m.Header == nil { m.Header = &ResponseHeader{} } - if err := m.Header.Unmarshal(data[iNdEx:postIndex]); err != nil { + if err := m.Header.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skipRpc(data[iNdEx:]) + skippy, err := skipRpc(dAtA[iNdEx:]) if err != nil { return err } @@ -11834,8 +12527,8 @@ func (m *DefragmentResponse) Unmarshal(data []byte) error { } return nil } -func (m *AlarmRequest) Unmarshal(data []byte) error { - l := len(data) +func (m *AlarmRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) iNdEx := 0 for iNdEx < l { preIndex := iNdEx @@ -11847,7 +12540,7 @@ func (m *AlarmRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -11875,7 +12568,7 @@ func (m *AlarmRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ m.Action |= (AlarmRequest_AlarmAction(b) & 0x7F) << shift if b < 0x80 { @@ -11894,7 +12587,7 @@ func (m *AlarmRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ m.MemberID |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -11913,7 +12606,7 @@ func (m *AlarmRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ m.Alarm |= (AlarmType(b) & 0x7F) << shift if b < 0x80 { @@ -11922,7 +12615,7 @@ func (m *AlarmRequest) Unmarshal(data []byte) error { } default: iNdEx = preIndex - skippy, err := skipRpc(data[iNdEx:]) + skippy, err := skipRpc(dAtA[iNdEx:]) if err != nil { return err } @@ -11941,8 +12634,8 @@ func (m *AlarmRequest) Unmarshal(data []byte) error { } return nil } -func (m *AlarmMember) Unmarshal(data []byte) error { - l := len(data) +func (m *AlarmMember) Unmarshal(dAtA []byte) error { + l := len(dAtA) iNdEx := 0 for iNdEx < l { preIndex := iNdEx @@ -11954,7 +12647,7 @@ func (m *AlarmMember) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -11982,7 +12675,7 @@ func (m *AlarmMember) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ m.MemberID |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -12001,7 +12694,7 @@ func (m *AlarmMember) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ m.Alarm |= (AlarmType(b) & 0x7F) << shift if b < 0x80 { @@ -12010,7 +12703,7 @@ func (m *AlarmMember) Unmarshal(data []byte) error { } default: iNdEx = preIndex - skippy, err := skipRpc(data[iNdEx:]) + skippy, err := skipRpc(dAtA[iNdEx:]) if err != nil { return err } @@ -12029,8 +12722,8 @@ func (m *AlarmMember) Unmarshal(data []byte) error { } return nil } -func (m *AlarmResponse) Unmarshal(data []byte) error { - l := len(data) +func (m *AlarmResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) iNdEx := 0 for iNdEx < l { preIndex := iNdEx @@ -12042,7 +12735,7 @@ func (m *AlarmResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -12070,7 +12763,7 @@ func (m *AlarmResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ msglen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -12087,7 +12780,7 @@ func (m *AlarmResponse) Unmarshal(data []byte) error { if m.Header == nil { m.Header = &ResponseHeader{} } - if err := m.Header.Unmarshal(data[iNdEx:postIndex]); err != nil { + if err := m.Header.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -12103,7 +12796,7 @@ func (m *AlarmResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ msglen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -12118,13 +12811,13 @@ func (m *AlarmResponse) Unmarshal(data []byte) error { return io.ErrUnexpectedEOF } m.Alarms = append(m.Alarms, &AlarmMember{}) - if err := m.Alarms[len(m.Alarms)-1].Unmarshal(data[iNdEx:postIndex]); err != nil { + if err := m.Alarms[len(m.Alarms)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skipRpc(data[iNdEx:]) + skippy, err := skipRpc(dAtA[iNdEx:]) if err != nil { return err } @@ -12143,8 +12836,8 @@ func (m *AlarmResponse) Unmarshal(data []byte) error { } return nil } -func (m *StatusRequest) Unmarshal(data []byte) error { - l := len(data) +func (m *StatusRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) iNdEx := 0 for iNdEx < l { preIndex := iNdEx @@ -12156,7 +12849,7 @@ func (m *StatusRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -12174,7 +12867,7 @@ func (m *StatusRequest) Unmarshal(data []byte) error { switch fieldNum { default: iNdEx = preIndex - skippy, err := skipRpc(data[iNdEx:]) + skippy, err := skipRpc(dAtA[iNdEx:]) if err != nil { return err } @@ -12193,8 +12886,8 @@ func (m *StatusRequest) Unmarshal(data []byte) error { } return nil } -func (m *StatusResponse) Unmarshal(data []byte) error { - l := len(data) +func (m *StatusResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) iNdEx := 0 for iNdEx < l { preIndex := iNdEx @@ -12206,7 +12899,7 @@ func (m *StatusResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -12234,7 +12927,7 @@ func (m *StatusResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ msglen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -12251,7 +12944,7 @@ func (m *StatusResponse) Unmarshal(data []byte) error { if m.Header == nil { m.Header = &ResponseHeader{} } - if err := m.Header.Unmarshal(data[iNdEx:postIndex]); err != nil { + if err := m.Header.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -12267,7 +12960,7 @@ func (m *StatusResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ stringLen |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -12282,7 +12975,7 @@ func (m *StatusResponse) Unmarshal(data []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Version = string(data[iNdEx:postIndex]) + m.Version = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 3: if wireType != 0 { @@ -12296,7 +12989,7 @@ func (m *StatusResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ m.DbSize |= (int64(b) & 0x7F) << shift if b < 0x80 { @@ -12315,7 +13008,7 @@ func (m *StatusResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ m.Leader |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -12334,7 +13027,7 @@ func (m *StatusResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ m.RaftIndex |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -12353,7 +13046,7 @@ func (m *StatusResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ m.RaftTerm |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -12362,7 +13055,7 @@ func (m *StatusResponse) Unmarshal(data []byte) error { } default: iNdEx = preIndex - skippy, err := skipRpc(data[iNdEx:]) + skippy, err := skipRpc(dAtA[iNdEx:]) if err != nil { return err } @@ -12381,8 +13074,8 @@ func (m *StatusResponse) Unmarshal(data []byte) error { } return nil } -func (m *AuthEnableRequest) Unmarshal(data []byte) error { - l := len(data) +func (m *AuthEnableRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) iNdEx := 0 for iNdEx < l { preIndex := iNdEx @@ -12394,7 +13087,7 @@ func (m *AuthEnableRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -12412,7 +13105,7 @@ func (m *AuthEnableRequest) Unmarshal(data []byte) error { switch fieldNum { default: iNdEx = preIndex - skippy, err := skipRpc(data[iNdEx:]) + skippy, err := skipRpc(dAtA[iNdEx:]) if err != nil { return err } @@ -12431,8 +13124,8 @@ func (m *AuthEnableRequest) Unmarshal(data []byte) error { } return nil } -func (m *AuthDisableRequest) Unmarshal(data []byte) error { - l := len(data) +func (m *AuthDisableRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) iNdEx := 0 for iNdEx < l { preIndex := iNdEx @@ -12444,7 +13137,7 @@ func (m *AuthDisableRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -12462,7 +13155,7 @@ func (m *AuthDisableRequest) Unmarshal(data []byte) error { switch fieldNum { default: iNdEx = preIndex - skippy, err := skipRpc(data[iNdEx:]) + skippy, err := skipRpc(dAtA[iNdEx:]) if err != nil { return err } @@ -12481,8 +13174,8 @@ func (m *AuthDisableRequest) Unmarshal(data []byte) error { } return nil } -func (m *AuthenticateRequest) Unmarshal(data []byte) error { - l := len(data) +func (m *AuthenticateRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) iNdEx := 0 for iNdEx < l { preIndex := iNdEx @@ -12494,7 +13187,7 @@ func (m *AuthenticateRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -12522,7 +13215,7 @@ func (m *AuthenticateRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ stringLen |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -12537,7 +13230,7 @@ func (m *AuthenticateRequest) Unmarshal(data []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Name = string(data[iNdEx:postIndex]) + m.Name = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: if wireType != 2 { @@ -12551,7 +13244,7 @@ func (m *AuthenticateRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ stringLen |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -12566,11 +13259,11 @@ func (m *AuthenticateRequest) Unmarshal(data []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Password = string(data[iNdEx:postIndex]) + m.Password = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skipRpc(data[iNdEx:]) + skippy, err := skipRpc(dAtA[iNdEx:]) if err != nil { return err } @@ -12589,8 +13282,8 @@ func (m *AuthenticateRequest) Unmarshal(data []byte) error { } return nil } -func (m *AuthUserAddRequest) Unmarshal(data []byte) error { - l := len(data) +func (m *AuthUserAddRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) iNdEx := 0 for iNdEx < l { preIndex := iNdEx @@ -12602,7 +13295,7 @@ func (m *AuthUserAddRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -12630,7 +13323,7 @@ func (m *AuthUserAddRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ stringLen |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -12645,7 +13338,7 @@ func (m *AuthUserAddRequest) Unmarshal(data []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Name = string(data[iNdEx:postIndex]) + m.Name = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: if wireType != 2 { @@ -12659,7 +13352,7 @@ func (m *AuthUserAddRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ stringLen |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -12674,11 +13367,11 @@ func (m *AuthUserAddRequest) Unmarshal(data []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Password = string(data[iNdEx:postIndex]) + m.Password = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skipRpc(data[iNdEx:]) + skippy, err := skipRpc(dAtA[iNdEx:]) if err != nil { return err } @@ -12697,8 +13390,8 @@ func (m *AuthUserAddRequest) Unmarshal(data []byte) error { } return nil } -func (m *AuthUserGetRequest) Unmarshal(data []byte) error { - l := len(data) +func (m *AuthUserGetRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) iNdEx := 0 for iNdEx < l { preIndex := iNdEx @@ -12710,7 +13403,7 @@ func (m *AuthUserGetRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -12738,7 +13431,7 @@ func (m *AuthUserGetRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ stringLen |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -12753,11 +13446,11 @@ func (m *AuthUserGetRequest) Unmarshal(data []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Name = string(data[iNdEx:postIndex]) + m.Name = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skipRpc(data[iNdEx:]) + skippy, err := skipRpc(dAtA[iNdEx:]) if err != nil { return err } @@ -12776,8 +13469,8 @@ func (m *AuthUserGetRequest) Unmarshal(data []byte) error { } return nil } -func (m *AuthUserDeleteRequest) Unmarshal(data []byte) error { - l := len(data) +func (m *AuthUserDeleteRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) iNdEx := 0 for iNdEx < l { preIndex := iNdEx @@ -12789,7 +13482,7 @@ func (m *AuthUserDeleteRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -12817,7 +13510,7 @@ func (m *AuthUserDeleteRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ stringLen |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -12832,11 +13525,11 @@ func (m *AuthUserDeleteRequest) Unmarshal(data []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Name = string(data[iNdEx:postIndex]) + m.Name = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skipRpc(data[iNdEx:]) + skippy, err := skipRpc(dAtA[iNdEx:]) if err != nil { return err } @@ -12855,8 +13548,8 @@ func (m *AuthUserDeleteRequest) Unmarshal(data []byte) error { } return nil } -func (m *AuthUserChangePasswordRequest) Unmarshal(data []byte) error { - l := len(data) +func (m *AuthUserChangePasswordRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) iNdEx := 0 for iNdEx < l { preIndex := iNdEx @@ -12868,7 +13561,7 @@ func (m *AuthUserChangePasswordRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -12896,7 +13589,7 @@ func (m *AuthUserChangePasswordRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ stringLen |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -12911,7 +13604,7 @@ func (m *AuthUserChangePasswordRequest) Unmarshal(data []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Name = string(data[iNdEx:postIndex]) + m.Name = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: if wireType != 2 { @@ -12925,7 +13618,7 @@ func (m *AuthUserChangePasswordRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ stringLen |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -12940,11 +13633,11 @@ func (m *AuthUserChangePasswordRequest) Unmarshal(data []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Password = string(data[iNdEx:postIndex]) + m.Password = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skipRpc(data[iNdEx:]) + skippy, err := skipRpc(dAtA[iNdEx:]) if err != nil { return err } @@ -12963,8 +13656,8 @@ func (m *AuthUserChangePasswordRequest) Unmarshal(data []byte) error { } return nil } -func (m *AuthUserGrantRoleRequest) Unmarshal(data []byte) error { - l := len(data) +func (m *AuthUserGrantRoleRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) iNdEx := 0 for iNdEx < l { preIndex := iNdEx @@ -12976,7 +13669,7 @@ func (m *AuthUserGrantRoleRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -13004,7 +13697,7 @@ func (m *AuthUserGrantRoleRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ stringLen |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -13019,7 +13712,7 @@ func (m *AuthUserGrantRoleRequest) Unmarshal(data []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.User = string(data[iNdEx:postIndex]) + m.User = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: if wireType != 2 { @@ -13033,7 +13726,7 @@ func (m *AuthUserGrantRoleRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ stringLen |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -13048,11 +13741,11 @@ func (m *AuthUserGrantRoleRequest) Unmarshal(data []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Role = string(data[iNdEx:postIndex]) + m.Role = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skipRpc(data[iNdEx:]) + skippy, err := skipRpc(dAtA[iNdEx:]) if err != nil { return err } @@ -13071,8 +13764,8 @@ func (m *AuthUserGrantRoleRequest) Unmarshal(data []byte) error { } return nil } -func (m *AuthUserRevokeRoleRequest) Unmarshal(data []byte) error { - l := len(data) +func (m *AuthUserRevokeRoleRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) iNdEx := 0 for iNdEx < l { preIndex := iNdEx @@ -13084,7 +13777,7 @@ func (m *AuthUserRevokeRoleRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -13112,7 +13805,7 @@ func (m *AuthUserRevokeRoleRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ stringLen |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -13127,7 +13820,7 @@ func (m *AuthUserRevokeRoleRequest) Unmarshal(data []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Name = string(data[iNdEx:postIndex]) + m.Name = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: if wireType != 2 { @@ -13141,7 +13834,7 @@ func (m *AuthUserRevokeRoleRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ stringLen |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -13156,11 +13849,11 @@ func (m *AuthUserRevokeRoleRequest) Unmarshal(data []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Role = string(data[iNdEx:postIndex]) + m.Role = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skipRpc(data[iNdEx:]) + skippy, err := skipRpc(dAtA[iNdEx:]) if err != nil { return err } @@ -13179,8 +13872,8 @@ func (m *AuthUserRevokeRoleRequest) Unmarshal(data []byte) error { } return nil } -func (m *AuthRoleAddRequest) Unmarshal(data []byte) error { - l := len(data) +func (m *AuthRoleAddRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) iNdEx := 0 for iNdEx < l { preIndex := iNdEx @@ -13192,7 +13885,7 @@ func (m *AuthRoleAddRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -13220,7 +13913,7 @@ func (m *AuthRoleAddRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ stringLen |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -13235,11 +13928,11 @@ func (m *AuthRoleAddRequest) Unmarshal(data []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Name = string(data[iNdEx:postIndex]) + m.Name = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skipRpc(data[iNdEx:]) + skippy, err := skipRpc(dAtA[iNdEx:]) if err != nil { return err } @@ -13258,8 +13951,8 @@ func (m *AuthRoleAddRequest) Unmarshal(data []byte) error { } return nil } -func (m *AuthRoleGetRequest) Unmarshal(data []byte) error { - l := len(data) +func (m *AuthRoleGetRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) iNdEx := 0 for iNdEx < l { preIndex := iNdEx @@ -13271,7 +13964,7 @@ func (m *AuthRoleGetRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -13299,7 +13992,7 @@ func (m *AuthRoleGetRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ stringLen |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -13314,11 +14007,11 @@ func (m *AuthRoleGetRequest) Unmarshal(data []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Role = string(data[iNdEx:postIndex]) + m.Role = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skipRpc(data[iNdEx:]) + skippy, err := skipRpc(dAtA[iNdEx:]) if err != nil { return err } @@ -13337,8 +14030,8 @@ func (m *AuthRoleGetRequest) Unmarshal(data []byte) error { } return nil } -func (m *AuthUserListRequest) Unmarshal(data []byte) error { - l := len(data) +func (m *AuthUserListRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) iNdEx := 0 for iNdEx < l { preIndex := iNdEx @@ -13350,7 +14043,7 @@ func (m *AuthUserListRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -13368,7 +14061,7 @@ func (m *AuthUserListRequest) Unmarshal(data []byte) error { switch fieldNum { default: iNdEx = preIndex - skippy, err := skipRpc(data[iNdEx:]) + skippy, err := skipRpc(dAtA[iNdEx:]) if err != nil { return err } @@ -13387,8 +14080,8 @@ func (m *AuthUserListRequest) Unmarshal(data []byte) error { } return nil } -func (m *AuthRoleListRequest) Unmarshal(data []byte) error { - l := len(data) +func (m *AuthRoleListRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) iNdEx := 0 for iNdEx < l { preIndex := iNdEx @@ -13400,7 +14093,7 @@ func (m *AuthRoleListRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -13418,7 +14111,7 @@ func (m *AuthRoleListRequest) Unmarshal(data []byte) error { switch fieldNum { default: iNdEx = preIndex - skippy, err := skipRpc(data[iNdEx:]) + skippy, err := skipRpc(dAtA[iNdEx:]) if err != nil { return err } @@ -13437,8 +14130,8 @@ func (m *AuthRoleListRequest) Unmarshal(data []byte) error { } return nil } -func (m *AuthRoleDeleteRequest) Unmarshal(data []byte) error { - l := len(data) +func (m *AuthRoleDeleteRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) iNdEx := 0 for iNdEx < l { preIndex := iNdEx @@ -13450,7 +14143,7 @@ func (m *AuthRoleDeleteRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -13478,7 +14171,7 @@ func (m *AuthRoleDeleteRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ stringLen |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -13493,11 +14186,11 @@ func (m *AuthRoleDeleteRequest) Unmarshal(data []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Role = string(data[iNdEx:postIndex]) + m.Role = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skipRpc(data[iNdEx:]) + skippy, err := skipRpc(dAtA[iNdEx:]) if err != nil { return err } @@ -13516,8 +14209,8 @@ func (m *AuthRoleDeleteRequest) Unmarshal(data []byte) error { } return nil } -func (m *AuthRoleGrantPermissionRequest) Unmarshal(data []byte) error { - l := len(data) +func (m *AuthRoleGrantPermissionRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) iNdEx := 0 for iNdEx < l { preIndex := iNdEx @@ -13529,7 +14222,7 @@ func (m *AuthRoleGrantPermissionRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -13557,7 +14250,7 @@ func (m *AuthRoleGrantPermissionRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ stringLen |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -13572,7 +14265,7 @@ func (m *AuthRoleGrantPermissionRequest) Unmarshal(data []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Name = string(data[iNdEx:postIndex]) + m.Name = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: if wireType != 2 { @@ -13586,7 +14279,7 @@ func (m *AuthRoleGrantPermissionRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ msglen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -13603,13 +14296,13 @@ func (m *AuthRoleGrantPermissionRequest) Unmarshal(data []byte) error { if m.Perm == nil { m.Perm = &authpb.Permission{} } - if err := m.Perm.Unmarshal(data[iNdEx:postIndex]); err != nil { + if err := m.Perm.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skipRpc(data[iNdEx:]) + skippy, err := skipRpc(dAtA[iNdEx:]) if err != nil { return err } @@ -13628,8 +14321,8 @@ func (m *AuthRoleGrantPermissionRequest) Unmarshal(data []byte) error { } return nil } -func (m *AuthRoleRevokePermissionRequest) Unmarshal(data []byte) error { - l := len(data) +func (m *AuthRoleRevokePermissionRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) iNdEx := 0 for iNdEx < l { preIndex := iNdEx @@ -13641,7 +14334,7 @@ func (m *AuthRoleRevokePermissionRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -13669,7 +14362,7 @@ func (m *AuthRoleRevokePermissionRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ stringLen |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -13684,7 +14377,7 @@ func (m *AuthRoleRevokePermissionRequest) Unmarshal(data []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Role = string(data[iNdEx:postIndex]) + m.Role = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: if wireType != 2 { @@ -13698,7 +14391,7 @@ func (m *AuthRoleRevokePermissionRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ stringLen |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -13713,7 +14406,7 @@ func (m *AuthRoleRevokePermissionRequest) Unmarshal(data []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Key = string(data[iNdEx:postIndex]) + m.Key = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 3: if wireType != 2 { @@ -13727,7 +14420,7 @@ func (m *AuthRoleRevokePermissionRequest) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ stringLen |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -13742,11 +14435,11 @@ func (m *AuthRoleRevokePermissionRequest) Unmarshal(data []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.RangeEnd = string(data[iNdEx:postIndex]) + m.RangeEnd = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skipRpc(data[iNdEx:]) + skippy, err := skipRpc(dAtA[iNdEx:]) if err != nil { return err } @@ -13765,8 +14458,8 @@ func (m *AuthRoleRevokePermissionRequest) Unmarshal(data []byte) error { } return nil } -func (m *AuthEnableResponse) Unmarshal(data []byte) error { - l := len(data) +func (m *AuthEnableResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) iNdEx := 0 for iNdEx < l { preIndex := iNdEx @@ -13778,7 +14471,7 @@ func (m *AuthEnableResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -13806,7 +14499,7 @@ func (m *AuthEnableResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ msglen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -13823,13 +14516,13 @@ func (m *AuthEnableResponse) Unmarshal(data []byte) error { if m.Header == nil { m.Header = &ResponseHeader{} } - if err := m.Header.Unmarshal(data[iNdEx:postIndex]); err != nil { + if err := m.Header.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skipRpc(data[iNdEx:]) + skippy, err := skipRpc(dAtA[iNdEx:]) if err != nil { return err } @@ -13848,8 +14541,8 @@ func (m *AuthEnableResponse) Unmarshal(data []byte) error { } return nil } -func (m *AuthDisableResponse) Unmarshal(data []byte) error { - l := len(data) +func (m *AuthDisableResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) iNdEx := 0 for iNdEx < l { preIndex := iNdEx @@ -13861,7 +14554,7 @@ func (m *AuthDisableResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -13889,7 +14582,7 @@ func (m *AuthDisableResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ msglen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -13906,13 +14599,13 @@ func (m *AuthDisableResponse) Unmarshal(data []byte) error { if m.Header == nil { m.Header = &ResponseHeader{} } - if err := m.Header.Unmarshal(data[iNdEx:postIndex]); err != nil { + if err := m.Header.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skipRpc(data[iNdEx:]) + skippy, err := skipRpc(dAtA[iNdEx:]) if err != nil { return err } @@ -13931,8 +14624,8 @@ func (m *AuthDisableResponse) Unmarshal(data []byte) error { } return nil } -func (m *AuthenticateResponse) Unmarshal(data []byte) error { - l := len(data) +func (m *AuthenticateResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) iNdEx := 0 for iNdEx < l { preIndex := iNdEx @@ -13944,7 +14637,7 @@ func (m *AuthenticateResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -13972,7 +14665,7 @@ func (m *AuthenticateResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ msglen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -13989,7 +14682,7 @@ func (m *AuthenticateResponse) Unmarshal(data []byte) error { if m.Header == nil { m.Header = &ResponseHeader{} } - if err := m.Header.Unmarshal(data[iNdEx:postIndex]); err != nil { + if err := m.Header.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -14005,7 +14698,7 @@ func (m *AuthenticateResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ stringLen |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -14020,11 +14713,11 @@ func (m *AuthenticateResponse) Unmarshal(data []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Token = string(data[iNdEx:postIndex]) + m.Token = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skipRpc(data[iNdEx:]) + skippy, err := skipRpc(dAtA[iNdEx:]) if err != nil { return err } @@ -14043,8 +14736,8 @@ func (m *AuthenticateResponse) Unmarshal(data []byte) error { } return nil } -func (m *AuthUserAddResponse) Unmarshal(data []byte) error { - l := len(data) +func (m *AuthUserAddResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) iNdEx := 0 for iNdEx < l { preIndex := iNdEx @@ -14056,7 +14749,7 @@ func (m *AuthUserAddResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -14084,7 +14777,7 @@ func (m *AuthUserAddResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ msglen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -14101,13 +14794,13 @@ func (m *AuthUserAddResponse) Unmarshal(data []byte) error { if m.Header == nil { m.Header = &ResponseHeader{} } - if err := m.Header.Unmarshal(data[iNdEx:postIndex]); err != nil { + if err := m.Header.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skipRpc(data[iNdEx:]) + skippy, err := skipRpc(dAtA[iNdEx:]) if err != nil { return err } @@ -14126,8 +14819,8 @@ func (m *AuthUserAddResponse) Unmarshal(data []byte) error { } return nil } -func (m *AuthUserGetResponse) Unmarshal(data []byte) error { - l := len(data) +func (m *AuthUserGetResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) iNdEx := 0 for iNdEx < l { preIndex := iNdEx @@ -14139,7 +14832,7 @@ func (m *AuthUserGetResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -14167,7 +14860,7 @@ func (m *AuthUserGetResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ msglen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -14184,7 +14877,7 @@ func (m *AuthUserGetResponse) Unmarshal(data []byte) error { if m.Header == nil { m.Header = &ResponseHeader{} } - if err := m.Header.Unmarshal(data[iNdEx:postIndex]); err != nil { + if err := m.Header.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -14200,7 +14893,7 @@ func (m *AuthUserGetResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ stringLen |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -14215,11 +14908,11 @@ func (m *AuthUserGetResponse) Unmarshal(data []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Roles = append(m.Roles, string(data[iNdEx:postIndex])) + m.Roles = append(m.Roles, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skipRpc(data[iNdEx:]) + skippy, err := skipRpc(dAtA[iNdEx:]) if err != nil { return err } @@ -14238,8 +14931,8 @@ func (m *AuthUserGetResponse) Unmarshal(data []byte) error { } return nil } -func (m *AuthUserDeleteResponse) Unmarshal(data []byte) error { - l := len(data) +func (m *AuthUserDeleteResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) iNdEx := 0 for iNdEx < l { preIndex := iNdEx @@ -14251,7 +14944,7 @@ func (m *AuthUserDeleteResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -14279,7 +14972,7 @@ func (m *AuthUserDeleteResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ msglen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -14296,13 +14989,13 @@ func (m *AuthUserDeleteResponse) Unmarshal(data []byte) error { if m.Header == nil { m.Header = &ResponseHeader{} } - if err := m.Header.Unmarshal(data[iNdEx:postIndex]); err != nil { + if err := m.Header.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skipRpc(data[iNdEx:]) + skippy, err := skipRpc(dAtA[iNdEx:]) if err != nil { return err } @@ -14321,8 +15014,8 @@ func (m *AuthUserDeleteResponse) Unmarshal(data []byte) error { } return nil } -func (m *AuthUserChangePasswordResponse) Unmarshal(data []byte) error { - l := len(data) +func (m *AuthUserChangePasswordResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) iNdEx := 0 for iNdEx < l { preIndex := iNdEx @@ -14334,7 +15027,7 @@ func (m *AuthUserChangePasswordResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -14362,7 +15055,7 @@ func (m *AuthUserChangePasswordResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ msglen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -14379,13 +15072,13 @@ func (m *AuthUserChangePasswordResponse) Unmarshal(data []byte) error { if m.Header == nil { m.Header = &ResponseHeader{} } - if err := m.Header.Unmarshal(data[iNdEx:postIndex]); err != nil { + if err := m.Header.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skipRpc(data[iNdEx:]) + skippy, err := skipRpc(dAtA[iNdEx:]) if err != nil { return err } @@ -14404,8 +15097,8 @@ func (m *AuthUserChangePasswordResponse) Unmarshal(data []byte) error { } return nil } -func (m *AuthUserGrantRoleResponse) Unmarshal(data []byte) error { - l := len(data) +func (m *AuthUserGrantRoleResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) iNdEx := 0 for iNdEx < l { preIndex := iNdEx @@ -14417,7 +15110,7 @@ func (m *AuthUserGrantRoleResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -14445,7 +15138,7 @@ func (m *AuthUserGrantRoleResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ msglen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -14462,13 +15155,13 @@ func (m *AuthUserGrantRoleResponse) Unmarshal(data []byte) error { if m.Header == nil { m.Header = &ResponseHeader{} } - if err := m.Header.Unmarshal(data[iNdEx:postIndex]); err != nil { + if err := m.Header.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skipRpc(data[iNdEx:]) + skippy, err := skipRpc(dAtA[iNdEx:]) if err != nil { return err } @@ -14487,8 +15180,8 @@ func (m *AuthUserGrantRoleResponse) Unmarshal(data []byte) error { } return nil } -func (m *AuthUserRevokeRoleResponse) Unmarshal(data []byte) error { - l := len(data) +func (m *AuthUserRevokeRoleResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) iNdEx := 0 for iNdEx < l { preIndex := iNdEx @@ -14500,7 +15193,7 @@ func (m *AuthUserRevokeRoleResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -14528,7 +15221,7 @@ func (m *AuthUserRevokeRoleResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ msglen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -14545,13 +15238,13 @@ func (m *AuthUserRevokeRoleResponse) Unmarshal(data []byte) error { if m.Header == nil { m.Header = &ResponseHeader{} } - if err := m.Header.Unmarshal(data[iNdEx:postIndex]); err != nil { + if err := m.Header.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skipRpc(data[iNdEx:]) + skippy, err := skipRpc(dAtA[iNdEx:]) if err != nil { return err } @@ -14570,8 +15263,8 @@ func (m *AuthUserRevokeRoleResponse) Unmarshal(data []byte) error { } return nil } -func (m *AuthRoleAddResponse) Unmarshal(data []byte) error { - l := len(data) +func (m *AuthRoleAddResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) iNdEx := 0 for iNdEx < l { preIndex := iNdEx @@ -14583,7 +15276,7 @@ func (m *AuthRoleAddResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -14611,7 +15304,7 @@ func (m *AuthRoleAddResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ msglen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -14628,13 +15321,13 @@ func (m *AuthRoleAddResponse) Unmarshal(data []byte) error { if m.Header == nil { m.Header = &ResponseHeader{} } - if err := m.Header.Unmarshal(data[iNdEx:postIndex]); err != nil { + if err := m.Header.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skipRpc(data[iNdEx:]) + skippy, err := skipRpc(dAtA[iNdEx:]) if err != nil { return err } @@ -14653,8 +15346,8 @@ func (m *AuthRoleAddResponse) Unmarshal(data []byte) error { } return nil } -func (m *AuthRoleGetResponse) Unmarshal(data []byte) error { - l := len(data) +func (m *AuthRoleGetResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) iNdEx := 0 for iNdEx < l { preIndex := iNdEx @@ -14666,7 +15359,7 @@ func (m *AuthRoleGetResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -14694,7 +15387,7 @@ func (m *AuthRoleGetResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ msglen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -14711,7 +15404,7 @@ func (m *AuthRoleGetResponse) Unmarshal(data []byte) error { if m.Header == nil { m.Header = &ResponseHeader{} } - if err := m.Header.Unmarshal(data[iNdEx:postIndex]); err != nil { + if err := m.Header.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -14727,7 +15420,7 @@ func (m *AuthRoleGetResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ msglen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -14742,13 +15435,13 @@ func (m *AuthRoleGetResponse) Unmarshal(data []byte) error { return io.ErrUnexpectedEOF } m.Perm = append(m.Perm, &authpb.Permission{}) - if err := m.Perm[len(m.Perm)-1].Unmarshal(data[iNdEx:postIndex]); err != nil { + if err := m.Perm[len(m.Perm)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skipRpc(data[iNdEx:]) + skippy, err := skipRpc(dAtA[iNdEx:]) if err != nil { return err } @@ -14767,8 +15460,8 @@ func (m *AuthRoleGetResponse) Unmarshal(data []byte) error { } return nil } -func (m *AuthRoleListResponse) Unmarshal(data []byte) error { - l := len(data) +func (m *AuthRoleListResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) iNdEx := 0 for iNdEx < l { preIndex := iNdEx @@ -14780,7 +15473,7 @@ func (m *AuthRoleListResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -14808,7 +15501,7 @@ func (m *AuthRoleListResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ msglen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -14825,7 +15518,7 @@ func (m *AuthRoleListResponse) Unmarshal(data []byte) error { if m.Header == nil { m.Header = &ResponseHeader{} } - if err := m.Header.Unmarshal(data[iNdEx:postIndex]); err != nil { + if err := m.Header.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -14841,7 +15534,7 @@ func (m *AuthRoleListResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ stringLen |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -14856,11 +15549,11 @@ func (m *AuthRoleListResponse) Unmarshal(data []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Roles = append(m.Roles, string(data[iNdEx:postIndex])) + m.Roles = append(m.Roles, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skipRpc(data[iNdEx:]) + skippy, err := skipRpc(dAtA[iNdEx:]) if err != nil { return err } @@ -14879,8 +15572,8 @@ func (m *AuthRoleListResponse) Unmarshal(data []byte) error { } return nil } -func (m *AuthUserListResponse) Unmarshal(data []byte) error { - l := len(data) +func (m *AuthUserListResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) iNdEx := 0 for iNdEx < l { preIndex := iNdEx @@ -14892,7 +15585,7 @@ func (m *AuthUserListResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -14920,7 +15613,7 @@ func (m *AuthUserListResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ msglen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -14937,7 +15630,7 @@ func (m *AuthUserListResponse) Unmarshal(data []byte) error { if m.Header == nil { m.Header = &ResponseHeader{} } - if err := m.Header.Unmarshal(data[iNdEx:postIndex]); err != nil { + if err := m.Header.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -14953,7 +15646,7 @@ func (m *AuthUserListResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ stringLen |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -14968,11 +15661,11 @@ func (m *AuthUserListResponse) Unmarshal(data []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Users = append(m.Users, string(data[iNdEx:postIndex])) + m.Users = append(m.Users, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skipRpc(data[iNdEx:]) + skippy, err := skipRpc(dAtA[iNdEx:]) if err != nil { return err } @@ -14991,8 +15684,8 @@ func (m *AuthUserListResponse) Unmarshal(data []byte) error { } return nil } -func (m *AuthRoleDeleteResponse) Unmarshal(data []byte) error { - l := len(data) +func (m *AuthRoleDeleteResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) iNdEx := 0 for iNdEx < l { preIndex := iNdEx @@ -15004,7 +15697,7 @@ func (m *AuthRoleDeleteResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -15032,7 +15725,7 @@ func (m *AuthRoleDeleteResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ msglen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -15049,13 +15742,13 @@ func (m *AuthRoleDeleteResponse) Unmarshal(data []byte) error { if m.Header == nil { m.Header = &ResponseHeader{} } - if err := m.Header.Unmarshal(data[iNdEx:postIndex]); err != nil { + if err := m.Header.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skipRpc(data[iNdEx:]) + skippy, err := skipRpc(dAtA[iNdEx:]) if err != nil { return err } @@ -15074,8 +15767,8 @@ func (m *AuthRoleDeleteResponse) Unmarshal(data []byte) error { } return nil } -func (m *AuthRoleGrantPermissionResponse) Unmarshal(data []byte) error { - l := len(data) +func (m *AuthRoleGrantPermissionResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) iNdEx := 0 for iNdEx < l { preIndex := iNdEx @@ -15087,7 +15780,7 @@ func (m *AuthRoleGrantPermissionResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -15115,7 +15808,7 @@ func (m *AuthRoleGrantPermissionResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ msglen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -15132,13 +15825,13 @@ func (m *AuthRoleGrantPermissionResponse) Unmarshal(data []byte) error { if m.Header == nil { m.Header = &ResponseHeader{} } - if err := m.Header.Unmarshal(data[iNdEx:postIndex]); err != nil { + if err := m.Header.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skipRpc(data[iNdEx:]) + skippy, err := skipRpc(dAtA[iNdEx:]) if err != nil { return err } @@ -15157,8 +15850,8 @@ func (m *AuthRoleGrantPermissionResponse) Unmarshal(data []byte) error { } return nil } -func (m *AuthRoleRevokePermissionResponse) Unmarshal(data []byte) error { - l := len(data) +func (m *AuthRoleRevokePermissionResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) iNdEx := 0 for iNdEx < l { preIndex := iNdEx @@ -15170,7 +15863,7 @@ func (m *AuthRoleRevokePermissionResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -15198,7 +15891,7 @@ func (m *AuthRoleRevokePermissionResponse) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ msglen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -15215,13 +15908,13 @@ func (m *AuthRoleRevokePermissionResponse) Unmarshal(data []byte) error { if m.Header == nil { m.Header = &ResponseHeader{} } - if err := m.Header.Unmarshal(data[iNdEx:postIndex]); err != nil { + if err := m.Header.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skipRpc(data[iNdEx:]) + skippy, err := skipRpc(dAtA[iNdEx:]) if err != nil { return err } @@ -15240,8 +15933,8 @@ func (m *AuthRoleRevokePermissionResponse) Unmarshal(data []byte) error { } return nil } -func skipRpc(data []byte) (n int, err error) { - l := len(data) +func skipRpc(dAtA []byte) (n int, err error) { + l := len(dAtA) iNdEx := 0 for iNdEx < l { var wire uint64 @@ -15252,7 +15945,7 @@ func skipRpc(data []byte) (n int, err error) { if iNdEx >= l { return 0, io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -15270,7 +15963,7 @@ func skipRpc(data []byte) (n int, err error) { return 0, io.ErrUnexpectedEOF } iNdEx++ - if data[iNdEx-1] < 0x80 { + if dAtA[iNdEx-1] < 0x80 { break } } @@ -15287,7 +15980,7 @@ func skipRpc(data []byte) (n int, err error) { if iNdEx >= l { return 0, io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ length |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -15310,7 +16003,7 @@ func skipRpc(data []byte) (n int, err error) { if iNdEx >= l { return 0, io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ innerWire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -15321,7 +16014,7 @@ func skipRpc(data []byte) (n int, err error) { if innerWireType == 4 { break } - next, err := skipRpc(data[start:]) + next, err := skipRpc(dAtA[start:]) if err != nil { return 0, err } @@ -15345,207 +16038,221 @@ var ( ErrIntOverflowRpc = fmt.Errorf("proto: integer overflow") ) +func init() { proto.RegisterFile("rpc.proto", fileDescriptorRpc) } + var fileDescriptorRpc = []byte{ - // 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, + // 3401 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xb4, 0x5b, 0xcb, 0x73, 0x1b, 0xc7, + 0xd1, 0xe7, 0x02, 0x24, 0x40, 0x34, 0x1e, 0x84, 0x86, 0x94, 0x04, 0xae, 0x24, 0x8a, 0x1a, 0xbd, + 0x28, 0xc9, 0x26, 0x6d, 0xda, 0xdf, 0x77, 0xd0, 0xe7, 0x72, 0x7d, 0x14, 0x09, 0x8b, 0x0c, 0x29, + 0x52, 0x5e, 0x52, 0xb2, 0x53, 0xe5, 0x0a, 0x6a, 0x09, 0x8c, 0xc8, 0x2d, 0x02, 0xbb, 0xf0, 0xee, + 0x02, 0x22, 0x9d, 0xa4, 0x2a, 0xe5, 0xd8, 0x95, 0x4a, 0x8e, 0xf1, 0x21, 0xaf, 0x63, 0x2a, 0x87, + 0xfc, 0x01, 0xb9, 0xe5, 0x0f, 0x48, 0xe5, 0x92, 0x54, 0xe5, 0x1f, 0x48, 0x39, 0x39, 0xe4, 0x90, + 0x7b, 0x4e, 0xa9, 0xa4, 0xe6, 0xb5, 0x3b, 0xbb, 0xd8, 0x05, 0xe5, 0x6c, 0x7c, 0x11, 0x77, 0x66, + 0x7a, 0xfa, 0xd7, 0xdd, 0x33, 0xdd, 0xd3, 0xd3, 0x03, 0x41, 0xc9, 0xed, 0xb7, 0x97, 0xfb, 0xae, + 0xe3, 0x3b, 0xa8, 0x42, 0xfc, 0x76, 0xc7, 0x23, 0xee, 0x90, 0xb8, 0xfd, 0x43, 0x7d, 0xee, 0xc8, + 0x39, 0x72, 0xd8, 0xc0, 0x0a, 0xfd, 0xe2, 0x34, 0xfa, 0x3c, 0xa5, 0x59, 0xe9, 0x0d, 0xdb, 0x6d, + 0xf6, 0x4f, 0xff, 0x70, 0xe5, 0x64, 0x28, 0x86, 0xae, 0xb0, 0x21, 0x73, 0xe0, 0x1f, 0xb3, 0x7f, + 0xfa, 0x87, 0xec, 0x8f, 0x18, 0xbc, 0x7a, 0xe4, 0x38, 0x47, 0x5d, 0xb2, 0x62, 0xf6, 0xad, 0x15, + 0xd3, 0xb6, 0x1d, 0xdf, 0xf4, 0x2d, 0xc7, 0xf6, 0xf8, 0x28, 0xfe, 0x5c, 0x83, 0x9a, 0x41, 0xbc, + 0xbe, 0x63, 0x7b, 0x64, 0x93, 0x98, 0x1d, 0xe2, 0xa2, 0x6b, 0x00, 0xed, 0xee, 0xc0, 0xf3, 0x89, + 0xdb, 0xb2, 0x3a, 0x0d, 0x6d, 0x51, 0x5b, 0x9a, 0x34, 0x4a, 0xa2, 0x67, 0xab, 0x83, 0xae, 0x40, + 0xa9, 0x47, 0x7a, 0x87, 0x7c, 0x34, 0xc7, 0x46, 0xa7, 0x79, 0xc7, 0x56, 0x07, 0xe9, 0x30, 0xed, + 0x92, 0xa1, 0xe5, 0x59, 0x8e, 0xdd, 0xc8, 0x2f, 0x6a, 0x4b, 0x79, 0x23, 0x68, 0xd3, 0x89, 0xae, + 0xf9, 0xc2, 0x6f, 0xf9, 0xc4, 0xed, 0x35, 0x26, 0xf9, 0x44, 0xda, 0x71, 0x40, 0xdc, 0x1e, 0xfe, + 0x6c, 0x0a, 0x2a, 0x86, 0x69, 0x1f, 0x11, 0x83, 0x7c, 0x3c, 0x20, 0x9e, 0x8f, 0xea, 0x90, 0x3f, + 0x21, 0x67, 0x0c, 0xbe, 0x62, 0xd0, 0x4f, 0x3e, 0xdf, 0x3e, 0x22, 0x2d, 0x62, 0x73, 0xe0, 0x0a, + 0x9d, 0x6f, 0x1f, 0x91, 0xa6, 0xdd, 0x41, 0x73, 0x30, 0xd5, 0xb5, 0x7a, 0x96, 0x2f, 0x50, 0x79, + 0x23, 0x22, 0xce, 0x64, 0x4c, 0x9c, 0x75, 0x00, 0xcf, 0x71, 0xfd, 0x96, 0xe3, 0x76, 0x88, 0xdb, + 0x98, 0x5a, 0xd4, 0x96, 0x6a, 0xab, 0xb7, 0x96, 0xd5, 0x85, 0x58, 0x56, 0x05, 0x5a, 0xde, 0x77, + 0x5c, 0x7f, 0x8f, 0xd2, 0x1a, 0x25, 0x4f, 0x7e, 0xa2, 0xf7, 0xa0, 0xcc, 0x98, 0xf8, 0xa6, 0x7b, + 0x44, 0xfc, 0x46, 0x81, 0x71, 0xb9, 0x7d, 0x0e, 0x97, 0x03, 0x46, 0x6c, 0x30, 0x78, 0xfe, 0x8d, + 0x30, 0x54, 0x3c, 0xe2, 0x5a, 0x66, 0xd7, 0xfa, 0xc4, 0x3c, 0xec, 0x92, 0x46, 0x71, 0x51, 0x5b, + 0x9a, 0x36, 0x22, 0x7d, 0x54, 0xff, 0x13, 0x72, 0xe6, 0xb5, 0x1c, 0xbb, 0x7b, 0xd6, 0x98, 0x66, + 0x04, 0xd3, 0xb4, 0x63, 0xcf, 0xee, 0x9e, 0xb1, 0x45, 0x73, 0x06, 0xb6, 0xcf, 0x47, 0x4b, 0x6c, + 0xb4, 0xc4, 0x7a, 0xd8, 0xf0, 0x12, 0xd4, 0x7b, 0x96, 0xdd, 0xea, 0x39, 0x9d, 0x56, 0x60, 0x10, + 0x60, 0x06, 0xa9, 0xf5, 0x2c, 0xfb, 0x89, 0xd3, 0x31, 0xa4, 0x59, 0x28, 0xa5, 0x79, 0x1a, 0xa5, + 0x2c, 0x0b, 0x4a, 0xf3, 0x54, 0xa5, 0x5c, 0x86, 0x59, 0xca, 0xb3, 0xed, 0x12, 0xd3, 0x27, 0x21, + 0x71, 0x85, 0x11, 0x5f, 0xe8, 0x59, 0xf6, 0x3a, 0x1b, 0x89, 0xd0, 0x9b, 0xa7, 0x23, 0xf4, 0x55, + 0x41, 0x6f, 0x9e, 0x46, 0xe9, 0xf1, 0x32, 0x94, 0x02, 0x9b, 0xa3, 0x69, 0x98, 0xdc, 0xdd, 0xdb, + 0x6d, 0xd6, 0x27, 0x10, 0x40, 0x61, 0x6d, 0x7f, 0xbd, 0xb9, 0xbb, 0x51, 0xd7, 0x50, 0x19, 0x8a, + 0x1b, 0x4d, 0xde, 0xc8, 0xe1, 0x47, 0x00, 0xa1, 0x75, 0x51, 0x11, 0xf2, 0xdb, 0xcd, 0x6f, 0xd6, + 0x27, 0x28, 0xcd, 0xf3, 0xa6, 0xb1, 0xbf, 0xb5, 0xb7, 0x5b, 0xd7, 0xe8, 0xe4, 0x75, 0xa3, 0xb9, + 0x76, 0xd0, 0xac, 0xe7, 0x28, 0xc5, 0x93, 0xbd, 0x8d, 0x7a, 0x1e, 0x95, 0x60, 0xea, 0xf9, 0xda, + 0xce, 0xb3, 0x66, 0x7d, 0x12, 0x7f, 0xa1, 0x41, 0x55, 0xac, 0x17, 0xf7, 0x09, 0xf4, 0x36, 0x14, + 0x8e, 0x99, 0x5f, 0xb0, 0xad, 0x58, 0x5e, 0xbd, 0x1a, 0x5b, 0xdc, 0x88, 0xef, 0x18, 0x82, 0x16, + 0x61, 0xc8, 0x9f, 0x0c, 0xbd, 0x46, 0x6e, 0x31, 0xbf, 0x54, 0x5e, 0xad, 0x2f, 0x73, 0x87, 0x5d, + 0xde, 0x26, 0x67, 0xcf, 0xcd, 0xee, 0x80, 0x18, 0x74, 0x10, 0x21, 0x98, 0xec, 0x39, 0x2e, 0x61, + 0x3b, 0x76, 0xda, 0x60, 0xdf, 0x74, 0x1b, 0xb3, 0x45, 0x13, 0xbb, 0x95, 0x37, 0x70, 0x1b, 0xe0, + 0xe9, 0xc0, 0x4f, 0xf7, 0x8c, 0x39, 0x98, 0x1a, 0x52, 0xbe, 0xc2, 0x2b, 0x78, 0x83, 0xb9, 0x04, + 0x31, 0x3d, 0x12, 0xb8, 0x04, 0x6d, 0xa0, 0xcb, 0x50, 0xec, 0xbb, 0x64, 0xd8, 0x3a, 0x19, 0x32, + 0x8c, 0x69, 0xa3, 0x40, 0x9b, 0xdb, 0x43, 0x6c, 0x43, 0x99, 0x81, 0x64, 0xd2, 0xfb, 0x5e, 0xc8, + 0x3d, 0xc7, 0xa6, 0x8d, 0xea, 0x2e, 0xf1, 0x3e, 0x02, 0xb4, 0x41, 0xba, 0xc4, 0x27, 0x59, 0xdc, + 0x5e, 0xd1, 0x26, 0x1f, 0xd1, 0xe6, 0xc7, 0x1a, 0xcc, 0x46, 0xd8, 0x67, 0x52, 0xab, 0x01, 0xc5, + 0x0e, 0x63, 0xc6, 0x25, 0xc8, 0x1b, 0xb2, 0x89, 0x1e, 0xc0, 0xb4, 0x10, 0xc0, 0x6b, 0xe4, 0x53, + 0x56, 0xbb, 0xc8, 0x65, 0xf2, 0xf0, 0xdf, 0x35, 0x28, 0x09, 0x45, 0xf7, 0xfa, 0x68, 0x0d, 0xaa, + 0x2e, 0x6f, 0xb4, 0x98, 0x3e, 0x42, 0x22, 0x3d, 0x3d, 0x7a, 0x6c, 0x4e, 0x18, 0x15, 0x31, 0x85, + 0x75, 0xa3, 0xff, 0x83, 0xb2, 0x64, 0xd1, 0x1f, 0xf8, 0xc2, 0xe4, 0x8d, 0x28, 0x83, 0x70, 0xe7, + 0x6c, 0x4e, 0x18, 0x20, 0xc8, 0x9f, 0x0e, 0x7c, 0x74, 0x00, 0x73, 0x72, 0x32, 0xd7, 0x46, 0x88, + 0x91, 0x67, 0x5c, 0x16, 0xa3, 0x5c, 0x46, 0x97, 0x6a, 0x73, 0xc2, 0x40, 0x62, 0xbe, 0x32, 0xf8, + 0xa8, 0x04, 0x45, 0xd1, 0x8b, 0xff, 0xa1, 0x01, 0x48, 0x83, 0xee, 0xf5, 0xd1, 0x06, 0xd4, 0x5c, + 0xd1, 0x8a, 0x28, 0x7c, 0x25, 0x51, 0x61, 0xb1, 0x0e, 0x13, 0x46, 0x55, 0x4e, 0xe2, 0x2a, 0xbf, + 0x0b, 0x95, 0x80, 0x4b, 0xa8, 0xf3, 0x7c, 0x82, 0xce, 0x01, 0x87, 0xb2, 0x9c, 0x40, 0xb5, 0xfe, + 0x00, 0x2e, 0x06, 0xf3, 0x13, 0xd4, 0xbe, 0x31, 0x46, 0xed, 0x80, 0xe1, 0xac, 0xe4, 0xa0, 0x2a, + 0x0e, 0xf4, 0xac, 0xe1, 0xdd, 0xf8, 0xd7, 0x79, 0x28, 0xae, 0x3b, 0xbd, 0xbe, 0xe9, 0xd2, 0x35, + 0x2a, 0xb8, 0xc4, 0x1b, 0x74, 0x7d, 0xa6, 0x6e, 0x6d, 0xf5, 0x66, 0x14, 0x41, 0x90, 0xc9, 0xbf, + 0x06, 0x23, 0x35, 0xc4, 0x14, 0x3a, 0x59, 0x1c, 0x2d, 0xb9, 0x57, 0x98, 0x2c, 0x0e, 0x16, 0x31, + 0x45, 0xfa, 0x52, 0x3e, 0xf4, 0x25, 0x1d, 0x8a, 0x43, 0xe2, 0x86, 0xc7, 0xe1, 0xe6, 0x84, 0x21, + 0x3b, 0xd0, 0x3d, 0x98, 0x89, 0x87, 0xe6, 0x29, 0x41, 0x53, 0x6b, 0x47, 0x23, 0xf9, 0x4d, 0xa8, + 0x44, 0xce, 0x87, 0x82, 0xa0, 0x2b, 0xf7, 0x94, 0xe3, 0xe1, 0x92, 0x0c, 0x4a, 0xf4, 0x2c, 0xab, + 0x6c, 0x4e, 0x88, 0xb0, 0x84, 0xff, 0x1f, 0xaa, 0x11, 0x5d, 0x69, 0xf8, 0x6d, 0xbe, 0xff, 0x6c, + 0x6d, 0x87, 0xc7, 0xea, 0xc7, 0x2c, 0x3c, 0x1b, 0x75, 0x8d, 0x86, 0xfc, 0x9d, 0xe6, 0xfe, 0x7e, + 0x3d, 0x87, 0xaa, 0x50, 0xda, 0xdd, 0x3b, 0x68, 0x71, 0xaa, 0x3c, 0x7e, 0x27, 0xe0, 0x20, 0x62, + 0xbd, 0x12, 0xe2, 0x27, 0x94, 0x10, 0xaf, 0xc9, 0x10, 0x9f, 0x0b, 0x43, 0x7c, 0xfe, 0x51, 0x0d, + 0x2a, 0xdc, 0x3e, 0xad, 0x81, 0x4d, 0x8f, 0x99, 0x5f, 0x6a, 0x00, 0x07, 0xa7, 0xb6, 0x0c, 0x40, + 0x2b, 0x50, 0x6c, 0x73, 0xe6, 0x0d, 0x8d, 0xf9, 0xf3, 0xc5, 0x44, 0x93, 0x1b, 0x92, 0x0a, 0xbd, + 0x09, 0x45, 0x6f, 0xd0, 0x6e, 0x13, 0x4f, 0x86, 0xfb, 0xcb, 0xf1, 0x90, 0x22, 0x1c, 0xde, 0x90, + 0x74, 0x74, 0xca, 0x0b, 0xd3, 0xea, 0x0e, 0x58, 0xf0, 0x1f, 0x3f, 0x45, 0xd0, 0xe1, 0x9f, 0x69, + 0x50, 0x66, 0x52, 0x66, 0x8a, 0x63, 0x57, 0xa1, 0xc4, 0x64, 0x20, 0x1d, 0x11, 0xc9, 0xa6, 0x8d, + 0xb0, 0x03, 0xfd, 0x2f, 0x94, 0xe4, 0x0e, 0x96, 0xc1, 0xac, 0x91, 0xcc, 0x76, 0xaf, 0x6f, 0x84, + 0xa4, 0x78, 0x1b, 0x2e, 0x30, 0xab, 0xb4, 0x69, 0x62, 0x29, 0xed, 0xa8, 0xa6, 0x5e, 0x5a, 0x2c, + 0xf5, 0xd2, 0x61, 0xba, 0x7f, 0x7c, 0xe6, 0x59, 0x6d, 0xb3, 0x2b, 0xa4, 0x08, 0xda, 0xf8, 0x1b, + 0x80, 0x54, 0x66, 0x59, 0xd4, 0xc5, 0x55, 0x28, 0x6f, 0x9a, 0xde, 0xb1, 0x10, 0x09, 0x7f, 0x08, + 0x15, 0xde, 0xcc, 0x64, 0x43, 0x04, 0x93, 0xc7, 0xa6, 0x77, 0xcc, 0x04, 0xaf, 0x1a, 0xec, 0x1b, + 0x5f, 0x80, 0x99, 0x7d, 0xdb, 0xec, 0x7b, 0xc7, 0x8e, 0x8c, 0xb5, 0x34, 0xb1, 0xae, 0x87, 0x7d, + 0x99, 0x10, 0xef, 0xc2, 0x8c, 0x4b, 0x7a, 0xa6, 0x65, 0x5b, 0xf6, 0x51, 0xeb, 0xf0, 0xcc, 0x27, + 0x9e, 0xc8, 0xbb, 0x6b, 0x41, 0xf7, 0x23, 0xda, 0x4b, 0x45, 0x3b, 0xec, 0x3a, 0x87, 0xc2, 0xe3, + 0xd9, 0x37, 0xfe, 0x8d, 0x06, 0x95, 0x0f, 0x4c, 0xbf, 0x2d, 0xad, 0x80, 0xb6, 0xa0, 0x16, 0xf8, + 0x39, 0xeb, 0x11, 0xb2, 0xc4, 0x02, 0x3e, 0x9b, 0x23, 0x33, 0x32, 0x19, 0xf0, 0xab, 0x6d, 0xb5, + 0x83, 0xb1, 0x32, 0xed, 0x36, 0xe9, 0x06, 0xac, 0x72, 0xe9, 0xac, 0x18, 0xa1, 0xca, 0x4a, 0xed, + 0x78, 0x34, 0x13, 0x1e, 0x86, 0xdc, 0x2d, 0x7f, 0x9e, 0x03, 0x34, 0x2a, 0xc3, 0x57, 0xcd, 0x0f, + 0x6e, 0x43, 0xcd, 0xf3, 0x4d, 0xd7, 0x6f, 0xc5, 0x6e, 0x25, 0x55, 0xd6, 0x1b, 0xc4, 0xaa, 0xbb, + 0x30, 0xd3, 0x77, 0x9d, 0x23, 0x97, 0x78, 0x5e, 0xcb, 0x76, 0x7c, 0xeb, 0xc5, 0x99, 0x48, 0x8e, + 0x6a, 0xb2, 0x7b, 0x97, 0xf5, 0xa2, 0x26, 0x14, 0x5f, 0x58, 0x5d, 0x9f, 0xb8, 0x5e, 0x63, 0x6a, + 0x31, 0xbf, 0x54, 0x5b, 0x7d, 0x70, 0x9e, 0xd5, 0x96, 0xdf, 0x63, 0xf4, 0x07, 0x67, 0x7d, 0x62, + 0xc8, 0xb9, 0x6a, 0xda, 0x52, 0x88, 0xa4, 0x2d, 0xb7, 0x01, 0x42, 0x7a, 0x1a, 0xb5, 0x76, 0xf7, + 0x9e, 0x3e, 0x3b, 0xa8, 0x4f, 0xa0, 0x0a, 0x4c, 0xef, 0xee, 0x6d, 0x34, 0x77, 0x9a, 0x34, 0xae, + 0xe1, 0x15, 0x69, 0x1b, 0xd5, 0x86, 0x68, 0x1e, 0xa6, 0x5f, 0xd2, 0x5e, 0x79, 0x6d, 0xcb, 0x1b, + 0x45, 0xd6, 0xde, 0xea, 0xe0, 0xbf, 0x69, 0x50, 0x15, 0xbb, 0x20, 0xd3, 0x56, 0x54, 0x21, 0x72, + 0x11, 0x08, 0x9a, 0x23, 0xf1, 0xdd, 0xd1, 0x11, 0xa9, 0x98, 0x6c, 0x52, 0x77, 0xe7, 0x8b, 0x4d, + 0x3a, 0xc2, 0xac, 0x41, 0x1b, 0xdd, 0x83, 0x7a, 0x9b, 0xbb, 0x7b, 0xec, 0xd8, 0x31, 0x66, 0x44, + 0x7f, 0xb0, 0x48, 0xb7, 0xa1, 0x40, 0x86, 0xc4, 0xf6, 0xbd, 0x46, 0x99, 0xc5, 0xa6, 0xaa, 0x4c, + 0xb4, 0x9a, 0xb4, 0xd7, 0x10, 0x83, 0xf8, 0x7f, 0xe0, 0xc2, 0x0e, 0xcd, 0x74, 0x1f, 0xbb, 0xa6, + 0xad, 0xe6, 0xcc, 0x07, 0x07, 0x3b, 0xc2, 0x2a, 0xf4, 0x13, 0xd5, 0x20, 0xb7, 0xb5, 0x21, 0x74, + 0xc8, 0x6d, 0x6d, 0xe0, 0x4f, 0x35, 0x40, 0xea, 0xbc, 0x4c, 0x66, 0x8a, 0x31, 0x97, 0xf0, 0xf9, + 0x10, 0x7e, 0x0e, 0xa6, 0x88, 0xeb, 0x3a, 0x2e, 0x33, 0x48, 0xc9, 0xe0, 0x0d, 0x7c, 0x4b, 0xc8, + 0x60, 0x90, 0xa1, 0x73, 0x12, 0xec, 0x79, 0xce, 0x4d, 0x0b, 0x44, 0xdd, 0x86, 0xd9, 0x08, 0x55, + 0xa6, 0x18, 0x79, 0x17, 0x2e, 0x32, 0x66, 0xdb, 0x84, 0xf4, 0xd7, 0xba, 0xd6, 0x30, 0x15, 0xb5, + 0x0f, 0x97, 0xe2, 0x84, 0x5f, 0xaf, 0x8d, 0xf0, 0x3b, 0x02, 0xf1, 0xc0, 0xea, 0x91, 0x03, 0x67, + 0x27, 0x5d, 0x36, 0x1a, 0xf8, 0xe8, 0x4d, 0x58, 0x1c, 0x26, 0xec, 0x1b, 0xff, 0x4a, 0x83, 0xcb, + 0x23, 0xd3, 0xbf, 0xe6, 0x55, 0x5d, 0x00, 0x38, 0xa2, 0xdb, 0x87, 0x74, 0xe8, 0x00, 0xbf, 0xc3, + 0x29, 0x3d, 0x81, 0x9c, 0x34, 0x76, 0x54, 0x84, 0x9c, 0xc7, 0x50, 0x78, 0xc2, 0xca, 0x27, 0x8a, + 0x56, 0x93, 0x52, 0x2b, 0xdb, 0xec, 0xf1, 0x5b, 0x5d, 0xc9, 0x60, 0xdf, 0xec, 0xe8, 0x24, 0xc4, + 0x7d, 0x66, 0xec, 0xf0, 0x23, 0xba, 0x64, 0x04, 0x6d, 0x8a, 0xde, 0xee, 0x5a, 0xc4, 0xf6, 0xd9, + 0xe8, 0x24, 0x1b, 0x55, 0x7a, 0xf0, 0x32, 0xd4, 0x39, 0xd2, 0x5a, 0xa7, 0xa3, 0x1c, 0xd3, 0x01, + 0x3f, 0x2d, 0xca, 0x0f, 0xbf, 0x84, 0x0b, 0x0a, 0x7d, 0x26, 0xd3, 0xbd, 0x06, 0x05, 0x5e, 0x23, + 0x12, 0x27, 0xc4, 0x5c, 0x74, 0x16, 0x87, 0x31, 0x04, 0x0d, 0xbe, 0x0d, 0xb3, 0xa2, 0x87, 0xf4, + 0x9c, 0xa4, 0x55, 0x67, 0xf6, 0xc1, 0x3b, 0x30, 0x17, 0x25, 0xcb, 0xe4, 0x08, 0x6b, 0x12, 0xf4, + 0x59, 0xbf, 0xa3, 0x1c, 0x38, 0xf1, 0x45, 0x51, 0x0d, 0x96, 0x8b, 0x19, 0x2c, 0x10, 0x48, 0xb2, + 0xc8, 0x24, 0xd0, 0xac, 0x34, 0xff, 0x8e, 0xe5, 0x05, 0x69, 0xc5, 0x27, 0x80, 0xd4, 0xce, 0x4c, + 0x8b, 0xb2, 0x0c, 0x45, 0x6e, 0x70, 0x99, 0xb9, 0x26, 0xaf, 0x8a, 0x24, 0xa2, 0x02, 0x6d, 0x90, + 0x17, 0xae, 0x79, 0xd4, 0x23, 0x41, 0x64, 0xa5, 0xf9, 0x9a, 0xda, 0x99, 0x49, 0xe3, 0x3f, 0x68, + 0x50, 0x59, 0xeb, 0x9a, 0x6e, 0x4f, 0x1a, 0xff, 0x5d, 0x28, 0xf0, 0x44, 0x50, 0xdc, 0x9d, 0xee, + 0x44, 0xd9, 0xa8, 0xb4, 0xbc, 0xb1, 0xc6, 0xd3, 0x46, 0x31, 0x8b, 0x2e, 0x96, 0x28, 0x4d, 0x6e, + 0xc4, 0x4a, 0x95, 0x1b, 0xe8, 0x75, 0x98, 0x32, 0xe9, 0x14, 0xe6, 0xbf, 0xb5, 0x78, 0x0a, 0xce, + 0xb8, 0xb1, 0x43, 0x9b, 0x53, 0xe1, 0xb7, 0xa1, 0xac, 0x20, 0xd0, 0x9b, 0xc5, 0xe3, 0xa6, 0x38, + 0x98, 0xd7, 0xd6, 0x0f, 0xb6, 0x9e, 0xf3, 0x0b, 0x47, 0x0d, 0x60, 0xa3, 0x19, 0xb4, 0x73, 0xf8, + 0x43, 0x31, 0x4b, 0x78, 0xb8, 0x2a, 0x8f, 0x96, 0x26, 0x4f, 0xee, 0x95, 0xe4, 0x39, 0x85, 0xaa, + 0x50, 0x3f, 0xd3, 0x1e, 0x78, 0x13, 0x0a, 0x8c, 0x9f, 0xdc, 0x02, 0xf3, 0x09, 0xb0, 0xd2, 0x3b, + 0x39, 0x21, 0x9e, 0x81, 0xea, 0xbe, 0x6f, 0xfa, 0x03, 0x4f, 0x6e, 0x81, 0xdf, 0x6b, 0x50, 0x93, + 0x3d, 0x59, 0xcb, 0x2c, 0xf2, 0x7a, 0xca, 0x63, 0x5e, 0x70, 0x39, 0xbd, 0x04, 0x85, 0xce, 0xe1, + 0xbe, 0xf5, 0x89, 0x2c, 0x66, 0x89, 0x16, 0xed, 0xef, 0x72, 0x1c, 0x5e, 0x50, 0x16, 0x2d, 0x7a, + 0xd1, 0x71, 0xcd, 0x17, 0xfe, 0x96, 0xdd, 0x21, 0xa7, 0x2c, 0x9f, 0x98, 0x34, 0xc2, 0x0e, 0x76, + 0x37, 0x11, 0x85, 0x67, 0x96, 0x7f, 0xa9, 0x85, 0xe8, 0x59, 0xb8, 0xb0, 0x36, 0xf0, 0x8f, 0x9b, + 0xb6, 0x79, 0xd8, 0x95, 0x41, 0x00, 0xcf, 0x01, 0xa2, 0x9d, 0x1b, 0x96, 0xa7, 0xf6, 0x36, 0x61, + 0x96, 0xf6, 0x12, 0xdb, 0xb7, 0xda, 0x4a, 0xc4, 0x90, 0x61, 0x5b, 0x8b, 0x85, 0x6d, 0xd3, 0xf3, + 0x5e, 0x3a, 0x6e, 0x47, 0xa8, 0x16, 0xb4, 0xf1, 0x06, 0x67, 0xfe, 0xcc, 0x8b, 0x04, 0xe6, 0xaf, + 0xca, 0x65, 0x29, 0xe4, 0xf2, 0x98, 0xf8, 0x63, 0xb8, 0xe0, 0x07, 0x70, 0x51, 0x52, 0x8a, 0xfa, + 0xc5, 0x18, 0xe2, 0x3d, 0xb8, 0x26, 0x89, 0xd7, 0x8f, 0x69, 0x56, 0xfd, 0x54, 0x00, 0xfe, 0xa7, + 0x72, 0x3e, 0x82, 0x46, 0x20, 0x27, 0xcb, 0xb4, 0x9c, 0xae, 0x2a, 0xc0, 0xc0, 0x13, 0x7b, 0xa6, + 0x64, 0xb0, 0x6f, 0xda, 0xe7, 0x3a, 0xdd, 0xe0, 0x10, 0xa4, 0xdf, 0x78, 0x1d, 0xe6, 0x25, 0x0f, + 0x91, 0x03, 0x45, 0x99, 0x8c, 0x08, 0x94, 0xc4, 0x44, 0x18, 0x8c, 0x4e, 0x1d, 0x6f, 0x76, 0x95, + 0x32, 0x6a, 0x5a, 0xc6, 0x53, 0x53, 0x78, 0x5e, 0xe4, 0x3b, 0x82, 0x0a, 0xa6, 0x06, 0x6d, 0xd1, + 0x4d, 0x19, 0xa8, 0xdd, 0x62, 0x21, 0x68, 0xf7, 0xc8, 0x42, 0x8c, 0xb0, 0xfe, 0x08, 0x16, 0x02, + 0x21, 0xa8, 0xdd, 0x9e, 0x12, 0xb7, 0x67, 0x79, 0x9e, 0x72, 0xe3, 0x4e, 0x52, 0xfc, 0x0e, 0x4c, + 0xf6, 0x89, 0x88, 0x29, 0xe5, 0x55, 0xb4, 0xcc, 0x9f, 0x87, 0x96, 0x95, 0xc9, 0x6c, 0x1c, 0x77, + 0xe0, 0xba, 0xe4, 0xce, 0x2d, 0x9a, 0xc8, 0x3e, 0x2e, 0x94, 0xbc, 0x8d, 0x71, 0xb3, 0x8e, 0xde, + 0xc6, 0xf2, 0x7c, 0xed, 0xe5, 0x6d, 0x8c, 0x9e, 0x15, 0xaa, 0x6f, 0x65, 0x3a, 0x2b, 0xb6, 0xb9, + 0x4d, 0x03, 0x97, 0xcc, 0xc4, 0xec, 0x10, 0xe6, 0xa2, 0x9e, 0x9c, 0x29, 0x8c, 0xcd, 0xc1, 0x94, + 0xef, 0x9c, 0x10, 0x19, 0xc4, 0x78, 0x43, 0x0a, 0x1c, 0xb8, 0x79, 0x26, 0x81, 0xcd, 0x90, 0x19, + 0xdb, 0x92, 0x59, 0xe5, 0xa5, 0xab, 0x29, 0xf3, 0x19, 0xde, 0xc0, 0xbb, 0x70, 0x29, 0x1e, 0x26, + 0x32, 0x89, 0xfc, 0x9c, 0x6f, 0xe0, 0xa4, 0x48, 0x92, 0x89, 0xef, 0xfb, 0x61, 0x30, 0x50, 0x02, + 0x4a, 0x26, 0x96, 0x06, 0xe8, 0x49, 0xf1, 0xe5, 0xbf, 0xb1, 0x5f, 0x83, 0x70, 0x93, 0x89, 0x99, + 0x17, 0x32, 0xcb, 0xbe, 0xfc, 0x61, 0x8c, 0xc8, 0x8f, 0x8d, 0x11, 0xc2, 0x49, 0xc2, 0x28, 0xf6, + 0x35, 0x6c, 0x3a, 0x81, 0x11, 0x06, 0xd0, 0xac, 0x18, 0xf4, 0x0c, 0x09, 0x30, 0x58, 0x43, 0x6e, + 0x6c, 0x35, 0xec, 0x66, 0x5a, 0x8c, 0x0f, 0xc2, 0xd8, 0x39, 0x12, 0x99, 0x33, 0x31, 0xfe, 0x10, + 0x16, 0xd3, 0x83, 0x72, 0x16, 0xce, 0xf7, 0x31, 0x94, 0x82, 0x84, 0x52, 0x79, 0x5a, 0x2d, 0x43, + 0x71, 0x77, 0x6f, 0xff, 0xe9, 0xda, 0x7a, 0xb3, 0xae, 0xad, 0xfe, 0x33, 0x0f, 0xb9, 0xed, 0xe7, + 0xe8, 0x5b, 0x30, 0xc5, 0x1f, 0x5e, 0xc6, 0xbc, 0x4b, 0xe9, 0xe3, 0x9e, 0x70, 0xf0, 0xd5, 0x4f, + 0xff, 0xf4, 0xd7, 0x2f, 0x72, 0x97, 0xf0, 0x85, 0x95, 0xe1, 0x5b, 0x66, 0xb7, 0x7f, 0x6c, 0xae, + 0x9c, 0x0c, 0x57, 0xd8, 0x99, 0xf0, 0x50, 0xbb, 0x8f, 0x9e, 0x43, 0xfe, 0xe9, 0xc0, 0x47, 0xa9, + 0x8f, 0x56, 0x7a, 0xfa, 0xd3, 0x0e, 0xd6, 0x19, 0xe7, 0x39, 0x3c, 0xa3, 0x72, 0xee, 0x0f, 0x7c, + 0xca, 0x77, 0x08, 0x65, 0xe5, 0x75, 0x06, 0x9d, 0xfb, 0x9c, 0xa5, 0x9f, 0xff, 0xf2, 0x83, 0x31, + 0xc3, 0xbb, 0x8a, 0x2f, 0xab, 0x78, 0xfc, 0x11, 0x49, 0xd5, 0xe7, 0xe0, 0xd4, 0x8e, 0xeb, 0x13, + 0x3e, 0x30, 0xc4, 0xf5, 0x51, 0x8a, 0xfa, 0xc9, 0xfa, 0xf8, 0xa7, 0x36, 0xe5, 0xeb, 0x88, 0x17, + 0xa5, 0xb6, 0x8f, 0xae, 0x27, 0xbc, 0x48, 0xa8, 0xb5, 0x77, 0x7d, 0x31, 0x9d, 0x40, 0x20, 0xdd, + 0x60, 0x48, 0x57, 0xf0, 0x25, 0x15, 0xa9, 0x1d, 0xd0, 0x3d, 0xd4, 0xee, 0xaf, 0x1e, 0xc3, 0x14, + 0xab, 0x18, 0xa2, 0x96, 0xfc, 0xd0, 0x13, 0x6a, 0x9d, 0x29, 0x3b, 0x20, 0x52, 0x6b, 0xc4, 0xf3, + 0x0c, 0x6d, 0x16, 0xd7, 0x02, 0x34, 0x56, 0x34, 0x7c, 0xa8, 0xdd, 0x5f, 0xd2, 0xde, 0xd0, 0x56, + 0xbf, 0x3f, 0x09, 0x53, 0xac, 0x52, 0x83, 0xfa, 0x00, 0x61, 0x0d, 0x2e, 0xae, 0xe7, 0x48, 0x55, + 0x2f, 0xae, 0xe7, 0x68, 0xf9, 0x0e, 0x5f, 0x67, 0xc8, 0xf3, 0x78, 0x2e, 0x40, 0x66, 0xaf, 0xe0, + 0x2b, 0xac, 0x26, 0x43, 0xcd, 0xfa, 0x12, 0xca, 0x4a, 0x2d, 0x0d, 0x25, 0x71, 0x8c, 0x14, 0xe3, + 0xe2, 0xdb, 0x24, 0xa1, 0x10, 0x87, 0x6f, 0x32, 0xd0, 0x6b, 0xb8, 0xa1, 0x1a, 0x97, 0xe3, 0xba, + 0x8c, 0x92, 0x02, 0x7f, 0xa6, 0x41, 0x2d, 0x5a, 0x4f, 0x43, 0x37, 0x13, 0x58, 0xc7, 0xcb, 0x72, + 0xfa, 0xad, 0xf1, 0x44, 0xa9, 0x22, 0x70, 0xfc, 0x13, 0x42, 0xfa, 0x26, 0xa5, 0x14, 0xb6, 0x47, + 0x3f, 0xd0, 0x60, 0x26, 0x56, 0x25, 0x43, 0x49, 0x10, 0x23, 0x35, 0x38, 0xfd, 0xf6, 0x39, 0x54, + 0x42, 0x92, 0xbb, 0x4c, 0x92, 0x1b, 0xf8, 0xea, 0xa8, 0x31, 0x7c, 0xab, 0x47, 0x7c, 0x47, 0x48, + 0xb3, 0xfa, 0xaf, 0x3c, 0x14, 0xd7, 0xf9, 0xaf, 0x8c, 0x90, 0x0f, 0xa5, 0xa0, 0xf2, 0x84, 0x16, + 0x92, 0xaa, 0x12, 0x61, 0xca, 0xae, 0x5f, 0x4f, 0x1d, 0x17, 0x22, 0xdc, 0x61, 0x22, 0x2c, 0xe2, + 0x2b, 0x81, 0x08, 0xe2, 0xd7, 0x4c, 0x2b, 0xfc, 0xf2, 0xbd, 0x62, 0x76, 0x3a, 0x74, 0x49, 0xbe, + 0xa7, 0x41, 0x45, 0x2d, 0x28, 0xa1, 0x1b, 0x89, 0xf5, 0x10, 0xb5, 0x26, 0xa5, 0xe3, 0x71, 0x24, + 0x02, 0xff, 0x1e, 0xc3, 0xbf, 0x89, 0x17, 0xd2, 0xf0, 0x5d, 0x46, 0x1f, 0x15, 0x81, 0x97, 0x90, + 0x92, 0x45, 0x88, 0x54, 0xa8, 0x92, 0x45, 0x88, 0x56, 0xa0, 0xce, 0x17, 0x61, 0xc0, 0xe8, 0xa9, + 0x08, 0xa7, 0x00, 0x61, 0x85, 0x09, 0x25, 0x1a, 0x57, 0xb9, 0xc4, 0xc4, 0x7d, 0x70, 0xb4, 0x38, + 0x95, 0xb0, 0x03, 0x62, 0xd8, 0x5d, 0xcb, 0xa3, 0xbe, 0xb8, 0xfa, 0xdb, 0x49, 0x28, 0x3f, 0x31, + 0x2d, 0xdb, 0x27, 0xb6, 0x69, 0xb7, 0x09, 0x3a, 0x82, 0x29, 0x76, 0x4a, 0xc5, 0x03, 0x8f, 0x5a, + 0xf6, 0x89, 0x07, 0x9e, 0x48, 0x4d, 0x04, 0xdf, 0x66, 0xd0, 0xd7, 0xb1, 0x1e, 0x40, 0xf7, 0x42, + 0xfe, 0x2b, 0xac, 0x9e, 0x41, 0x55, 0x3e, 0x81, 0x02, 0xaf, 0x5f, 0xa0, 0x18, 0xb7, 0x48, 0x9d, + 0x43, 0xbf, 0x9a, 0x3c, 0x98, 0xba, 0xcb, 0x54, 0x2c, 0x8f, 0x11, 0x53, 0xb0, 0x6f, 0x03, 0x84, + 0x05, 0xb3, 0xb8, 0x7d, 0x47, 0xea, 0x6b, 0xfa, 0x62, 0x3a, 0x81, 0x00, 0xbe, 0xcf, 0x80, 0x6f, + 0xe1, 0xeb, 0x89, 0xc0, 0x9d, 0x60, 0x02, 0x05, 0x6f, 0xc3, 0xe4, 0xa6, 0xe9, 0x1d, 0xa3, 0xd8, + 0x21, 0xa4, 0xbc, 0x92, 0xea, 0x7a, 0xd2, 0x90, 0x80, 0xba, 0xc5, 0xa0, 0x16, 0xf0, 0x7c, 0x22, + 0xd4, 0xb1, 0xe9, 0xd1, 0x98, 0x8e, 0x06, 0x30, 0x2d, 0x5f, 0x3e, 0xd1, 0xb5, 0x98, 0xcd, 0xa2, + 0xaf, 0xa4, 0xfa, 0x42, 0xda, 0xb0, 0x00, 0x5c, 0x62, 0x80, 0x18, 0x5f, 0x4b, 0x36, 0xaa, 0x20, + 0x7f, 0xa8, 0xdd, 0x7f, 0x43, 0x5b, 0xfd, 0x51, 0x1d, 0x26, 0x69, 0xbe, 0x44, 0x4f, 0x91, 0xf0, + 0x9a, 0x19, 0xb7, 0xf0, 0x48, 0x71, 0x27, 0x6e, 0xe1, 0xd1, 0x1b, 0x6a, 0xc2, 0x29, 0xc2, 0x7e, + 0x6b, 0x49, 0x18, 0x15, 0xd5, 0xd8, 0x87, 0xb2, 0x72, 0x19, 0x45, 0x09, 0x1c, 0xa3, 0xa5, 0xa3, + 0xf8, 0x29, 0x92, 0x70, 0x93, 0xc5, 0x8b, 0x0c, 0x54, 0xc7, 0x17, 0xa3, 0xa0, 0x1d, 0x4e, 0x46, + 0x51, 0xbf, 0x03, 0x15, 0xf5, 0xd6, 0x8a, 0x12, 0x98, 0xc6, 0x6a, 0x53, 0xf1, 0x58, 0x91, 0x74, + 0xe9, 0x4d, 0x70, 0x9a, 0xe0, 0x97, 0xa5, 0x92, 0x96, 0xa2, 0x7f, 0x0c, 0x45, 0x71, 0x97, 0x4d, + 0xd2, 0x37, 0x5a, 0xcd, 0x4a, 0xd2, 0x37, 0x76, 0x11, 0x4e, 0x48, 0x49, 0x18, 0x2c, 0xcd, 0xd9, + 0x65, 0x80, 0x16, 0x90, 0x8f, 0x89, 0x9f, 0x06, 0x19, 0xd6, 0x67, 0xd2, 0x20, 0x95, 0xfb, 0xd2, + 0x58, 0xc8, 0x23, 0xe2, 0x8b, 0xbd, 0x2c, 0x2f, 0x23, 0x28, 0x85, 0xa3, 0x1a, 0x0d, 0xf1, 0x38, + 0x92, 0xd4, 0x2c, 0x32, 0x44, 0x15, 0xa1, 0x10, 0x7d, 0x17, 0x20, 0xbc, 0x78, 0xc7, 0x13, 0x83, + 0xc4, 0xea, 0x5d, 0x3c, 0x31, 0x48, 0xbe, 0xbb, 0x27, 0x78, 0x70, 0x08, 0xce, 0x33, 0x59, 0x0a, + 0xff, 0x13, 0x0d, 0xd0, 0xe8, 0x45, 0x1d, 0x3d, 0x48, 0x86, 0x48, 0x2c, 0x0c, 0xea, 0xaf, 0xbd, + 0x1a, 0x71, 0x6a, 0xf4, 0x0c, 0xe5, 0x6a, 0xb3, 0x29, 0xfd, 0x97, 0x54, 0xb2, 0xcf, 0x35, 0xa8, + 0x46, 0xae, 0xfa, 0xe8, 0x4e, 0xca, 0x3a, 0xc7, 0x8a, 0x8b, 0xfa, 0xdd, 0x73, 0xe9, 0x52, 0x73, + 0x27, 0x65, 0x57, 0xc8, 0xbc, 0xf1, 0x87, 0x1a, 0xd4, 0xa2, 0xf5, 0x01, 0x94, 0x02, 0x30, 0x52, + 0xa1, 0xd4, 0x97, 0xce, 0x27, 0x7c, 0x85, 0xd5, 0x0a, 0x53, 0xc9, 0x8f, 0xa1, 0x28, 0xca, 0x0a, + 0x49, 0x6e, 0x11, 0x2d, 0x70, 0x26, 0xb9, 0x45, 0xac, 0x26, 0x91, 0xe6, 0x16, 0xf4, 0x86, 0xae, + 0x78, 0xa2, 0x28, 0x3e, 0xa4, 0x41, 0x8e, 0xf7, 0xc4, 0x58, 0xe5, 0x62, 0x2c, 0x64, 0xe8, 0x89, + 0xb2, 0xf4, 0x80, 0x52, 0x38, 0x9e, 0xe3, 0x89, 0xf1, 0xca, 0x45, 0x9a, 0x27, 0x32, 0x54, 0xc5, + 0x13, 0xc3, 0x4a, 0x41, 0x92, 0x27, 0x8e, 0x94, 0x6f, 0x93, 0x3c, 0x71, 0xb4, 0xd8, 0x90, 0xb6, + 0xb6, 0x0c, 0x3c, 0xe2, 0x89, 0xb3, 0x09, 0x95, 0x05, 0xf4, 0x5a, 0x8a, 0x4d, 0x13, 0x4b, 0xc3, + 0xfa, 0xeb, 0xaf, 0x48, 0x3d, 0xde, 0x03, 0xf8, 0x6a, 0x48, 0x0f, 0xf8, 0x85, 0x06, 0x73, 0x49, + 0xa5, 0x09, 0x94, 0x02, 0x96, 0x52, 0x57, 0xd6, 0x97, 0x5f, 0x95, 0xfc, 0x15, 0xec, 0x16, 0xf8, + 0xc4, 0xa3, 0xfa, 0xef, 0xbe, 0x5c, 0xd0, 0xfe, 0xf8, 0xe5, 0x82, 0xf6, 0xe7, 0x2f, 0x17, 0xb4, + 0x9f, 0xfe, 0x65, 0x61, 0xe2, 0xb0, 0xc0, 0xfe, 0xc3, 0xc3, 0x5b, 0xff, 0x0e, 0x00, 0x00, 0xff, + 0xff, 0x73, 0x7e, 0xb4, 0xb4, 0x77, 0x31, 0x00, 0x00, } diff --git a/vendor/github.com/coreos/etcd/etcdserver/etcdserverpb/rpc.pb.gw.go b/vendor/github.com/coreos/etcd/etcdserver/etcdserverpb/rpc.pb.gw.go index a2efbcd98..473ad582e 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/etcdserverpb/rpc.pb.gw.go +++ b/vendor/github.com/coreos/etcd/etcdserver/etcdserverpb/rpc.pb.gw.go @@ -222,6 +222,19 @@ func request_Lease_LeaseKeepAlive_0(ctx context.Context, marshaler runtime.Marsh return stream, metadata, nil } +func request_Lease_LeaseTimeToLive_0(ctx context.Context, marshaler runtime.Marshaler, client LeaseClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq LeaseTimeToLiveRequest + var metadata runtime.ServerMetadata + + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { + return nil, metadata, grpc.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.LeaseTimeToLive(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + func request_Cluster_MemberAdd_0(ctx context.Context, marshaler runtime.Marshaler, client ClusterClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { var protoReq MemberAddRequest var metadata runtime.ServerMetadata @@ -935,6 +948,34 @@ func RegisterLeaseHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc }) + mux.Handle("POST", pattern_Lease_LeaseTimeToLive_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(ctx) + defer cancel() + if cn, ok := w.(http.CloseNotifier); ok { + go func(done <-chan struct{}, closed <-chan bool) { + select { + case <-done: + case <-closed: + cancel() + } + }(ctx.Done(), cn.CloseNotify()) + } + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, req) + if err != nil { + runtime.HTTPError(ctx, outboundMarshaler, w, req, err) + } + resp, md, err := request_Lease_LeaseTimeToLive_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, outboundMarshaler, w, req, err) + return + } + + forward_Lease_LeaseTimeToLive_0(ctx, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + return nil } @@ -944,6 +985,8 @@ var ( pattern_Lease_LeaseRevoke_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"v3alpha", "kv", "lease", "revoke"}, "")) pattern_Lease_LeaseKeepAlive_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v3alpha", "lease", "keepalive"}, "")) + + pattern_Lease_LeaseTimeToLive_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"v3alpha", "kv", "lease", "timetolive"}, "")) ) var ( @@ -952,6 +995,8 @@ var ( forward_Lease_LeaseRevoke_0 = runtime.ForwardResponseMessage forward_Lease_LeaseKeepAlive_0 = runtime.ForwardResponseStream + + forward_Lease_LeaseTimeToLive_0 = runtime.ForwardResponseMessage ) // RegisterClusterHandlerFromEndpoint is same as RegisterClusterHandler but diff --git a/vendor/github.com/coreos/etcd/etcdserver/etcdserverpb/rpc.proto b/vendor/github.com/coreos/etcd/etcdserver/etcdserverpb/rpc.proto index 5c04ccb8e..ddf1ad233 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/etcdserverpb/rpc.proto +++ b/vendor/github.com/coreos/etcd/etcdserver/etcdserverpb/rpc.proto @@ -104,8 +104,15 @@ service Lease { }; } + // LeaseTimeToLive retrieves lease information. + rpc LeaseTimeToLive(LeaseTimeToLiveRequest) returns (LeaseTimeToLiveResponse) { + option (google.api.http) = { + post: "/v3alpha/kv/lease/timetolive" + body: "*" + }; + } + // TODO(xiangli) List all existing Leases? - // TODO(xiangli) Get details information (expirations, leased keys, etc.) of a lease? } service Cluster { @@ -375,6 +382,22 @@ message RangeRequest { // count_only when set returns only the count of the keys in the range. bool count_only = 9; + + // min_mod_revision is the lower bound for returned key mod revisions; all keys with + // lesser mod revisions will be filtered away. + int64 min_mod_revision = 10; + + // max_mod_revision is the upper bound for returned key mod revisions; all keys with + // greater mod revisions will be filtered away. + int64 max_mod_revision = 11; + + // min_create_revision is the lower bound for returned key create revisions; all keys with + // lesser create trevisions will be filtered away. + int64 min_create_revision = 12; + + // max_create_revision is the upper bound for returned key create revisions; all keys with + // greater create revisions will be filtered away. + int64 max_create_revision = 13; } message RangeResponse { @@ -413,8 +436,11 @@ message DeleteRangeRequest { bytes key = 1; // range_end is the key following the last key to delete for the range [key, range_end). // If range_end is not given, the range is defined to contain only the key argument. + // If range_end is one bit larger than the given key, then the range is all + // the all keys with the prefix (the given key). // 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; @@ -451,6 +477,7 @@ message Compare { EQUAL = 0; GREATER = 1; LESS = 2; + NOT_EQUAL = 3; } enum CompareTarget { VERSION = 0; @@ -566,6 +593,8 @@ message WatchCreateRequest { // range_end is the end of the range [key, range_end) to watch. If range_end is not given, // only the key argument is watched. If range_end is equal to '\0', all keys greater than // or equal to the key argument are watched. + // If the range_end is one bit larger than the given key, + // then all keys with the prefix (the given key) will be watched. bytes range_end = 2; // start_revision is an optional revision to watch from (inclusive). No start_revision is "now". int64 start_revision = 3; @@ -574,6 +603,16 @@ 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; + + enum FilterType { + // filter out put event. + NOPUT = 0; + // filter out delete event. + NODELETE = 1; + } + // filters filter the events at server side before it sends back to the watcher. + repeated FilterType filters = 5; + // 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; @@ -647,6 +686,25 @@ message LeaseKeepAliveResponse { int64 TTL = 3; } +message LeaseTimeToLiveRequest { + // ID is the lease ID for the lease. + int64 ID = 1; + // keys is true to query all the keys attached to this lease. + bool keys = 2; +} + +message LeaseTimeToLiveResponse { + ResponseHeader header = 1; + // ID is the lease ID from the keep alive request. + int64 ID = 2; + // TTL is the remaining TTL in seconds for the lease; the lease will expire in under TTL+1 seconds. + int64 TTL = 3; + // GrantedTTL is the initial granted time in seconds upon lease creation/renewal. + int64 grantedTTL = 4; + // Keys is the list of keys attached to this lease. + repeated bytes keys = 5; +} + message Member { // ID is the member ID for this member. uint64 ID = 1; diff --git a/vendor/github.com/coreos/etcd/etcdserver/membership/cluster.go b/vendor/github.com/coreos/etcd/etcdserver/membership/cluster.go index 4e757725d..25c45dfce 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/membership/cluster.go +++ b/vendor/github.com/coreos/etcd/etcdserver/membership/cluster.go @@ -24,6 +24,9 @@ import ( "sort" "strings" "sync" + "time" + + "golang.org/x/net/context" "github.com/coreos/etcd/mvcc/backend" "github.com/coreos/etcd/pkg/netutil" @@ -484,8 +487,10 @@ func ValidateClusterAndAssignIDs(local *RaftCluster, existing *RaftCluster) erro sort.Sort(MembersByPeerURLs(ems)) sort.Sort(MembersByPeerURLs(lms)) + ctx, cancel := context.WithTimeout(context.TODO(), 30*time.Second) + defer cancel() for i := range ems { - if !netutil.URLStringsEqual(ems[i].PeerURLs, lms[i].PeerURLs) { + if !netutil.URLStringsEqual(ctx, ems[i].PeerURLs, lms[i].PeerURLs) { return fmt.Errorf("unmatched member while checking PeerURLs") } lms[i].ID = ems[i].ID diff --git a/vendor/github.com/coreos/etcd/etcdserver/membership/member.go b/vendor/github.com/coreos/etcd/etcdserver/membership/member.go index 35ce3a973..6de74d26f 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/membership/member.go +++ b/vendor/github.com/coreos/etcd/etcdserver/membership/member.go @@ -27,7 +27,7 @@ import ( ) var ( - plog = capnslog.NewPackageLogger("github.com/coreos/etcd/etcdserver", "membership") + plog = capnslog.NewPackageLogger("github.com/coreos/etcd", "etcdserver/membership") ) // RaftAttributes represents the raft related attributes of an etcd member. diff --git a/vendor/github.com/coreos/etcd/etcdserver/metrics.go b/vendor/github.com/coreos/etcd/etcdserver/metrics.go index c701a9175..2b549f738 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/metrics.go +++ b/vendor/github.com/coreos/etcd/etcdserver/metrics.go @@ -52,7 +52,7 @@ var ( Name: "proposals_pending", Help: "The current number of pending proposals to commit.", }) - proposalsFailed = prometheus.NewGauge(prometheus.GaugeOpts{ + proposalsFailed = prometheus.NewCounter(prometheus.CounterOpts{ Namespace: "etcd", Subsystem: "server", Name: "proposals_failed_total", diff --git a/vendor/github.com/coreos/etcd/etcdserver/raft.go b/vendor/github.com/coreos/etcd/etcdserver/raft.go index 95e95fd22..d7ec176eb 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/raft.go +++ b/vendor/github.com/coreos/etcd/etcdserver/raft.go @@ -98,18 +98,25 @@ type raftNode struct { // last lead elected time lt time.Time + // to check if msg receiver is removed from cluster + isIDRemoved func(id uint64) bool + raft.Node + // a chan to send/receive snapshot + msgSnapC chan raftpb.Message + // a chan to send out apply applyc chan apply - // TODO: remove the etcdserver related logic from raftNode - // TODO: add a state machine interface to apply the commit entries - // and do snapshot/recover - s *EtcdServer + // a chan to send out readState + readStateC chan raft.ReadState // utility - ticker <-chan time.Time + ticker <-chan time.Time + // contention detectors for raft heartbeat message + td *contention.TimeoutDetector + heartbeat time.Duration // for logging raftStorage *raft.MemoryStorage storage Storage // transport specifies the transport to send and receive msgs to members. @@ -118,32 +125,19 @@ type raftNode struct { // If transport is nil, server will panic. transport rafthttp.Transporter - td *contention.TimeoutDetector - stopped chan struct{} done chan struct{} } // start prepares and starts raftNode in a new goroutine. It is no longer safe // to modify the fields after it has been started. -// TODO: Ideally raftNode should get rid of the passed in server structure. -func (r *raftNode) start(s *EtcdServer) { - r.s = s +func (r *raftNode) start(rh *raftReadyHandler) { r.applyc = make(chan apply) r.stopped = make(chan struct{}) r.done = make(chan struct{}) - - heartbeat := 200 * time.Millisecond - if s.Cfg != nil { - heartbeat = time.Duration(s.Cfg.TickMs) * time.Millisecond - } - // set up contention detectors for raft heartbeat message. - // expect to send a heartbeat within 2 heartbeat intervals. - r.td = contention.NewTimeoutDetector(2 * heartbeat) + internalTimeout := time.Second go func() { - var syncC <-chan time.Time - defer r.onStop() islead := false @@ -167,32 +161,17 @@ func (r *raftNode) start(s *EtcdServer) { } atomic.StoreUint64(&r.lead, rd.SoftState.Lead) - if rd.RaftState == raft.StateLeader { - islead = true - // TODO: raft should send server a notification through chan when - // it promotes or demotes instead of modifying server directly. - syncC = r.s.SyncTicker - if r.s.lessor != nil { - r.s.lessor.Promote(r.s.Cfg.electionTimeout()) - } - // TODO: remove the nil checking - // current test utility does not provide the stats - if r.s.stats != nil { - r.s.stats.BecomeLeader() - } - if r.s.compactor != nil { - r.s.compactor.Resume() - } - r.td.Reset() - } else { - islead = false - if r.s.lessor != nil { - r.s.lessor.Demote() - } - if r.s.compactor != nil { - r.s.compactor.Pause() - } - syncC = nil + islead = rd.RaftState == raft.StateLeader + rh.updateLeadership() + } + + if len(rd.ReadStates) != 0 { + select { + case r.readStateC <- rd.ReadStates[len(rd.ReadStates)-1]: + case <-time.After(internalTimeout): + plog.Warningf("timed out sending read state") + case <-r.stopped: + return } } @@ -203,6 +182,8 @@ func (r *raftNode) start(s *EtcdServer) { raftDone: raftDone, } + updateCommittedIndex(&ap, rh) + select { case r.applyc <- ap: case <-r.stopped: @@ -214,7 +195,7 @@ func (r *raftNode) start(s *EtcdServer) { // For more details, check raft thesis 10.2.1 if islead { // gofail: var raftBeforeLeaderSend struct{} - r.s.send(rd.Messages) + r.sendMessages(rd.Messages) } // gofail: var raftBeforeSave struct{} @@ -241,12 +222,10 @@ func (r *raftNode) start(s *EtcdServer) { if !islead { // gofail: var raftBeforeFollowerSend struct{} - r.s.send(rd.Messages) + r.sendMessages(rd.Messages) } raftDone <- struct{}{} r.Advance() - case <-syncC: - r.s.sync(r.s.Cfg.ReqTimeout()) case <-r.stopped: return } @@ -254,6 +233,59 @@ func (r *raftNode) start(s *EtcdServer) { }() } +func updateCommittedIndex(ap *apply, rh *raftReadyHandler) { + var ci uint64 + if len(ap.entries) != 0 { + ci = ap.entries[len(ap.entries)-1].Index + } + if ap.snapshot.Metadata.Index > ci { + ci = ap.snapshot.Metadata.Index + } + if ci != 0 { + rh.updateCommittedIndex(ci) + } +} + +func (r *raftNode) sendMessages(ms []raftpb.Message) { + sentAppResp := false + for i := len(ms) - 1; i >= 0; i-- { + if r.isIDRemoved(ms[i].To) { + ms[i].To = 0 + } + + if ms[i].Type == raftpb.MsgAppResp { + if sentAppResp { + ms[i].To = 0 + } else { + sentAppResp = true + } + } + + if ms[i].Type == raftpb.MsgSnap { + // There are two separate data store: the store for v2, and the KV for v3. + // The msgSnap only contains the most recent snapshot of store without KV. + // So we need to redirect the msgSnap to etcd server main loop for merging in the + // current store snapshot and KV snapshot. + select { + case r.msgSnapC <- ms[i]: + default: + // drop msgSnap if the inflight chan if full. + } + ms[i].To = 0 + } + if ms[i].Type == raftpb.MsgHeartbeat { + ok, exceed := r.td.Observe(ms[i].To) + if !ok { + // TODO: limit request rate. + plog.Warningf("failed to send out heartbeat on time (exceeded the %v timeout for %v)", r.heartbeat, exceed) + plog.Warningf("server is likely overloaded") + } + } + } + + r.transport.Send(ms) +} + func (r *raftNode) apply() chan apply { return r.applyc } diff --git a/vendor/github.com/coreos/etcd/etcdserver/server.go b/vendor/github.com/coreos/etcd/etcdserver/server.go index 3644e7d51..4ebe7eb4c 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/server.go +++ b/vendor/github.com/coreos/etcd/etcdserver/server.go @@ -23,6 +23,7 @@ import ( "net/http" "os" "path" + "path/filepath" "regexp" "sync" "sync/atomic" @@ -40,6 +41,7 @@ import ( "github.com/coreos/etcd/lease" "github.com/coreos/etcd/mvcc" "github.com/coreos/etcd/mvcc/backend" + "github.com/coreos/etcd/pkg/contention" "github.com/coreos/etcd/pkg/fileutil" "github.com/coreos/etcd/pkg/idutil" "github.com/coreos/etcd/pkg/pbutil" @@ -65,6 +67,10 @@ const ( StoreClusterPrefix = "/0" StoreKeysPrefix = "/1" + // HealthInterval is the minimum time the cluster should be healthy + // before accepting add member requests. + HealthInterval = 5 * time.Second + purgeFileInterval = 30 * time.Second // monitorVersionInterval should be smaller than the timeout // on the connection. Or we will not be able to reuse the connection @@ -77,6 +83,9 @@ const ( maxInFlightMsgSnap = 16 releaseDelayAfterSnapshot = 30 * time.Second + + // maxPendingRevokes is the maximum number of outstanding expired lease revocations. + maxPendingRevokes = 16 ) var ( @@ -158,6 +167,7 @@ type EtcdServer struct { // inflightSnapshots holds count the number of snapshots currently inflight. inflightSnapshots int64 // must use atomic operations to access; keep 64-bit aligned. appliedIndex uint64 // must use atomic operations to access; keep 64-bit aligned. + committedIndex uint64 // must use atomic operations to access; keep 64-bit aligned. // consistIndex used to hold the offset of current executing entry // It is initialized to 0 before executing any entry. consistIndex consistentIndex // must use atomic operations to access; keep 64-bit aligned. @@ -168,9 +178,23 @@ type EtcdServer struct { snapCount uint64 - w wait.Wait - stop chan struct{} - done chan struct{} + w wait.Wait + + readMu sync.RWMutex + // read routine notifies etcd server that it waits for reading by sending an empty struct to + // readwaitC + readwaitc chan struct{} + // readNotifier is used to notify the read routine that it can process the request + // when there is no error + readNotifier *notifier + + // stop signals the run goroutine should shutdown. + stop chan struct{} + // stopping is closed by run goroutine on shutdown. + stopping chan struct{} + // done is closed when all goroutines from start() complete. + done chan struct{} + errorc chan error id types.ID attributes membership.Attributes @@ -181,7 +205,12 @@ type EtcdServer struct { applyV2 ApplierV2 - applyV3 applierV3 + // applyV3 is the applier with auth and quotas + applyV3 applierV3 + // applyV3Base is the core applier without auth or quotas + applyV3Base applierV3 + applyWait wait.WaitTime + kv mvcc.ConsistentWatchableKV lessor lease.Lessor bemu sync.Mutex @@ -204,8 +233,8 @@ type EtcdServer struct { // to detect the cluster version immediately. forceVersionC chan struct{} - msgSnapC chan raftpb.Message - + // wgMu blocks concurrent waitgroup mutation while server stopping + wgMu sync.RWMutex // wg is used to wait for the go routines that depends on the server state // to exit when stopping the server. wg sync.WaitGroup @@ -228,15 +257,6 @@ func NewServer(cfg *ServerConfig) (srv *EtcdServer, err error) { return nil, fmt.Errorf("cannot access data directory: %v", terr) } - // Run the migrations. - dataVer, err := version.DetectDataDir(cfg.DataDir) - if err != nil { - return nil, err - } - if err = upgradeDataDir(cfg.DataDir, cfg.Name, dataVer); err != nil { - return nil, err - } - haveWAL := wal.Exist(cfg.WALDir()) if err = fileutil.TouchDirAll(cfg.SnapDir()); err != nil { @@ -244,9 +264,24 @@ func NewServer(cfg *ServerConfig) (srv *EtcdServer, err error) { } ss := snap.New(cfg.SnapDir()) - bepath := path.Join(cfg.SnapDir(), databaseFilename) + bepath := filepath.Join(cfg.SnapDir(), databaseFilename) beExist := fileutil.Exist(bepath) - be := backend.NewDefaultBackend(bepath) + + var be backend.Backend + beOpened := make(chan struct{}) + go func() { + be = backend.NewDefaultBackend(bepath) + beOpened <- struct{}{} + }() + + select { + case <-beOpened: + case <-time.After(time.Second): + plog.Warningf("another etcd process is running with the same data dir and holding the file lock.") + plog.Warningf("waiting for it to exit before starting...") + <-beOpened + } + defer func() { if err != nil { be.Close() @@ -372,6 +407,7 @@ func NewServer(cfg *ServerConfig) (srv *EtcdServer, err error) { sstats.Initialize() lstats := stats.NewLeaderStats(id.String()) + heartbeat := time.Duration(cfg.TickMs) * time.Millisecond srv = &EtcdServer{ readych: make(chan struct{}), Cfg: cfg, @@ -379,10 +415,17 @@ func NewServer(cfg *ServerConfig) (srv *EtcdServer, err error) { errorc: make(chan error, 1), store: st, r: raftNode{ + isIDRemoved: func(id uint64) bool { return cl.IsIDRemoved(types.ID(id)) }, Node: n, - ticker: time.Tick(time.Duration(cfg.TickMs) * time.Millisecond), + ticker: time.Tick(heartbeat), + // set up contention detectors for raft heartbeat message. + // expect to send a heartbeat within 2 heartbeat intervals. + td: contention.NewTimeoutDetector(2 * heartbeat), + heartbeat: heartbeat, raftStorage: s, storage: NewStorage(w, ss), + msgSnapC: make(chan raftpb.Message, maxInFlightMsgSnap), + readStateC: make(chan raft.ReadState, 1), }, id: id, attributes: membership.Attributes{Name: cfg.Name, ClientURLs: cfg.ClientURLs.StringSlice()}, @@ -393,15 +436,16 @@ func NewServer(cfg *ServerConfig) (srv *EtcdServer, err error) { peerRt: prt, reqIDGen: idutil.NewGenerator(uint16(id), time.Now()), forceVersionC: make(chan struct{}), - msgSnapC: make(chan raftpb.Message, maxInFlightMsgSnap), } srv.applyV2 = &applierV2store{store: srv.store, cluster: srv.cluster} srv.be = be - minTTL := time.Duration((3*cfg.ElectionTicks)/2) * time.Duration(cfg.TickMs) * time.Millisecond - srv.lessor = lease.NewLessor(srv.be, int64(math.Ceil(minTTL.Seconds()))) + minTTL := time.Duration((3*cfg.ElectionTicks)/2) * heartbeat + // always recover lessor before kv. When we recover the mvcc.KV it will reattach keys to its leases. + // If we recover mvcc.KV first, it will attach the keys to the wrong lessor before it recovers. + srv.lessor = lease.NewLessor(srv.be, int64(math.Ceil(minTTL.Seconds()))) srv.kv = mvcc.New(srv.be, srv.lessor, &srv.consistIndex) if beExist { kvindex := srv.kv.ConsistentIndex() @@ -416,12 +460,16 @@ func NewServer(cfg *ServerConfig) (srv *EtcdServer, err error) { } srv.consistIndex.setConsistentIndex(srv.kv.ConsistentIndex()) - srv.authStore = auth.NewAuthStore(srv.be) + srv.authStore = auth.NewAuthStore(srv.be, + func(index uint64) <-chan struct{} { + return srv.applyWait.Wait(index) + }) if h := cfg.AutoCompactionRetention; h != 0 { srv.compactor = compactor.NewPeriodic(h, srv.kv, srv) srv.compactor.Run() } + srv.applyV3Base = &applierV3backend{srv} if err = srv.restoreAlarms(); err != nil { return nil, err } @@ -463,10 +511,11 @@ func NewServer(cfg *ServerConfig) (srv *EtcdServer, err error) { // It also starts a goroutine to publish its server information. func (s *EtcdServer) Start() { s.start() - go s.publish(s.Cfg.ReqTimeout()) - go s.purgeFile() - go monitorFileDescriptor(s.done) - go s.monitorVersions() + s.goAttach(func() { s.publish(s.Cfg.ReqTimeout()) }) + s.goAttach(s.purgeFile) + s.goAttach(func() { monitorFileDescriptor(s.stopping) }) + s.goAttach(s.monitorVersions) + s.goAttach(s.linearizableReadLoop) } // start prepares and starts server in a new goroutine. It is no longer safe to @@ -478,8 +527,12 @@ func (s *EtcdServer) start() { s.snapCount = DefaultSnapCount } s.w = wait.New() + s.applyWait = wait.NewTimeList() s.done = make(chan struct{}) s.stop = make(chan struct{}) + s.stopping = make(chan struct{}) + s.readwaitc = make(chan struct{}, 1) + s.readNotifier = newNotifier() if s.ClusterVersion() != nil { plog.Infof("starting server... [version: %v, cluster version: %v]", version.Version, version.Cluster(s.ClusterVersion().String())) } else { @@ -503,7 +556,7 @@ func (s *EtcdServer) purgeFile() { plog.Fatalf("failed to purge wal file %v", e) case e := <-serrc: plog.Fatalf("failed to purge snap file %v", e) - case <-s.done: + case <-s.stopping: return } } @@ -516,6 +569,8 @@ func (s *EtcdServer) RaftHandler() http.Handler { return s.r.transport.Handler() func (s *EtcdServer) Lessor() lease.Lessor { return s.lessor } +func (s *EtcdServer) ApplyWait() <-chan struct{} { return s.applyWait.Wait(s.getCommittedIndex()) } + func (s *EtcdServer) Process(ctx context.Context, m raftpb.Message) error { if s.cluster.IsIDRemoved(types.ID(m.From)) { plog.Warningf("reject message from removed member %s", types.ID(m.From).String()) @@ -540,28 +595,91 @@ func (s *EtcdServer) ReportSnapshot(id uint64, status raft.SnapshotStatus) { type etcdProgress struct { confState raftpb.ConfState snapi uint64 + appliedt uint64 appliedi uint64 } +// raftReadyHandler contains a set of EtcdServer operations to be called by raftNode, +// and helps decouple state machine logic from Raft algorithms. +// TODO: add a state machine interface to apply the commit entries and do snapshot/recover +type raftReadyHandler struct { + updateLeadership func() + updateCommittedIndex func(uint64) +} + func (s *EtcdServer) run() { snap, err := s.r.raftStorage.Snapshot() if err != nil { plog.Panicf("get snapshot from raft storage error: %v", err) } - s.r.start(s) + + var ( + smu sync.RWMutex + syncC <-chan time.Time + ) + setSyncC := func(ch <-chan time.Time) { + smu.Lock() + syncC = ch + smu.Unlock() + } + getSyncC := func() (ch <-chan time.Time) { + smu.RLock() + ch = syncC + smu.RUnlock() + return + } + rh := &raftReadyHandler{ + updateLeadership: func() { + if !s.isLeader() { + if s.lessor != nil { + s.lessor.Demote() + } + if s.compactor != nil { + s.compactor.Pause() + } + setSyncC(nil) + } else { + setSyncC(s.SyncTicker) + if s.compactor != nil { + s.compactor.Resume() + } + } + + // TODO: remove the nil checking + // current test utility does not provide the stats + if s.stats != nil { + s.stats.BecomeLeader() + } + if s.r.td != nil { + s.r.td.Reset() + } + }, + updateCommittedIndex: func(ci uint64) { + cci := s.getCommittedIndex() + if ci > cci { + s.setCommittedIndex(ci) + } + }, + } + s.r.start(rh) // asynchronously accept apply packets, dispatch progress in-order sched := schedule.NewFIFOScheduler() ep := etcdProgress{ confState: snap.Metadata.ConfState, snapi: snap.Metadata.Index, + appliedt: snap.Metadata.Term, appliedi: snap.Metadata.Index, } defer func() { + s.wgMu.Lock() // block concurrent waitgroup adds in goAttach while stopping + close(s.stopping) + s.wgMu.Unlock() + sched.Stop() - // wait for snapshots before closing raft so wal stays open + // wait for gouroutines before closing raft so wal stays open s.wg.Wait() // must stop raft after scheduler-- etcdserver can leak rafthttp pipelines @@ -576,6 +694,9 @@ func (s *EtcdServer) run() { if s.kv != nil { s.kv.Close() } + if s.authStore != nil { + s.authStore.Close() + } if s.be != nil { s.be.Close() } @@ -596,15 +717,30 @@ func (s *EtcdServer) run() { f := func(context.Context) { s.applyAll(&ep, &ap) } sched.Schedule(f) case leases := <-expiredLeaseC: - go func() { - for _, l := range leases { - s.LeaseRevoke(context.TODO(), &pb.LeaseRevokeRequest{ID: int64(l.ID)}) + s.goAttach(func() { + // Increases throughput of expired leases deletion process through parallelization + c := make(chan struct{}, maxPendingRevokes) + for _, lease := range leases { + select { + case c <- struct{}{}: + case <-s.stopping: + return + } + lid := lease.ID + s.goAttach(func() { + s.LeaseRevoke(context.TODO(), &pb.LeaseRevokeRequest{ID: int64(lid)}) + <-c + }) } - }() + }) case err := <-s.errorc: plog.Errorf("%s", err) plog.Infof("the data-dir used by this member must be removed.") return + case <-getSyncC(): + if s.store.HasTTLKeys() { + s.sync(s.Cfg.ReqTimeout()) + } case <-s.stop: return } @@ -622,15 +758,17 @@ func (s *EtcdServer) applyAll(ep *etcdProgress, apply *apply) { plog.Warningf("avoid queries with large range/delete range!") } proposalsApplied.Set(float64(ep.appliedi)) + s.applyWait.Trigger(ep.appliedi) // wait for the raft routine to finish the disk writes before triggering a // snapshot. or applied index might be greater than the last index in raft // storage, since the raft routine might be slower than apply routine. <-apply.raftDone + s.triggerSnapshot(ep) select { // snapshot requested via send() - case m := <-s.msgSnapC: - merged := s.createMergedSnapshotMessage(m, ep.appliedi, ep.confState) + case m := <-s.r.msgSnapC: + merged := s.createMergedSnapshotMessage(m, ep.appliedt, ep.appliedi, ep.confState) s.sendMergedSnap(merged) default: } @@ -654,7 +792,7 @@ func (s *EtcdServer) applySnapshot(ep *etcdProgress, apply *apply) { plog.Panicf("get database snapshot file path error: %v", err) } - fn := path.Join(s.Cfg.SnapDir(), databaseFilename) + fn := filepath.Join(s.Cfg.SnapDir(), databaseFilename) if err := os.Rename(snapfn, fn); err != nil { plog.Panicf("rename snapshot file error: %v", err) } @@ -732,6 +870,7 @@ func (s *EtcdServer) applySnapshot(ep *etcdProgress, apply *apply) { } plog.Info("finished adding peers from new cluster configuration into network...") + ep.appliedt = apply.snapshot.Metadata.Term ep.appliedi = apply.snapshot.Metadata.Index ep.snapi = ep.appliedi ep.confState = apply.snapshot.Metadata.ConfState @@ -753,7 +892,7 @@ func (s *EtcdServer) applyEntries(ep *etcdProgress, apply *apply) { return } var shouldstop bool - if ep.appliedi, shouldstop = s.apply(ents, &ep.confState); shouldstop { + if ep.appliedt, ep.appliedi, shouldstop = s.apply(ents, &ep.confState); shouldstop { go s.stopWithDelay(10*100*time.Millisecond, fmt.Errorf("the member has been permanently removed from the cluster")) } } @@ -768,9 +907,62 @@ func (s *EtcdServer) triggerSnapshot(ep *etcdProgress) { ep.snapi = ep.appliedi } -// Stop stops the server gracefully, and shuts down the running goroutine. -// Stop should be called after a Start(s), otherwise it will block forever. -func (s *EtcdServer) Stop() { +func (s *EtcdServer) isMultiNode() bool { + return s.cluster != nil && len(s.cluster.MemberIDs()) > 1 +} + +func (s *EtcdServer) isLeader() bool { + return uint64(s.ID()) == s.Lead() +} + +// transferLeadership transfers the leader to the given transferee. +// TODO: maybe expose to client? +func (s *EtcdServer) transferLeadership(ctx context.Context, lead, transferee uint64) error { + now := time.Now() + interval := time.Duration(s.Cfg.TickMs) * time.Millisecond + + plog.Infof("%s starts leadership transfer from %s to %s", s.ID(), types.ID(lead), types.ID(transferee)) + s.r.TransferLeadership(ctx, lead, transferee) + for s.Lead() != transferee { + select { + case <-ctx.Done(): // time out + return ErrTimeoutLeaderTransfer + case <-time.After(interval): + } + } + + // TODO: drain all requests, or drop all messages to the old leader + + plog.Infof("%s finished leadership transfer from %s to %s (took %v)", s.ID(), types.ID(lead), types.ID(transferee), time.Since(now)) + return nil +} + +// TransferLeadership transfers the leader to the chosen transferee. +func (s *EtcdServer) TransferLeadership() error { + if !s.isLeader() { + plog.Printf("skipped leadership transfer for stopping non-leader member") + return nil + } + + if !s.isMultiNode() { + plog.Printf("skipped leadership transfer for single member cluster") + return nil + } + + transferee, ok := longestConnected(s.r.transport, s.cluster.MemberIDs()) + if !ok { + return ErrUnhealthy + } + + tm := s.Cfg.ReqTimeout() + ctx, cancel := context.WithTimeout(context.TODO(), tm) + err := s.transferLeadership(ctx, s.Lead(), uint64(transferee)) + cancel() + return err +} + +// HardStop stops the server without coordination with other members in the cluster. +func (s *EtcdServer) HardStop() { select { case s.stop <- struct{}{}: case <-s.done: @@ -779,6 +971,17 @@ func (s *EtcdServer) Stop() { <-s.done } +// Stop stops the server gracefully, and shuts down the running goroutine. +// Stop should be called after a Start(s), otherwise it will block forever. +// When stopping leader, Stop transfers its leadership to one of its peers +// before stopping the server. +func (s *EtcdServer) Stop() { + if err := s.TransferLeadership(); err != nil { + plog.Warningf("%s failed to transfer leadership (%v)", s.ID(), err) + } + s.HardStop() +} + // ReadyNotify returns a channel that will be closed when the server // is ready to serve client requests func (s *EtcdServer) ReadyNotify() <-chan struct{} { return s.readych } @@ -810,11 +1013,42 @@ func (s *EtcdServer) LeaderStats() []byte { func (s *EtcdServer) StoreStats() []byte { return s.store.JsonStats() } +func (s *EtcdServer) checkMembershipOperationPermission(ctx context.Context) error { + if s.authStore == nil { + // In the context of ordinal etcd process, s.authStore will never be nil. + // This branch is for handling cases in server_test.go + return nil + } + + // Note that this permission check is done in the API layer, + // so TOCTOU problem can be caused potentially in a schedule like this: + // update membership with user A -> revoke root role of A -> apply membership change + // in the state machine layer + // However, both of membership change and role management requires the root privilege. + // So careful operation by admins can prevent the problem. + authInfo, err := s.AuthStore().AuthInfoFromCtx(ctx) + if err != nil { + return err + } + + return s.AuthStore().IsAdminPermitted(authInfo) +} + func (s *EtcdServer) AddMember(ctx context.Context, memb membership.Member) error { - if s.Cfg.StrictReconfigCheck && !s.cluster.IsReadyToAddNewMember() { - // If s.cfg.StrictReconfigCheck is false, it means the option --strict-reconfig-check isn't passed to etcd. - // In such a case adding a new member is allowed unconditionally - return ErrNotEnoughStartedMembers + if err := s.checkMembershipOperationPermission(ctx); err != nil { + return err + } + + if s.Cfg.StrictReconfigCheck { + // by default StrictReconfigCheck is enabled; reject new members if unhealthy + if !s.cluster.IsReadyToAddNewMember() { + plog.Warningf("not enough started members, rejecting member add %+v", memb) + return ErrNotEnoughStartedMembers + } + if !isConnectedFullySince(s.r.transport, time.Now().Add(-HealthInterval), s.ID(), s.cluster.Members()) { + plog.Warningf("not healthy for reconfigure, rejecting member add %+v", memb) + return ErrUnhealthy + } } // TODO: move Member to protobuf type @@ -831,10 +1065,13 @@ func (s *EtcdServer) AddMember(ctx context.Context, memb membership.Member) erro } func (s *EtcdServer) RemoveMember(ctx context.Context, id uint64) error { - if s.Cfg.StrictReconfigCheck && !s.cluster.IsReadyToRemoveMember(id) { - // If s.cfg.StrictReconfigCheck is false, it means the option --strict-reconfig-check isn't passed to etcd. - // In such a case removing a member is allowed unconditionally - return ErrNotEnoughStartedMembers + if err := s.checkMembershipOperationPermission(ctx); err != nil { + return err + } + + // by default StrictReconfigCheck is enabled; reject removal if leads to quorum loss + if err := s.mayRemoveMember(types.ID(id)); err != nil { + return err } cc := raftpb.ConfChange{ @@ -844,9 +1081,39 @@ func (s *EtcdServer) RemoveMember(ctx context.Context, id uint64) error { return s.configure(ctx, cc) } +func (s *EtcdServer) mayRemoveMember(id types.ID) error { + if !s.Cfg.StrictReconfigCheck { + return nil + } + + if !s.cluster.IsReadyToRemoveMember(uint64(id)) { + plog.Warningf("not enough started members, rejecting remove member %s", id) + return ErrNotEnoughStartedMembers + } + + // downed member is safe to remove since it's not part of the active quorum + if t := s.r.transport.ActiveSince(id); id != s.ID() && t.IsZero() { + return nil + } + + // protect quorum if some members are down + m := s.cluster.Members() + active := numConnectedSince(s.r.transport, time.Now().Add(-HealthInterval), s.ID(), m) + if (active - 1) < 1+((len(m)-1)/2) { + plog.Warningf("reconfigure breaks active quorum, rejecting remove member %s", id) + return ErrUnhealthy + } + + return nil +} + func (s *EtcdServer) UpdateMember(ctx context.Context, memb membership.Member) error { - b, err := json.Marshal(memb) - if err != nil { + b, merr := json.Marshal(memb) + if merr != nil { + return merr + } + + if err := s.checkMembershipOperationPermission(ctx); err != nil { return err } cc := raftpb.ConfChange{ @@ -870,8 +1137,6 @@ func (s *EtcdServer) Lead() uint64 { return atomic.LoadUint64(&s.r.lead) } func (s *EtcdServer) Leader() types.ID { return types.ID(s.Lead()) } -func (s *EtcdServer) IsPprofEnabled() bool { return s.Cfg.EnablePprof } - // configure sends a configuration change through consensus and // then waits for it to be applied to the server. It // will block until the change is performed or there is an error. @@ -895,7 +1160,7 @@ func (s *EtcdServer) configure(ctx context.Context, cc raftpb.ConfChange) error case <-ctx.Done(): s.w.Trigger(cc.ID, nil) // GC wait return s.parseProposeCtxErr(ctx.Err(), start) - case <-s.done: + case <-s.stopping: return ErrStopped } } @@ -913,10 +1178,10 @@ func (s *EtcdServer) sync(timeout time.Duration) { data := pbutil.MustMarshal(&req) // There is no promise that node has leader when do SYNC request, // so it uses goroutine to propose. - go func() { + s.goAttach(func() { s.r.Propose(ctx, data) cancel() - }() + }) } // publish registers server information into the cluster. The information @@ -954,52 +1219,11 @@ func (s *EtcdServer) publish(timeout time.Duration) { } } -// TODO: move this function into raft.go -func (s *EtcdServer) send(ms []raftpb.Message) { - sentAppResp := false - for i := len(ms) - 1; i >= 0; i-- { - if s.cluster.IsIDRemoved(types.ID(ms[i].To)) { - ms[i].To = 0 - } - - if ms[i].Type == raftpb.MsgAppResp { - if sentAppResp { - ms[i].To = 0 - } else { - sentAppResp = true - } - } - - if ms[i].Type == raftpb.MsgSnap { - // There are two separate data store: the store for v2, and the KV for v3. - // The msgSnap only contains the most recent snapshot of store without KV. - // So we need to redirect the msgSnap to etcd server main loop for merging in the - // current store snapshot and KV snapshot. - select { - case s.msgSnapC <- ms[i]: - default: - // drop msgSnap if the inflight chan if full. - } - ms[i].To = 0 - } - if ms[i].Type == raftpb.MsgHeartbeat { - ok, exceed := s.r.td.Observe(ms[i].To) - if !ok { - // TODO: limit request rate. - plog.Warningf("failed to send out heartbeat on time (exceeded the %dms timeout for %v)", s.Cfg.TickMs, exceed) - plog.Warningf("server is likely overloaded") - } - } - } - - s.r.transport.Send(ms) -} - func (s *EtcdServer) sendMergedSnap(merged snap.Message) { atomic.AddInt64(&s.inflightSnapshots, 1) s.r.transport.SendSnapshot(merged) - go func() { + s.goAttach(func() { select { case ok := <-merged.CloseNotify(): // delay releasing inflight snapshot for another 30 seconds to @@ -1009,22 +1233,20 @@ func (s *EtcdServer) sendMergedSnap(merged snap.Message) { if ok { select { case <-time.After(releaseDelayAfterSnapshot): - case <-s.done: + case <-s.stopping: } } atomic.AddInt64(&s.inflightSnapshots, -1) - case <-s.done: + case <-s.stopping: return } - }() + }) } // apply takes entries received from Raft (after it has been committed) and // applies them to the current state of the EtcdServer. // The given entries should not be empty. -func (s *EtcdServer) apply(es []raftpb.Entry, confState *raftpb.ConfState) (uint64, bool) { - var applied uint64 - var shouldstop bool +func (s *EtcdServer) apply(es []raftpb.Entry, confState *raftpb.ConfState) (appliedt uint64, appliedi uint64, shouldStop bool) { for i := range es { e := es[i] switch e.Type { @@ -1034,16 +1256,17 @@ func (s *EtcdServer) apply(es []raftpb.Entry, confState *raftpb.ConfState) (uint var cc raftpb.ConfChange pbutil.MustUnmarshal(&cc, e.Data) removedSelf, err := s.applyConfChange(cc, confState) - shouldstop = shouldstop || removedSelf + shouldStop = shouldStop || removedSelf s.w.Trigger(cc.ID, err) default: plog.Panicf("entry type should be either EntryNormal or EntryConfChange") } atomic.StoreUint64(&s.r.index, e.Index) atomic.StoreUint64(&s.r.term, e.Term) - applied = e.Index + appliedt = e.Term + appliedi = e.Index } - return applied, shouldstop + return appliedt, appliedi, shouldStop } // applyEntryNormal apples an EntryNormal type raftpb request to the EtcdServer @@ -1054,6 +1277,7 @@ func (s *EtcdServer) applyEntryNormal(e *raftpb.Entry) { s.consistIndex.setConsistentIndex(e.Index) shouldApplyV3 = true } + defer s.setAppliedIndex(e.Index) // raft state machine may generate noop entry when leader confirmation. // skip it in advance to avoid some potential bug in the future @@ -1062,6 +1286,11 @@ func (s *EtcdServer) applyEntryNormal(e *raftpb.Entry) { case s.forceVersionC <- struct{}{}: default: } + // promote lessor when the local member is leader and finished + // applying all entries from the last term. + if s.isLeader() { + s.lessor.Promote(s.Cfg.electionTimeout()) + } return } @@ -1088,15 +1317,26 @@ func (s *EtcdServer) applyEntryNormal(e *raftpb.Entry) { id = raftReq.Header.ID } - ar := s.applyV3.Apply(&raftReq) - s.setAppliedIndex(e.Index) + var ar *applyResult + needResult := s.w.IsRegistered(id) + if needResult || !noSideEffect(&raftReq) { + if !needResult && raftReq.Txn != nil { + removeNeedlessRangeReqs(raftReq.Txn) + } + ar = s.applyV3.Apply(&raftReq) + } + + if ar == nil { + return + } + if ar.err != ErrNoSpace || len(s.alarmStore.Get(pb.AlarmType_NOSPACE)) > 0 { s.w.Trigger(id, ar) return } plog.Errorf("applying raft message exceeded backend quota") - go func() { + s.goAttach(func() { a := &pb.AlarmRequest{ MemberID: uint64(s.ID()), Action: pb.AlarmRequest_ACTIVATE, @@ -1105,7 +1345,7 @@ func (s *EtcdServer) applyEntryNormal(e *raftpb.Entry) { r := pb.InternalRaftRequest{Alarm: a} s.processInternalRaftRequest(context.TODO(), r) s.w.Trigger(id, ar) - }() + }) } // applyConfChange applies a ConfChange to the server. It is only @@ -1156,11 +1396,15 @@ func (s *EtcdServer) applyConfChange(cc raftpb.ConfChange, confState *raftpb.Con // TODO: non-blocking snapshot func (s *EtcdServer) snapshot(snapi uint64, confState raftpb.ConfState) { clone := s.store.Clone() + // commit kv to write metadata (for example: consistent index) to disk. + // KV().commit() updates the consistent index in backend. + // All operations that update consistent index must be called sequentially + // from applyAll function. + // So KV().Commit() cannot run in parallel with apply. It has to be called outside + // the go routine created below. + s.KV().Commit() - s.wg.Add(1) - go func() { - defer s.wg.Done() - + s.goAttach(func() { d, err := clone.SaveNoCopy() // TODO: current store will never fail to do a snapshot // what should we do if the store might fail? @@ -1176,8 +1420,6 @@ func (s *EtcdServer) snapshot(snapi uint64, confState raftpb.ConfState) { } plog.Panicf("unexpected create snapshot error %v", err) } - // commit kv to write metadata (for example: consistent index) to disk. - s.KV().Commit() // SaveSnap saves the snapshot and releases the locked wal files // to the snapshot index. if err = s.r.storage.SaveSnap(snap); err != nil { @@ -1210,7 +1452,23 @@ func (s *EtcdServer) snapshot(snapi uint64, confState raftpb.ConfState) { plog.Panicf("unexpected compaction error %v", err) } plog.Infof("compacted raft log at %d", compacti) - }() + }) +} + +// CutPeer drops messages to the specified peer. +func (s *EtcdServer) CutPeer(id types.ID) { + tr, ok := s.r.transport.(*rafthttp.Transport) + if ok { + tr.CutPeer(id) + } +} + +// MendPeer recovers the message dropping behavior of the given peer. +func (s *EtcdServer) MendPeer(id types.ID) { + tr, ok := s.r.transport.(*rafthttp.Transport) + if ok { + tr.MendPeer(id) + } } func (s *EtcdServer) PauseSending() { s.r.pauseSending() } @@ -1233,7 +1491,7 @@ func (s *EtcdServer) monitorVersions() { select { case <-s.forceVersionC: case <-time.After(monitorVersionInterval): - case <-s.done: + case <-s.stopping: return } @@ -1254,18 +1512,18 @@ func (s *EtcdServer) monitorVersions() { // 1. use the decided version if possible // 2. or use the min cluster version if s.cluster.Version() == nil { + verStr := version.MinClusterVersion if v != nil { - go s.updateClusterVersion(v.String()) - } else { - go s.updateClusterVersion(version.MinClusterVersion) + verStr = v.String() } + s.goAttach(func() { s.updateClusterVersion(verStr) }) continue } // update cluster version only if the decided version is greater than // the current cluster version if v != nil && s.cluster.Version().LessThan(*v) { - go s.updateClusterVersion(v.String()) + s.goAttach(func() { s.updateClusterVersion(v.String()) }) } } } @@ -1355,3 +1613,31 @@ func (s *EtcdServer) getAppliedIndex() uint64 { func (s *EtcdServer) setAppliedIndex(v uint64) { atomic.StoreUint64(&s.appliedIndex, v) } + +func (s *EtcdServer) getCommittedIndex() uint64 { + return atomic.LoadUint64(&s.committedIndex) +} + +func (s *EtcdServer) setCommittedIndex(v uint64) { + atomic.StoreUint64(&s.committedIndex, v) +} + +// goAttach creates a goroutine on a given function and tracks it using +// the etcdserver waitgroup. +func (s *EtcdServer) goAttach(f func()) { + s.wgMu.RLock() // this blocks with ongoing close(s.stopping) + defer s.wgMu.RUnlock() + select { + case <-s.stopping: + plog.Warning("server has stopped (skipping goAttach)") + return + default: + } + + // now safe to add since waitgroup wait has not started yet + s.wg.Add(1) + go func() { + defer s.wg.Done() + f() + }() +} diff --git a/vendor/github.com/coreos/etcd/etcdserver/snapshot_merge.go b/vendor/github.com/coreos/etcd/etcdserver/snapshot_merge.go index 1de996c50..9cfc85216 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/snapshot_merge.go +++ b/vendor/github.com/coreos/etcd/etcdserver/snapshot_merge.go @@ -16,7 +16,6 @@ package etcdserver import ( "io" - "log" "github.com/coreos/etcd/mvcc/backend" "github.com/coreos/etcd/raft/raftpb" @@ -26,12 +25,7 @@ import ( // createMergedSnapshotMessage creates a snapshot message that contains: raft status (term, conf), // a snapshot of v2 store inside raft.Snapshot as []byte, a snapshot of v3 KV in the top level message // as ReadCloser. -func (s *EtcdServer) createMergedSnapshotMessage(m raftpb.Message, snapi uint64, confState raftpb.ConfState) snap.Message { - snapt, err := s.r.raftStorage.Term(snapi) - if err != nil { - log.Panicf("get term should never fail: %v", err) - } - +func (s *EtcdServer) createMergedSnapshotMessage(m raftpb.Message, snapt, snapi uint64, confState raftpb.ConfState) snap.Message { // get a snapshot of v2 store as []byte clone := s.store.Clone() d, err := clone.SaveNoCopy() diff --git a/vendor/github.com/coreos/etcd/etcdserver/stats/server.go b/vendor/github.com/coreos/etcd/etcdserver/stats/server.go index 10849813c..cd450e2d1 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/stats/server.go +++ b/vendor/github.com/coreos/etcd/etcdserver/stats/server.go @@ -123,17 +123,11 @@ func (ss *ServerStats) SendAppendReq(reqSize int) { ss.Lock() defer ss.Unlock() - now := time.Now() - - if ss.State != raft.StateLeader { - ss.State = raft.StateLeader - ss.LeaderInfo.Name = ss.ID - ss.LeaderInfo.StartTime = now - } + ss.becomeLeader() ss.sendRateQueue.Insert( &RequestStats{ - SendingTime: now, + SendingTime: time.Now(), Size: reqSize, }, ) @@ -144,7 +138,10 @@ func (ss *ServerStats) SendAppendReq(reqSize int) { func (ss *ServerStats) BecomeLeader() { ss.Lock() defer ss.Unlock() + ss.becomeLeader() +} +func (ss *ServerStats) becomeLeader() { if ss.State != raft.StateLeader { ss.State = raft.StateLeader ss.LeaderInfo.Name = ss.ID diff --git a/vendor/github.com/coreos/etcd/etcdserver/stats/stats.go b/vendor/github.com/coreos/etcd/etcdserver/stats/stats.go index e79339894..2b5f7071a 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/stats/stats.go +++ b/vendor/github.com/coreos/etcd/etcdserver/stats/stats.go @@ -18,7 +18,7 @@ package stats import "github.com/coreos/pkg/capnslog" var ( - plog = capnslog.NewPackageLogger("github.com/coreos/etcd/etcdserver", "stats") + plog = capnslog.NewPackageLogger("github.com/coreos/etcd", "etcdserver/stats") ) type Stats interface { diff --git a/vendor/github.com/coreos/etcd/etcdserver/storage.go b/vendor/github.com/coreos/etcd/etcdserver/storage.go index 6453a1794..693618fbd 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/storage.go +++ b/vendor/github.com/coreos/etcd/etcdserver/storage.go @@ -16,16 +16,12 @@ package etcdserver import ( "io" - "os" - "path" pb "github.com/coreos/etcd/etcdserver/etcdserverpb" - "github.com/coreos/etcd/pkg/fileutil" "github.com/coreos/etcd/pkg/pbutil" "github.com/coreos/etcd/pkg/types" "github.com/coreos/etcd/raft/raftpb" "github.com/coreos/etcd/snap" - "github.com/coreos/etcd/version" "github.com/coreos/etcd/wal" "github.com/coreos/etcd/wal/walpb" ) @@ -103,41 +99,3 @@ func readWAL(waldir string, snap walpb.Snapshot) (w *wal.WAL, id, cid types.ID, cid = types.ID(metadata.ClusterID) return } - -// upgradeDataDir converts an older version of the etcdServer data to the newest version. -// It must ensure that, after upgrading, the most recent version is present. -func upgradeDataDir(baseDataDir string, name string, ver version.DataDirVersion) error { - switch ver { - case version.DataDir2_0: - err := makeMemberDir(baseDataDir) - if err != nil { - return err - } - fallthrough - case version.DataDir2_0_1: - fallthrough - default: - } - return nil -} - -func makeMemberDir(dir string) error { - membdir := path.Join(dir, "member") - _, err := os.Stat(membdir) - switch { - case err == nil: - return nil - case !os.IsNotExist(err): - return err - } - if err := fileutil.CreateDirAll(membdir); err != nil { - return err - } - names := []string{"snap", "wal"} - for _, name := range names { - if err := os.Rename(path.Join(dir, name), path.Join(membdir, name)); err != nil { - return err - } - } - return nil -} diff --git a/vendor/github.com/coreos/etcd/etcdserver/util.go b/vendor/github.com/coreos/etcd/etcdserver/util.go index 32c161743..66084ae12 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/util.go +++ b/vendor/github.com/coreos/etcd/etcdserver/util.go @@ -25,13 +25,7 @@ import ( // isConnectedToQuorumSince checks whether the local member is connected to the // quorum of the cluster since the given time. func isConnectedToQuorumSince(transport rafthttp.Transporter, since time.Time, self types.ID, members []*membership.Member) bool { - var connectedNum int - for _, m := range members { - if m.ID == self || isConnectedSince(transport, since, m.ID) { - connectedNum++ - } - } - return connectedNum >= (len(members)+1)/2 + return numConnectedSince(transport, since, self, members) >= (len(members)/2)+1 } // isConnectedSince checks whether the local member is connected to the @@ -40,3 +34,64 @@ func isConnectedSince(transport rafthttp.Transporter, since time.Time, remote ty t := transport.ActiveSince(remote) return !t.IsZero() && t.Before(since) } + +// isConnectedFullySince checks whether the local member is connected to all +// members in the cluster since the given time. +func isConnectedFullySince(transport rafthttp.Transporter, since time.Time, self types.ID, members []*membership.Member) bool { + return numConnectedSince(transport, since, self, members) == len(members) +} + +// numConnectedSince counts how many members are connected to the local member +// since the given time. +func numConnectedSince(transport rafthttp.Transporter, since time.Time, self types.ID, members []*membership.Member) int { + connectedNum := 0 + for _, m := range members { + if m.ID == self || isConnectedSince(transport, since, m.ID) { + connectedNum++ + } + } + return connectedNum +} + +// longestConnected chooses the member with longest active-since-time. +// It returns false, if nothing is active. +func longestConnected(tp rafthttp.Transporter, membs []types.ID) (types.ID, bool) { + var longest types.ID + var oldest time.Time + for _, id := range membs { + tm := tp.ActiveSince(id) + if tm.IsZero() { // inactive + continue + } + + if oldest.IsZero() { // first longest candidate + oldest = tm + longest = id + } + + if tm.Before(oldest) { + oldest = tm + longest = id + } + } + if uint64(longest) == 0 { + return longest, false + } + return longest, true +} + +type notifier struct { + c chan struct{} + err error +} + +func newNotifier() *notifier { + return ¬ifier{ + c: make(chan struct{}, 0), + } +} + +func (nc *notifier) notify(err error) { + nc.err = err + close(nc.c) +} diff --git a/vendor/github.com/coreos/etcd/etcdserver/v2_server.go b/vendor/github.com/coreos/etcd/etcdserver/v2_server.go index a7285688e..72c4eb7c5 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/v2_server.go +++ b/vendor/github.com/coreos/etcd/etcdserver/v2_server.go @@ -68,7 +68,7 @@ func (a *v2apiStore) processRaftRequest(ctx context.Context, r *pb.Request) (Res proposalsFailed.Inc() a.s.w.Trigger(r.ID, nil) // GC wait return Response{}, a.s.parseProposeCtxErr(ctx.Err(), start) - case <-a.s.done: + case <-a.s.stopping: } return Response{}, ErrStopped } diff --git a/vendor/github.com/coreos/etcd/etcdserver/v3_server.go b/vendor/github.com/coreos/etcd/etcdserver/v3_server.go index 743dd2af5..60653cb6d 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/v3_server.go +++ b/vendor/github.com/coreos/etcd/etcdserver/v3_server.go @@ -15,17 +15,20 @@ package etcdserver import ( - "strconv" - "strings" + "bytes" + "encoding/binary" "time" + "github.com/coreos/etcd/auth" pb "github.com/coreos/etcd/etcdserver/etcdserverpb" "github.com/coreos/etcd/etcdserver/membership" "github.com/coreos/etcd/lease" "github.com/coreos/etcd/lease/leasehttp" "github.com/coreos/etcd/mvcc" + "github.com/coreos/etcd/raft" + + "github.com/coreos/go-semver/semver" "golang.org/x/net/context" - "google.golang.org/grpc/metadata" ) const ( @@ -35,8 +38,15 @@ const ( // specify a large value might end up with shooting in the foot. maxRequestBytes = 1.5 * 1024 * 1024 - // max timeout for waiting a v3 request to go through raft. - maxV3RequestTimeout = 5 * time.Second + // In the health case, there might be a small gap (10s of entries) between + // the applied index and committed index. + // However, if the committed entries are very heavy to apply, the gap might grow. + // We should stop accepting new proposals if the gap growing to a certain point. + maxGapBetweenApplyAndCommitIndex = 5000 +) + +var ( + newRangeClusterVersion = *semver.Must(semver.NewVersion("3.1.0")) ) type RaftKV interface { @@ -56,6 +66,9 @@ type Lessor interface { // LeaseRenew renews the lease with given ID. The renewed TTL is returned. Or an error // is returned. LeaseRenew(ctx context.Context, id lease.LeaseID) (int64, error) + + // LeaseTimeToLive retrieves lease information. + LeaseTimeToLive(ctx context.Context, r *pb.LeaseTimeToLiveRequest) (*pb.LeaseTimeToLiveResponse, error) } type Authenticator interface { @@ -78,22 +91,44 @@ type Authenticator interface { } func (s *EtcdServer) Range(ctx context.Context, r *pb.RangeRequest) (*pb.RangeResponse, error) { - var result *applyResult - var err error + // TODO: remove this checking when we release etcd 3.2 + if s.ClusterVersion() == nil || s.ClusterVersion().LessThan(newRangeClusterVersion) { + return s.legacyRange(ctx, r) + } - if r.Serializable { - var user string - user, err = s.usernameFromCtx(ctx) + if !r.Serializable { + err := s.linearizableReadNotify(ctx) if err != nil { return nil, err } - result = s.applyV3.Apply( - &pb.InternalRaftRequest{ - Header: &pb.RequestHeader{Username: user}, - Range: r}) - } else { - result, err = s.processInternalRaftRequest(ctx, pb.InternalRaftRequest{Range: r}) } + var resp *pb.RangeResponse + var err error + chk := func(ai *auth.AuthInfo) error { + return s.authStore.IsRangePermitted(ai, r.Key, r.RangeEnd) + } + get := func() { resp, err = s.applyV3Base.Range(noTxn, r) } + if serr := s.doSerialize(ctx, chk, get); serr != nil { + return nil, serr + } + return resp, err +} + +// TODO: remove this func when we release etcd 3.2 +func (s *EtcdServer) legacyRange(ctx context.Context, r *pb.RangeRequest) (*pb.RangeResponse, error) { + if r.Serializable { + var resp *pb.RangeResponse + var err error + chk := func(ai *auth.AuthInfo) error { + return s.authStore.IsRangePermitted(ai, r.Key, r.RangeEnd) + } + get := func() { resp, err = s.applyV3Base.Range(noTxn, r) } + if serr := s.doSerialize(ctx, chk, get); serr != nil { + return nil, serr + } + return resp, err + } + result, err := s.processInternalRaftRequest(ctx, pb.InternalRaftRequest{Range: r}) if err != nil { return nil, err } @@ -126,21 +161,54 @@ func (s *EtcdServer) DeleteRange(ctx context.Context, r *pb.DeleteRangeRequest) } func (s *EtcdServer) Txn(ctx context.Context, r *pb.TxnRequest) (*pb.TxnResponse, error) { - var result *applyResult - var err error - - if isTxnSerializable(r) { - user, err := s.usernameFromCtx(ctx) - if err != nil { - return nil, err - } - result = s.applyV3.Apply( - &pb.InternalRaftRequest{ - Header: &pb.RequestHeader{Username: user}, - Txn: r}) - } else { - result, err = s.processInternalRaftRequest(ctx, pb.InternalRaftRequest{Txn: r}) + // TODO: remove this checking when we release etcd 3.2 + if s.ClusterVersion() == nil || s.ClusterVersion().LessThan(newRangeClusterVersion) { + return s.legacyTxn(ctx, r) } + + if isTxnReadonly(r) { + if !isTxnSerializable(r) { + err := s.linearizableReadNotify(ctx) + if err != nil { + return nil, err + } + } + var resp *pb.TxnResponse + var err error + chk := func(ai *auth.AuthInfo) error { + return checkTxnAuth(s.authStore, ai, r) + } + get := func() { resp, err = s.applyV3Base.Txn(r) } + if serr := s.doSerialize(ctx, chk, get); serr != nil { + return nil, serr + } + return resp, err + } + result, err := s.processInternalRaftRequest(ctx, pb.InternalRaftRequest{Txn: r}) + if err != nil { + return nil, err + } + if result.err != nil { + return nil, result.err + } + return result.resp.(*pb.TxnResponse), nil +} + +// TODO: remove this func when we release etcd 3.2 +func (s *EtcdServer) legacyTxn(ctx context.Context, r *pb.TxnRequest) (*pb.TxnResponse, error) { + if isTxnSerializable(r) { + var resp *pb.TxnResponse + var err error + chk := func(ai *auth.AuthInfo) error { + return checkTxnAuth(s.authStore, ai, r) + } + get := func() { resp, err = s.applyV3Base.Txn(r) } + if serr := s.doSerialize(ctx, chk, get); serr != nil { + return nil, serr + } + return resp, err + } + result, err := s.processInternalRaftRequest(ctx, pb.InternalRaftRequest{Txn: r}) if err != nil { return nil, err } @@ -164,8 +232,22 @@ func isTxnSerializable(r *pb.TxnRequest) bool { return true } +func isTxnReadonly(r *pb.TxnRequest) bool { + for _, u := range r.Success { + if r := u.GetRequestRange(); r == nil { + return false + } + } + for _, u := range r.Failure { + if r := u.GetRequestRange(); r == nil { + return false + } + } + return true +} + func (s *EtcdServer) Compact(ctx context.Context, r *pb.CompactionRequest) (*pb.CompactionResponse, error) { - result, err := s.processInternalRaftRequest(ctx, pb.InternalRaftRequest{Compaction: r}) + result, err := s.processInternalRaftRequestOnce(ctx, pb.InternalRaftRequest{Compaction: r}) if r.Physical && result != nil && result.physc != nil { <-result.physc // The compaction is done deleting keys; the hash is now settled @@ -198,7 +280,7 @@ func (s *EtcdServer) LeaseGrant(ctx context.Context, r *pb.LeaseGrantRequest) (* // only use positive int64 id's r.ID = int64(s.reqIDGen.Next() & ((1 << 63) - 1)) } - result, err := s.processInternalRaftRequest(ctx, pb.InternalRaftRequest{LeaseGrant: r}) + result, err := s.processInternalRaftRequestOnce(ctx, pb.InternalRaftRequest{LeaseGrant: r}) if err != nil { return nil, err } @@ -209,7 +291,7 @@ func (s *EtcdServer) LeaseGrant(ctx context.Context, r *pb.LeaseGrantRequest) (* } func (s *EtcdServer) LeaseRevoke(ctx context.Context, r *pb.LeaseRevokeRequest) (*pb.LeaseRevokeResponse, error) { - result, err := s.processInternalRaftRequest(ctx, pb.InternalRaftRequest{LeaseRevoke: r}) + result, err := s.processInternalRaftRequestOnce(ctx, pb.InternalRaftRequest{LeaseRevoke: r}) if err != nil { return nil, err } @@ -221,14 +303,13 @@ func (s *EtcdServer) LeaseRevoke(ctx context.Context, r *pb.LeaseRevokeRequest) func (s *EtcdServer) LeaseRenew(ctx context.Context, id lease.LeaseID) (int64, error) { ttl, err := s.lessor.Renew(id) - if err == nil { + if err == nil { // already requested to primary lessor(leader) return ttl, nil } if err != lease.ErrNotPrimary { return -1, err } - // renewals don't go through raft; forward to leader manually cctx, cancel := context.WithTimeout(ctx, s.Cfg.ReqTimeout()) defer cancel() @@ -239,7 +320,7 @@ func (s *EtcdServer) LeaseRenew(ctx context.Context, id lease.LeaseID) (int64, e return -1, lerr } for _, url := range leader.PeerURLs { - lurl := url + "/leases" + lurl := url + leasehttp.LeasePrefix ttl, err = leasehttp.RenewHTTP(cctx, id, lurl, s.peerRt) if err == nil || err == lease.ErrLeaseNotFound { return ttl, err @@ -249,6 +330,49 @@ func (s *EtcdServer) LeaseRenew(ctx context.Context, id lease.LeaseID) (int64, e return -1, ErrTimeout } +func (s *EtcdServer) LeaseTimeToLive(ctx context.Context, r *pb.LeaseTimeToLiveRequest) (*pb.LeaseTimeToLiveResponse, error) { + if s.Leader() == s.ID() { + // primary; timetolive directly from leader + le := s.lessor.Lookup(lease.LeaseID(r.ID)) + if le == nil { + return nil, lease.ErrLeaseNotFound + } + // TODO: fill out ResponseHeader + resp := &pb.LeaseTimeToLiveResponse{Header: &pb.ResponseHeader{}, ID: r.ID, TTL: int64(le.Remaining().Seconds()), GrantedTTL: le.TTL()} + if r.Keys { + ks := le.Keys() + kbs := make([][]byte, len(ks)) + for i := range ks { + kbs[i] = []byte(ks[i]) + } + resp.Keys = kbs + } + return resp, nil + } + + cctx, cancel := context.WithTimeout(ctx, s.Cfg.ReqTimeout()) + defer cancel() + + // forward to leader + for cctx.Err() == nil { + leader, err := s.waitLeader(cctx) + if err != nil { + return nil, err + } + for _, url := range leader.PeerURLs { + lurl := url + leasehttp.LeaseInternalPrefix + resp, err := leasehttp.TimeToLiveHTTP(cctx, lease.LeaseID(r.ID), r.Keys, lurl, s.peerRt) + if err == nil { + return resp.LeaseTimeToLiveResponse, nil + } + if err == lease.ErrLeaseNotFound { + return nil, err + } + } + } + return nil, ErrTimeout +} + func (s *EtcdServer) waitLeader(ctx context.Context) (*membership.Member, error) { leader := s.cluster.Member(s.Leader()) for leader == nil { @@ -257,7 +381,7 @@ func (s *EtcdServer) waitLeader(ctx context.Context) (*membership.Member, error) select { case <-time.After(dur): leader = s.cluster.Member(s.Leader()) - case <-s.done: + case <-s.stopping: return nil, ErrStopped case <-ctx.Done(): return nil, ErrNoLeader @@ -270,7 +394,7 @@ func (s *EtcdServer) waitLeader(ctx context.Context) (*membership.Member, error) } func (s *EtcdServer) Alarm(ctx context.Context, r *pb.AlarmRequest) (*pb.AlarmResponse, error) { - result, err := s.processInternalRaftRequest(ctx, pb.InternalRaftRequest{Alarm: r}) + result, err := s.processInternalRaftRequestOnce(ctx, pb.InternalRaftRequest{Alarm: r}) if err != nil { return nil, err } @@ -281,7 +405,7 @@ func (s *EtcdServer) Alarm(ctx context.Context, r *pb.AlarmRequest) (*pb.AlarmRe } func (s *EtcdServer) AuthEnable(ctx context.Context, r *pb.AuthEnableRequest) (*pb.AuthEnableResponse, error) { - result, err := s.processInternalRaftRequest(ctx, pb.InternalRaftRequest{AuthEnable: r}) + result, err := s.processInternalRaftRequestOnce(ctx, pb.InternalRaftRequest{AuthEnable: r}) if err != nil { return nil, err } @@ -303,24 +427,47 @@ func (s *EtcdServer) AuthDisable(ctx context.Context, r *pb.AuthDisableRequest) } func (s *EtcdServer) Authenticate(ctx context.Context, r *pb.AuthenticateRequest) (*pb.AuthenticateResponse, error) { - st, err := s.AuthStore().GenSimpleToken() + var result *applyResult + + err := s.linearizableReadNotify(ctx) if err != nil { return nil, err } - internalReq := &pb.InternalAuthenticateRequest{ - Name: r.Name, - Password: r.Password, - SimpleToken: st, + for { + checkedRevision, err := s.AuthStore().CheckPassword(r.Name, r.Password) + if err != nil { + plog.Errorf("invalid authentication request to user %s was issued", r.Name) + return nil, err + } + + st, err := s.AuthStore().GenSimpleToken() + if err != nil { + return nil, err + } + + internalReq := &pb.InternalAuthenticateRequest{ + Name: r.Name, + Password: r.Password, + SimpleToken: st, + } + + result, err = s.processInternalRaftRequestOnce(ctx, pb.InternalRaftRequest{Authenticate: internalReq}) + if err != nil { + return nil, err + } + if result.err != nil { + return nil, result.err + } + + if checkedRevision != s.AuthStore().Revision() { + plog.Infof("revision when password checked is obsolete, retrying") + continue + } + + break } - result, err := s.processInternalRaftRequest(ctx, pb.InternalRaftRequest{Authenticate: internalReq}) - if err != nil { - return nil, err - } - if result.err != nil { - return nil, result.err - } return result.resp.(*pb.AuthenticateResponse), nil } @@ -467,69 +614,52 @@ func (s *EtcdServer) RoleDelete(ctx context.Context, r *pb.AuthRoleDeleteRequest return result.resp.(*pb.AuthRoleDeleteResponse), nil } -func (s *EtcdServer) isValidSimpleToken(token string) bool { - splitted := strings.Split(token, ".") - if len(splitted) != 2 { - return false - } - index, err := strconv.Atoi(splitted[1]) - if err != nil { - return false - } - - // CAUTION: below index synchronization is required because this node - // might not receive and apply the log entry of Authenticate() RPC. - authApplied := false - for i := 0; i < 10; i++ { - if uint64(index) <= s.getAppliedIndex() { - authApplied = true - break +// doSerialize handles the auth logic, with permissions checked by "chk", for a serialized request "get". Returns a non-nil error on authentication failure. +func (s *EtcdServer) doSerialize(ctx context.Context, chk func(*auth.AuthInfo) error, get func()) error { + for { + ai, err := s.AuthStore().AuthInfoFromCtx(ctx) + if err != nil { + return err } - - time.Sleep(100 * time.Millisecond) + if ai == nil { + // chk expects non-nil AuthInfo; use empty credentials + ai = &auth.AuthInfo{} + } + if err = chk(ai); err != nil { + if err == auth.ErrAuthOldRevision { + continue + } + return err + } + // fetch response for serialized request + get() + // empty credentials or current auth info means no need to retry + if ai.Revision == 0 || ai.Revision == s.authStore.Revision() { + return nil + } + // avoid TOCTOU error, retry of the request is required. } - - if !authApplied { - plog.Errorf("timeout of waiting Authenticate() RPC") - return false - } - - return true } -func (s *EtcdServer) usernameFromCtx(ctx context.Context) (string, error) { - md, ok := metadata.FromContext(ctx) - if !ok { - return "", nil +func (s *EtcdServer) processInternalRaftRequestOnce(ctx context.Context, r pb.InternalRaftRequest) (*applyResult, error) { + ai := s.getAppliedIndex() + ci := s.getCommittedIndex() + if ci > ai+maxGapBetweenApplyAndCommitIndex { + return nil, ErrTooManyRequests } - ts, tok := md["token"] - if !tok { - return "", nil - } - - token := ts[0] - if !s.isValidSimpleToken(token) { - return "", ErrInvalidAuthToken - } - - username, uok := s.AuthStore().UsernameFromToken(token) - if !uok { - plog.Warningf("invalid auth token: %s", token) - return "", ErrInvalidAuthToken - } - return username, nil -} - -func (s *EtcdServer) processInternalRaftRequest(ctx context.Context, r pb.InternalRaftRequest) (*applyResult, error) { r.Header = &pb.RequestHeader{ ID: s.reqIDGen.Next(), } - username, err := s.usernameFromCtx(ctx) + + authInfo, err := s.AuthStore().AuthInfoFromCtx(ctx) if err != nil { return nil, err } - r.Header.Username = username + if authInfo != nil { + r.Header.Username = authInfo.Username + r.Header.AuthRevision = authInfo.Revision + } data, err := r.Marshal() if err != nil { @@ -546,7 +676,7 @@ func (s *EtcdServer) processInternalRaftRequest(ctx context.Context, r pb.Intern } ch := s.w.Register(id) - cctx, cancel := context.WithTimeout(ctx, maxV3RequestTimeout) + cctx, cancel := context.WithTimeout(ctx, s.Cfg.ReqTimeout()) defer cancel() start := time.Now() @@ -566,5 +696,109 @@ func (s *EtcdServer) processInternalRaftRequest(ctx context.Context, r pb.Intern } } +func (s *EtcdServer) processInternalRaftRequest(ctx context.Context, r pb.InternalRaftRequest) (*applyResult, error) { + var result *applyResult + var err error + for { + result, err = s.processInternalRaftRequestOnce(ctx, r) + if err != auth.ErrAuthOldRevision { + break + } + } + + return result, err +} + // Watchable returns a watchable interface attached to the etcdserver. func (s *EtcdServer) Watchable() mvcc.WatchableKV { return s.KV() } + +func (s *EtcdServer) linearizableReadLoop() { + var rs raft.ReadState + + for { + ctx := make([]byte, 8) + binary.BigEndian.PutUint64(ctx, s.reqIDGen.Next()) + + select { + case <-s.readwaitc: + case <-s.stopping: + return + } + + nextnr := newNotifier() + + s.readMu.Lock() + nr := s.readNotifier + s.readNotifier = nextnr + s.readMu.Unlock() + + cctx, cancel := context.WithTimeout(context.Background(), s.Cfg.ReqTimeout()) + if err := s.r.ReadIndex(cctx, ctx); err != nil { + cancel() + if err == raft.ErrStopped { + return + } + plog.Errorf("failed to get read index from raft: %v", err) + nr.notify(err) + continue + } + cancel() + + var ( + timeout bool + done bool + ) + for !timeout && !done { + select { + case rs = <-s.r.readStateC: + done = bytes.Equal(rs.RequestCtx, ctx) + if !done { + // a previous request might time out. now we should ignore the response of it and + // continue waiting for the response of the current requests. + plog.Warningf("ignored out-of-date read index response (want %v, got %v)", rs.RequestCtx, ctx) + } + case <-time.After(s.Cfg.ReqTimeout()): + plog.Warningf("timed out waiting for read index response") + nr.notify(ErrTimeout) + timeout = true + case <-s.stopping: + return + } + } + if !done { + continue + } + + if ai := s.getAppliedIndex(); ai < rs.Index { + select { + case <-s.applyWait.Wait(rs.Index): + case <-s.stopping: + return + } + } + // unblock all l-reads requested at indices before rs.Index + nr.notify(nil) + } +} + +func (s *EtcdServer) linearizableReadNotify(ctx context.Context) error { + s.readMu.RLock() + nc := s.readNotifier + s.readMu.RUnlock() + + // signal linearizable loop for current notify if it hasn't been already + select { + case s.readwaitc <- struct{}{}: + default: + } + + // wait for read state notification + select { + case <-nc.c: + return nc.err + case <-ctx.Done(): + return ctx.Err() + case <-s.done: + return ErrStopped + } +} diff --git a/vendor/github.com/coreos/etcd/integration/bridge.go b/vendor/github.com/coreos/etcd/integration/bridge.go index e46397ca8..6c1ec5449 100644 --- a/vendor/github.com/coreos/etcd/integration/bridge.go +++ b/vendor/github.com/coreos/etcd/integration/bridge.go @@ -39,7 +39,8 @@ type bridge struct { func newBridge(addr string) (*bridge, error) { b := &bridge{ - inaddr: addr + ".bridge", + // bridge "port" is ("%05d%05d0", port, pid) since go1.8 expects the port to be a number + inaddr: addr + "0", outaddr: addr, conns: make(map[*bridgeConn]struct{}), stopc: make(chan struct{}, 1), diff --git a/vendor/github.com/coreos/etcd/integration/cluster.go b/vendor/github.com/coreos/etcd/integration/cluster.go index b63c1fc66..1b056f64b 100644 --- a/vendor/github.com/coreos/etcd/integration/cluster.go +++ b/vendor/github.com/coreos/etcd/integration/cluster.go @@ -276,12 +276,18 @@ func (c *cluster) AddMember(t *testing.T) { } func (c *cluster) RemoveMember(t *testing.T, id uint64) { + if err := c.removeMember(t, id); err != nil { + t.Fatal(err) + } +} + +func (c *cluster) removeMember(t *testing.T, id uint64) error { // send remove request to the cluster cc := MustNewHTTPClient(t, c.URLs(), c.cfg.ClientTLS) ma := client.NewMembersAPI(cc) ctx, cancel := context.WithTimeout(context.Background(), requestTimeout) if err := ma.Remove(ctx, types.ID(id).String()); err != nil { - t.Fatalf("unexpected remove error %v", err) + return err } cancel() newMembers := make([]*member, 0) @@ -302,6 +308,7 @@ func (c *cluster) RemoveMember(t *testing.T, id uint64) { } c.Members = newMembers c.waitMembersMatch(t, c.HTTPMembers()) + return nil } func (c *cluster) Terminate(t *testing.T) { @@ -329,6 +336,7 @@ func (c *cluster) waitMembersMatch(t *testing.T, membs []client.Member) { func (c *cluster) WaitLeader(t *testing.T) int { return c.waitLeader(t, c.Members) } +// waitLeader waits until given members agree on the same leader. func (c *cluster) waitLeader(t *testing.T, membs []*member) int { possibleLead := make(map[uint64]bool) var lead uint64 @@ -362,6 +370,28 @@ func (c *cluster) waitLeader(t *testing.T, membs []*member) int { return -1 } +func (c *cluster) WaitNoLeader(t *testing.T) { c.waitNoLeader(t, c.Members) } + +// waitNoLeader waits until given members lose leader. +func (c *cluster) waitNoLeader(t *testing.T, membs []*member) { + noLeader := false + for !noLeader { + noLeader = true + for _, m := range membs { + select { + case <-m.s.StopNotify(): + continue + default: + } + if m.s.Lead() != 0 { + noLeader = false + time.Sleep(10 * tickDuration) + break + } + } + } +} + func (c *cluster) waitVersion() { for _, m := range c.Members { for { @@ -374,7 +404,7 @@ func (c *cluster) waitVersion() { } func (c *cluster) name(i int) string { - return fmt.Sprint("node", i) + return fmt.Sprint(i) } // isMembersEqual checks whether two members equal except ID field. @@ -390,7 +420,8 @@ func isMembersEqual(membs []client.Member, wmembs []client.Member) bool { func newLocalListener(t *testing.T) net.Listener { c := atomic.AddInt64(&localListenCount, 1) - addr := fmt.Sprintf("127.0.0.1:%d.%d.sock", c+basePort, os.Getpid()) + // Go 1.8+ allows only numbers in port + addr := fmt.Sprintf("127.0.0.1:%05d%05d", c+basePort, os.Getpid()) return NewListenerWithAddr(t, addr) } @@ -418,6 +449,8 @@ type member struct { grpcServer *grpc.Server grpcAddr string grpcBridge *bridge + + keepDataDirTerminate bool } func (m *member) GRPCAddr() string { return m.grpcAddr } @@ -480,7 +513,7 @@ func mustNewMember(t *testing.T, mcfg memberConfig) *member { // listenGRPC starts a grpc server over a unix domain socket on the member func (m *member) listenGRPC() error { // prefix with localhost so cert has right domain - m.grpcAddr = "localhost:" + m.Name + ".sock" + m.grpcAddr = "localhost:" + m.Name l, err := transport.NewUnixListener(m.grpcAddr) if err != nil { return fmt.Errorf("listen failed on grpc socket %s (%v)", m.grpcAddr, err) @@ -495,6 +528,10 @@ func (m *member) listenGRPC() error { return nil } +func (m *member) electionTimeout() time.Duration { + return time.Duration(m.s.Cfg.ElectionTicks) * time.Millisecond +} + func (m *member) DropConnections() { m.grpcBridge.Reset() } // NewClientV3 creates a new grpc client connection to the member @@ -515,7 +552,7 @@ func NewClientV3(m *member) (*clientv3.Client, error) { } cfg.TLS = tls } - return clientv3.New(cfg) + return newClientV3(cfg) } // Clone returns a member with the same server configuration. The returned @@ -653,7 +690,7 @@ func (m *member) Close() { m.grpcServer.Stop() m.grpcServer = nil } - m.s.Stop() + m.s.HardStop() for _, hs := range m.hss { hs.CloseClientConnections() hs.Close() @@ -668,6 +705,15 @@ func (m *member) Stop(t *testing.T) { plog.Printf("stopped %s (%s)", m.Name, m.grpcAddr) } +// checkLeaderTransition waits for leader transition, returning the new leader ID. +func checkLeaderTransition(t *testing.T, m *member, oldLead uint64) uint64 { + interval := time.Duration(m.s.Cfg.TickMs) * time.Millisecond + for m.s.Lead() == 0 || (m.s.Lead() == oldLead) { + time.Sleep(interval) + } + return m.s.Lead() +} + // StopNotify unblocks when a member stop completes func (m *member) StopNotify() <-chan struct{} { return m.s.StopNotify() @@ -702,12 +748,56 @@ func (m *member) Restart(t *testing.T) error { func (m *member) Terminate(t *testing.T) { plog.Printf("terminating %s (%s)", m.Name, m.grpcAddr) m.Close() - if err := os.RemoveAll(m.ServerConfig.DataDir); err != nil { - t.Fatal(err) + if !m.keepDataDirTerminate { + if err := os.RemoveAll(m.ServerConfig.DataDir); err != nil { + t.Fatal(err) + } } plog.Printf("terminated %s (%s)", m.Name, m.grpcAddr) } +// Metric gets the metric value for a member +func (m *member) Metric(metricName string) (string, error) { + cfgtls := transport.TLSInfo{} + tr, err := transport.NewTimeoutTransport(cfgtls, time.Second, time.Second, time.Second) + if err != nil { + return "", err + } + cli := &http.Client{Transport: tr} + resp, err := cli.Get(m.ClientURLs[0].String() + "/metrics") + if err != nil { + return "", err + } + defer resp.Body.Close() + b, rerr := ioutil.ReadAll(resp.Body) + if rerr != nil { + return "", rerr + } + lines := strings.Split(string(b), "\n") + for _, l := range lines { + if strings.HasPrefix(l, metricName) { + return strings.Split(l, " ")[1], nil + } + } + return "", nil +} + +// InjectPartition drops connections from m to others, vice versa. +func (m *member) InjectPartition(t *testing.T, others []*member) { + for _, other := range others { + m.s.CutPeer(other.s.ID()) + other.s.CutPeer(m.s.ID()) + } +} + +// RecoverPartition recovers connections from m to others, vice versa. +func (m *member) RecoverPartition(t *testing.T, others []*member) { + for _, other := range others { + m.s.MendPeer(other.s.ID()) + other.s.MendPeer(m.s.ID()) + } +} + func MustNewHTTPClient(t *testing.T, eps []string, tls *transport.TLSInfo) client.Client { cfgtls := transport.TLSInfo{} if tls != nil { @@ -803,14 +893,6 @@ type grpcAPI struct { Watch pb.WatchClient // Maintenance is the maintenance API for the client's connection. Maintenance pb.MaintenanceClient -} - -func toGRPC(c *clientv3.Client) grpcAPI { - return grpcAPI{ - pb.NewClusterClient(c.ActiveConnection()), - pb.NewKVClient(c.ActiveConnection()), - pb.NewLeaseClient(c.ActiveConnection()), - pb.NewWatchClient(c.ActiveConnection()), - pb.NewMaintenanceClient(c.ActiveConnection()), - } + // Auth is the authentication API for the client's connection. + Auth pb.AuthClient } diff --git a/vendor/github.com/coreos/etcd/integration/cluster_direct.go b/vendor/github.com/coreos/etcd/integration/cluster_direct.go new file mode 100644 index 000000000..84b2a796c --- /dev/null +++ b/vendor/github.com/coreos/etcd/integration/cluster_direct.go @@ -0,0 +1,37 @@ +// Copyright 2016 The etcd Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// +build !cluster_proxy + +package integration + +import ( + "github.com/coreos/etcd/clientv3" + pb "github.com/coreos/etcd/etcdserver/etcdserverpb" +) + +func toGRPC(c *clientv3.Client) grpcAPI { + return grpcAPI{ + pb.NewClusterClient(c.ActiveConnection()), + pb.NewKVClient(c.ActiveConnection()), + pb.NewLeaseClient(c.ActiveConnection()), + pb.NewWatchClient(c.ActiveConnection()), + pb.NewMaintenanceClient(c.ActiveConnection()), + pb.NewAuthClient(c.ActiveConnection()), + } +} + +func newClientV3(cfg clientv3.Config) (*clientv3.Client, error) { + return clientv3.New(cfg) +} diff --git a/vendor/github.com/coreos/etcd/integration/cluster_proxy.go b/vendor/github.com/coreos/etcd/integration/cluster_proxy.go new file mode 100644 index 000000000..75319218e --- /dev/null +++ b/vendor/github.com/coreos/etcd/integration/cluster_proxy.go @@ -0,0 +1,89 @@ +// Copyright 2016 The etcd Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// +build cluster_proxy + +package integration + +import ( + "sync" + + "github.com/coreos/etcd/clientv3" + pb "github.com/coreos/etcd/etcdserver/etcdserverpb" + "github.com/coreos/etcd/proxy/grpcproxy" +) + +var ( + pmu sync.Mutex + proxies map[*clientv3.Client]grpcClientProxy = make(map[*clientv3.Client]grpcClientProxy) +) + +type grpcClientProxy struct { + grpc grpcAPI + wdonec <-chan struct{} + kvdonec <-chan struct{} +} + +func toGRPC(c *clientv3.Client) grpcAPI { + pmu.Lock() + defer pmu.Unlock() + + if v, ok := proxies[c]; ok { + return v.grpc + } + + wp, wpch := grpcproxy.NewWatchProxy(c) + kvp, kvpch := grpcproxy.NewKvProxy(c) + grpc := grpcAPI{ + pb.NewClusterClient(c.ActiveConnection()), + grpcproxy.KvServerToKvClient(kvp), + pb.NewLeaseClient(c.ActiveConnection()), + grpcproxy.WatchServerToWatchClient(wp), + pb.NewMaintenanceClient(c.ActiveConnection()), + pb.NewAuthClient(c.ActiveConnection()), + } + proxies[c] = grpcClientProxy{grpc: grpc, wdonec: wpch, kvdonec: kvpch} + return grpc +} + +type proxyCloser struct { + clientv3.Watcher + wdonec <-chan struct{} + kvdonec <-chan struct{} +} + +func (pc *proxyCloser) Close() error { + // client ctx is canceled before calling close, so kv will close out + <-pc.kvdonec + err := pc.Watcher.Close() + <-pc.wdonec + return err +} + +func newClientV3(cfg clientv3.Config) (*clientv3.Client, error) { + c, err := clientv3.New(cfg) + if err != nil { + return nil, err + } + rpc := toGRPC(c) + c.KV = clientv3.NewKVFromKVClient(rpc.KV) + pmu.Lock() + c.Watcher = &proxyCloser{ + Watcher: clientv3.NewWatchFromWatchClient(rpc.Watch), + wdonec: proxies[c].wdonec, + kvdonec: proxies[c].kvdonec, + } + pmu.Unlock() + return c, nil +} diff --git a/vendor/github.com/coreos/etcd/lease/leasehttp/http.go b/vendor/github.com/coreos/etcd/lease/leasehttp/http.go index e730b2d2d..256051efc 100644 --- a/vendor/github.com/coreos/etcd/lease/leasehttp/http.go +++ b/vendor/github.com/coreos/etcd/lease/leasehttp/http.go @@ -16,21 +16,35 @@ package leasehttp import ( "bytes" + "errors" "fmt" "io/ioutil" "net/http" + "time" pb "github.com/coreos/etcd/etcdserver/etcdserverpb" "github.com/coreos/etcd/lease" + "github.com/coreos/etcd/lease/leasepb" + "github.com/coreos/etcd/pkg/httputil" "golang.org/x/net/context" ) +var ( + LeasePrefix = "/leases" + LeaseInternalPrefix = "/leases/internal" + applyTimeout = time.Second + ErrLeaseHTTPTimeout = errors.New("waiting for node to catch up its applied index has timed out") +) + // NewHandler returns an http Handler for lease renewals -func NewHandler(l lease.Lessor) http.Handler { - return &leaseHandler{l} +func NewHandler(l lease.Lessor, waitch func() <-chan struct{}) http.Handler { + return &leaseHandler{l, waitch} } -type leaseHandler struct{ l lease.Lessor } +type leaseHandler struct { + l lease.Lessor + waitch func() <-chan struct{} +} func (h *leaseHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { if r.Method != "POST" { @@ -44,28 +58,81 @@ func (h *leaseHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { return } - lreq := pb.LeaseKeepAliveRequest{} - if err := lreq.Unmarshal(b); err != nil { - http.Error(w, "error unmarshalling request", http.StatusBadRequest) - return - } + var v []byte + switch r.URL.Path { + case LeasePrefix: + lreq := pb.LeaseKeepAliveRequest{} + if err := lreq.Unmarshal(b); err != nil { + http.Error(w, "error unmarshalling request", http.StatusBadRequest) + return + } + select { + case <-h.waitch(): + case <-time.After(applyTimeout): + http.Error(w, ErrLeaseHTTPTimeout.Error(), http.StatusRequestTimeout) + return + } + ttl, err := h.l.Renew(lease.LeaseID(lreq.ID)) + if err != nil { + if err == lease.ErrLeaseNotFound { + http.Error(w, err.Error(), http.StatusNotFound) + return + } - ttl, err := h.l.Renew(lease.LeaseID(lreq.ID)) - if err != nil { - if err == lease.ErrLeaseNotFound { - http.Error(w, err.Error(), http.StatusNotFound) + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + // TODO: fill out ResponseHeader + resp := &pb.LeaseKeepAliveResponse{ID: lreq.ID, TTL: ttl} + v, err = resp.Marshal() + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) return } - http.Error(w, err.Error(), http.StatusBadRequest) - return - } + case LeaseInternalPrefix: + lreq := leasepb.LeaseInternalRequest{} + if err := lreq.Unmarshal(b); err != nil { + http.Error(w, "error unmarshalling request", http.StatusBadRequest) + return + } + select { + case <-h.waitch(): + case <-time.After(applyTimeout): + http.Error(w, ErrLeaseHTTPTimeout.Error(), http.StatusRequestTimeout) + return + } + l := h.l.Lookup(lease.LeaseID(lreq.LeaseTimeToLiveRequest.ID)) + if l == nil { + http.Error(w, lease.ErrLeaseNotFound.Error(), http.StatusNotFound) + return + } + // TODO: fill out ResponseHeader + resp := &leasepb.LeaseInternalResponse{ + LeaseTimeToLiveResponse: &pb.LeaseTimeToLiveResponse{ + Header: &pb.ResponseHeader{}, + ID: lreq.LeaseTimeToLiveRequest.ID, + TTL: int64(l.Remaining().Seconds()), + GrantedTTL: l.TTL(), + }, + } + if lreq.LeaseTimeToLiveRequest.Keys { + ks := l.Keys() + kbs := make([][]byte, len(ks)) + for i := range ks { + kbs[i] = []byte(ks[i]) + } + resp.LeaseTimeToLiveResponse.Keys = kbs + } - // TODO: fill out ResponseHeader - resp := &pb.LeaseKeepAliveResponse{ID: lreq.ID, TTL: ttl} - v, err := resp.Marshal() - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) + v, err = resp.Marshal() + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + + default: + http.Error(w, fmt.Sprintf("unknown request path %q", r.URL.Path), http.StatusBadRequest) return } @@ -92,15 +159,17 @@ func RenewHTTP(ctx context.Context, id lease.LeaseID, url string, rt http.RoundT resp, err := cc.Do(req) if err != nil { - // TODO detect if leader failed and retry? return -1, err } - b, err := ioutil.ReadAll(resp.Body) - resp.Body.Close() + b, err := readResponse(resp) if err != nil { return -1, err } + if resp.StatusCode == http.StatusRequestTimeout { + return -1, ErrLeaseHTTPTimeout + } + if resp.StatusCode == http.StatusNotFound { return -1, lease.ErrLeaseNotFound } @@ -118,3 +187,74 @@ func RenewHTTP(ctx context.Context, id lease.LeaseID, url string, rt http.RoundT } return lresp.TTL, nil } + +// TimeToLiveHTTP retrieves lease information of the given lease ID. +func TimeToLiveHTTP(ctx context.Context, id lease.LeaseID, keys bool, url string, rt http.RoundTripper) (*leasepb.LeaseInternalResponse, error) { + // will post lreq protobuf to leader + lreq, err := (&leasepb.LeaseInternalRequest{&pb.LeaseTimeToLiveRequest{ID: int64(id), Keys: keys}}).Marshal() + if err != nil { + return nil, err + } + + req, err := http.NewRequest("POST", url, bytes.NewReader(lreq)) + if err != nil { + return nil, err + } + req.Header.Set("Content-Type", "application/protobuf") + + cancel := httputil.RequestCanceler(req) + + cc := &http.Client{Transport: rt} + var b []byte + // buffer errc channel so that errc don't block inside the go routinue + errc := make(chan error, 2) + go func() { + resp, err := cc.Do(req) + if err != nil { + errc <- err + return + } + b, err = readResponse(resp) + if err != nil { + errc <- err + return + } + if resp.StatusCode == http.StatusRequestTimeout { + errc <- ErrLeaseHTTPTimeout + return + } + if resp.StatusCode == http.StatusNotFound { + errc <- lease.ErrLeaseNotFound + return + } + if resp.StatusCode != http.StatusOK { + errc <- fmt.Errorf("lease: unknown error(%s)", string(b)) + return + } + errc <- nil + }() + select { + case derr := <-errc: + if derr != nil { + return nil, derr + } + case <-ctx.Done(): + cancel() + return nil, ctx.Err() + } + + lresp := &leasepb.LeaseInternalResponse{} + if err := lresp.Unmarshal(b); err != nil { + return nil, fmt.Errorf(`lease: %v. data = "%s"`, err, string(b)) + } + if lresp.LeaseTimeToLiveResponse.ID != int64(id) { + return nil, fmt.Errorf("lease: renew id mismatch") + } + return lresp, nil +} + +func readResponse(resp *http.Response) (b []byte, err error) { + b, err = ioutil.ReadAll(resp.Body) + httputil.GracefulClose(resp) + return +} 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 dde5f286e..fb3a9bab0 100644 --- a/vendor/github.com/coreos/etcd/lease/leasepb/lease.pb.go +++ b/vendor/github.com/coreos/etcd/lease/leasepb/lease.pb.go @@ -10,6 +10,8 @@ It has these top-level messages: Lease + LeaseInternalRequest + LeaseInternalResponse */ package leasepb @@ -20,6 +22,8 @@ import ( math "math" + etcdserverpb "github.com/coreos/etcd/etcdserver/etcdserverpb" + io "io" ) @@ -30,11 +34,13 @@ var _ = math.Inf // This is a compile-time assertion to ensure that this generated file // is compatible with the proto package it is being compiled against. -const _ = proto.ProtoPackageIsVersion1 +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package type Lease struct { - ID int64 `protobuf:"varint,1,opt,name=ID,json=iD,proto3" json:"ID,omitempty"` - TTL int64 `protobuf:"varint,2,opt,name=TTL,json=tTL,proto3" json:"TTL,omitempty"` + ID int64 `protobuf:"varint,1,opt,name=ID,proto3" json:"ID,omitempty"` + TTL int64 `protobuf:"varint,2,opt,name=TTL,proto3" json:"TTL,omitempty"` } func (m *Lease) Reset() { *m = Lease{} } @@ -42,62 +48,138 @@ func (m *Lease) String() string { return proto.CompactTextString(m) } func (*Lease) ProtoMessage() {} func (*Lease) Descriptor() ([]byte, []int) { return fileDescriptorLease, []int{0} } +type LeaseInternalRequest struct { + LeaseTimeToLiveRequest *etcdserverpb.LeaseTimeToLiveRequest `protobuf:"bytes,1,opt,name=LeaseTimeToLiveRequest" json:"LeaseTimeToLiveRequest,omitempty"` +} + +func (m *LeaseInternalRequest) Reset() { *m = LeaseInternalRequest{} } +func (m *LeaseInternalRequest) String() string { return proto.CompactTextString(m) } +func (*LeaseInternalRequest) ProtoMessage() {} +func (*LeaseInternalRequest) Descriptor() ([]byte, []int) { return fileDescriptorLease, []int{1} } + +type LeaseInternalResponse struct { + LeaseTimeToLiveResponse *etcdserverpb.LeaseTimeToLiveResponse `protobuf:"bytes,1,opt,name=LeaseTimeToLiveResponse" json:"LeaseTimeToLiveResponse,omitempty"` +} + +func (m *LeaseInternalResponse) Reset() { *m = LeaseInternalResponse{} } +func (m *LeaseInternalResponse) String() string { return proto.CompactTextString(m) } +func (*LeaseInternalResponse) ProtoMessage() {} +func (*LeaseInternalResponse) Descriptor() ([]byte, []int) { return fileDescriptorLease, []int{2} } + func init() { proto.RegisterType((*Lease)(nil), "leasepb.Lease") + proto.RegisterType((*LeaseInternalRequest)(nil), "leasepb.LeaseInternalRequest") + proto.RegisterType((*LeaseInternalResponse)(nil), "leasepb.LeaseInternalResponse") } -func (m *Lease) Marshal() (data []byte, err error) { +func (m *Lease) Marshal() (dAtA []byte, err error) { size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) if err != nil { return nil, err } - return data[:n], nil + return dAtA[:n], nil } -func (m *Lease) MarshalTo(data []byte) (int, error) { +func (m *Lease) MarshalTo(dAtA []byte) (int, error) { var i int _ = i var l int _ = l if m.ID != 0 { - data[i] = 0x8 + dAtA[i] = 0x8 i++ - i = encodeVarintLease(data, i, uint64(m.ID)) + i = encodeVarintLease(dAtA, i, uint64(m.ID)) } if m.TTL != 0 { - data[i] = 0x10 + dAtA[i] = 0x10 i++ - i = encodeVarintLease(data, i, uint64(m.TTL)) + i = encodeVarintLease(dAtA, i, uint64(m.TTL)) } return i, nil } -func encodeFixed64Lease(data []byte, offset int, v uint64) int { - data[offset] = uint8(v) - data[offset+1] = uint8(v >> 8) - data[offset+2] = uint8(v >> 16) - data[offset+3] = uint8(v >> 24) - data[offset+4] = uint8(v >> 32) - data[offset+5] = uint8(v >> 40) - data[offset+6] = uint8(v >> 48) - data[offset+7] = uint8(v >> 56) +func (m *LeaseInternalRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *LeaseInternalRequest) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.LeaseTimeToLiveRequest != nil { + dAtA[i] = 0xa + i++ + i = encodeVarintLease(dAtA, i, uint64(m.LeaseTimeToLiveRequest.Size())) + n1, err := m.LeaseTimeToLiveRequest.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n1 + } + return i, nil +} + +func (m *LeaseInternalResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *LeaseInternalResponse) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.LeaseTimeToLiveResponse != nil { + dAtA[i] = 0xa + i++ + i = encodeVarintLease(dAtA, i, uint64(m.LeaseTimeToLiveResponse.Size())) + n2, err := m.LeaseTimeToLiveResponse.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n2 + } + return i, nil +} + +func encodeFixed64Lease(dAtA []byte, offset int, v uint64) int { + dAtA[offset] = uint8(v) + dAtA[offset+1] = uint8(v >> 8) + dAtA[offset+2] = uint8(v >> 16) + dAtA[offset+3] = uint8(v >> 24) + dAtA[offset+4] = uint8(v >> 32) + dAtA[offset+5] = uint8(v >> 40) + dAtA[offset+6] = uint8(v >> 48) + dAtA[offset+7] = uint8(v >> 56) return offset + 8 } -func encodeFixed32Lease(data []byte, offset int, v uint32) int { - data[offset] = uint8(v) - data[offset+1] = uint8(v >> 8) - data[offset+2] = uint8(v >> 16) - data[offset+3] = uint8(v >> 24) +func encodeFixed32Lease(dAtA []byte, offset int, v uint32) int { + dAtA[offset] = uint8(v) + dAtA[offset+1] = uint8(v >> 8) + dAtA[offset+2] = uint8(v >> 16) + dAtA[offset+3] = uint8(v >> 24) return offset + 4 } -func encodeVarintLease(data []byte, offset int, v uint64) int { +func encodeVarintLease(dAtA []byte, offset int, v uint64) int { for v >= 1<<7 { - data[offset] = uint8(v&0x7f | 0x80) + dAtA[offset] = uint8(v&0x7f | 0x80) v >>= 7 offset++ } - data[offset] = uint8(v) + dAtA[offset] = uint8(v) return offset + 1 } func (m *Lease) Size() (n int) { @@ -112,6 +194,26 @@ func (m *Lease) Size() (n int) { return n } +func (m *LeaseInternalRequest) Size() (n int) { + var l int + _ = l + if m.LeaseTimeToLiveRequest != nil { + l = m.LeaseTimeToLiveRequest.Size() + n += 1 + l + sovLease(uint64(l)) + } + return n +} + +func (m *LeaseInternalResponse) Size() (n int) { + var l int + _ = l + if m.LeaseTimeToLiveResponse != nil { + l = m.LeaseTimeToLiveResponse.Size() + n += 1 + l + sovLease(uint64(l)) + } + return n +} + func sovLease(x uint64) (n int) { for { n++ @@ -125,8 +227,8 @@ func sovLease(x uint64) (n int) { func sozLease(x uint64) (n int) { return sovLease(uint64((x << 1) ^ uint64((int64(x) >> 63)))) } -func (m *Lease) Unmarshal(data []byte) error { - l := len(data) +func (m *Lease) Unmarshal(dAtA []byte) error { + l := len(dAtA) iNdEx := 0 for iNdEx < l { preIndex := iNdEx @@ -138,7 +240,7 @@ func (m *Lease) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -166,7 +268,7 @@ func (m *Lease) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ m.ID |= (int64(b) & 0x7F) << shift if b < 0x80 { @@ -185,7 +287,7 @@ func (m *Lease) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ m.TTL |= (int64(b) & 0x7F) << shift if b < 0x80 { @@ -194,7 +296,7 @@ func (m *Lease) Unmarshal(data []byte) error { } default: iNdEx = preIndex - skippy, err := skipLease(data[iNdEx:]) + skippy, err := skipLease(dAtA[iNdEx:]) if err != nil { return err } @@ -213,8 +315,174 @@ func (m *Lease) Unmarshal(data []byte) error { } return nil } -func skipLease(data []byte) (n int, err error) { - l := len(data) +func (m *LeaseInternalRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLease + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: LeaseInternalRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: LeaseInternalRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field LeaseTimeToLiveRequest", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLease + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthLease + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.LeaseTimeToLiveRequest == nil { + m.LeaseTimeToLiveRequest = &etcdserverpb.LeaseTimeToLiveRequest{} + } + if err := m.LeaseTimeToLiveRequest.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipLease(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthLease + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *LeaseInternalResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLease + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: LeaseInternalResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: LeaseInternalResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field LeaseTimeToLiveResponse", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLease + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthLease + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.LeaseTimeToLiveResponse == nil { + m.LeaseTimeToLiveResponse = &etcdserverpb.LeaseTimeToLiveResponse{} + } + if err := m.LeaseTimeToLiveResponse.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipLease(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthLease + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipLease(dAtA []byte) (n int, err error) { + l := len(dAtA) iNdEx := 0 for iNdEx < l { var wire uint64 @@ -225,7 +493,7 @@ func skipLease(data []byte) (n int, err error) { if iNdEx >= l { return 0, io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -243,7 +511,7 @@ func skipLease(data []byte) (n int, err error) { return 0, io.ErrUnexpectedEOF } iNdEx++ - if data[iNdEx-1] < 0x80 { + if dAtA[iNdEx-1] < 0x80 { break } } @@ -260,7 +528,7 @@ func skipLease(data []byte) (n int, err error) { if iNdEx >= l { return 0, io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ length |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -283,7 +551,7 @@ func skipLease(data []byte) (n int, err error) { if iNdEx >= l { return 0, io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ innerWire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -294,7 +562,7 @@ func skipLease(data []byte) (n int, err error) { if innerWireType == 4 { break } - next, err := skipLease(data[start:]) + next, err := skipLease(dAtA[start:]) if err != nil { return 0, err } @@ -318,14 +586,23 @@ var ( ErrIntOverflowLease = fmt.Errorf("proto: integer overflow") ) +func init() { proto.RegisterFile("lease.proto", fileDescriptorLease) } + var fileDescriptorLease = []byte{ - // 126 bytes of a gzipped FileDescriptorProto + // 233 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0xe2, 0xce, 0x49, 0x4d, 0x2c, 0x4e, 0xd5, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0x07, 0x73, 0x0a, 0x92, 0xa4, 0x44, 0xd2, - 0xf3, 0xd3, 0xf3, 0xc1, 0x62, 0xfa, 0x20, 0x16, 0x44, 0x5a, 0x49, 0x93, 0x8b, 0xd5, 0x07, 0xa4, - 0x40, 0x88, 0x8f, 0x8b, 0xc9, 0xd3, 0x45, 0x82, 0x51, 0x81, 0x51, 0x83, 0x39, 0x88, 0x29, 0xd3, - 0x45, 0x48, 0x80, 0x8b, 0x39, 0x24, 0xc4, 0x47, 0x82, 0x09, 0x2c, 0xc0, 0x5c, 0x12, 0xe2, 0xe3, - 0x24, 0x71, 0xe2, 0xa1, 0x1c, 0xc3, 0x85, 0x87, 0x72, 0x0c, 0x27, 0x1e, 0xc9, 0x31, 0x5e, 0x78, - 0x24, 0xc7, 0xf8, 0xe0, 0x91, 0x1c, 0xe3, 0x8c, 0xc7, 0x72, 0x0c, 0x49, 0x6c, 0x60, 0xb3, 0x8c, - 0x01, 0x01, 0x00, 0x00, 0xff, 0xff, 0x0d, 0xa0, 0x42, 0x1a, 0x79, 0x00, 0x00, 0x00, + 0xf3, 0xd3, 0xf3, 0xc1, 0x62, 0xfa, 0x20, 0x16, 0x44, 0x5a, 0x4a, 0x2d, 0xb5, 0x24, 0x39, 0x45, + 0x1f, 0x44, 0x14, 0xa7, 0x16, 0x95, 0xa5, 0x16, 0x21, 0x31, 0x0b, 0x92, 0xf4, 0x8b, 0x0a, 0x92, + 0x21, 0xea, 0x94, 0x34, 0xb9, 0x58, 0x7d, 0x40, 0x06, 0x09, 0xf1, 0x71, 0x31, 0x79, 0xba, 0x48, + 0x30, 0x2a, 0x30, 0x6a, 0x30, 0x07, 0x31, 0x79, 0xba, 0x08, 0x09, 0x70, 0x31, 0x87, 0x84, 0xf8, + 0x48, 0x30, 0x81, 0x05, 0x40, 0x4c, 0xa5, 0x12, 0x2e, 0x11, 0xb0, 0x52, 0xcf, 0xbc, 0x92, 0xd4, + 0xa2, 0xbc, 0xc4, 0x9c, 0xa0, 0xd4, 0xc2, 0xd2, 0xd4, 0xe2, 0x12, 0xa1, 0x18, 0x2e, 0x31, 0xb0, + 0x78, 0x48, 0x66, 0x6e, 0x6a, 0x48, 0xbe, 0x4f, 0x66, 0x59, 0x2a, 0x54, 0x06, 0x6c, 0x1a, 0xb7, + 0x91, 0x8a, 0x1e, 0xb2, 0xdd, 0x7a, 0xd8, 0xd5, 0x06, 0xe1, 0x30, 0x43, 0xa9, 0x82, 0x4b, 0x14, + 0xcd, 0xd6, 0xe2, 0x82, 0xfc, 0xbc, 0xe2, 0x54, 0xa1, 0x78, 0x2e, 0x71, 0x0c, 0x2d, 0x10, 0x29, + 0xa8, 0xbd, 0xaa, 0x04, 0xec, 0x85, 0x28, 0x0e, 0xc2, 0x65, 0x8a, 0x93, 0xc4, 0x89, 0x87, 0x72, + 0x0c, 0x17, 0x1e, 0xca, 0x31, 0x9c, 0x78, 0x24, 0xc7, 0x78, 0xe1, 0x91, 0x1c, 0xe3, 0x83, 0x47, + 0x72, 0x8c, 0x33, 0x1e, 0xcb, 0x31, 0x24, 0xb1, 0x81, 0xc3, 0xce, 0x18, 0x10, 0x00, 0x00, 0xff, + 0xff, 0x9f, 0xf2, 0x42, 0xe0, 0x91, 0x01, 0x00, 0x00, } diff --git a/vendor/github.com/coreos/etcd/lease/leasepb/lease.proto b/vendor/github.com/coreos/etcd/lease/leasepb/lease.proto index f2c996c8a..be414b993 100644 --- a/vendor/github.com/coreos/etcd/lease/leasepb/lease.proto +++ b/vendor/github.com/coreos/etcd/lease/leasepb/lease.proto @@ -2,6 +2,7 @@ syntax = "proto3"; package leasepb; import "gogoproto/gogo.proto"; +import "etcd/etcdserver/etcdserverpb/rpc.proto"; option (gogoproto.marshaler_all) = true; option (gogoproto.sizer_all) = true; @@ -13,3 +14,11 @@ message Lease { int64 ID = 1; int64 TTL = 2; } + +message LeaseInternalRequest { + etcdserverpb.LeaseTimeToLiveRequest LeaseTimeToLiveRequest = 1; +} + +message LeaseInternalResponse { + etcdserverpb.LeaseTimeToLiveResponse LeaseTimeToLiveResponse = 1; +} diff --git a/vendor/github.com/coreos/etcd/lease/lessor.go b/vendor/github.com/coreos/etcd/lease/lessor.go index 682d7376b..385bd76d7 100644 --- a/vendor/github.com/coreos/etcd/lease/lessor.go +++ b/vendor/github.com/coreos/etcd/lease/lessor.go @@ -18,11 +18,14 @@ import ( "encoding/binary" "errors" "math" + "sort" "sync" + "sync/atomic" "time" "github.com/coreos/etcd/lease/leasepb" "github.com/coreos/etcd/mvcc/backend" + "github.com/coreos/etcd/pkg/monotime" ) const ( @@ -32,9 +35,8 @@ const ( var ( leaseBucketName = []byte("lease") - // do not use maxInt64 since it can overflow time which will add - // the offset of unix time (1970yr to seconds). - forever = time.Unix(math.MaxInt64>>1, 0) + + forever = monotime.Time(math.MaxInt64) ErrNotPrimary = errors.New("not a primary lessor") ErrLeaseNotFound = errors.New("lease not found") @@ -75,6 +77,10 @@ type Lessor interface { // If the lease does not exist, an error will be returned. Attach(id LeaseID, items []LeaseItem) error + // GetLease returns LeaseID for given item. + // If no lease found, NoLease value will be returned. + GetLease(item LeaseItem) LeaseID + // Detach detaches given leaseItem from the lease with given LeaseID. // If the lease does not exist, an error will be returned. Detach(id LeaseID, items []LeaseItem) error @@ -110,20 +116,9 @@ type Lessor interface { type lessor struct { mu sync.Mutex - // primary indicates if this lessor is the primary lessor. The primary - // lessor manages lease expiration and renew. - // - // in etcd, raft leader is the primary. Thus there might be two primary - // leaders at the same time (raft allows concurrent leader but with different term) - // for at most a leader election timeout. - // The old primary leader cannot affect the correctness since its proposal has a - // smaller term and will not be committed. - // - // TODO: raft follower do not forward lease management proposals. There might be a - // very small window (within second normally which depends on go scheduling) that - // a raft follow is the primary between the raft leader demotion and lessor demotion. - // Usually this should not be a problem. Lease should not be that sensitive to timing. - primary bool + // demotec is set when the lessor is the primary. + // demotec will be closed if the lessor is demoted. + demotec chan struct{} // TODO: probably this should be a heap with a secondary // id index. @@ -133,6 +128,8 @@ type lessor struct { // findExpiredLeases and Renew should be the most frequent operations. leaseMap map[LeaseID]*Lease + itemMap map[LeaseItem]LeaseID + // When a lease expires, the lessor will delete the // leased range (or key) by the RangeDeleter. rd RangeDeleter @@ -159,6 +156,7 @@ func NewLessor(b backend.Backend, minLeaseTTL int64) Lessor { func newLessor(b backend.Backend, minLeaseTTL int64) *lessor { l := &lessor{ leaseMap: make(map[LeaseID]*Lease), + itemMap: make(map[LeaseItem]LeaseID), b: b, minLeaseTTL: minLeaseTTL, // expiredC is a small buffered chan to avoid unnecessary blocking. @@ -173,6 +171,23 @@ func newLessor(b backend.Backend, minLeaseTTL int64) *lessor { return l } +// isPrimary indicates if this lessor is the primary lessor. The primary +// lessor manages lease expiration and renew. +// +// in etcd, raft leader is the primary. Thus there might be two primary +// leaders at the same time (raft allows concurrent leader but with different term) +// for at most a leader election timeout. +// The old primary leader cannot affect the correctness since its proposal has a +// smaller term and will not be committed. +// +// TODO: raft follower do not forward lease management proposals. There might be a +// very small window (within second normally which depends on go scheduling) that +// a raft follow is the primary between the raft leader demotion and lessor demotion. +// Usually this should not be a problem. Lease should not be that sensitive to timing. +func (le *lessor) isPrimary() bool { + return le.demotec != nil +} + func (le *lessor) SetRangeDeleter(rd RangeDeleter) { le.mu.Lock() defer le.mu.Unlock() @@ -187,7 +202,12 @@ func (le *lessor) Grant(id LeaseID, ttl int64) (*Lease, error) { // TODO: when lessor is under high load, it should give out lease // with longer TTL to reduce renew load. - l := &Lease{ID: id, TTL: ttl, itemSet: make(map[LeaseItem]struct{})} + l := &Lease{ + ID: id, + ttl: ttl, + itemSet: make(map[LeaseItem]struct{}), + revokec: make(chan struct{}), + } le.mu.Lock() defer le.mu.Unlock() @@ -196,11 +216,11 @@ func (le *lessor) Grant(id LeaseID, ttl int64) (*Lease, error) { return nil, ErrLeaseExists } - if l.TTL < le.minLeaseTTL { - l.TTL = le.minLeaseTTL + if l.ttl < le.minLeaseTTL { + l.ttl = le.minLeaseTTL } - if le.primary { + if le.isPrimary() { l.refresh(0) } else { l.forever() @@ -220,6 +240,7 @@ func (le *lessor) Revoke(id LeaseID) error { le.mu.Unlock() return ErrLeaseNotFound } + defer close(l.revokec) // unlock before doing external work le.mu.Unlock() @@ -228,8 +249,13 @@ func (le *lessor) Revoke(id LeaseID) error { } tid := le.rd.TxnBegin() - for item := range l.itemSet { - _, _, err := le.rd.TxnDeleteRange(tid, []byte(item.Key), nil) + + // sort keys so deletes are in same order among all members, + // otherwise the backened hashes will be different + keys := l.Keys() + sort.StringSlice(keys).Sort() + for _, key := range keys { + _, _, err := le.rd.TxnDeleteRange(tid, []byte(key), nil) if err != nil { panic(err) } @@ -255,36 +281,55 @@ func (le *lessor) Revoke(id LeaseID) error { // has expired, an error will be returned. func (le *lessor) Renew(id LeaseID) (int64, error) { le.mu.Lock() - defer le.mu.Unlock() - if !le.primary { + unlock := func() { le.mu.Unlock() } + defer func() { unlock() }() + + if !le.isPrimary() { // forward renew request to primary instead of returning error. return -1, ErrNotPrimary } + demotec := le.demotec + l := le.leaseMap[id] if l == nil { return -1, ErrLeaseNotFound } + if l.expired() { + le.mu.Unlock() + unlock = func() {} + select { + // A expired lease might be pending for revoking or going through + // quorum to be revoked. To be accurate, renew request must wait for the + // deletion to complete. + case <-l.revokec: + return -1, ErrLeaseNotFound + // The expired lease might fail to be revoked if the primary changes. + // The caller will retry on ErrNotPrimary. + case <-demotec: + return -1, ErrNotPrimary + case <-le.stopC: + return -1, ErrNotPrimary + } + } + l.refresh(0) - return l.TTL, nil + return l.ttl, nil } func (le *lessor) Lookup(id LeaseID) *Lease { le.mu.Lock() defer le.mu.Unlock() - if l, ok := le.leaseMap[id]; ok { - return l - } - return nil + return le.leaseMap[id] } func (le *lessor) Promote(extend time.Duration) { le.mu.Lock() defer le.mu.Unlock() - le.primary = true + le.demotec = make(chan struct{}) // refresh the expiries of all leases. for _, l := range le.leaseMap { @@ -301,7 +346,10 @@ func (le *lessor) Demote() { l.forever() } - le.primary = false + if le.demotec != nil { + close(le.demotec) + le.demotec = nil + } } // Attach attaches items to the lease with given ID. When the lease @@ -316,12 +364,22 @@ func (le *lessor) Attach(id LeaseID, items []LeaseItem) error { return ErrLeaseNotFound } + l.mu.Lock() for _, it := range items { l.itemSet[it] = struct{}{} + le.itemMap[it] = id } + l.mu.Unlock() return nil } +func (le *lessor) GetLease(item LeaseItem) LeaseID { + le.mu.Lock() + id := le.itemMap[item] + le.mu.Unlock() + return id +} + // Detach detaches items from the lease with given ID. // If the given lease does not exist, an error will be returned. func (le *lessor) Detach(id LeaseID, items []LeaseItem) error { @@ -333,9 +391,12 @@ func (le *lessor) Detach(id LeaseID, items []LeaseItem) error { return ErrLeaseNotFound } + l.mu.Lock() for _, it := range items { delete(l.itemSet, it) + delete(le.itemMap, it) } + l.mu.Unlock() return nil } @@ -346,7 +407,7 @@ func (le *lessor) Recover(b backend.Backend, rd RangeDeleter) { le.b = b le.rd = rd le.leaseMap = make(map[LeaseID]*Lease) - + le.itemMap = make(map[LeaseItem]LeaseID) le.initAndRecover() } @@ -366,7 +427,7 @@ func (le *lessor) runLoop() { var ls []*Lease le.mu.Lock() - if le.primary { + if le.isPrimary() { ls = le.findExpiredLeases() } le.mu.Unlock() @@ -395,12 +456,11 @@ func (le *lessor) runLoop() { // leases that needed to be revoked. func (le *lessor) findExpiredLeases() []*Lease { leases := make([]*Lease, 0, 16) - now := time.Now() for _, l := range le.leaseMap { // TODO: probably should change to <= 100-500 millisecond to // make up committing latency. - if l.expiry.Sub(now) <= 0 { + if l.expired() { leases = append(leases, l) } } @@ -408,15 +468,6 @@ func (le *lessor) findExpiredLeases() []*Lease { return leases } -// get gets the lease with given id. -// get is a helper function for testing, at least for now. -func (le *lessor) get(id LeaseID) *Lease { - le.mu.Lock() - defer le.mu.Unlock() - - return le.leaseMap[id] -} - func (le *lessor) initAndRecover() { tx := le.b.BatchTx() tx.Lock() @@ -437,11 +488,12 @@ func (le *lessor) initAndRecover() { } le.leaseMap[ID] = &Lease{ ID: ID, - TTL: lpb.TTL, + ttl: lpb.TTL, // itemSet will be filled in when recover key-value pairs // set expiry to forever, refresh when promoted itemSet: make(map[LeaseItem]struct{}), expiry: forever, + revokec: make(chan struct{}), } } tx.Unlock() @@ -451,17 +503,24 @@ func (le *lessor) initAndRecover() { type Lease struct { ID LeaseID - TTL int64 // time to live in seconds + ttl int64 // time to live in seconds + // expiry is time when lease should expire; must be 64-bit aligned. + expiry monotime.Time + // mu protects concurrent accesses to itemSet + mu sync.RWMutex itemSet map[LeaseItem]struct{} - // expiry time in unixnano - expiry time.Time + revokec chan struct{} } -func (l Lease) persistTo(b backend.Backend) { +func (l *Lease) expired() bool { + return l.Remaining() <= 0 +} + +func (l *Lease) persistTo(b backend.Backend) { key := int64ToBytes(int64(l.ID)) - lpb := leasepb.Lease{ID: int64(l.ID), TTL: int64(l.TTL)} + lpb := leasepb.Lease{ID: int64(l.ID), TTL: int64(l.ttl)} val, err := lpb.Marshal() if err != nil { panic("failed to marshal lease proto item") @@ -472,13 +531,36 @@ func (l Lease) persistTo(b backend.Backend) { b.BatchTx().Unlock() } +// TTL returns the TTL of the Lease. +func (l *Lease) TTL() int64 { + return l.ttl +} + // refresh refreshes the expiry of the lease. func (l *Lease) refresh(extend time.Duration) { - l.expiry = time.Now().Add(extend + time.Second*time.Duration(l.TTL)) + t := monotime.Now().Add(extend + time.Duration(l.ttl)*time.Second) + atomic.StoreUint64((*uint64)(&l.expiry), uint64(t)) } // forever sets the expiry of lease to be forever. -func (l *Lease) forever() { l.expiry = forever } +func (l *Lease) forever() { atomic.StoreUint64((*uint64)(&l.expiry), uint64(forever)) } + +// Keys returns all the keys attached to the lease. +func (l *Lease) Keys() []string { + l.mu.RLock() + keys := make([]string, 0, len(l.itemSet)) + for k := range l.itemSet { + keys = append(keys, k.Key) + } + l.mu.RUnlock() + return keys +} + +// Remaining returns the remaining time of the lease. +func (l *Lease) Remaining() time.Duration { + t := monotime.Time(atomic.LoadUint64((*uint64)(&l.expiry))) + return time.Duration(t - monotime.Now()) +} type LeaseItem struct { Key string @@ -502,6 +584,7 @@ func (fl *FakeLessor) Revoke(id LeaseID) error { return nil } func (fl *FakeLessor) Attach(id LeaseID, items []LeaseItem) error { return nil } +func (fl *FakeLessor) GetLease(item LeaseItem) LeaseID { return 0 } func (fl *FakeLessor) Detach(id LeaseID, items []LeaseItem) error { return nil } func (fl *FakeLessor) Promote(extend time.Duration) {} diff --git a/vendor/github.com/coreos/etcd/mvcc/backend/backend.go b/vendor/github.com/coreos/etcd/mvcc/backend/backend.go index 51b89021d..e5e0028f9 100644 --- a/vendor/github.com/coreos/etcd/mvcc/backend/backend.go +++ b/vendor/github.com/coreos/etcd/mvcc/backend/backend.go @@ -20,7 +20,7 @@ import ( "io" "io/ioutil" "os" - "path" + "path/filepath" "sync" "sync/atomic" "time" @@ -40,7 +40,7 @@ var ( // This only works for linux. InitialMmapSize = int64(10 * 1024 * 1024 * 1024) - plog = capnslog.NewPackageLogger("github.com/coreos/etcd/mvcc", "backend") + plog = capnslog.NewPackageLogger("github.com/coreos/etcd", "mvcc/backend") ) const ( @@ -303,6 +303,7 @@ func defragdb(odb, tmpdb *bolt.DB, limit int) error { } tmpb, berr := tmptx.CreateBucketIfNotExists(next) + tmpb.FillPercent = 0.9 // for seq write in for each if berr != nil { return berr } @@ -319,6 +320,8 @@ func defragdb(odb, tmpdb *bolt.DB, limit int) error { return err } tmpb = tmptx.Bucket(next) + tmpb.FillPercent = 0.9 // for seq write in for each + count = 0 } return tmpb.Put(k, v) @@ -334,7 +337,7 @@ func NewTmpBackend(batchInterval time.Duration, batchLimit int) (*backend, strin if err != nil { plog.Fatal(err) } - tmpPath := path.Join(dir, "database") + tmpPath := filepath.Join(dir, "database") return newBackend(tmpPath, batchInterval, batchLimit), tmpPath } diff --git a/vendor/github.com/coreos/etcd/mvcc/backend/batch_tx.go b/vendor/github.com/coreos/etcd/mvcc/backend/batch_tx.go index e1cdcc65a..04fea1e94 100644 --- a/vendor/github.com/coreos/etcd/mvcc/backend/batch_tx.go +++ b/vendor/github.com/coreos/etcd/mvcc/backend/batch_tx.go @@ -162,11 +162,26 @@ func (t *batchTx) commit(stop bool) { if t.pending == 0 && !stop { t.backend.mu.RLock() defer t.backend.mu.RUnlock() - atomic.StoreInt64(&t.backend.size, t.tx.Size()) + + // batchTx.commit(true) calls *bolt.Tx.Commit, which + // initializes *bolt.Tx.db and *bolt.Tx.meta as nil, + // and subsequent *bolt.Tx.Size() call panics. + // + // This nil pointer reference panic happens when: + // 1. batchTx.commit(false) from newBatchTx + // 2. batchTx.commit(true) from stopping backend + // 3. batchTx.commit(false) from inflight mvcc Hash call + // + // Check if db is nil to prevent this panic + if t.tx.DB() != nil { + atomic.StoreInt64(&t.backend.size, t.tx.Size()) + } return } start := time.Now() + // gofail: var beforeCommit struct{} err = t.tx.Commit() + // gofail: var afterCommit struct{} commitDurations.Observe(time.Since(start).Seconds()) atomic.AddInt64(&t.backend.commits, 1) diff --git a/vendor/github.com/coreos/etcd/mvcc/index.go b/vendor/github.com/coreos/etcd/mvcc/index.go index e8e489b4d..397098a7b 100644 --- a/vendor/github.com/coreos/etcd/mvcc/index.go +++ b/vendor/github.com/coreos/etcd/mvcc/index.go @@ -25,11 +25,11 @@ type index interface { Get(key []byte, atRev int64) (rev, created revision, ver int64, err error) Range(key, end []byte, atRev int64) ([][]byte, []revision) Put(key []byte, rev revision) - Restore(key []byte, created, modified revision, ver int64) Tombstone(key []byte, rev revision) error RangeSince(key, end []byte, rev int64) []revision Compact(rev int64) map[revision]struct{} Equal(b index) bool + Insert(ki *keyIndex) } type treeIndex struct { @@ -58,21 +58,6 @@ func (ti *treeIndex) Put(key []byte, rev revision) { okeyi.put(rev.main, rev.sub) } -func (ti *treeIndex) Restore(key []byte, created, modified revision, ver int64) { - keyi := &keyIndex{key: key} - - ti.Lock() - defer ti.Unlock() - item := ti.tree.Get(keyi) - if item == nil { - keyi.restore(created, modified, ver) - ti.tree.ReplaceOrInsert(keyi) - return - } - okeyi := item.(*keyIndex) - okeyi.put(modified.main, modified.sub) -} - func (ti *treeIndex) Get(key []byte, atRev int64) (modified, created revision, ver int64, err error) { keyi := &keyIndex{key: key} @@ -215,3 +200,9 @@ func (a *treeIndex) Equal(bi index) bool { return equal } + +func (ti *treeIndex) Insert(ki *keyIndex) { + ti.Lock() + defer ti.Unlock() + ti.tree.ReplaceOrInsert(ki) +} diff --git a/vendor/github.com/coreos/etcd/mvcc/kvstore.go b/vendor/github.com/coreos/etcd/mvcc/kvstore.go index 6819c69a1..28a18a065 100644 --- a/vendor/github.com/coreos/etcd/mvcc/kvstore.go +++ b/vendor/github.com/coreos/etcd/mvcc/kvstore.go @@ -74,8 +74,9 @@ type store struct { // the main revision of the last compaction compactMainRev int64 - tx backend.BatchTx - txnID int64 // tracks the current txnID to verify txn operations + tx backend.BatchTx + txnID int64 // tracks the current txnID to verify txn operations + txnModify bool // bytesBuf8 is a byte slice of length 8 // to avoid a repetitive allocation in saveIndex. @@ -180,7 +181,6 @@ func (s *store) TxnBegin() int64 { s.currentRev.sub = 0 s.tx = s.b.BatchTx() s.tx.Lock() - s.saveIndex() s.txnID = rand.Int63() return s.txnID @@ -203,6 +203,14 @@ func (s *store) txnEnd(txnID int64) error { return ErrTxnIDMismatch } + // only update index if the txn modifies the mvcc state. + // read only txn might execute with one write txn concurrently, + // it should not write its index to mvcc. + if s.txnModify { + s.saveIndex() + } + s.txnModify = false + s.tx.Unlock() if s.currentRev.sub != 0 { s.currentRev.main += 1 @@ -314,20 +322,23 @@ func (s *store) Compact(rev int64) (<-chan struct{}, error) { return ch, nil } -func (s *store) Hash() (uint32, int64, error) { - s.b.ForceCommit() +// DefaultIgnores is a map of keys to ignore in hash checking. +var DefaultIgnores map[backend.IgnoreKey]struct{} +func init() { + DefaultIgnores = map[backend.IgnoreKey]struct{}{ + // consistent index might be changed due to v2 internal sync, which + // is not controllable by the user. + {Bucket: string(metaBucketName), Key: string(consistentIndexKeyName)}: {}, + } +} + +func (s *store) Hash() (uint32, int64, error) { s.mu.Lock() defer s.mu.Unlock() + s.b.ForceCommit() - // ignore hash consistent index field for now. - // consistent index might be changed due to v2 internal sync, which - // is not controllable by the user. - ignores := make(map[backend.IgnoreKey]struct{}) - bk := backend.IgnoreKey{Bucket: string(metaBucketName), Key: string(consistentIndexKeyName)} - ignores[bk] = struct{}{} - - h, err := s.b.Hash(ignores) + h, err := s.b.Hash(DefaultIgnores) rev := s.currentRev.main return h, rev, err } @@ -369,6 +380,11 @@ func (s *store) restore() error { keyToLease := make(map[string]lease.LeaseID) + // use an unordered map to hold the temp index data to speed up + // the initial key index recovery. + // we will convert this unordered map into the tree index later. + unordered := make(map[string]*keyIndex, 100000) + // restore index tx := s.b.BatchTx() tx.Lock() @@ -391,11 +407,20 @@ func (s *store) restore() error { // restore index switch { case isTombstone(key): - s.kvindex.Tombstone(kv.Key, rev) + if ki, ok := unordered[string(kv.Key)]; ok { + ki.tombstone(rev.main, rev.sub) + } delete(keyToLease, string(kv.Key)) default: - s.kvindex.Restore(kv.Key, revision{kv.CreateRevision, 0}, rev, kv.Version) + ki, ok := unordered[string(kv.Key)] + if ok { + ki.put(rev.main, rev.sub) + } else { + ki = &keyIndex{key: kv.Key} + ki.restore(revision{kv.CreateRevision, 0}, rev, kv.Version) + unordered[string(kv.Key)] = ki + } if lid := lease.LeaseID(kv.Lease); lid != lease.NoLease { keyToLease[string(kv.Key)] = lid @@ -408,6 +433,11 @@ func (s *store) restore() error { s.currentRev = rev } + // restore the tree index from the unordered index. + for _, v := range unordered { + s.kvindex.Insert(v) + } + // keys in the range [compacted revision -N, compaction] might all be deleted due to compaction. // the correct revision should be set to compaction revision in the case, not the largest revision // we have seen. @@ -509,23 +539,18 @@ func (s *store) rangeKeys(key, end []byte, limit, rangeRev int64, countOnly bool } func (s *store) put(key, value []byte, leaseID lease.LeaseID) { + s.txnModify = true + rev := s.currentRev.main + 1 c := rev oldLease := lease.NoLease // if the key exists before, use its previous created and // get its previous leaseID - grev, created, ver, err := s.kvindex.Get(key, rev) + _, created, ver, err := s.kvindex.Get(key, rev) if err == nil { c = created.main - ibytes := newRevBytes() - revToBytes(grev, ibytes) - _, vs := s.tx.UnsafeRange(keyBucketName, ibytes, nil, 0) - var kv mvccpb.KeyValue - if err = kv.Unmarshal(vs[0]); err != nil { - plog.Fatalf("cannot unmarshal value: %v", err) - } - oldLease = lease.LeaseID(kv.Lease) + oldLease = s.le.GetLease(lease.LeaseItem{Key: string(key)}) } ibytes := newRevBytes() @@ -575,6 +600,8 @@ func (s *store) put(key, value []byte, leaseID lease.LeaseID) { } func (s *store) deleteRange(key, end []byte) int64 { + s.txnModify = true + rrev := s.currentRev.main if s.currentRev.sub > 0 { rrev += 1 @@ -615,17 +642,11 @@ func (s *store) delete(key []byte, rev revision) { s.changes = append(s.changes, kv) s.currentRev.sub += 1 - ibytes = newRevBytes() - revToBytes(rev, ibytes) - _, vs := s.tx.UnsafeRange(keyBucketName, ibytes, nil, 0) + item := lease.LeaseItem{Key: string(key)} + leaseID := s.le.GetLease(item) - kv.Reset() - if err = kv.Unmarshal(vs[0]); err != nil { - plog.Fatalf("cannot unmarshal value: %v", err) - } - - if lease.LeaseID(kv.Lease) != lease.NoLease { - err = s.le.Detach(lease.LeaseID(kv.Lease), []lease.LeaseItem{{Key: string(kv.Key)}}) + if leaseID != lease.NoLease { + err = s.le.Detach(leaseID, []lease.LeaseItem{item}) if err != nil { plog.Errorf("cannot detach %v", err) } 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 12c038328..aa053f4e6 100644 --- a/vendor/github.com/coreos/etcd/mvcc/mvccpb/kv.pb.go +++ b/vendor/github.com/coreos/etcd/mvcc/mvccpb/kv.pb.go @@ -31,7 +31,9 @@ var _ = math.Inf // This is a compile-time assertion to ensure that this generated file // is compatible with the proto package it is being compiled against. -const _ = proto.ProtoPackageIsVersion1 +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package type Event_EventType int32 @@ -103,91 +105,91 @@ func init() { proto.RegisterType((*Event)(nil), "mvccpb.Event") proto.RegisterEnum("mvccpb.Event_EventType", Event_EventType_name, Event_EventType_value) } -func (m *KeyValue) Marshal() (data []byte, err error) { +func (m *KeyValue) Marshal() (dAtA []byte, err error) { size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) if err != nil { return nil, err } - return data[:n], nil + return dAtA[:n], nil } -func (m *KeyValue) MarshalTo(data []byte) (int, error) { +func (m *KeyValue) MarshalTo(dAtA []byte) (int, error) { var i int _ = i var l int _ = l if len(m.Key) > 0 { - data[i] = 0xa + dAtA[i] = 0xa i++ - i = encodeVarintKv(data, i, uint64(len(m.Key))) - i += copy(data[i:], m.Key) + i = encodeVarintKv(dAtA, i, uint64(len(m.Key))) + i += copy(dAtA[i:], m.Key) } if m.CreateRevision != 0 { - data[i] = 0x10 + dAtA[i] = 0x10 i++ - i = encodeVarintKv(data, i, uint64(m.CreateRevision)) + i = encodeVarintKv(dAtA, i, uint64(m.CreateRevision)) } if m.ModRevision != 0 { - data[i] = 0x18 + dAtA[i] = 0x18 i++ - i = encodeVarintKv(data, i, uint64(m.ModRevision)) + i = encodeVarintKv(dAtA, i, uint64(m.ModRevision)) } if m.Version != 0 { - data[i] = 0x20 + dAtA[i] = 0x20 i++ - i = encodeVarintKv(data, i, uint64(m.Version)) + i = encodeVarintKv(dAtA, i, uint64(m.Version)) } if len(m.Value) > 0 { - data[i] = 0x2a + dAtA[i] = 0x2a i++ - i = encodeVarintKv(data, i, uint64(len(m.Value))) - i += copy(data[i:], m.Value) + i = encodeVarintKv(dAtA, i, uint64(len(m.Value))) + i += copy(dAtA[i:], m.Value) } if m.Lease != 0 { - data[i] = 0x30 + dAtA[i] = 0x30 i++ - i = encodeVarintKv(data, i, uint64(m.Lease)) + i = encodeVarintKv(dAtA, i, uint64(m.Lease)) } return i, nil } -func (m *Event) Marshal() (data []byte, err error) { +func (m *Event) Marshal() (dAtA []byte, err error) { size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) if err != nil { return nil, err } - return data[:n], nil + return dAtA[:n], nil } -func (m *Event) MarshalTo(data []byte) (int, error) { +func (m *Event) MarshalTo(dAtA []byte) (int, error) { var i int _ = i var l int _ = l if m.Type != 0 { - data[i] = 0x8 + dAtA[i] = 0x8 i++ - i = encodeVarintKv(data, i, uint64(m.Type)) + i = encodeVarintKv(dAtA, i, uint64(m.Type)) } if m.Kv != nil { - data[i] = 0x12 + dAtA[i] = 0x12 i++ - i = encodeVarintKv(data, i, uint64(m.Kv.Size())) - n1, err := m.Kv.MarshalTo(data[i:]) + i = encodeVarintKv(dAtA, i, uint64(m.Kv.Size())) + n1, err := m.Kv.MarshalTo(dAtA[i:]) if err != nil { return 0, err } i += n1 } if m.PrevKv != nil { - data[i] = 0x1a + dAtA[i] = 0x1a i++ - i = encodeVarintKv(data, i, uint64(m.PrevKv.Size())) - n2, err := m.PrevKv.MarshalTo(data[i:]) + i = encodeVarintKv(dAtA, i, uint64(m.PrevKv.Size())) + n2, err := m.PrevKv.MarshalTo(dAtA[i:]) if err != nil { return 0, err } @@ -196,31 +198,31 @@ func (m *Event) MarshalTo(data []byte) (int, error) { return i, nil } -func encodeFixed64Kv(data []byte, offset int, v uint64) int { - data[offset] = uint8(v) - data[offset+1] = uint8(v >> 8) - data[offset+2] = uint8(v >> 16) - data[offset+3] = uint8(v >> 24) - data[offset+4] = uint8(v >> 32) - data[offset+5] = uint8(v >> 40) - data[offset+6] = uint8(v >> 48) - data[offset+7] = uint8(v >> 56) +func encodeFixed64Kv(dAtA []byte, offset int, v uint64) int { + dAtA[offset] = uint8(v) + dAtA[offset+1] = uint8(v >> 8) + dAtA[offset+2] = uint8(v >> 16) + dAtA[offset+3] = uint8(v >> 24) + dAtA[offset+4] = uint8(v >> 32) + dAtA[offset+5] = uint8(v >> 40) + dAtA[offset+6] = uint8(v >> 48) + dAtA[offset+7] = uint8(v >> 56) return offset + 8 } -func encodeFixed32Kv(data []byte, offset int, v uint32) int { - data[offset] = uint8(v) - data[offset+1] = uint8(v >> 8) - data[offset+2] = uint8(v >> 16) - data[offset+3] = uint8(v >> 24) +func encodeFixed32Kv(dAtA []byte, offset int, v uint32) int { + dAtA[offset] = uint8(v) + dAtA[offset+1] = uint8(v >> 8) + dAtA[offset+2] = uint8(v >> 16) + dAtA[offset+3] = uint8(v >> 24) return offset + 4 } -func encodeVarintKv(data []byte, offset int, v uint64) int { +func encodeVarintKv(dAtA []byte, offset int, v uint64) int { for v >= 1<<7 { - data[offset] = uint8(v&0x7f | 0x80) + dAtA[offset] = uint8(v&0x7f | 0x80) v >>= 7 offset++ } - data[offset] = uint8(v) + dAtA[offset] = uint8(v) return offset + 1 } func (m *KeyValue) Size() (n int) { @@ -279,8 +281,8 @@ func sovKv(x uint64) (n int) { func sozKv(x uint64) (n int) { return sovKv(uint64((x << 1) ^ uint64((int64(x) >> 63)))) } -func (m *KeyValue) Unmarshal(data []byte) error { - l := len(data) +func (m *KeyValue) Unmarshal(dAtA []byte) error { + l := len(dAtA) iNdEx := 0 for iNdEx < l { preIndex := iNdEx @@ -292,7 +294,7 @@ func (m *KeyValue) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -320,7 +322,7 @@ func (m *KeyValue) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ byteLen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -334,7 +336,7 @@ func (m *KeyValue) Unmarshal(data []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Key = append(m.Key[:0], data[iNdEx:postIndex]...) + m.Key = append(m.Key[:0], dAtA[iNdEx:postIndex]...) if m.Key == nil { m.Key = []byte{} } @@ -351,7 +353,7 @@ func (m *KeyValue) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ m.CreateRevision |= (int64(b) & 0x7F) << shift if b < 0x80 { @@ -370,7 +372,7 @@ func (m *KeyValue) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ m.ModRevision |= (int64(b) & 0x7F) << shift if b < 0x80 { @@ -389,7 +391,7 @@ func (m *KeyValue) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ m.Version |= (int64(b) & 0x7F) << shift if b < 0x80 { @@ -408,7 +410,7 @@ func (m *KeyValue) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ byteLen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -422,7 +424,7 @@ func (m *KeyValue) Unmarshal(data []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Value = append(m.Value[:0], data[iNdEx:postIndex]...) + m.Value = append(m.Value[:0], dAtA[iNdEx:postIndex]...) if m.Value == nil { m.Value = []byte{} } @@ -439,7 +441,7 @@ func (m *KeyValue) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ m.Lease |= (int64(b) & 0x7F) << shift if b < 0x80 { @@ -448,7 +450,7 @@ func (m *KeyValue) Unmarshal(data []byte) error { } default: iNdEx = preIndex - skippy, err := skipKv(data[iNdEx:]) + skippy, err := skipKv(dAtA[iNdEx:]) if err != nil { return err } @@ -467,8 +469,8 @@ func (m *KeyValue) Unmarshal(data []byte) error { } return nil } -func (m *Event) Unmarshal(data []byte) error { - l := len(data) +func (m *Event) Unmarshal(dAtA []byte) error { + l := len(dAtA) iNdEx := 0 for iNdEx < l { preIndex := iNdEx @@ -480,7 +482,7 @@ func (m *Event) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -508,7 +510,7 @@ func (m *Event) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ m.Type |= (Event_EventType(b) & 0x7F) << shift if b < 0x80 { @@ -527,7 +529,7 @@ func (m *Event) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ msglen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -544,7 +546,7 @@ func (m *Event) Unmarshal(data []byte) error { if m.Kv == nil { m.Kv = &KeyValue{} } - if err := m.Kv.Unmarshal(data[iNdEx:postIndex]); err != nil { + if err := m.Kv.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -560,7 +562,7 @@ func (m *Event) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ msglen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -577,13 +579,13 @@ func (m *Event) Unmarshal(data []byte) error { if m.PrevKv == nil { m.PrevKv = &KeyValue{} } - if err := m.PrevKv.Unmarshal(data[iNdEx:postIndex]); err != nil { + if err := m.PrevKv.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skipKv(data[iNdEx:]) + skippy, err := skipKv(dAtA[iNdEx:]) if err != nil { return err } @@ -602,8 +604,8 @@ func (m *Event) Unmarshal(data []byte) error { } return nil } -func skipKv(data []byte) (n int, err error) { - l := len(data) +func skipKv(dAtA []byte) (n int, err error) { + l := len(dAtA) iNdEx := 0 for iNdEx < l { var wire uint64 @@ -614,7 +616,7 @@ func skipKv(data []byte) (n int, err error) { if iNdEx >= l { return 0, io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -632,7 +634,7 @@ func skipKv(data []byte) (n int, err error) { return 0, io.ErrUnexpectedEOF } iNdEx++ - if data[iNdEx-1] < 0x80 { + if dAtA[iNdEx-1] < 0x80 { break } } @@ -649,7 +651,7 @@ func skipKv(data []byte) (n int, err error) { if iNdEx >= l { return 0, io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ length |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -672,7 +674,7 @@ func skipKv(data []byte) (n int, err error) { if iNdEx >= l { return 0, io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ innerWire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -683,7 +685,7 @@ func skipKv(data []byte) (n int, err error) { if innerWireType == 4 { break } - next, err := skipKv(data[start:]) + next, err := skipKv(dAtA[start:]) if err != nil { return 0, err } @@ -707,6 +709,8 @@ var ( ErrIntOverflowKv = fmt.Errorf("proto: integer overflow") ) +func init() { proto.RegisterFile("kv.proto", fileDescriptorKv) } + var fileDescriptorKv = []byte{ // 303 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x6c, 0x90, 0x41, 0x4e, 0xc2, 0x40, diff --git a/vendor/github.com/coreos/etcd/mvcc/mvccpb/kv.proto b/vendor/github.com/coreos/etcd/mvcc/mvccpb/kv.proto index f150d26c7..23c911b7d 100644 --- a/vendor/github.com/coreos/etcd/mvcc/mvccpb/kv.proto +++ b/vendor/github.com/coreos/etcd/mvcc/mvccpb/kv.proto @@ -43,6 +43,7 @@ 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/mvcc/watchable_store.go b/vendor/github.com/coreos/etcd/mvcc/watchable_store.go index 8339500ec..dbb79bcb6 100644 --- a/vendor/github.com/coreos/etcd/mvcc/watchable_store.go +++ b/vendor/github.com/coreos/etcd/mvcc/watchable_store.go @@ -35,7 +35,7 @@ const ( ) type watchable interface { - watch(key, end []byte, startRev int64, id WatchID, ch chan<- WatchResponse) (*watcher, cancelFunc) + watch(key, end []byte, startRev int64, id WatchID, ch chan<- WatchResponse, fcs ...FilterFunc) (*watcher, cancelFunc) progress(w *watcher) rev() int64 } @@ -185,7 +185,7 @@ func (s *watchableStore) NewWatchStream() WatchStream { } } -func (s *watchableStore) watch(key, end []byte, startRev int64, id WatchID, ch chan<- WatchResponse) (*watcher, cancelFunc) { +func (s *watchableStore) watch(key, end []byte, startRev int64, id WatchID, ch chan<- WatchResponse, fcs ...FilterFunc) (*watcher, cancelFunc) { s.mu.Lock() defer s.mu.Unlock() @@ -195,6 +195,7 @@ func (s *watchableStore) watch(key, end []byte, startRev int64, id WatchID, ch c minRev: startRev, id: id, ch: ch, + fcs: fcs, } s.store.mu.Lock() @@ -325,10 +326,9 @@ func (s *watchableStore) moveVictims() (moved int) { for w, eb := range wb { // watcher has observed the store up to, but not including, w.minRev rev := w.minRev - 1 - select { - case w.ch <- WatchResponse{WatchID: w.id, Events: eb.evs, Revision: rev}: + if w.send(WatchResponse{WatchID: w.id, Events: eb.evs, Revision: rev}) { pendingEventsGauge.Add(float64(len(eb.evs))) - default: + } else { if newVictim == nil { newVictim = make(watcherBatch) } @@ -419,10 +419,9 @@ func (s *watchableStore) syncWatchers() { w.minRev = eb.moreRev } - select { - case w.ch <- WatchResponse{WatchID: w.id, Events: eb.evs, Revision: curRev}: + if w.send(WatchResponse{WatchID: w.id, Events: eb.evs, Revision: curRev}) { pendingEventsGauge.Add(float64(len(eb.evs))) - default: + } else { if victims == nil { victims = make(watcherBatch) } @@ -480,10 +479,10 @@ func (s *watchableStore) notify(rev int64, evs []mvccpb.Event) { if eb.revs != 1 { plog.Panicf("unexpected multiple revisions in notification") } - select { - case w.ch <- WatchResponse{WatchID: w.id, Events: eb.evs, Revision: rev}: + + if w.send(WatchResponse{WatchID: w.id, Events: eb.evs, Revision: rev}) { pendingEventsGauge.Add(float64(len(eb.evs))) - default: + } else { // move slow watcher to victims w.minRev = rev + 1 if victim == nil { @@ -516,12 +515,9 @@ func (s *watchableStore) progress(w *watcher) { defer s.mu.Unlock() if _, ok := s.synced.watchers[w]; ok { - select { - case w.ch <- WatchResponse{WatchID: w.id, Revision: s.rev()}: - default: - // If the ch is full, this watcher is receiving events. - // We do not need to send progress at all. - } + w.send(WatchResponse{WatchID: w.id, Revision: s.rev()}) + // If the ch is full, this watcher is receiving events. + // We do not need to send progress at all. } } @@ -542,7 +538,40 @@ type watcher struct { minRev int64 id WatchID + fcs []FilterFunc // a chan to send out the watch response. // The chan might be shared with other watchers. ch chan<- WatchResponse } + +func (w *watcher) send(wr WatchResponse) bool { + progressEvent := len(wr.Events) == 0 + + if len(w.fcs) != 0 { + ne := make([]mvccpb.Event, 0, len(wr.Events)) + for i := range wr.Events { + filtered := false + for _, filter := range w.fcs { + if filter(wr.Events[i]) { + filtered = true + break + } + } + if !filtered { + ne = append(ne, wr.Events[i]) + } + } + wr.Events = ne + } + + // if all events are filtered out, we should send nothing. + if !progressEvent && len(wr.Events) == 0 { + return true + } + select { + case w.ch <- wr: + return true + default: + return false + } +} diff --git a/vendor/github.com/coreos/etcd/mvcc/watcher.go b/vendor/github.com/coreos/etcd/mvcc/watcher.go index 8410aa845..9468d4269 100644 --- a/vendor/github.com/coreos/etcd/mvcc/watcher.go +++ b/vendor/github.com/coreos/etcd/mvcc/watcher.go @@ -28,6 +28,9 @@ var ( type WatchID int64 +// FilterFunc returns true if the given event should be filtered out. +type FilterFunc func(e mvccpb.Event) bool + type WatchStream interface { // Watch creates a watcher. The watcher watches the events happening or // happened on the given key or range [key, end) from the given startRev. @@ -38,7 +41,7 @@ type WatchStream interface { // The returned `id` is the ID of this watcher. It appears as WatchID // in events that are sent to the created watcher through stream channel. // - Watch(key, end []byte, startRev int64) WatchID + Watch(key, end []byte, startRev int64, fcs ...FilterFunc) WatchID // Chan returns a chan. All watch response will be sent to the returned chan. Chan() <-chan WatchResponse @@ -96,7 +99,7 @@ type watchStream struct { // Watch creates a new watcher in the stream and returns its WatchID. // TODO: return error if ws is closed? -func (ws *watchStream) Watch(key, end []byte, startRev int64) WatchID { +func (ws *watchStream) Watch(key, end []byte, startRev int64, fcs ...FilterFunc) WatchID { // prevent wrong range where key >= end lexicographically // watch request with 'WithFromKey' has empty-byte range end if len(end) != 0 && bytes.Compare(key, end) != -1 { @@ -112,7 +115,7 @@ func (ws *watchStream) Watch(key, end []byte, startRev int64) WatchID { id := ws.nextID ws.nextID++ - w, c := ws.watchable.watch(key, end, startRev, id, ws.ch) + w, c := ws.watchable.watch(key, end, startRev, id, ws.ch, fcs...) ws.cancels[id] = c ws.watchers[id] = w diff --git a/vendor/github.com/coreos/etcd/mvcc/watcher_group.go b/vendor/github.com/coreos/etcd/mvcc/watcher_group.go index 7a4d7daa8..2710c1cc9 100644 --- a/vendor/github.com/coreos/etcd/mvcc/watcher_group.go +++ b/vendor/github.com/coreos/etcd/mvcc/watcher_group.go @@ -78,6 +78,10 @@ func (wb watcherBatch) add(w *watcher, ev mvccpb.Event) { // newWatcherBatch maps watchers to their matched events. It enables quick // events look up by watcher. func newWatcherBatch(wg *watcherGroup, evs []mvccpb.Event) watcherBatch { + if len(wg.watchers) == 0 { + return nil + } + wb := make(watcherBatch) for _, ev := range evs { for w := range wg.watcherSetByKey(string(ev.Kv.Key)) { diff --git a/vendor/github.com/coreos/etcd/pkg/adt/interval_tree.go b/vendor/github.com/coreos/etcd/pkg/adt/interval_tree.go index ab311c6d6..6edbe593f 100644 --- a/vendor/github.com/coreos/etcd/pkg/adt/interval_tree.go +++ b/vendor/github.com/coreos/etcd/pkg/adt/interval_tree.go @@ -447,6 +447,9 @@ func (ivt *IntervalTree) Contains(iv Interval) bool { // Stab returns a slice with all elements in the tree intersecting the interval. func (ivt *IntervalTree) Stab(iv Interval) (ivs []*IntervalValue) { + if ivt.count == 0 { + return nil + } f := func(n *IntervalValue) bool { ivs = append(ivs, n); return true } ivt.Visit(iv, f) return ivs diff --git a/vendor/github.com/coreos/etcd/pkg/cpuutil/doc.go b/vendor/github.com/coreos/etcd/pkg/cpuutil/doc.go new file mode 100644 index 000000000..0323b2d34 --- /dev/null +++ b/vendor/github.com/coreos/etcd/pkg/cpuutil/doc.go @@ -0,0 +1,16 @@ +// Copyright 2017 The etcd Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package cpuutil provides facilities for detecting cpu-specific features. +package cpuutil diff --git a/vendor/github.com/coreos/etcd/pkg/cpuutil/endian.go b/vendor/github.com/coreos/etcd/pkg/cpuutil/endian.go new file mode 100644 index 000000000..6ab898d4b --- /dev/null +++ b/vendor/github.com/coreos/etcd/pkg/cpuutil/endian.go @@ -0,0 +1,36 @@ +// Copyright 2017 The etcd Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package cpuutil + +import ( + "encoding/binary" + "unsafe" +) + +const intWidth int = int(unsafe.Sizeof(0)) + +var byteOrder binary.ByteOrder + +// ByteOrder returns the byte order for the CPU's native endianness. +func ByteOrder() binary.ByteOrder { return byteOrder } + +func init() { + var i int = 0x1 + if v := (*[intWidth]byte)(unsafe.Pointer(&i)); v[0] == 0 { + byteOrder = binary.BigEndian + } else { + byteOrder = binary.LittleEndian + } +} diff --git a/vendor/github.com/coreos/etcd/pkg/fileutil/fileutil.go b/vendor/github.com/coreos/etcd/pkg/fileutil/fileutil.go index 8d9e725f0..aad40b759 100644 --- a/vendor/github.com/coreos/etcd/pkg/fileutil/fileutil.go +++ b/vendor/github.com/coreos/etcd/pkg/fileutil/fileutil.go @@ -19,7 +19,7 @@ import ( "fmt" "io/ioutil" "os" - "path" + "path/filepath" "sort" "github.com/coreos/pkg/capnslog" @@ -33,13 +33,13 @@ const ( ) var ( - plog = capnslog.NewPackageLogger("github.com/coreos/etcd/pkg", "fileutil") + plog = capnslog.NewPackageLogger("github.com/coreos/etcd", "pkg/fileutil") ) // IsDirWriteable checks if dir is writable by writing and removing a file // to dir. It returns nil if dir is writable. func IsDirWriteable(dir string) error { - f := path.Join(dir, ".touch") + f := filepath.Join(dir, ".touch") if err := ioutil.WriteFile(f, []byte(""), PrivateFileMode); err != nil { return err } diff --git a/vendor/github.com/coreos/etcd/pkg/fileutil/purge.go b/vendor/github.com/coreos/etcd/pkg/fileutil/purge.go index 53bda0c01..92fceab01 100644 --- a/vendor/github.com/coreos/etcd/pkg/fileutil/purge.go +++ b/vendor/github.com/coreos/etcd/pkg/fileutil/purge.go @@ -16,7 +16,7 @@ package fileutil import ( "os" - "path" + "path/filepath" "sort" "strings" "time" @@ -45,7 +45,7 @@ func purgeFile(dirname string, suffix string, max uint, interval time.Duration, sort.Strings(newfnames) fnames = newfnames for len(newfnames) > int(max) { - f := path.Join(dirname, newfnames[0]) + f := filepath.Join(dirname, newfnames[0]) l, err := TryLockFile(f, os.O_WRONLY, PrivateFileMode) if err != nil { break diff --git a/vendor/github.com/coreos/etcd/pkg/httputil/httputil.go b/vendor/github.com/coreos/etcd/pkg/httputil/httputil.go index daf43bd8f..859fc9d49 100644 --- a/vendor/github.com/coreos/etcd/pkg/httputil/httputil.go +++ b/vendor/github.com/coreos/etcd/pkg/httputil/httputil.go @@ -13,7 +13,7 @@ import ( "net/http" ) -func RequestCanceler(rt http.RoundTripper, req *http.Request) func() { +func RequestCanceler(req *http.Request) func() { ch := make(chan struct{}) req.Cancel = ch diff --git a/vendor/github.com/coreos/etcd/pkg/monotime/issue15006.s b/vendor/github.com/coreos/etcd/pkg/monotime/issue15006.s new file mode 100644 index 000000000..c3132a1f0 --- /dev/null +++ b/vendor/github.com/coreos/etcd/pkg/monotime/issue15006.s @@ -0,0 +1,6 @@ +// Copyright (C) 2016 Arista Networks, Inc. +// Use of this source code is governed by the Apache License 2.0 +// that can be found in the COPYING file. + +// This file is intentionally empty. +// It's a workaround for https://github.com/golang/go/issues/15006 \ No newline at end of file diff --git a/vendor/github.com/coreos/etcd/pkg/monotime/monotime.go b/vendor/github.com/coreos/etcd/pkg/monotime/monotime.go new file mode 100644 index 000000000..a5e16ce1d --- /dev/null +++ b/vendor/github.com/coreos/etcd/pkg/monotime/monotime.go @@ -0,0 +1,26 @@ +// Copyright 2016 The etcd Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package monotime + +import ( + "time" +) + +// Time represents a point in monotonic time +type Time uint64 + +func (t Time) Add(d time.Duration) Time { + return Time(uint64(t) + uint64(d.Nanoseconds())) +} diff --git a/vendor/github.com/coreos/etcd/pkg/monotime/nanotime.go b/vendor/github.com/coreos/etcd/pkg/monotime/nanotime.go new file mode 100644 index 000000000..e3fc846ef --- /dev/null +++ b/vendor/github.com/coreos/etcd/pkg/monotime/nanotime.go @@ -0,0 +1,24 @@ +// Copyright (C) 2016 Arista Networks, Inc. +// Use of this source code is governed by the Apache License 2.0 +// that can be found in the COPYING file. + +// Package monotime provides a fast monotonic clock source. +package monotime + +import ( + _ "unsafe" // required to use //go:linkname +) + +//go:noescape +//go:linkname nanotime runtime.nanotime +func nanotime() int64 + +// Now returns the current time in nanoseconds from a monotonic clock. +// The time returned is based on some arbitrary platform-specific point in the +// past. The time returned is guaranteed to increase monotonically at a +// constant rate, unlike time.Now() from the Go standard library, which may +// slow down, speed up, jump forward or backward, due to NTP activity or leap +// seconds. +func Now() Time { + return Time(nanotime()) +} diff --git a/vendor/github.com/coreos/etcd/pkg/netutil/isolate_linux.go b/vendor/github.com/coreos/etcd/pkg/netutil/isolate_linux.go index c866cea8e..418580ac4 100644 --- a/vendor/github.com/coreos/etcd/pkg/netutil/isolate_linux.go +++ b/vendor/github.com/coreos/etcd/pkg/netutil/isolate_linux.go @@ -43,17 +43,24 @@ func RecoverPort(port int) error { // SetLatency adds latency in millisecond scale with random variations. func SetLatency(ms, rv int) error { + ifces, err := GetDefaultInterfaces() + if err != nil { + return err + } + if rv > ms { rv = 1 } - cmdStr := fmt.Sprintf("sudo tc qdisc add dev eth0 root netem delay %dms %dms distribution normal", ms, rv) - _, err := exec.Command("/bin/sh", "-c", cmdStr).Output() - if err != nil { - // the rule has already been added. Overwrite it. - cmdStr = fmt.Sprintf("sudo tc qdisc change dev eth0 root netem delay %dms %dms distribution normal", ms, rv) + for ifce := range ifces { + cmdStr := fmt.Sprintf("sudo tc qdisc add dev %s root netem delay %dms %dms distribution normal", ifce, ms, rv) _, err = exec.Command("/bin/sh", "-c", cmdStr).Output() if err != nil { - return err + // the rule has already been added. Overwrite it. + cmdStr = fmt.Sprintf("sudo tc qdisc change dev %s root netem delay %dms %dms distribution normal", ifce, ms, rv) + _, err = exec.Command("/bin/sh", "-c", cmdStr).Output() + if err != nil { + return err + } } } return nil @@ -61,6 +68,15 @@ func SetLatency(ms, rv int) error { // RemoveLatency resets latency configurations. func RemoveLatency() error { - _, err := exec.Command("/bin/sh", "-c", "sudo tc qdisc del dev eth0 root netem").Output() - return err + ifces, err := GetDefaultInterfaces() + if err != nil { + return err + } + for ifce := range ifces { + _, err = exec.Command("/bin/sh", "-c", fmt.Sprintf("sudo tc qdisc del dev %s root netem", ifce)).Output() + if err != nil { + return err + } + } + return nil } diff --git a/vendor/github.com/coreos/etcd/pkg/netutil/netutil.go b/vendor/github.com/coreos/etcd/pkg/netutil/netutil.go index b13ebcc93..bb5f392b3 100644 --- a/vendor/github.com/coreos/etcd/pkg/netutil/netutil.go +++ b/vendor/github.com/coreos/etcd/pkg/netutil/netutil.go @@ -20,22 +20,27 @@ import ( "net/url" "reflect" "sort" + "time" + + "golang.org/x/net/context" "github.com/coreos/etcd/pkg/types" "github.com/coreos/pkg/capnslog" ) var ( - plog = capnslog.NewPackageLogger("github.com/coreos/etcd/pkg", "netutil") + plog = capnslog.NewPackageLogger("github.com/coreos/etcd", "pkg/netutil") // indirection for testing resolveTCPAddr = net.ResolveTCPAddr ) +const retryInterval = time.Second + // resolveTCPAddrs is a convenience wrapper for net.ResolveTCPAddr. // resolveTCPAddrs return a new set of url.URLs, in which all DNS hostnames // are resolved. -func resolveTCPAddrs(urls [][]url.URL) ([][]url.URL, error) { +func resolveTCPAddrs(ctx context.Context, urls [][]url.URL) ([][]url.URL, error) { newurls := make([][]url.URL, 0) for _, us := range urls { nus := make([]url.URL, len(us)) @@ -47,37 +52,52 @@ func resolveTCPAddrs(urls [][]url.URL) ([][]url.URL, error) { nus[i] = *nu } for i, u := range nus { - host, _, err := net.SplitHostPort(u.Host) + h, err := resolveURL(ctx, u) if err != nil { - plog.Errorf("could not parse url %s during tcp resolving", u.Host) return nil, err } - if host == "localhost" { - continue + if h != "" { + nus[i].Host = h } - if net.ParseIP(host) != nil { - continue - } - tcpAddr, err := resolveTCPAddr("tcp", u.Host) - if err != nil { - plog.Errorf("could not resolve host %s", u.Host) - return nil, err - } - plog.Infof("resolving %s to %s", u.Host, tcpAddr.String()) - nus[i].Host = tcpAddr.String() } newurls = append(newurls, nus) } return newurls, nil } +func resolveURL(ctx context.Context, u url.URL) (string, error) { + for ctx.Err() == nil { + host, _, err := net.SplitHostPort(u.Host) + if err != nil { + plog.Errorf("could not parse url %s during tcp resolving", u.Host) + return "", err + } + if host == "localhost" || net.ParseIP(host) != nil { + return "", nil + } + tcpAddr, err := resolveTCPAddr("tcp", u.Host) + if err == nil { + plog.Infof("resolving %s to %s", u.Host, tcpAddr.String()) + return tcpAddr.String(), nil + } + plog.Warningf("failed resolving host %s (%v); retrying in %v", u.Host, err, retryInterval) + select { + case <-ctx.Done(): + plog.Errorf("could not resolve host %s", u.Host) + return "", err + case <-time.After(retryInterval): + } + } + return "", ctx.Err() +} + // urlsEqual checks equality of url.URLS between two arrays. // This check pass even if an URL is in hostname and opposite is in IP address. -func urlsEqual(a []url.URL, b []url.URL) bool { +func urlsEqual(ctx context.Context, a []url.URL, b []url.URL) bool { if len(a) != len(b) { return false } - urls, err := resolveTCPAddrs([][]url.URL{a, b}) + urls, err := resolveTCPAddrs(ctx, [][]url.URL{a, b}) if err != nil { return false } @@ -93,7 +113,7 @@ func urlsEqual(a []url.URL, b []url.URL) bool { return true } -func URLStringsEqual(a []string, b []string) bool { +func URLStringsEqual(ctx context.Context, a []string, b []string) bool { if len(a) != len(b) { return false } @@ -114,7 +134,7 @@ func URLStringsEqual(a []string, b []string) bool { urlsB = append(urlsB, *u) } - return urlsEqual(urlsA, urlsB) + return urlsEqual(ctx, urlsA, urlsB) } func IsNetworkTimeoutError(err error) bool { diff --git a/vendor/github.com/coreos/etcd/pkg/netutil/routes.go b/vendor/github.com/coreos/etcd/pkg/netutil/routes.go new file mode 100644 index 000000000..3eb6a19ec --- /dev/null +++ b/vendor/github.com/coreos/etcd/pkg/netutil/routes.go @@ -0,0 +1,33 @@ +// Copyright 2016 The etcd Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// +build !linux + +package netutil + +import ( + "fmt" + "runtime" +) + +// GetDefaultHost fetches the a resolvable name that corresponds +// to the machine's default routable interface +func GetDefaultHost() (string, error) { + return "", fmt.Errorf("default host not supported on %s_%s", runtime.GOOS, runtime.GOARCH) +} + +// GetDefaultInterfaces fetches the device name of default routable interface. +func GetDefaultInterfaces() (map[string]uint8, error) { + return nil, fmt.Errorf("default host not supported on %s_%s", runtime.GOOS, runtime.GOARCH) +} diff --git a/vendor/github.com/coreos/etcd/pkg/netutil/routes_linux.go b/vendor/github.com/coreos/etcd/pkg/netutil/routes_linux.go new file mode 100644 index 000000000..5d234d460 --- /dev/null +++ b/vendor/github.com/coreos/etcd/pkg/netutil/routes_linux.go @@ -0,0 +1,250 @@ +// Copyright 2016 The etcd Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// +build linux + +package netutil + +import ( + "bytes" + "encoding/binary" + "fmt" + "net" + "sort" + "syscall" + + "github.com/coreos/etcd/pkg/cpuutil" +) + +var errNoDefaultRoute = fmt.Errorf("could not find default route") +var errNoDefaultHost = fmt.Errorf("could not find default host") +var errNoDefaultInterface = fmt.Errorf("could not find default interface") + +// GetDefaultHost obtains the first IP address of machine from the routing table and returns the IP address as string. +// An IPv4 address is preferred to an IPv6 address for backward compatibility. +func GetDefaultHost() (string, error) { + rmsgs, rerr := getDefaultRoutes() + if rerr != nil { + return "", rerr + } + + // prioritize IPv4 + if rmsg, ok := rmsgs[syscall.AF_INET]; ok { + if host, err := chooseHost(syscall.AF_INET, rmsg); host != "" || err != nil { + return host, err + } + delete(rmsgs, syscall.AF_INET) + } + + // sort so choice is deterministic + var families []int + for family := range rmsgs { + families = append(families, int(family)) + } + sort.Ints(families) + + for _, f := range families { + family := uint8(f) + if host, err := chooseHost(family, rmsgs[family]); host != "" || err != nil { + return host, err + } + } + + return "", errNoDefaultHost +} + +func chooseHost(family uint8, rmsg *syscall.NetlinkMessage) (string, error) { + host, oif, err := parsePREFSRC(rmsg) + if host != "" || err != nil { + return host, err + } + + // prefsrc not detected, fall back to getting address from iface + ifmsg, ierr := getIfaceAddr(oif, family) + if ierr != nil { + return "", ierr + } + + attrs, aerr := syscall.ParseNetlinkRouteAttr(ifmsg) + if aerr != nil { + return "", aerr + } + + for _, attr := range attrs { + // search for RTA_DST because ipv6 doesn't have RTA_SRC + if attr.Attr.Type == syscall.RTA_DST { + return net.IP(attr.Value).String(), nil + } + } + + return "", nil +} + +func getDefaultRoutes() (map[uint8]*syscall.NetlinkMessage, error) { + dat, err := syscall.NetlinkRIB(syscall.RTM_GETROUTE, syscall.AF_UNSPEC) + if err != nil { + return nil, err + } + + msgs, msgErr := syscall.ParseNetlinkMessage(dat) + if msgErr != nil { + return nil, msgErr + } + + routes := make(map[uint8]*syscall.NetlinkMessage) + rtmsg := syscall.RtMsg{} + for _, m := range msgs { + if m.Header.Type != syscall.RTM_NEWROUTE { + continue + } + buf := bytes.NewBuffer(m.Data[:syscall.SizeofRtMsg]) + if rerr := binary.Read(buf, cpuutil.ByteOrder(), &rtmsg); rerr != nil { + continue + } + if rtmsg.Dst_len == 0 && rtmsg.Table == syscall.RT_TABLE_MAIN { + // zero-length Dst_len implies default route + msg := m + routes[rtmsg.Family] = &msg + } + } + + if len(routes) > 0 { + return routes, nil + } + + return nil, errNoDefaultRoute +} + +// Used to get an address of interface. +func getIfaceAddr(idx uint32, family uint8) (*syscall.NetlinkMessage, error) { + dat, err := syscall.NetlinkRIB(syscall.RTM_GETADDR, int(family)) + if err != nil { + return nil, err + } + + msgs, msgErr := syscall.ParseNetlinkMessage(dat) + if msgErr != nil { + return nil, msgErr + } + + ifaddrmsg := syscall.IfAddrmsg{} + for _, m := range msgs { + if m.Header.Type != syscall.RTM_NEWADDR { + continue + } + buf := bytes.NewBuffer(m.Data[:syscall.SizeofIfAddrmsg]) + if rerr := binary.Read(buf, cpuutil.ByteOrder(), &ifaddrmsg); rerr != nil { + continue + } + if ifaddrmsg.Index == idx { + return &m, nil + } + } + + return nil, fmt.Errorf("could not find address for interface index %v", idx) + +} + +// Used to get a name of interface. +func getIfaceLink(idx uint32) (*syscall.NetlinkMessage, error) { + dat, err := syscall.NetlinkRIB(syscall.RTM_GETLINK, syscall.AF_UNSPEC) + if err != nil { + return nil, err + } + + msgs, msgErr := syscall.ParseNetlinkMessage(dat) + if msgErr != nil { + return nil, msgErr + } + + ifinfomsg := syscall.IfInfomsg{} + for _, m := range msgs { + if m.Header.Type != syscall.RTM_NEWLINK { + continue + } + buf := bytes.NewBuffer(m.Data[:syscall.SizeofIfInfomsg]) + if rerr := binary.Read(buf, cpuutil.ByteOrder(), &ifinfomsg); rerr != nil { + continue + } + if ifinfomsg.Index == int32(idx) { + return &m, nil + } + } + + return nil, fmt.Errorf("could not find link for interface index %v", idx) +} + +// GetDefaultInterfaces gets names of interfaces and returns a map[interface]families. +func GetDefaultInterfaces() (map[string]uint8, error) { + interfaces := make(map[string]uint8) + rmsgs, rerr := getDefaultRoutes() + if rerr != nil { + return interfaces, rerr + } + + for family, rmsg := range rmsgs { + _, oif, err := parsePREFSRC(rmsg) + if err != nil { + return interfaces, err + } + + ifmsg, ierr := getIfaceLink(oif) + if ierr != nil { + return interfaces, ierr + } + + attrs, aerr := syscall.ParseNetlinkRouteAttr(ifmsg) + if aerr != nil { + return interfaces, aerr + } + + for _, attr := range attrs { + if attr.Attr.Type == syscall.IFLA_IFNAME { + // key is an interface name + // possible values: 2 - AF_INET, 10 - AF_INET6, 12 - dualstack + interfaces[string(attr.Value[:len(attr.Value)-1])] += family + } + } + } + if len(interfaces) > 0 { + return interfaces, nil + } + return interfaces, errNoDefaultInterface +} + +// parsePREFSRC returns preferred source address and output interface index (RTA_OIF). +func parsePREFSRC(m *syscall.NetlinkMessage) (host string, oif uint32, err error) { + var attrs []syscall.NetlinkRouteAttr + attrs, err = syscall.ParseNetlinkRouteAttr(m) + if err != nil { + return "", 0, err + } + + for _, attr := range attrs { + if attr.Attr.Type == syscall.RTA_PREFSRC { + host = net.IP(attr.Value).String() + } + if attr.Attr.Type == syscall.RTA_OIF { + oif = cpuutil.ByteOrder().Uint32(attr.Value) + } + if host != "" && oif != uint32(0) { + break + } + } + + if oif == 0 { + err = errNoDefaultRoute + } + return +} diff --git a/vendor/github.com/coreos/etcd/pkg/pbutil/pbutil.go b/vendor/github.com/coreos/etcd/pkg/pbutil/pbutil.go index 8f96b4d54..d70f98dd8 100644 --- a/vendor/github.com/coreos/etcd/pkg/pbutil/pbutil.go +++ b/vendor/github.com/coreos/etcd/pkg/pbutil/pbutil.go @@ -18,7 +18,7 @@ package pbutil import "github.com/coreos/pkg/capnslog" var ( - plog = capnslog.NewPackageLogger("github.com/coreos/etcd/pkg", "flags") + plog = capnslog.NewPackageLogger("github.com/coreos/etcd", "pkg/pbutil") ) type Marshaler interface { diff --git a/vendor/github.com/coreos/etcd/pkg/testutil/leak.go b/vendor/github.com/coreos/etcd/pkg/testutil/leak.go index 0f2ee559f..80bc0eebc 100644 --- a/vendor/github.com/coreos/etcd/pkg/testutil/leak.go +++ b/vendor/github.com/coreos/etcd/pkg/testutil/leak.go @@ -106,6 +106,8 @@ func interestingGoroutines() (gs []string) { } stack := strings.TrimSpace(sl[1]) if stack == "" || + strings.Contains(stack, "created by os/signal.init") || + strings.Contains(stack, "runtime/panic.go") || strings.Contains(stack, "created by testing.RunTests") || strings.Contains(stack, "testing.Main(") || strings.Contains(stack, "runtime.goexit") || diff --git a/vendor/github.com/coreos/etcd/pkg/testutil/testutil.go b/vendor/github.com/coreos/etcd/pkg/testutil/testutil.go index a67eded1e..db2dd3285 100644 --- a/vendor/github.com/coreos/etcd/pkg/testutil/testutil.go +++ b/vendor/github.com/coreos/etcd/pkg/testutil/testutil.go @@ -50,7 +50,7 @@ func MustNewURL(t *testing.T, s string) *url.URL { // FatalStack helps to fatal the test and print out the stacks of all running goroutines. func FatalStack(t *testing.T, s string) { - stackTrace := make([]byte, 8*1024) + stackTrace := make([]byte, 1024*1024) n := runtime.Stack(stackTrace, true) t.Error(string(stackTrace[:n])) t.Fatalf(s) diff --git a/vendor/github.com/coreos/etcd/pkg/transport/listener.go b/vendor/github.com/coreos/etcd/pkg/transport/listener.go index 46fe12009..83f9aa48a 100644 --- a/vendor/github.com/coreos/etcd/pkg/transport/listener.go +++ b/vendor/github.com/coreos/etcd/pkg/transport/listener.go @@ -23,10 +23,11 @@ import ( "crypto/x509/pkix" "encoding/pem" "fmt" + "log" "math/big" "net" "os" - "path" + "path/filepath" "strings" "time" @@ -34,27 +35,30 @@ import ( "github.com/coreos/etcd/pkg/tlsutil" ) -func NewListener(addr string, scheme string, tlscfg *tls.Config) (l net.Listener, err error) { - if scheme == "unix" || scheme == "unixs" { - // unix sockets via unix://laddr - l, err = NewUnixListener(addr) - } else { - l, err = net.Listen("tcp", addr) - } - - if err != nil { +func NewListener(addr, scheme string, tlscfg *tls.Config) (l net.Listener, err error) { + if l, err = newListener(addr, scheme); err != nil { return nil, err } + return wrapTLS(addr, scheme, tlscfg, l) +} - if scheme == "https" || scheme == "unixs" { - if tlscfg == nil { - return nil, fmt.Errorf("cannot listen on TLS for %s: KeyFile and CertFile are not presented", scheme+"://"+addr) - } - - l = tls.NewListener(l, tlscfg) +func newListener(addr string, scheme string) (net.Listener, error) { + if scheme == "unix" || scheme == "unixs" { + // unix sockets via unix://laddr + return NewUnixListener(addr) } + return net.Listen("tcp", addr) +} - return l, nil +func wrapTLS(addr, scheme string, tlscfg *tls.Config, l net.Listener) (net.Listener, error) { + if scheme != "https" && scheme != "unixs" { + return l, nil + } + if tlscfg == nil { + l.Close() + return nil, fmt.Errorf("cannot listen on TLS for %s: KeyFile and CertFile are not presented", scheme+"://"+addr) + } + return tls.NewListener(l, tlscfg), nil } type TLSInfo struct { @@ -87,8 +91,8 @@ func SelfCert(dirpath string, hosts []string) (info TLSInfo, err error) { return } - certPath := path.Join(dirpath, "cert.pem") - keyPath := path.Join(dirpath, "key.pem") + certPath := filepath.Join(dirpath, "cert.pem") + keyPath := filepath.Join(dirpath, "key.pem") _, errcert := os.Stat(certPath) _, errkey := os.Stat(keyPath) if errcert == nil && errkey == nil { @@ -205,6 +209,9 @@ func (info TLSInfo) ServerConfig() (*tls.Config, error) { cfg.ClientCAs = cp } + // "h2" NextProtos is necessary for enabling HTTP2 for go's HTTP server + cfg.NextProtos = []string{"h2"} + return cfg, nil } @@ -229,6 +236,7 @@ func (info TLSInfo) ClientConfig() (*tls.Config, error) { return nil, err } // if given a CA, trust any host with a cert signed by the CA + log.Println("warning: ignoring ServerName for user-provided CA for backwards compatibility is deprecated") cfg.ServerName = "" } diff --git a/vendor/github.com/coreos/etcd/pkg/transport/timeout_listener.go b/vendor/github.com/coreos/etcd/pkg/transport/timeout_listener.go index f176c43b9..0f4df5fbe 100644 --- a/vendor/github.com/coreos/etcd/pkg/transport/timeout_listener.go +++ b/vendor/github.com/coreos/etcd/pkg/transport/timeout_listener.go @@ -24,15 +24,19 @@ import ( // If read/write on the accepted connection blocks longer than its time limit, // it will return timeout error. func NewTimeoutListener(addr string, scheme string, tlscfg *tls.Config, rdtimeoutd, wtimeoutd time.Duration) (net.Listener, error) { - ln, err := NewListener(addr, scheme, tlscfg) + ln, err := newListener(addr, scheme) if err != nil { return nil, err } - return &rwTimeoutListener{ + ln = &rwTimeoutListener{ Listener: ln, rdtimeoutd: rdtimeoutd, wtimeoutd: wtimeoutd, - }, nil + } + if ln, err = wrapTLS(addr, scheme, tlscfg, ln); err != nil { + return nil, err + } + return ln, nil } type rwTimeoutListener struct { diff --git a/vendor/github.com/coreos/etcd/pkg/transport/timeout_transport.go b/vendor/github.com/coreos/etcd/pkg/transport/timeout_transport.go index 742cc5cbf..ea16b4c0f 100644 --- a/vendor/github.com/coreos/etcd/pkg/transport/timeout_transport.go +++ b/vendor/github.com/coreos/etcd/pkg/transport/timeout_transport.go @@ -35,7 +35,7 @@ func NewTimeoutTransport(info TLSInfo, dialtimeoutd, rdtimeoutd, wtimeoutd time. // it should not be put back to http transport as an idle connection for future usage. tr.MaxIdleConnsPerHost = -1 } else { - // allow more idle connections between peers to avoid unncessary port allocation. + // allow more idle connections between peers to avoid unnecessary port allocation. tr.MaxIdleConnsPerHost = 1024 } diff --git a/vendor/github.com/coreos/etcd/pkg/transport/transport.go b/vendor/github.com/coreos/etcd/pkg/transport/transport.go index ca9ccfd80..4a7fe69d2 100644 --- a/vendor/github.com/coreos/etcd/pkg/transport/transport.go +++ b/vendor/github.com/coreos/etcd/pkg/transport/transport.go @@ -64,7 +64,8 @@ func NewTransport(info TLSInfo, dialtimeoutd time.Duration) (*http.Transport, er } func (urt *unixTransport) RoundTrip(req *http.Request) (*http.Response, error) { - req2 := *req - req2.URL.Scheme = strings.Replace(req.URL.Scheme, "unix", "http", 1) + url := *req.URL + req.URL = &url + req.URL.Scheme = strings.Replace(req.URL.Scheme, "unix", "http", 1) return urt.Transport.RoundTrip(req) } diff --git a/vendor/github.com/coreos/etcd/pkg/wait/wait.go b/vendor/github.com/coreos/etcd/pkg/wait/wait.go index a341c0270..0f31eeb97 100644 --- a/vendor/github.com/coreos/etcd/pkg/wait/wait.go +++ b/vendor/github.com/coreos/etcd/pkg/wait/wait.go @@ -24,6 +24,7 @@ import ( type Wait interface { Register(id uint64) <-chan interface{} Trigger(id uint64, x interface{}) + IsRegistered(id uint64) bool } type List struct { @@ -59,6 +60,13 @@ func (w *List) Trigger(id uint64, x interface{}) { } } +func (w *List) IsRegistered(id uint64) bool { + w.l.Lock() + defer w.l.Unlock() + _, ok := w.m[id] + return ok +} + type waitWithResponse struct { ch <-chan interface{} } @@ -71,3 +79,6 @@ func (w *waitWithResponse) Register(id uint64) <-chan interface{} { return w.ch } func (w *waitWithResponse) Trigger(id uint64, x interface{}) {} +func (w *waitWithResponse) IsRegistered(id uint64) bool { + panic("waitWithResponse.IsRegistered() shouldn't be called") +} diff --git a/vendor/github.com/coreos/etcd/pkg/wait/wait_time.go b/vendor/github.com/coreos/etcd/pkg/wait/wait_time.go index 0357d81f3..297e48a47 100644 --- a/vendor/github.com/coreos/etcd/pkg/wait/wait_time.go +++ b/vendor/github.com/coreos/etcd/pkg/wait/wait_time.go @@ -14,45 +14,51 @@ package wait -import ( - "sync" - "time" -) +import "sync" type WaitTime interface { - // Wait returns a chan that waits on the given deadline. + // Wait returns a chan that waits on the given logical deadline. // The chan will be triggered when Trigger is called with a // deadline that is later than the one it is waiting for. - // The given deadline MUST be unique. The deadline should be - // retrieved by calling time.Now() in most cases. - Wait(deadline time.Time) <-chan struct{} - // Trigger triggers all the waiting chans with an earlier deadline. - Trigger(deadline time.Time) + Wait(deadline uint64) <-chan struct{} + // Trigger triggers all the waiting chans with an earlier logical deadline. + Trigger(deadline uint64) } +var closec chan struct{} + +func init() { closec = make(chan struct{}); close(closec) } + type timeList struct { - l sync.Mutex - m map[int64]chan struct{} + l sync.Mutex + lastTriggerDeadline uint64 + m map[uint64]chan struct{} } func NewTimeList() *timeList { - return &timeList{m: make(map[int64]chan struct{})} + return &timeList{m: make(map[uint64]chan struct{})} } -func (tl *timeList) Wait(deadline time.Time) <-chan struct{} { +func (tl *timeList) Wait(deadline uint64) <-chan struct{} { tl.l.Lock() defer tl.l.Unlock() - ch := make(chan struct{}, 1) - // The given deadline SHOULD be unique. - tl.m[deadline.UnixNano()] = ch + if tl.lastTriggerDeadline >= deadline { + return closec + } + ch := tl.m[deadline] + if ch == nil { + ch = make(chan struct{}) + tl.m[deadline] = ch + } return ch } -func (tl *timeList) Trigger(deadline time.Time) { +func (tl *timeList) Trigger(deadline uint64) { tl.l.Lock() defer tl.l.Unlock() + tl.lastTriggerDeadline = deadline for t, ch := range tl.m { - if t < deadline.UnixNano() { + if t <= deadline { delete(tl.m, t) close(ch) } diff --git a/vendor/github.com/coreos/etcd/proxy/grpcproxy/auth.go b/vendor/github.com/coreos/etcd/proxy/grpcproxy/auth.go new file mode 100644 index 000000000..c1b75e36d --- /dev/null +++ b/vendor/github.com/coreos/etcd/proxy/grpcproxy/auth.go @@ -0,0 +1,110 @@ +// Copyright 2016 The etcd Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package grpcproxy + +import ( + "golang.org/x/net/context" + + "github.com/coreos/etcd/clientv3" + pb "github.com/coreos/etcd/etcdserver/etcdserverpb" +) + +type AuthProxy struct { + client *clientv3.Client +} + +func NewAuthProxy(c *clientv3.Client) pb.AuthServer { + return &AuthProxy{client: c} +} + +func (ap *AuthProxy) AuthEnable(ctx context.Context, r *pb.AuthEnableRequest) (*pb.AuthEnableResponse, error) { + conn := ap.client.ActiveConnection() + return pb.NewAuthClient(conn).AuthEnable(ctx, r) +} + +func (ap *AuthProxy) AuthDisable(ctx context.Context, r *pb.AuthDisableRequest) (*pb.AuthDisableResponse, error) { + conn := ap.client.ActiveConnection() + return pb.NewAuthClient(conn).AuthDisable(ctx, r) +} + +func (ap *AuthProxy) Authenticate(ctx context.Context, r *pb.AuthenticateRequest) (*pb.AuthenticateResponse, error) { + conn := ap.client.ActiveConnection() + return pb.NewAuthClient(conn).Authenticate(ctx, r) +} + +func (ap *AuthProxy) RoleAdd(ctx context.Context, r *pb.AuthRoleAddRequest) (*pb.AuthRoleAddResponse, error) { + conn := ap.client.ActiveConnection() + return pb.NewAuthClient(conn).RoleAdd(ctx, r) +} + +func (ap *AuthProxy) RoleDelete(ctx context.Context, r *pb.AuthRoleDeleteRequest) (*pb.AuthRoleDeleteResponse, error) { + conn := ap.client.ActiveConnection() + return pb.NewAuthClient(conn).RoleDelete(ctx, r) +} + +func (ap *AuthProxy) RoleGet(ctx context.Context, r *pb.AuthRoleGetRequest) (*pb.AuthRoleGetResponse, error) { + conn := ap.client.ActiveConnection() + return pb.NewAuthClient(conn).RoleGet(ctx, r) +} + +func (ap *AuthProxy) RoleList(ctx context.Context, r *pb.AuthRoleListRequest) (*pb.AuthRoleListResponse, error) { + conn := ap.client.ActiveConnection() + return pb.NewAuthClient(conn).RoleList(ctx, r) +} + +func (ap *AuthProxy) RoleRevokePermission(ctx context.Context, r *pb.AuthRoleRevokePermissionRequest) (*pb.AuthRoleRevokePermissionResponse, error) { + conn := ap.client.ActiveConnection() + return pb.NewAuthClient(conn).RoleRevokePermission(ctx, r) +} + +func (ap *AuthProxy) RoleGrantPermission(ctx context.Context, r *pb.AuthRoleGrantPermissionRequest) (*pb.AuthRoleGrantPermissionResponse, error) { + conn := ap.client.ActiveConnection() + return pb.NewAuthClient(conn).RoleGrantPermission(ctx, r) +} + +func (ap *AuthProxy) UserAdd(ctx context.Context, r *pb.AuthUserAddRequest) (*pb.AuthUserAddResponse, error) { + conn := ap.client.ActiveConnection() + return pb.NewAuthClient(conn).UserAdd(ctx, r) +} + +func (ap *AuthProxy) UserDelete(ctx context.Context, r *pb.AuthUserDeleteRequest) (*pb.AuthUserDeleteResponse, error) { + conn := ap.client.ActiveConnection() + return pb.NewAuthClient(conn).UserDelete(ctx, r) +} + +func (ap *AuthProxy) UserGet(ctx context.Context, r *pb.AuthUserGetRequest) (*pb.AuthUserGetResponse, error) { + conn := ap.client.ActiveConnection() + return pb.NewAuthClient(conn).UserGet(ctx, r) +} + +func (ap *AuthProxy) UserList(ctx context.Context, r *pb.AuthUserListRequest) (*pb.AuthUserListResponse, error) { + conn := ap.client.ActiveConnection() + return pb.NewAuthClient(conn).UserList(ctx, r) +} + +func (ap *AuthProxy) UserGrantRole(ctx context.Context, r *pb.AuthUserGrantRoleRequest) (*pb.AuthUserGrantRoleResponse, error) { + conn := ap.client.ActiveConnection() + return pb.NewAuthClient(conn).UserGrantRole(ctx, r) +} + +func (ap *AuthProxy) UserRevokeRole(ctx context.Context, r *pb.AuthUserRevokeRoleRequest) (*pb.AuthUserRevokeRoleResponse, error) { + conn := ap.client.ActiveConnection() + return pb.NewAuthClient(conn).UserRevokeRole(ctx, r) +} + +func (ap *AuthProxy) UserChangePassword(ctx context.Context, r *pb.AuthUserChangePasswordRequest) (*pb.AuthUserChangePasswordResponse, error) { + conn := ap.client.ActiveConnection() + return pb.NewAuthClient(conn).UserChangePassword(ctx, r) +} diff --git a/vendor/github.com/coreos/etcd/proxy/grpcproxy/cache/store.go b/vendor/github.com/coreos/etcd/proxy/grpcproxy/cache/store.go new file mode 100644 index 000000000..155bbf900 --- /dev/null +++ b/vendor/github.com/coreos/etcd/proxy/grpcproxy/cache/store.go @@ -0,0 +1,168 @@ +// Copyright 2016 The etcd Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package cache + +import ( + "errors" + "sync" + "time" + + "github.com/karlseguin/ccache" + + "github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes" + pb "github.com/coreos/etcd/etcdserver/etcdserverpb" + "github.com/coreos/etcd/pkg/adt" +) + +var ( + DefaultMaxEntries = 2048 + ErrCompacted = rpctypes.ErrGRPCCompacted +) + +const defaultHistoricTTL = time.Hour +const defaultCurrentTTL = time.Minute + +type Cache interface { + Add(req *pb.RangeRequest, resp *pb.RangeResponse) + Get(req *pb.RangeRequest) (*pb.RangeResponse, error) + Compact(revision int64) + Invalidate(key []byte, endkey []byte) + Close() +} + +// keyFunc returns the key of an request, which is used to look up in the cache for it's caching response. +func keyFunc(req *pb.RangeRequest) string { + // TODO: use marshalTo to reduce allocation + b, err := req.Marshal() + if err != nil { + panic(err) + } + return string(b) +} + +func NewCache(maxCacheEntries int) Cache { + return &cache{ + lru: ccache.New(ccache.Configure().MaxSize(int64(maxCacheEntries))), + compactedRev: -1, + } +} + +func (c *cache) Close() { c.lru.Stop() } + +// cache implements Cache +type cache struct { + mu sync.RWMutex + lru *ccache.Cache + + // a reverse index for cache invalidation + cachedRanges adt.IntervalTree + + compactedRev int64 +} + +// Add adds the response of a request to the cache if its revision is larger than the compacted revision of the cache. +func (c *cache) Add(req *pb.RangeRequest, resp *pb.RangeResponse) { + key := keyFunc(req) + + c.mu.Lock() + defer c.mu.Unlock() + + if req.Revision > c.compactedRev { + if req.Revision == 0 { + c.lru.Set(key, resp, defaultCurrentTTL) + } else { + c.lru.Set(key, resp, defaultHistoricTTL) + } + } + // we do not need to invalidate a request with a revision specified. + // so we do not need to add it into the reverse index. + if req.Revision != 0 { + return + } + + var ( + iv *adt.IntervalValue + ivl adt.Interval + ) + if len(req.RangeEnd) != 0 { + ivl = adt.NewStringAffineInterval(string(req.Key), string(req.RangeEnd)) + } else { + ivl = adt.NewStringAffinePoint(string(req.Key)) + } + + iv = c.cachedRanges.Find(ivl) + + if iv == nil { + c.cachedRanges.Insert(ivl, []string{key}) + } else { + iv.Val = append(iv.Val.([]string), key) + } +} + +// Get looks up the caching response for a given request. +// Get is also responsible for lazy eviction when accessing compacted entries. +func (c *cache) Get(req *pb.RangeRequest) (*pb.RangeResponse, error) { + key := keyFunc(req) + + c.mu.RLock() + defer c.mu.RUnlock() + + if req.Revision < c.compactedRev { + c.lru.Delete(key) + return nil, ErrCompacted + } + + if item := c.lru.Get(key); item != nil { + return item.Value().(*pb.RangeResponse), nil + } + return nil, errors.New("not exist") +} + +// Invalidate invalidates the cache entries that intersecting with the given range from key to endkey. +func (c *cache) Invalidate(key, endkey []byte) { + c.mu.Lock() + defer c.mu.Unlock() + + var ( + ivs []*adt.IntervalValue + ivl adt.Interval + ) + if len(endkey) == 0 { + ivl = adt.NewStringAffinePoint(string(key)) + } else { + ivl = adt.NewStringAffineInterval(string(key), string(endkey)) + } + + ivs = c.cachedRanges.Stab(ivl) + for _, iv := range ivs { + keys := iv.Val.([]string) + for _, key := range keys { + c.lru.Delete(key) + } + } + // delete after removing all keys since it is destructive to 'ivs' + c.cachedRanges.Delete(ivl) +} + +// Compact invalidate all caching response before the given rev. +// Replace with the invalidation is lazy. The actual removal happens when the entries is accessed. +func (c *cache) Compact(revision int64) { + c.mu.Lock() + defer c.mu.Unlock() + + if revision > c.compactedRev { + c.compactedRev = revision + } +} diff --git a/vendor/github.com/coreos/etcd/proxy/grpcproxy/cluster.go b/vendor/github.com/coreos/etcd/proxy/grpcproxy/cluster.go new file mode 100644 index 000000000..8a2fa16c1 --- /dev/null +++ b/vendor/github.com/coreos/etcd/proxy/grpcproxy/cluster.go @@ -0,0 +1,52 @@ +// Copyright 2016 The etcd Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package grpcproxy + +import ( + "github.com/coreos/etcd/clientv3" + pb "github.com/coreos/etcd/etcdserver/etcdserverpb" + + "golang.org/x/net/context" +) + +type clusterProxy struct { + client *clientv3.Client +} + +func NewClusterProxy(c *clientv3.Client) pb.ClusterServer { + return &clusterProxy{ + client: c, + } +} + +func (cp *clusterProxy) MemberAdd(ctx context.Context, r *pb.MemberAddRequest) (*pb.MemberAddResponse, error) { + conn := cp.client.ActiveConnection() + return pb.NewClusterClient(conn).MemberAdd(ctx, r) +} + +func (cp *clusterProxy) MemberRemove(ctx context.Context, r *pb.MemberRemoveRequest) (*pb.MemberRemoveResponse, error) { + conn := cp.client.ActiveConnection() + return pb.NewClusterClient(conn).MemberRemove(ctx, r) +} + +func (cp *clusterProxy) MemberUpdate(ctx context.Context, r *pb.MemberUpdateRequest) (*pb.MemberUpdateResponse, error) { + conn := cp.client.ActiveConnection() + return pb.NewClusterClient(conn).MemberUpdate(ctx, r) +} + +func (cp *clusterProxy) MemberList(ctx context.Context, r *pb.MemberListRequest) (*pb.MemberListResponse, error) { + conn := cp.client.ActiveConnection() + return pb.NewClusterClient(conn).MemberList(ctx, r) +} diff --git a/vendor/github.com/coreos/etcd/proxy/grpcproxy/doc.go b/vendor/github.com/coreos/etcd/proxy/grpcproxy/doc.go new file mode 100644 index 000000000..fc022e3c5 --- /dev/null +++ b/vendor/github.com/coreos/etcd/proxy/grpcproxy/doc.go @@ -0,0 +1,16 @@ +// Copyright 2016 The etcd Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package grpcproxy is an OSI level 7 proxy for etcd v3 API requests. +package grpcproxy diff --git a/vendor/github.com/coreos/etcd/proxy/grpcproxy/kv.go b/vendor/github.com/coreos/etcd/proxy/grpcproxy/kv.go new file mode 100644 index 000000000..368851357 --- /dev/null +++ b/vendor/github.com/coreos/etcd/proxy/grpcproxy/kv.go @@ -0,0 +1,210 @@ +// Copyright 2016 The etcd Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package grpcproxy + +import ( + "github.com/coreos/etcd/clientv3" + pb "github.com/coreos/etcd/etcdserver/etcdserverpb" + "github.com/coreos/etcd/proxy/grpcproxy/cache" + + "golang.org/x/net/context" +) + +type kvProxy struct { + kv clientv3.KV + cache cache.Cache +} + +func NewKvProxy(c *clientv3.Client) (pb.KVServer, <-chan struct{}) { + kv := &kvProxy{ + kv: c.KV, + cache: cache.NewCache(cache.DefaultMaxEntries), + } + donec := make(chan struct{}) + go func() { + defer close(donec) + <-c.Ctx().Done() + kv.cache.Close() + }() + return kv, donec +} + +func (p *kvProxy) Range(ctx context.Context, r *pb.RangeRequest) (*pb.RangeResponse, error) { + if r.Serializable { + resp, err := p.cache.Get(r) + switch err { + case nil: + cacheHits.Inc() + return resp, nil + case cache.ErrCompacted: + cacheHits.Inc() + return nil, err + } + } + cachedMisses.Inc() + + resp, err := p.kv.Do(ctx, RangeRequestToOp(r)) + if err != nil { + return nil, err + } + + // cache linearizable as serializable + req := *r + req.Serializable = true + gresp := (*pb.RangeResponse)(resp.Get()) + p.cache.Add(&req, gresp) + + return gresp, nil +} + +func (p *kvProxy) Put(ctx context.Context, r *pb.PutRequest) (*pb.PutResponse, error) { + p.cache.Invalidate(r.Key, nil) + + resp, err := p.kv.Do(ctx, PutRequestToOp(r)) + return (*pb.PutResponse)(resp.Put()), err +} + +func (p *kvProxy) DeleteRange(ctx context.Context, r *pb.DeleteRangeRequest) (*pb.DeleteRangeResponse, error) { + p.cache.Invalidate(r.Key, r.RangeEnd) + + resp, err := p.kv.Do(ctx, DelRequestToOp(r)) + return (*pb.DeleteRangeResponse)(resp.Del()), err +} + +func (p *kvProxy) txnToCache(reqs []*pb.RequestOp, resps []*pb.ResponseOp) { + for i := range resps { + switch tv := resps[i].Response.(type) { + case *pb.ResponseOp_ResponsePut: + p.cache.Invalidate(reqs[i].GetRequestPut().Key, nil) + case *pb.ResponseOp_ResponseDeleteRange: + rdr := reqs[i].GetRequestDeleteRange() + p.cache.Invalidate(rdr.Key, rdr.RangeEnd) + case *pb.ResponseOp_ResponseRange: + req := *(reqs[i].GetRequestRange()) + req.Serializable = true + p.cache.Add(&req, tv.ResponseRange) + } + } +} + +func (p *kvProxy) Txn(ctx context.Context, r *pb.TxnRequest) (*pb.TxnResponse, error) { + txn := p.kv.Txn(ctx) + cmps := make([]clientv3.Cmp, len(r.Compare)) + thenops := make([]clientv3.Op, len(r.Success)) + elseops := make([]clientv3.Op, len(r.Failure)) + + for i := range r.Compare { + cmps[i] = (clientv3.Cmp)(*r.Compare[i]) + } + + for i := range r.Success { + thenops[i] = requestOpToOp(r.Success[i]) + } + + for i := range r.Failure { + elseops[i] = requestOpToOp(r.Failure[i]) + } + + resp, err := txn.If(cmps...).Then(thenops...).Else(elseops...).Commit() + + if err != nil { + return nil, err + } + // txn may claim an outdated key is updated; be safe and invalidate + for _, cmp := range r.Compare { + p.cache.Invalidate(cmp.Key, nil) + } + // update any fetched keys + if resp.Succeeded { + p.txnToCache(r.Success, resp.Responses) + } else { + p.txnToCache(r.Failure, resp.Responses) + } + + return (*pb.TxnResponse)(resp), nil +} + +func (p *kvProxy) Compact(ctx context.Context, r *pb.CompactionRequest) (*pb.CompactionResponse, error) { + var opts []clientv3.CompactOption + if r.Physical { + opts = append(opts, clientv3.WithCompactPhysical()) + } + + resp, err := p.kv.Compact(ctx, r.Revision, opts...) + if err == nil { + p.cache.Compact(r.Revision) + } + + return (*pb.CompactionResponse)(resp), err +} + +func requestOpToOp(union *pb.RequestOp) clientv3.Op { + switch tv := union.Request.(type) { + case *pb.RequestOp_RequestRange: + if tv.RequestRange != nil { + return RangeRequestToOp(tv.RequestRange) + } + case *pb.RequestOp_RequestPut: + if tv.RequestPut != nil { + return PutRequestToOp(tv.RequestPut) + } + case *pb.RequestOp_RequestDeleteRange: + if tv.RequestDeleteRange != nil { + return DelRequestToOp(tv.RequestDeleteRange) + } + } + panic("unknown request") +} + +func RangeRequestToOp(r *pb.RangeRequest) clientv3.Op { + opts := []clientv3.OpOption{} + if len(r.RangeEnd) != 0 { + opts = append(opts, clientv3.WithRange(string(r.RangeEnd))) + } + opts = append(opts, clientv3.WithRev(r.Revision)) + opts = append(opts, clientv3.WithLimit(r.Limit)) + opts = append(opts, clientv3.WithSort( + clientv3.SortTarget(r.SortTarget), + clientv3.SortOrder(r.SortOrder)), + ) + opts = append(opts, clientv3.WithMaxCreateRev(r.MaxCreateRevision)) + opts = append(opts, clientv3.WithMinCreateRev(r.MinCreateRevision)) + opts = append(opts, clientv3.WithMaxModRev(r.MaxModRevision)) + opts = append(opts, clientv3.WithMinModRev(r.MinModRevision)) + + if r.Serializable { + opts = append(opts, clientv3.WithSerializable()) + } + + return clientv3.OpGet(string(r.Key), opts...) +} + +func PutRequestToOp(r *pb.PutRequest) clientv3.Op { + opts := []clientv3.OpOption{} + opts = append(opts, clientv3.WithLease(clientv3.LeaseID(r.Lease))) + + return clientv3.OpPut(string(r.Key), string(r.Value), opts...) +} + +func DelRequestToOp(r *pb.DeleteRangeRequest) clientv3.Op { + opts := []clientv3.OpOption{} + if len(r.RangeEnd) != 0 { + opts = append(opts, clientv3.WithRange(string(r.RangeEnd))) + } + if r.PrevKv { + opts = append(opts, clientv3.WithPrevKV()) + } + return clientv3.OpDelete(string(r.Key), opts...) +} diff --git a/vendor/github.com/coreos/etcd/proxy/grpcproxy/kv_client_adapter.go b/vendor/github.com/coreos/etcd/proxy/grpcproxy/kv_client_adapter.go new file mode 100644 index 000000000..7880b1810 --- /dev/null +++ b/vendor/github.com/coreos/etcd/proxy/grpcproxy/kv_client_adapter.go @@ -0,0 +1,47 @@ +// Copyright 2016 The etcd Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package grpcproxy + +import ( + pb "github.com/coreos/etcd/etcdserver/etcdserverpb" + "golang.org/x/net/context" + grpc "google.golang.org/grpc" +) + +type kvs2kvc struct{ kvs pb.KVServer } + +func KvServerToKvClient(kvs pb.KVServer) pb.KVClient { + return &kvs2kvc{kvs} +} + +func (s *kvs2kvc) Range(ctx context.Context, in *pb.RangeRequest, opts ...grpc.CallOption) (*pb.RangeResponse, error) { + return s.kvs.Range(ctx, in) +} + +func (s *kvs2kvc) Put(ctx context.Context, in *pb.PutRequest, opts ...grpc.CallOption) (*pb.PutResponse, error) { + return s.kvs.Put(ctx, in) +} + +func (s *kvs2kvc) DeleteRange(ctx context.Context, in *pb.DeleteRangeRequest, opts ...grpc.CallOption) (*pb.DeleteRangeResponse, error) { + return s.kvs.DeleteRange(ctx, in) +} + +func (s *kvs2kvc) Txn(ctx context.Context, in *pb.TxnRequest, opts ...grpc.CallOption) (*pb.TxnResponse, error) { + return s.kvs.Txn(ctx, in) +} + +func (s *kvs2kvc) Compact(ctx context.Context, in *pb.CompactionRequest, opts ...grpc.CallOption) (*pb.CompactionResponse, error) { + return s.kvs.Compact(ctx, in) +} diff --git a/vendor/github.com/coreos/etcd/proxy/grpcproxy/lease.go b/vendor/github.com/coreos/etcd/proxy/grpcproxy/lease.go new file mode 100644 index 000000000..4f870220b --- /dev/null +++ b/vendor/github.com/coreos/etcd/proxy/grpcproxy/lease.go @@ -0,0 +1,87 @@ +// Copyright 2016 The etcd Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package grpcproxy + +import ( + "golang.org/x/net/context" + + "github.com/coreos/etcd/clientv3" + pb "github.com/coreos/etcd/etcdserver/etcdserverpb" +) + +type leaseProxy struct { + client *clientv3.Client +} + +func NewLeaseProxy(c *clientv3.Client) pb.LeaseServer { + return &leaseProxy{ + client: c, + } +} + +func (lp *leaseProxy) LeaseGrant(ctx context.Context, cr *pb.LeaseGrantRequest) (*pb.LeaseGrantResponse, error) { + conn := lp.client.ActiveConnection() + return pb.NewLeaseClient(conn).LeaseGrant(ctx, cr) +} + +func (lp *leaseProxy) LeaseRevoke(ctx context.Context, rr *pb.LeaseRevokeRequest) (*pb.LeaseRevokeResponse, error) { + conn := lp.client.ActiveConnection() + return pb.NewLeaseClient(conn).LeaseRevoke(ctx, rr) +} + +func (lp *leaseProxy) LeaseTimeToLive(ctx context.Context, rr *pb.LeaseTimeToLiveRequest) (*pb.LeaseTimeToLiveResponse, error) { + conn := lp.client.ActiveConnection() + return pb.NewLeaseClient(conn).LeaseTimeToLive(ctx, rr) +} + +func (lp *leaseProxy) LeaseKeepAlive(stream pb.Lease_LeaseKeepAliveServer) error { + conn := lp.client.ActiveConnection() + ctx, cancel := context.WithCancel(stream.Context()) + lc, err := pb.NewLeaseClient(conn).LeaseKeepAlive(ctx) + if err != nil { + cancel() + return err + } + + go func() { + // Cancel the context attached to lc to unblock lc.Recv when + // this routine returns on error. + defer cancel() + + for { + // stream.Recv will be unblock when the loop in the parent routine + // returns on error. + rr, err := stream.Recv() + if err != nil { + return + } + err = lc.Send(rr) + if err != nil { + return + } + } + }() + + for { + rr, err := lc.Recv() + if err != nil { + return err + } + err = stream.Send(rr) + if err != nil { + return err + } + } +} diff --git a/vendor/github.com/coreos/etcd/proxy/grpcproxy/maintenance.go b/vendor/github.com/coreos/etcd/proxy/grpcproxy/maintenance.go new file mode 100644 index 000000000..209dc94a7 --- /dev/null +++ b/vendor/github.com/coreos/etcd/proxy/grpcproxy/maintenance.go @@ -0,0 +1,74 @@ +// Copyright 2016 The etcd Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package grpcproxy + +import ( + "golang.org/x/net/context" + + "github.com/coreos/etcd/clientv3" + pb "github.com/coreos/etcd/etcdserver/etcdserverpb" +) + +type maintenanceProxy struct { + client *clientv3.Client +} + +func NewMaintenanceProxy(c *clientv3.Client) pb.MaintenanceServer { + return &maintenanceProxy{ + client: c, + } +} + +func (mp *maintenanceProxy) Defragment(ctx context.Context, dr *pb.DefragmentRequest) (*pb.DefragmentResponse, error) { + conn := mp.client.ActiveConnection() + return pb.NewMaintenanceClient(conn).Defragment(ctx, dr) +} + +func (mp *maintenanceProxy) Snapshot(sr *pb.SnapshotRequest, stream pb.Maintenance_SnapshotServer) error { + conn := mp.client.ActiveConnection() + ctx, cancel := context.WithCancel(stream.Context()) + defer cancel() + + sc, err := pb.NewMaintenanceClient(conn).Snapshot(ctx, sr) + if err != nil { + return err + } + + for { + rr, err := sc.Recv() + if err != nil { + return err + } + err = stream.Send(rr) + if err != nil { + return err + } + } +} + +func (mp *maintenanceProxy) Hash(ctx context.Context, r *pb.HashRequest) (*pb.HashResponse, error) { + conn := mp.client.ActiveConnection() + return pb.NewMaintenanceClient(conn).Hash(ctx, r) +} + +func (mp *maintenanceProxy) Alarm(ctx context.Context, r *pb.AlarmRequest) (*pb.AlarmResponse, error) { + conn := mp.client.ActiveConnection() + return pb.NewMaintenanceClient(conn).Alarm(ctx, r) +} + +func (mp *maintenanceProxy) Status(ctx context.Context, r *pb.StatusRequest) (*pb.StatusResponse, error) { + conn := mp.client.ActiveConnection() + return pb.NewMaintenanceClient(conn).Status(ctx, r) +} diff --git a/vendor/github.com/coreos/etcd/proxy/grpcproxy/metrics.go b/vendor/github.com/coreos/etcd/proxy/grpcproxy/metrics.go new file mode 100644 index 000000000..f4a1d4c8d --- /dev/null +++ b/vendor/github.com/coreos/etcd/proxy/grpcproxy/metrics.go @@ -0,0 +1,51 @@ +// Copyright 2016 The etcd Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package grpcproxy + +import "github.com/prometheus/client_golang/prometheus" + +var ( + watchersCoalescing = prometheus.NewGauge(prometheus.GaugeOpts{ + Namespace: "etcd", + Subsystem: "grpc_proxy", + Name: "watchers_coalescing_total", + Help: "Total number of current watchers coalescing", + }) + eventsCoalescing = prometheus.NewCounter(prometheus.CounterOpts{ + Namespace: "etcd", + Subsystem: "grpc_proxy", + Name: "events_coalescing_total", + Help: "Total number of events coalescing", + }) + cacheHits = prometheus.NewGauge(prometheus.GaugeOpts{ + Namespace: "etcd", + Subsystem: "grpc_proxy", + Name: "cache_hits_total", + Help: "Total number of cache hits", + }) + cachedMisses = prometheus.NewGauge(prometheus.GaugeOpts{ + Namespace: "etcd", + Subsystem: "grpc_proxy", + Name: "cache_misses_total", + Help: "Total number of cache misses", + }) +) + +func init() { + prometheus.MustRegister(watchersCoalescing) + prometheus.MustRegister(eventsCoalescing) + prometheus.MustRegister(cacheHits) + prometheus.MustRegister(cachedMisses) +} diff --git a/vendor/github.com/coreos/etcd/proxy/grpcproxy/watch.go b/vendor/github.com/coreos/etcd/proxy/grpcproxy/watch.go new file mode 100644 index 000000000..42d196ca2 --- /dev/null +++ b/vendor/github.com/coreos/etcd/proxy/grpcproxy/watch.go @@ -0,0 +1,267 @@ +// Copyright 2016 The etcd Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package grpcproxy + +import ( + "sync" + + "golang.org/x/net/context" + "golang.org/x/time/rate" + "google.golang.org/grpc/metadata" + + "github.com/coreos/etcd/clientv3" + "github.com/coreos/etcd/etcdserver/api/v3rpc" + "github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes" + pb "github.com/coreos/etcd/etcdserver/etcdserverpb" +) + +type watchProxy struct { + cw clientv3.Watcher + ctx context.Context + + ranges *watchRanges + + // retryLimiter controls the create watch retry rate on lost leaders. + retryLimiter *rate.Limiter + + // mu protects leaderc updates. + mu sync.RWMutex + leaderc chan struct{} + + // wg waits until all outstanding watch servers quit. + wg sync.WaitGroup +} + +const ( + lostLeaderKey = "__lostleader" // watched to detect leader loss + retryPerSecond = 10 +) + +func NewWatchProxy(c *clientv3.Client) (pb.WatchServer, <-chan struct{}) { + wp := &watchProxy{ + cw: c.Watcher, + ctx: clientv3.WithRequireLeader(c.Ctx()), + retryLimiter: rate.NewLimiter(rate.Limit(retryPerSecond), retryPerSecond), + leaderc: make(chan struct{}), + } + wp.ranges = newWatchRanges(wp) + ch := make(chan struct{}) + go func() { + defer close(ch) + // a new streams without opening any watchers won't catch + // a lost leader event, so have a special watch to monitor it + rev := int64((uint64(1) << 63) - 2) + for wp.ctx.Err() == nil { + wch := wp.cw.Watch(wp.ctx, lostLeaderKey, clientv3.WithRev(rev)) + for range wch { + } + wp.mu.Lock() + close(wp.leaderc) + wp.leaderc = make(chan struct{}) + wp.mu.Unlock() + wp.retryLimiter.Wait(wp.ctx) + } + wp.mu.Lock() + <-wp.ctx.Done() + wp.mu.Unlock() + wp.wg.Wait() + wp.ranges.stop() + }() + return wp, ch +} + +func (wp *watchProxy) Watch(stream pb.Watch_WatchServer) (err error) { + wp.mu.Lock() + select { + case <-wp.ctx.Done(): + wp.mu.Unlock() + return + default: + wp.wg.Add(1) + } + wp.mu.Unlock() + + ctx, cancel := context.WithCancel(stream.Context()) + wps := &watchProxyStream{ + ranges: wp.ranges, + watchers: make(map[int64]*watcher), + stream: stream, + watchCh: make(chan *pb.WatchResponse, 1024), + ctx: ctx, + cancel: cancel, + } + + var leaderc <-chan struct{} + if md, ok := metadata.FromContext(stream.Context()); ok { + v := md[rpctypes.MetadataRequireLeaderKey] + if len(v) > 0 && v[0] == rpctypes.MetadataHasLeader { + leaderc = wp.lostLeaderNotify() + } + } + + // post to stopc => terminate server stream; can't use a waitgroup + // since all goroutines will only terminate after Watch() exits. + stopc := make(chan struct{}, 3) + go func() { + defer func() { stopc <- struct{}{} }() + wps.recvLoop() + }() + go func() { + defer func() { stopc <- struct{}{} }() + wps.sendLoop() + }() + // tear down watch if leader goes down or entire watch proxy is terminated + go func() { + defer func() { stopc <- struct{}{} }() + select { + case <-leaderc: + case <-ctx.Done(): + case <-wp.ctx.Done(): + } + }() + + <-stopc + cancel() + + // recv/send may only shutdown after function exits; + // goroutine notifies proxy that stream is through + go func() { + <-stopc + <-stopc + wps.close() + wp.wg.Done() + }() + + select { + case <-leaderc: + return rpctypes.ErrNoLeader + default: + return wps.ctx.Err() + } +} + +func (wp *watchProxy) lostLeaderNotify() <-chan struct{} { + wp.mu.RLock() + defer wp.mu.RUnlock() + return wp.leaderc +} + +// watchProxyStream forwards etcd watch events to a proxied client stream. +type watchProxyStream struct { + ranges *watchRanges + + // mu protects watchers and nextWatcherID + mu sync.Mutex + // watchers receive events from watch broadcast. + watchers map[int64]*watcher + // nextWatcherID is the id to assign the next watcher on this stream. + nextWatcherID int64 + + stream pb.Watch_WatchServer + + // watchCh receives watch responses from the watchers. + watchCh chan *pb.WatchResponse + + ctx context.Context + cancel context.CancelFunc +} + +func (wps *watchProxyStream) close() { + var wg sync.WaitGroup + wps.cancel() + wps.mu.Lock() + wg.Add(len(wps.watchers)) + for _, wpsw := range wps.watchers { + go func(w *watcher) { + wps.ranges.delete(w) + wg.Done() + }(wpsw) + } + wps.watchers = nil + wps.mu.Unlock() + + wg.Wait() + + close(wps.watchCh) +} + +func (wps *watchProxyStream) recvLoop() error { + for { + req, err := wps.stream.Recv() + if err != nil { + return err + } + switch uv := req.RequestUnion.(type) { + case *pb.WatchRequest_CreateRequest: + cr := uv.CreateRequest + w := &watcher{ + wr: watchRange{string(cr.Key), string(cr.RangeEnd)}, + id: wps.nextWatcherID, + wps: wps, + + nextrev: cr.StartRevision, + progress: cr.ProgressNotify, + prevKV: cr.PrevKv, + filters: v3rpc.FiltersFromRequest(cr), + } + if !w.wr.valid() { + w.post(&pb.WatchResponse{WatchId: -1, Created: true, Canceled: true}) + continue + } + wps.nextWatcherID++ + w.nextrev = cr.StartRevision + wps.watchers[w.id] = w + wps.ranges.add(w) + case *pb.WatchRequest_CancelRequest: + wps.delete(uv.CancelRequest.WatchId) + default: + panic("not implemented") + } + } +} + +func (wps *watchProxyStream) sendLoop() { + for { + select { + case wresp, ok := <-wps.watchCh: + if !ok { + return + } + if err := wps.stream.Send(wresp); err != nil { + return + } + case <-wps.ctx.Done(): + return + } + } +} + +func (wps *watchProxyStream) delete(id int64) { + wps.mu.Lock() + defer wps.mu.Unlock() + + w, ok := wps.watchers[id] + if !ok { + return + } + wps.ranges.delete(w) + delete(wps.watchers, id) + resp := &pb.WatchResponse{ + Header: &w.lastHeader, + WatchId: id, + Canceled: true, + } + wps.watchCh <- resp +} diff --git a/vendor/github.com/coreos/etcd/proxy/grpcproxy/watch_broadcast.go b/vendor/github.com/coreos/etcd/proxy/grpcproxy/watch_broadcast.go new file mode 100644 index 000000000..5529fb5a2 --- /dev/null +++ b/vendor/github.com/coreos/etcd/proxy/grpcproxy/watch_broadcast.go @@ -0,0 +1,158 @@ +// Copyright 2016 The etcd Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package grpcproxy + +import ( + "sync" + + "golang.org/x/net/context" + + "github.com/coreos/etcd/clientv3" + pb "github.com/coreos/etcd/etcdserver/etcdserverpb" +) + +// watchBroadcast broadcasts a server watcher to many client watchers. +type watchBroadcast struct { + // cancel stops the underlying etcd server watcher and closes ch. + cancel context.CancelFunc + donec chan struct{} + + // mu protects rev and receivers. + mu sync.RWMutex + // nextrev is the minimum expected next revision of the watcher on ch. + nextrev int64 + // receivers contains all the client-side watchers to serve. + receivers map[*watcher]struct{} + // responses counts the number of responses + responses int +} + +func newWatchBroadcast(wp *watchProxy, w *watcher, update func(*watchBroadcast)) *watchBroadcast { + cctx, cancel := context.WithCancel(wp.ctx) + wb := &watchBroadcast{ + cancel: cancel, + nextrev: w.nextrev, + receivers: make(map[*watcher]struct{}), + donec: make(chan struct{}), + } + wb.add(w) + go func() { + defer close(wb.donec) + // loop because leader loss will close channel + for cctx.Err() == nil { + opts := []clientv3.OpOption{ + clientv3.WithRange(w.wr.end), + clientv3.WithProgressNotify(), + clientv3.WithRev(wb.nextrev), + clientv3.WithPrevKV(), + } + // The create notification should be the first response; + // if the watch is recreated following leader loss, it + // shouldn't post a second create response to the client. + if wb.responses == 0 { + opts = append(opts, clientv3.WithCreatedNotify()) + } + wch := wp.cw.Watch(cctx, w.wr.key, opts...) + + for wr := range wch { + wb.bcast(wr) + update(wb) + } + wp.retryLimiter.Wait(cctx) + } + }() + return wb +} + +func (wb *watchBroadcast) bcast(wr clientv3.WatchResponse) { + wb.mu.Lock() + defer wb.mu.Unlock() + // watchers start on the given revision, if any; ignore header rev on create + if wb.responses > 0 || wb.nextrev == 0 { + wb.nextrev = wr.Header.Revision + 1 + } + wb.responses++ + for r := range wb.receivers { + r.send(wr) + } + if len(wb.receivers) > 0 { + eventsCoalescing.Add(float64(len(wb.receivers) - 1)) + } +} + +// add puts a watcher into receiving a broadcast if its revision at least +// meets the broadcast revision. Returns true if added. +func (wb *watchBroadcast) add(w *watcher) bool { + wb.mu.Lock() + defer wb.mu.Unlock() + if wb.nextrev > w.nextrev || (wb.nextrev == 0 && w.nextrev != 0) { + // wb is too far ahead, w will miss events + // or wb is being established with a current watcher + return false + } + if wb.responses == 0 { + // Newly created; create event will be sent by etcd. + wb.receivers[w] = struct{}{} + return true + } + // already sent by etcd; emulate create event + ok := w.post(&pb.WatchResponse{ + Header: &pb.ResponseHeader{ + // todo: fill in ClusterId + // todo: fill in MemberId: + Revision: w.nextrev, + // todo: fill in RaftTerm: + }, + WatchId: w.id, + Created: true, + }) + if !ok { + return false + } + wb.receivers[w] = struct{}{} + watchersCoalescing.Inc() + + return true +} +func (wb *watchBroadcast) delete(w *watcher) { + wb.mu.Lock() + defer wb.mu.Unlock() + if _, ok := wb.receivers[w]; !ok { + panic("deleting missing watcher from broadcast") + } + delete(wb.receivers, w) + if len(wb.receivers) > 0 { + // do not dec the only left watcher for coalescing. + watchersCoalescing.Dec() + } +} + +func (wb *watchBroadcast) size() int { + wb.mu.RLock() + defer wb.mu.RUnlock() + return len(wb.receivers) +} + +func (wb *watchBroadcast) empty() bool { return wb.size() == 0 } + +func (wb *watchBroadcast) stop() { + if !wb.empty() { + // do not dec the only left watcher for coalescing. + watchersCoalescing.Sub(float64(wb.size() - 1)) + } + + wb.cancel() + <-wb.donec +} diff --git a/vendor/github.com/coreos/etcd/proxy/grpcproxy/watch_broadcasts.go b/vendor/github.com/coreos/etcd/proxy/grpcproxy/watch_broadcasts.go new file mode 100644 index 000000000..8fe9e5f51 --- /dev/null +++ b/vendor/github.com/coreos/etcd/proxy/grpcproxy/watch_broadcasts.go @@ -0,0 +1,135 @@ +// Copyright 2016 The etcd Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package grpcproxy + +import ( + "sync" +) + +type watchBroadcasts struct { + wp *watchProxy + + // mu protects bcasts and watchers from the coalesce loop. + mu sync.Mutex + bcasts map[*watchBroadcast]struct{} + watchers map[*watcher]*watchBroadcast + + updatec chan *watchBroadcast + donec chan struct{} +} + +// maxCoalesceRecievers prevents a popular watchBroadcast from being coalseced. +const maxCoalesceReceivers = 5 + +func newWatchBroadcasts(wp *watchProxy) *watchBroadcasts { + wbs := &watchBroadcasts{ + wp: wp, + bcasts: make(map[*watchBroadcast]struct{}), + watchers: make(map[*watcher]*watchBroadcast), + updatec: make(chan *watchBroadcast, 1), + donec: make(chan struct{}), + } + go func() { + defer close(wbs.donec) + for wb := range wbs.updatec { + wbs.coalesce(wb) + } + }() + return wbs +} + +func (wbs *watchBroadcasts) coalesce(wb *watchBroadcast) { + if wb.size() >= maxCoalesceReceivers { + return + } + wbs.mu.Lock() + for wbswb := range wbs.bcasts { + if wbswb == wb { + continue + } + wb.mu.Lock() + wbswb.mu.Lock() + // 1. check if wbswb is behind wb so it won't skip any events in wb + // 2. ensure wbswb started; nextrev == 0 may mean wbswb is waiting + // for a current watcher and expects a create event from the server. + if wb.nextrev >= wbswb.nextrev && wbswb.responses > 0 { + for w := range wb.receivers { + wbswb.receivers[w] = struct{}{} + wbs.watchers[w] = wbswb + } + wb.receivers = nil + } + wbswb.mu.Unlock() + wb.mu.Unlock() + if wb.empty() { + delete(wbs.bcasts, wb) + wb.stop() + break + } + } + wbs.mu.Unlock() +} + +func (wbs *watchBroadcasts) add(w *watcher) { + wbs.mu.Lock() + defer wbs.mu.Unlock() + // find fitting bcast + for wb := range wbs.bcasts { + if wb.add(w) { + wbs.watchers[w] = wb + return + } + } + // no fit; create a bcast + wb := newWatchBroadcast(wbs.wp, w, wbs.update) + wbs.watchers[w] = wb + wbs.bcasts[wb] = struct{}{} +} + +// delete removes a watcher and returns the number of remaining watchers. +func (wbs *watchBroadcasts) delete(w *watcher) int { + wbs.mu.Lock() + defer wbs.mu.Unlock() + + wb, ok := wbs.watchers[w] + if !ok { + panic("deleting missing watcher from broadcasts") + } + delete(wbs.watchers, w) + wb.delete(w) + if wb.empty() { + delete(wbs.bcasts, wb) + wb.stop() + } + return len(wbs.bcasts) +} + +func (wbs *watchBroadcasts) stop() { + wbs.mu.Lock() + for wb := range wbs.bcasts { + wb.stop() + } + wbs.bcasts = nil + close(wbs.updatec) + wbs.mu.Unlock() + <-wbs.donec +} + +func (wbs *watchBroadcasts) update(wb *watchBroadcast) { + select { + case wbs.updatec <- wb: + default: + } +} diff --git a/vendor/github.com/coreos/etcd/proxy/grpcproxy/watch_client_adapter.go b/vendor/github.com/coreos/etcd/proxy/grpcproxy/watch_client_adapter.go new file mode 100644 index 000000000..283c2ed07 --- /dev/null +++ b/vendor/github.com/coreos/etcd/proxy/grpcproxy/watch_client_adapter.go @@ -0,0 +1,196 @@ +// Copyright 2016 The etcd Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package grpcproxy + +import ( + "errors" + + pb "github.com/coreos/etcd/etcdserver/etcdserverpb" + "golang.org/x/net/context" + "google.golang.org/grpc" + "google.golang.org/grpc/metadata" +) + +var errAlreadySentHeader = errors.New("grpcproxy: already send header") + +type ws2wc struct{ wserv pb.WatchServer } + +func WatchServerToWatchClient(wserv pb.WatchServer) pb.WatchClient { + return &ws2wc{wserv} +} + +func (s *ws2wc) Watch(ctx context.Context, opts ...grpc.CallOption) (pb.Watch_WatchClient, error) { + // ch1 is buffered so server can send error on close + ch1, ch2 := make(chan interface{}, 1), make(chan interface{}) + headerc, trailerc := make(chan metadata.MD, 1), make(chan metadata.MD, 1) + + cctx, ccancel := context.WithCancel(ctx) + cli := &chanStream{recvc: ch1, sendc: ch2, ctx: cctx, cancel: ccancel} + wclient := &ws2wcClientStream{chanClientStream{headerc, trailerc, cli}} + + sctx, scancel := context.WithCancel(ctx) + srv := &chanStream{recvc: ch2, sendc: ch1, ctx: sctx, cancel: scancel} + wserver := &ws2wcServerStream{chanServerStream{headerc, trailerc, srv, nil}} + go func() { + if err := s.wserv.Watch(wserver); err != nil { + select { + case srv.sendc <- err: + case <-sctx.Done(): + case <-cctx.Done(): + } + } + scancel() + ccancel() + }() + return wclient, nil +} + +// ws2wcClientStream implements Watch_WatchClient +type ws2wcClientStream struct{ chanClientStream } + +// ws2wcServerStream implements Watch_WatchServer +type ws2wcServerStream struct{ chanServerStream } + +func (s *ws2wcClientStream) Send(wr *pb.WatchRequest) error { + return s.SendMsg(wr) +} +func (s *ws2wcClientStream) Recv() (*pb.WatchResponse, error) { + var v interface{} + if err := s.RecvMsg(&v); err != nil { + return nil, err + } + return v.(*pb.WatchResponse), nil +} + +func (s *ws2wcServerStream) Send(wr *pb.WatchResponse) error { + return s.SendMsg(wr) +} +func (s *ws2wcServerStream) Recv() (*pb.WatchRequest, error) { + var v interface{} + if err := s.RecvMsg(&v); err != nil { + return nil, err + } + return v.(*pb.WatchRequest), nil +} + +// chanServerStream implements grpc.ServerStream with a chanStream +type chanServerStream struct { + headerc chan<- metadata.MD + trailerc chan<- metadata.MD + grpc.Stream + + headers []metadata.MD +} + +func (ss *chanServerStream) SendHeader(md metadata.MD) error { + if ss.headerc == nil { + return errAlreadySentHeader + } + outmd := make(map[string][]string) + for _, h := range append(ss.headers, md) { + for k, v := range h { + outmd[k] = v + } + } + select { + case ss.headerc <- outmd: + ss.headerc = nil + ss.headers = nil + return nil + case <-ss.Context().Done(): + } + return ss.Context().Err() +} + +func (ss *chanServerStream) SetHeader(md metadata.MD) error { + if ss.headerc == nil { + return errAlreadySentHeader + } + ss.headers = append(ss.headers, md) + return nil +} + +func (ss *chanServerStream) SetTrailer(md metadata.MD) { + ss.trailerc <- md +} + +// chanClientStream implements grpc.ClientStream with a chanStream +type chanClientStream struct { + headerc <-chan metadata.MD + trailerc <-chan metadata.MD + *chanStream +} + +func (cs *chanClientStream) Header() (metadata.MD, error) { + select { + case md := <-cs.headerc: + return md, nil + case <-cs.Context().Done(): + } + return nil, cs.Context().Err() +} + +func (cs *chanClientStream) Trailer() metadata.MD { + select { + case md := <-cs.trailerc: + return md + case <-cs.Context().Done(): + return nil + } +} + +func (s *chanClientStream) CloseSend() error { + close(s.chanStream.sendc) + return nil +} + +// chanStream implements grpc.Stream using channels +type chanStream struct { + recvc <-chan interface{} + sendc chan<- interface{} + ctx context.Context + cancel context.CancelFunc +} + +func (s *chanStream) Context() context.Context { return s.ctx } + +func (s *chanStream) SendMsg(m interface{}) error { + select { + case s.sendc <- m: + if err, ok := m.(error); ok { + return err + } + return nil + case <-s.ctx.Done(): + } + return s.ctx.Err() +} + +func (s *chanStream) RecvMsg(m interface{}) error { + v := m.(*interface{}) + select { + case msg, ok := <-s.recvc: + if !ok { + return grpc.ErrClientConnClosing + } + if err, ok := msg.(error); ok { + return err + } + *v = msg + return nil + case <-s.ctx.Done(): + } + return s.ctx.Err() +} diff --git a/vendor/github.com/coreos/etcd/proxy/grpcproxy/watch_ranges.go b/vendor/github.com/coreos/etcd/proxy/grpcproxy/watch_ranges.go new file mode 100644 index 000000000..31c6b5925 --- /dev/null +++ b/vendor/github.com/coreos/etcd/proxy/grpcproxy/watch_ranges.go @@ -0,0 +1,69 @@ +// Copyright 2016 The etcd Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package grpcproxy + +import ( + "sync" +) + +// watchRanges tracks all open watches for the proxy. +type watchRanges struct { + wp *watchProxy + + mu sync.Mutex + bcasts map[watchRange]*watchBroadcasts +} + +func newWatchRanges(wp *watchProxy) *watchRanges { + return &watchRanges{ + wp: wp, + bcasts: make(map[watchRange]*watchBroadcasts), + } +} + +func (wrs *watchRanges) add(w *watcher) { + wrs.mu.Lock() + defer wrs.mu.Unlock() + + if wbs := wrs.bcasts[w.wr]; wbs != nil { + wbs.add(w) + return + } + wbs := newWatchBroadcasts(wrs.wp) + wrs.bcasts[w.wr] = wbs + wbs.add(w) +} + +func (wrs *watchRanges) delete(w *watcher) { + wrs.mu.Lock() + defer wrs.mu.Unlock() + wbs, ok := wrs.bcasts[w.wr] + if !ok { + panic("deleting missing range") + } + if wbs.delete(w) == 0 { + wbs.stop() + delete(wrs.bcasts, w.wr) + } +} + +func (wrs *watchRanges) stop() { + wrs.mu.Lock() + defer wrs.mu.Unlock() + for _, wb := range wrs.bcasts { + wb.stop() + } + wrs.bcasts = nil +} diff --git a/vendor/github.com/coreos/etcd/proxy/grpcproxy/watcher.go b/vendor/github.com/coreos/etcd/proxy/grpcproxy/watcher.go new file mode 100644 index 000000000..e860a69ce --- /dev/null +++ b/vendor/github.com/coreos/etcd/proxy/grpcproxy/watcher.go @@ -0,0 +1,127 @@ +// Copyright 2016 The etcd Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package grpcproxy + +import ( + "time" + + "github.com/coreos/etcd/clientv3" + pb "github.com/coreos/etcd/etcdserver/etcdserverpb" + "github.com/coreos/etcd/mvcc" + "github.com/coreos/etcd/mvcc/mvccpb" +) + +type watchRange struct { + key, end string +} + +func (wr *watchRange) valid() bool { + return len(wr.end) == 0 || wr.end > wr.key || (wr.end[0] == 0 && len(wr.end) == 1) +} + +type watcher struct { + // user configuration + + wr watchRange + filters []mvcc.FilterFunc + progress bool + prevKV bool + + // id is the id returned to the client on its watch stream. + id int64 + // nextrev is the minimum expected next event revision. + nextrev int64 + // lastHeader has the last header sent over the stream. + lastHeader pb.ResponseHeader + + // wps is the parent. + wps *watchProxyStream +} + +// send filters out repeated events by discarding revisions older +// than the last one sent over the watch channel. +func (w *watcher) send(wr clientv3.WatchResponse) { + if wr.IsProgressNotify() && !w.progress { + return + } + if w.nextrev > wr.Header.Revision && len(wr.Events) > 0 { + return + } + if w.nextrev == 0 { + // current watch; expect updates following this revision + w.nextrev = wr.Header.Revision + 1 + } + + events := make([]*mvccpb.Event, 0, len(wr.Events)) + + var lastRev int64 + for i := range wr.Events { + ev := (*mvccpb.Event)(wr.Events[i]) + if ev.Kv.ModRevision < w.nextrev { + continue + } else { + // We cannot update w.rev here. + // txn can have multiple events with the same rev. + // If w.nextrev updates here, it would skip events in the same txn. + lastRev = ev.Kv.ModRevision + } + + filtered := false + for _, filter := range w.filters { + if filter(*ev) { + filtered = true + break + } + } + if filtered { + continue + } + + if !w.prevKV { + evCopy := *ev + evCopy.PrevKv = nil + ev = &evCopy + } + events = append(events, ev) + } + + if lastRev >= w.nextrev { + w.nextrev = lastRev + 1 + } + + // all events are filtered out? + if !wr.IsProgressNotify() && !wr.Created && len(events) == 0 { + return + } + + w.lastHeader = wr.Header + w.post(&pb.WatchResponse{ + Header: &wr.Header, + Created: wr.Created, + WatchId: w.id, + Events: events, + }) +} + +// post puts a watch response on the watcher's proxy stream channel +func (w *watcher) post(wr *pb.WatchResponse) bool { + select { + case w.wps.watchCh <- wr: + case <-time.After(50 * time.Millisecond): + w.wps.cancel() + return false + } + return true +} diff --git a/vendor/github.com/coreos/etcd/raft/README.md b/vendor/github.com/coreos/etcd/raft/README.md index c828081aa..a724b9585 100644 --- a/vendor/github.com/coreos/etcd/raft/README.md +++ b/vendor/github.com/coreos/etcd/raft/README.md @@ -5,15 +5,51 @@ The state machine is kept in sync through the use of a replicated log. For more details on Raft, see "In Search of an Understandable Consensus Algorithm" (https://ramcloud.stanford.edu/raft.pdf) by Diego Ongaro and John Ousterhout. +This Raft library is stable and feature complete. As of 2016, it is **the most widely used** Raft library in production, serving tens of thousands clusters each day. It powers distributed systems such as etcd, Kubernetes, Docker Swarm, Cloud Foundry Diego, CockroachDB, TiDB, Project Calico, Flannel, and more. + +Most Raft implementations have a monolithic design, including storage handling, messaging serialization, and network transport. This library instead follows a minimalistic design philosophy by only implementing the core raft algorithm. This minimalism buys flexibility, determinism, and performance. + +To keep the codebase small as well as provide flexibility, the library only implements the Raft algorithm; both network and disk IO are left to the user. Library users must implement their own transportation layer for message passing between Raft peers over the wire. Similarly, users must implement their own storage layer to persist the Raft log and state. + +In order to easily test the Raft library, its behavior should be deterministic. To achieve this determinism, the library models Raft as a state machine. The state machine takes a `Message` as input. A message can either be a local timer update or a network message sent from a remote peer. The state machine's output is a 3-tuple `{[]Messages, []LogEntries, NextState}` consisting of an array of `Messages`, `log entries`, and `Raft state changes`. For state machines with the same state, the same state machine input should always generate the same state machine output. + A simple example application, _raftexample_, is also available to help illustrate how to use this package in practice: https://github.com/coreos/etcd/tree/master/contrib/raftexample +# Features + +This raft implementation is a full feature implementation of Raft protocol. Features includes: + +- Leader election +- Log replication +- Log compaction +- Membership changes +- Leadership transfer extension +- Efficient linearizable read-only queries served by both the leader and followers + - leader checks with quorum and bypasses Raft log before processing read-only queries + - followers asks leader to get a safe read index before processing read-only queries +- More efficient lease-based linearizable read-only queries served by both the leader and followers + - leader bypasses Raft log and processing read-only queries locally + - followers asks leader to get a safe read index before processing read-only queries + - this approach relies on the clock of the all the machines in raft group + +This raft implementation also includes a few optional enhancements: + +- Optimistic pipelining to reduce log replication latency +- Flow control for log replication +- Batching Raft messages to reduce synchronized network I/O calls +- Batching log entries to reduce disk synchronized I/O +- Writing to leader's disk in parallel +- Internal proposal redirection from followers to leader +- Automatic stepping down when the leader loses quorum + ## Notable Users - [cockroachdb](https://github.com/cockroachdb/cockroach) A Scalable, Survivable, Strongly-Consistent SQL Database +- [dgraph](https://github.com/dgraph-io/dgraph) A Scalable, Distributed, Low Latency, High Throughput Graph Database - [etcd](https://github.com/coreos/etcd) A distributed reliable key-value store -- [tikv](https://github.com/pingcap/tikv) Distributed transactional key value database powered by Rust and Raft +- [tikv](https://github.com/pingcap/tikv) A Distributed transactional key value database powered by Rust and Raft - [swarmkit](https://github.com/docker/swarmkit) A toolkit for orchestrating distributed systems at any scale. ## Usage @@ -21,8 +57,7 @@ https://github.com/coreos/etcd/tree/master/contrib/raftexample The primary object in raft is a Node. You either start a Node from scratch using raft.StartNode or start a Node from some initial state using raft.RestartNode. -To start a node from scratch: - +To start a three-node cluster ```go storage := raft.NewMemoryStorage() c := &Config{ @@ -33,16 +68,30 @@ To start a node from scratch: MaxSizePerMsg: 4096, MaxInflightMsgs: 256, } + // Set peer list to the other nodes in the cluster. + // Note that they need to be started separately as well. n := raft.StartNode(c, []raft.Peer{{ID: 0x02}, {ID: 0x03}}) ``` -To restart a node from previous state: +You can start a single node cluster, like so: +```go + // Create storage and config as shown above. + // Set peer list to itself, so this node can become the leader of this single-node cluster. + peers := []raft.Peer{{ID: 0x01}} + n := raft.StartNode(c, peers) +``` +To allow a new node to join this cluster, do not pass in any peers. First, you need add the node to the existing cluster by calling `ProposeConfChange` on any existing node inside the cluster. Then, you can start the node with empty peer list, like so: +```go + // Create storage and config as shown above. + n := raft.StartNode(c, nil) +``` + +To restart a node from previous state: ```go storage := raft.NewMemoryStorage() - // recover the in-memory storage from persistent - // snapshot, state and entries. + // Recover the in-memory storage from persistent snapshot, state and entries. storage.ApplySnapshot(snapshot) storage.SetHardState(state) storage.Append(entries) @@ -56,8 +105,8 @@ To restart a node from previous state: MaxInflightMsgs: 256, } - // restart raft without peer information. - // peer information is already included in the storage. + // Restart raft without peer information. + // Peer information is already included in the storage. n := raft.RestartNode(c) ``` diff --git a/vendor/github.com/coreos/etcd/raft/doc.go b/vendor/github.com/coreos/etcd/raft/doc.go index a071932ae..b55c591ff 100644 --- a/vendor/github.com/coreos/etcd/raft/doc.go +++ b/vendor/github.com/coreos/etcd/raft/doc.go @@ -257,6 +257,12 @@ stale log entries: If candidate receives majority of votes of denials, it reverts back to follower. + 'MsgPreVote' and 'MsgPreVoteResp' are used in an optional two-phase election + protocol. When Config.PreVote is true, a pre-election is carried out first + (using the same rules as a regular election), and no node increases its term + number unless the pre-election indicates that the campaigining node would win. + This minimizes disruption when a partitioned node rejoins the cluster. + 'MsgSnap' requests to install a snapshot message. When a node has just become a leader or the leader receives 'MsgProp' message, it calls 'bcastAppend' method, which then calls 'sendAppend' method to each diff --git a/vendor/github.com/coreos/etcd/raft/log.go b/vendor/github.com/coreos/etcd/raft/log.go index 263f42255..c3036d3c9 100644 --- a/vendor/github.com/coreos/etcd/raft/log.go +++ b/vendor/github.com/coreos/etcd/raft/log.go @@ -74,8 +74,8 @@ func (l *raftLog) String() string { // maybeAppend returns (0, false) if the entries cannot be appended. Otherwise, // it returns (last index of new entries, true). func (l *raftLog) maybeAppend(index, logTerm, committed uint64, ents ...pb.Entry) (lastnewi uint64, ok bool) { - lastnewi = index + uint64(len(ents)) if l.matchTerm(index, logTerm) { + lastnewi = index + uint64(len(ents)) ci := l.findConflict(ents) switch { case ci == 0: @@ -232,7 +232,7 @@ func (l *raftLog) term(i uint64) (uint64, error) { if err == nil { return t, nil } - if err == ErrCompacted { + if err == ErrCompacted || err == ErrUnavailable { return 0, err } panic(err) // TODO(bdarnell) @@ -339,7 +339,7 @@ func (l *raftLog) mustCheckOutOfBounds(lo, hi uint64) error { return ErrCompacted } - length := l.lastIndex() - fi + 1 + length := l.lastIndex() + 1 - fi if lo < fi || hi > fi+length { l.logger.Panicf("slice[%d,%d) out of bound [%d,%d]", lo, hi, fi, l.lastIndex()) } diff --git a/vendor/github.com/coreos/etcd/raft/log_unstable.go b/vendor/github.com/coreos/etcd/raft/log_unstable.go index bfd4daa67..8ae301c3d 100644 --- a/vendor/github.com/coreos/etcd/raft/log_unstable.go +++ b/vendor/github.com/coreos/etcd/raft/log_unstable.go @@ -101,23 +101,23 @@ func (u *unstable) restore(s pb.Snapshot) { } func (u *unstable) truncateAndAppend(ents []pb.Entry) { - after := ents[0].Index - 1 + after := ents[0].Index switch { - case after == u.offset+uint64(len(u.entries))-1: - // after is the last index in the u.entries + case after == u.offset+uint64(len(u.entries)): + // after is the next index in the u.entries // directly append u.entries = append(u.entries, ents...) - case after < u.offset: - u.logger.Infof("replace the unstable entries from index %d", after+1) + case after <= u.offset: + u.logger.Infof("replace the unstable entries from index %d", after) // The log is being truncated to before our current offset // portion, so set the offset and replace the entries - u.offset = after + 1 + u.offset = after u.entries = ents default: // truncate to after and copy to u.entries // then append - u.logger.Infof("truncate the unstable entries to index %d", after) - u.entries = append([]pb.Entry{}, u.slice(u.offset, after+1)...) + u.logger.Infof("truncate the unstable entries before index %d", after) + u.entries = append([]pb.Entry{}, u.slice(u.offset, after)...) u.entries = append(u.entries, ents...) } } diff --git a/vendor/github.com/coreos/etcd/raft/node.go b/vendor/github.com/coreos/etcd/raft/node.go index 22332be6b..c8410fdc7 100644 --- a/vendor/github.com/coreos/etcd/raft/node.go +++ b/vendor/github.com/coreos/etcd/raft/node.go @@ -60,6 +60,12 @@ type Ready struct { // HardState will be equal to empty state if there is no update. pb.HardState + // ReadStates can be used for node to serve linearizable read requests locally + // when its applied index is greater than the index in ReadState. + // Note that the readState will be returned when raft receives msgReadIndex. + // The returned is only valid for the request that requested to read. + ReadStates []ReadState + // Entries specifies entries to be saved to stable storage BEFORE // Messages are sent. Entries []pb.Entry @@ -96,7 +102,7 @@ func IsEmptySnap(sp pb.Snapshot) bool { func (rd Ready) containsUpdates() bool { return rd.SoftState != nil || !IsEmptyHardState(rd.HardState) || !IsEmptySnap(rd.Snapshot) || len(rd.Entries) > 0 || - len(rd.CommittedEntries) > 0 || len(rd.Messages) > 0 + len(rd.CommittedEntries) > 0 || len(rd.Messages) > 0 || len(rd.ReadStates) != 0 } // Node represents a node in a raft cluster. @@ -130,27 +136,23 @@ type Node interface { // However, as an optimization, the application may call Advance while it is applying the // commands. For example. when the last Ready contains a snapshot, the application might take // a long time to apply the snapshot data. To continue receiving Ready without blocking raft - // progress, it can call Advance before finish applying the last ready. To make this optimization - // work safely, when the application receives a Ready with softState.RaftState equal to Candidate - // it MUST apply all pending configuration changes if there is any. - // - // Here is a simple solution that waiting for ALL pending entries to get applied. - // ``` - // ... - // rd := <-n.Ready() - // go apply(rd.CommittedEntries) // optimization to apply asynchronously in FIFO order. - // if rd.SoftState.RaftState == StateCandidate { - // waitAllApplied() - // } - // n.Advance() - // ... - //``` + // progress, it can call Advance before finishing applying the last ready. Advance() // ApplyConfChange applies config change to the local node. // Returns an opaque ConfState protobuf which must be recorded // in snapshots. Will never return nil; it returns a pointer only // to match MemoryStorage.Compact. ApplyConfChange(cc pb.ConfChange) *pb.ConfState + + // TransferLeadership attempts to transfer leadership to the given transferee. + TransferLeadership(ctx context.Context, lead, transferee uint64) + + // ReadIndex request a read state. The read state will be set in the ready. + // Read state has a read index. Once the application advances further than the read + // index, any linearizable read requests issued before the read request can be + // processed safely. The read state will have the same rctx attached. + ReadIndex(ctx context.Context, rctx []byte) error + // Status returns the current status of the raft state machine. Status() Status // ReportUnreachable reports the given node is not reachable for the last send. @@ -361,7 +363,9 @@ func (n *node) run(r *raft) { if !IsEmptySnap(rd.Snapshot) { prevSnapi = rd.Snapshot.Metadata.Index } + r.msgs = nil + r.readStates = nil advancec = n.advancec case <-advancec: if prevHardSt.Commit != 0 { @@ -458,8 +462,12 @@ func (n *node) ApplyConfChange(cc pb.ConfChange) *pb.ConfState { func (n *node) Status() Status { c := make(chan Status) - n.status <- c - return <-c + select { + case n.status <- c: + return <-c + case <-n.done: + return Status{} + } } func (n *node) ReportUnreachable(id uint64) { @@ -478,6 +486,19 @@ func (n *node) ReportSnapshot(id uint64, status SnapshotStatus) { } } +func (n *node) TransferLeadership(ctx context.Context, lead, transferee uint64) { + select { + // manually set 'from' and 'to', so that leader can voluntarily transfers its leadership + case n.recvc <- pb.Message{Type: pb.MsgTransferLeader, From: transferee, To: lead}: + case <-n.done: + case <-ctx.Done(): + } +} + +func (n *node) ReadIndex(ctx context.Context, rctx []byte) error { + return n.step(ctx, pb.Message{Type: pb.MsgReadIndex, Entries: []pb.Entry{{Data: rctx}}}) +} + func newReady(r *raft, prevSoftSt *SoftState, prevHardSt pb.HardState) Ready { rd := Ready{ Entries: r.raftLog.unstableEntries(), @@ -493,5 +514,8 @@ func newReady(r *raft, prevSoftSt *SoftState, prevHardSt pb.HardState) Ready { if r.raftLog.unstable.snapshot != nil { rd.Snapshot = *r.raftLog.unstable.snapshot } + if len(r.readStates) != 0 { + rd.ReadStates = r.readStates + } return rd } diff --git a/vendor/github.com/coreos/etcd/raft/progress.go b/vendor/github.com/coreos/etcd/raft/progress.go index 395470534..77c7b52ef 100644 --- a/vendor/github.com/coreos/etcd/raft/progress.go +++ b/vendor/github.com/coreos/etcd/raft/progress.go @@ -64,12 +64,17 @@ type Progress struct { RecentActive bool // inflights is a sliding window for the inflight messages. + // Each inflight message contains one or more log entries. + // The max number of entries per message is defined in raft config as MaxSizePerMsg. + // Thus inflight effectively limits both the number of inflight messages + // and the bandwidth each Progress can use. // When inflights is full, no more message should be sent. // When a leader sends out a message, the index of the last // entry should be added to inflights. The index MUST be added // into inflights in order. // When a leader receives a reply, the previous inflights should - // be freed by calling inflights.freeTo. + // be freed by calling inflights.freeTo with the index of the last + // received entry. ins *inflights } @@ -150,8 +155,11 @@ func (pr *Progress) maybeDecrTo(rejected, last uint64) bool { func (pr *Progress) pause() { pr.Paused = true } func (pr *Progress) resume() { pr.Paused = false } -// isPaused returns whether progress stops sending message. -func (pr *Progress) isPaused() bool { +// IsPaused returns whether sending log entries to this node has been +// paused. A node may be paused because it has rejected recent +// MsgApps, is currently waiting for a snapshot, or has reached the +// MaxInflightMsgs limit. +func (pr *Progress) IsPaused() bool { switch pr.State { case ProgressStateProbe: return pr.Paused @@ -173,7 +181,7 @@ func (pr *Progress) needSnapshotAbort() bool { } func (pr *Progress) String() string { - return fmt.Sprintf("next = %d, match = %d, state = %s, waiting = %v, pendingSnapshot = %d", pr.Next, pr.Match, pr.State, pr.isPaused(), pr.PendingSnapshot) + return fmt.Sprintf("next = %d, match = %d, state = %s, waiting = %v, pendingSnapshot = %d", pr.Next, pr.Match, pr.State, pr.IsPaused(), pr.PendingSnapshot) } type inflights struct { @@ -183,14 +191,16 @@ type inflights struct { count int // the size of the buffer - size int + size int + + // buffer contains the index of the last entry + // inside one message. buffer []uint64 } func newInflights(size int) *inflights { return &inflights{ - size: size, - buffer: make([]uint64, size), + size: size, } } @@ -200,13 +210,32 @@ func (in *inflights) add(inflight uint64) { panic("cannot add into a full inflights") } next := in.start + in.count - if next >= in.size { - next -= in.size + size := in.size + if next >= size { + next -= size + } + if next >= len(in.buffer) { + in.growBuf() } in.buffer[next] = inflight in.count++ } +// grow the inflight buffer by doubling up to inflights.size. We grow on demand +// instead of preallocating to inflights.size to handle systems which have +// thousands of Raft groups per process. +func (in *inflights) growBuf() { + newSize := len(in.buffer) * 2 + if newSize == 0 { + newSize = 1 + } else if newSize > in.size { + newSize = in.size + } + newBuffer := make([]uint64, newSize) + copy(newBuffer, in.buffer) + in.buffer = newBuffer +} + // freeTo frees the inflights smaller or equal to the given `to` flight. func (in *inflights) freeTo(to uint64) { if in.count == 0 || to < in.buffer[in.start] { @@ -221,13 +250,19 @@ func (in *inflights) freeTo(to uint64) { } // increase index and maybe rotate - if idx++; idx >= in.size { - idx -= in.size + size := in.size + if idx++; idx >= size { + idx -= size } } // free i inflights and set new start index in.count -= i in.start = idx + if in.count == 0 { + // inflights is empty, reset the start index so that we don't grow the + // buffer unnecessarily. + in.start = 0 + } } func (in *inflights) freeFirstOne() { in.freeTo(in.buffer[in.start]) } diff --git a/vendor/github.com/coreos/etcd/raft/raft.go b/vendor/github.com/coreos/etcd/raft/raft.go index 86b393d6a..7be4407ee 100644 --- a/vendor/github.com/coreos/etcd/raft/raft.go +++ b/vendor/github.com/coreos/etcd/raft/raft.go @@ -15,12 +15,15 @@ package raft import ( + "bytes" "errors" "fmt" "math" "math/rand" "sort" "strings" + "sync" + "time" pb "github.com/coreos/etcd/raft/raftpb" ) @@ -34,8 +37,60 @@ const ( StateFollower StateType = iota StateCandidate StateLeader + StatePreCandidate + numStates ) +type ReadOnlyOption int + +const ( + // ReadOnlySafe guarantees the linearizability of the read only request by + // communicating with the quorum. It is the default and suggested option. + ReadOnlySafe ReadOnlyOption = iota + // ReadOnlyLeaseBased ensures linearizability of the read only request by + // relying on the leader lease. It can be affected by clock drift. + // If the clock drift is unbounded, leader might keep the lease longer than it + // should (clock can move backward/pause without any bound). ReadIndex is not safe + // in that case. + ReadOnlyLeaseBased +) + +// Possible values for CampaignType +const ( + // campaignPreElection represents the first phase of a normal election when + // Config.PreVote is true. + campaignPreElection CampaignType = "CampaignPreElection" + // campaignElection represents a normal (time-based) election (the second phase + // of the election when Config.PreVote is true). + campaignElection CampaignType = "CampaignElection" + // campaignTransfer represents the type of leader transfer + campaignTransfer CampaignType = "CampaignTransfer" +) + +// lockedRand is a small wrapper around rand.Rand to provide +// synchronization. Only the methods needed by the code are exposed +// (e.g. Intn). +type lockedRand struct { + mu sync.Mutex + rand *rand.Rand +} + +func (r *lockedRand) Intn(n int) int { + r.mu.Lock() + v := r.rand.Intn(n) + r.mu.Unlock() + return v +} + +var globalRand = &lockedRand{ + rand: rand.New(rand.NewSource(time.Now().UnixNano())), +} + +// CampaignType represents the type of campaigning +// the reason we use the type of string instead of uint64 +// is because it's simpler to compare and fill in raft entries +type CampaignType string + // StateType represents the role of a node in a cluster. type StateType uint64 @@ -43,6 +98,7 @@ var stmap = [...]string{ "StateFollower", "StateCandidate", "StateLeader", + "StatePreCandidate", } func (st StateType) String() string { @@ -100,6 +156,23 @@ type Config struct { // steps down when quorum is not active for an electionTimeout. CheckQuorum bool + // PreVote enables the Pre-Vote algorithm described in raft thesis section + // 9.6. This prevents disruption when a node that has been partitioned away + // rejoins the cluster. + PreVote bool + + // ReadOnlyOption specifies how the read only request is processed. + // + // ReadOnlySafe guarantees the linearizability of the read only request by + // communicating with the quorum. It is the default and suggested option. + // + // ReadOnlyLeaseBased ensures linearizability of the read only request by + // relying on the leader lease. It can be affected by clock drift. + // If the clock drift is unbounded, leader might keep the lease longer than it + // should (clock can move backward/pause without any bound). ReadIndex is not safe + // in that case. + ReadOnlyOption ReadOnlyOption + // Logger is the logger used for raft log. For multinode which can host // multiple raft group, each raft group can have its own logger Logger Logger @@ -139,6 +212,8 @@ type raft struct { Term uint64 Vote uint64 + readStates []ReadState + // the log raftLog *raftLog @@ -160,6 +235,8 @@ type raft struct { // New configuration is ignored if there exists unapplied configuration. pendingConf bool + readOnly *readOnly + // number of ticks since it reached last electionTimeout when it is leader // or candidate. // number of ticks since it reached last electionTimeout or received a @@ -171,6 +248,7 @@ type raft struct { heartbeatElapsed int checkQuorum bool + preVote bool heartbeatTimeout int electionTimeout int @@ -179,7 +257,6 @@ type raft struct { // when raft changes its state to follower or candidate. randomizedElectionTimeout int - rand *rand.Rand tick func() step stepFunc @@ -216,8 +293,9 @@ func newRaft(c *Config) *raft { heartbeatTimeout: c.HeartbeatTick, logger: c.Logger, checkQuorum: c.CheckQuorum, + preVote: c.PreVote, + readOnly: newReadOnly(c.ReadOnlyOption), } - r.rand = rand.New(rand.NewSource(int64(c.ID))) for _, p := range peers { r.prs[p] = &Progress{Next: 1, ins: newInflights(r.maxInflight)} } @@ -265,11 +343,23 @@ func (r *raft) nodes() []uint64 { // send persists state to stable storage and then sends to its mailbox. func (r *raft) send(m pb.Message) { m.From = r.id - // do not attach term to MsgProp - // proposals are a way to forward to the leader and - // should be treated as local message. - if m.Type != pb.MsgProp { - m.Term = r.Term + if m.Type == pb.MsgVote || m.Type == pb.MsgPreVote { + if m.Term == 0 { + // PreVote RPCs are sent at a term other than our actual term, so the code + // that sends these messages is responsible for setting the term. + panic(fmt.Sprintf("term should be set when sending %s", m.Type)) + } + } else { + if m.Term != 0 { + panic(fmt.Sprintf("term should not be set when sending %s (was %d)", m.Type, m.Term)) + } + // do not attach term to MsgProp, MsgReadIndex + // proposals are a way to forward to the leader and + // should be treated as local message. + // MsgReadIndex is also forwarded to leader. + if m.Type != pb.MsgProp && m.Type != pb.MsgReadIndex { + m.Term = r.Term + } } r.msgs = append(r.msgs, m) } @@ -277,7 +367,7 @@ func (r *raft) send(m pb.Message) { // sendAppend sends RPC, with entries to the given peer. func (r *raft) sendAppend(to uint64) { pr := r.prs[to] - if pr.isPaused() { + if pr.IsPaused() { return } m := pb.Message{} @@ -334,7 +424,7 @@ func (r *raft) sendAppend(to uint64) { } // sendHeartbeat sends an empty MsgApp -func (r *raft) sendHeartbeat(to uint64) { +func (r *raft) sendHeartbeat(to uint64, ctx []byte) { // Attach the commit as min(to.matched, r.committed). // When the leader sends out heartbeat message, // the receiver(follower) might not be matched with the leader @@ -343,10 +433,12 @@ func (r *raft) sendHeartbeat(to uint64) { // an unmatched index. commit := min(r.prs[to].Match, r.raftLog.committed) m := pb.Message{ - To: to, - Type: pb.MsgHeartbeat, - Commit: commit, + To: to, + Type: pb.MsgHeartbeat, + Commit: commit, + Context: ctx, } + r.send(m) } @@ -363,12 +455,20 @@ func (r *raft) bcastAppend() { // bcastHeartbeat sends RPC, without entries to all the peers. func (r *raft) bcastHeartbeat() { + lastCtx := r.readOnly.lastPendingRequestCtx() + if len(lastCtx) == 0 { + r.bcastHeartbeatWithCtx(nil) + } else { + r.bcastHeartbeatWithCtx([]byte(lastCtx)) + } +} + +func (r *raft) bcastHeartbeatWithCtx(ctx []byte) { for id := range r.prs { if id == r.id { continue } - r.sendHeartbeat(id) - r.prs[id].resume() + r.sendHeartbeat(id, ctx) } } @@ -407,6 +507,7 @@ func (r *raft) reset(term uint64) { } } r.pendingConf = false + r.readOnly = newReadOnly(r.readOnly.option) } func (r *raft) appendEntry(es ...pb.Entry) { @@ -479,6 +580,20 @@ func (r *raft) becomeCandidate() { r.logger.Infof("%x became candidate at term %d", r.id, r.Term) } +func (r *raft) becomePreCandidate() { + // TODO(xiangli) remove the panic when the raft implementation is stable + if r.state == StateLeader { + panic("invalid transition [leader -> pre-candidate]") + } + // Becoming a pre-candidate changes our step functions and state, + // but doesn't change anything else. In particular it does not increase + // r.Term or change r.Vote. + r.step = stepCandidate + r.tick = r.tickElection + r.state = StatePreCandidate + r.logger.Infof("%x became pre-candidate at term %d", r.id, r.Term) +} + func (r *raft) becomeLeader() { // TODO(xiangli) remove the panic when the raft implementation is stable if r.state == StateFollower { @@ -494,40 +609,61 @@ func (r *raft) becomeLeader() { r.logger.Panicf("unexpected error getting uncommitted entries (%v)", err) } - for _, e := range ents { - if e.Type != pb.EntryConfChange { - continue - } - if r.pendingConf { - panic("unexpected double uncommitted config entry") - } + nconf := numOfPendingConf(ents) + if nconf > 1 { + panic("unexpected multiple uncommitted config entry") + } + if nconf == 1 { r.pendingConf = true } + r.appendEntry(pb.Entry{Data: nil}) r.logger.Infof("%x became leader at term %d", r.id, r.Term) } -func (r *raft) campaign() { - r.becomeCandidate() - if r.quorum() == r.poll(r.id, true) { - r.becomeLeader() +func (r *raft) campaign(t CampaignType) { + var term uint64 + var voteMsg pb.MessageType + if t == campaignPreElection { + r.becomePreCandidate() + voteMsg = pb.MsgPreVote + // PreVote RPCs are sent for the next term before we've incremented r.Term. + term = r.Term + 1 + } else { + r.becomeCandidate() + voteMsg = pb.MsgVote + term = r.Term + } + if r.quorum() == r.poll(r.id, voteRespMsgType(voteMsg), true) { + // We won the election after voting for ourselves (which must mean that + // this is a single-node cluster). Advance to the next state. + if t == campaignPreElection { + r.campaign(campaignElection) + } else { + r.becomeLeader() + } return } for id := range r.prs { if id == r.id { continue } - r.logger.Infof("%x [logterm: %d, index: %d] sent vote request to %x at term %d", - r.id, r.raftLog.lastTerm(), r.raftLog.lastIndex(), id, r.Term) - r.send(pb.Message{To: id, Type: pb.MsgVote, Index: r.raftLog.lastIndex(), LogTerm: r.raftLog.lastTerm()}) + r.logger.Infof("%x [logterm: %d, index: %d] sent %s request to %x at term %d", + r.id, r.raftLog.lastTerm(), r.raftLog.lastIndex(), voteMsg, id, r.Term) + + var ctx []byte + if t == campaignTransfer { + ctx = []byte(t) + } + r.send(pb.Message{Term: term, To: id, Type: voteMsg, Index: r.raftLog.lastIndex(), LogTerm: r.raftLog.lastTerm(), Context: ctx}) } } -func (r *raft) poll(id uint64, v bool) (granted int) { +func (r *raft) poll(id uint64, t pb.MessageType, v bool) (granted int) { if v { - r.logger.Infof("%x received vote from %x at term %d", r.id, id, r.Term) + r.logger.Infof("%x received %s from %x at term %d", r.id, t, id, r.Term) } else { - r.logger.Infof("%x received vote rejection from %x at term %d", r.id, id, r.Term) + r.logger.Infof("%x received %s rejection from %x at term %d", r.id, t, id, r.Term) } if _, ok := r.votes[id]; !ok { r.votes[id] = v @@ -541,50 +677,54 @@ func (r *raft) poll(id uint64, v bool) (granted int) { } func (r *raft) Step(m pb.Message) error { - if m.Type == pb.MsgHup { - if r.state != StateLeader { - r.logger.Infof("%x is starting a new election at term %d", r.id, r.Term) - r.campaign() - } else { - r.logger.Debugf("%x ignoring MsgHup because already leader", r.id) - } - return nil - } - if m.Type == pb.MsgTransferLeader { - if r.state != StateLeader { - r.logger.Debugf("%x [term %d state %v] ignoring MsgTransferLeader to %x", r.id, r.Term, r.state, m.From) - } - } - + // Handle the message term, which may result in our stepping down to a follower. switch { case m.Term == 0: // local message case m.Term > r.Term: lead := m.From - if m.Type == pb.MsgVote { - if r.checkQuorum && r.state != StateCandidate && r.electionElapsed < r.electionTimeout { + if m.Type == pb.MsgVote || m.Type == pb.MsgPreVote { + force := bytes.Equal(m.Context, []byte(campaignTransfer)) + inLease := r.checkQuorum && r.lead != None && r.electionElapsed < r.electionTimeout + if !force && inLease { // If a server receives a RequestVote request within the minimum election timeout // of hearing from a current leader, it does not update its term or grant its vote - r.logger.Infof("%x [logterm: %d, index: %d, vote: %x] ignored vote from %x [logterm: %d, index: %d] at term %d: lease is not expired (remaining ticks: %d)", - r.id, r.raftLog.lastTerm(), r.raftLog.lastIndex(), r.Vote, m.From, m.LogTerm, m.Index, r.Term, r.electionTimeout-r.electionElapsed) + r.logger.Infof("%x [logterm: %d, index: %d, vote: %x] ignored %s from %x [logterm: %d, index: %d] at term %d: lease is not expired (remaining ticks: %d)", + r.id, r.raftLog.lastTerm(), r.raftLog.lastIndex(), r.Vote, m.Type, m.From, m.LogTerm, m.Index, r.Term, r.electionTimeout-r.electionElapsed) return nil } lead = None } - r.logger.Infof("%x [term: %d] received a %s message with higher term from %x [term: %d]", - r.id, r.Term, m.Type, m.From, m.Term) - r.becomeFollower(m.Term, lead) + switch { + case m.Type == pb.MsgPreVote: + // Never change our term in response to a PreVote + case m.Type == pb.MsgPreVoteResp && !m.Reject: + // We send pre-vote requests with a term in our future. If the + // pre-vote is granted, we will increment our term when we get a + // quorum. If it is not, the term comes from the node that + // rejected our vote so we should become a follower at the new + // term. + default: + r.logger.Infof("%x [term: %d] received a %s message with higher term from %x [term: %d]", + r.id, r.Term, m.Type, m.From, m.Term) + r.becomeFollower(m.Term, lead) + } + case m.Term < r.Term: if r.checkQuorum && (m.Type == pb.MsgHeartbeat || m.Type == pb.MsgApp) { - // We have received messages from a leader at a lower term. It is possible that these messages were - // simply delayed in the network, but this could also mean that this node has advanced its term number - // during a network partition, and it is now unable to either win an election or to rejoin the majority - // on the old term. If checkQuorum is false, this will be handled by incrementing term numbers in response - // to MsgVote with a higher term, but if checkQuorum is true we may not advance the term on MsgVote and - // must generate other messages to advance the term. The net result of these two features is to minimize - // the disruption caused by nodes that have been removed from the cluster's configuration: a removed node - // will send MsgVotes which will be ignored, but it will not receive MsgApp or MsgHeartbeat, so it will not - // create disruptive term increases + // We have received messages from a leader at a lower term. It is possible + // that these messages were simply delayed in the network, but this could + // also mean that this node has advanced its term number during a network + // partition, and it is now unable to either win an election or to rejoin + // the majority on the old term. If checkQuorum is false, this will be + // handled by incrementing term numbers in response to MsgVote with a + // higher term, but if checkQuorum is true we may not advance the term on + // MsgVote and must generate other messages to advance the term. The net + // result of these two features is to minimize the disruption caused by + // nodes that have been removed from the cluster's configuration: a + // removed node will send MsgVotes (or MsgPreVotes) which will be ignored, + // but it will not receive MsgApp or MsgHeartbeat, so it will not create + // disruptive term increases r.send(pb.Message{To: m.From, Type: pb.MsgAppResp}) } else { // ignore other cases @@ -593,7 +733,50 @@ func (r *raft) Step(m pb.Message) error { } return nil } - r.step(r, m) + + switch m.Type { + case pb.MsgHup: + if r.state != StateLeader { + ents, err := r.raftLog.slice(r.raftLog.applied+1, r.raftLog.committed+1, noLimit) + if err != nil { + r.logger.Panicf("unexpected error getting unapplied entries (%v)", err) + } + if n := numOfPendingConf(ents); n != 0 && r.raftLog.committed > r.raftLog.applied { + r.logger.Warningf("%x cannot campaign at term %d since there are still %d pending configuration changes to apply", r.id, r.Term, n) + return nil + } + + r.logger.Infof("%x is starting a new election at term %d", r.id, r.Term) + if r.preVote { + r.campaign(campaignPreElection) + } else { + r.campaign(campaignElection) + } + } else { + r.logger.Debugf("%x ignoring MsgHup because already leader", r.id) + } + + case pb.MsgVote, pb.MsgPreVote: + // The m.Term > r.Term clause is for MsgPreVote. For MsgVote m.Term should + // always equal r.Term. + if (r.Vote == None || m.Term > r.Term || r.Vote == m.From) && r.raftLog.isUpToDate(m.Index, m.LogTerm) { + r.logger.Infof("%x [logterm: %d, index: %d, vote: %x] cast %s for %x [logterm: %d, index: %d] at term %d", + r.id, r.raftLog.lastTerm(), r.raftLog.lastIndex(), r.Vote, m.Type, m.From, m.LogTerm, m.Index, r.Term) + r.send(pb.Message{To: m.From, Type: voteRespMsgType(m.Type)}) + if m.Type == pb.MsgVote { + // Only record real votes. + r.electionElapsed = 0 + r.Vote = m.From + } + } else { + r.logger.Infof("%x [logterm: %d, index: %d, vote: %x] rejected %s from %x [logterm: %d, index: %d] at term %d", + r.id, r.raftLog.lastTerm(), r.raftLog.lastIndex(), r.Vote, m.Type, m.From, m.LogTerm, m.Index, r.Term) + r.send(pb.Message{To: m.From, Type: voteRespMsgType(m.Type), Reject: true}) + } + + default: + r.step(r, m) + } return nil } @@ -629,6 +812,7 @@ func stepLeader(r *raft, m pb.Message) { for i, e := range m.Entries { if e.Type == pb.EntryConfChange { if r.pendingConf { + r.logger.Infof("propose conf %s ignored since pending unapplied configuration", e.String()) m.Entries[i] = pb.Entry{Type: pb.EntryNormal} } r.pendingConf = true @@ -637,10 +821,35 @@ func stepLeader(r *raft, m pb.Message) { r.appendEntry(m.Entries...) r.bcastAppend() return - case pb.MsgVote: - r.logger.Infof("%x [logterm: %d, index: %d, vote: %x] rejected vote from %x [logterm: %d, index: %d] at term %d", - r.id, r.raftLog.lastTerm(), r.raftLog.lastIndex(), r.Vote, m.From, m.LogTerm, m.Index, r.Term) - r.send(pb.Message{To: m.From, Type: pb.MsgVoteResp, Reject: true}) + case pb.MsgReadIndex: + if r.quorum() > 1 { + if r.raftLog.zeroTermOnErrCompacted(r.raftLog.term(r.raftLog.committed)) != r.Term { + // Reject read only request when this leader has not committed any log entry at its term. + return + } + + // thinking: use an interally defined context instead of the user given context. + // We can express this in terms of the term and index instead of a user-supplied value. + // This would allow multiple reads to piggyback on the same message. + switch r.readOnly.option { + case ReadOnlySafe: + r.readOnly.addRequest(r.raftLog.committed, m) + r.bcastHeartbeatWithCtx(m.Entries[0].Data) + case ReadOnlyLeaseBased: + var ri uint64 + if r.checkQuorum { + ri = r.raftLog.committed + } + if m.From == None || m.From == r.id { // from local member + r.readStates = append(r.readStates, ReadState{Index: r.raftLog.committed, RequestCtx: m.Entries[0].Data}) + } else { + r.send(pb.Message{To: m.From, Type: pb.MsgReadIndexResp, Index: ri, Entries: m.Entries}) + } + } + } else { + r.readStates = append(r.readStates, ReadState{Index: r.raftLog.committed, RequestCtx: m.Entries[0].Data}) + } + return } @@ -665,7 +874,7 @@ func stepLeader(r *raft, m pb.Message) { r.sendAppend(m.From) } } else { - oldPaused := pr.isPaused() + oldPaused := pr.IsPaused() if pr.maybeUpdate(m.Index) { switch { case pr.State == ProgressStateProbe: @@ -693,6 +902,7 @@ func stepLeader(r *raft, m pb.Message) { } case pb.MsgHeartbeatResp: pr.RecentActive = true + pr.resume() // free one slot for the full inflights window to allow progress. if pr.State == ProgressStateReplicate && pr.ins.full() { @@ -701,6 +911,25 @@ func stepLeader(r *raft, m pb.Message) { if pr.Match < r.raftLog.lastIndex() { r.sendAppend(m.From) } + + if r.readOnly.option != ReadOnlySafe || len(m.Context) == 0 { + return + } + + ackCount := r.readOnly.recvAck(m) + if ackCount < r.quorum() { + return + } + + rss := r.readOnly.advance(m) + for _, rs := range rss { + req := rs.req + if req.From == None || req.From == r.id { // from local member + r.readStates = append(r.readStates, ReadState{Index: rs.index, RequestCtx: req.Entries[0].Data}) + } else { + r.send(pb.Message{To: req.From, Type: pb.MsgReadIndexResp, Index: rs.index, Entries: req.Entries}) + } + } case pb.MsgSnapStatus: if pr.State != ProgressStateSnapshot { return @@ -754,7 +983,18 @@ func stepLeader(r *raft, m pb.Message) { } } +// stepCandidate is shared by StateCandidate and StatePreCandidate; the difference is +// whether they respond to MsgVoteResp or MsgPreVoteResp. func stepCandidate(r *raft, m pb.Message) { + // Only handle vote responses corresponding to our candidacy (while in + // StateCandidate, we may get stale MsgPreVoteResp messages in this term from + // our pre-candidate state). + var myVoteRespType pb.MessageType + if r.state == StatePreCandidate { + myVoteRespType = pb.MsgPreVoteResp + } else { + myVoteRespType = pb.MsgVoteResp + } switch m.Type { case pb.MsgProp: r.logger.Infof("%x no leader at term %d; dropping proposal", r.id, r.Term) @@ -768,17 +1008,17 @@ func stepCandidate(r *raft, m pb.Message) { case pb.MsgSnap: r.becomeFollower(m.Term, m.From) r.handleSnapshot(m) - case pb.MsgVote: - r.logger.Infof("%x [logterm: %d, index: %d, vote: %x] rejected vote from %x [logterm: %d, index: %d] at term %d", - r.id, r.raftLog.lastTerm(), r.raftLog.lastIndex(), r.Vote, m.From, m.LogTerm, m.Index, r.Term) - r.send(pb.Message{To: m.From, Type: pb.MsgVoteResp, Reject: true}) - case pb.MsgVoteResp: - gr := r.poll(m.From, !m.Reject) - r.logger.Infof("%x [quorum:%d] has received %d votes and %d vote rejections", r.id, r.quorum(), gr, len(r.votes)-gr) + case myVoteRespType: + gr := r.poll(m.From, m.Type, !m.Reject) + r.logger.Infof("%x [quorum:%d] has received %d %s votes and %d vote rejections", r.id, r.quorum(), gr, m.Type, len(r.votes)-gr) switch r.quorum() { case gr: - r.becomeLeader() - r.bcastAppend() + if r.state == StatePreCandidate { + r.campaign(campaignElection) + } else { + r.becomeLeader() + r.bcastAppend() + } case len(r.votes) - gr: r.becomeFollower(r.Term, None) } @@ -806,22 +1046,38 @@ func stepFollower(r *raft, m pb.Message) { r.handleHeartbeat(m) case pb.MsgSnap: r.electionElapsed = 0 + r.lead = m.From r.handleSnapshot(m) - case pb.MsgVote: - if (r.Vote == None || r.Vote == m.From) && r.raftLog.isUpToDate(m.Index, m.LogTerm) { - r.electionElapsed = 0 - r.logger.Infof("%x [logterm: %d, index: %d, vote: %x] voted for %x [logterm: %d, index: %d] at term %d", - r.id, r.raftLog.lastTerm(), r.raftLog.lastIndex(), r.Vote, m.From, m.LogTerm, m.Index, r.Term) - r.Vote = m.From - r.send(pb.Message{To: m.From, Type: pb.MsgVoteResp}) - } else { - r.logger.Infof("%x [logterm: %d, index: %d, vote: %x] rejected vote from %x [logterm: %d, index: %d] at term %d", - r.id, r.raftLog.lastTerm(), r.raftLog.lastIndex(), r.Vote, m.From, m.LogTerm, m.Index, r.Term) - r.send(pb.Message{To: m.From, Type: pb.MsgVoteResp, Reject: true}) + case pb.MsgTransferLeader: + if r.lead == None { + r.logger.Infof("%x no leader at term %d; dropping leader transfer msg", r.id, r.Term) + return } + m.To = r.lead + r.send(m) case pb.MsgTimeoutNow: - r.logger.Infof("%x [term %d] received MsgTimeoutNow from %x and starts an election to get leadership.", r.id, r.Term, m.From) - r.campaign() + if r.promotable() { + r.logger.Infof("%x [term %d] received MsgTimeoutNow from %x and starts an election to get leadership.", r.id, r.Term, m.From) + // Leadership transfers never use pre-vote even if r.preVote is true; we + // know we are not recovering from a partition so there is no need for the + // extra round trip. + r.campaign(campaignTransfer) + } else { + r.logger.Infof("%x received MsgTimeoutNow from %x but is not promotable", r.id, m.From) + } + case pb.MsgReadIndex: + if r.lead == None { + r.logger.Infof("%x no leader at term %d; dropping index reading msg", r.id, r.Term) + return + } + m.To = r.lead + r.send(m) + case pb.MsgReadIndexResp: + if len(m.Entries) != 1 { + r.logger.Errorf("%x invalid format of MsgReadIndexResp from %x, entries count: %d", r.id, m.From, len(m.Entries)) + return + } + r.readStates = append(r.readStates, ReadState{Index: m.Index, RequestCtx: m.Entries[0].Data}) } } @@ -842,7 +1098,7 @@ func (r *raft) handleAppendEntries(m pb.Message) { func (r *raft) handleHeartbeat(m pb.Message) { r.raftLog.commitTo(m.Commit) - r.send(pb.Message{To: m.From, Type: pb.MsgHeartbeatResp}) + r.send(pb.Message{To: m.From, Type: pb.MsgHeartbeatResp, Context: m.Context}) } func (r *raft) handleSnapshot(m pb.Message) { @@ -877,11 +1133,9 @@ func (r *raft) restore(s pb.Snapshot) bool { r.raftLog.restore(s) r.prs = make(map[uint64]*Progress) for _, n := range s.Metadata.ConfState.Nodes { - match, next := uint64(0), uint64(r.raftLog.lastIndex())+1 + match, next := uint64(0), r.raftLog.lastIndex()+1 if n == r.id { match = next - 1 - } else { - match = 0 } r.setProgress(n, match, next) r.logger.Infof("%x restored progress of %x [%s]", r.id, n, r.prs[n]) @@ -897,6 +1151,7 @@ func (r *raft) promotable() bool { } func (r *raft) addNode(id uint64) { + r.pendingConf = false if _, ok := r.prs[id]; ok { // Ignore any redundant addNode calls (which can happen because the // initial bootstrapping entries are applied twice). @@ -904,7 +1159,6 @@ func (r *raft) addNode(id uint64) { } r.setProgress(id, 0, r.raftLog.lastIndex()+1) - r.pendingConf = false } func (r *raft) removeNode(id uint64) { @@ -954,7 +1208,7 @@ func (r *raft) pastElectionTimeout() bool { } func (r *raft) resetRandomizedElectionTimeout() { - r.randomizedElectionTimeout = r.electionTimeout + r.rand.Intn(r.electionTimeout) + r.randomizedElectionTimeout = r.electionTimeout + globalRand.Intn(r.electionTimeout) } // checkQuorumActive returns true if the quorum is active from @@ -987,3 +1241,13 @@ func (r *raft) sendTimeoutNow(to uint64) { func (r *raft) abortLeaderTransfer() { r.leadTransferee = None } + +func numOfPendingConf(ents []pb.Entry) int { + n := 0 + for i := range ents { + if ents[i].Type == pb.EntryConfChange { + n++ + } + } + return n +} 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 e60fb88df..86ad31207 100644 --- a/vendor/github.com/coreos/etcd/raft/raftpb/raft.pb.go +++ b/vendor/github.com/coreos/etcd/raft/raftpb/raft.pb.go @@ -36,7 +36,9 @@ var _ = math.Inf // This is a compile-time assertion to ensure that this generated file // is compatible with the proto package it is being compiled against. -const _ = proto.ProtoPackageIsVersion1 +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package type EntryType int32 @@ -90,6 +92,10 @@ const ( MsgCheckQuorum MessageType = 12 MsgTransferLeader MessageType = 13 MsgTimeoutNow MessageType = 14 + MsgReadIndex MessageType = 15 + MsgReadIndexResp MessageType = 16 + MsgPreVote MessageType = 17 + MsgPreVoteResp MessageType = 18 ) var MessageType_name = map[int32]string{ @@ -108,6 +114,10 @@ var MessageType_name = map[int32]string{ 12: "MsgCheckQuorum", 13: "MsgTransferLeader", 14: "MsgTimeoutNow", + 15: "MsgReadIndex", + 16: "MsgReadIndexResp", + 17: "MsgPreVote", + 18: "MsgPreVoteResp", } var MessageType_value = map[string]int32{ "MsgHup": 0, @@ -125,6 +135,10 @@ var MessageType_value = map[string]int32{ "MsgCheckQuorum": 12, "MsgTransferLeader": 13, "MsgTimeoutNow": 14, + "MsgReadIndex": 15, + "MsgReadIndexResp": 16, + "MsgPreVote": 17, + "MsgPreVoteResp": 18, } func (x MessageType) Enum() *MessageType { @@ -183,10 +197,10 @@ func (x *ConfChangeType) UnmarshalJSON(data []byte) error { func (ConfChangeType) EnumDescriptor() ([]byte, []int) { return fileDescriptorRaft, []int{2} } type Entry struct { - Term uint64 `protobuf:"varint,2,opt,name=Term,json=term" json:"Term"` - Index uint64 `protobuf:"varint,3,opt,name=Index,json=index" json:"Index"` - Type EntryType `protobuf:"varint,1,opt,name=Type,json=type,enum=raftpb.EntryType" json:"Type"` - Data []byte `protobuf:"bytes,4,opt,name=Data,json=data" json:"Data,omitempty"` + Term uint64 `protobuf:"varint,2,opt,name=Term" json:"Term"` + Index uint64 `protobuf:"varint,3,opt,name=Index" json:"Index"` + Type EntryType `protobuf:"varint,1,opt,name=Type,enum=raftpb.EntryType" json:"Type"` + Data []byte `protobuf:"bytes,4,opt,name=Data" json:"Data,omitempty"` XXX_unrecognized []byte `json:"-"` } @@ -230,6 +244,7 @@ type Message struct { Snapshot Snapshot `protobuf:"bytes,9,opt,name=snapshot" json:"snapshot"` Reject bool `protobuf:"varint,10,opt,name=reject" json:"reject"` RejectHint uint64 `protobuf:"varint,11,opt,name=rejectHint" json:"rejectHint"` + Context []byte `protobuf:"bytes,12,opt,name=context" json:"context,omitempty"` XXX_unrecognized []byte `json:"-"` } @@ -261,10 +276,10 @@ func (*ConfState) ProtoMessage() {} func (*ConfState) Descriptor() ([]byte, []int) { return fileDescriptorRaft, []int{5} } type ConfChange struct { - ID uint64 `protobuf:"varint,1,opt,name=ID,json=iD" json:"ID"` - Type ConfChangeType `protobuf:"varint,2,opt,name=Type,json=type,enum=raftpb.ConfChangeType" json:"Type"` - NodeID uint64 `protobuf:"varint,3,opt,name=NodeID,json=nodeID" json:"NodeID"` - Context []byte `protobuf:"bytes,4,opt,name=Context,json=context" json:"Context,omitempty"` + ID uint64 `protobuf:"varint,1,opt,name=ID" json:"ID"` + Type ConfChangeType `protobuf:"varint,2,opt,name=Type,enum=raftpb.ConfChangeType" json:"Type"` + NodeID uint64 `protobuf:"varint,3,opt,name=NodeID" json:"NodeID"` + Context []byte `protobuf:"bytes,4,opt,name=Context" json:"Context,omitempty"` XXX_unrecognized []byte `json:"-"` } @@ -285,304 +300,310 @@ func init() { proto.RegisterEnum("raftpb.MessageType", MessageType_name, MessageType_value) proto.RegisterEnum("raftpb.ConfChangeType", ConfChangeType_name, ConfChangeType_value) } -func (m *Entry) Marshal() (data []byte, err error) { +func (m *Entry) Marshal() (dAtA []byte, err error) { size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) if err != nil { return nil, err } - return data[:n], nil + return dAtA[:n], nil } -func (m *Entry) MarshalTo(data []byte) (int, error) { +func (m *Entry) MarshalTo(dAtA []byte) (int, error) { var i int _ = i var l int _ = l - data[i] = 0x8 + dAtA[i] = 0x8 i++ - i = encodeVarintRaft(data, i, uint64(m.Type)) - data[i] = 0x10 + i = encodeVarintRaft(dAtA, i, uint64(m.Type)) + dAtA[i] = 0x10 i++ - i = encodeVarintRaft(data, i, uint64(m.Term)) - data[i] = 0x18 + i = encodeVarintRaft(dAtA, i, uint64(m.Term)) + dAtA[i] = 0x18 i++ - i = encodeVarintRaft(data, i, uint64(m.Index)) + i = encodeVarintRaft(dAtA, i, uint64(m.Index)) if m.Data != nil { - data[i] = 0x22 + dAtA[i] = 0x22 i++ - i = encodeVarintRaft(data, i, uint64(len(m.Data))) - i += copy(data[i:], m.Data) + i = encodeVarintRaft(dAtA, i, uint64(len(m.Data))) + i += copy(dAtA[i:], m.Data) } if m.XXX_unrecognized != nil { - i += copy(data[i:], m.XXX_unrecognized) + i += copy(dAtA[i:], m.XXX_unrecognized) } return i, nil } -func (m *SnapshotMetadata) Marshal() (data []byte, err error) { +func (m *SnapshotMetadata) Marshal() (dAtA []byte, err error) { size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) if err != nil { return nil, err } - return data[:n], nil + return dAtA[:n], nil } -func (m *SnapshotMetadata) MarshalTo(data []byte) (int, error) { +func (m *SnapshotMetadata) MarshalTo(dAtA []byte) (int, error) { var i int _ = i var l int _ = l - data[i] = 0xa + dAtA[i] = 0xa i++ - i = encodeVarintRaft(data, i, uint64(m.ConfState.Size())) - n1, err := m.ConfState.MarshalTo(data[i:]) + i = encodeVarintRaft(dAtA, i, uint64(m.ConfState.Size())) + n1, err := m.ConfState.MarshalTo(dAtA[i:]) if err != nil { return 0, err } i += n1 - data[i] = 0x10 + dAtA[i] = 0x10 i++ - i = encodeVarintRaft(data, i, uint64(m.Index)) - data[i] = 0x18 + i = encodeVarintRaft(dAtA, i, uint64(m.Index)) + dAtA[i] = 0x18 i++ - i = encodeVarintRaft(data, i, uint64(m.Term)) + i = encodeVarintRaft(dAtA, i, uint64(m.Term)) if m.XXX_unrecognized != nil { - i += copy(data[i:], m.XXX_unrecognized) + i += copy(dAtA[i:], m.XXX_unrecognized) } return i, nil } -func (m *Snapshot) Marshal() (data []byte, err error) { +func (m *Snapshot) Marshal() (dAtA []byte, err error) { size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) if err != nil { return nil, err } - return data[:n], nil + return dAtA[:n], nil } -func (m *Snapshot) MarshalTo(data []byte) (int, error) { +func (m *Snapshot) MarshalTo(dAtA []byte) (int, error) { var i int _ = i var l int _ = l if m.Data != nil { - data[i] = 0xa + dAtA[i] = 0xa i++ - i = encodeVarintRaft(data, i, uint64(len(m.Data))) - i += copy(data[i:], m.Data) + i = encodeVarintRaft(dAtA, i, uint64(len(m.Data))) + i += copy(dAtA[i:], m.Data) } - data[i] = 0x12 + dAtA[i] = 0x12 i++ - i = encodeVarintRaft(data, i, uint64(m.Metadata.Size())) - n2, err := m.Metadata.MarshalTo(data[i:]) + i = encodeVarintRaft(dAtA, i, uint64(m.Metadata.Size())) + n2, err := m.Metadata.MarshalTo(dAtA[i:]) if err != nil { return 0, err } i += n2 if m.XXX_unrecognized != nil { - i += copy(data[i:], m.XXX_unrecognized) + i += copy(dAtA[i:], m.XXX_unrecognized) } return i, nil } -func (m *Message) Marshal() (data []byte, err error) { +func (m *Message) Marshal() (dAtA []byte, err error) { size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) if err != nil { return nil, err } - return data[:n], nil + return dAtA[:n], nil } -func (m *Message) MarshalTo(data []byte) (int, error) { +func (m *Message) MarshalTo(dAtA []byte) (int, error) { var i int _ = i var l int _ = l - data[i] = 0x8 + dAtA[i] = 0x8 i++ - i = encodeVarintRaft(data, i, uint64(m.Type)) - data[i] = 0x10 + i = encodeVarintRaft(dAtA, i, uint64(m.Type)) + dAtA[i] = 0x10 i++ - i = encodeVarintRaft(data, i, uint64(m.To)) - data[i] = 0x18 + i = encodeVarintRaft(dAtA, i, uint64(m.To)) + dAtA[i] = 0x18 i++ - i = encodeVarintRaft(data, i, uint64(m.From)) - data[i] = 0x20 + i = encodeVarintRaft(dAtA, i, uint64(m.From)) + dAtA[i] = 0x20 i++ - i = encodeVarintRaft(data, i, uint64(m.Term)) - data[i] = 0x28 + i = encodeVarintRaft(dAtA, i, uint64(m.Term)) + dAtA[i] = 0x28 i++ - i = encodeVarintRaft(data, i, uint64(m.LogTerm)) - data[i] = 0x30 + i = encodeVarintRaft(dAtA, i, uint64(m.LogTerm)) + dAtA[i] = 0x30 i++ - i = encodeVarintRaft(data, i, uint64(m.Index)) + i = encodeVarintRaft(dAtA, i, uint64(m.Index)) if len(m.Entries) > 0 { for _, msg := range m.Entries { - data[i] = 0x3a + dAtA[i] = 0x3a i++ - i = encodeVarintRaft(data, i, uint64(msg.Size())) - n, err := msg.MarshalTo(data[i:]) + i = encodeVarintRaft(dAtA, i, uint64(msg.Size())) + n, err := msg.MarshalTo(dAtA[i:]) if err != nil { return 0, err } i += n } } - data[i] = 0x40 + dAtA[i] = 0x40 i++ - i = encodeVarintRaft(data, i, uint64(m.Commit)) - data[i] = 0x4a + i = encodeVarintRaft(dAtA, i, uint64(m.Commit)) + dAtA[i] = 0x4a i++ - i = encodeVarintRaft(data, i, uint64(m.Snapshot.Size())) - n3, err := m.Snapshot.MarshalTo(data[i:]) + i = encodeVarintRaft(dAtA, i, uint64(m.Snapshot.Size())) + n3, err := m.Snapshot.MarshalTo(dAtA[i:]) if err != nil { return 0, err } i += n3 - data[i] = 0x50 + dAtA[i] = 0x50 i++ if m.Reject { - data[i] = 1 + dAtA[i] = 1 } else { - data[i] = 0 + dAtA[i] = 0 } i++ - data[i] = 0x58 + dAtA[i] = 0x58 i++ - i = encodeVarintRaft(data, i, uint64(m.RejectHint)) + i = encodeVarintRaft(dAtA, i, uint64(m.RejectHint)) + if m.Context != nil { + dAtA[i] = 0x62 + i++ + i = encodeVarintRaft(dAtA, i, uint64(len(m.Context))) + i += copy(dAtA[i:], m.Context) + } if m.XXX_unrecognized != nil { - i += copy(data[i:], m.XXX_unrecognized) + i += copy(dAtA[i:], m.XXX_unrecognized) } return i, nil } -func (m *HardState) Marshal() (data []byte, err error) { +func (m *HardState) Marshal() (dAtA []byte, err error) { size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) if err != nil { return nil, err } - return data[:n], nil + return dAtA[:n], nil } -func (m *HardState) MarshalTo(data []byte) (int, error) { +func (m *HardState) MarshalTo(dAtA []byte) (int, error) { var i int _ = i var l int _ = l - data[i] = 0x8 + dAtA[i] = 0x8 i++ - i = encodeVarintRaft(data, i, uint64(m.Term)) - data[i] = 0x10 + i = encodeVarintRaft(dAtA, i, uint64(m.Term)) + dAtA[i] = 0x10 i++ - i = encodeVarintRaft(data, i, uint64(m.Vote)) - data[i] = 0x18 + i = encodeVarintRaft(dAtA, i, uint64(m.Vote)) + dAtA[i] = 0x18 i++ - i = encodeVarintRaft(data, i, uint64(m.Commit)) + i = encodeVarintRaft(dAtA, i, uint64(m.Commit)) if m.XXX_unrecognized != nil { - i += copy(data[i:], m.XXX_unrecognized) + i += copy(dAtA[i:], m.XXX_unrecognized) } return i, nil } -func (m *ConfState) Marshal() (data []byte, err error) { +func (m *ConfState) Marshal() (dAtA []byte, err error) { size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) if err != nil { return nil, err } - return data[:n], nil + return dAtA[:n], nil } -func (m *ConfState) MarshalTo(data []byte) (int, error) { +func (m *ConfState) MarshalTo(dAtA []byte) (int, error) { var i int _ = i var l int _ = l if len(m.Nodes) > 0 { for _, num := range m.Nodes { - data[i] = 0x8 + dAtA[i] = 0x8 i++ - i = encodeVarintRaft(data, i, uint64(num)) + i = encodeVarintRaft(dAtA, i, uint64(num)) } } if m.XXX_unrecognized != nil { - i += copy(data[i:], m.XXX_unrecognized) + i += copy(dAtA[i:], m.XXX_unrecognized) } return i, nil } -func (m *ConfChange) Marshal() (data []byte, err error) { +func (m *ConfChange) Marshal() (dAtA []byte, err error) { size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) if err != nil { return nil, err } - return data[:n], nil + return dAtA[:n], nil } -func (m *ConfChange) MarshalTo(data []byte) (int, error) { +func (m *ConfChange) MarshalTo(dAtA []byte) (int, error) { var i int _ = i var l int _ = l - data[i] = 0x8 + dAtA[i] = 0x8 i++ - i = encodeVarintRaft(data, i, uint64(m.ID)) - data[i] = 0x10 + i = encodeVarintRaft(dAtA, i, uint64(m.ID)) + dAtA[i] = 0x10 i++ - i = encodeVarintRaft(data, i, uint64(m.Type)) - data[i] = 0x18 + i = encodeVarintRaft(dAtA, i, uint64(m.Type)) + dAtA[i] = 0x18 i++ - i = encodeVarintRaft(data, i, uint64(m.NodeID)) + i = encodeVarintRaft(dAtA, i, uint64(m.NodeID)) if m.Context != nil { - data[i] = 0x22 + dAtA[i] = 0x22 i++ - i = encodeVarintRaft(data, i, uint64(len(m.Context))) - i += copy(data[i:], m.Context) + i = encodeVarintRaft(dAtA, i, uint64(len(m.Context))) + i += copy(dAtA[i:], m.Context) } if m.XXX_unrecognized != nil { - i += copy(data[i:], m.XXX_unrecognized) + i += copy(dAtA[i:], m.XXX_unrecognized) } return i, nil } -func encodeFixed64Raft(data []byte, offset int, v uint64) int { - data[offset] = uint8(v) - data[offset+1] = uint8(v >> 8) - data[offset+2] = uint8(v >> 16) - data[offset+3] = uint8(v >> 24) - data[offset+4] = uint8(v >> 32) - data[offset+5] = uint8(v >> 40) - data[offset+6] = uint8(v >> 48) - data[offset+7] = uint8(v >> 56) +func encodeFixed64Raft(dAtA []byte, offset int, v uint64) int { + dAtA[offset] = uint8(v) + dAtA[offset+1] = uint8(v >> 8) + dAtA[offset+2] = uint8(v >> 16) + dAtA[offset+3] = uint8(v >> 24) + dAtA[offset+4] = uint8(v >> 32) + dAtA[offset+5] = uint8(v >> 40) + dAtA[offset+6] = uint8(v >> 48) + dAtA[offset+7] = uint8(v >> 56) return offset + 8 } -func encodeFixed32Raft(data []byte, offset int, v uint32) int { - data[offset] = uint8(v) - data[offset+1] = uint8(v >> 8) - data[offset+2] = uint8(v >> 16) - data[offset+3] = uint8(v >> 24) +func encodeFixed32Raft(dAtA []byte, offset int, v uint32) int { + dAtA[offset] = uint8(v) + dAtA[offset+1] = uint8(v >> 8) + dAtA[offset+2] = uint8(v >> 16) + dAtA[offset+3] = uint8(v >> 24) return offset + 4 } -func encodeVarintRaft(data []byte, offset int, v uint64) int { +func encodeVarintRaft(dAtA []byte, offset int, v uint64) int { for v >= 1<<7 { - data[offset] = uint8(v&0x7f | 0x80) + dAtA[offset] = uint8(v&0x7f | 0x80) v >>= 7 offset++ } - data[offset] = uint8(v) + dAtA[offset] = uint8(v) return offset + 1 } func (m *Entry) Size() (n int) { @@ -649,6 +670,10 @@ func (m *Message) Size() (n int) { n += 1 + l + sovRaft(uint64(l)) n += 2 n += 1 + sovRaft(uint64(m.RejectHint)) + if m.Context != nil { + l = len(m.Context) + n += 1 + l + sovRaft(uint64(l)) + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -710,8 +735,8 @@ func sovRaft(x uint64) (n int) { func sozRaft(x uint64) (n int) { return sovRaft(uint64((x << 1) ^ uint64((int64(x) >> 63)))) } -func (m *Entry) Unmarshal(data []byte) error { - l := len(data) +func (m *Entry) Unmarshal(dAtA []byte) error { + l := len(dAtA) iNdEx := 0 for iNdEx < l { preIndex := iNdEx @@ -723,7 +748,7 @@ func (m *Entry) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -751,7 +776,7 @@ func (m *Entry) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ m.Type |= (EntryType(b) & 0x7F) << shift if b < 0x80 { @@ -770,7 +795,7 @@ func (m *Entry) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ m.Term |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -789,7 +814,7 @@ func (m *Entry) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ m.Index |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -808,7 +833,7 @@ func (m *Entry) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ byteLen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -822,14 +847,14 @@ func (m *Entry) Unmarshal(data []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Data = append(m.Data[:0], data[iNdEx:postIndex]...) + m.Data = append(m.Data[:0], dAtA[iNdEx:postIndex]...) if m.Data == nil { m.Data = []byte{} } iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skipRaft(data[iNdEx:]) + skippy, err := skipRaft(dAtA[iNdEx:]) if err != nil { return err } @@ -839,7 +864,7 @@ func (m *Entry) Unmarshal(data []byte) error { if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF } - m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) iNdEx += skippy } } @@ -849,8 +874,8 @@ func (m *Entry) Unmarshal(data []byte) error { } return nil } -func (m *SnapshotMetadata) Unmarshal(data []byte) error { - l := len(data) +func (m *SnapshotMetadata) Unmarshal(dAtA []byte) error { + l := len(dAtA) iNdEx := 0 for iNdEx < l { preIndex := iNdEx @@ -862,7 +887,7 @@ func (m *SnapshotMetadata) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -890,7 +915,7 @@ func (m *SnapshotMetadata) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ msglen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -904,7 +929,7 @@ func (m *SnapshotMetadata) Unmarshal(data []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.ConfState.Unmarshal(data[iNdEx:postIndex]); err != nil { + if err := m.ConfState.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -920,7 +945,7 @@ func (m *SnapshotMetadata) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ m.Index |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -939,7 +964,7 @@ func (m *SnapshotMetadata) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ m.Term |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -948,7 +973,7 @@ func (m *SnapshotMetadata) Unmarshal(data []byte) error { } default: iNdEx = preIndex - skippy, err := skipRaft(data[iNdEx:]) + skippy, err := skipRaft(dAtA[iNdEx:]) if err != nil { return err } @@ -958,7 +983,7 @@ func (m *SnapshotMetadata) Unmarshal(data []byte) error { if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF } - m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) iNdEx += skippy } } @@ -968,8 +993,8 @@ func (m *SnapshotMetadata) Unmarshal(data []byte) error { } return nil } -func (m *Snapshot) Unmarshal(data []byte) error { - l := len(data) +func (m *Snapshot) Unmarshal(dAtA []byte) error { + l := len(dAtA) iNdEx := 0 for iNdEx < l { preIndex := iNdEx @@ -981,7 +1006,7 @@ func (m *Snapshot) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -1009,7 +1034,7 @@ func (m *Snapshot) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ byteLen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -1023,7 +1048,7 @@ func (m *Snapshot) Unmarshal(data []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Data = append(m.Data[:0], data[iNdEx:postIndex]...) + m.Data = append(m.Data[:0], dAtA[iNdEx:postIndex]...) if m.Data == nil { m.Data = []byte{} } @@ -1040,7 +1065,7 @@ func (m *Snapshot) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ msglen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -1054,13 +1079,13 @@ func (m *Snapshot) Unmarshal(data []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.Metadata.Unmarshal(data[iNdEx:postIndex]); err != nil { + if err := m.Metadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skipRaft(data[iNdEx:]) + skippy, err := skipRaft(dAtA[iNdEx:]) if err != nil { return err } @@ -1070,7 +1095,7 @@ func (m *Snapshot) Unmarshal(data []byte) error { if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF } - m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) iNdEx += skippy } } @@ -1080,8 +1105,8 @@ func (m *Snapshot) Unmarshal(data []byte) error { } return nil } -func (m *Message) Unmarshal(data []byte) error { - l := len(data) +func (m *Message) Unmarshal(dAtA []byte) error { + l := len(dAtA) iNdEx := 0 for iNdEx < l { preIndex := iNdEx @@ -1093,7 +1118,7 @@ func (m *Message) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -1121,7 +1146,7 @@ func (m *Message) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ m.Type |= (MessageType(b) & 0x7F) << shift if b < 0x80 { @@ -1140,7 +1165,7 @@ func (m *Message) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ m.To |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -1159,7 +1184,7 @@ func (m *Message) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ m.From |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -1178,7 +1203,7 @@ func (m *Message) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ m.Term |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -1197,7 +1222,7 @@ func (m *Message) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ m.LogTerm |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -1216,7 +1241,7 @@ func (m *Message) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ m.Index |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -1235,7 +1260,7 @@ func (m *Message) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ msglen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -1250,7 +1275,7 @@ func (m *Message) Unmarshal(data []byte) error { return io.ErrUnexpectedEOF } m.Entries = append(m.Entries, Entry{}) - if err := m.Entries[len(m.Entries)-1].Unmarshal(data[iNdEx:postIndex]); err != nil { + if err := m.Entries[len(m.Entries)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -1266,7 +1291,7 @@ func (m *Message) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ m.Commit |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -1285,7 +1310,7 @@ func (m *Message) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ msglen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -1299,7 +1324,7 @@ func (m *Message) Unmarshal(data []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.Snapshot.Unmarshal(data[iNdEx:postIndex]); err != nil { + if err := m.Snapshot.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -1315,7 +1340,7 @@ func (m *Message) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ v |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -1335,16 +1360,47 @@ func (m *Message) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ m.RejectHint |= (uint64(b) & 0x7F) << shift if b < 0x80 { break } } + case 12: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Context", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRaft + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthRaft + } + postIndex := iNdEx + byteLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Context = append(m.Context[:0], dAtA[iNdEx:postIndex]...) + if m.Context == nil { + m.Context = []byte{} + } + iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skipRaft(data[iNdEx:]) + skippy, err := skipRaft(dAtA[iNdEx:]) if err != nil { return err } @@ -1354,7 +1410,7 @@ func (m *Message) Unmarshal(data []byte) error { if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF } - m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) iNdEx += skippy } } @@ -1364,8 +1420,8 @@ func (m *Message) Unmarshal(data []byte) error { } return nil } -func (m *HardState) Unmarshal(data []byte) error { - l := len(data) +func (m *HardState) Unmarshal(dAtA []byte) error { + l := len(dAtA) iNdEx := 0 for iNdEx < l { preIndex := iNdEx @@ -1377,7 +1433,7 @@ func (m *HardState) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -1405,7 +1461,7 @@ func (m *HardState) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ m.Term |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -1424,7 +1480,7 @@ func (m *HardState) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ m.Vote |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -1443,7 +1499,7 @@ func (m *HardState) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ m.Commit |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -1452,7 +1508,7 @@ func (m *HardState) Unmarshal(data []byte) error { } default: iNdEx = preIndex - skippy, err := skipRaft(data[iNdEx:]) + skippy, err := skipRaft(dAtA[iNdEx:]) if err != nil { return err } @@ -1462,7 +1518,7 @@ func (m *HardState) Unmarshal(data []byte) error { if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF } - m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) iNdEx += skippy } } @@ -1472,8 +1528,8 @@ func (m *HardState) Unmarshal(data []byte) error { } return nil } -func (m *ConfState) Unmarshal(data []byte) error { - l := len(data) +func (m *ConfState) Unmarshal(dAtA []byte) error { + l := len(dAtA) iNdEx := 0 for iNdEx < l { preIndex := iNdEx @@ -1485,7 +1541,7 @@ func (m *ConfState) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -1513,7 +1569,7 @@ func (m *ConfState) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ v |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -1523,7 +1579,7 @@ func (m *ConfState) Unmarshal(data []byte) error { m.Nodes = append(m.Nodes, v) default: iNdEx = preIndex - skippy, err := skipRaft(data[iNdEx:]) + skippy, err := skipRaft(dAtA[iNdEx:]) if err != nil { return err } @@ -1533,7 +1589,7 @@ func (m *ConfState) Unmarshal(data []byte) error { if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF } - m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) iNdEx += skippy } } @@ -1543,8 +1599,8 @@ func (m *ConfState) Unmarshal(data []byte) error { } return nil } -func (m *ConfChange) Unmarshal(data []byte) error { - l := len(data) +func (m *ConfChange) Unmarshal(dAtA []byte) error { + l := len(dAtA) iNdEx := 0 for iNdEx < l { preIndex := iNdEx @@ -1556,7 +1612,7 @@ func (m *ConfChange) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -1584,7 +1640,7 @@ func (m *ConfChange) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ m.ID |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -1603,7 +1659,7 @@ func (m *ConfChange) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ m.Type |= (ConfChangeType(b) & 0x7F) << shift if b < 0x80 { @@ -1622,7 +1678,7 @@ func (m *ConfChange) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ m.NodeID |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -1641,7 +1697,7 @@ func (m *ConfChange) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ byteLen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -1655,14 +1711,14 @@ func (m *ConfChange) Unmarshal(data []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Context = append(m.Context[:0], data[iNdEx:postIndex]...) + m.Context = append(m.Context[:0], dAtA[iNdEx:postIndex]...) if m.Context == nil { m.Context = []byte{} } iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skipRaft(data[iNdEx:]) + skippy, err := skipRaft(dAtA[iNdEx:]) if err != nil { return err } @@ -1672,7 +1728,7 @@ func (m *ConfChange) Unmarshal(data []byte) error { if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF } - m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) iNdEx += skippy } } @@ -1682,8 +1738,8 @@ func (m *ConfChange) Unmarshal(data []byte) error { } return nil } -func skipRaft(data []byte) (n int, err error) { - l := len(data) +func skipRaft(dAtA []byte) (n int, err error) { + l := len(dAtA) iNdEx := 0 for iNdEx < l { var wire uint64 @@ -1694,7 +1750,7 @@ func skipRaft(data []byte) (n int, err error) { if iNdEx >= l { return 0, io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -1712,7 +1768,7 @@ func skipRaft(data []byte) (n int, err error) { return 0, io.ErrUnexpectedEOF } iNdEx++ - if data[iNdEx-1] < 0x80 { + if dAtA[iNdEx-1] < 0x80 { break } } @@ -1729,7 +1785,7 @@ func skipRaft(data []byte) (n int, err error) { if iNdEx >= l { return 0, io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ length |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -1752,7 +1808,7 @@ func skipRaft(data []byte) (n int, err error) { if iNdEx >= l { return 0, io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ innerWire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -1763,7 +1819,7 @@ func skipRaft(data []byte) (n int, err error) { if innerWireType == 4 { break } - next, err := skipRaft(data[start:]) + next, err := skipRaft(dAtA[start:]) if err != nil { return 0, err } @@ -1787,54 +1843,58 @@ var ( ErrIntOverflowRaft = fmt.Errorf("proto: integer overflow") ) +func init() { proto.RegisterFile("raft.proto", fileDescriptorRaft) } + var fileDescriptorRaft = []byte{ - // 753 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x64, 0x53, 0xc1, 0x6e, 0xdb, 0x38, - 0x10, 0xb5, 0x64, 0xd9, 0xb2, 0x47, 0x89, 0xc3, 0x30, 0xde, 0x05, 0x11, 0x04, 0x5e, 0xaf, 0xb1, - 0x07, 0x23, 0x8b, 0x64, 0x77, 0x7d, 0xd8, 0xc3, 0xde, 0x12, 0x7b, 0x81, 0x04, 0x58, 0x07, 0x5b, - 0xc7, 0xe9, 0xa1, 0x45, 0x51, 0x30, 0x16, 0x2d, 0xbb, 0x8d, 0x44, 0x81, 0xa2, 0xd3, 0xe4, 0x52, - 0x14, 0xe8, 0xa1, 0x97, 0x7e, 0x40, 0x3f, 0x29, 0xc7, 0x7c, 0x41, 0xd1, 0xa4, 0x3f, 0x52, 0x90, - 0xa2, 0x6c, 0x29, 0xbe, 0x91, 0xef, 0x0d, 0x67, 0xde, 0xbc, 0x19, 0x02, 0x08, 0x3a, 0x95, 0x87, - 0xb1, 0xe0, 0x92, 0xe3, 0xaa, 0x3a, 0xc7, 0x97, 0xbb, 0xcd, 0x80, 0x07, 0x5c, 0x43, 0x7f, 0xa8, - 0x53, 0xca, 0x76, 0xde, 0x43, 0xe5, 0xdf, 0x48, 0x8a, 0x5b, 0xfc, 0x3b, 0x38, 0xe3, 0xdb, 0x98, - 0x11, 0xab, 0x6d, 0x75, 0x1b, 0xbd, 0xed, 0xc3, 0xf4, 0xd5, 0xa1, 0x26, 0x15, 0x71, 0xec, 0xdc, - 0x7d, 0xfd, 0xa5, 0x34, 0x72, 0xe4, 0x6d, 0xcc, 0x30, 0x01, 0x67, 0xcc, 0x44, 0x48, 0xec, 0xb6, - 0xd5, 0x75, 0x96, 0x0c, 0x13, 0x21, 0xde, 0x85, 0xca, 0x69, 0xe4, 0xb3, 0x1b, 0x52, 0xce, 0x51, - 0x95, 0xb9, 0x82, 0x30, 0x06, 0x67, 0x40, 0x25, 0x25, 0x4e, 0xdb, 0xea, 0x6e, 0x8c, 0x1c, 0x9f, - 0x4a, 0xda, 0xf9, 0x60, 0x01, 0x3a, 0x8f, 0x68, 0x9c, 0xcc, 0xb8, 0x1c, 0x32, 0x49, 0x15, 0x88, - 0xff, 0x06, 0x98, 0xf0, 0x68, 0xfa, 0x3a, 0x91, 0x54, 0xa6, 0x8a, 0xbc, 0x95, 0xa2, 0x3e, 0x8f, - 0xa6, 0xe7, 0x8a, 0x30, 0xc9, 0xeb, 0x93, 0x0c, 0x50, 0xc5, 0x75, 0xa5, 0x82, 0x2e, 0x53, 0x9c, - 0x80, 0x16, 0x58, 0xd0, 0xa5, 0x91, 0xce, 0x0b, 0xa8, 0x65, 0x0a, 0x94, 0x44, 0xa5, 0x40, 0xd7, - 0x34, 0x12, 0xf1, 0x3f, 0x50, 0x0b, 0x8d, 0x32, 0x9d, 0xd8, 0xeb, 0x91, 0x4c, 0xcb, 0x53, 0xe5, - 0x26, 0xef, 0x32, 0xbe, 0xf3, 0xb1, 0x0c, 0xee, 0x90, 0x25, 0x09, 0x0d, 0x18, 0x3e, 0x00, 0x6d, - 0x9e, 0x71, 0x78, 0x27, 0xcb, 0x61, 0xe8, 0x35, 0x8f, 0x9b, 0x60, 0x4b, 0x5e, 0xe8, 0xc4, 0x96, - 0x5c, 0xb5, 0x31, 0x15, 0xfc, 0x49, 0x1b, 0x0a, 0x59, 0x36, 0xe8, 0xac, 0xcd, 0xa4, 0x05, 0xee, - 0x15, 0x0f, 0xf4, 0xc0, 0x2a, 0x39, 0x32, 0x03, 0x57, 0xb6, 0x55, 0xd7, 0x6d, 0x3b, 0x00, 0x97, - 0x45, 0x52, 0xcc, 0x59, 0x42, 0xdc, 0x76, 0xb9, 0xeb, 0xf5, 0x36, 0x0b, 0x9b, 0x91, 0xa5, 0x32, - 0x31, 0x78, 0x0f, 0xaa, 0x13, 0x1e, 0x86, 0x73, 0x49, 0x6a, 0xb9, 0x5c, 0x06, 0xc3, 0x3d, 0xa8, - 0x25, 0xc6, 0x31, 0x52, 0xd7, 0x4e, 0xa2, 0xa7, 0x4e, 0x66, 0x0e, 0x66, 0x71, 0x2a, 0xa3, 0x60, - 0x6f, 0xd8, 0x44, 0x12, 0x68, 0x5b, 0xdd, 0x5a, 0x96, 0x31, 0xc5, 0xf0, 0x6f, 0x00, 0xe9, 0xe9, - 0x64, 0x1e, 0x49, 0xe2, 0xe5, 0x6a, 0xe6, 0xf0, 0xce, 0x2b, 0xa8, 0x9f, 0x50, 0xe1, 0xa7, 0x4b, - 0x92, 0xf9, 0x64, 0xad, 0xf9, 0x44, 0xc0, 0xb9, 0xe6, 0x92, 0x15, 0xb7, 0x5a, 0x21, 0xb9, 0xb6, - 0xca, 0xeb, 0x6d, 0x75, 0x7e, 0x85, 0xfa, 0x72, 0x29, 0x71, 0x13, 0x2a, 0x11, 0xf7, 0x59, 0x42, - 0xac, 0x76, 0xb9, 0xeb, 0x8c, 0xd2, 0x4b, 0xe7, 0xb3, 0x05, 0xa0, 0x62, 0xfa, 0x33, 0x1a, 0x05, - 0x7a, 0xb6, 0xa7, 0x83, 0x82, 0x02, 0x7b, 0x3e, 0xc0, 0x7f, 0x9a, 0x2f, 0x68, 0xeb, 0x05, 0xf9, - 0x39, 0xbf, 0xf0, 0xe9, 0xbb, 0xb5, 0x1d, 0xd9, 0x83, 0xea, 0x19, 0xf7, 0xd9, 0xe9, 0xa0, 0xa8, - 0x2b, 0xd2, 0x18, 0x26, 0xe0, 0xf6, 0x79, 0x24, 0xd9, 0x8d, 0x34, 0x5f, 0xce, 0x9d, 0xa4, 0xd7, - 0xfd, 0xbf, 0xa0, 0xbe, 0xfc, 0xd8, 0x78, 0x0b, 0x3c, 0x7d, 0x39, 0xe3, 0x22, 0xa4, 0x57, 0xa8, - 0x84, 0x77, 0x60, 0x4b, 0x03, 0xab, 0xc2, 0xc8, 0xda, 0xff, 0x64, 0x83, 0x97, 0x5b, 0x55, 0x0c, - 0x50, 0x1d, 0x26, 0xc1, 0xc9, 0x22, 0x46, 0x25, 0xec, 0x81, 0x3b, 0x4c, 0x82, 0x63, 0x46, 0x25, - 0xb2, 0xcc, 0xe5, 0x7f, 0xc1, 0x63, 0x64, 0x9b, 0xa8, 0xa3, 0x38, 0x46, 0x65, 0xdc, 0x00, 0x48, - 0xcf, 0x23, 0x96, 0xc4, 0xc8, 0x31, 0x81, 0xcf, 0xb9, 0x64, 0xa8, 0xa2, 0x44, 0x98, 0x8b, 0x66, - 0xab, 0x86, 0x55, 0x6b, 0x81, 0x5c, 0x8c, 0x60, 0x43, 0x15, 0x63, 0x54, 0xc8, 0x4b, 0x55, 0xa5, - 0x86, 0x9b, 0x80, 0xf2, 0x88, 0x7e, 0x54, 0xc7, 0x18, 0x1a, 0xc3, 0x24, 0xb8, 0x88, 0x04, 0xa3, - 0x93, 0x19, 0xbd, 0xbc, 0x62, 0x08, 0xf0, 0x36, 0x6c, 0x9a, 0x44, 0x6a, 0x40, 0x8b, 0x04, 0x79, - 0x26, 0xac, 0x3f, 0x63, 0x93, 0xb7, 0xcf, 0x16, 0x5c, 0x2c, 0x42, 0xb4, 0x81, 0x7f, 0x82, 0xed, - 0x61, 0x12, 0x8c, 0x05, 0x8d, 0x92, 0x29, 0x13, 0xff, 0x31, 0xea, 0x33, 0x81, 0x36, 0xcd, 0xeb, - 0xf1, 0x3c, 0x64, 0x7c, 0x21, 0xcf, 0xf8, 0x3b, 0xd4, 0xd8, 0x7f, 0x09, 0x8d, 0xe2, 0x48, 0xd4, - 0xdb, 0x15, 0x72, 0xe4, 0xfb, 0x6a, 0x26, 0xa8, 0x84, 0x09, 0x34, 0x57, 0xf0, 0x88, 0x85, 0xfc, - 0x9a, 0x69, 0xc6, 0x2a, 0x32, 0x17, 0xb1, 0x4f, 0x65, 0xca, 0xd8, 0xc7, 0xe4, 0xee, 0xa1, 0x55, - 0xba, 0x7f, 0x68, 0x95, 0xee, 0x1e, 0x5b, 0xd6, 0xfd, 0x63, 0xcb, 0xfa, 0xf6, 0xd8, 0xb2, 0xbe, - 0x7c, 0x6f, 0x95, 0x7e, 0x04, 0x00, 0x00, 0xff, 0xff, 0xb3, 0x85, 0x0b, 0xb6, 0xd4, 0x05, 0x00, - 0x00, + // 790 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x64, 0x54, 0xcd, 0x6e, 0xdb, 0x46, + 0x10, 0x16, 0x29, 0xea, 0x6f, 0x28, 0xcb, 0xab, 0xb5, 0x5a, 0x2c, 0x0c, 0x43, 0x55, 0x85, 0x1e, + 0x04, 0x17, 0x76, 0x5b, 0x1d, 0x7a, 0xe8, 0xcd, 0x96, 0x0a, 0x58, 0x40, 0x65, 0xb8, 0xb2, 0xdc, + 0x43, 0x83, 0x20, 0x58, 0x8b, 0x2b, 0x4a, 0x89, 0xc9, 0x25, 0x96, 0x2b, 0xc7, 0xbe, 0x04, 0x79, + 0x80, 0x3c, 0x40, 0x2e, 0x79, 0x1f, 0x1f, 0x0d, 0xe4, 0x1e, 0xc4, 0xce, 0x8b, 0x04, 0xbb, 0x5c, + 0x4a, 0x94, 0x74, 0xdb, 0xf9, 0xbe, 0xe1, 0xcc, 0x37, 0xdf, 0xce, 0x12, 0x40, 0xd0, 0xa9, 0x3c, + 0x8e, 0x04, 0x97, 0x1c, 0x17, 0xd5, 0x39, 0xba, 0xde, 0x6f, 0xf8, 0xdc, 0xe7, 0x1a, 0xfa, 0x4d, + 0x9d, 0x12, 0xb6, 0xfd, 0x0e, 0x0a, 0x7f, 0x87, 0x52, 0xdc, 0xe3, 0x5f, 0xc1, 0x19, 0xdf, 0x47, + 0x8c, 0x58, 0x2d, 0xab, 0x53, 0xeb, 0xd6, 0x8f, 0x93, 0xaf, 0x8e, 0x35, 0xa9, 0x88, 0x53, 0xe7, + 0xe1, 0xcb, 0x4f, 0xb9, 0x91, 0x4e, 0xc2, 0x04, 0x9c, 0x31, 0x13, 0x01, 0xb1, 0x5b, 0x56, 0xc7, + 0x59, 0x32, 0x4c, 0x04, 0x78, 0x1f, 0x0a, 0x83, 0xd0, 0x63, 0x77, 0x24, 0x9f, 0xa1, 0x12, 0x08, + 0x63, 0x70, 0xfa, 0x54, 0x52, 0xe2, 0xb4, 0xac, 0x4e, 0x75, 0xa4, 0xcf, 0xed, 0xf7, 0x16, 0xa0, + 0xcb, 0x90, 0x46, 0xf1, 0x8c, 0xcb, 0x21, 0x93, 0xd4, 0xa3, 0x92, 0xe2, 0x3f, 0x01, 0x26, 0x3c, + 0x9c, 0xbe, 0x8a, 0x25, 0x95, 0x89, 0x22, 0x77, 0xa5, 0xa8, 0xc7, 0xc3, 0xe9, 0xa5, 0x22, 0x4c, + 0xf1, 0xca, 0x24, 0x05, 0x54, 0xf3, 0xb9, 0x6e, 0x9e, 0xd5, 0x95, 0x40, 0x4a, 0xb2, 0x54, 0x92, + 0xb3, 0xba, 0x34, 0xd2, 0xfe, 0x1f, 0xca, 0xa9, 0x02, 0x25, 0x51, 0x29, 0xd0, 0x3d, 0xab, 0x23, + 0x7d, 0xc6, 0x7f, 0x41, 0x39, 0x30, 0xca, 0x74, 0x61, 0xb7, 0x4b, 0x52, 0x2d, 0x9b, 0xca, 0x4d, + 0xdd, 0x65, 0x7e, 0xfb, 0x53, 0x1e, 0x4a, 0x43, 0x16, 0xc7, 0xd4, 0x67, 0xf8, 0x08, 0x1c, 0xb9, + 0x72, 0x78, 0x2f, 0xad, 0x61, 0xe8, 0xac, 0xc7, 0x2a, 0x0d, 0x37, 0xc0, 0x96, 0x7c, 0x6d, 0x12, + 0x5b, 0x72, 0x35, 0xc6, 0x54, 0xf0, 0x8d, 0x31, 0x14, 0xb2, 0x1c, 0xd0, 0xd9, 0x1c, 0x10, 0x37, + 0xa1, 0x74, 0xc3, 0x7d, 0x7d, 0x61, 0x85, 0x0c, 0x99, 0x82, 0x2b, 0xdb, 0x8a, 0xdb, 0xb6, 0x1d, + 0x41, 0x89, 0x85, 0x52, 0xcc, 0x59, 0x4c, 0x4a, 0xad, 0x7c, 0xc7, 0xed, 0xee, 0xac, 0x6d, 0x46, + 0x5a, 0xca, 0xe4, 0xe0, 0x03, 0x28, 0x4e, 0x78, 0x10, 0xcc, 0x25, 0x29, 0x67, 0x6a, 0x19, 0x0c, + 0x77, 0xa1, 0x1c, 0x1b, 0xc7, 0x48, 0x45, 0x3b, 0x89, 0x36, 0x9d, 0x4c, 0x1d, 0x4c, 0xf3, 0x54, + 0x45, 0xc1, 0x5e, 0xb3, 0x89, 0x24, 0xd0, 0xb2, 0x3a, 0xe5, 0xb4, 0x62, 0x82, 0xe1, 0x5f, 0x00, + 0x92, 0xd3, 0xd9, 0x3c, 0x94, 0xc4, 0xcd, 0xf4, 0xcc, 0xe0, 0x98, 0x40, 0x69, 0xc2, 0x43, 0xc9, + 0xee, 0x24, 0xa9, 0xea, 0x8b, 0x4d, 0xc3, 0xf6, 0x4b, 0xa8, 0x9c, 0x51, 0xe1, 0x25, 0xeb, 0x93, + 0x3a, 0x68, 0x6d, 0x39, 0x48, 0xc0, 0xb9, 0xe5, 0x92, 0xad, 0xef, 0xbb, 0x42, 0x32, 0x03, 0xe7, + 0xb7, 0x07, 0x6e, 0xff, 0x0c, 0x95, 0xe5, 0xba, 0xe2, 0x06, 0x14, 0x42, 0xee, 0xb1, 0x98, 0x58, + 0xad, 0x7c, 0xc7, 0x19, 0x25, 0x41, 0xfb, 0x83, 0x05, 0xa0, 0x72, 0x7a, 0x33, 0x1a, 0xfa, 0xfa, + 0xd6, 0x07, 0xfd, 0x35, 0x05, 0xf6, 0xa0, 0x8f, 0x7f, 0x37, 0x8f, 0xd3, 0xd6, 0xab, 0xf3, 0x63, + 0xf6, 0x29, 0x24, 0xdf, 0x6d, 0xbd, 0xd0, 0x03, 0x28, 0x9e, 0x73, 0x8f, 0x0d, 0xfa, 0xeb, 0xba, + 0x12, 0x4c, 0x19, 0xd2, 0x33, 0x86, 0x24, 0x8f, 0x31, 0x0d, 0x0f, 0xff, 0x80, 0xca, 0xf2, 0xc9, + 0xe3, 0x5d, 0x70, 0x75, 0x70, 0xce, 0x45, 0x40, 0x6f, 0x50, 0x0e, 0xef, 0xc1, 0xae, 0x06, 0x56, + 0x8d, 0x91, 0x75, 0xf8, 0xd9, 0x06, 0x37, 0xb3, 0xc4, 0x18, 0xa0, 0x38, 0x8c, 0xfd, 0xb3, 0x45, + 0x84, 0x72, 0xd8, 0x85, 0xd2, 0x30, 0xf6, 0x4f, 0x19, 0x95, 0xc8, 0x32, 0xc1, 0x85, 0xe0, 0x11, + 0xb2, 0x4d, 0xd6, 0x49, 0x14, 0xa1, 0x3c, 0xae, 0x01, 0x24, 0xe7, 0x11, 0x8b, 0x23, 0xe4, 0x98, + 0xc4, 0xff, 0xb8, 0x64, 0xa8, 0xa0, 0x44, 0x98, 0x40, 0xb3, 0x45, 0xc3, 0xaa, 0x85, 0x41, 0x25, + 0x8c, 0xa0, 0xaa, 0x9a, 0x31, 0x2a, 0xe4, 0xb5, 0xea, 0x52, 0xc6, 0x0d, 0x40, 0x59, 0x44, 0x7f, + 0x54, 0xc1, 0x18, 0x6a, 0xc3, 0xd8, 0xbf, 0x0a, 0x05, 0xa3, 0x93, 0x19, 0xbd, 0xbe, 0x61, 0x08, + 0x70, 0x1d, 0x76, 0x4c, 0x21, 0x75, 0x41, 0x8b, 0x18, 0xb9, 0x26, 0xad, 0x37, 0x63, 0x93, 0x37, + 0xff, 0x2e, 0xb8, 0x58, 0x04, 0xa8, 0x8a, 0x7f, 0x80, 0xfa, 0x30, 0xf6, 0xc7, 0x82, 0x86, 0xf1, + 0x94, 0x89, 0x7f, 0x18, 0xf5, 0x98, 0x40, 0x3b, 0xe6, 0xeb, 0xf1, 0x3c, 0x60, 0x7c, 0x21, 0xcf, + 0xf9, 0x5b, 0x54, 0x33, 0x62, 0x46, 0x8c, 0x7a, 0xfa, 0x87, 0x87, 0x76, 0x8d, 0x98, 0x25, 0xa2, + 0xc5, 0x20, 0x33, 0xef, 0x85, 0x60, 0x7a, 0xc4, 0xba, 0xe9, 0x6a, 0x62, 0x9d, 0x83, 0x0f, 0x5f, + 0x40, 0x6d, 0xfd, 0x7a, 0x95, 0x8e, 0x15, 0x72, 0xe2, 0x79, 0xea, 0x2e, 0x51, 0x0e, 0x13, 0x68, + 0xac, 0xe0, 0x11, 0x0b, 0xf8, 0x2d, 0xd3, 0x8c, 0xb5, 0xce, 0x5c, 0x45, 0x1e, 0x95, 0x09, 0x63, + 0x9f, 0x92, 0x87, 0xa7, 0x66, 0xee, 0xf1, 0xa9, 0x99, 0x7b, 0x78, 0x6e, 0x5a, 0x8f, 0xcf, 0x4d, + 0xeb, 0xeb, 0x73, 0xd3, 0xfa, 0xf8, 0xad, 0x99, 0xfb, 0x1e, 0x00, 0x00, 0xff, 0xff, 0xcf, 0x30, + 0x01, 0x41, 0x3a, 0x06, 0x00, 0x00, } diff --git a/vendor/github.com/coreos/etcd/raft/raftpb/raft.proto b/vendor/github.com/coreos/etcd/raft/raftpb/raft.proto index 8cd630046..806a43634 100644 --- a/vendor/github.com/coreos/etcd/raft/raftpb/raft.proto +++ b/vendor/github.com/coreos/etcd/raft/raftpb/raft.proto @@ -48,6 +48,10 @@ enum MessageType { MsgCheckQuorum = 12; MsgTransferLeader = 13; MsgTimeoutNow = 14; + MsgReadIndex = 15; + MsgReadIndexResp = 16; + MsgPreVote = 17; + MsgPreVoteResp = 18; } message Message { @@ -62,6 +66,7 @@ message Message { optional Snapshot snapshot = 9 [(gogoproto.nullable) = false]; optional bool reject = 10 [(gogoproto.nullable) = false]; optional uint64 rejectHint = 11 [(gogoproto.nullable) = false]; + optional bytes context = 12; } message HardState { diff --git a/vendor/github.com/coreos/etcd/raft/rawnode.go b/vendor/github.com/coreos/etcd/raft/rawnode.go index 4cea62f64..b950d5169 100644 --- a/vendor/github.com/coreos/etcd/raft/rawnode.go +++ b/vendor/github.com/coreos/etcd/raft/rawnode.go @@ -66,6 +66,9 @@ func (rn *RawNode) commitReady(rd Ready) { if !IsEmptySnap(rd.Snapshot) { rn.raft.raftLog.stableSnapTo(rd.Snapshot.Metadata.Index) } + if len(rd.ReadStates) != 0 { + rn.raft.readStates = nil + } } // NewRawNode returns a new RawNode given configuration and a list of raft peers. @@ -103,9 +106,14 @@ func NewRawNode(config *Config, peers []Peer) (*RawNode, error) { r.addNode(peer.ID) } } + // Set the initial hard and soft states after performing all initialization. rn.prevSoftSt = r.softState() - rn.prevHardSt = r.hardState() + if lastIndex == 0 { + rn.prevHardSt = emptyState + } else { + rn.prevHardSt = r.hardState() + } return rn, nil } @@ -115,6 +123,18 @@ func (rn *RawNode) Tick() { rn.raft.tick() } +// TickQuiesced advances the internal logical clock by a single tick without +// performing any other state machine processing. It allows the caller to avoid +// periodic heartbeats and elections when all of the peers in a Raft group are +// known to be at the same state. Expected usage is to periodically invoke Tick +// or TickQuiesced depending on whether the group is "active" or "quiesced". +// +// WARNING: Be very careful about using this method as it subverts the Raft +// state machine. You should probably be using Tick instead. +func (rn *RawNode) TickQuiesced() { + rn.raft.electionElapsed++ +} + // Campaign causes this RawNode to transition to candidate state. func (rn *RawNode) Campaign() error { return rn.raft.Step(pb.Message{ @@ -200,6 +220,9 @@ func (rn *RawNode) HasReady() bool { if len(r.msgs) > 0 || len(r.raftLog.unstableEntries()) > 0 || r.raftLog.hasNextEnts() { return true } + if len(r.readStates) != 0 { + return true + } return false } @@ -231,3 +254,11 @@ func (rn *RawNode) ReportSnapshot(id uint64, status SnapshotStatus) { func (rn *RawNode) TransferLeader(transferee uint64) { _ = rn.raft.Step(pb.Message{Type: pb.MsgTransferLeader, From: transferee}) } + +// ReadIndex requests a read state. The read state will be set in ready. +// Read State has a read index. Once the application advances further than the read +// index, any linearizable read requests issued before the read request can be +// processed safely. The read state will have the same rctx attached. +func (rn *RawNode) ReadIndex(rctx []byte) { + _ = rn.raft.Step(pb.Message{Type: pb.MsgReadIndex, Entries: []pb.Entry{{Data: rctx}}}) +} diff --git a/vendor/github.com/coreos/etcd/raft/read_only.go b/vendor/github.com/coreos/etcd/raft/read_only.go new file mode 100644 index 000000000..d0085237e --- /dev/null +++ b/vendor/github.com/coreos/etcd/raft/read_only.go @@ -0,0 +1,118 @@ +// Copyright 2016 The etcd Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package raft + +import pb "github.com/coreos/etcd/raft/raftpb" + +// ReadState provides state for read only query. +// It's caller's responsibility to call ReadIndex first before getting +// this state from ready, It's also caller's duty to differentiate if this +// state is what it requests through RequestCtx, eg. given a unique id as +// RequestCtx +type ReadState struct { + Index uint64 + RequestCtx []byte +} + +type readIndexStatus struct { + req pb.Message + index uint64 + acks map[uint64]struct{} +} + +type readOnly struct { + option ReadOnlyOption + pendingReadIndex map[string]*readIndexStatus + readIndexQueue []string +} + +func newReadOnly(option ReadOnlyOption) *readOnly { + return &readOnly{ + option: option, + pendingReadIndex: make(map[string]*readIndexStatus), + } +} + +// addRequest adds a read only reuqest into readonly struct. +// `index` is the commit index of the raft state machine when it received +// the read only request. +// `m` is the original read only request message from the local or remote node. +func (ro *readOnly) addRequest(index uint64, m pb.Message) { + ctx := string(m.Entries[0].Data) + if _, ok := ro.pendingReadIndex[ctx]; ok { + return + } + ro.pendingReadIndex[ctx] = &readIndexStatus{index: index, req: m, acks: make(map[uint64]struct{})} + ro.readIndexQueue = append(ro.readIndexQueue, ctx) +} + +// recvAck notifies the readonly struct that the raft state machine received +// an acknowledgment of the heartbeat that attached with the read only request +// context. +func (ro *readOnly) recvAck(m pb.Message) int { + rs, ok := ro.pendingReadIndex[string(m.Context)] + if !ok { + return 0 + } + + rs.acks[m.From] = struct{}{} + // add one to include an ack from local node + return len(rs.acks) + 1 +} + +// advance advances the read only request queue kept by the readonly struct. +// It dequeues the requests until it finds the read only request that has +// the same context as the given `m`. +func (ro *readOnly) advance(m pb.Message) []*readIndexStatus { + var ( + i int + found bool + ) + + ctx := string(m.Context) + rss := []*readIndexStatus{} + + for _, okctx := range ro.readIndexQueue { + i++ + rs, ok := ro.pendingReadIndex[okctx] + if !ok { + panic("cannot find corresponding read state from pending map") + } + rss = append(rss, rs) + if okctx == ctx { + found = true + break + } + } + + if found { + ro.readIndexQueue = ro.readIndexQueue[i:] + for _, rs := range rss { + delete(ro.pendingReadIndex, string(rs.req.Entries[0].Data)) + } + return rss + } + + return nil +} + +// lastPendingRequestCtx returns the context of the last pending read only +// request in readonly struct. +func (ro *readOnly) lastPendingRequestCtx() string { + if len(ro.readIndexQueue) == 0 { + return "" + } + return ro.readIndexQueue[len(ro.readIndexQueue)-1] +} diff --git a/vendor/github.com/coreos/etcd/raft/storage.go b/vendor/github.com/coreos/etcd/raft/storage.go index 37f6b378e..69c3a7d90 100644 --- a/vendor/github.com/coreos/etcd/raft/storage.go +++ b/vendor/github.com/coreos/etcd/raft/storage.go @@ -98,6 +98,8 @@ func (ms *MemoryStorage) InitialState() (pb.HardState, pb.ConfState, error) { // SetHardState saves the current HardState. func (ms *MemoryStorage) SetHardState(st pb.HardState) error { + ms.Lock() + defer ms.Unlock() ms.hardState = st return nil } @@ -130,6 +132,9 @@ func (ms *MemoryStorage) Term(i uint64) (uint64, error) { if i < offset { return 0, ErrCompacted } + if int(i-offset) >= len(ms.ents) { + return 0, ErrUnavailable + } return ms.ents[i-offset].Term, nil } @@ -168,7 +173,13 @@ func (ms *MemoryStorage) ApplySnapshot(snap pb.Snapshot) error { ms.Lock() defer ms.Unlock() - // TODO: return ErrSnapOutOfDate? + //handle check for old snapshot being applied + msIndex := ms.snapshot.Metadata.Index + snapIndex := snap.Metadata.Index + if msIndex >= snapIndex { + return ErrSnapOutOfDate + } + ms.snapshot = snap ms.ents = []pb.Entry{{Term: snap.Metadata.Term, Index: snap.Metadata.Index}} return nil diff --git a/vendor/github.com/coreos/etcd/raft/util.go b/vendor/github.com/coreos/etcd/raft/util.go index c57855a17..f4141fe65 100644 --- a/vendor/github.com/coreos/etcd/raft/util.go +++ b/vendor/github.com/coreos/etcd/raft/util.go @@ -48,11 +48,23 @@ func max(a, b uint64) uint64 { func IsLocalMsg(msgt pb.MessageType) bool { return msgt == pb.MsgHup || msgt == pb.MsgBeat || msgt == pb.MsgUnreachable || - msgt == pb.MsgSnapStatus || msgt == pb.MsgCheckQuorum || msgt == pb.MsgTransferLeader + msgt == pb.MsgSnapStatus || msgt == pb.MsgCheckQuorum } func IsResponseMsg(msgt pb.MessageType) bool { - return msgt == pb.MsgAppResp || msgt == pb.MsgVoteResp || msgt == pb.MsgHeartbeatResp || msgt == pb.MsgUnreachable + return msgt == pb.MsgAppResp || msgt == pb.MsgVoteResp || msgt == pb.MsgHeartbeatResp || msgt == pb.MsgUnreachable || msgt == pb.MsgPreVoteResp +} + +// voteResponseType maps vote and prevote message types to their corresponding responses. +func voteRespMsgType(msgt pb.MessageType) pb.MessageType { + switch msgt { + case pb.MsgVote: + return pb.MsgVoteResp + case pb.MsgPreVote: + return pb.MsgPreVoteResp + default: + panic(fmt.Sprintf("not a vote message: %s", msgt)) + } } // EntryFormatter can be implemented by the application to provide human-readable formatting diff --git a/vendor/github.com/coreos/etcd/rafthttp/coder.go b/vendor/github.com/coreos/etcd/rafthttp/coder.go index 2d2d24c9b..86ede972e 100644 --- a/vendor/github.com/coreos/etcd/rafthttp/coder.go +++ b/vendor/github.com/coreos/etcd/rafthttp/coder.go @@ -18,7 +18,7 @@ import "github.com/coreos/etcd/raft/raftpb" type encoder interface { // encode encodes the given message to an output stream. - encode(m raftpb.Message) error + encode(m *raftpb.Message) error } type decoder interface { diff --git a/vendor/github.com/coreos/etcd/rafthttp/http.go b/vendor/github.com/coreos/etcd/rafthttp/http.go index 76b74bd8a..471028a61 100644 --- a/vendor/github.com/coreos/etcd/rafthttp/http.go +++ b/vendor/github.com/coreos/etcd/rafthttp/http.go @@ -104,6 +104,7 @@ func (h *pipelineHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { if err != nil { plog.Errorf("failed to read raft message (%v)", err) http.Error(w, "error reading raft message", http.StatusBadRequest) + recvFailures.WithLabelValues(r.RemoteAddr).Inc() return } @@ -111,6 +112,7 @@ func (h *pipelineHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { if err := m.Unmarshal(b); err != nil { plog.Errorf("failed to unmarshal raft message (%v)", err) http.Error(w, "error unmarshaling raft message", http.StatusBadRequest) + recvFailures.WithLabelValues(r.RemoteAddr).Inc() return } @@ -123,6 +125,9 @@ func (h *pipelineHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { default: plog.Warningf("failed to process raft message (%v)", err) http.Error(w, "error processing raft message", http.StatusInternalServerError) + w.(http.Flusher).Flush() + // disconnect the http stream + panic(err) } return } @@ -183,6 +188,7 @@ func (h *snapshotHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { msg := fmt.Sprintf("failed to decode raft message (%v)", err) plog.Errorf(msg) http.Error(w, msg, http.StatusBadRequest) + recvFailures.WithLabelValues(r.RemoteAddr).Inc() return } diff --git a/vendor/github.com/coreos/etcd/rafthttp/metrics.go b/vendor/github.com/coreos/etcd/rafthttp/metrics.go index e9550c3bb..320bfe726 100644 --- a/vendor/github.com/coreos/etcd/rafthttp/metrics.go +++ b/vendor/github.com/coreos/etcd/rafthttp/metrics.go @@ -16,7 +16,6 @@ package rafthttp import "github.com/prometheus/client_golang/prometheus" -// TODO: record write/recv failures. var ( sentBytes = prometheus.NewCounterVec(prometheus.CounterOpts{ Namespace: "etcd", @@ -36,6 +35,24 @@ var ( []string{"From"}, ) + sentFailures = prometheus.NewCounterVec(prometheus.CounterOpts{ + Namespace: "etcd", + Subsystem: "network", + Name: "peer_sent_failures_total", + Help: "The total number of send failures from peers.", + }, + []string{"To"}, + ) + + recvFailures = prometheus.NewCounterVec(prometheus.CounterOpts{ + Namespace: "etcd", + Subsystem: "network", + Name: "peer_received_failures_total", + Help: "The total number of receive failures from peers.", + }, + []string{"From"}, + ) + rtts = prometheus.NewHistogramVec(prometheus.HistogramOpts{ Namespace: "etcd", Subsystem: "network", @@ -50,5 +67,7 @@ var ( func init() { prometheus.MustRegister(sentBytes) prometheus.MustRegister(receivedBytes) + prometheus.MustRegister(sentFailures) + prometheus.MustRegister(recvFailures) prometheus.MustRegister(rtts) } diff --git a/vendor/github.com/coreos/etcd/rafthttp/msg_codec.go b/vendor/github.com/coreos/etcd/rafthttp/msg_codec.go index b6c97e362..bf1f6bc00 100644 --- a/vendor/github.com/coreos/etcd/rafthttp/msg_codec.go +++ b/vendor/github.com/coreos/etcd/rafthttp/msg_codec.go @@ -16,6 +16,7 @@ package rafthttp import ( "encoding/binary" + "errors" "io" "github.com/coreos/etcd/pkg/pbutil" @@ -28,11 +29,11 @@ type messageEncoder struct { w io.Writer } -func (enc *messageEncoder) encode(m raftpb.Message) error { +func (enc *messageEncoder) encode(m *raftpb.Message) error { if err := binary.Write(enc.w, binary.BigEndian, uint64(m.Size())); err != nil { return err } - _, err := enc.w.Write(pbutil.MustMarshal(&m)) + _, err := enc.w.Write(pbutil.MustMarshal(m)) return err } @@ -41,12 +42,20 @@ type messageDecoder struct { r io.Reader } +var ( + readBytesLimit uint64 = 512 * 1024 * 1024 // 512 MB + ErrExceedSizeLimit = errors.New("rafthttp: error limit exceeded") +) + func (dec *messageDecoder) decode() (raftpb.Message, error) { var m raftpb.Message var l uint64 if err := binary.Read(dec.r, binary.BigEndian, &l); err != nil { return m, err } + if l > readBytesLimit { + return m, ErrExceedSizeLimit + } buf := make([]byte, int(l)) if _, err := io.ReadFull(dec.r, buf); err != nil { return m, err diff --git a/vendor/github.com/coreos/etcd/rafthttp/msgappv2_codec.go b/vendor/github.com/coreos/etcd/rafthttp/msgappv2_codec.go index e61bd98c2..013ffe7c7 100644 --- a/vendor/github.com/coreos/etcd/rafthttp/msgappv2_codec.go +++ b/vendor/github.com/coreos/etcd/rafthttp/msgappv2_codec.go @@ -82,7 +82,7 @@ func newMsgAppV2Encoder(w io.Writer, fs *stats.FollowerStats) *msgAppV2Encoder { } } -func (enc *msgAppV2Encoder) encode(m raftpb.Message) error { +func (enc *msgAppV2Encoder) encode(m *raftpb.Message) error { start := time.Now() switch { case isLinkHeartbeatMessage(m): @@ -135,7 +135,7 @@ func (enc *msgAppV2Encoder) encode(m raftpb.Message) error { return err } // write message - if _, err := enc.w.Write(pbutil.MustMarshal(&m)); err != nil { + if _, err := enc.w.Write(pbutil.MustMarshal(m)); err != nil { return err } diff --git a/vendor/github.com/coreos/etcd/rafthttp/peer.go b/vendor/github.com/coreos/etcd/rafthttp/peer.go index 3bc8b5190..a82d7beed 100644 --- a/vendor/github.com/coreos/etcd/rafthttp/peer.go +++ b/vendor/github.com/coreos/etcd/rafthttp/peer.go @@ -106,7 +106,6 @@ type peer struct { msgAppV2Reader *streamReader msgAppReader *streamReader - sendc chan raftpb.Message recvc chan raftpb.Message propc chan raftpb.Message @@ -145,7 +144,6 @@ func startPeer(transport *Transport, urls types.URLs, peerID types.ID, fs *stats writer: startStreamWriter(peerID, status, fs, r), pipeline: pipeline, snapSender: newSnapshotSender(transport, picker, peerID, status), - sendc: make(chan raftpb.Message), recvc: make(chan raftpb.Message, recvBufSize), propc: make(chan raftpb.Message, maxPendingProposals), stopc: make(chan struct{}), diff --git a/vendor/github.com/coreos/etcd/rafthttp/pipeline.go b/vendor/github.com/coreos/etcd/rafthttp/pipeline.go index 4774c91b8..ccd9eb786 100644 --- a/vendor/github.com/coreos/etcd/rafthttp/pipeline.go +++ b/vendor/github.com/coreos/etcd/rafthttp/pipeline.go @@ -93,6 +93,7 @@ func (p *pipeline) handle() { if isMsgSnap(m) { p.raft.ReportSnapshot(m.To, raft.SnapshotFailure) } + sentFailures.WithLabelValues(types.ID(m.To).String()).Inc() continue } @@ -117,7 +118,7 @@ func (p *pipeline) post(data []byte) (err error) { req := createPostRequest(u, RaftPrefix, bytes.NewBuffer(data), "application/protobuf", p.tr.URLs, p.tr.ID, p.tr.ClusterID) done := make(chan struct{}, 1) - cancel := httputil.RequestCanceler(p.tr.pipelineRt, req) + cancel := httputil.RequestCanceler(req) go func() { select { case <-done: diff --git a/vendor/github.com/coreos/etcd/rafthttp/probing_status.go b/vendor/github.com/coreos/etcd/rafthttp/probing_status.go index a0859a4cb..c7a3c7ab9 100644 --- a/vendor/github.com/coreos/etcd/rafthttp/probing_status.go +++ b/vendor/github.com/coreos/etcd/rafthttp/probing_status.go @@ -25,6 +25,7 @@ var ( // Or the connection will time-out. proberInterval = ConnReadTimeout - time.Second statusMonitoringInterval = 30 * time.Second + statusErrorInterval = 5 * time.Second ) func addPeerToProber(p probing.Prober, id string, us []string) { @@ -44,11 +45,16 @@ func addPeerToProber(p probing.Prober, id string, us []string) { } func monitorProbingStatus(s probing.Status, id string) { + // set the first interval short to log error early. + interval := statusErrorInterval for { select { - case <-time.After(statusMonitoringInterval): + case <-time.After(interval): if !s.Health() { - plog.Warningf("health check for peer %s failed", id) + plog.Warningf("health check for peer %s could not connect: %v", id, s.Err()) + interval = statusErrorInterval + } else { + interval = statusMonitoringInterval } if s.ClockDiff() > time.Second { plog.Warningf("the clock difference against peer %s is too high [%v > %v]", id, s.ClockDiff(), time.Second) diff --git a/vendor/github.com/coreos/etcd/rafthttp/remote.go b/vendor/github.com/coreos/etcd/rafthttp/remote.go index f83f4ab82..c62c81823 100644 --- a/vendor/github.com/coreos/etcd/rafthttp/remote.go +++ b/vendor/github.com/coreos/etcd/rafthttp/remote.go @@ -59,3 +59,11 @@ func (g *remote) send(m raftpb.Message) { func (g *remote) stop() { g.pipeline.stop() } + +func (g *remote) Pause() { + g.stop() +} + +func (g *remote) Resume() { + g.pipeline.start() +} diff --git a/vendor/github.com/coreos/etcd/rafthttp/snapshot_sender.go b/vendor/github.com/coreos/etcd/rafthttp/snapshot_sender.go index 615e408e3..105b33072 100644 --- a/vendor/github.com/coreos/etcd/rafthttp/snapshot_sender.go +++ b/vendor/github.com/coreos/etcd/rafthttp/snapshot_sender.go @@ -91,6 +91,7 @@ func (s *snapshotSender) send(merged snap.Message) { // machine knows about it, it would pause a while and retry sending // new snapshot message. s.r.ReportSnapshot(m.To, raft.SnapshotFailure) + sentFailures.WithLabelValues(types.ID(m.To).String()).Inc() return } s.status.activate() @@ -103,7 +104,7 @@ func (s *snapshotSender) send(merged snap.Message) { // post posts the given request. // It returns nil when request is sent out and processed successfully. func (s *snapshotSender) post(req *http.Request) (err error) { - cancel := httputil.RequestCanceler(s.tr.pipelineRt, req) + cancel := httputil.RequestCanceler(req) type responseAndError struct { resp *http.Response @@ -143,7 +144,7 @@ func createSnapBody(merged snap.Message) io.ReadCloser { buf := new(bytes.Buffer) enc := &messageEncoder{w: buf} // encode raft message - if err := enc.encode(merged.Message); err != nil { + if err := enc.encode(&merged.Message); err != nil { plog.Panicf("encode message error (%v)", err) } diff --git a/vendor/github.com/coreos/etcd/rafthttp/stream.go b/vendor/github.com/coreos/etcd/rafthttp/stream.go index 748770726..e69a44ff6 100644 --- a/vendor/github.com/coreos/etcd/rafthttp/stream.go +++ b/vendor/github.com/coreos/etcd/rafthttp/stream.go @@ -50,6 +50,7 @@ var ( "2.2.0": {streamTypeMsgAppV2, streamTypeMessage}, "2.3.0": {streamTypeMsgAppV2, streamTypeMessage}, "3.0.0": {streamTypeMsgAppV2, streamTypeMessage}, + "3.1.0": {streamTypeMsgAppV2, streamTypeMessage}, } ) @@ -85,7 +86,7 @@ var ( linkHeartbeatMessage = raftpb.Message{Type: raftpb.MsgHeartbeat} ) -func isLinkHeartbeatMessage(m raftpb.Message) bool { +func isLinkHeartbeatMessage(m *raftpb.Message) bool { return m.Type == raftpb.MsgHeartbeat && m.From == 0 && m.To == 0 } @@ -147,7 +148,7 @@ func (cw *streamWriter) run() { for { select { case <-heartbeatc: - err := enc.encode(linkHeartbeatMessage) + err := enc.encode(&linkHeartbeatMessage) unflushed += linkHeartbeatMessage.Size() if err == nil { flusher.Flush() @@ -159,12 +160,13 @@ func (cw *streamWriter) run() { cw.status.deactivate(failureType{source: t.String(), action: "heartbeat"}, err.Error()) + sentFailures.WithLabelValues(cw.peerID.String()).Inc() cw.close() plog.Warningf("lost the TCP streaming connection with peer %s (%s writer)", cw.peerID, t) heartbeatc, msgc = nil, nil case m := <-msgc: - err := enc.encode(m) + err := enc.encode(&m) if err == nil { unflushed += m.Size() @@ -185,11 +187,11 @@ func (cw *streamWriter) run() { plog.Warningf("lost the TCP streaming connection with peer %s (%s writer)", cw.peerID, t) heartbeatc, msgc = nil, nil cw.r.ReportUnreachable(m.To) + sentFailures.WithLabelValues(cw.peerID.String()).Inc() case conn := <-cw.connc: - if cw.close() { - plog.Warningf("closed an existing TCP streaming connection with peer %s (%s writer)", cw.peerID, t) - } + cw.mu.Lock() + closed := cw.closeUnlocked() t = conn.t switch conn.t { case streamTypeMsgAppV2: @@ -201,19 +203,22 @@ func (cw *streamWriter) run() { } flusher = conn.Flusher unflushed = 0 - cw.mu.Lock() cw.status.activate() cw.closer = conn.Closer cw.working = true cw.mu.Unlock() + + if closed { + plog.Warningf("closed an existing TCP streaming connection with peer %s (%s writer)", cw.peerID, t) + } plog.Infof("established a TCP streaming connection with peer %s (%s writer)", cw.peerID, t) heartbeatc, msgc = tickc, cw.msgc case <-cw.stopc: if cw.close() { plog.Infof("closed the TCP streaming connection with peer %s (%s writer)", cw.peerID, t) } - close(cw.done) plog.Infof("stopped streaming with peer %s (writer)", cw.peerID) + close(cw.done) return } } @@ -228,6 +233,10 @@ func (cw *streamWriter) writec() (chan<- raftpb.Message, bool) { func (cw *streamWriter) close() bool { cw.mu.Lock() defer cw.mu.Unlock() + return cw.closeUnlocked() +} + +func (cw *streamWriter) closeUnlocked() bool { if !cw.working { return false } @@ -315,8 +324,8 @@ func (cr *streamReader) run() { // overhead when retry. case <-time.After(100 * time.Millisecond): case <-cr.stopc: - close(cr.done) plog.Infof("stopped streaming with peer %s (%s reader)", cr.peerID, t) + close(cr.done) return } } @@ -364,7 +373,7 @@ func (cr *streamReader) decodeLoop(rc io.ReadCloser, t streamType) error { continue } - if isLinkHeartbeatMessage(m) { + if isLinkHeartbeatMessage(&m) { // raft is not interested in link layer // heartbeat message, so we should ignore // it. @@ -383,6 +392,7 @@ func (cr *streamReader) decodeLoop(rc io.ReadCloser, t streamType) error { plog.MergeWarningf("dropped internal raft message from %s since receiving buffer is full (overloaded network)", types.ID(m.From)) } plog.Debugf("dropped %s from %s since receiving buffer is full", m.Type, types.ID(m.From)) + recvFailures.WithLabelValues(types.ID(m.From).String()).Inc() } } } @@ -423,7 +433,7 @@ func (cr *streamReader) dial(t streamType) (io.ReadCloser, error) { return nil, fmt.Errorf("stream reader is stopped") default: } - cr.cancel = httputil.RequestCanceler(cr.tr.streamRt, req) + cr.cancel = httputil.RequestCanceler(req) cr.mu.Unlock() resp, err := cr.tr.streamRt.RoundTrip(req) @@ -444,18 +454,14 @@ func (cr *streamReader) dial(t streamType) (io.ReadCloser, error) { case http.StatusGone: httputil.GracefulClose(resp) cr.picker.unreachable(u) - err := fmt.Errorf("the member has been permanently removed from the cluster") - select { - case cr.errorc <- err: - default: - } - return nil, err + reportCriticalError(errMemberRemoved, cr.errorc) + return nil, errMemberRemoved case http.StatusOK: return resp.Body, nil case http.StatusNotFound: httputil.GracefulClose(resp) cr.picker.unreachable(u) - return nil, fmt.Errorf("peer %s faild to fine local node %s", cr.peerID, cr.tr.ID) + return nil, fmt.Errorf("peer %s failed to find local node %s", cr.peerID, cr.tr.ID) case http.StatusPreconditionFailed: b, err := ioutil.ReadAll(resp.Body) if err != nil { diff --git a/vendor/github.com/coreos/etcd/rafthttp/transport.go b/vendor/github.com/coreos/etcd/rafthttp/transport.go index a7692d3b9..1f0b46836 100644 --- a/vendor/github.com/coreos/etcd/rafthttp/transport.go +++ b/vendor/github.com/coreos/etcd/rafthttp/transport.go @@ -206,6 +206,36 @@ func (t *Transport) Stop() { t.remotes = nil } +// CutPeer drops messages to the specified peer. +func (t *Transport) CutPeer(id types.ID) { + t.mu.RLock() + p, pok := t.peers[id] + g, gok := t.remotes[id] + t.mu.RUnlock() + + if pok { + p.(Pausable).Pause() + } + if gok { + g.Pause() + } +} + +// MendPeer recovers the message dropping behavior of the given peer. +func (t *Transport) MendPeer(id types.ID) { + t.mu.RLock() + p, pok := t.peers[id] + g, gok := t.remotes[id] + t.mu.RUnlock() + + if pok { + p.(Pausable).Resume() + } + if gok { + g.Resume() + } +} + func (t *Transport) AddRemote(id types.ID, us []string) { t.mu.Lock() defer t.mu.Unlock() diff --git a/vendor/github.com/coreos/etcd/snap/db.go b/vendor/github.com/coreos/etcd/snap/db.go index 743deac1e..ae3c743f8 100644 --- a/vendor/github.com/coreos/etcd/snap/db.go +++ b/vendor/github.com/coreos/etcd/snap/db.go @@ -19,7 +19,7 @@ import ( "io" "io/ioutil" "os" - "path" + "path/filepath" "github.com/coreos/etcd/pkg/fileutil" ) @@ -41,7 +41,7 @@ func (s *Snapshotter) SaveDBFrom(r io.Reader, id uint64) (int64, error) { os.Remove(f.Name()) return n, err } - fn := path.Join(s.dir, fmt.Sprintf("%016x.snap.db", id)) + fn := filepath.Join(s.dir, fmt.Sprintf("%016x.snap.db", id)) if fileutil.Exist(fn) { os.Remove(f.Name()) return n, nil @@ -67,7 +67,7 @@ func (s *Snapshotter) DBFilePath(id uint64) (string, error) { wfn := fmt.Sprintf("%016x.snap.db", id) for _, fn := range fns { if fn == wfn { - return path.Join(s.dir, fn), nil + return filepath.Join(s.dir, fn), nil } } return "", fmt.Errorf("snap: snapshot file doesn't exist") 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 f9ef5077d..130e2277c 100644 --- a/vendor/github.com/coreos/etcd/snap/snappb/snap.pb.go +++ b/vendor/github.com/coreos/etcd/snap/snappb/snap.pb.go @@ -30,7 +30,9 @@ var _ = math.Inf // This is a compile-time assertion to ensure that this generated file // is compatible with the proto package it is being compiled against. -const _ = proto.ProtoPackageIsVersion1 +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package type Snapshot struct { Crc uint32 `protobuf:"varint,1,opt,name=crc" json:"crc"` @@ -46,61 +48,61 @@ func (*Snapshot) Descriptor() ([]byte, []int) { return fileDescriptorSnap, []int func init() { proto.RegisterType((*Snapshot)(nil), "snappb.snapshot") } -func (m *Snapshot) Marshal() (data []byte, err error) { +func (m *Snapshot) Marshal() (dAtA []byte, err error) { size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) if err != nil { return nil, err } - return data[:n], nil + return dAtA[:n], nil } -func (m *Snapshot) MarshalTo(data []byte) (int, error) { +func (m *Snapshot) MarshalTo(dAtA []byte) (int, error) { var i int _ = i var l int _ = l - data[i] = 0x8 + dAtA[i] = 0x8 i++ - i = encodeVarintSnap(data, i, uint64(m.Crc)) + i = encodeVarintSnap(dAtA, i, uint64(m.Crc)) if m.Data != nil { - data[i] = 0x12 + dAtA[i] = 0x12 i++ - i = encodeVarintSnap(data, i, uint64(len(m.Data))) - i += copy(data[i:], m.Data) + i = encodeVarintSnap(dAtA, i, uint64(len(m.Data))) + i += copy(dAtA[i:], m.Data) } if m.XXX_unrecognized != nil { - i += copy(data[i:], m.XXX_unrecognized) + i += copy(dAtA[i:], m.XXX_unrecognized) } return i, nil } -func encodeFixed64Snap(data []byte, offset int, v uint64) int { - data[offset] = uint8(v) - data[offset+1] = uint8(v >> 8) - data[offset+2] = uint8(v >> 16) - data[offset+3] = uint8(v >> 24) - data[offset+4] = uint8(v >> 32) - data[offset+5] = uint8(v >> 40) - data[offset+6] = uint8(v >> 48) - data[offset+7] = uint8(v >> 56) +func encodeFixed64Snap(dAtA []byte, offset int, v uint64) int { + dAtA[offset] = uint8(v) + dAtA[offset+1] = uint8(v >> 8) + dAtA[offset+2] = uint8(v >> 16) + dAtA[offset+3] = uint8(v >> 24) + dAtA[offset+4] = uint8(v >> 32) + dAtA[offset+5] = uint8(v >> 40) + dAtA[offset+6] = uint8(v >> 48) + dAtA[offset+7] = uint8(v >> 56) return offset + 8 } -func encodeFixed32Snap(data []byte, offset int, v uint32) int { - data[offset] = uint8(v) - data[offset+1] = uint8(v >> 8) - data[offset+2] = uint8(v >> 16) - data[offset+3] = uint8(v >> 24) +func encodeFixed32Snap(dAtA []byte, offset int, v uint32) int { + dAtA[offset] = uint8(v) + dAtA[offset+1] = uint8(v >> 8) + dAtA[offset+2] = uint8(v >> 16) + dAtA[offset+3] = uint8(v >> 24) return offset + 4 } -func encodeVarintSnap(data []byte, offset int, v uint64) int { +func encodeVarintSnap(dAtA []byte, offset int, v uint64) int { for v >= 1<<7 { - data[offset] = uint8(v&0x7f | 0x80) + dAtA[offset] = uint8(v&0x7f | 0x80) v >>= 7 offset++ } - data[offset] = uint8(v) + dAtA[offset] = uint8(v) return offset + 1 } func (m *Snapshot) Size() (n int) { @@ -130,8 +132,8 @@ func sovSnap(x uint64) (n int) { func sozSnap(x uint64) (n int) { return sovSnap(uint64((x << 1) ^ uint64((int64(x) >> 63)))) } -func (m *Snapshot) Unmarshal(data []byte) error { - l := len(data) +func (m *Snapshot) Unmarshal(dAtA []byte) error { + l := len(dAtA) iNdEx := 0 for iNdEx < l { preIndex := iNdEx @@ -143,7 +145,7 @@ func (m *Snapshot) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -171,7 +173,7 @@ func (m *Snapshot) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ m.Crc |= (uint32(b) & 0x7F) << shift if b < 0x80 { @@ -190,7 +192,7 @@ func (m *Snapshot) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ byteLen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -204,14 +206,14 @@ func (m *Snapshot) Unmarshal(data []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Data = append(m.Data[:0], data[iNdEx:postIndex]...) + m.Data = append(m.Data[:0], dAtA[iNdEx:postIndex]...) if m.Data == nil { m.Data = []byte{} } iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skipSnap(data[iNdEx:]) + skippy, err := skipSnap(dAtA[iNdEx:]) if err != nil { return err } @@ -221,7 +223,7 @@ func (m *Snapshot) Unmarshal(data []byte) error { if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF } - m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) iNdEx += skippy } } @@ -231,8 +233,8 @@ func (m *Snapshot) Unmarshal(data []byte) error { } return nil } -func skipSnap(data []byte) (n int, err error) { - l := len(data) +func skipSnap(dAtA []byte) (n int, err error) { + l := len(dAtA) iNdEx := 0 for iNdEx < l { var wire uint64 @@ -243,7 +245,7 @@ func skipSnap(data []byte) (n int, err error) { if iNdEx >= l { return 0, io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -261,7 +263,7 @@ func skipSnap(data []byte) (n int, err error) { return 0, io.ErrUnexpectedEOF } iNdEx++ - if data[iNdEx-1] < 0x80 { + if dAtA[iNdEx-1] < 0x80 { break } } @@ -278,7 +280,7 @@ func skipSnap(data []byte) (n int, err error) { if iNdEx >= l { return 0, io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ length |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -301,7 +303,7 @@ func skipSnap(data []byte) (n int, err error) { if iNdEx >= l { return 0, io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ innerWire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -312,7 +314,7 @@ func skipSnap(data []byte) (n int, err error) { if innerWireType == 4 { break } - next, err := skipSnap(data[start:]) + next, err := skipSnap(dAtA[start:]) if err != nil { return 0, err } @@ -336,6 +338,8 @@ var ( ErrIntOverflowSnap = fmt.Errorf("proto: integer overflow") ) +func init() { proto.RegisterFile("snap.proto", fileDescriptorSnap) } + var fileDescriptorSnap = []byte{ // 126 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0xe2, 0x2a, 0xce, 0x4b, 0x2c, diff --git a/vendor/github.com/coreos/etcd/snap/snapshotter.go b/vendor/github.com/coreos/etcd/snap/snapshotter.go index 50d09dda1..007555921 100644 --- a/vendor/github.com/coreos/etcd/snap/snapshotter.go +++ b/vendor/github.com/coreos/etcd/snap/snapshotter.go @@ -21,7 +21,7 @@ import ( "hash/crc32" "io/ioutil" "os" - "path" + "path/filepath" "sort" "strings" "time" @@ -84,13 +84,13 @@ func (s *Snapshotter) save(snapshot *raftpb.Snapshot) error { marshallingDurations.Observe(float64(time.Since(start)) / float64(time.Second)) } - err = pioutil.WriteAndSyncFile(path.Join(s.dir, fname), d, 0666) + err = pioutil.WriteAndSyncFile(filepath.Join(s.dir, fname), d, 0666) if err == nil { saveDurations.Observe(float64(time.Since(start)) / float64(time.Second)) } else { - err1 := os.Remove(path.Join(s.dir, fname)) + err1 := os.Remove(filepath.Join(s.dir, fname)) if err1 != nil { - plog.Errorf("failed to remove broken snapshot file %s", path.Join(s.dir, fname)) + plog.Errorf("failed to remove broken snapshot file %s", filepath.Join(s.dir, fname)) } } return err @@ -114,7 +114,7 @@ func (s *Snapshotter) Load() (*raftpb.Snapshot, error) { } func loadSnap(dir, name string) (*raftpb.Snapshot, error) { - fpath := path.Join(dir, name) + fpath := filepath.Join(dir, name) snap, err := Read(fpath) if err != nil { renameBroken(fpath) diff --git a/vendor/github.com/coreos/etcd/store/event_history.go b/vendor/github.com/coreos/etcd/store/event_history.go index 4977ee93a..235d87a26 100644 --- a/vendor/github.com/coreos/etcd/store/event_history.go +++ b/vendor/github.com/coreos/etcd/store/event_history.go @@ -83,12 +83,12 @@ func (eh *EventHistory) scan(key string, recursive bool, index uint64) (*Event, if recursive { // add tailing slash - key = path.Clean(key) - if key[len(key)-1] != '/' { - key = key + "/" + nkey := path.Clean(key) + if nkey[len(nkey)-1] != '/' { + nkey = nkey + "/" } - ok = ok || strings.HasPrefix(e.Node.Key, key) + ok = ok || strings.HasPrefix(e.Node.Key, nkey) } if (e.Action == Delete || e.Action == Expire) && e.PrevNode != nil && e.PrevNode.Dir { diff --git a/vendor/github.com/coreos/etcd/store/store.go b/vendor/github.com/coreos/etcd/store/store.go index f0a1fe538..6c19ad4c9 100644 --- a/vendor/github.com/coreos/etcd/store/store.go +++ b/vendor/github.com/coreos/etcd/store/store.go @@ -61,6 +61,8 @@ type Store interface { JsonStats() []byte DeleteExpiredKeys(cutoff time.Time) + + HasTTLKeys() bool } type TTLOptionSet struct { @@ -141,8 +143,6 @@ func (s *store) Get(nodePath string, recursive, sorted bool) (*Event, error) { } }() - nodePath = path.Clean(path.Join("/", nodePath)) - n, err := s.internalGet(nodePath) if err != nil { return nil, err @@ -780,3 +780,9 @@ func (s *store) JsonStats() []byte { s.Stats.Watchers = uint64(s.WatcherHub.count) return s.Stats.toJson() } + +func (s *store) HasTTLKeys() bool { + s.worldLock.RLock() + defer s.worldLock.RUnlock() + return s.ttlKeyHeap.Len() != 0 +} diff --git a/vendor/github.com/coreos/etcd/version/version.go b/vendor/github.com/coreos/etcd/version/version.go index a3122aa49..8cc470346 100644 --- a/vendor/github.com/coreos/etcd/version/version.go +++ b/vendor/github.com/coreos/etcd/version/version.go @@ -18,32 +18,27 @@ package version import ( "fmt" - "os" - "path" "strings" - "github.com/coreos/etcd/pkg/fileutil" - "github.com/coreos/etcd/pkg/types" + "github.com/coreos/go-semver/semver" ) var ( // MinClusterVersion is the min cluster version this etcd binary is compatible with. - MinClusterVersion = "2.3.0" - Version = "3.0.17" + MinClusterVersion = "3.0.0" + Version = "3.1.5" + APIVersion = "unknown" // Git SHA Value will be set during build GitSHA = "Not provided (use ./build instead of go build)" ) -// DataDirVersion is an enum for versions of etcd logs. -type DataDirVersion string - -const ( - DataDirUnknown DataDirVersion = "Unknown WAL" - DataDir2_0 DataDirVersion = "2.0.0" - DataDir2_0Proxy DataDirVersion = "2.0 proxy" - DataDir2_0_1 DataDirVersion = "2.0.1" -) +func init() { + ver, err := semver.NewVersion(Version) + if err == nil { + APIVersion = fmt.Sprintf("%d.%d", ver.Major, ver.Minor) + } +} type Versions struct { Server string `json:"etcdserver"` @@ -51,36 +46,6 @@ type Versions struct { // TODO: raft state machine version } -func DetectDataDir(dirpath string) (DataDirVersion, error) { - names, err := fileutil.ReadDir(dirpath) - if err != nil { - if os.IsNotExist(err) { - err = nil - } - // Error reading the directory - return DataDirUnknown, err - } - nameSet := types.NewUnsafeSet(names...) - if nameSet.Contains("member") { - ver, err := DetectDataDir(path.Join(dirpath, "member")) - if ver == DataDir2_0 { - return DataDir2_0_1, nil - } - return ver, err - } - if nameSet.ContainsAll([]string{"snap", "wal"}) { - // .../wal cannot be empty to exist. - walnames, err := fileutil.ReadDir(path.Join(dirpath, "wal")) - if err == nil && len(walnames) > 0 { - return DataDir2_0, nil - } - } - if nameSet.ContainsAll([]string{"proxy"}) { - return DataDir2_0Proxy, nil - } - return DataDirUnknown, nil -} - // Cluster only keeps the major.minor. func Cluster(v string) string { vs := strings.Split(v, ".") diff --git a/vendor/github.com/coreos/etcd/wal/doc.go b/vendor/github.com/coreos/etcd/wal/doc.go index 031a043a3..a3abd6961 100644 --- a/vendor/github.com/coreos/etcd/wal/doc.go +++ b/vendor/github.com/coreos/etcd/wal/doc.go @@ -25,7 +25,7 @@ to it with the Save method: ... err := w.Save(s, ents) -After saving an raft snapshot to disk, SaveSnapshot method should be called to +After saving a raft snapshot to disk, SaveSnapshot method should be called to record it. So WAL can match with the saved snapshot when restarting. err := w.SaveSnapshot(walpb.Snapshot{Index: 10, Term: 2}) diff --git a/vendor/github.com/coreos/etcd/wal/encoder.go b/vendor/github.com/coreos/etcd/wal/encoder.go index cc3eeebcc..efe58928c 100644 --- a/vendor/github.com/coreos/etcd/wal/encoder.go +++ b/vendor/github.com/coreos/etcd/wal/encoder.go @@ -27,8 +27,8 @@ import ( ) // walPageBytes is the alignment for flushing records to the backing Writer. -// It should be a multiple of the minimum sector size so that WAL repair can -// safely between torn writes and ordinary data corruption. +// It should be a multiple of the minimum sector size so that WAL can safely +// distinguish between torn writes and ordinary data corruption. const walPageBytes = 8 * minSectorSize type encoder struct { diff --git a/vendor/github.com/coreos/etcd/wal/file_pipeline.go b/vendor/github.com/coreos/etcd/wal/file_pipeline.go index 3412210a3..5e32a0693 100644 --- a/vendor/github.com/coreos/etcd/wal/file_pipeline.go +++ b/vendor/github.com/coreos/etcd/wal/file_pipeline.go @@ -17,7 +17,7 @@ package wal import ( "fmt" "os" - "path" + "path/filepath" "github.com/coreos/etcd/pkg/fileutil" ) @@ -65,7 +65,7 @@ func (fp *filePipeline) Close() error { func (fp *filePipeline) alloc() (f *fileutil.LockedFile, err error) { // count % 2 so this file isn't the same as the one last published - fpath := path.Join(fp.dir, fmt.Sprintf("%d.tmp", fp.count%2)) + fpath := filepath.Join(fp.dir, fmt.Sprintf("%d.tmp", fp.count%2)) if f, err = fileutil.LockFile(fpath, os.O_CREATE|os.O_WRONLY, fileutil.PrivateFileMode); err != nil { return nil, err } diff --git a/vendor/github.com/coreos/etcd/wal/repair.go b/vendor/github.com/coreos/etcd/wal/repair.go index 0a920e2d8..ffb141616 100644 --- a/vendor/github.com/coreos/etcd/wal/repair.go +++ b/vendor/github.com/coreos/etcd/wal/repair.go @@ -17,7 +17,7 @@ package wal import ( "io" "os" - "path" + "path/filepath" "github.com/coreos/etcd/pkg/fileutil" "github.com/coreos/etcd/wal/walpb" @@ -94,6 +94,6 @@ func openLast(dirpath string) (*fileutil.LockedFile, error) { if err != nil { return nil, err } - last := path.Join(dirpath, names[len(names)-1]) + last := filepath.Join(dirpath, names[len(names)-1]) return fileutil.LockFile(last, os.O_RDWR, fileutil.PrivateFileMode) } diff --git a/vendor/github.com/coreos/etcd/wal/wal.go b/vendor/github.com/coreos/etcd/wal/wal.go index 2e4e0ba0e..b65f64483 100644 --- a/vendor/github.com/coreos/etcd/wal/wal.go +++ b/vendor/github.com/coreos/etcd/wal/wal.go @@ -21,7 +21,7 @@ import ( "hash/crc32" "io" "os" - "path" + "path/filepath" "sync" "time" @@ -41,16 +41,18 @@ const ( crcType snapshotType - // the expected size of each wal segment file. - // the actual size might be bigger than it. - segmentSizeBytes = 64 * 1000 * 1000 // 64MB - // warnSyncDuration is the amount of time allotted to an fsync before // logging a warning warnSyncDuration = time.Second ) var ( + // SegmentSizeBytes is the preallocated size of each wal segment file. + // The actual size might be larger than this. In general, the default + // value should be used, but this is defined as an exported variable + // so that tests can set a different segment size. + SegmentSizeBytes int64 = 64 * 1000 * 1000 // 64MB + plog = capnslog.NewPackageLogger("github.com/coreos/etcd", "wal") ErrMetadataConflict = errors.New("wal: conflicting metadata found") @@ -95,7 +97,7 @@ func Create(dirpath string, metadata []byte) (*WAL, error) { } // keep temporary wal directory so WAL initialization appears atomic - tmpdirpath := path.Clean(dirpath) + ".tmp" + tmpdirpath := filepath.Clean(dirpath) + ".tmp" if fileutil.Exist(tmpdirpath) { if err := os.RemoveAll(tmpdirpath); err != nil { return nil, err @@ -105,7 +107,7 @@ func Create(dirpath string, metadata []byte) (*WAL, error) { return nil, err } - p := path.Join(tmpdirpath, walName(0, 0)) + p := filepath.Join(tmpdirpath, walName(0, 0)) f, err := fileutil.LockFile(p, os.O_WRONLY|os.O_CREATE, fileutil.PrivateFileMode) if err != nil { return nil, err @@ -113,7 +115,7 @@ func Create(dirpath string, metadata []byte) (*WAL, error) { if _, err = f.Seek(0, os.SEEK_END); err != nil { return nil, err } - if err = fileutil.Preallocate(f.File, segmentSizeBytes, true); err != nil { + if err = fileutil.Preallocate(f.File, SegmentSizeBytes, true); err != nil { return nil, err } @@ -141,7 +143,7 @@ func Create(dirpath string, metadata []byte) (*WAL, error) { } // directory was renamed; sync parent dir to persist rename - pdir, perr := fileutil.OpenDir(path.Dir(w.dir)) + pdir, perr := fileutil.OpenDir(filepath.Dir(w.dir)) if perr != nil { return nil, perr } @@ -194,7 +196,7 @@ func openAtIndex(dirpath string, snap walpb.Snapshot, write bool) (*WAL, error) rs := make([]io.Reader, 0) ls := make([]*fileutil.LockedFile, 0) for _, name := range names[nameIndex:] { - p := path.Join(dirpath, name) + p := filepath.Join(dirpath, name) if write { l, err := fileutil.TryLockFile(p, os.O_RDWR, fileutil.PrivateFileMode) if err != nil { @@ -230,11 +232,11 @@ func openAtIndex(dirpath string, snap walpb.Snapshot, write bool) (*WAL, error) // write reuses the file descriptors from read; don't close so // WAL can append without dropping the file lock w.readClose = nil - if _, _, err := parseWalName(path.Base(w.tail().Name())); err != nil { + if _, _, err := parseWalName(filepath.Base(w.tail().Name())); err != nil { closer() return nil, err } - w.fp = newFilePipeline(w.dir, segmentSizeBytes) + w.fp = newFilePipeline(w.dir, SegmentSizeBytes) } return w, nil @@ -370,7 +372,7 @@ func (w *WAL) cut() error { return err } - fpath := path.Join(w.dir, walName(w.seq()+1, w.enti+1)) + fpath := filepath.Join(w.dir, walName(w.seq()+1, w.enti+1)) // create a temp wal file with name sequence + 1, or truncate the existing one newTail, err := w.fp.Open() @@ -462,7 +464,7 @@ func (w *WAL) ReleaseLockTo(index uint64) error { found := false for i, l := range w.locks { - _, lockIndex, err := parseWalName(path.Base(l.Name())) + _, lockIndex, err := parseWalName(filepath.Base(l.Name())) if err != nil { return err } @@ -516,6 +518,7 @@ func (w *WAL) Close() error { plog.Errorf("failed to unlock during closing wal: %s", err) } } + return w.dirFile.Close() } @@ -565,22 +568,22 @@ func (w *WAL) Save(st raftpb.HardState, ents []raftpb.Entry) error { if err != nil { return err } - if curOff < segmentSizeBytes { + if curOff < SegmentSizeBytes { if mustSync { return w.sync() } return nil } - // TODO: add a test for this code path when refactoring the tests return w.cut() } func (w *WAL) SaveSnapshot(e walpb.Snapshot) error { + b := pbutil.MustMarshal(&e) + w.mu.Lock() defer w.mu.Unlock() - b := pbutil.MustMarshal(&e) rec := &walpb.Record{Type: snapshotType, Data: b} if err := w.encoder.encode(rec); err != nil { return err @@ -608,7 +611,7 @@ func (w *WAL) seq() uint64 { if t == nil { return 0 } - seq, _, err := parseWalName(path.Base(t.Name())) + seq, _, err := parseWalName(filepath.Base(t.Name())) if err != nil { plog.Fatalf("bad wal name %s (%v)", t.Name(), err) } diff --git a/vendor/github.com/coreos/etcd/wal/wal_unix.go b/vendor/github.com/coreos/etcd/wal/wal_unix.go index a066d2d38..82fd6a17a 100644 --- a/vendor/github.com/coreos/etcd/wal/wal_unix.go +++ b/vendor/github.com/coreos/etcd/wal/wal_unix.go @@ -37,7 +37,7 @@ func (w *WAL) renameWal(tmpdirpath string) (*WAL, error) { return nil, err } - w.fp = newFilePipeline(w.dir, segmentSizeBytes) + w.fp = newFilePipeline(w.dir, SegmentSizeBytes) df, err := fileutil.OpenDir(w.dir) w.dirFile = df return w, err 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 0e86f363e..e1a77d5e5 100644 --- a/vendor/github.com/coreos/etcd/wal/walpb/record.pb.go +++ b/vendor/github.com/coreos/etcd/wal/walpb/record.pb.go @@ -31,7 +31,9 @@ var _ = math.Inf // This is a compile-time assertion to ensure that this generated file // is compatible with the proto package it is being compiled against. -const _ = proto.ProtoPackageIsVersion1 +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package type Record struct { Type int64 `protobuf:"varint,1,opt,name=type" json:"type"` @@ -60,91 +62,91 @@ func init() { proto.RegisterType((*Record)(nil), "walpb.Record") proto.RegisterType((*Snapshot)(nil), "walpb.Snapshot") } -func (m *Record) Marshal() (data []byte, err error) { +func (m *Record) Marshal() (dAtA []byte, err error) { size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) if err != nil { return nil, err } - return data[:n], nil + return dAtA[:n], nil } -func (m *Record) MarshalTo(data []byte) (int, error) { +func (m *Record) MarshalTo(dAtA []byte) (int, error) { var i int _ = i var l int _ = l - data[i] = 0x8 + dAtA[i] = 0x8 i++ - i = encodeVarintRecord(data, i, uint64(m.Type)) - data[i] = 0x10 + i = encodeVarintRecord(dAtA, i, uint64(m.Type)) + dAtA[i] = 0x10 i++ - i = encodeVarintRecord(data, i, uint64(m.Crc)) + i = encodeVarintRecord(dAtA, i, uint64(m.Crc)) if m.Data != nil { - data[i] = 0x1a + dAtA[i] = 0x1a i++ - i = encodeVarintRecord(data, i, uint64(len(m.Data))) - i += copy(data[i:], m.Data) + i = encodeVarintRecord(dAtA, i, uint64(len(m.Data))) + i += copy(dAtA[i:], m.Data) } if m.XXX_unrecognized != nil { - i += copy(data[i:], m.XXX_unrecognized) + i += copy(dAtA[i:], m.XXX_unrecognized) } return i, nil } -func (m *Snapshot) Marshal() (data []byte, err error) { +func (m *Snapshot) Marshal() (dAtA []byte, err error) { size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) if err != nil { return nil, err } - return data[:n], nil + return dAtA[:n], nil } -func (m *Snapshot) MarshalTo(data []byte) (int, error) { +func (m *Snapshot) MarshalTo(dAtA []byte) (int, error) { var i int _ = i var l int _ = l - data[i] = 0x8 + dAtA[i] = 0x8 i++ - i = encodeVarintRecord(data, i, uint64(m.Index)) - data[i] = 0x10 + i = encodeVarintRecord(dAtA, i, uint64(m.Index)) + dAtA[i] = 0x10 i++ - i = encodeVarintRecord(data, i, uint64(m.Term)) + i = encodeVarintRecord(dAtA, i, uint64(m.Term)) if m.XXX_unrecognized != nil { - i += copy(data[i:], m.XXX_unrecognized) + i += copy(dAtA[i:], m.XXX_unrecognized) } return i, nil } -func encodeFixed64Record(data []byte, offset int, v uint64) int { - data[offset] = uint8(v) - data[offset+1] = uint8(v >> 8) - data[offset+2] = uint8(v >> 16) - data[offset+3] = uint8(v >> 24) - data[offset+4] = uint8(v >> 32) - data[offset+5] = uint8(v >> 40) - data[offset+6] = uint8(v >> 48) - data[offset+7] = uint8(v >> 56) +func encodeFixed64Record(dAtA []byte, offset int, v uint64) int { + dAtA[offset] = uint8(v) + dAtA[offset+1] = uint8(v >> 8) + dAtA[offset+2] = uint8(v >> 16) + dAtA[offset+3] = uint8(v >> 24) + dAtA[offset+4] = uint8(v >> 32) + dAtA[offset+5] = uint8(v >> 40) + dAtA[offset+6] = uint8(v >> 48) + dAtA[offset+7] = uint8(v >> 56) return offset + 8 } -func encodeFixed32Record(data []byte, offset int, v uint32) int { - data[offset] = uint8(v) - data[offset+1] = uint8(v >> 8) - data[offset+2] = uint8(v >> 16) - data[offset+3] = uint8(v >> 24) +func encodeFixed32Record(dAtA []byte, offset int, v uint32) int { + dAtA[offset] = uint8(v) + dAtA[offset+1] = uint8(v >> 8) + dAtA[offset+2] = uint8(v >> 16) + dAtA[offset+3] = uint8(v >> 24) return offset + 4 } -func encodeVarintRecord(data []byte, offset int, v uint64) int { +func encodeVarintRecord(dAtA []byte, offset int, v uint64) int { for v >= 1<<7 { - data[offset] = uint8(v&0x7f | 0x80) + dAtA[offset] = uint8(v&0x7f | 0x80) v >>= 7 offset++ } - data[offset] = uint8(v) + dAtA[offset] = uint8(v) return offset + 1 } func (m *Record) Size() (n int) { @@ -186,8 +188,8 @@ func sovRecord(x uint64) (n int) { func sozRecord(x uint64) (n int) { return sovRecord(uint64((x << 1) ^ uint64((int64(x) >> 63)))) } -func (m *Record) Unmarshal(data []byte) error { - l := len(data) +func (m *Record) Unmarshal(dAtA []byte) error { + l := len(dAtA) iNdEx := 0 for iNdEx < l { preIndex := iNdEx @@ -199,7 +201,7 @@ func (m *Record) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -227,7 +229,7 @@ func (m *Record) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ m.Type |= (int64(b) & 0x7F) << shift if b < 0x80 { @@ -246,7 +248,7 @@ func (m *Record) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ m.Crc |= (uint32(b) & 0x7F) << shift if b < 0x80 { @@ -265,7 +267,7 @@ func (m *Record) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ byteLen |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -279,14 +281,14 @@ func (m *Record) Unmarshal(data []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Data = append(m.Data[:0], data[iNdEx:postIndex]...) + m.Data = append(m.Data[:0], dAtA[iNdEx:postIndex]...) if m.Data == nil { m.Data = []byte{} } iNdEx = postIndex default: iNdEx = preIndex - skippy, err := skipRecord(data[iNdEx:]) + skippy, err := skipRecord(dAtA[iNdEx:]) if err != nil { return err } @@ -296,7 +298,7 @@ func (m *Record) Unmarshal(data []byte) error { if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF } - m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) iNdEx += skippy } } @@ -306,8 +308,8 @@ func (m *Record) Unmarshal(data []byte) error { } return nil } -func (m *Snapshot) Unmarshal(data []byte) error { - l := len(data) +func (m *Snapshot) Unmarshal(dAtA []byte) error { + l := len(dAtA) iNdEx := 0 for iNdEx < l { preIndex := iNdEx @@ -319,7 +321,7 @@ func (m *Snapshot) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -347,7 +349,7 @@ func (m *Snapshot) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ m.Index |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -366,7 +368,7 @@ func (m *Snapshot) Unmarshal(data []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ m.Term |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -375,7 +377,7 @@ func (m *Snapshot) Unmarshal(data []byte) error { } default: iNdEx = preIndex - skippy, err := skipRecord(data[iNdEx:]) + skippy, err := skipRecord(dAtA[iNdEx:]) if err != nil { return err } @@ -385,7 +387,7 @@ func (m *Snapshot) Unmarshal(data []byte) error { if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF } - m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) iNdEx += skippy } } @@ -395,8 +397,8 @@ func (m *Snapshot) Unmarshal(data []byte) error { } return nil } -func skipRecord(data []byte) (n int, err error) { - l := len(data) +func skipRecord(dAtA []byte) (n int, err error) { + l := len(dAtA) iNdEx := 0 for iNdEx < l { var wire uint64 @@ -407,7 +409,7 @@ func skipRecord(data []byte) (n int, err error) { if iNdEx >= l { return 0, io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -425,7 +427,7 @@ func skipRecord(data []byte) (n int, err error) { return 0, io.ErrUnexpectedEOF } iNdEx++ - if data[iNdEx-1] < 0x80 { + if dAtA[iNdEx-1] < 0x80 { break } } @@ -442,7 +444,7 @@ func skipRecord(data []byte) (n int, err error) { if iNdEx >= l { return 0, io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ length |= (int(b) & 0x7F) << shift if b < 0x80 { @@ -465,7 +467,7 @@ func skipRecord(data []byte) (n int, err error) { if iNdEx >= l { return 0, io.ErrUnexpectedEOF } - b := data[iNdEx] + b := dAtA[iNdEx] iNdEx++ innerWire |= (uint64(b) & 0x7F) << shift if b < 0x80 { @@ -476,7 +478,7 @@ func skipRecord(data []byte) (n int, err error) { if innerWireType == 4 { break } - next, err := skipRecord(data[start:]) + next, err := skipRecord(dAtA[start:]) if err != nil { return 0, err } @@ -500,6 +502,8 @@ var ( ErrIntOverflowRecord = fmt.Errorf("proto: integer overflow") ) +func init() { proto.RegisterFile("record.proto", fileDescriptorRecord) } + var fileDescriptorRecord = []byte{ // 186 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0xe2, 0x29, 0x4a, 0x4d, 0xce, diff --git a/vendor/github.com/gogo/protobuf/AUTHORS b/vendor/github.com/gogo/protobuf/AUTHORS new file mode 100644 index 000000000..2eaf4d53a --- /dev/null +++ b/vendor/github.com/gogo/protobuf/AUTHORS @@ -0,0 +1,14 @@ +# This is the official list of GoGo authors for copyright purposes. +# This file is distinct from the CONTRIBUTORS file, which +# lists people. For example, employees are listed in CONTRIBUTORS, +# but not in AUTHORS, because the employer holds the copyright. + +# Names should be added to this file as one of +# Organization's name +# Individual's name +# Individual's name + +# Please keep the list sorted. + +Vastech SA (PTY) LTD +Walter Schulze diff --git a/vendor/github.com/gogo/protobuf/CONTRIBUTORS b/vendor/github.com/gogo/protobuf/CONTRIBUTORS index d2c3b418f..84a85b1e8 100644 --- a/vendor/github.com/gogo/protobuf/CONTRIBUTORS +++ b/vendor/github.com/gogo/protobuf/CONTRIBUTORS @@ -5,9 +5,12 @@ DongYun Kang Dwayne Schultz Georg Apitz Gustav Paul +Johan Brandhorst +John Shahid John Tuley Laurent Patrick Lee +Sergio Arbeo Stephen J Day Tamir Duberstein Todd Eisenberger diff --git a/vendor/github.com/gogo/protobuf/LICENSE b/vendor/github.com/gogo/protobuf/LICENSE index 335e38e19..7be0cc7b6 100644 --- a/vendor/github.com/gogo/protobuf/LICENSE +++ b/vendor/github.com/gogo/protobuf/LICENSE @@ -1,7 +1,7 @@ -Extensions for Protocol Buffers to create more go like structures. +Protocol Buffers for Go with Gadgets -Copyright (c) 2013, Vastech SA (PTY) LTD. All rights reserved. -http://github.com/gogo/protobuf/gogoproto +Copyright (c) 2013, The GoGo Authors. All rights reserved. +http://github.com/gogo/protobuf Go support for Protocol Buffers - Google's data interchange format diff --git a/vendor/github.com/gogo/protobuf/proto/Makefile b/vendor/github.com/gogo/protobuf/proto/Makefile index 23a6b1734..41c717573 100644 --- a/vendor/github.com/gogo/protobuf/proto/Makefile +++ b/vendor/github.com/gogo/protobuf/proto/Makefile @@ -39,5 +39,5 @@ test: install generate-test-pbs generate-test-pbs: make install make -C testdata - protoc-min-version --version="3.0.0" --proto_path=.:../../../../ --gogo_out=. proto3_proto/proto3.proto + protoc-min-version --version="3.0.0" --proto_path=.:../../../../:../protobuf --gogo_out=Mtestdata/test.proto=github.com/gogo/protobuf/proto/testdata,Mgoogle/protobuf/any.proto=github.com/gogo/protobuf/types:. proto3_proto/proto3.proto make diff --git a/vendor/github.com/gogo/protobuf/proto/clone.go b/vendor/github.com/gogo/protobuf/proto/clone.go index 79edb8611..5d4cba4b5 100644 --- a/vendor/github.com/gogo/protobuf/proto/clone.go +++ b/vendor/github.com/gogo/protobuf/proto/clone.go @@ -84,14 +84,20 @@ func mergeStruct(out, in reflect.Value) { mergeAny(out.Field(i), in.Field(i), false, sprop.Prop[i]) } - if emIn, ok := in.Addr().Interface().(extensionsMap); ok { - emOut := out.Addr().Interface().(extensionsMap) - mergeExtension(emOut.ExtensionMap(), emIn.ExtensionMap()) - } else if emIn, ok := in.Addr().Interface().(extensionsBytes); ok { + if emIn, ok := in.Addr().Interface().(extensionsBytes); ok { emOut := out.Addr().Interface().(extensionsBytes) bIn := emIn.GetExtensions() bOut := emOut.GetExtensions() *bOut = append(*bOut, *bIn...) + } else if emIn, ok := extendable(in.Addr().Interface()); ok { + emOut, _ := extendable(out.Addr().Interface()) + mIn, muIn := emIn.extensionsRead() + if mIn != nil { + mOut := emOut.extensionsWrite() + muIn.Lock() + mergeExtension(mOut, mIn) + muIn.Unlock() + } } uf := in.FieldByName("XXX_unrecognized") diff --git a/vendor/github.com/gogo/protobuf/proto/decode.go b/vendor/github.com/gogo/protobuf/proto/decode.go index 7b06266d1..737f2731d 100644 --- a/vendor/github.com/gogo/protobuf/proto/decode.go +++ b/vendor/github.com/gogo/protobuf/proto/decode.go @@ -61,7 +61,6 @@ var ErrInternalBadWireType = errors.New("proto: internal error: bad wiretype for // int32, int64, uint32, uint64, bool, and enum // protocol buffer types. func DecodeVarint(buf []byte) (x uint64, n int) { - // x, n already 0 for shift := uint(0); shift < 64; shift += 7 { if n >= len(buf) { return 0, 0 @@ -78,13 +77,7 @@ func DecodeVarint(buf []byte) (x uint64, n int) { return 0, 0 } -// DecodeVarint reads a varint-encoded integer from the Buffer. -// This is the format for the -// int32, int64, uint32, uint64, bool, and enum -// protocol buffer types. -func (p *Buffer) DecodeVarint() (x uint64, err error) { - // x, err already 0 - +func (p *Buffer) decodeVarintSlow() (x uint64, err error) { i := p.index l := len(p.buf) @@ -107,6 +100,107 @@ func (p *Buffer) DecodeVarint() (x uint64, err error) { return } +// DecodeVarint reads a varint-encoded integer from the Buffer. +// This is the format for the +// int32, int64, uint32, uint64, bool, and enum +// protocol buffer types. +func (p *Buffer) DecodeVarint() (x uint64, err error) { + i := p.index + buf := p.buf + + if i >= len(buf) { + return 0, io.ErrUnexpectedEOF + } else if buf[i] < 0x80 { + p.index++ + return uint64(buf[i]), nil + } else if len(buf)-i < 10 { + return p.decodeVarintSlow() + } + + var b uint64 + // we already checked the first byte + x = uint64(buf[i]) - 0x80 + i++ + + b = uint64(buf[i]) + i++ + x += b << 7 + if b&0x80 == 0 { + goto done + } + x -= 0x80 << 7 + + b = uint64(buf[i]) + i++ + x += b << 14 + if b&0x80 == 0 { + goto done + } + x -= 0x80 << 14 + + b = uint64(buf[i]) + i++ + x += b << 21 + if b&0x80 == 0 { + goto done + } + x -= 0x80 << 21 + + b = uint64(buf[i]) + i++ + x += b << 28 + if b&0x80 == 0 { + goto done + } + x -= 0x80 << 28 + + b = uint64(buf[i]) + i++ + x += b << 35 + if b&0x80 == 0 { + goto done + } + x -= 0x80 << 35 + + b = uint64(buf[i]) + i++ + x += b << 42 + if b&0x80 == 0 { + goto done + } + x -= 0x80 << 42 + + b = uint64(buf[i]) + i++ + x += b << 49 + if b&0x80 == 0 { + goto done + } + x -= 0x80 << 49 + + b = uint64(buf[i]) + i++ + x += b << 56 + if b&0x80 == 0 { + goto done + } + x -= 0x80 << 56 + + b = uint64(buf[i]) + i++ + x += b << 63 + if b&0x80 == 0 { + goto done + } + // x -= 0x80 << 63 // Always zero. + + return 0, errOverflow + +done: + p.index = i + return x, nil +} + // DecodeFixed64 reads a 64-bit integer from the Buffer. // This is the format for the // fixed64, sfixed64, and double protocol buffer types. @@ -340,6 +434,8 @@ func (p *Buffer) DecodeGroup(pb Message) error { // Buffer and places the decoded result in pb. If the struct // underlying pb does not match the data in the buffer, the results can be // unpredictable. +// +// Unlike proto.Unmarshal, this does not reset pb before starting to unmarshal. func (p *Buffer) Unmarshal(pb Message) error { // If the object can unmarshal itself, let it. if u, ok := pb.(Unmarshaler); ok { @@ -378,6 +474,11 @@ func (o *Buffer) unmarshalType(st reflect.Type, prop *StructProperties, is_group wire := int(u & 0x7) if wire == WireEndGroup { if is_group { + if required > 0 { + // Not enough information to determine the exact field. + // (See below.) + return &RequiredNotSetError{"{Unknown}"} + } return nil // input is satisfied } return fmt.Errorf("proto: %s: wiretype end group for non-group", st) @@ -390,16 +491,20 @@ func (o *Buffer) unmarshalType(st reflect.Type, prop *StructProperties, is_group if !ok { // Maybe it's an extension? if prop.extendable { - if e := structPointer_Interface(base, st).(extendableProto); isExtensionField(e, int32(tag)) { - if err = o.skip(st, tag, wire); err == nil { - if ee, eok := e.(extensionsMap); eok { - ext := ee.ExtensionMap()[int32(tag)] // may be missing - ext.enc = append(ext.enc, o.buf[oi:o.index]...) - ee.ExtensionMap()[int32(tag)] = ext - } else if ee, eok := e.(extensionsBytes); eok { - ext := ee.GetExtensions() + if e, eok := structPointer_Interface(base, st).(extensionsBytes); eok { + if isExtensionField(e, int32(tag)) { + if err = o.skip(st, tag, wire); err == nil { + ext := e.GetExtensions() *ext = append(*ext, o.buf[oi:o.index]...) } + continue + } + } else if e, _ := extendable(structPointer_Interface(base, st)); isExtensionField(e, int32(tag)) { + if err = o.skip(st, tag, wire); err == nil { + extmap := e.extensionsWrite() + ext := extmap[int32(tag)] // may be missing + ext.enc = append(ext.enc, o.buf[oi:o.index]...) + extmap[int32(tag)] = ext } continue } diff --git a/vendor/github.com/gogo/protobuf/proto/decode_gogo.go b/vendor/github.com/gogo/protobuf/proto/decode_gogo.go index 603dabec3..6fb74de4c 100644 --- a/vendor/github.com/gogo/protobuf/proto/decode_gogo.go +++ b/vendor/github.com/gogo/protobuf/proto/decode_gogo.go @@ -1,5 +1,7 @@ -// Copyright (c) 2013, Vastech SA (PTY) LTD. All rights reserved. -// http://github.com/gogo/protobuf/gogoproto +// Protocol Buffers for Go with Gadgets +// +// Copyright (c) 2013, The GoGo Authors. All rights reserved. +// http://github.com/gogo/protobuf // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are @@ -96,7 +98,7 @@ func setPtrCustomType(base structPointer, f field, v interface{}) { if v == nil { return } - structPointer_SetStructPointer(base, f, structPointer(reflect.ValueOf(v).Pointer())) + structPointer_SetStructPointer(base, f, toStructPointer(reflect.ValueOf(v))) } func setCustomType(base structPointer, f field, value interface{}) { @@ -163,7 +165,8 @@ func (o *Buffer) dec_custom_slice_bytes(p *Properties, base structPointer) error } newBas := appendStructPointer(base, p.field, p.ctype) - setCustomType(newBas, 0, custom) + var zero field + setCustomType(newBas, zero, custom) return nil } diff --git a/vendor/github.com/gogo/protobuf/proto/duration.go b/vendor/github.com/gogo/protobuf/proto/duration.go new file mode 100644 index 000000000..93464c91c --- /dev/null +++ b/vendor/github.com/gogo/protobuf/proto/duration.go @@ -0,0 +1,100 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2016 The Go Authors. All rights reserved. +// https://github.com/golang/protobuf +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package proto + +// This file implements conversions between google.protobuf.Duration +// and time.Duration. + +import ( + "errors" + "fmt" + "time" +) + +const ( + // Range of a Duration in seconds, as specified in + // google/protobuf/duration.proto. This is about 10,000 years in seconds. + maxSeconds = int64(10000 * 365.25 * 24 * 60 * 60) + minSeconds = -maxSeconds +) + +// validateDuration determines whether the Duration is valid according to the +// definition in google/protobuf/duration.proto. A valid Duration +// may still be too large to fit into a time.Duration (the range of Duration +// is about 10,000 years, and the range of time.Duration is about 290). +func validateDuration(d *duration) error { + if d == nil { + return errors.New("duration: nil Duration") + } + if d.Seconds < minSeconds || d.Seconds > maxSeconds { + return fmt.Errorf("duration: %#v: seconds out of range", d) + } + if d.Nanos <= -1e9 || d.Nanos >= 1e9 { + return fmt.Errorf("duration: %#v: nanos out of range", d) + } + // Seconds and Nanos must have the same sign, unless d.Nanos is zero. + if (d.Seconds < 0 && d.Nanos > 0) || (d.Seconds > 0 && d.Nanos < 0) { + return fmt.Errorf("duration: %#v: seconds and nanos have different signs", d) + } + return nil +} + +// DurationFromProto converts a Duration to a time.Duration. DurationFromProto +// returns an error if the Duration is invalid or is too large to be +// represented in a time.Duration. +func durationFromProto(p *duration) (time.Duration, error) { + if err := validateDuration(p); err != nil { + return 0, err + } + d := time.Duration(p.Seconds) * time.Second + if int64(d/time.Second) != p.Seconds { + return 0, fmt.Errorf("duration: %#v is out of range for time.Duration", p) + } + if p.Nanos != 0 { + d += time.Duration(p.Nanos) + if (d < 0) != (p.Nanos < 0) { + return 0, fmt.Errorf("duration: %#v is out of range for time.Duration", p) + } + } + return d, nil +} + +// DurationProto converts a time.Duration to a Duration. +func durationProto(d time.Duration) *duration { + nanos := d.Nanoseconds() + secs := nanos / 1e9 + nanos -= secs * 1e9 + return &duration{ + Seconds: secs, + Nanos: int32(nanos), + } +} diff --git a/vendor/github.com/gogo/protobuf/proto/duration_gogo.go b/vendor/github.com/gogo/protobuf/proto/duration_gogo.go new file mode 100644 index 000000000..18e2a5f77 --- /dev/null +++ b/vendor/github.com/gogo/protobuf/proto/duration_gogo.go @@ -0,0 +1,203 @@ +// Protocol Buffers for Go with Gadgets +// +// Copyright (c) 2016, The GoGo Authors. All rights reserved. +// http://github.com/gogo/protobuf +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package proto + +import ( + "reflect" + "time" +) + +var durationType = reflect.TypeOf((*time.Duration)(nil)).Elem() + +type duration struct { + Seconds int64 `protobuf:"varint,1,opt,name=seconds,proto3" json:"seconds,omitempty"` + Nanos int32 `protobuf:"varint,2,opt,name=nanos,proto3" json:"nanos,omitempty"` +} + +func (m *duration) Reset() { *m = duration{} } +func (*duration) ProtoMessage() {} +func (*duration) String() string { return "duration" } + +func init() { + RegisterType((*duration)(nil), "gogo.protobuf.proto.duration") +} + +func (o *Buffer) decDuration() (time.Duration, error) { + b, err := o.DecodeRawBytes(true) + if err != nil { + return 0, err + } + dproto := &duration{} + if err := Unmarshal(b, dproto); err != nil { + return 0, err + } + return durationFromProto(dproto) +} + +func (o *Buffer) dec_duration(p *Properties, base structPointer) error { + d, err := o.decDuration() + if err != nil { + return err + } + word64_Set(structPointer_Word64(base, p.field), o, uint64(d)) + return nil +} + +func (o *Buffer) dec_ref_duration(p *Properties, base structPointer) error { + d, err := o.decDuration() + if err != nil { + return err + } + word64Val_Set(structPointer_Word64Val(base, p.field), o, uint64(d)) + return nil +} + +func (o *Buffer) dec_slice_duration(p *Properties, base structPointer) error { + d, err := o.decDuration() + if err != nil { + return err + } + newBas := appendStructPointer(base, p.field, reflect.SliceOf(reflect.PtrTo(durationType))) + var zero field + setPtrCustomType(newBas, zero, &d) + return nil +} + +func (o *Buffer) dec_slice_ref_duration(p *Properties, base structPointer) error { + d, err := o.decDuration() + if err != nil { + return err + } + structPointer_Word64Slice(base, p.field).Append(uint64(d)) + return nil +} + +func size_duration(p *Properties, base structPointer) (n int) { + structp := structPointer_GetStructPointer(base, p.field) + if structPointer_IsNil(structp) { + return 0 + } + dur := structPointer_Interface(structp, durationType).(*time.Duration) + d := durationProto(*dur) + size := Size(d) + return size + sizeVarint(uint64(size)) + len(p.tagcode) +} + +func (o *Buffer) enc_duration(p *Properties, base structPointer) error { + structp := structPointer_GetStructPointer(base, p.field) + if structPointer_IsNil(structp) { + return ErrNil + } + dur := structPointer_Interface(structp, durationType).(*time.Duration) + d := durationProto(*dur) + data, err := Marshal(d) + if err != nil { + return err + } + o.buf = append(o.buf, p.tagcode...) + o.EncodeRawBytes(data) + return nil +} + +func size_ref_duration(p *Properties, base structPointer) (n int) { + dur := structPointer_InterfaceAt(base, p.field, durationType).(*time.Duration) + d := durationProto(*dur) + size := Size(d) + return size + sizeVarint(uint64(size)) + len(p.tagcode) +} + +func (o *Buffer) enc_ref_duration(p *Properties, base structPointer) error { + dur := structPointer_InterfaceAt(base, p.field, durationType).(*time.Duration) + d := durationProto(*dur) + data, err := Marshal(d) + if err != nil { + return err + } + o.buf = append(o.buf, p.tagcode...) + o.EncodeRawBytes(data) + return nil +} + +func size_slice_duration(p *Properties, base structPointer) (n int) { + pdurs := structPointer_InterfaceAt(base, p.field, reflect.SliceOf(reflect.PtrTo(durationType))).(*[]*time.Duration) + durs := *pdurs + for i := 0; i < len(durs); i++ { + if durs[i] == nil { + return 0 + } + dproto := durationProto(*durs[i]) + size := Size(dproto) + n += len(p.tagcode) + size + sizeVarint(uint64(size)) + } + return n +} + +func (o *Buffer) enc_slice_duration(p *Properties, base structPointer) error { + pdurs := structPointer_InterfaceAt(base, p.field, reflect.SliceOf(reflect.PtrTo(durationType))).(*[]*time.Duration) + durs := *pdurs + for i := 0; i < len(durs); i++ { + if durs[i] == nil { + return errRepeatedHasNil + } + dproto := durationProto(*durs[i]) + data, err := Marshal(dproto) + if err != nil { + return err + } + o.buf = append(o.buf, p.tagcode...) + o.EncodeRawBytes(data) + } + return nil +} + +func size_slice_ref_duration(p *Properties, base structPointer) (n int) { + pdurs := structPointer_InterfaceAt(base, p.field, reflect.SliceOf(durationType)).(*[]time.Duration) + durs := *pdurs + for i := 0; i < len(durs); i++ { + dproto := durationProto(durs[i]) + size := Size(dproto) + n += len(p.tagcode) + size + sizeVarint(uint64(size)) + } + return n +} + +func (o *Buffer) enc_slice_ref_duration(p *Properties, base structPointer) error { + pdurs := structPointer_InterfaceAt(base, p.field, reflect.SliceOf(durationType)).(*[]time.Duration) + durs := *pdurs + for i := 0; i < len(durs); i++ { + dproto := durationProto(durs[i]) + data, err := Marshal(dproto) + if err != nil { + return err + } + o.buf = append(o.buf, p.tagcode...) + o.EncodeRawBytes(data) + } + return nil +} diff --git a/vendor/github.com/gogo/protobuf/proto/encode.go b/vendor/github.com/gogo/protobuf/proto/encode.go index eb7e0474e..2b30f8462 100644 --- a/vendor/github.com/gogo/protobuf/proto/encode.go +++ b/vendor/github.com/gogo/protobuf/proto/encode.go @@ -70,6 +70,10 @@ var ( // ErrNil is the error returned if Marshal is called with nil. ErrNil = errors.New("proto: Marshal called with nil") + + // ErrTooLarge is the error returned if Marshal is called with a + // message that encodes to >2GB. + ErrTooLarge = errors.New("proto: message encodes to over 2 GB") ) // The fundamental encoders that put bytes on the wire. @@ -78,6 +82,10 @@ var ( const maxVarintBytes = 10 // maximum length of a varint +// maxMarshalSize is the largest allowed size of an encoded protobuf, +// since C++ and Java use signed int32s for the size. +const maxMarshalSize = 1<<31 - 1 + // EncodeVarint returns the varint encoding of x. // This is the format for the // int32, int64, uint32, uint64, bool, and enum @@ -226,10 +234,6 @@ func Marshal(pb Message) ([]byte, error) { } p := NewBuffer(nil) err := p.Marshal(pb) - var state errorState - if err != nil && !state.shouldContinue(err, nil) { - return nil, err - } if p.buf == nil && err == nil { // Return a non-nil slice on success. return []byte{}, nil @@ -258,11 +262,8 @@ func (p *Buffer) Marshal(pb Message) error { // Can the object marshal itself? if m, ok := pb.(Marshaler); ok { data, err := m.Marshal() - if err != nil { - return err - } p.buf = append(p.buf, data...) - return nil + return err } t, base, err := getbase(pb) @@ -274,9 +275,12 @@ func (p *Buffer) Marshal(pb Message) error { } if collectStats { - stats.Encode++ + (stats).Encode++ // Parens are to work around a goimports bug. } + if len(p.buf) > maxMarshalSize { + return ErrTooLarge + } return err } @@ -298,7 +302,7 @@ func Size(pb Message) (n int) { } if collectStats { - stats.Size++ + (stats).Size++ // Parens are to work around a goimports bug. } return @@ -1003,7 +1007,6 @@ func size_slice_struct_message(p *Properties, base structPointer) (n int) { if p.isMarshaler { m := structPointer_Interface(structp, p.stype).(Marshaler) data, _ := m.Marshal() - n += len(p.tagcode) n += sizeRawBytes(data) continue } @@ -1062,10 +1065,32 @@ func size_slice_struct_group(p *Properties, base structPointer) (n int) { // Encode an extension map. func (o *Buffer) enc_map(p *Properties, base structPointer) error { - v := *structPointer_ExtMap(base, p.field) - if err := encodeExtensionMap(v); err != nil { + exts := structPointer_ExtMap(base, p.field) + if err := encodeExtensionsMap(*exts); err != nil { return err } + + return o.enc_map_body(*exts) +} + +func (o *Buffer) enc_exts(p *Properties, base structPointer) error { + exts := structPointer_Extensions(base, p.field) + + v, mu := exts.extensionsRead() + if v == nil { + return nil + } + + mu.Lock() + defer mu.Unlock() + if err := encodeExtensionsMap(v); err != nil { + return err + } + + return o.enc_map_body(v) +} + +func (o *Buffer) enc_map_body(v map[int32]Extension) error { // Fast-path for common cases: zero or one extensions. if len(v) <= 1 { for _, e := range v { @@ -1088,8 +1113,13 @@ func (o *Buffer) enc_map(p *Properties, base structPointer) error { } func size_map(p *Properties, base structPointer) int { - v := *structPointer_ExtMap(base, p.field) - return sizeExtensionMap(v) + v := structPointer_ExtMap(base, p.field) + return extensionsMapSize(*v) +} + +func size_exts(p *Properties, base structPointer) int { + v := structPointer_Extensions(base, p.field) + return extensionsSize(v) } // Encode a map field. @@ -1118,7 +1148,7 @@ func (o *Buffer) enc_new_map(p *Properties, base structPointer) error { if err := p.mkeyprop.enc(o, p.mkeyprop, keybase); err != nil { return err } - if err := p.mvalprop.enc(o, p.mvalprop, valbase); err != nil { + if err := p.mvalprop.enc(o, p.mvalprop, valbase); err != nil && err != ErrNil { return err } return nil @@ -1128,11 +1158,6 @@ func (o *Buffer) enc_new_map(p *Properties, base structPointer) error { for _, key := range v.MapKeys() { val := v.MapIndex(key) - // The only illegal map entry values are nil message pointers. - if val.Kind() == reflect.Ptr && val.IsNil() { - return errors.New("proto: map has nil element") - } - keycopy.Set(key) valcopy.Set(val) @@ -1220,6 +1245,9 @@ func (o *Buffer) enc_struct(prop *StructProperties, base structPointer) error { return err } } + if len(o.buf) > maxMarshalSize { + return ErrTooLarge + } } } @@ -1236,6 +1264,9 @@ func (o *Buffer) enc_struct(prop *StructProperties, base structPointer) error { // Add unrecognized fields at the end. if prop.unrecField.IsValid() { v := *structPointer_Bytes(base, prop.unrecField) + if len(o.buf)+len(v) > maxMarshalSize { + return ErrTooLarge + } if len(v) > 0 { o.buf = append(o.buf, v...) } diff --git a/vendor/github.com/gogo/protobuf/proto/encode_gogo.go b/vendor/github.com/gogo/protobuf/proto/encode_gogo.go index f77cfb1ee..32111b7f4 100644 --- a/vendor/github.com/gogo/protobuf/proto/encode_gogo.go +++ b/vendor/github.com/gogo/protobuf/proto/encode_gogo.go @@ -1,7 +1,7 @@ -// Extensions for Protocol Buffers to create more go like structures. +// Protocol Buffers for Go with Gadgets // -// Copyright (c) 2013, Vastech SA (PTY) LTD. All rights reserved. -// http://github.com/gogo/protobuf/gogoproto +// Copyright (c) 2013, The GoGo Authors. All rights reserved. +// http://github.com/gogo/protobuf // // Go support for Protocol Buffers - Google's data interchange format // @@ -196,12 +196,10 @@ func size_ref_struct_message(p *Properties, base structPointer) int { // Encode a slice of references to message struct pointers ([]struct). func (o *Buffer) enc_slice_ref_struct_message(p *Properties, base structPointer) error { var state errorState - ss := structPointer_GetStructPointer(base, p.field) - ss1 := structPointer_GetRefStructPointer(ss, field(0)) - size := p.stype.Size() - l := structPointer_Len(base, p.field) + ss := structPointer_StructRefSlice(base, p.field, p.stype.Size()) + l := ss.Len() for i := 0; i < l; i++ { - structp := structPointer_Add(ss1, field(uintptr(i)*size)) + structp := ss.Index(i) if structPointer_IsNil(structp) { return errRepeatedHasNil } @@ -233,13 +231,11 @@ func (o *Buffer) enc_slice_ref_struct_message(p *Properties, base structPointer) //TODO this is only copied, please fix this func size_slice_ref_struct_message(p *Properties, base structPointer) (n int) { - ss := structPointer_GetStructPointer(base, p.field) - ss1 := structPointer_GetRefStructPointer(ss, field(0)) - size := p.stype.Size() - l := structPointer_Len(base, p.field) + ss := structPointer_StructRefSlice(base, p.field, p.stype.Size()) + l := ss.Len() n += l * len(p.tagcode) for i := 0; i < l; i++ { - structp := structPointer_Add(ss1, field(uintptr(i)*size)) + structp := ss.Index(i) if structPointer_IsNil(structp) { return // return the size up to this point } diff --git a/vendor/github.com/gogo/protobuf/proto/equal.go b/vendor/github.com/gogo/protobuf/proto/equal.go index f5db1def3..2ed1cf596 100644 --- a/vendor/github.com/gogo/protobuf/proto/equal.go +++ b/vendor/github.com/gogo/protobuf/proto/equal.go @@ -54,13 +54,17 @@ Equality is defined in this way: in a proto3 .proto file, fields are not "set"; specifically, zero length proto3 "bytes" fields are equal (nil == {}). - Two repeated fields are equal iff their lengths are the same, - and their corresponding elements are equal (a "bytes" field, - although represented by []byte, is not a repeated field) + and their corresponding elements are equal. Note a "bytes" field, + although represented by []byte, is not a repeated field and the + rule for the scalar fields described above applies. - Two unset fields are equal. - Two unknown field sets are equal if their current encoded state is equal. - Two extension sets are equal iff they have corresponding elements that are pairwise equal. + - Two map fields are equal iff their lengths are the same, + and they contain the same set of elements. Zero-length map + fields are equal. - Every other combination of things are not equal. The return value is undefined if a and b are not protocol buffers. @@ -121,9 +125,16 @@ func equalStruct(v1, v2 reflect.Value) bool { } } + if em1 := v1.FieldByName("XXX_InternalExtensions"); em1.IsValid() { + em2 := v2.FieldByName("XXX_InternalExtensions") + if !equalExtensions(v1.Type(), em1.Interface().(XXX_InternalExtensions), em2.Interface().(XXX_InternalExtensions)) { + return false + } + } + if em1 := v1.FieldByName("XXX_extensions"); em1.IsValid() { em2 := v2.FieldByName("XXX_extensions") - if !equalExtensions(v1.Type(), em1.Interface().(map[int32]Extension), em2.Interface().(map[int32]Extension)) { + if !equalExtMap(v1.Type(), em1.Interface().(map[int32]Extension), em2.Interface().(map[int32]Extension)) { return false } } @@ -184,6 +195,13 @@ func equalAny(v1, v2 reflect.Value, prop *Properties) bool { } return true case reflect.Ptr: + // Maps may have nil values in them, so check for nil. + if v1.IsNil() && v2.IsNil() { + return true + } + if v1.IsNil() != v2.IsNil() { + return false + } return equalAny(v1.Elem(), v2.Elem(), prop) case reflect.Slice: if v1.Type().Elem().Kind() == reflect.Uint8 { @@ -223,8 +241,14 @@ func equalAny(v1, v2 reflect.Value, prop *Properties) bool { } // base is the struct type that the extensions are based on. -// em1 and em2 are extension maps. -func equalExtensions(base reflect.Type, em1, em2 map[int32]Extension) bool { +// x1 and x2 are InternalExtensions. +func equalExtensions(base reflect.Type, x1, x2 XXX_InternalExtensions) bool { + em1, _ := x1.extensionsRead() + em2, _ := x2.extensionsRead() + return equalExtMap(base, em1, em2) +} + +func equalExtMap(base reflect.Type, em1, em2 map[int32]Extension) bool { if len(em1) != len(em2) { return false } diff --git a/vendor/github.com/gogo/protobuf/proto/extensions.go b/vendor/github.com/gogo/protobuf/proto/extensions.go index 6180347e3..0dfcb538e 100644 --- a/vendor/github.com/gogo/protobuf/proto/extensions.go +++ b/vendor/github.com/gogo/protobuf/proto/extensions.go @@ -52,23 +52,112 @@ type ExtensionRange struct { Start, End int32 // both inclusive } -// extendableProto is an interface implemented by any protocol buffer that may be extended. +// extendableProto is an interface implemented by any protocol buffer generated by the current +// proto compiler that may be extended. type extendableProto interface { Message ExtensionRangeArray() []ExtensionRange + extensionsWrite() map[int32]Extension + extensionsRead() (map[int32]Extension, sync.Locker) } -type extensionsMap interface { - extendableProto +// extendableProtoV1 is an interface implemented by a protocol buffer generated by the previous +// version of the proto compiler that may be extended. +type extendableProtoV1 interface { + Message + ExtensionRangeArray() []ExtensionRange ExtensionMap() map[int32]Extension } type extensionsBytes interface { - extendableProto + Message + ExtensionRangeArray() []ExtensionRange GetExtensions() *[]byte } +// extensionAdapter is a wrapper around extendableProtoV1 that implements extendableProto. +type extensionAdapter struct { + extendableProtoV1 +} + +func (e extensionAdapter) extensionsWrite() map[int32]Extension { + return e.ExtensionMap() +} + +func (e extensionAdapter) extensionsRead() (map[int32]Extension, sync.Locker) { + return e.ExtensionMap(), notLocker{} +} + +// notLocker is a sync.Locker whose Lock and Unlock methods are nops. +type notLocker struct{} + +func (n notLocker) Lock() {} +func (n notLocker) Unlock() {} + +// extendable returns the extendableProto interface for the given generated proto message. +// If the proto message has the old extension format, it returns a wrapper that implements +// the extendableProto interface. +func extendable(p interface{}) (extendableProto, bool) { + if ep, ok := p.(extendableProto); ok { + return ep, ok + } + if ep, ok := p.(extendableProtoV1); ok { + return extensionAdapter{ep}, ok + } + return nil, false +} + +// XXX_InternalExtensions is an internal representation of proto extensions. +// +// Each generated message struct type embeds an anonymous XXX_InternalExtensions field, +// thus gaining the unexported 'extensions' method, which can be called only from the proto package. +// +// The methods of XXX_InternalExtensions are not concurrency safe in general, +// but calls to logically read-only methods such as has and get may be executed concurrently. +type XXX_InternalExtensions struct { + // The struct must be indirect so that if a user inadvertently copies a + // generated message and its embedded XXX_InternalExtensions, they + // avoid the mayhem of a copied mutex. + // + // The mutex serializes all logically read-only operations to p.extensionMap. + // It is up to the client to ensure that write operations to p.extensionMap are + // mutually exclusive with other accesses. + p *struct { + mu sync.Mutex + extensionMap map[int32]Extension + } +} + +// extensionsWrite returns the extension map, creating it on first use. +func (e *XXX_InternalExtensions) extensionsWrite() map[int32]Extension { + if e.p == nil { + e.p = new(struct { + mu sync.Mutex + extensionMap map[int32]Extension + }) + e.p.extensionMap = make(map[int32]Extension) + } + return e.p.extensionMap +} + +// extensionsRead returns the extensions map for read-only use. It may be nil. +// The caller must hold the returned mutex's lock when accessing Elements within the map. +func (e *XXX_InternalExtensions) extensionsRead() (map[int32]Extension, sync.Locker) { + if e.p == nil { + return nil, nil + } + return e.p.extensionMap, &e.p.mu +} + +type extensionRange interface { + Message + ExtensionRangeArray() []ExtensionRange +} + var extendableProtoType = reflect.TypeOf((*extendableProto)(nil)).Elem() +var extendableProtoV1Type = reflect.TypeOf((*extendableProtoV1)(nil)).Elem() +var extendableBytesType = reflect.TypeOf((*extensionsBytes)(nil)).Elem() +var extensionRangeType = reflect.TypeOf((*extensionRange)(nil)).Elem() // ExtensionDesc represents an extension specification. // Used in generated code from the protocol compiler. @@ -78,6 +167,7 @@ type ExtensionDesc struct { Field int32 // field number Name string // fully-qualified name of extension, for text formatting Tag string // protobuf tag style + Filename string // name of the file in which the extension is defined } func (ed *ExtensionDesc) repeated() bool { @@ -101,20 +191,23 @@ type Extension struct { } // SetRawExtension is for testing only. -func SetRawExtension(base extendableProto, id int32, b []byte) { - if ebase, ok := base.(extensionsMap); ok { - ebase.ExtensionMap()[id] = Extension{enc: b} - } else if ebase, ok := base.(extensionsBytes); ok { +func SetRawExtension(base Message, id int32, b []byte) { + if ebase, ok := base.(extensionsBytes); ok { clearExtension(base, id) ext := ebase.GetExtensions() *ext = append(*ext, b...) - } else { - panic("unreachable") + return } + epb, ok := extendable(base) + if !ok { + return + } + extmap := epb.extensionsWrite() + extmap[id] = Extension{enc: b} } // isExtensionField returns true iff the given field number is in an extension range. -func isExtensionField(pb extendableProto, field int32) bool { +func isExtensionField(pb extensionRange, field int32) bool { for _, er := range pb.ExtensionRangeArray() { if er.Start <= field && field <= er.End { return true @@ -125,8 +218,12 @@ func isExtensionField(pb extendableProto, field int32) bool { // checkExtensionTypes checks that the given extension is valid for pb. func checkExtensionTypes(pb extendableProto, extension *ExtensionDesc) error { + var pbi interface{} = pb // Check the extended type. - if a, b := reflect.TypeOf(pb), reflect.TypeOf(extension.ExtendedType); a != b { + if ea, ok := pbi.(extensionAdapter); ok { + pbi = ea.extendableProtoV1 + } + if a, b := reflect.TypeOf(pbi), reflect.TypeOf(extension.ExtendedType); a != b { return errors.New("proto: bad extended type; " + b.String() + " does not extend " + a.String()) } // Check the range. @@ -172,43 +269,57 @@ func extensionProperties(ed *ExtensionDesc) *Properties { return prop } -// encodeExtensionMap encodes any unmarshaled (unencoded) extensions in m. -func encodeExtensionMap(m map[int32]Extension) error { +// encode encodes any unmarshaled (unencoded) extensions in e. +func encodeExtensions(e *XXX_InternalExtensions) error { + m, mu := e.extensionsRead() + if m == nil { + return nil // fast path + } + mu.Lock() + defer mu.Unlock() + return encodeExtensionsMap(m) +} + +// encode encodes any unmarshaled (unencoded) extensions in e. +func encodeExtensionsMap(m map[int32]Extension) error { for k, e := range m { - err := encodeExtension(&e) - if err != nil { + if e.value == nil || e.desc == nil { + // Extension is only in its encoded form. + continue + } + + // We don't skip extensions that have an encoded form set, + // because the extension value may have been mutated after + // the last time this function was called. + + et := reflect.TypeOf(e.desc.ExtensionType) + props := extensionProperties(e.desc) + + p := NewBuffer(nil) + // If e.value has type T, the encoder expects a *struct{ X T }. + // Pass a *T with a zero field and hope it all works out. + x := reflect.New(et) + x.Elem().Set(reflect.ValueOf(e.value)) + if err := props.enc(p, props, toStructPointer(x)); err != nil { return err } + e.enc = p.buf m[k] = e } return nil } -func encodeExtension(e *Extension) error { - if e.value == nil || e.desc == nil { - // Extension is only in its encoded form. - return nil +func extensionsSize(e *XXX_InternalExtensions) (n int) { + m, mu := e.extensionsRead() + if m == nil { + return 0 } - // We don't skip extensions that have an encoded form set, - // because the extension value may have been mutated after - // the last time this function was called. - - et := reflect.TypeOf(e.desc.ExtensionType) - props := extensionProperties(e.desc) - - p := NewBuffer(nil) - // If e.value has type T, the encoder expects a *struct{ X T }. - // Pass a *T with a zero field and hope it all works out. - x := reflect.New(et) - x.Elem().Set(reflect.ValueOf(e.value)) - if err := props.enc(p, props, toStructPointer(x)); err != nil { - return err - } - e.enc = p.buf - return nil + mu.Lock() + defer mu.Unlock() + return extensionsMapSize(m) } -func sizeExtensionMap(m map[int32]Extension) (n int) { +func extensionsMapSize(m map[int32]Extension) (n int) { for _, e := range m { if e.value == nil || e.desc == nil { // Extension is only in its encoded form. @@ -233,12 +344,8 @@ func sizeExtensionMap(m map[int32]Extension) (n int) { } // HasExtension returns whether the given extension is present in pb. -func HasExtension(pb extendableProto, extension *ExtensionDesc) bool { - // TODO: Check types, field numbers, etc.? - if epb, doki := pb.(extensionsMap); doki { - _, ok := epb.ExtensionMap()[extension.Field] - return ok - } else if epb, doki := pb.(extensionsBytes); doki { +func HasExtension(pb Message, extension *ExtensionDesc) bool { + if epb, doki := pb.(extensionsBytes); doki { ext := epb.GetExtensions() buf := *ext o := 0 @@ -258,7 +365,19 @@ func HasExtension(pb extendableProto, extension *ExtensionDesc) bool { } return false } - panic("unreachable") + // TODO: Check types, field numbers, etc.? + epb, ok := extendable(pb) + if !ok { + return false + } + extmap, mu := epb.extensionsRead() + if extmap == nil { + return false + } + mu.Lock() + _, ok = extmap[extension.Field] + mu.Unlock() + return ok } func deleteExtension(pb extensionsBytes, theFieldNum int32, offset int) int { @@ -281,64 +400,32 @@ func deleteExtension(pb extensionsBytes, theFieldNum int32, offset int) int { return -1 } -func clearExtension(pb extendableProto, fieldNum int32) { - if epb, doki := pb.(extensionsMap); doki { - delete(epb.ExtensionMap(), fieldNum) - } else if epb, doki := pb.(extensionsBytes); doki { +// ClearExtension removes the given extension from pb. +func ClearExtension(pb Message, extension *ExtensionDesc) { + clearExtension(pb, extension.Field) +} + +func clearExtension(pb Message, fieldNum int32) { + if epb, doki := pb.(extensionsBytes); doki { offset := 0 for offset != -1 { offset = deleteExtension(epb, fieldNum, offset) } - } else { - panic("unreachable") + return + } + epb, ok := extendable(pb) + if !ok { + return } -} - -// ClearExtension removes the given extension from pb. -func ClearExtension(pb extendableProto, extension *ExtensionDesc) { // TODO: Check types, field numbers, etc.? - clearExtension(pb, extension.Field) + extmap := epb.extensionsWrite() + delete(extmap, fieldNum) } // GetExtension parses and returns the given extension of pb. -// If the extension is not present it returns ErrMissingExtension. -func GetExtension(pb extendableProto, extension *ExtensionDesc) (interface{}, error) { - if err := checkExtensionTypes(pb, extension); err != nil { - return nil, err - } - - if epb, doki := pb.(extensionsMap); doki { - emap := epb.ExtensionMap() - e, ok := emap[extension.Field] - if !ok { - // defaultExtensionValue returns the default value or - // ErrMissingExtension if there is no default. - return defaultExtensionValue(extension) - } - if e.value != nil { - // Already decoded. Check the descriptor, though. - if e.desc != extension { - // This shouldn't happen. If it does, it means that - // GetExtension was called twice with two different - // descriptors with the same field number. - return nil, errors.New("proto: descriptor conflict") - } - return e.value, nil - } - - v, err := decodeExtension(e.enc, extension) - if err != nil { - return nil, err - } - - // Remember the decoded version and drop the encoded version. - // That way it is safe to mutate what we return. - e.value = v - e.desc = extension - e.enc = nil - emap[extension.Field] = e - return e.value, nil - } else if epb, doki := pb.(extensionsBytes); doki { +// If the extension is not present and has no default value it returns ErrMissingExtension. +func GetExtension(pb Message, extension *ExtensionDesc) (interface{}, error) { + if epb, doki := pb.(extensionsBytes); doki { ext := epb.GetExtensions() o := 0 for o < len(*ext) { @@ -360,7 +447,50 @@ func GetExtension(pb extendableProto, extension *ExtensionDesc) (interface{}, er } return defaultExtensionValue(extension) } - panic("unreachable") + epb, ok := extendable(pb) + if !ok { + return nil, errors.New("proto: not an extendable proto") + } + if err := checkExtensionTypes(epb, extension); err != nil { + return nil, err + } + + emap, mu := epb.extensionsRead() + if emap == nil { + return defaultExtensionValue(extension) + } + mu.Lock() + defer mu.Unlock() + e, ok := emap[extension.Field] + if !ok { + // defaultExtensionValue returns the default value or + // ErrMissingExtension if there is no default. + return defaultExtensionValue(extension) + } + + if e.value != nil { + // Already decoded. Check the descriptor, though. + if e.desc != extension { + // This shouldn't happen. If it does, it means that + // GetExtension was called twice with two different + // descriptors with the same field number. + return nil, errors.New("proto: descriptor conflict") + } + return e.value, nil + } + + v, err := decodeExtension(e.enc, extension) + if err != nil { + return nil, err + } + + // Remember the decoded version and drop the encoded version. + // That way it is safe to mutate what we return. + e.value = v + e.desc = extension + e.enc = nil + emap[extension.Field] = e + return e.value, nil } // defaultExtensionValue returns the default value for extension. @@ -434,14 +564,9 @@ func decodeExtension(b []byte, extension *ExtensionDesc) (interface{}, error) { // GetExtensions returns a slice of the extensions present in pb that are also listed in es. // The returned slice has the same length as es; missing extensions will appear as nil elements. func GetExtensions(pb Message, es []*ExtensionDesc) (extensions []interface{}, err error) { - epb, ok := pb.(extendableProto) - if !ok { - err = errors.New("proto: not an extendable proto") - return - } extensions = make([]interface{}, len(es)) for i, e := range es { - extensions[i], err = GetExtension(epb, e) + extensions[i], err = GetExtension(pb, e) if err == ErrMissingExtension { err = nil } @@ -452,9 +577,58 @@ func GetExtensions(pb Message, es []*ExtensionDesc) (extensions []interface{}, e return } +// ExtensionDescs returns a new slice containing pb's extension descriptors, in undefined order. +// For non-registered extensions, ExtensionDescs returns an incomplete descriptor containing +// just the Field field, which defines the extension's field number. +func ExtensionDescs(pb Message) ([]*ExtensionDesc, error) { + epb, ok := extendable(pb) + if !ok { + return nil, fmt.Errorf("proto: %T is not an extendable proto.Message", pb) + } + registeredExtensions := RegisteredExtensions(pb) + + emap, mu := epb.extensionsRead() + if emap == nil { + return nil, nil + } + mu.Lock() + defer mu.Unlock() + extensions := make([]*ExtensionDesc, 0, len(emap)) + for extid, e := range emap { + desc := e.desc + if desc == nil { + desc = registeredExtensions[extid] + if desc == nil { + desc = &ExtensionDesc{Field: extid} + } + } + + extensions = append(extensions, desc) + } + return extensions, nil +} + // SetExtension sets the specified extension of pb to the specified value. -func SetExtension(pb extendableProto, extension *ExtensionDesc, value interface{}) error { - if err := checkExtensionTypes(pb, extension); err != nil { +func SetExtension(pb Message, extension *ExtensionDesc, value interface{}) error { + if epb, doki := pb.(extensionsBytes); doki { + ClearExtension(pb, extension) + ext := epb.GetExtensions() + et := reflect.TypeOf(extension.ExtensionType) + props := extensionProperties(extension) + p := NewBuffer(nil) + x := reflect.New(et) + x.Elem().Set(reflect.ValueOf(value)) + if err := props.enc(p, props, toStructPointer(x)); err != nil { + return err + } + *ext = append(*ext, p.buf...) + return nil + } + epb, ok := extendable(pb) + if !ok { + return errors.New("proto: not an extendable proto") + } + if err := checkExtensionTypes(epb, extension); err != nil { return err } typ := reflect.TypeOf(extension.ExtensionType) @@ -469,26 +643,27 @@ func SetExtension(pb extendableProto, extension *ExtensionDesc, value interface{ if reflect.ValueOf(value).IsNil() { return fmt.Errorf("proto: SetExtension called with nil value of type %T", value) } - return setExtension(pb, extension, value) + + extmap := epb.extensionsWrite() + extmap[extension.Field] = Extension{desc: extension, value: value} + return nil } -func setExtension(pb extendableProto, extension *ExtensionDesc, value interface{}) error { - if epb, doki := pb.(extensionsMap); doki { - epb.ExtensionMap()[extension.Field] = Extension{desc: extension, value: value} - } else if epb, doki := pb.(extensionsBytes); doki { - ClearExtension(pb, extension) +// ClearAllExtensions clears all extensions from pb. +func ClearAllExtensions(pb Message) { + if epb, doki := pb.(extensionsBytes); doki { ext := epb.GetExtensions() - et := reflect.TypeOf(extension.ExtensionType) - props := extensionProperties(extension) - p := NewBuffer(nil) - x := reflect.New(et) - x.Elem().Set(reflect.ValueOf(value)) - if err := props.enc(p, props, toStructPointer(x)); err != nil { - return err - } - *ext = append(*ext, p.buf...) + *ext = []byte{} + return + } + epb, ok := extendable(pb) + if !ok { + return + } + m := epb.extensionsWrite() + for k := range m { + delete(m, k) } - return nil } // A global registry of extensions. diff --git a/vendor/github.com/gogo/protobuf/proto/extensions_gogo.go b/vendor/github.com/gogo/protobuf/proto/extensions_gogo.go index 86b1fa234..ea6478f00 100644 --- a/vendor/github.com/gogo/protobuf/proto/extensions_gogo.go +++ b/vendor/github.com/gogo/protobuf/proto/extensions_gogo.go @@ -1,5 +1,7 @@ -// Copyright (c) 2013, Vastech SA (PTY) LTD. All rights reserved. -// http://github.com/gogo/protobuf/gogoproto +// Protocol Buffers for Go with Gadgets +// +// Copyright (c) 2013, The GoGo Authors. All rights reserved. +// http://github.com/gogo/protobuf // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are @@ -33,9 +35,10 @@ import ( "reflect" "sort" "strings" + "sync" ) -func GetBoolExtension(pb extendableProto, extension *ExtensionDesc, ifnotset bool) bool { +func GetBoolExtension(pb Message, extension *ExtensionDesc, ifnotset bool) bool { if reflect.ValueOf(pb).IsNil() { return ifnotset } @@ -60,8 +63,12 @@ func (this *Extension) Compare(that *Extension) int { return bytes.Compare(this.enc, that.enc) } +func SizeOfInternalExtension(m extendableProto) (n int) { + return SizeOfExtensionMap(m.extensionsWrite()) +} + func SizeOfExtensionMap(m map[int32]Extension) (n int) { - return sizeExtensionMap(m) + return extensionsMapSize(m) } type sortableMapElem struct { @@ -94,6 +101,10 @@ func (this sortableExtensions) String() string { return "map[" + strings.Join(ss, ",") + "]" } +func StringFromInternalExtension(m extendableProto) string { + return StringFromExtensionsMap(m.extensionsWrite()) +} + func StringFromExtensionsMap(m map[int32]Extension) string { return newSortableExtensionsFromMap(m).String() } @@ -106,8 +117,12 @@ func StringFromExtensionsBytes(ext []byte) string { return StringFromExtensionsMap(m) } +func EncodeInternalExtension(m extendableProto, data []byte) (n int, err error) { + return EncodeExtensionMap(m.extensionsWrite(), data) +} + func EncodeExtensionMap(m map[int32]Extension, data []byte) (n int, err error) { - if err := encodeExtensionMap(m); err != nil { + if err := encodeExtensionsMap(m); err != nil { return 0, err } keys := make([]int, 0, len(m)) @@ -125,7 +140,7 @@ func GetRawExtension(m map[int32]Extension, id int32) ([]byte, error) { if m[id].value == nil || m[id].desc == nil { return m[id].enc, nil } - if err := encodeExtensionMap(m); err != nil { + if err := encodeExtensionsMap(m); err != nil { return nil, err } return m[id].enc, nil @@ -189,15 +204,42 @@ func NewExtension(e []byte) Extension { return ee } -func AppendExtension(e extendableProto, tag int32, buf []byte) { - if ee, eok := e.(extensionsMap); eok { - ext := ee.ExtensionMap()[int32(tag)] // may be missing - ext.enc = append(ext.enc, buf...) - ee.ExtensionMap()[int32(tag)] = ext - } else if ee, eok := e.(extensionsBytes); eok { +func AppendExtension(e Message, tag int32, buf []byte) { + if ee, eok := e.(extensionsBytes); eok { ext := ee.GetExtensions() *ext = append(*ext, buf...) + return } + if ee, eok := e.(extendableProto); eok { + m := ee.extensionsWrite() + ext := m[int32(tag)] // may be missing + ext.enc = append(ext.enc, buf...) + m[int32(tag)] = ext + } +} + +func encodeExtension(e *Extension) error { + if e.value == nil || e.desc == nil { + // Extension is only in its encoded form. + return nil + } + // We don't skip extensions that have an encoded form set, + // because the extension value may have been mutated after + // the last time this function was called. + + et := reflect.TypeOf(e.desc.ExtensionType) + props := extensionProperties(e.desc) + + p := NewBuffer(nil) + // If e.value has type T, the encoder expects a *struct{ X T }. + // Pass a *T with a zero field and hope it all works out. + x := reflect.New(et) + x.Elem().Set(reflect.ValueOf(e.value)) + if err := props.enc(p, props, toStructPointer(x)); err != nil { + return err + } + e.enc = p.buf + return nil } func (this Extension) GoString() string { @@ -209,7 +251,7 @@ func (this Extension) GoString() string { return fmt.Sprintf("proto.NewExtension(%#v)", this.enc) } -func SetUnsafeExtension(pb extendableProto, fieldNum int32, value interface{}) error { +func SetUnsafeExtension(pb Message, fieldNum int32, value interface{}) error { typ := reflect.TypeOf(pb).Elem() ext, ok := extensionMaps[typ] if !ok { @@ -219,10 +261,10 @@ func SetUnsafeExtension(pb extendableProto, fieldNum int32, value interface{}) e if !ok { return errors.New("proto: bad extension number; not in declared ranges") } - return setExtension(pb, desc, value) + return SetExtension(pb, desc, value) } -func GetUnsafeExtension(pb extendableProto, fieldNum int32) (interface{}, error) { +func GetUnsafeExtension(pb Message, fieldNum int32) (interface{}, error) { typ := reflect.TypeOf(pb).Elem() ext, ok := extensionMaps[typ] if !ok { @@ -234,3 +276,19 @@ func GetUnsafeExtension(pb extendableProto, fieldNum int32) (interface{}, error) } return GetExtension(pb, desc) } + +func NewUnsafeXXX_InternalExtensions(m map[int32]Extension) XXX_InternalExtensions { + x := &XXX_InternalExtensions{ + p: new(struct { + mu sync.Mutex + extensionMap map[int32]Extension + }), + } + x.p.extensionMap = m + return *x +} + +func GetUnsafeExtensionsMap(extendable Message) map[int32]Extension { + pb := extendable.(extendableProto) + return pb.extensionsWrite() +} diff --git a/vendor/github.com/gogo/protobuf/proto/lib.go b/vendor/github.com/gogo/protobuf/proto/lib.go index 2e35ae2d2..7580bb45c 100644 --- a/vendor/github.com/gogo/protobuf/proto/lib.go +++ b/vendor/github.com/gogo/protobuf/proto/lib.go @@ -308,7 +308,7 @@ func GetStats() Stats { return stats } // temporary Buffer and are fine for most applications. type Buffer struct { buf []byte // encode/decode byte stream - index int // write point + index int // read point // pools of basic types to amortize allocation. bools []bool @@ -889,6 +889,10 @@ func isProto3Zero(v reflect.Value) bool { return false } +// ProtoPackageIsVersion2 is referenced from generated protocol buffer files +// to assert that that code is compatible with this version of the proto package. +const GoGoProtoPackageIsVersion2 = true + // ProtoPackageIsVersion1 is referenced from generated protocol buffer files // to assert that that code is compatible with this version of the proto package. const GoGoProtoPackageIsVersion1 = true diff --git a/vendor/github.com/gogo/protobuf/proto/lib_gogo.go b/vendor/github.com/gogo/protobuf/proto/lib_gogo.go index a6c2c06b2..4b4f7c909 100644 --- a/vendor/github.com/gogo/protobuf/proto/lib_gogo.go +++ b/vendor/github.com/gogo/protobuf/proto/lib_gogo.go @@ -1,5 +1,7 @@ -// Copyright (c) 2013, Vastech SA (PTY) LTD. All rights reserved. -// http://github.com/gogo/protobuf/gogoproto +// Protocol Buffers for Go with Gadgets +// +// Copyright (c) 2013, The GoGo Authors. All rights reserved. +// http://github.com/gogo/protobuf // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are diff --git a/vendor/github.com/gogo/protobuf/proto/message_set.go b/vendor/github.com/gogo/protobuf/proto/message_set.go index e25e01e63..fd982decd 100644 --- a/vendor/github.com/gogo/protobuf/proto/message_set.go +++ b/vendor/github.com/gogo/protobuf/proto/message_set.go @@ -149,9 +149,21 @@ func skipVarint(buf []byte) []byte { // MarshalMessageSet encodes the extension map represented by m in the message set wire format. // It is called by generated Marshal methods on protocol buffer messages with the message_set_wire_format option. -func MarshalMessageSet(m map[int32]Extension) ([]byte, error) { - if err := encodeExtensionMap(m); err != nil { - return nil, err +func MarshalMessageSet(exts interface{}) ([]byte, error) { + var m map[int32]Extension + switch exts := exts.(type) { + case *XXX_InternalExtensions: + if err := encodeExtensions(exts); err != nil { + return nil, err + } + m, _ = exts.extensionsRead() + case map[int32]Extension: + if err := encodeExtensionsMap(exts); err != nil { + return nil, err + } + m = exts + default: + return nil, errors.New("proto: not an extension map") } // Sort extension IDs to provide a deterministic encoding. @@ -178,7 +190,17 @@ func MarshalMessageSet(m map[int32]Extension) ([]byte, error) { // UnmarshalMessageSet decodes the extension map encoded in buf in the message set wire format. // It is called by generated Unmarshal methods on protocol buffer messages with the message_set_wire_format option. -func UnmarshalMessageSet(buf []byte, m map[int32]Extension) error { +func UnmarshalMessageSet(buf []byte, exts interface{}) error { + var m map[int32]Extension + switch exts := exts.(type) { + case *XXX_InternalExtensions: + m = exts.extensionsWrite() + case map[int32]Extension: + m = exts + default: + return errors.New("proto: not an extension map") + } + ms := new(messageSet) if err := Unmarshal(buf, ms); err != nil { return err @@ -209,7 +231,16 @@ func UnmarshalMessageSet(buf []byte, m map[int32]Extension) error { // MarshalMessageSetJSON encodes the extension map represented by m in JSON format. // It is called by generated MarshalJSON methods on protocol buffer messages with the message_set_wire_format option. -func MarshalMessageSetJSON(m map[int32]Extension) ([]byte, error) { +func MarshalMessageSetJSON(exts interface{}) ([]byte, error) { + var m map[int32]Extension + switch exts := exts.(type) { + case *XXX_InternalExtensions: + m, _ = exts.extensionsRead() + case map[int32]Extension: + m = exts + default: + return nil, errors.New("proto: not an extension map") + } var b bytes.Buffer b.WriteByte('{') @@ -252,7 +283,7 @@ func MarshalMessageSetJSON(m map[int32]Extension) ([]byte, error) { // UnmarshalMessageSetJSON decodes the extension map encoded in buf in JSON format. // It is called by generated UnmarshalJSON methods on protocol buffer messages with the message_set_wire_format option. -func UnmarshalMessageSetJSON(buf []byte, m map[int32]Extension) error { +func UnmarshalMessageSetJSON(buf []byte, exts interface{}) error { // Common-case fast path. if len(buf) == 0 || bytes.Equal(buf, []byte("{}")) { return nil diff --git a/vendor/github.com/gogo/protobuf/proto/pointer_reflect.go b/vendor/github.com/gogo/protobuf/proto/pointer_reflect.go index 749919d25..fb512e2e1 100644 --- a/vendor/github.com/gogo/protobuf/proto/pointer_reflect.go +++ b/vendor/github.com/gogo/protobuf/proto/pointer_reflect.go @@ -29,7 +29,7 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// +build appengine +// +build appengine js // This file contains an implementation of proto field accesses using package reflect. // It is slower than the code in pointer_unsafe.go but it avoids package unsafe and can @@ -139,6 +139,11 @@ func structPointer_StringSlice(p structPointer, f field) *[]string { return structPointer_ifield(p, f).(*[]string) } +// Extensions returns the address of an extension map field in the struct. +func structPointer_Extensions(p structPointer, f field) *XXX_InternalExtensions { + return structPointer_ifield(p, f).(*XXX_InternalExtensions) +} + // ExtMap returns the address of an extension map field in the struct. func structPointer_ExtMap(p structPointer, f field) *map[int32]Extension { return structPointer_ifield(p, f).(*map[int32]Extension) diff --git a/vendor/github.com/gogo/protobuf/proto/pointer_reflect_gogo.go b/vendor/github.com/gogo/protobuf/proto/pointer_reflect_gogo.go new file mode 100644 index 000000000..1763a5f22 --- /dev/null +++ b/vendor/github.com/gogo/protobuf/proto/pointer_reflect_gogo.go @@ -0,0 +1,85 @@ +// Protocol Buffers for Go with Gadgets +// +// Copyright (c) 2016, The GoGo Authors. All rights reserved. +// http://github.com/gogo/protobuf +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// +build appengine js + +package proto + +import ( + "reflect" +) + +func structPointer_FieldPointer(p structPointer, f field) structPointer { + panic("not implemented") +} + +func appendStructPointer(base structPointer, f field, typ reflect.Type) structPointer { + panic("not implemented") +} + +func structPointer_InterfaceAt(p structPointer, f field, t reflect.Type) interface{} { + panic("not implemented") +} + +func structPointer_InterfaceRef(p structPointer, f field, t reflect.Type) interface{} { + panic("not implemented") +} + +func structPointer_GetRefStructPointer(p structPointer, f field) structPointer { + panic("not implemented") +} + +func structPointer_Add(p structPointer, size field) structPointer { + panic("not implemented") +} + +func structPointer_Len(p structPointer, f field) int { + panic("not implemented") +} + +func structPointer_GetSliceHeader(p structPointer, f field) *reflect.SliceHeader { + panic("not implemented") +} + +func structPointer_Copy(oldptr structPointer, newptr structPointer, size int) { + panic("not implemented") +} + +func structPointer_StructRefSlice(p structPointer, f field, size uintptr) *structRefSlice { + panic("not implemented") +} + +type structRefSlice struct{} + +func (v *structRefSlice) Len() int { + panic("not implemented") +} + +func (v *structRefSlice) Index(i int) structPointer { + panic("not implemented") +} diff --git a/vendor/github.com/gogo/protobuf/proto/pointer_unsafe.go b/vendor/github.com/gogo/protobuf/proto/pointer_unsafe.go index e9be0fe92..6b5567d47 100644 --- a/vendor/github.com/gogo/protobuf/proto/pointer_unsafe.go +++ b/vendor/github.com/gogo/protobuf/proto/pointer_unsafe.go @@ -29,7 +29,7 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// +build !appengine +// +build !appengine,!js // This file contains the implementation of the proto field accesses using package unsafe. @@ -126,6 +126,10 @@ func structPointer_StringSlice(p structPointer, f field) *[]string { } // ExtMap returns the address of an extension map field in the struct. +func structPointer_Extensions(p structPointer, f field) *XXX_InternalExtensions { + return (*XXX_InternalExtensions)(unsafe.Pointer(uintptr(p) + uintptr(f))) +} + func structPointer_ExtMap(p structPointer, f field) *map[int32]Extension { return (*map[int32]Extension)(unsafe.Pointer(uintptr(p) + uintptr(f))) } diff --git a/vendor/github.com/gogo/protobuf/proto/pointer_unsafe_gogo.go b/vendor/github.com/gogo/protobuf/proto/pointer_unsafe_gogo.go index 6bc85fa98..f156a29f0 100644 --- a/vendor/github.com/gogo/protobuf/proto/pointer_unsafe_gogo.go +++ b/vendor/github.com/gogo/protobuf/proto/pointer_unsafe_gogo.go @@ -1,5 +1,7 @@ -// Copyright (c) 2013, Vastech SA (PTY) LTD. All rights reserved. -// http://github.com/gogo/protobuf/gogoproto +// Protocol Buffers for Go with Gadgets +// +// Copyright (c) 2013, The GoGo Authors. All rights reserved. +// http://github.com/gogo/protobuf // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are @@ -24,7 +26,7 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// +build !appengine +// +build !appengine,!js // This file contains the implementation of the proto field accesses using package unsafe. @@ -70,16 +72,13 @@ func structPointer_Copy(oldptr structPointer, newptr structPointer, size int) { func appendStructPointer(base structPointer, f field, typ reflect.Type) structPointer { size := typ.Elem().Size() - oldHeader := structPointer_GetSliceHeader(base, f) - newLen := oldHeader.Len + 1 - slice := reflect.MakeSlice(typ, newLen, newLen) - bas := toStructPointer(slice) - for i := 0; i < oldHeader.Len; i++ { - newElemptr := uintptr(bas) + uintptr(i)*size - oldElemptr := oldHeader.Data + uintptr(i)*size - copyUintPtr(oldElemptr, newElemptr, int(size)) - } + oldHeader := structPointer_GetSliceHeader(base, f) + oldSlice := reflect.NewAt(typ, unsafe.Pointer(oldHeader)).Elem() + newLen := oldHeader.Len + 1 + newSlice := reflect.MakeSlice(typ, newLen, newLen) + reflect.Copy(newSlice, oldSlice) + bas := toStructPointer(newSlice) oldHeader.Data = uintptr(bas) oldHeader.Len = newLen oldHeader.Cap = newLen @@ -106,3 +105,24 @@ func structPointer_Add(p structPointer, size field) structPointer { func structPointer_Len(p structPointer, f field) int { return len(*(*[]interface{})(unsafe.Pointer(structPointer_GetRefStructPointer(p, f)))) } + +func structPointer_StructRefSlice(p structPointer, f field, size uintptr) *structRefSlice { + return &structRefSlice{p: p, f: f, size: size} +} + +// A structRefSlice represents a slice of structs (themselves submessages or groups). +type structRefSlice struct { + p structPointer + f field + size uintptr +} + +func (v *structRefSlice) Len() int { + return structPointer_Len(v.p, v.f) +} + +func (v *structRefSlice) Index(i int) structPointer { + ss := structPointer_GetStructPointer(v.p, v.f) + ss1 := structPointer_GetRefStructPointer(ss, 0) + return structPointer_Add(ss1, field(uintptr(i)*v.size)) +} diff --git a/vendor/github.com/gogo/protobuf/proto/properties.go b/vendor/github.com/gogo/protobuf/proto/properties.go index 5e6a0b3ba..44b332052 100644 --- a/vendor/github.com/gogo/protobuf/proto/properties.go +++ b/vendor/github.com/gogo/protobuf/proto/properties.go @@ -1,7 +1,7 @@ -// Extensions for Protocol Buffers to create more go like structures. +// Protocol Buffers for Go with Gadgets // -// Copyright (c) 2013, Vastech SA (PTY) LTD. All rights reserved. -// http://github.com/gogo/protobuf/gogoproto +// Copyright (c) 2013, The GoGo Authors. All rights reserved. +// http://github.com/gogo/protobuf // // Go support for Protocol Buffers - Google's data interchange format // @@ -190,10 +190,11 @@ type Properties struct { proto3 bool // whether this is known to be a proto3 field; set for []byte only oneof bool // whether this is a oneof field - Default string // default value - HasDefault bool // whether an explicit default was provided - CustomType string - def_uint64 uint64 + Default string // default value + HasDefault bool // whether an explicit default was provided + CustomType string + StdTime bool + StdDuration bool enc encoder valEnc valueEncoder // set for bool and numeric types only @@ -340,6 +341,10 @@ func (p *Properties) Parse(s string) { p.OrigName = strings.Split(f, "=")[1] case strings.HasPrefix(f, "customtype="): p.CustomType = strings.Split(f, "=")[1] + case f == "stdtime": + p.StdTime = true + case f == "stdduration": + p.StdDuration = true } } } @@ -355,11 +360,22 @@ func (p *Properties) setEncAndDec(typ reflect.Type, f *reflect.StructField, lock p.enc = nil p.dec = nil p.size = nil - if len(p.CustomType) > 0 { + isMap := typ.Kind() == reflect.Map + if len(p.CustomType) > 0 && !isMap { p.setCustomEncAndDec(typ) p.setTag(lockGetProp) return } + if p.StdTime && !isMap { + p.setTimeEncAndDec(typ) + p.setTag(lockGetProp) + return + } + if p.StdDuration && !isMap { + p.setDurationEncAndDec(typ) + p.setTag(lockGetProp) + return + } switch t1 := typ; t1.Kind() { default: fmt.Fprintf(os.Stderr, "proto: no coders for %v\n", t1) @@ -542,17 +558,13 @@ func (p *Properties) setEncAndDec(typ reflect.Type, f *reflect.StructField, lock p.dec = (*Buffer).dec_slice_int64 p.packedDec = (*Buffer).dec_slice_packed_int64 case reflect.Uint8: - p.enc = (*Buffer).enc_slice_byte p.dec = (*Buffer).dec_slice_byte - p.size = size_slice_byte - // This is a []byte, which is either a bytes field, - // or the value of a map field. In the latter case, - // we always encode an empty []byte, so we should not - // use the proto3 enc/size funcs. - // f == nil iff this is the key/value of a map field. - if p.proto3 && f != nil { + if p.proto3 { p.enc = (*Buffer).enc_proto3_slice_byte p.size = size_proto3_slice_byte + } else { + p.enc = (*Buffer).enc_slice_byte + p.size = size_slice_byte } case reflect.Float32, reflect.Float64: switch t2.Bits() { @@ -634,6 +646,10 @@ func (p *Properties) setEncAndDec(typ reflect.Type, f *reflect.StructField, lock // so we need encoders for the pointer to this type. vtype = reflect.PtrTo(vtype) } + + p.mvalprop.CustomType = p.CustomType + p.mvalprop.StdDuration = p.StdDuration + p.mvalprop.StdTime = p.StdTime p.mvalprop.init(vtype, "Value", f.Tag.Get("protobuf_val"), nil, lockGetProp) } p.setTag(lockGetProp) @@ -744,7 +760,9 @@ func getPropertiesLocked(t reflect.Type) *StructProperties { propertiesMap[t] = prop // build properties - prop.extendable = reflect.PtrTo(t).Implements(extendableProtoType) + prop.extendable = reflect.PtrTo(t).Implements(extendableProtoType) || + reflect.PtrTo(t).Implements(extendableProtoV1Type) || + reflect.PtrTo(t).Implements(extendableBytesType) prop.unrecField = invalidField prop.Prop = make([]*Properties, t.NumField()) prop.order = make([]int, t.NumField()) @@ -756,7 +774,11 @@ func getPropertiesLocked(t reflect.Type) *StructProperties { name := f.Name p.init(f.Type, name, f.Tag.Get("protobuf"), &f, false) - if f.Name == "XXX_extensions" { // special case + if f.Name == "XXX_InternalExtensions" { // special case + p.enc = (*Buffer).enc_exts + p.dec = nil // not needed + p.size = size_exts + } else if f.Name == "XXX_extensions" { // special case if len(f.Tag.Get("protobuf")) > 0 { p.enc = (*Buffer).enc_ext_slice_byte p.dec = nil // not needed @@ -766,13 +788,14 @@ func getPropertiesLocked(t reflect.Type) *StructProperties { p.dec = nil // not needed p.size = size_map } - } - if f.Name == "XXX_unrecognized" { // special case + } else if f.Name == "XXX_unrecognized" { // special case prop.unrecField = toField(&f) } - oneof := f.Tag.Get("protobuf_oneof") != "" // special case - if oneof { + oneof := f.Tag.Get("protobuf_oneof") // special case + if oneof != "" { isOneofMessage = true + // Oneof fields don't use the traditional protobuf tag. + p.OrigName = oneof } prop.Prop[i] = p prop.order[i] = i @@ -783,7 +806,7 @@ func getPropertiesLocked(t reflect.Type) *StructProperties { } print("\n") } - if p.enc == nil && !strings.HasPrefix(f.Name, "XXX_") && !oneof { + if p.enc == nil && !strings.HasPrefix(f.Name, "XXX_") && oneof == "" { fmt.Fprintln(os.Stderr, "proto: no encoder for", f.Name, f.Type.String(), "[GetProperties]") } } @@ -917,7 +940,29 @@ func RegisterType(x Message, name string) { } // MessageName returns the fully-qualified proto name for the given message type. -func MessageName(x Message) string { return revProtoTypes[reflect.TypeOf(x)] } +func MessageName(x Message) string { + type xname interface { + XXX_MessageName() string + } + if m, ok := x.(xname); ok { + return m.XXX_MessageName() + } + return revProtoTypes[reflect.TypeOf(x)] +} // MessageType returns the message type (pointer to struct) for a named message. func MessageType(name string) reflect.Type { return protoTypes[name] } + +// A registry of all linked proto files. +var ( + protoFiles = make(map[string][]byte) // file name => fileDescriptor +) + +// RegisterFile is called from generated code and maps from the +// full file name of a .proto file to its compressed FileDescriptorProto. +func RegisterFile(filename string, fileDescriptor []byte) { + protoFiles[filename] = fileDescriptor +} + +// FileDescriptor returns the compressed FileDescriptorProto for a .proto file. +func FileDescriptor(filename string) []byte { return protoFiles[filename] } diff --git a/vendor/github.com/gogo/protobuf/proto/properties_gogo.go b/vendor/github.com/gogo/protobuf/proto/properties_gogo.go index 8daf9f776..b6b7176c5 100644 --- a/vendor/github.com/gogo/protobuf/proto/properties_gogo.go +++ b/vendor/github.com/gogo/protobuf/proto/properties_gogo.go @@ -1,5 +1,7 @@ -// Copyright (c) 2013, Vastech SA (PTY) LTD. All rights reserved. -// http://github.com/gogo/protobuf/gogoproto +// Protocol Buffers for Go with Gadgets +// +// Copyright (c) 2013, The GoGo Authors. All rights reserved. +// http://github.com/gogo/protobuf // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are @@ -49,6 +51,51 @@ func (p *Properties) setCustomEncAndDec(typ reflect.Type) { } } +func (p *Properties) setDurationEncAndDec(typ reflect.Type) { + if p.Repeated { + if typ.Elem().Kind() == reflect.Ptr { + p.enc = (*Buffer).enc_slice_duration + p.dec = (*Buffer).dec_slice_duration + p.size = size_slice_duration + } else { + p.enc = (*Buffer).enc_slice_ref_duration + p.dec = (*Buffer).dec_slice_ref_duration + p.size = size_slice_ref_duration + } + } else if typ.Kind() == reflect.Ptr { + p.enc = (*Buffer).enc_duration + p.dec = (*Buffer).dec_duration + p.size = size_duration + } else { + p.enc = (*Buffer).enc_ref_duration + p.dec = (*Buffer).dec_ref_duration + p.size = size_ref_duration + } +} + +func (p *Properties) setTimeEncAndDec(typ reflect.Type) { + if p.Repeated { + if typ.Elem().Kind() == reflect.Ptr { + p.enc = (*Buffer).enc_slice_time + p.dec = (*Buffer).dec_slice_time + p.size = size_slice_time + } else { + p.enc = (*Buffer).enc_slice_ref_time + p.dec = (*Buffer).dec_slice_ref_time + p.size = size_slice_ref_time + } + } else if typ.Kind() == reflect.Ptr { + p.enc = (*Buffer).enc_time + p.dec = (*Buffer).dec_time + p.size = size_time + } else { + p.enc = (*Buffer).enc_ref_time + p.dec = (*Buffer).dec_ref_time + p.size = size_ref_time + } + +} + func (p *Properties) setSliceOfNonPointerStructs(typ reflect.Type) { t2 := typ.Elem() p.sstype = typ diff --git a/vendor/github.com/gogo/protobuf/proto/skip_gogo.go b/vendor/github.com/gogo/protobuf/proto/skip_gogo.go index 4fe7e0815..5a5fd93f7 100644 --- a/vendor/github.com/gogo/protobuf/proto/skip_gogo.go +++ b/vendor/github.com/gogo/protobuf/proto/skip_gogo.go @@ -1,5 +1,7 @@ -// Copyright (c) 2013, Vastech SA (PTY) LTD. All rights reserved. -// http://github.com/gogo/protobuf/gogoproto +// Protocol Buffers for Go with Gadgets +// +// Copyright (c) 2013, The GoGo Authors. All rights reserved. +// http://github.com/gogo/protobuf // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are diff --git a/vendor/github.com/gogo/protobuf/proto/text.go b/vendor/github.com/gogo/protobuf/proto/text.go index b60be28ab..d63732fcb 100644 --- a/vendor/github.com/gogo/protobuf/proto/text.go +++ b/vendor/github.com/gogo/protobuf/proto/text.go @@ -1,7 +1,7 @@ -// Extensions for Protocol Buffers to create more go like structures. +// Protocol Buffers for Go with Gadgets // -// Copyright (c) 2013, Vastech SA (PTY) LTD. All rights reserved. -// http://github.com/gogo/protobuf/gogoproto +// Copyright (c) 2013, The GoGo Authors. All rights reserved. +// http://github.com/gogo/protobuf // // Go support for Protocol Buffers - Google's data interchange format // @@ -50,6 +50,8 @@ import ( "reflect" "sort" "strings" + "sync" + "time" ) var ( @@ -159,7 +161,7 @@ func (w *textWriter) indent() { w.ind++ } func (w *textWriter) unindent() { if w.ind == 0 { - log.Printf("proto: textWriter unindented too far") + log.Print("proto: textWriter unindented too far") return } w.ind-- @@ -180,7 +182,93 @@ type raw interface { Bytes() []byte } -func writeStruct(w *textWriter, sv reflect.Value) error { +func requiresQuotes(u string) bool { + // When type URL contains any characters except [0-9A-Za-z./\-]*, it must be quoted. + for _, ch := range u { + switch { + case ch == '.' || ch == '/' || ch == '_': + continue + case '0' <= ch && ch <= '9': + continue + case 'A' <= ch && ch <= 'Z': + continue + case 'a' <= ch && ch <= 'z': + continue + default: + return true + } + } + return false +} + +// isAny reports whether sv is a google.protobuf.Any message +func isAny(sv reflect.Value) bool { + type wkt interface { + XXX_WellKnownType() string + } + t, ok := sv.Addr().Interface().(wkt) + return ok && t.XXX_WellKnownType() == "Any" +} + +// writeProto3Any writes an expanded google.protobuf.Any message. +// +// It returns (false, nil) if sv value can't be unmarshaled (e.g. because +// required messages are not linked in). +// +// It returns (true, error) when sv was written in expanded format or an error +// was encountered. +func (tm *TextMarshaler) writeProto3Any(w *textWriter, sv reflect.Value) (bool, error) { + turl := sv.FieldByName("TypeUrl") + val := sv.FieldByName("Value") + if !turl.IsValid() || !val.IsValid() { + return true, errors.New("proto: invalid google.protobuf.Any message") + } + + b, ok := val.Interface().([]byte) + if !ok { + return true, errors.New("proto: invalid google.protobuf.Any message") + } + + parts := strings.Split(turl.String(), "/") + mt := MessageType(parts[len(parts)-1]) + if mt == nil { + return false, nil + } + m := reflect.New(mt.Elem()) + if err := Unmarshal(b, m.Interface().(Message)); err != nil { + return false, nil + } + w.Write([]byte("[")) + u := turl.String() + if requiresQuotes(u) { + writeString(w, u) + } else { + w.Write([]byte(u)) + } + if w.compact { + w.Write([]byte("]:<")) + } else { + w.Write([]byte("]: <\n")) + w.ind++ + } + if err := tm.writeStruct(w, m.Elem()); err != nil { + return true, err + } + if w.compact { + w.Write([]byte("> ")) + } else { + w.ind-- + w.Write([]byte(">\n")) + } + return true, nil +} + +func (tm *TextMarshaler) writeStruct(w *textWriter, sv reflect.Value) error { + if tm.ExpandAny && isAny(sv) { + if canExpand, err := tm.writeProto3Any(w, sv); canExpand { + return err + } + } st := sv.Type() sprops := GetProperties(st) for i := 0; i < sv.NumField(); i++ { @@ -233,10 +321,10 @@ func writeStruct(w *textWriter, sv reflect.Value) error { continue } if len(props.Enum) > 0 { - if err := writeEnum(w, v, props); err != nil { + if err := tm.writeEnum(w, v, props); err != nil { return err } - } else if err := writeAny(w, v, props); err != nil { + } else if err := tm.writeAny(w, v, props); err != nil { return err } if err := w.WriteByte('\n'); err != nil { @@ -278,7 +366,7 @@ func writeStruct(w *textWriter, sv reflect.Value) error { return err } } - if err := writeAny(w, key, props.mkeyprop); err != nil { + if err := tm.writeAny(w, key, props.mkeyprop); err != nil { return err } if err := w.WriteByte('\n'); err != nil { @@ -295,7 +383,7 @@ func writeStruct(w *textWriter, sv reflect.Value) error { return err } } - if err := writeAny(w, val, props.mvalprop); err != nil { + if err := tm.writeAny(w, val, props.mvalprop); err != nil { return err } if err := w.WriteByte('\n'); err != nil { @@ -367,10 +455,10 @@ func writeStruct(w *textWriter, sv reflect.Value) error { } if len(props.Enum) > 0 { - if err := writeEnum(w, fv, props); err != nil { + if err := tm.writeEnum(w, fv, props); err != nil { return err } - } else if err := writeAny(w, fv, props); err != nil { + } else if err := tm.writeAny(w, fv, props); err != nil { return err } @@ -387,8 +475,8 @@ func writeStruct(w *textWriter, sv reflect.Value) error { pv = reflect.New(sv.Type()) pv.Elem().Set(sv) } - if pv.Type().Implements(extendableProtoType) { - if err := writeExtensions(w, pv); err != nil { + if pv.Type().Implements(extensionRangeType) { + if err := tm.writeExtensions(w, pv); err != nil { return err } } @@ -418,20 +506,45 @@ func writeRaw(w *textWriter, b []byte) error { } // writeAny writes an arbitrary field. -func writeAny(w *textWriter, v reflect.Value, props *Properties) error { +func (tm *TextMarshaler) writeAny(w *textWriter, v reflect.Value, props *Properties) error { v = reflect.Indirect(v) - if props != nil && len(props.CustomType) > 0 { - custom, ok := v.Interface().(Marshaler) - if ok { - data, err := custom.Marshal() + if props != nil { + if len(props.CustomType) > 0 { + custom, ok := v.Interface().(Marshaler) + if ok { + data, err := custom.Marshal() + if err != nil { + return err + } + if err := writeString(w, string(data)); err != nil { + return err + } + return nil + } + } else if props.StdTime { + t, ok := v.Interface().(time.Time) + if !ok { + return fmt.Errorf("stdtime is not time.Time, but %T", v.Interface()) + } + tproto, err := timestampProto(t) if err != nil { return err } - if err := writeString(w, string(data)); err != nil { - return err + props.StdTime = false + err = tm.writeAny(w, reflect.ValueOf(tproto), props) + props.StdTime = true + return err + } else if props.StdDuration { + d, ok := v.Interface().(time.Duration) + if !ok { + return fmt.Errorf("stdtime is not time.Duration, but %T", v.Interface()) } - return nil + dproto := durationProto(d) + props.StdDuration = false + err := tm.writeAny(w, reflect.ValueOf(dproto), props) + props.StdDuration = true + return err } } @@ -481,15 +594,15 @@ func writeAny(w *textWriter, v reflect.Value, props *Properties) error { } } w.indent() - if tm, ok := v.Interface().(encoding.TextMarshaler); ok { - text, err := tm.MarshalText() + if etm, ok := v.Interface().(encoding.TextMarshaler); ok { + text, err := etm.MarshalText() if err != nil { return err } if _, err = w.Write(text); err != nil { return err } - } else if err := writeStruct(w, v); err != nil { + } else if err := tm.writeStruct(w, v); err != nil { return err } w.unindent() @@ -633,30 +746,39 @@ func (s int32Slice) Swap(i, j int) { s[i], s[j] = s[j], s[i] } // writeExtensions writes all the extensions in pv. // pv is assumed to be a pointer to a protocol message struct that is extendable. -func writeExtensions(w *textWriter, pv reflect.Value) error { +func (tm *TextMarshaler) writeExtensions(w *textWriter, pv reflect.Value) error { emap := extensionMaps[pv.Type().Elem()] - ep := pv.Interface().(extendableProto) + e := pv.Interface().(Message) - // Order the extensions by ID. - // This isn't strictly necessary, but it will give us - // canonical output, which will also make testing easier. var m map[int32]Extension - if em, ok := ep.(extensionsMap); ok { - m = em.ExtensionMap() - } else if em, ok := ep.(extensionsBytes); ok { + var mu sync.Locker + if em, ok := e.(extensionsBytes); ok { eb := em.GetExtensions() var err error m, err = BytesToExtensionsMap(*eb) if err != nil { return err } + mu = notLocker{} + } else if _, ok := e.(extendableProto); ok { + ep, _ := extendable(e) + m, mu = ep.extensionsRead() + if m == nil { + return nil + } } + // Order the extensions by ID. + // This isn't strictly necessary, but it will give us + // canonical output, which will also make testing easier. + + mu.Lock() ids := make([]int32, 0, len(m)) for id := range m { ids = append(ids, id) } sort.Sort(int32Slice(ids)) + mu.Unlock() for _, extNum := range ids { ext := m[extNum] @@ -672,20 +794,20 @@ func writeExtensions(w *textWriter, pv reflect.Value) error { continue } - pb, err := GetExtension(ep, desc) + pb, err := GetExtension(e, desc) if err != nil { return fmt.Errorf("failed getting extension: %v", err) } // Repeated extensions will appear as a slice. if !desc.repeated() { - if err := writeExtension(w, desc.Name, pb); err != nil { + if err := tm.writeExtension(w, desc.Name, pb); err != nil { return err } } else { v := reflect.ValueOf(pb) for i := 0; i < v.Len(); i++ { - if err := writeExtension(w, desc.Name, v.Index(i).Interface()); err != nil { + if err := tm.writeExtension(w, desc.Name, v.Index(i).Interface()); err != nil { return err } } @@ -694,7 +816,7 @@ func writeExtensions(w *textWriter, pv reflect.Value) error { return nil } -func writeExtension(w *textWriter, name string, pb interface{}) error { +func (tm *TextMarshaler) writeExtension(w *textWriter, name string, pb interface{}) error { if _, err := fmt.Fprintf(w, "[%s]:", name); err != nil { return err } @@ -703,7 +825,7 @@ func writeExtension(w *textWriter, name string, pb interface{}) error { return err } } - if err := writeAny(w, reflect.ValueOf(pb), nil); err != nil { + if err := tm.writeAny(w, reflect.ValueOf(pb), nil); err != nil { return err } if err := w.WriteByte('\n'); err != nil { @@ -730,12 +852,13 @@ func (w *textWriter) writeIndent() { // TextMarshaler is a configurable text format marshaler. type TextMarshaler struct { - Compact bool // use compact text format (one line). + Compact bool // use compact text format (one line). + ExpandAny bool // expand google.protobuf.Any messages of known types } // Marshal writes a given protocol buffer in text format. // The only errors returned are from w. -func (m *TextMarshaler) Marshal(w io.Writer, pb Message) error { +func (tm *TextMarshaler) Marshal(w io.Writer, pb Message) error { val := reflect.ValueOf(pb) if pb == nil || val.IsNil() { w.Write([]byte("")) @@ -750,11 +873,11 @@ func (m *TextMarshaler) Marshal(w io.Writer, pb Message) error { aw := &textWriter{ w: ww, complete: true, - compact: m.Compact, + compact: tm.Compact, } - if tm, ok := pb.(encoding.TextMarshaler); ok { - text, err := tm.MarshalText() + if etm, ok := pb.(encoding.TextMarshaler); ok { + text, err := etm.MarshalText() if err != nil { return err } @@ -768,7 +891,7 @@ func (m *TextMarshaler) Marshal(w io.Writer, pb Message) error { } // Dereference the received pointer so we don't have outer < and >. v := reflect.Indirect(val) - if err := writeStruct(aw, v); err != nil { + if err := tm.writeStruct(aw, v); err != nil { return err } if bw != nil { @@ -778,9 +901,9 @@ func (m *TextMarshaler) Marshal(w io.Writer, pb Message) error { } // Text is the same as Marshal, but returns the string directly. -func (m *TextMarshaler) Text(pb Message) string { +func (tm *TextMarshaler) Text(pb Message) string { var buf bytes.Buffer - m.Marshal(&buf, pb) + tm.Marshal(&buf, pb) return buf.String() } diff --git a/vendor/github.com/gogo/protobuf/proto/text_gogo.go b/vendor/github.com/gogo/protobuf/proto/text_gogo.go index cdb23373c..1d6c6aa0e 100644 --- a/vendor/github.com/gogo/protobuf/proto/text_gogo.go +++ b/vendor/github.com/gogo/protobuf/proto/text_gogo.go @@ -1,5 +1,7 @@ -// Copyright (c) 2013, Vastech SA (PTY) LTD. All rights reserved. -// http://github.com/gogo/protobuf/gogoproto +// Protocol Buffers for Go with Gadgets +// +// Copyright (c) 2013, The GoGo Authors. All rights reserved. +// http://github.com/gogo/protobuf // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are @@ -31,10 +33,10 @@ import ( "reflect" ) -func writeEnum(w *textWriter, v reflect.Value, props *Properties) error { +func (tm *TextMarshaler) writeEnum(w *textWriter, v reflect.Value, props *Properties) error { m, ok := enumStringMaps[props.Enum] if !ok { - if err := writeAny(w, v, props); err != nil { + if err := tm.writeAny(w, v, props); err != nil { return err } } @@ -46,7 +48,7 @@ func writeEnum(w *textWriter, v reflect.Value, props *Properties) error { } s, ok := m[key] if !ok { - if err := writeAny(w, v, props); err != nil { + if err := tm.writeAny(w, v, props); err != nil { return err } } diff --git a/vendor/github.com/gogo/protobuf/proto/text_parser.go b/vendor/github.com/gogo/protobuf/proto/text_parser.go index 61b4bc8cc..9db12e960 100644 --- a/vendor/github.com/gogo/protobuf/proto/text_parser.go +++ b/vendor/github.com/gogo/protobuf/proto/text_parser.go @@ -1,7 +1,7 @@ -// Extensions for Protocol Buffers to create more go like structures. +// Protocol Buffers for Go with Gadgets // -// Copyright (c) 2013, Vastech SA (PTY) LTD. All rights reserved. -// http://github.com/gogo/protobuf/gogoproto +// Copyright (c) 2013, The GoGo Authors. All rights reserved. +// http://github.com/gogo/protobuf // // Go support for Protocol Buffers - Google's data interchange format // @@ -46,9 +46,13 @@ import ( "reflect" "strconv" "strings" + "time" "unicode/utf8" ) +// Error string emitted when deserializing Any and fields are already set +const anyRepeatedlyUnpacked = "Any message unpacked multiple times, or %q already set" + type ParseError struct { Message string Line int // 1-based line number @@ -168,7 +172,7 @@ func (p *textParser) advance() { p.cur.offset, p.cur.line = p.offset, p.line p.cur.unquoted = "" switch p.s[0] { - case '<', '>', '{', '}', ':', '[', ']', ';', ',': + case '<', '>', '{', '}', ':', '[', ']', ';', ',', '/': // Single symbol p.cur.value, p.s = p.s[0:1], p.s[1:len(p.s)] case '"', '\'': @@ -456,7 +460,10 @@ func (p *textParser) readStruct(sv reflect.Value, terminator string) error { fieldSet := make(map[string]bool) // A struct is a sequence of "name: value", terminated by one of // '>' or '}', or the end of the input. A name may also be - // "[extension]". + // "[extension]" or "[type/url]". + // + // The whole struct can also be an expanded Any message, like: + // [type/url] < ... struct contents ... > for { tok := p.next() if tok.err != nil { @@ -466,33 +473,74 @@ func (p *textParser) readStruct(sv reflect.Value, terminator string) error { break } if tok.value == "[" { - // Looks like an extension. + // Looks like an extension or an Any. // // TODO: Check whether we need to handle // namespace rooted names (e.g. ".something.Foo"). - tok = p.next() - if tok.err != nil { - return tok.err + extName, err := p.consumeExtName() + if err != nil { + return err } + + if s := strings.LastIndex(extName, "/"); s >= 0 { + // If it contains a slash, it's an Any type URL. + messageName := extName[s+1:] + mt := MessageType(messageName) + if mt == nil { + return p.errorf("unrecognized message %q in google.protobuf.Any", messageName) + } + tok = p.next() + if tok.err != nil { + return tok.err + } + // consume an optional colon + if tok.value == ":" { + tok = p.next() + if tok.err != nil { + return tok.err + } + } + var terminator string + switch tok.value { + case "<": + terminator = ">" + case "{": + terminator = "}" + default: + return p.errorf("expected '{' or '<', found %q", tok.value) + } + v := reflect.New(mt.Elem()) + if pe := p.readStruct(v.Elem(), terminator); pe != nil { + return pe + } + b, err := Marshal(v.Interface().(Message)) + if err != nil { + return p.errorf("failed to marshal message of type %q: %v", messageName, err) + } + if fieldSet["type_url"] { + return p.errorf(anyRepeatedlyUnpacked, "type_url") + } + if fieldSet["value"] { + return p.errorf(anyRepeatedlyUnpacked, "value") + } + sv.FieldByName("TypeUrl").SetString(extName) + sv.FieldByName("Value").SetBytes(b) + fieldSet["type_url"] = true + fieldSet["value"] = true + continue + } + var desc *ExtensionDesc // This could be faster, but it's functional. // TODO: Do something smarter than a linear scan. for _, d := range RegisteredExtensions(reflect.New(st).Interface().(Message)) { - if d.Name == tok.value { + if d.Name == extName { desc = d break } } if desc == nil { - return p.errorf("unrecognized extension %q", tok.value) - } - // Check the extension terminator. - tok = p.next() - if tok.err != nil { - return tok.err - } - if tok.value != "]" { - return p.errorf("unrecognized extension terminator %q", tok.value) + return p.errorf("unrecognized extension %q", extName) } props := &Properties{} @@ -519,7 +567,7 @@ func (p *textParser) readStruct(sv reflect.Value, terminator string) error { } reqFieldErr = err } - ep := sv.Addr().Interface().(extendableProto) + ep := sv.Addr().Interface().(Message) if !rep { SetExtension(ep, desc, ext.Interface()) } else { @@ -550,7 +598,11 @@ func (p *textParser) readStruct(sv reflect.Value, terminator string) error { props = oop.Prop nv := reflect.New(oop.Type.Elem()) dst = nv.Elem().Field(0) - sv.Field(oop.Field).Set(nv) + field := sv.Field(oop.Field) + if !field.IsNil() { + return p.errorf("field '%s' would overwrite already parsed oneof '%s'", name, sv.Type().Field(oop.Field).Name) + } + field.Set(nv) } if !dst.IsValid() { return p.errorf("unknown field name %q in %v", name, st) @@ -571,8 +623,9 @@ func (p *textParser) readStruct(sv reflect.Value, terminator string) error { // The map entry should be this sequence of tokens: // < key : KEY value : VALUE > - // Technically the "key" and "value" could come in any order, - // but in practice they won't. + // However, implementations may omit key or value, and technically + // we should support them in any order. See b/28924776 for a time + // this went wrong. tok := p.next() var terminator string @@ -584,32 +637,39 @@ func (p *textParser) readStruct(sv reflect.Value, terminator string) error { default: return p.errorf("expected '{' or '<', found %q", tok.value) } - if err := p.consumeToken("key"); err != nil { - return err - } - if err := p.consumeToken(":"); err != nil { - return err - } - if err := p.readAny(key, props.mkeyprop); err != nil { - return err - } - if err := p.consumeOptionalSeparator(); err != nil { - return err - } - if err := p.consumeToken("value"); err != nil { - return err - } - if err := p.checkForColon(props.mvalprop, dst.Type().Elem()); err != nil { - return err - } - if err := p.readAny(val, props.mvalprop); err != nil { - return err - } - if err := p.consumeOptionalSeparator(); err != nil { - return err - } - if err := p.consumeToken(terminator); err != nil { - return err + for { + tok := p.next() + if tok.err != nil { + return tok.err + } + if tok.value == terminator { + break + } + switch tok.value { + case "key": + if err := p.consumeToken(":"); err != nil { + return err + } + if err := p.readAny(key, props.mkeyprop); err != nil { + return err + } + if err := p.consumeOptionalSeparator(); err != nil { + return err + } + case "value": + if err := p.checkForColon(props.mvalprop, dst.Type().Elem()); err != nil { + return err + } + if err := p.readAny(val, props.mvalprop); err != nil { + return err + } + if err := p.consumeOptionalSeparator(); err != nil { + return err + } + default: + p.back() + return p.errorf(`expected "key", "value", or %q, found %q`, terminator, tok.value) + } } dst.SetMapIndex(key, val) @@ -632,7 +692,8 @@ func (p *textParser) readStruct(sv reflect.Value, terminator string) error { return err } reqFieldErr = err - } else if props.Required { + } + if props.Required { reqCount-- } @@ -648,6 +709,35 @@ func (p *textParser) readStruct(sv reflect.Value, terminator string) error { return reqFieldErr } +// consumeExtName consumes extension name or expanded Any type URL and the +// following ']'. It returns the name or URL consumed. +func (p *textParser) consumeExtName() (string, error) { + tok := p.next() + if tok.err != nil { + return "", tok.err + } + + // If extension name or type url is quoted, it's a single token. + if len(tok.value) > 2 && isQuote(tok.value[0]) && tok.value[len(tok.value)-1] == tok.value[0] { + name, err := unquoteC(tok.value[1:len(tok.value)-1], rune(tok.value[0])) + if err != nil { + return "", err + } + return name, p.consumeToken("]") + } + + // Consume everything up to "]" + var parts []string + for tok.value != "]" { + parts = append(parts, tok.value) + tok = p.next() + if tok.err != nil { + return "", p.errorf("unrecognized type_url or extension name: %s", tok.err) + } + } + return strings.Join(parts, ""), nil +} + // consumeOptionalSeparator consumes an optional semicolon or comma. // It is used in readStruct to provide backward compatibility. func (p *textParser) consumeOptionalSeparator() error { @@ -708,6 +798,80 @@ func (p *textParser) readAny(v reflect.Value, props *Properties) error { } return nil } + if props.StdTime { + fv := v + p.back() + props.StdTime = false + tproto := ×tamp{} + err := p.readAny(reflect.ValueOf(tproto).Elem(), props) + props.StdTime = true + if err != nil { + return err + } + tim, err := timestampFromProto(tproto) + if err != nil { + return err + } + if props.Repeated { + t := reflect.TypeOf(v.Interface()) + if t.Kind() == reflect.Slice { + if t.Elem().Kind() == reflect.Ptr { + ts := fv.Interface().([]*time.Time) + ts = append(ts, &tim) + fv.Set(reflect.ValueOf(ts)) + return nil + } else { + ts := fv.Interface().([]time.Time) + ts = append(ts, tim) + fv.Set(reflect.ValueOf(ts)) + return nil + } + } + } + if reflect.TypeOf(v.Interface()).Kind() == reflect.Ptr { + v.Set(reflect.ValueOf(&tim)) + } else { + v.Set(reflect.Indirect(reflect.ValueOf(&tim))) + } + return nil + } + if props.StdDuration { + fv := v + p.back() + props.StdDuration = false + dproto := &duration{} + err := p.readAny(reflect.ValueOf(dproto).Elem(), props) + props.StdDuration = true + if err != nil { + return err + } + dur, err := durationFromProto(dproto) + if err != nil { + return err + } + if props.Repeated { + t := reflect.TypeOf(v.Interface()) + if t.Kind() == reflect.Slice { + if t.Elem().Kind() == reflect.Ptr { + ds := fv.Interface().([]*time.Duration) + ds = append(ds, &dur) + fv.Set(reflect.ValueOf(ds)) + return nil + } else { + ds := fv.Interface().([]time.Duration) + ds = append(ds, dur) + fv.Set(reflect.ValueOf(ds)) + return nil + } + } + } + if reflect.TypeOf(v.Interface()).Kind() == reflect.Ptr { + v.Set(reflect.ValueOf(&dur)) + } else { + v.Set(reflect.Indirect(reflect.ValueOf(&dur))) + } + return nil + } switch fv := v; fv.Kind() { case reflect.Slice: at := v.Type() @@ -750,12 +914,12 @@ func (p *textParser) readAny(v reflect.Value, props *Properties) error { fv.Set(reflect.Append(fv, reflect.New(at.Elem()).Elem())) return p.readAny(fv.Index(fv.Len()-1), props) case reflect.Bool: - // Either "true", "false", 1 or 0. + // true/1/t/True or false/f/0/False. switch tok.value { - case "true", "1": + case "true", "1", "t", "True": fv.SetBool(true) return nil - case "false", "0": + case "false", "0", "f", "False": fv.SetBool(false) return nil } diff --git a/vendor/github.com/gogo/protobuf/proto/timestamp.go b/vendor/github.com/gogo/protobuf/proto/timestamp.go new file mode 100644 index 000000000..9324f6542 --- /dev/null +++ b/vendor/github.com/gogo/protobuf/proto/timestamp.go @@ -0,0 +1,113 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2016 The Go Authors. All rights reserved. +// https://github.com/golang/protobuf +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package proto + +// This file implements operations on google.protobuf.Timestamp. + +import ( + "errors" + "fmt" + "time" +) + +const ( + // Seconds field of the earliest valid Timestamp. + // This is time.Date(1, 1, 1, 0, 0, 0, 0, time.UTC).Unix(). + minValidSeconds = -62135596800 + // Seconds field just after the latest valid Timestamp. + // This is time.Date(10000, 1, 1, 0, 0, 0, 0, time.UTC).Unix(). + maxValidSeconds = 253402300800 +) + +// validateTimestamp determines whether a Timestamp is valid. +// A valid timestamp represents a time in the range +// [0001-01-01, 10000-01-01) and has a Nanos field +// in the range [0, 1e9). +// +// If the Timestamp is valid, validateTimestamp returns nil. +// Otherwise, it returns an error that describes +// the problem. +// +// Every valid Timestamp can be represented by a time.Time, but the converse is not true. +func validateTimestamp(ts *timestamp) error { + if ts == nil { + return errors.New("timestamp: nil Timestamp") + } + if ts.Seconds < minValidSeconds { + return fmt.Errorf("timestamp: %#v before 0001-01-01", ts) + } + if ts.Seconds >= maxValidSeconds { + return fmt.Errorf("timestamp: %#v after 10000-01-01", ts) + } + if ts.Nanos < 0 || ts.Nanos >= 1e9 { + return fmt.Errorf("timestamp: %#v: nanos not in range [0, 1e9)", ts) + } + return nil +} + +// TimestampFromProto converts a google.protobuf.Timestamp proto to a time.Time. +// It returns an error if the argument is invalid. +// +// Unlike most Go functions, if Timestamp returns an error, the first return value +// is not the zero time.Time. Instead, it is the value obtained from the +// time.Unix function when passed the contents of the Timestamp, in the UTC +// locale. This may or may not be a meaningful time; many invalid Timestamps +// do map to valid time.Times. +// +// A nil Timestamp returns an error. The first return value in that case is +// undefined. +func timestampFromProto(ts *timestamp) (time.Time, error) { + // Don't return the zero value on error, because corresponds to a valid + // timestamp. Instead return whatever time.Unix gives us. + var t time.Time + if ts == nil { + t = time.Unix(0, 0).UTC() // treat nil like the empty Timestamp + } else { + t = time.Unix(ts.Seconds, int64(ts.Nanos)).UTC() + } + return t, validateTimestamp(ts) +} + +// TimestampProto converts the time.Time to a google.protobuf.Timestamp proto. +// It returns an error if the resulting Timestamp is invalid. +func timestampProto(t time.Time) (*timestamp, error) { + seconds := t.Unix() + nanos := int32(t.Sub(time.Unix(seconds, 0))) + ts := ×tamp{ + Seconds: seconds, + Nanos: nanos, + } + if err := validateTimestamp(ts); err != nil { + return nil, err + } + return ts, nil +} diff --git a/vendor/github.com/gogo/protobuf/proto/timestamp_gogo.go b/vendor/github.com/gogo/protobuf/proto/timestamp_gogo.go new file mode 100644 index 000000000..d42764743 --- /dev/null +++ b/vendor/github.com/gogo/protobuf/proto/timestamp_gogo.go @@ -0,0 +1,229 @@ +// Protocol Buffers for Go with Gadgets +// +// Copyright (c) 2016, The GoGo Authors. All rights reserved. +// http://github.com/gogo/protobuf +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package proto + +import ( + "reflect" + "time" +) + +var timeType = reflect.TypeOf((*time.Time)(nil)).Elem() + +type timestamp struct { + Seconds int64 `protobuf:"varint,1,opt,name=seconds,proto3" json:"seconds,omitempty"` + Nanos int32 `protobuf:"varint,2,opt,name=nanos,proto3" json:"nanos,omitempty"` +} + +func (m *timestamp) Reset() { *m = timestamp{} } +func (*timestamp) ProtoMessage() {} +func (*timestamp) String() string { return "timestamp" } + +func init() { + RegisterType((*timestamp)(nil), "gogo.protobuf.proto.timestamp") +} + +func (o *Buffer) decTimestamp() (time.Time, error) { + b, err := o.DecodeRawBytes(true) + if err != nil { + return time.Time{}, err + } + tproto := ×tamp{} + if err := Unmarshal(b, tproto); err != nil { + return time.Time{}, err + } + return timestampFromProto(tproto) +} + +func (o *Buffer) dec_time(p *Properties, base structPointer) error { + t, err := o.decTimestamp() + if err != nil { + return err + } + setPtrCustomType(base, p.field, &t) + return nil +} + +func (o *Buffer) dec_ref_time(p *Properties, base structPointer) error { + t, err := o.decTimestamp() + if err != nil { + return err + } + setCustomType(base, p.field, &t) + return nil +} + +func (o *Buffer) dec_slice_time(p *Properties, base structPointer) error { + t, err := o.decTimestamp() + if err != nil { + return err + } + newBas := appendStructPointer(base, p.field, reflect.SliceOf(reflect.PtrTo(timeType))) + var zero field + setPtrCustomType(newBas, zero, &t) + return nil +} + +func (o *Buffer) dec_slice_ref_time(p *Properties, base structPointer) error { + t, err := o.decTimestamp() + if err != nil { + return err + } + newBas := appendStructPointer(base, p.field, reflect.SliceOf(timeType)) + var zero field + setCustomType(newBas, zero, &t) + return nil +} + +func size_time(p *Properties, base structPointer) (n int) { + structp := structPointer_GetStructPointer(base, p.field) + if structPointer_IsNil(structp) { + return 0 + } + tim := structPointer_Interface(structp, timeType).(*time.Time) + t, err := timestampProto(*tim) + if err != nil { + return 0 + } + size := Size(t) + return size + sizeVarint(uint64(size)) + len(p.tagcode) +} + +func (o *Buffer) enc_time(p *Properties, base structPointer) error { + structp := structPointer_GetStructPointer(base, p.field) + if structPointer_IsNil(structp) { + return ErrNil + } + tim := structPointer_Interface(structp, timeType).(*time.Time) + t, err := timestampProto(*tim) + if err != nil { + return err + } + data, err := Marshal(t) + if err != nil { + return err + } + o.buf = append(o.buf, p.tagcode...) + o.EncodeRawBytes(data) + return nil +} + +func size_ref_time(p *Properties, base structPointer) (n int) { + tim := structPointer_InterfaceAt(base, p.field, timeType).(*time.Time) + t, err := timestampProto(*tim) + if err != nil { + return 0 + } + size := Size(t) + return size + sizeVarint(uint64(size)) + len(p.tagcode) +} + +func (o *Buffer) enc_ref_time(p *Properties, base structPointer) error { + tim := structPointer_InterfaceAt(base, p.field, timeType).(*time.Time) + t, err := timestampProto(*tim) + if err != nil { + return err + } + data, err := Marshal(t) + if err != nil { + return err + } + o.buf = append(o.buf, p.tagcode...) + o.EncodeRawBytes(data) + return nil +} + +func size_slice_time(p *Properties, base structPointer) (n int) { + ptims := structPointer_InterfaceAt(base, p.field, reflect.SliceOf(reflect.PtrTo(timeType))).(*[]*time.Time) + tims := *ptims + for i := 0; i < len(tims); i++ { + if tims[i] == nil { + return 0 + } + tproto, err := timestampProto(*tims[i]) + if err != nil { + return 0 + } + size := Size(tproto) + n += len(p.tagcode) + size + sizeVarint(uint64(size)) + } + return n +} + +func (o *Buffer) enc_slice_time(p *Properties, base structPointer) error { + ptims := structPointer_InterfaceAt(base, p.field, reflect.SliceOf(reflect.PtrTo(timeType))).(*[]*time.Time) + tims := *ptims + for i := 0; i < len(tims); i++ { + if tims[i] == nil { + return errRepeatedHasNil + } + tproto, err := timestampProto(*tims[i]) + if err != nil { + return err + } + data, err := Marshal(tproto) + if err != nil { + return err + } + o.buf = append(o.buf, p.tagcode...) + o.EncodeRawBytes(data) + } + return nil +} + +func size_slice_ref_time(p *Properties, base structPointer) (n int) { + ptims := structPointer_InterfaceAt(base, p.field, reflect.SliceOf(timeType)).(*[]time.Time) + tims := *ptims + for i := 0; i < len(tims); i++ { + tproto, err := timestampProto(tims[i]) + if err != nil { + return 0 + } + size := Size(tproto) + n += len(p.tagcode) + size + sizeVarint(uint64(size)) + } + return n +} + +func (o *Buffer) enc_slice_ref_time(p *Properties, base structPointer) error { + ptims := structPointer_InterfaceAt(base, p.field, reflect.SliceOf(timeType)).(*[]time.Time) + tims := *ptims + for i := 0; i < len(tims); i++ { + tproto, err := timestampProto(tims[i]) + if err != nil { + return err + } + data, err := Marshal(tproto) + if err != nil { + return err + } + o.buf = append(o.buf, p.tagcode...) + o.EncodeRawBytes(data) + } + return nil +} diff --git a/vendor/github.com/gogo/protobuf/sortkeys/sortkeys.go b/vendor/github.com/gogo/protobuf/sortkeys/sortkeys.go index c52878dd5..ceadde6a5 100644 --- a/vendor/github.com/gogo/protobuf/sortkeys/sortkeys.go +++ b/vendor/github.com/gogo/protobuf/sortkeys/sortkeys.go @@ -1,4 +1,6 @@ -// Copyright (c) 2013, Vastech SA (PTY) LTD. All rights reserved. +// Protocol Buffers for Go with Gadgets +// +// Copyright (c) 2013, The GoGo Authors. All rights reserved. // http://github.com/gogo/protobuf // // Redistribution and use in source and binary forms, with or without diff --git a/vendor/github.com/golang/protobuf/jsonpb/jsonpb.go b/vendor/github.com/golang/protobuf/jsonpb/jsonpb.go index 6308548cb..1fc8ae8d7 100644 --- a/vendor/github.com/golang/protobuf/jsonpb/jsonpb.go +++ b/vendor/github.com/golang/protobuf/jsonpb/jsonpb.go @@ -510,41 +510,63 @@ func (m *Marshaler) marshalValue(out *errWriter, prop *proto.Properties, v refle return out.err } +// Unmarshaler is a configurable object for converting from a JSON +// representation to a protocol buffer object. +type Unmarshaler struct { + // Whether to allow messages to contain unknown fields, as opposed to + // failing to unmarshal. + AllowUnknownFields bool +} + // UnmarshalNext unmarshals the next protocol buffer from a JSON object stream. // This function is lenient and will decode any options permutations of the // related Marshaler. -func UnmarshalNext(dec *json.Decoder, pb proto.Message) error { +func (u *Unmarshaler) UnmarshalNext(dec *json.Decoder, pb proto.Message) error { inputValue := json.RawMessage{} if err := dec.Decode(&inputValue); err != nil { return err } - return unmarshalValue(reflect.ValueOf(pb).Elem(), inputValue, nil) + return u.unmarshalValue(reflect.ValueOf(pb).Elem(), inputValue, nil) +} + +// Unmarshal unmarshals a JSON object stream into a protocol +// buffer. This function is lenient and will decode any options +// permutations of the related Marshaler. +func (u *Unmarshaler) Unmarshal(r io.Reader, pb proto.Message) error { + dec := json.NewDecoder(r) + return u.UnmarshalNext(dec, pb) +} + +// UnmarshalNext unmarshals the next protocol buffer from a JSON object stream. +// This function is lenient and will decode any options permutations of the +// related Marshaler. +func UnmarshalNext(dec *json.Decoder, pb proto.Message) error { + return new(Unmarshaler).UnmarshalNext(dec, pb) } // Unmarshal unmarshals a JSON object stream into a protocol // buffer. This function is lenient and will decode any options // permutations of the related Marshaler. func Unmarshal(r io.Reader, pb proto.Message) error { - dec := json.NewDecoder(r) - return UnmarshalNext(dec, pb) + return new(Unmarshaler).Unmarshal(r, pb) } // UnmarshalString will populate the fields of a protocol buffer based // on a JSON string. This function is lenient and will decode any options // permutations of the related Marshaler. func UnmarshalString(str string, pb proto.Message) error { - return Unmarshal(strings.NewReader(str), pb) + return new(Unmarshaler).Unmarshal(strings.NewReader(str), pb) } // unmarshalValue converts/copies a value into the target. // prop may be nil. -func unmarshalValue(target reflect.Value, inputValue json.RawMessage, prop *proto.Properties) error { +func (u *Unmarshaler) unmarshalValue(target reflect.Value, inputValue json.RawMessage, prop *proto.Properties) error { targetType := target.Type() // Allocate memory for pointer fields. if targetType.Kind() == reflect.Ptr { target.Set(reflect.New(targetType.Elem())) - return unmarshalValue(target.Elem(), inputValue, prop) + return u.unmarshalValue(target.Elem(), inputValue, prop) } // Handle well-known types. @@ -559,7 +581,7 @@ func unmarshalValue(target reflect.Value, inputValue json.RawMessage, prop *prot // as the wrapped primitive type, except that null is allowed." // encoding/json will turn JSON `null` into Go `nil`, // so we don't have to do any extra work. - return unmarshalValue(target.Field(0), inputValue, prop) + return u.unmarshalValue(target.Field(0), inputValue, prop) case "Any": return fmt.Errorf("unmarshaling Any not supported yet") case "Duration": @@ -586,11 +608,8 @@ func unmarshalValue(target reflect.Value, inputValue json.RawMessage, prop *prot if err != nil { return fmt.Errorf("bad Timestamp: %v", err) } - ns := t.UnixNano() - s := ns / 1e9 - ns %= 1e9 - target.Field(0).SetInt(s) - target.Field(1).SetInt(ns) + target.Field(0).SetInt(int64(t.Unix())) + target.Field(1).SetInt(int64(t.Nanosecond())) return nil } } @@ -657,7 +676,7 @@ func unmarshalValue(target reflect.Value, inputValue json.RawMessage, prop *prot continue } - if err := unmarshalValue(target.Field(i), valueForField, sprops.Prop[i]); err != nil { + if err := u.unmarshalValue(target.Field(i), valueForField, sprops.Prop[i]); err != nil { return err } } @@ -670,12 +689,12 @@ func unmarshalValue(target reflect.Value, inputValue json.RawMessage, prop *prot } nv := reflect.New(oop.Type.Elem()) target.Field(oop.Field).Set(nv) - if err := unmarshalValue(nv.Elem().Field(0), raw, oop.Prop); err != nil { + if err := u.unmarshalValue(nv.Elem().Field(0), raw, oop.Prop); err != nil { return err } } } - if len(jsonFields) > 0 { + if !u.AllowUnknownFields && len(jsonFields) > 0 { // Pick any field to be the scapegoat. var f string for fname := range jsonFields { @@ -696,7 +715,7 @@ func unmarshalValue(target reflect.Value, inputValue json.RawMessage, prop *prot len := len(slc) target.Set(reflect.MakeSlice(targetType, len, len)) for i := 0; i < len; i++ { - if err := unmarshalValue(target.Index(i), slc[i], prop); err != nil { + if err := u.unmarshalValue(target.Index(i), slc[i], prop); err != nil { return err } } @@ -725,14 +744,14 @@ func unmarshalValue(target reflect.Value, inputValue json.RawMessage, prop *prot k = reflect.ValueOf(ks) } else { k = reflect.New(targetType.Key()).Elem() - if err := unmarshalValue(k, json.RawMessage(ks), keyprop); err != nil { + if err := u.unmarshalValue(k, json.RawMessage(ks), keyprop); err != nil { return err } } // Unmarshal map value. v := reflect.New(targetType.Elem()).Elem() - if err := unmarshalValue(v, raw, valprop); err != nil { + if err := u.unmarshalValue(v, raw, valprop); err != nil { return err } target.SetMapIndex(k, v) @@ -790,10 +809,21 @@ func (w *errWriter) write(str string) { // The easiest way to sort them in some deterministic order is to use fmt. // If this turns out to be inefficient we can always consider other options, // such as doing a Schwartzian transform. +// +// Numeric keys are sorted in numeric order per +// https://developers.google.com/protocol-buffers/docs/proto#maps. type mapKeys []reflect.Value func (s mapKeys) Len() int { return len(s) } func (s mapKeys) Swap(i, j int) { s[i], s[j] = s[j], s[i] } func (s mapKeys) Less(i, j int) bool { + if k := s[i].Kind(); k == s[j].Kind() { + switch k { + case reflect.Int32, reflect.Int64: + return s[i].Int() < s[j].Int() + case reflect.Uint32, reflect.Uint64: + return s[i].Uint() < s[j].Uint() + } + } return fmt.Sprint(s[i].Interface()) < fmt.Sprint(s[j].Interface()) } diff --git a/vendor/github.com/golang/protobuf/proto/decode.go b/vendor/github.com/golang/protobuf/proto/decode.go index 07288a250..aa207298f 100644 --- a/vendor/github.com/golang/protobuf/proto/decode.go +++ b/vendor/github.com/golang/protobuf/proto/decode.go @@ -61,7 +61,6 @@ var ErrInternalBadWireType = errors.New("proto: internal error: bad wiretype for // int32, int64, uint32, uint64, bool, and enum // protocol buffer types. func DecodeVarint(buf []byte) (x uint64, n int) { - // x, n already 0 for shift := uint(0); shift < 64; shift += 7 { if n >= len(buf) { return 0, 0 @@ -78,13 +77,7 @@ func DecodeVarint(buf []byte) (x uint64, n int) { return 0, 0 } -// DecodeVarint reads a varint-encoded integer from the Buffer. -// This is the format for the -// int32, int64, uint32, uint64, bool, and enum -// protocol buffer types. -func (p *Buffer) DecodeVarint() (x uint64, err error) { - // x, err already 0 - +func (p *Buffer) decodeVarintSlow() (x uint64, err error) { i := p.index l := len(p.buf) @@ -107,6 +100,107 @@ func (p *Buffer) DecodeVarint() (x uint64, err error) { return } +// DecodeVarint reads a varint-encoded integer from the Buffer. +// This is the format for the +// int32, int64, uint32, uint64, bool, and enum +// protocol buffer types. +func (p *Buffer) DecodeVarint() (x uint64, err error) { + i := p.index + buf := p.buf + + if i >= len(buf) { + return 0, io.ErrUnexpectedEOF + } else if buf[i] < 0x80 { + p.index++ + return uint64(buf[i]), nil + } else if len(buf)-i < 10 { + return p.decodeVarintSlow() + } + + var b uint64 + // we already checked the first byte + x = uint64(buf[i]) - 0x80 + i++ + + b = uint64(buf[i]) + i++ + x += b << 7 + if b&0x80 == 0 { + goto done + } + x -= 0x80 << 7 + + b = uint64(buf[i]) + i++ + x += b << 14 + if b&0x80 == 0 { + goto done + } + x -= 0x80 << 14 + + b = uint64(buf[i]) + i++ + x += b << 21 + if b&0x80 == 0 { + goto done + } + x -= 0x80 << 21 + + b = uint64(buf[i]) + i++ + x += b << 28 + if b&0x80 == 0 { + goto done + } + x -= 0x80 << 28 + + b = uint64(buf[i]) + i++ + x += b << 35 + if b&0x80 == 0 { + goto done + } + x -= 0x80 << 35 + + b = uint64(buf[i]) + i++ + x += b << 42 + if b&0x80 == 0 { + goto done + } + x -= 0x80 << 42 + + b = uint64(buf[i]) + i++ + x += b << 49 + if b&0x80 == 0 { + goto done + } + x -= 0x80 << 49 + + b = uint64(buf[i]) + i++ + x += b << 56 + if b&0x80 == 0 { + goto done + } + x -= 0x80 << 56 + + b = uint64(buf[i]) + i++ + x += b << 63 + if b&0x80 == 0 { + goto done + } + // x -= 0x80 << 63 // Always zero. + + return 0, errOverflow + +done: + p.index = i + return x, nil +} + // DecodeFixed64 reads a 64-bit integer from the Buffer. // This is the format for the // fixed64, sfixed64, and double protocol buffer types. @@ -340,6 +434,8 @@ func (p *Buffer) DecodeGroup(pb Message) error { // Buffer and places the decoded result in pb. If the struct // underlying pb does not match the data in the buffer, the results can be // unpredictable. +// +// Unlike proto.Unmarshal, this does not reset pb before starting to unmarshal. func (p *Buffer) Unmarshal(pb Message) error { // If the object can unmarshal itself, let it. if u, ok := pb.(Unmarshaler); ok { @@ -378,6 +474,11 @@ func (o *Buffer) unmarshalType(st reflect.Type, prop *StructProperties, is_group wire := int(u & 0x7) if wire == WireEndGroup { if is_group { + if required > 0 { + // Not enough information to determine the exact field. + // (See below.) + return &RequiredNotSetError{"{Unknown}"} + } return nil // input is satisfied } return fmt.Errorf("proto: %s: wiretype end group for non-group", st) diff --git a/vendor/github.com/golang/protobuf/proto/encode.go b/vendor/github.com/golang/protobuf/proto/encode.go index 8c1b8fd1f..68b9b30cf 100644 --- a/vendor/github.com/golang/protobuf/proto/encode.go +++ b/vendor/github.com/golang/protobuf/proto/encode.go @@ -234,10 +234,6 @@ func Marshal(pb Message) ([]byte, error) { } p := NewBuffer(nil) err := p.Marshal(pb) - var state errorState - if err != nil && !state.shouldContinue(err, nil) { - return nil, err - } if p.buf == nil && err == nil { // Return a non-nil slice on success. return []byte{}, nil @@ -266,11 +262,8 @@ func (p *Buffer) Marshal(pb Message) error { // Can the object marshal itself? if m, ok := pb.(Marshaler); ok { data, err := m.Marshal() - if err != nil { - return err - } p.buf = append(p.buf, data...) - return nil + return err } t, base, err := getbase(pb) @@ -282,7 +275,7 @@ func (p *Buffer) Marshal(pb Message) error { } if collectStats { - stats.Encode++ + (stats).Encode++ // Parens are to work around a goimports bug. } if len(p.buf) > maxMarshalSize { @@ -309,7 +302,7 @@ func Size(pb Message) (n int) { } if collectStats { - stats.Size++ + (stats).Size++ // Parens are to work around a goimports bug. } return @@ -1014,7 +1007,6 @@ func size_slice_struct_message(p *Properties, base structPointer) (n int) { if p.isMarshaler { m := structPointer_Interface(structp, p.stype).(Marshaler) data, _ := m.Marshal() - n += len(p.tagcode) n += sizeRawBytes(data) continue } diff --git a/vendor/github.com/golang/protobuf/proto/equal.go b/vendor/github.com/golang/protobuf/proto/equal.go index 8b16f951c..2ed1cf596 100644 --- a/vendor/github.com/golang/protobuf/proto/equal.go +++ b/vendor/github.com/golang/protobuf/proto/equal.go @@ -54,13 +54,17 @@ Equality is defined in this way: in a proto3 .proto file, fields are not "set"; specifically, zero length proto3 "bytes" fields are equal (nil == {}). - Two repeated fields are equal iff their lengths are the same, - and their corresponding elements are equal (a "bytes" field, - although represented by []byte, is not a repeated field) + and their corresponding elements are equal. Note a "bytes" field, + although represented by []byte, is not a repeated field and the + rule for the scalar fields described above applies. - Two unset fields are equal. - Two unknown field sets are equal if their current encoded state is equal. - Two extension sets are equal iff they have corresponding elements that are pairwise equal. + - Two map fields are equal iff their lengths are the same, + and they contain the same set of elements. Zero-length map + fields are equal. - Every other combination of things are not equal. The return value is undefined if a and b are not protocol buffers. diff --git a/vendor/github.com/golang/protobuf/proto/extensions.go b/vendor/github.com/golang/protobuf/proto/extensions.go index 9f484f53a..6b9b36374 100644 --- a/vendor/github.com/golang/protobuf/proto/extensions.go +++ b/vendor/github.com/golang/protobuf/proto/extensions.go @@ -489,6 +489,37 @@ func GetExtensions(pb Message, es []*ExtensionDesc) (extensions []interface{}, e return } +// ExtensionDescs returns a new slice containing pb's extension descriptors, in undefined order. +// For non-registered extensions, ExtensionDescs returns an incomplete descriptor containing +// just the Field field, which defines the extension's field number. +func ExtensionDescs(pb Message) ([]*ExtensionDesc, error) { + epb, ok := extendable(pb) + if !ok { + return nil, fmt.Errorf("proto: %T is not an extendable proto.Message", pb) + } + registeredExtensions := RegisteredExtensions(pb) + + emap, mu := epb.extensionsRead() + if emap == nil { + return nil, nil + } + mu.Lock() + defer mu.Unlock() + extensions := make([]*ExtensionDesc, 0, len(emap)) + for extid, e := range emap { + desc := e.desc + if desc == nil { + desc = registeredExtensions[extid] + if desc == nil { + desc = &ExtensionDesc{Field: extid} + } + } + + extensions = append(extensions, desc) + } + return extensions, nil +} + // SetExtension sets the specified extension of pb to the specified value. func SetExtension(pb Message, extension *ExtensionDesc, value interface{}) error { epb, ok := extendable(pb) diff --git a/vendor/github.com/golang/protobuf/proto/lib.go b/vendor/github.com/golang/protobuf/proto/lib.go index 170b8e87d..ac4ddbc07 100644 --- a/vendor/github.com/golang/protobuf/proto/lib.go +++ b/vendor/github.com/golang/protobuf/proto/lib.go @@ -308,7 +308,7 @@ func GetStats() Stats { return stats } // temporary Buffer and are fine for most applications. type Buffer struct { buf []byte // encode/decode byte stream - index int // write point + index int // read point // pools of basic types to amortize allocation. bools []bool diff --git a/vendor/github.com/golang/protobuf/proto/properties.go b/vendor/github.com/golang/protobuf/proto/properties.go index 69ddda8d4..ec2289c00 100644 --- a/vendor/github.com/golang/protobuf/proto/properties.go +++ b/vendor/github.com/golang/protobuf/proto/properties.go @@ -844,7 +844,15 @@ func RegisterType(x Message, name string) { } // MessageName returns the fully-qualified proto name for the given message type. -func MessageName(x Message) string { return revProtoTypes[reflect.TypeOf(x)] } +func MessageName(x Message) string { + type xname interface { + XXX_MessageName() string + } + if m, ok := x.(xname); ok { + return m.XXX_MessageName() + } + return revProtoTypes[reflect.TypeOf(x)] +} // MessageType returns the message type (pointer to struct) for a named message. func MessageType(name string) reflect.Type { return protoTypes[name] } diff --git a/vendor/github.com/golang/protobuf/proto/text.go b/vendor/github.com/golang/protobuf/proto/text.go index 8214ce326..965876bf0 100644 --- a/vendor/github.com/golang/protobuf/proto/text.go +++ b/vendor/github.com/golang/protobuf/proto/text.go @@ -154,7 +154,7 @@ func (w *textWriter) indent() { w.ind++ } func (w *textWriter) unindent() { if w.ind == 0 { - log.Printf("proto: textWriter unindented too far") + log.Print("proto: textWriter unindented too far") return } w.ind-- diff --git a/vendor/github.com/golang/protobuf/proto/text_parser.go b/vendor/github.com/golang/protobuf/proto/text_parser.go index 0b8c59f74..61f83c1e1 100644 --- a/vendor/github.com/golang/protobuf/proto/text_parser.go +++ b/vendor/github.com/golang/protobuf/proto/text_parser.go @@ -44,6 +44,9 @@ import ( "unicode/utf8" ) +// Error string emitted when deserializing Any and fields are already set +const anyRepeatedlyUnpacked = "Any message unpacked multiple times, or %q already set" + type ParseError struct { Message string Line int // 1-based line number @@ -508,8 +511,16 @@ func (p *textParser) readStruct(sv reflect.Value, terminator string) error { if err != nil { return p.errorf("failed to marshal message of type %q: %v", messageName, err) } + if fieldSet["type_url"] { + return p.errorf(anyRepeatedlyUnpacked, "type_url") + } + if fieldSet["value"] { + return p.errorf(anyRepeatedlyUnpacked, "value") + } sv.FieldByName("TypeUrl").SetString(extName) sv.FieldByName("Value").SetBytes(b) + fieldSet["type_url"] = true + fieldSet["value"] = true continue } @@ -581,7 +592,11 @@ func (p *textParser) readStruct(sv reflect.Value, terminator string) error { props = oop.Prop nv := reflect.New(oop.Type.Elem()) dst = nv.Elem().Field(0) - sv.Field(oop.Field).Set(nv) + field := sv.Field(oop.Field) + if !field.IsNil() { + return p.errorf("field '%s' would overwrite already parsed oneof '%s'", name, sv.Type().Field(oop.Field).Name) + } + field.Set(nv) } if !dst.IsValid() { return p.errorf("unknown field name %q in %v", name, st) @@ -781,12 +796,12 @@ func (p *textParser) readAny(v reflect.Value, props *Properties) error { fv.Set(reflect.Append(fv, reflect.New(at.Elem()).Elem())) return p.readAny(fv.Index(fv.Len()-1), props) case reflect.Bool: - // Either "true", "false", 1 or 0. + // true/1/t/True or false/f/0/False. switch tok.value { - case "true", "1": + case "true", "1", "t", "True": fv.SetBool(true) return nil - case "false", "0": + case "false", "0", "f", "False": fv.SetBool(false) return nil } diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/.gitignore b/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/.gitignore new file mode 100644 index 000000000..364c624e6 --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/.gitignore @@ -0,0 +1,198 @@ +# Created by .ignore support plugin (hsz.mobi) +coverage.txt +### Go template +# Compiled Object files, Static and Dynamic libs (Shared Objects) +*.o +*.a +*.so + +# Folders +_obj +_test + +# Architecture specific extensions/prefixes +*.[568vq] +[568vq].out + +*.cgo1.go +*.cgo2.c +_cgo_defun.c +_cgo_gotypes.go +_cgo_export.* + +_testmain.go + +*.exe +*.test +*.prof +### Windows template +# Windows image file caches +Thumbs.db +ehthumbs.db + +# Folder config file +Desktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msm +*.msp + +# Windows shortcuts +*.lnk +### Kate template +# Swap Files # +.*.kate-swp +.swp.* +### SublimeText template +# cache files for sublime text +*.tmlanguage.cache +*.tmPreferences.cache +*.stTheme.cache + +# workspace files are user-specific +*.sublime-workspace + +# project files should be checked into the repository, unless a significant +# proportion of contributors will probably not be using SublimeText +# *.sublime-project + +# sftp configuration file +sftp-config.json +### Linux template +*~ + +# temporary files which can be created if a process still has a handle open of a deleted file +.fuse_hidden* + +# KDE directory preferences +.directory + +# Linux trash folder which might appear on any partition or disk +.Trash-* +### JetBrains template +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific stuff: +.idea +.idea/tasks.xml +.idea/dictionaries +.idea/vcs.xml +.idea/jsLibraryMappings.xml + +# Sensitive or high-churn files: +.idea/dataSources.ids +.idea/dataSources.xml +.idea/dataSources.local.xml +.idea/sqlDataSources.xml +.idea/dynamic.xml +.idea/uiDesigner.xml + +# Gradle: +.idea/gradle.xml +.idea/libraries + +# Mongo Explorer plugin: +.idea/mongoSettings.xml + +## File-based project format: +*.iws + +## Plugin-specific files: + +# IntelliJ +/out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties +### Xcode template +# Xcode +# +# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore + +## Build generated +build/ +DerivedData/ + +## Various settings +*.pbxuser +!default.pbxuser +*.mode1v3 +!default.mode1v3 +*.mode2v3 +!default.mode2v3 +*.perspectivev3 +!default.perspectivev3 +xcuserdata/ + +## Other +*.moved-aside +*.xccheckout +*.xcscmblueprint +### Eclipse template + +.metadata +bin/ +tmp/ +*.tmp +*.bak +*.swp +*~.nib +local.properties +.settings/ +.loadpath +.recommenders + +# Eclipse Core +.project + +# External tool builders +.externalToolBuilders/ + +# Locally stored "Eclipse launch configurations" +*.launch + +# PyDev specific (Python IDE for Eclipse) +*.pydevproject + +# CDT-specific (C/C++ Development Tooling) +.cproject + +# JDT-specific (Eclipse Java Development Tools) +.classpath + +# Java annotation processor (APT) +.factorypath + +# PDT-specific (PHP Development Tools) +.buildpath + +# sbteclipse plugin +.target + +# Tern plugin +.tern-project + +# TeXlipse plugin +.texlipse + +# STS (Spring Tool Suite) +.springBeans + +# Code Recommenders +.recommenders/ + diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/.travis.yml b/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/.travis.yml new file mode 100644 index 000000000..47d7f90b3 --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/.travis.yml @@ -0,0 +1,18 @@ +sudo: false +language: go +go: + - 1.6.x + - 1.7.x + - 1.8.x + +install: + - go get github.com/prometheus/client_golang/prometheus + - go get google.golang.org/grpc + - go get golang.org/x/net/context + - go get github.com/stretchr/testify + +script: + - ./test_all.sh + +after_success: + - bash <(curl -s https://codecov.io/bash) diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/LICENSE b/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/LICENSE new file mode 100644 index 000000000..b2b065037 --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/README.md b/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/README.md new file mode 100644 index 000000000..616547a78 --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/README.md @@ -0,0 +1,247 @@ +# Go gRPC Interceptors for Prometheus monitoring + +[![Travis Build](https://travis-ci.org/grpc-ecosystem/go-grpc-prometheus.svg)](https://travis-ci.org/grpc-ecosystem/go-grpc-prometheus) +[![Go Report Card](https://goreportcard.com/badge/github.com/grpc-ecosystem/go-grpc-prometheus)](http://goreportcard.com/report/grpc-ecosystem/go-grpc-prometheus) +[![GoDoc](http://img.shields.io/badge/GoDoc-Reference-blue.svg)](https://godoc.org/github.com/grpc-ecosystem/go-grpc-prometheus) +[![SourceGraph](https://sourcegraph.com/github.com/grpc-ecosystem/go-grpc-prometheus/-/badge.svg)](https://sourcegraph.com/github.com/grpc-ecosystem/go-grpc-prometheus/?badge) +[![codecov](https://codecov.io/gh/grpc-ecosystem/go-grpc-prometheus/branch/master/graph/badge.svg)](https://codecov.io/gh/grpc-ecosystem/go-grpc-prometheus) +[![Apache 2.0 License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](LICENSE) + +[Prometheus](https://prometheus.io/) monitoring for your [gRPC Go](https://github.com/grpc/grpc-go) servers and clients. + +A sister implementation for [gRPC Java](https://github.com/grpc/grpc-java) (same metrics, same semantics) is in [grpc-ecosystem/java-grpc-prometheus](https://github.com/grpc-ecosystem/java-grpc-prometheus). + +## Interceptors + +[gRPC Go](https://github.com/grpc/grpc-go) recently acquired support for Interceptors, i.e. middleware that is executed +by a gRPC Server before the request is passed onto the user's application logic. It is a perfect way to implement +common patterns: auth, logging and... monitoring. + +To use Interceptors in chains, please see [`go-grpc-middleware`](https://github.com/mwitkow/go-grpc-middleware). + +## Usage + +There are two types of interceptors: client-side and server-side. This package provides monitoring Interceptors for both. + +### Server-side + +```go +import "github.com/grpc-ecosystem/go-grpc-prometheus" +... + // Initialize your gRPC server's interceptor. + myServer := grpc.NewServer( + grpc.StreamInterceptor(grpc_prometheus.StreamServerInterceptor), + grpc.UnaryInterceptor(grpc_prometheus.UnaryServerInterceptor), + ) + // Register your gRPC service implementations. + myservice.RegisterMyServiceServer(s.server, &myServiceImpl{}) + // After all your registrations, make sure all of the Prometheus metrics are initialized. + grpc_prometheus.Register(myServer) + // Register Prometheus metrics handler. + http.Handle("/metrics", prometheus.Handler()) +... +``` + +### Client-side + +```go +import "github.com/grpc-ecosystem/go-grpc-prometheus" +... + clientConn, err = grpc.Dial( + address, + grpc.WithUnaryInterceptor(UnaryClientInterceptor), + grpc.WithStreamInterceptor(StreamClientInterceptor) + ) + client = pb_testproto.NewTestServiceClient(clientConn) + resp, err := client.PingEmpty(s.ctx, &myservice.Request{Msg: "hello"}) +... +``` + +# Metrics + +## Labels + +All server-side metrics start with `grpc_server` as Prometheus subsystem name. All client-side metrics start with `grpc_client`. Both of them have mirror-concepts. Similarly all methods +contain the same rich labels: + + * `grpc_service` - the [gRPC service](http://www.grpc.io/docs/#defining-a-service) name, which is the combination of protobuf `package` and + the `grpc_service` section name. E.g. for `package = mwitkow.testproto` and + `service TestService` the label will be `grpc_service="mwitkow.testproto.TestService"` + * `grpc_method` - the name of the method called on the gRPC service. E.g. + `grpc_method="Ping"` + * `grpc_type` - the gRPC [type of request](http://www.grpc.io/docs/guides/concepts.html#rpc-life-cycle). + Differentiating between the two is important especially for latency measurements. + + - `unary` is single request, single response RPC + - `client_stream` is a multi-request, single response RPC + - `server_stream` is a single request, multi-response RPC + - `bidi_stream` is a multi-request, multi-response RPC + + +Additionally for completed RPCs, the following labels are used: + + * `grpc_code` - the human-readable [gRPC status code](https://github.com/grpc/grpc-go/blob/master/codes/codes.go). + The list of all statuses is to long, but here are some common ones: + + - `OK` - means the RPC was successful + - `IllegalArgument` - RPC contained bad values + - `Internal` - server-side error not disclosed to the clients + +## Counters + +The counters and their up to date documentation is in [server_reporter.go](server_reporter.go) and [client_reporter.go](client_reporter.go) +the respective Prometheus handler (usually `/metrics`). + +For the purpose of this documentation we will only discuss `grpc_server` metrics. The `grpc_client` ones contain mirror concepts. + +For simplicity, let's assume we're tracking a single server-side RPC call of [`mwitkow.testproto.TestService`](examples/testproto/test.proto), +calling the method `PingList`. The call succeeds and returns 20 messages in the stream. + +First, immediately after the server receives the call it will increment the +`grpc_server_started_total` and start the handling time clock (if histograms are enabled). + +```jsoniq +grpc_server_started_total{grpc_method="PingList",grpc_service="mwitkow.testproto.TestService",grpc_type="server_stream"} 1 +``` + +Then the user logic gets invoked. It receives one message from the client containing the request +(it's a `server_stream`): + +```jsoniq +grpc_server_msg_received_total{grpc_method="PingList",grpc_service="mwitkow.testproto.TestService",grpc_type="server_stream"} 1 +``` + +The user logic may return an error, or send multiple messages back to the client. In this case, on +each of the 20 messages sent back, a counter will be incremented: + +```jsoniq +grpc_server_msg_sent_total{grpc_method="PingList",grpc_service="mwitkow.testproto.TestService",grpc_type="server_stream"} 20 +``` + +After the call completes, it's status (`OK` or other [gRPC status code](https://github.com/grpc/grpc-go/blob/master/codes/codes.go)) +and the relevant call labels increment the `grpc_server_handled_total` counter. + +```jsoniq +grpc_server_handled_total{grpc_code="OK",grpc_method="PingList",grpc_service="mwitkow.testproto.TestService",grpc_type="server_stream"} 1 +``` + +## Histograms + +[Prometheus histograms](https://prometheus.io/docs/concepts/metric_types/#histogram) are a great way +to measure latency distributions of your RPCs. However since it is bad practice to have metrics +of [high cardinality](https://prometheus.io/docs/practices/instrumentation/#do-not-overuse-labels)) +the latency monitoring metrics are disabled by default. To enable them please call the following +in your server initialization code: + +```jsoniq +grpc_prometheus.EnableHandlingTimeHistogram() +``` + +After the call completes, it's handling time will be recorded in a [Prometheus histogram](https://prometheus.io/docs/concepts/metric_types/#histogram) +variable `grpc_server_handling_seconds`. It contains three sub-metrics: + + * `grpc_server_handling_seconds_count` - the count of all completed RPCs by status and method + * `grpc_server_handling_seconds_sum` - cumulative time of RPCs by status and method, useful for + calculating average handling times + * `grpc_server_handling_seconds_bucket` - contains the counts of RPCs by status and method in respective + handling-time buckets. These buckets can be used by Prometheus to estimate SLAs (see [here](https://prometheus.io/docs/practices/histograms/)) + +The counter values will look as follows: + +```jsoniq +grpc_server_handling_seconds_bucket{grpc_code="OK",grpc_method="PingList",grpc_service="mwitkow.testproto.TestService",grpc_type="server_stream",le="0.005"} 1 +grpc_server_handling_seconds_bucket{grpc_code="OK",grpc_method="PingList",grpc_service="mwitkow.testproto.TestService",grpc_type="server_stream",le="0.01"} 1 +grpc_server_handling_seconds_bucket{grpc_code="OK",grpc_method="PingList",grpc_service="mwitkow.testproto.TestService",grpc_type="server_stream",le="0.025"} 1 +grpc_server_handling_seconds_bucket{grpc_code="OK",grpc_method="PingList",grpc_service="mwitkow.testproto.TestService",grpc_type="server_stream",le="0.05"} 1 +grpc_server_handling_seconds_bucket{grpc_code="OK",grpc_method="PingList",grpc_service="mwitkow.testproto.TestService",grpc_type="server_stream",le="0.1"} 1 +grpc_server_handling_seconds_bucket{grpc_code="OK",grpc_method="PingList",grpc_service="mwitkow.testproto.TestService",grpc_type="server_stream",le="0.25"} 1 +grpc_server_handling_seconds_bucket{grpc_code="OK",grpc_method="PingList",grpc_service="mwitkow.testproto.TestService",grpc_type="server_stream",le="0.5"} 1 +grpc_server_handling_seconds_bucket{grpc_code="OK",grpc_method="PingList",grpc_service="mwitkow.testproto.TestService",grpc_type="server_stream",le="1"} 1 +grpc_server_handling_seconds_bucket{grpc_code="OK",grpc_method="PingList",grpc_service="mwitkow.testproto.TestService",grpc_type="server_stream",le="2.5"} 1 +grpc_server_handling_seconds_bucket{grpc_code="OK",grpc_method="PingList",grpc_service="mwitkow.testproto.TestService",grpc_type="server_stream",le="5"} 1 +grpc_server_handling_seconds_bucket{grpc_code="OK",grpc_method="PingList",grpc_service="mwitkow.testproto.TestService",grpc_type="server_stream",le="10"} 1 +grpc_server_handling_seconds_bucket{grpc_code="OK",grpc_method="PingList",grpc_service="mwitkow.testproto.TestService",grpc_type="server_stream",le="+Inf"} 1 +grpc_server_handling_seconds_sum{grpc_code="OK",grpc_method="PingList",grpc_service="mwitkow.testproto.TestService",grpc_type="server_stream"} 0.0003866430000000001 +grpc_server_handling_seconds_count{grpc_code="OK",grpc_method="PingList",grpc_service="mwitkow.testproto.TestService",grpc_type="server_stream"} 1 +``` + + +## Useful query examples + +Prometheus philosophy is to provide the most detailed metrics possible to the monitoring system, and +let the aggregations be handled there. The verbosity of above metrics make it possible to have that +flexibility. Here's a couple of useful monitoring queries: + + +### request inbound rate +```jsoniq +sum(rate(grpc_server_started_total{job="foo"}[1m])) by (grpc_service) +``` +For `job="foo"` (common label to differentiate between Prometheus monitoring targets), calculate the +rate of requests per second (1 minute window) for each gRPC `grpc_service` that the job has. Please note +how the `grpc_method` is being omitted here: all methods of a given gRPC service will be summed together. + +### unary request error rate +```jsoniq +sum(rate(grpc_server_handled_total{job="foo",grpc_type="unary",grpc_code!="OK"}[1m])) by (grpc_service) +``` +For `job="foo"`, calculate the per-`grpc_service` rate of `unary` (1:1) RPCs that failed, i.e. the +ones that didn't finish with `OK` code. + +### unary request error percentage +```jsoniq +sum(rate(grpc_server_handled_total{job="foo",grpc_type="unary",grpc_code!="OK"}[1m])) by (grpc_service) + / +sum(rate(grpc_server_started_total{job="foo",grpc_type="unary"}[1m])) by (grpc_service) + * 100.0 +``` +For `job="foo"`, calculate the percentage of failed requests by service. It's easy to notice that +this is a combination of the two above examples. This is an example of a query you would like to +[alert on](https://prometheus.io/docs/alerting/rules/) in your system for SLA violations, e.g. +"no more than 1% requests should fail". + +### average response stream size +```jsoniq +sum(rate(grpc_server_msg_sent_total{job="foo",grpc_type="server_stream"}[10m])) by (grpc_service) + / +sum(rate(grpc_server_started_total{job="foo",grpc_type="server_stream"}[10m])) by (grpc_service) +``` +For `job="foo"` what is the `grpc_service`-wide `10m` average of messages returned for all ` +server_stream` RPCs. This allows you to track the stream sizes returned by your system, e.g. allows +you to track when clients started to send "wide" queries that ret +Note the divisor is the number of started RPCs, in order to account for in-flight requests. + +### 99%-tile latency of unary requests +```jsoniq +histogram_quantile(0.99, + sum(rate(grpc_server_handling_seconds_bucket{job="foo",grpc_type="unary"}[5m])) by (grpc_service,le) +) +``` +For `job="foo"`, returns an 99%-tile [quantile estimation](https://prometheus.io/docs/practices/histograms/#quantiles) +of the handling time of RPCs per service. Please note the `5m` rate, this means that the quantile +estimation will take samples in a rolling `5m` window. When combined with other quantiles +(e.g. 50%, 90%), this query gives you tremendous insight into the responsiveness of your system +(e.g. impact of caching). + +### percentage of slow unary queries (>250ms) +```jsoniq +100.0 - ( +sum(rate(grpc_server_handling_seconds_bucket{job="foo",grpc_type="unary",le="0.25"}[5m])) by (grpc_service) + / +sum(rate(grpc_server_handling_seconds_count{job="foo",grpc_type="unary"}[5m])) by (grpc_service) +) * 100.0 +``` +For `job="foo"` calculate the by-`grpc_service` fraction of slow requests that took longer than `0.25` +seconds. This query is relatively complex, since the Prometheus aggregations use `le` (less or equal) +buckets, meaning that counting "fast" requests fractions is easier. However, simple maths helps. +This is an example of a query you would like to alert on in your system for SLA violations, +e.g. "less than 1% of requests are slower than 250ms". + + +## Status + +This code has been used since August 2015 as the basis for monitoring of *production* gRPC micro services at [Improbable](https://improbable.io). + +## License + +`go-grpc-prometheus` is released under the Apache 2.0 license. See the [LICENSE](LICENSE) file for details. diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/client.go b/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/client.go new file mode 100644 index 000000000..d9e87b2f7 --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/client.go @@ -0,0 +1,72 @@ +// Copyright 2016 Michal Witkowski. All Rights Reserved. +// See LICENSE for licensing terms. + +// gRPC Prometheus monitoring interceptors for client-side gRPC. + +package grpc_prometheus + +import ( + "io" + + "golang.org/x/net/context" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" +) + +// UnaryClientInterceptor is a gRPC client-side interceptor that provides Prometheus monitoring for Unary RPCs. +func UnaryClientInterceptor(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error { + monitor := newClientReporter(Unary, method) + monitor.SentMessage() + err := invoker(ctx, method, req, reply, cc, opts...) + if err != nil { + monitor.ReceivedMessage() + } + monitor.Handled(grpc.Code(err)) + return err +} + +// StreamServerInterceptor is a gRPC client-side interceptor that provides Prometheus monitoring for Streaming RPCs. +func StreamClientInterceptor(ctx context.Context, desc *grpc.StreamDesc, cc *grpc.ClientConn, method string, streamer grpc.Streamer, opts ...grpc.CallOption) (grpc.ClientStream, error) { + monitor := newClientReporter(clientStreamType(desc), method) + clientStream, err := streamer(ctx, desc, cc, method, opts...) + if err != nil { + monitor.Handled(grpc.Code(err)) + return nil, err + } + return &monitoredClientStream{clientStream, monitor}, nil +} + +func clientStreamType(desc *grpc.StreamDesc) grpcType { + if desc.ClientStreams && !desc.ServerStreams { + return ClientStream + } else if !desc.ClientStreams && desc.ServerStreams { + return ServerStream + } + return BidiStream +} + +// monitoredClientStream wraps grpc.ClientStream allowing each Sent/Recv of message to increment counters. +type monitoredClientStream struct { + grpc.ClientStream + monitor *clientReporter +} + +func (s *monitoredClientStream) SendMsg(m interface{}) error { + err := s.ClientStream.SendMsg(m) + if err == nil { + s.monitor.SentMessage() + } + return err +} + +func (s *monitoredClientStream) RecvMsg(m interface{}) error { + err := s.ClientStream.RecvMsg(m) + if err == nil { + s.monitor.ReceivedMessage() + } else if err == io.EOF { + s.monitor.Handled(codes.OK) + } else { + s.monitor.Handled(grpc.Code(err)) + } + return err +} diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/client_reporter.go b/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/client_reporter.go new file mode 100644 index 000000000..16b761553 --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/client_reporter.go @@ -0,0 +1,111 @@ +// Copyright 2016 Michal Witkowski. All Rights Reserved. +// See LICENSE for licensing terms. + +package grpc_prometheus + +import ( + "time" + + "google.golang.org/grpc/codes" + + prom "github.com/prometheus/client_golang/prometheus" +) + +var ( + clientStartedCounter = prom.NewCounterVec( + prom.CounterOpts{ + Namespace: "grpc", + Subsystem: "client", + Name: "started_total", + Help: "Total number of RPCs started on the client.", + }, []string{"grpc_type", "grpc_service", "grpc_method"}) + + clientHandledCounter = prom.NewCounterVec( + prom.CounterOpts{ + Namespace: "grpc", + Subsystem: "client", + Name: "handled_total", + Help: "Total number of RPCs completed by the client, regardless of success or failure.", + }, []string{"grpc_type", "grpc_service", "grpc_method", "grpc_code"}) + + clientStreamMsgReceived = prom.NewCounterVec( + prom.CounterOpts{ + Namespace: "grpc", + Subsystem: "client", + Name: "msg_received_total", + Help: "Total number of RPC stream messages received by the client.", + }, []string{"grpc_type", "grpc_service", "grpc_method"}) + + clientStreamMsgSent = prom.NewCounterVec( + prom.CounterOpts{ + Namespace: "grpc", + Subsystem: "client", + Name: "msg_sent_total", + Help: "Total number of gRPC stream messages sent by the client.", + }, []string{"grpc_type", "grpc_service", "grpc_method"}) + + clientHandledHistogramEnabled = false + clientHandledHistogramOpts = prom.HistogramOpts{ + Namespace: "grpc", + Subsystem: "client", + Name: "handling_seconds", + Help: "Histogram of response latency (seconds) of the gRPC until it is finished by the application.", + Buckets: prom.DefBuckets, + } + clientHandledHistogram *prom.HistogramVec +) + +func init() { + prom.MustRegister(clientStartedCounter) + prom.MustRegister(clientHandledCounter) + prom.MustRegister(clientStreamMsgReceived) + prom.MustRegister(clientStreamMsgSent) +} + +// EnableClientHandlingTimeHistogram turns on recording of handling time of RPCs. +// Histogram metrics can be very expensive for Prometheus to retain and query. +func EnableClientHandlingTimeHistogram(opts ...HistogramOption) { + for _, o := range opts { + o(&clientHandledHistogramOpts) + } + if !clientHandledHistogramEnabled { + clientHandledHistogram = prom.NewHistogramVec( + clientHandledHistogramOpts, + []string{"grpc_type", "grpc_service", "grpc_method"}, + ) + prom.Register(clientHandledHistogram) + } + clientHandledHistogramEnabled = true +} + +type clientReporter struct { + rpcType grpcType + serviceName string + methodName string + startTime time.Time +} + +func newClientReporter(rpcType grpcType, fullMethod string) *clientReporter { + r := &clientReporter{rpcType: rpcType} + if clientHandledHistogramEnabled { + r.startTime = time.Now() + } + r.serviceName, r.methodName = splitMethodName(fullMethod) + clientStartedCounter.WithLabelValues(string(r.rpcType), r.serviceName, r.methodName).Inc() + return r +} + +func (r *clientReporter) ReceivedMessage() { + clientStreamMsgReceived.WithLabelValues(string(r.rpcType), r.serviceName, r.methodName).Inc() +} + +func (r *clientReporter) SentMessage() { + clientStreamMsgSent.WithLabelValues(string(r.rpcType), r.serviceName, r.methodName).Inc() +} + +func (r *clientReporter) Handled(code codes.Code) { + clientHandledCounter.WithLabelValues(string(r.rpcType), r.serviceName, r.methodName, code.String()).Inc() + if clientHandledHistogramEnabled { + clientHandledHistogram.WithLabelValues(string(r.rpcType), r.serviceName, r.methodName).Observe(time.Since(r.startTime).Seconds()) + } +} diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/server.go b/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/server.go new file mode 100644 index 000000000..f85c8c237 --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/server.go @@ -0,0 +1,74 @@ +// Copyright 2016 Michal Witkowski. All Rights Reserved. +// See LICENSE for licensing terms. + +// gRPC Prometheus monitoring interceptors for server-side gRPC. + +package grpc_prometheus + +import ( + "golang.org/x/net/context" + "google.golang.org/grpc" +) + +// PreregisterServices takes a gRPC server and pre-initializes all counters to 0. +// This allows for easier monitoring in Prometheus (no missing metrics), and should be called *after* all services have +// been registered with the server. +func Register(server *grpc.Server) { + serviceInfo := server.GetServiceInfo() + for serviceName, info := range serviceInfo { + for _, mInfo := range info.Methods { + preRegisterMethod(serviceName, &mInfo) + } + } +} + +// UnaryServerInterceptor is a gRPC server-side interceptor that provides Prometheus monitoring for Unary RPCs. +func UnaryServerInterceptor(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) { + monitor := newServerReporter(Unary, info.FullMethod) + monitor.ReceivedMessage() + resp, err := handler(ctx, req) + monitor.Handled(grpc.Code(err)) + if err == nil { + monitor.SentMessage() + } + return resp, err +} + +// StreamServerInterceptor is a gRPC server-side interceptor that provides Prometheus monitoring for Streaming RPCs. +func StreamServerInterceptor(srv interface{}, ss grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error { + monitor := newServerReporter(streamRpcType(info), info.FullMethod) + err := handler(srv, &monitoredServerStream{ss, monitor}) + monitor.Handled(grpc.Code(err)) + return err +} + +func streamRpcType(info *grpc.StreamServerInfo) grpcType { + if info.IsClientStream && !info.IsServerStream { + return ClientStream + } else if !info.IsClientStream && info.IsServerStream { + return ServerStream + } + return BidiStream +} + +// monitoredStream wraps grpc.ServerStream allowing each Sent/Recv of message to increment counters. +type monitoredServerStream struct { + grpc.ServerStream + monitor *serverReporter +} + +func (s *monitoredServerStream) SendMsg(m interface{}) error { + err := s.ServerStream.SendMsg(m) + if err == nil { + s.monitor.SentMessage() + } + return err +} + +func (s *monitoredServerStream) RecvMsg(m interface{}) error { + err := s.ServerStream.RecvMsg(m) + if err == nil { + s.monitor.ReceivedMessage() + } + return err +} diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/server_reporter.go b/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/server_reporter.go new file mode 100644 index 000000000..628a89056 --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/server_reporter.go @@ -0,0 +1,157 @@ +// Copyright 2016 Michal Witkowski. All Rights Reserved. +// See LICENSE for licensing terms. + +package grpc_prometheus + +import ( + "time" + + "google.golang.org/grpc/codes" + + prom "github.com/prometheus/client_golang/prometheus" + "google.golang.org/grpc" +) + +type grpcType string + +const ( + Unary grpcType = "unary" + ClientStream grpcType = "client_stream" + ServerStream grpcType = "server_stream" + BidiStream grpcType = "bidi_stream" +) + +var ( + serverStartedCounter = prom.NewCounterVec( + prom.CounterOpts{ + Namespace: "grpc", + Subsystem: "server", + Name: "started_total", + Help: "Total number of RPCs started on the server.", + }, []string{"grpc_type", "grpc_service", "grpc_method"}) + + serverHandledCounter = prom.NewCounterVec( + prom.CounterOpts{ + Namespace: "grpc", + Subsystem: "server", + Name: "handled_total", + Help: "Total number of RPCs completed on the server, regardless of success or failure.", + }, []string{"grpc_type", "grpc_service", "grpc_method", "grpc_code"}) + + serverStreamMsgReceived = prom.NewCounterVec( + prom.CounterOpts{ + Namespace: "grpc", + Subsystem: "server", + Name: "msg_received_total", + Help: "Total number of RPC stream messages received on the server.", + }, []string{"grpc_type", "grpc_service", "grpc_method"}) + + serverStreamMsgSent = prom.NewCounterVec( + prom.CounterOpts{ + Namespace: "grpc", + Subsystem: "server", + Name: "msg_sent_total", + Help: "Total number of gRPC stream messages sent by the server.", + }, []string{"grpc_type", "grpc_service", "grpc_method"}) + + serverHandledHistogramEnabled = false + serverHandledHistogramOpts = prom.HistogramOpts{ + Namespace: "grpc", + Subsystem: "server", + Name: "handling_seconds", + Help: "Histogram of response latency (seconds) of gRPC that had been application-level handled by the server.", + Buckets: prom.DefBuckets, + } + serverHandledHistogram *prom.HistogramVec +) + +func init() { + prom.MustRegister(serverStartedCounter) + prom.MustRegister(serverHandledCounter) + prom.MustRegister(serverStreamMsgReceived) + prom.MustRegister(serverStreamMsgSent) +} + +type HistogramOption func(*prom.HistogramOpts) + +// WithHistogramBuckets allows you to specify custom bucket ranges for histograms if EnableHandlingTimeHistogram is on. +func WithHistogramBuckets(buckets []float64) HistogramOption { + return func(o *prom.HistogramOpts) { o.Buckets = buckets } +} + +// EnableHandlingTimeHistogram turns on recording of handling time of RPCs for server-side interceptors. +// Histogram metrics can be very expensive for Prometheus to retain and query. +func EnableHandlingTimeHistogram(opts ...HistogramOption) { + for _, o := range opts { + o(&serverHandledHistogramOpts) + } + if !serverHandledHistogramEnabled { + serverHandledHistogram = prom.NewHistogramVec( + serverHandledHistogramOpts, + []string{"grpc_type", "grpc_service", "grpc_method"}, + ) + prom.Register(serverHandledHistogram) + } + serverHandledHistogramEnabled = true +} + +type serverReporter struct { + rpcType grpcType + serviceName string + methodName string + startTime time.Time +} + +func newServerReporter(rpcType grpcType, fullMethod string) *serverReporter { + r := &serverReporter{rpcType: rpcType} + if serverHandledHistogramEnabled { + r.startTime = time.Now() + } + r.serviceName, r.methodName = splitMethodName(fullMethod) + serverStartedCounter.WithLabelValues(string(r.rpcType), r.serviceName, r.methodName).Inc() + return r +} + +func (r *serverReporter) ReceivedMessage() { + serverStreamMsgReceived.WithLabelValues(string(r.rpcType), r.serviceName, r.methodName).Inc() +} + +func (r *serverReporter) SentMessage() { + serverStreamMsgSent.WithLabelValues(string(r.rpcType), r.serviceName, r.methodName).Inc() +} + +func (r *serverReporter) Handled(code codes.Code) { + serverHandledCounter.WithLabelValues(string(r.rpcType), r.serviceName, r.methodName, code.String()).Inc() + if serverHandledHistogramEnabled { + serverHandledHistogram.WithLabelValues(string(r.rpcType), r.serviceName, r.methodName).Observe(time.Since(r.startTime).Seconds()) + } +} + +// preRegisterMethod is invoked on Register of a Server, allowing all gRPC services labels to be pre-populated. +func preRegisterMethod(serviceName string, mInfo *grpc.MethodInfo) { + methodName := mInfo.Name + methodType := string(typeFromMethodInfo(mInfo)) + // These are just references (no increments), as just referencing will create the labels but not set values. + serverStartedCounter.GetMetricWithLabelValues(methodType, serviceName, methodName) + serverStreamMsgReceived.GetMetricWithLabelValues(methodType, serviceName, methodName) + serverStreamMsgSent.GetMetricWithLabelValues(methodType, serviceName, methodName) + if serverHandledHistogramEnabled { + serverHandledHistogram.GetMetricWithLabelValues(methodType, serviceName, methodName) + } + for _, code := range allCodes { + serverHandledCounter.GetMetricWithLabelValues(methodType, serviceName, methodName, code.String()) + } +} + +func typeFromMethodInfo(mInfo *grpc.MethodInfo) grpcType { + if mInfo.IsClientStream == false && mInfo.IsServerStream == false { + return Unary + } + if mInfo.IsClientStream == true && mInfo.IsServerStream == false { + return ClientStream + } + if mInfo.IsClientStream == false && mInfo.IsServerStream == true { + return ServerStream + } + return BidiStream +} diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/test_all.sh b/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/test_all.sh new file mode 100755 index 000000000..e1e780080 --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/test_all.sh @@ -0,0 +1,14 @@ +#!/usr/bin/env bash + +set -e +echo "" > coverage.txt + +for d in $(go list ./... | grep -v vendor); do + echo -e "TESTS FOR: for \033[0;35m${d}\033[0m" + go test -race -v -coverprofile=profile.coverage.out -covermode=atomic $d + if [ -f profile.coverage.out ]; then + cat profile.coverage.out >> coverage.txt + rm profile.coverage.out + fi + echo "" +done diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/util.go b/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/util.go new file mode 100644 index 000000000..372460ac4 --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/util.go @@ -0,0 +1,27 @@ +// Copyright 2016 Michal Witkowski. All Rights Reserved. +// See LICENSE for licensing terms. + +package grpc_prometheus + +import ( + "strings" + + "google.golang.org/grpc/codes" +) + +var ( + allCodes = []codes.Code{ + codes.OK, codes.Canceled, codes.Unknown, codes.InvalidArgument, codes.DeadlineExceeded, codes.NotFound, + codes.AlreadyExists, codes.PermissionDenied, codes.Unauthenticated, codes.ResourceExhausted, + codes.FailedPrecondition, codes.Aborted, codes.OutOfRange, codes.Unimplemented, codes.Internal, + codes.Unavailable, codes.DataLoss, + } +) + +func splitMethodName(fullMethodName string) (string, string) { + fullMethodName = strings.TrimPrefix(fullMethodName, "/") // remove leading slash + if i := strings.Index(fullMethodName, "/"); i >= 0 { + return fullMethodName[:i], fullMethodName[i+1:] + } + return "unknown", "unknown" +} diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/context.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/context.go index ad4253566..f248c738b 100644 --- a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/context.go +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/context.go @@ -15,8 +15,12 @@ import ( "google.golang.org/grpc/metadata" ) -const metadataHeaderPrefix = "Grpc-Metadata-" -const metadataTrailerPrefix = "Grpc-Trailer-" +// MetadataHeaderPrefix is prepended to HTTP headers in order to convert them to +// gRPC metadata for incoming requests processed by grpc-gateway +const MetadataHeaderPrefix = "Grpc-Metadata-" +// MetadataTrailerPrefix is prepended to gRPC metadata as it is converted to +// HTTP headers in a response handled by grpc-gateway +const MetadataTrailerPrefix = "Grpc-Trailer-" const metadataGrpcTimeout = "Grpc-Timeout" const xForwardedFor = "X-Forwarded-For" @@ -52,8 +56,8 @@ func AnnotateContext(ctx context.Context, req *http.Request) (context.Context, e pairs = append(pairs, "authorization", val) continue } - if strings.HasPrefix(key, metadataHeaderPrefix) { - pairs = append(pairs, key[len(metadataHeaderPrefix):], val) + if strings.HasPrefix(key, MetadataHeaderPrefix) { + pairs = append(pairs, key[len(MetadataHeaderPrefix):], val) } } } diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/errors.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/errors.go index 7d7a9b224..0d3cb3bf3 100644 --- a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/errors.go +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/errors.go @@ -63,8 +63,8 @@ var ( ) type errorBody struct { - Error string `json:"error"` - Code int `json:"code"` + Error string `protobuf:"bytes,1,name=error" json:"error"` + Code int `protobuf:"bytes,2,name=code" json:"code"` } //Make this also conform to proto.Message for builtin JSONPb Marshaler diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/handler.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/handler.go index bafa4285f..d7040851a 100644 --- a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/handler.go +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/handler.go @@ -67,7 +67,7 @@ func ForwardResponseStream(ctx context.Context, marshaler Marshaler, w http.Resp func handleForwardResponseServerMetadata(w http.ResponseWriter, md ServerMetadata) { for k, vs := range md.HeaderMD { - hKey := fmt.Sprintf("%s%s", metadataHeaderPrefix, k) + hKey := fmt.Sprintf("%s%s", MetadataHeaderPrefix, k) for i := range vs { w.Header().Add(hKey, vs[i]) } @@ -76,14 +76,14 @@ func handleForwardResponseServerMetadata(w http.ResponseWriter, md ServerMetadat func handleForwardResponseTrailerHeader(w http.ResponseWriter, md ServerMetadata) { for k := range md.TrailerMD { - tKey := textproto.CanonicalMIMEHeaderKey(fmt.Sprintf("%s%s", metadataTrailerPrefix, k)) + tKey := textproto.CanonicalMIMEHeaderKey(fmt.Sprintf("%s%s", MetadataTrailerPrefix, k)) w.Header().Add("Trailer", tKey) } } func handleForwardResponseTrailer(w http.ResponseWriter, md ServerMetadata) { for k, vs := range md.TrailerMD { - tKey := fmt.Sprintf("%s%s", metadataTrailerPrefix, k) + tKey := fmt.Sprintf("%s%s", MetadataTrailerPrefix, k) for i := range vs { w.Header().Add(tKey, vs[i]) } diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/internal/stream_chunk.pb.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/internal/stream_chunk.pb.go index 524e0d3c3..6f837cfd5 100644 --- a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/internal/stream_chunk.pb.go +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/internal/stream_chunk.pb.go @@ -49,17 +49,17 @@ func init() { func init() { proto.RegisterFile("runtime/internal/stream_chunk.proto", fileDescriptor0) } var fileDescriptor0 = []byte{ - // 180 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0x52, 0x2e, 0x2a, 0xcd, 0x2b, - 0xc9, 0xcc, 0x4d, 0xd5, 0xcf, 0xcc, 0x2b, 0x49, 0x2d, 0xca, 0x4b, 0xcc, 0xd1, 0x2f, 0x2e, 0x29, - 0x4a, 0x4d, 0xcc, 0x8d, 0x4f, 0xce, 0x28, 0xcd, 0xcb, 0xd6, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, - 0x12, 0x49, 0x2f, 0x2a, 0x48, 0xd6, 0x4b, 0x4f, 0x2c, 0x49, 0x2d, 0x4f, 0xac, 0xd4, 0x83, 0xea, - 0x50, 0x6a, 0x62, 0xe4, 0xe2, 0x0e, 0x06, 0x2b, 0x76, 0x2d, 0x2a, 0xca, 0x2f, 0x12, 0x92, 0xe6, - 0xe2, 0x04, 0xa9, 0x8b, 0x4f, 0xce, 0x4f, 0x49, 0x95, 0x60, 0x54, 0x60, 0xd4, 0x60, 0x0d, 0xe2, - 0x00, 0x09, 0x38, 0x03, 0xf9, 0x20, 0xc9, 0x8c, 0x92, 0x92, 0x02, 0x88, 0x24, 0x13, 0x44, 0x12, - 0x24, 0x00, 0x96, 0x94, 0xe0, 0x62, 0xcf, 0x4d, 0x2d, 0x2e, 0x4e, 0x4c, 0x4f, 0x95, 0x60, 0x06, - 0x4a, 0x71, 0x06, 0xc1, 0xb8, 0x42, 0xf2, 0x5c, 0xdc, 0x60, 0x6d, 0xc5, 0x25, 0x89, 0x25, 0xa5, - 0xc5, 0x12, 0x2c, 0x60, 0x59, 0x2e, 0x90, 0x50, 0x30, 0x58, 0xc4, 0x89, 0x2b, 0x8a, 0x03, 0xe6, - 0xf2, 0x24, 0x36, 0xb0, 0x6b, 0x8d, 0x01, 0x01, 0x00, 0x00, 0xff, 0xff, 0xa9, 0x07, 0x92, 0xb6, - 0xd4, 0x00, 0x00, 0x00, + // 181 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x34, 0x8e, 0xbf, 0xee, 0x82, 0x30, + 0x14, 0x85, 0xd3, 0xdf, 0x1f, 0x85, 0xcb, 0x46, 0x1c, 0x9a, 0x38, 0x48, 0x74, 0x61, 0x82, 0xc1, + 0x37, 0xd0, 0xf8, 0x02, 0xb0, 0xb9, 0x90, 0x0a, 0x37, 0x40, 0x94, 0x96, 0xdc, 0x5e, 0x62, 0x5c, + 0x7d, 0x72, 0xd3, 0x22, 0xe3, 0xf9, 0xbe, 0x73, 0x92, 0x03, 0x07, 0x9a, 0x34, 0xf7, 0x03, 0xe6, + 0xbd, 0x66, 0x24, 0xad, 0x1e, 0xb9, 0x65, 0x42, 0x35, 0x54, 0x75, 0x37, 0xe9, 0x7b, 0x36, 0x92, + 0x61, 0x13, 0x6f, 0x5a, 0x1a, 0xeb, 0xac, 0x55, 0x8c, 0x4f, 0xf5, 0xca, 0xbe, 0x8b, 0xfd, 0x5b, + 0x40, 0x54, 0xfa, 0xf2, 0x85, 0xc8, 0x50, 0xbc, 0x85, 0xd0, 0xf5, 0xaa, 0xda, 0x34, 0x28, 0x45, + 0x22, 0xd2, 0xff, 0x22, 0x70, 0xe0, 0x6c, 0x1a, 0x74, 0xb2, 0x63, 0x1e, 0x67, 0xf9, 0x33, 0x4b, + 0x07, 0xbc, 0x94, 0xb0, 0x1e, 0xd0, 0x5a, 0xd5, 0xa2, 0xfc, 0x4d, 0x44, 0x1a, 0x16, 0x4b, 0x8c, + 0x77, 0x10, 0xf9, 0x99, 0x65, 0xc5, 0x93, 0x95, 0x7f, 0xde, 0x82, 0x43, 0xa5, 0x27, 0x27, 0xb8, + 0x06, 0xcb, 0xf3, 0xdb, 0xca, 0xbf, 0x3d, 0x7e, 0x02, 0x00, 0x00, 0xff, 0xff, 0xa9, 0x07, 0x92, + 0xb6, 0xd4, 0x00, 0x00, 0x00, } diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshal_jsonpb.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshal_jsonpb.go index 9a4219111..49f13f7fc 100644 --- a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshal_jsonpb.go +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshal_jsonpb.go @@ -111,7 +111,8 @@ func decodeJSONPb(d *json.Decoder, v interface{}) error { if !ok { return decodeNonProtoField(d, v) } - return jsonpb.UnmarshalNext(d, p) + unmarshaler := &jsonpb.Unmarshaler{AllowUnknownFields: true} + return unmarshaler.UnmarshalNext(d, p) } func decodeNonProtoField(d *json.Decoder, v interface{}) error { @@ -124,7 +125,8 @@ func decodeNonProtoField(d *json.Decoder, v interface{}) error { rv.Set(reflect.New(rv.Type().Elem())) } if rv.Type().ConvertibleTo(typeProtoMessage) { - return jsonpb.UnmarshalNext(d, rv.Interface().(proto.Message)) + unmarshaler := &jsonpb.Unmarshaler{AllowUnknownFields: true} + return unmarshaler.UnmarshalNext(d, rv.Interface().(proto.Message)) } rv = rv.Elem() } diff --git a/vendor/github.com/karlseguin/ccache/Makefile b/vendor/github.com/karlseguin/ccache/Makefile new file mode 100644 index 000000000..5b3f26baf --- /dev/null +++ b/vendor/github.com/karlseguin/ccache/Makefile @@ -0,0 +1,5 @@ +t: + go test ./... + +f: + go fmt ./... diff --git a/vendor/github.com/karlseguin/ccache/bucket.go b/vendor/github.com/karlseguin/ccache/bucket.go new file mode 100644 index 000000000..d67535170 --- /dev/null +++ b/vendor/github.com/karlseguin/ccache/bucket.go @@ -0,0 +1,41 @@ +package ccache + +import ( + "sync" + "time" +) + +type bucket struct { + sync.RWMutex + lookup map[string]*Item +} + +func (b *bucket) get(key string) *Item { + b.RLock() + defer b.RUnlock() + return b.lookup[key] +} + +func (b *bucket) set(key string, value interface{}, duration time.Duration) (*Item, *Item) { + expires := time.Now().Add(duration).UnixNano() + item := newItem(key, value, expires) + b.Lock() + defer b.Unlock() + existing := b.lookup[key] + b.lookup[key] = item + return item, existing +} + +func (b *bucket) delete(key string) *Item { + b.Lock() + defer b.Unlock() + item := b.lookup[key] + delete(b.lookup, key) + return item +} + +func (b *bucket) clear() { + b.Lock() + defer b.Unlock() + b.lookup = make(map[string]*Item) +} diff --git a/vendor/github.com/karlseguin/ccache/cache.go b/vendor/github.com/karlseguin/ccache/cache.go new file mode 100644 index 000000000..a9e94f486 --- /dev/null +++ b/vendor/github.com/karlseguin/ccache/cache.go @@ -0,0 +1,227 @@ +// An LRU cached aimed at high concurrency +package ccache + +import ( + "container/list" + "hash/fnv" + "sync/atomic" + "time" +) + +type Cache struct { + *Configuration + list *list.List + size int64 + buckets []*bucket + bucketMask uint32 + deletables chan *Item + promotables chan *Item + donec chan struct{} +} + +// Create a new cache with the specified configuration +// See ccache.Configure() for creating a configuration +func New(config *Configuration) *Cache { + c := &Cache{ + list: list.New(), + Configuration: config, + bucketMask: uint32(config.buckets) - 1, + buckets: make([]*bucket, config.buckets), + } + for i := 0; i < int(config.buckets); i++ { + c.buckets[i] = &bucket{ + lookup: make(map[string]*Item), + } + } + c.restart() + return c +} + +// Get an item from the cache. Returns nil if the item wasn't found. +// This can return an expired item. Use item.Expired() to see if the item +// is expired and item.TTL() to see how long until the item expires (which +// will be negative for an already expired item). +func (c *Cache) Get(key string) *Item { + item := c.bucket(key).get(key) + if item == nil { + return nil + } + if item.expires > time.Now().UnixNano() { + c.promote(item) + } + return item +} + +// Used when the cache was created with the Track() configuration option. +// Avoid otherwise +func (c *Cache) TrackingGet(key string) TrackedItem { + item := c.Get(key) + if item == nil { + return NilTracked + } + item.track() + return item +} + +// Set the value in the cache for the specified duration +func (c *Cache) Set(key string, value interface{}, duration time.Duration) { + c.set(key, value, duration) +} + +// Replace the value if it exists, does not set if it doesn't. +// Returns true if the item existed an was replaced, false otherwise. +// Replace does not reset item's TTL +func (c *Cache) Replace(key string, value interface{}) bool { + item := c.bucket(key).get(key) + if item == nil { + return false + } + c.Set(key, value, item.TTL()) + return true +} + +// Attempts to get the value from the cache and calles fetch on a miss (missing +// or stale item). If fetch returns an error, no value is cached and the error +// is returned back to the caller. +func (c *Cache) Fetch(key string, duration time.Duration, fetch func() (interface{}, error)) (*Item, error) { + item := c.Get(key) + if item != nil && !item.Expired() { + return item, nil + } + value, err := fetch() + if err != nil { + return nil, err + } + return c.set(key, value, duration), nil +} + +// Remove the item from the cache, return true if the item was present, false otherwise. +func (c *Cache) Delete(key string) bool { + item := c.bucket(key).delete(key) + if item != nil { + c.deletables <- item + return true + } + return false +} + +//this isn't thread safe. It's meant to be called from non-concurrent tests +func (c *Cache) Clear() { + for _, bucket := range c.buckets { + bucket.clear() + } + c.size = 0 + c.list = list.New() +} + +// Stops the background worker. Operations performed on the cache after Stop +// is called are likely to panic +func (c *Cache) Stop() { + close(c.promotables) + <-c.donec +} + +func (c *Cache) restart() { + c.deletables = make(chan *Item, c.deleteBuffer) + c.promotables = make(chan *Item, c.promoteBuffer) + c.donec = make(chan struct{}) + go c.worker() +} + +func (c *Cache) deleteItem(bucket *bucket, item *Item) { + bucket.delete(item.key) //stop other GETs from getting it + c.deletables <- item +} + +func (c *Cache) set(key string, value interface{}, duration time.Duration) *Item { + item, existing := c.bucket(key).set(key, value, duration) + if existing != nil { + c.deletables <- existing + } + c.promote(item) + return item +} + +func (c *Cache) bucket(key string) *bucket { + h := fnv.New32a() + h.Write([]byte(key)) + return c.buckets[h.Sum32()&c.bucketMask] +} + +func (c *Cache) promote(item *Item) { + c.promotables <- item +} + +func (c *Cache) worker() { + defer close(c.donec) + + for { + select { + case item, ok := <-c.promotables: + if ok == false { + goto drain + } + if c.doPromote(item) && c.size > c.maxSize { + c.gc() + } + case item := <-c.deletables: + c.doDelete(item) + } + } + +drain: + for { + select { + case item := <-c.deletables: + c.doDelete(item) + default: + close(c.deletables) + return + } + } +} + +func (c *Cache) doDelete(item *Item) { + if item.element == nil { + item.promotions = -2 + } else { + c.size -= item.size + c.list.Remove(item.element) + } +} + +func (c *Cache) doPromote(item *Item) bool { + //already deleted + if item.promotions == -2 { + return false + } + if item.element != nil { //not a new item + if item.shouldPromote(c.getsPerPromote) { + c.list.MoveToFront(item.element) + item.promotions = 0 + } + return false + } + + c.size += item.size + item.element = c.list.PushFront(item) + return true +} + +func (c *Cache) gc() { + element := c.list.Back() + for i := 0; i < c.itemsToPrune; i++ { + if element == nil { + return + } + prev := element.Prev() + item := element.Value.(*Item) + if c.tracking == false || atomic.LoadInt32(&item.refCount) == 0 { + c.bucket(item.key).delete(item.key) + c.size -= item.size + c.list.Remove(element) + item.promotions = -2 + } + element = prev + } +} diff --git a/vendor/github.com/karlseguin/ccache/configuration.go b/vendor/github.com/karlseguin/ccache/configuration.go new file mode 100644 index 000000000..daa835776 --- /dev/null +++ b/vendor/github.com/karlseguin/ccache/configuration.go @@ -0,0 +1,94 @@ +package ccache + +type Configuration struct { + maxSize int64 + buckets int + itemsToPrune int + deleteBuffer int + promoteBuffer int + getsPerPromote int32 + tracking bool +} + +// Creates a configuration object with sensible defaults +// Use this as the start of the fluent configuration: +// e.g.: ccache.New(ccache.Configure().MaxSize(10000)) +func Configure() *Configuration { + return &Configuration{ + buckets: 16, + itemsToPrune: 500, + deleteBuffer: 1024, + getsPerPromote: 3, + promoteBuffer: 1024, + maxSize: 5000, + tracking: false, + } +} + +// The max size for the cache +// [5000] +func (c *Configuration) MaxSize(max int64) *Configuration { + c.maxSize = max + return c +} + +// Keys are hashed into % bucket count to provide greater concurrency (every set +// requires a write lock on the bucket). Must be a power of 2 (1, 2, 4, 8, 16, ...) +// [16] +func (c *Configuration) Buckets(count uint32) *Configuration { + if count == 0 || ((count&(^count+1)) == count) == false { + count = 16 + } + c.buckets = int(count) + return c +} + +// The number of items to prune when memory is low +// [500] +func (c *Configuration) ItemsToPrune(count uint32) *Configuration { + c.itemsToPrune = int(count) + return c +} + +// The size of the queue for items which should be promoted. If the queue fills +// up, promotions are skipped +// [1024] +func (c *Configuration) PromoteBuffer(size uint32) *Configuration { + c.promoteBuffer = int(size) + return c +} + +// The size of the queue for items which should be deleted. If the queue fills +// up, calls to Delete() will block +func (c *Configuration) DeleteBuffer(size uint32) *Configuration { + c.deleteBuffer = int(size) + return c +} + +// Give a large cache with a high read / write ratio, it's usually unecessary +// to promote an item on every Get. GetsPerPromote specifies the number of Gets +// a key must have before being promoted +// [3] +func (c *Configuration) GetsPerPromote(count int32) *Configuration { + c.getsPerPromote = count + return c +} + +// Typically, a cache is agnostic about how cached values are use. This is fine +// for a typical cache usage, where you fetch an item from the cache, do something +// (write it out) and nothing else. + +// However, if callers are going to keep a reference to a cached item for a long +// time, things get messy. Specifically, the cache can evict the item, while +// references still exist. Technically, this isn't an issue. However, if you reload +// the item back into the cache, you end up with 2 objects representing the same +// data. This is a waste of space and could lead to weird behavior (the type an +// identity map is meant to solve). + +// By turning tracking on and using the cache's TrackingGet, the cache +// won't evict items which you haven't called Release() on. It's a simple reference +// counter. +func (c *Configuration) Track() *Configuration { + c.tracking = true + return c +} diff --git a/vendor/github.com/karlseguin/ccache/item.go b/vendor/github.com/karlseguin/ccache/item.go new file mode 100644 index 000000000..bb7c04fff --- /dev/null +++ b/vendor/github.com/karlseguin/ccache/item.go @@ -0,0 +1,103 @@ +package ccache + +import ( + "container/list" + "sync/atomic" + "time" +) + +type Sized interface { + Size() int64 +} + +type TrackedItem interface { + Value() interface{} + Release() + Expired() bool + TTL() time.Duration + Expires() time.Time + Extend(duration time.Duration) +} + +type nilItem struct{} + +func (n *nilItem) Value() interface{} { return nil } +func (n *nilItem) Release() {} + +func (i *nilItem) Expired() bool { + return true +} + +func (i *nilItem) TTL() time.Duration { + return time.Minute +} + +func (i *nilItem) Expires() time.Time { + return time.Time{} +} + +func (i *nilItem) Extend(duration time.Duration) { +} + +var NilTracked = new(nilItem) + +type Item struct { + key string + group string + promotions int32 + refCount int32 + expires int64 + size int64 + value interface{} + element *list.Element +} + +func newItem(key string, value interface{}, expires int64) *Item { + size := int64(1) + if sized, ok := value.(Sized); ok { + size = sized.Size() + } + return &Item{ + key: key, + value: value, + promotions: 0, + size: size, + expires: expires, + } +} + +func (i *Item) shouldPromote(getsPerPromote int32) bool { + i.promotions += 1 + return i.promotions == getsPerPromote +} + +func (i *Item) Value() interface{} { + return i.value +} + +func (i *Item) track() { + atomic.AddInt32(&i.refCount, 1) +} + +func (i *Item) Release() { + atomic.AddInt32(&i.refCount, -1) +} + +func (i *Item) Expired() bool { + expires := atomic.LoadInt64(&i.expires) + return expires < time.Now().UnixNano() +} + +func (i *Item) TTL() time.Duration { + expires := atomic.LoadInt64(&i.expires) + return time.Nanosecond * time.Duration(expires-time.Now().UnixNano()) +} + +func (i *Item) Expires() time.Time { + expires := atomic.LoadInt64(&i.expires) + return time.Unix(0, expires) +} + +func (i *Item) Extend(duration time.Duration) { + atomic.StoreInt64(&i.expires, time.Now().Add(duration).UnixNano()) +} diff --git a/vendor/github.com/karlseguin/ccache/layeredbucket.go b/vendor/github.com/karlseguin/ccache/layeredbucket.go new file mode 100644 index 000000000..88f3def42 --- /dev/null +++ b/vendor/github.com/karlseguin/ccache/layeredbucket.go @@ -0,0 +1,82 @@ +package ccache + +import ( + "sync" + "time" +) + +type layeredBucket struct { + sync.RWMutex + buckets map[string]*bucket +} + +func (b *layeredBucket) get(primary, secondary string) *Item { + bucket := b.getSecondaryBucket(primary) + if bucket == nil { + return nil + } + return bucket.get(secondary) +} + +func (b *layeredBucket) getSecondaryBucket(primary string) *bucket { + b.RLock() + bucket, exists := b.buckets[primary] + b.RUnlock() + if exists == false { + return nil + } + return bucket +} + +func (b *layeredBucket) set(primary, secondary string, value interface{}, duration time.Duration) (*Item, *Item) { + b.Lock() + bkt, exists := b.buckets[primary] + if exists == false { + bkt = &bucket{lookup: make(map[string]*Item)} + b.buckets[primary] = bkt + } + b.Unlock() + item, existing := bkt.set(secondary, value, duration) + item.group = primary + return item, existing +} + +func (b *layeredBucket) delete(primary, secondary string) *Item { + b.RLock() + bucket, exists := b.buckets[primary] + b.RUnlock() + if exists == false { + return nil + } + return bucket.delete(secondary) +} + +func (b *layeredBucket) deleteAll(primary string, deletables chan *Item) bool { + b.RLock() + bucket, exists := b.buckets[primary] + b.RUnlock() + if exists == false { + return false + } + + bucket.Lock() + defer bucket.Unlock() + + if l := len(bucket.lookup); l == 0 { + return false + } + for key, item := range bucket.lookup { + delete(bucket.lookup, key) + deletables <- item + } + return true +} + +func (b *layeredBucket) clear() { + b.Lock() + defer b.Unlock() + for _, bucket := range b.buckets { + bucket.clear() + } + b.buckets = make(map[string]*bucket) +} diff --git a/vendor/github.com/karlseguin/ccache/layeredcache.go b/vendor/github.com/karlseguin/ccache/layeredcache.go new file mode 100644 index 000000000..20b13f94d --- /dev/null +++ b/vendor/github.com/karlseguin/ccache/layeredcache.go @@ -0,0 +1,237 @@ +// An LRU cached aimed at high concurrency +package ccache + +import ( + "container/list" + "hash/fnv" + "sync/atomic" + "time" +) + +type LayeredCache struct { + *Configuration + list *list.List + buckets []*layeredBucket + bucketMask uint32 + size int64 + deletables chan *Item + promotables chan *Item + donec chan struct{} +} + +// Create a new layered cache with the specified configuration. +// A layered cache used a two keys to identify a value: a primary key +// and a secondary key. Get, Set and Delete require both a primary and +// secondary key. However, DeleteAll requires only a primary key, deleting +// all values that share the same primary key. + +// Layered Cache is useful as an HTTP cache, where an HTTP purge might +// delete multiple variants of the same resource: +// primary key = "user/44" +// secondary key 1 = ".json" +// secondary key 2 = ".xml" + +// See ccache.Configure() for creating a configuration +func Layered(config *Configuration) *LayeredCache { + c := &LayeredCache{ + list: list.New(), + Configuration: config, + bucketMask: uint32(config.buckets) - 1, + buckets: make([]*layeredBucket, config.buckets), + deletables: make(chan *Item, config.deleteBuffer), + } + for i := 0; i < int(config.buckets); i++ { + c.buckets[i] = &layeredBucket{ + buckets: make(map[string]*bucket), + } + } + c.restart() + return c +} + +// Get an item from the cache. Returns nil if the item wasn't found. +// This can return an expired item. Use item.Expired() to see if the item +// is expired and item.TTL() to see how long until the item expires (which +// will be negative for an already expired item). +func (c *LayeredCache) Get(primary, secondary string) *Item { + item := c.bucket(primary).get(primary, secondary) + if item == nil { + return nil + } + if item.expires > time.Now().UnixNano() { + c.promote(item) + } + return item +} + +// Get the secondary cache for a given primary key. This operation will +// never return nil. In the case where the primary key does not exist, a +// new, underlying, empty bucket will be created and returned. +func (c *LayeredCache) GetOrCreateSecondaryCache(primary string) *SecondaryCache { + primaryBkt := c.bucket(primary) + bkt := primaryBkt.getSecondaryBucket(primary) + primaryBkt.Lock() + if bkt == nil { + bkt = &bucket{lookup: make(map[string]*Item)} + primaryBkt.buckets[primary] = bkt + } + primaryBkt.Unlock() + return &SecondaryCache{ + bucket: bkt, + pCache: c, + } +} + +// Used when the cache was created with the Track() configuration option. +// Avoid otherwise +func (c *LayeredCache) TrackingGet(primary, secondary string) TrackedItem { + item := c.Get(primary, secondary) + if item == nil { + return NilTracked + } + item.track() + return item +} + +// Set the value in the cache for the specified duration +func (c *LayeredCache) Set(primary, secondary string, value interface{}, duration time.Duration) { + c.set(primary, secondary, value, duration) +} + +// Replace the value if it exists, does not set if it doesn't. +// Returns true if the item existed an was replaced, false otherwise. +// Replace does not reset item's TTL nor does it alter its position in the LRU +func (c *LayeredCache) Replace(primary, secondary string, value interface{}) bool { + item := c.bucket(primary).get(primary, secondary) + if item == nil { + return false + } + c.Set(primary, secondary, value, item.TTL()) + return true +} + +// Attempts to get the value from the cache and calles fetch on a miss. +// If fetch returns an error, no value is cached and the error is returned back +// to the caller. +func (c *LayeredCache) Fetch(primary, secondary string, duration time.Duration, fetch func() (interface{}, error)) (*Item, error) { + item := c.Get(primary, secondary) + if item != nil { + return item, nil + } + value, err := fetch() + if err != nil { + return nil, err + } + return c.set(primary, secondary, value, duration), nil +} + +// Remove the item from the cache, return true if the item was present, false otherwise. +func (c *LayeredCache) Delete(primary, secondary string) bool { + item := c.bucket(primary).delete(primary, secondary) + if item != nil { + c.deletables <- item + return true + } + return false +} + +// Deletes all items that share the same primary key +func (c *LayeredCache) DeleteAll(primary string) bool { + return c.bucket(primary).deleteAll(primary, c.deletables) +} + +//this isn't thread safe. It's meant to be called from non-concurrent tests +func (c *LayeredCache) Clear() { + for _, bucket := range c.buckets { + bucket.clear() + } + c.size = 0 + c.list = list.New() +} + +func (c *LayeredCache) Stop() { + close(c.promotables) + <-c.donec +} + +func (c *LayeredCache) restart() { + c.promotables = make(chan *Item, c.promoteBuffer) + c.donec = make(chan struct{}) + go c.worker() +} + +func (c *LayeredCache) set(primary, secondary string, value interface{}, duration time.Duration) *Item { + item, existing := c.bucket(primary).set(primary, secondary, value, duration) + if existing != nil { + c.deletables <- existing + } + c.promote(item) + return item +} + +func (c *LayeredCache) bucket(key string) *layeredBucket { + h := fnv.New32a() + h.Write([]byte(key)) + return c.buckets[h.Sum32()&c.bucketMask] +} + +func (c *LayeredCache) promote(item *Item) { + c.promotables <- item +} + +func (c *LayeredCache) worker() { + defer close(c.donec) + for { + select { + case item, ok := <-c.promotables: + if ok == false { + return + } + if c.doPromote(item) && c.size > c.maxSize { + c.gc() + } + case item := <-c.deletables: + if item.element == nil { + item.promotions = -2 + } else { + c.size -= item.size + c.list.Remove(item.element) + } + } + } +} + +func (c *LayeredCache) doPromote(item *Item) bool { + // deleted before it ever got promoted + if item.promotions == -2 { + return false + } + if item.element != nil { //not a new item + if item.shouldPromote(c.getsPerPromote) { + c.list.MoveToFront(item.element) + item.promotions = 0 + } + return false + } + c.size += item.size + item.element = c.list.PushFront(item) + return true +} + +func (c *LayeredCache) gc() { + element := c.list.Back() + for i := 0; i < c.itemsToPrune; i++ { + if element == nil { + return + } + prev := element.Prev() + item := element.Value.(*Item) + if c.tracking == false || atomic.LoadInt32(&item.refCount) == 0 { + c.bucket(item.group).delete(item.group, item.key) + c.size -= item.size + c.list.Remove(element) + item.promotions = -2 + } + element = prev + } +} diff --git a/vendor/github.com/karlseguin/ccache/license.txt b/vendor/github.com/karlseguin/ccache/license.txt new file mode 100644 index 000000000..aebeebfa5 --- /dev/null +++ b/vendor/github.com/karlseguin/ccache/license.txt @@ -0,0 +1,19 @@ +Copyright (c) 2013 Karl Seguin. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/github.com/karlseguin/ccache/readme.md b/vendor/github.com/karlseguin/ccache/readme.md new file mode 100644 index 000000000..8a7efa2e2 --- /dev/null +++ b/vendor/github.com/karlseguin/ccache/readme.md @@ -0,0 +1,172 @@ +# CCache +CCache is an LRU Cache, written in Go, focused on supporting high concurrency. + +Lock contention on the list is reduced by: + +* Introducing a window which limits the frequency that an item can get promoted +* Using a buffered channel to queue promotions for a single worker +* Garbage collecting within the same thread as the worker + +## Setup + +First, download the project: + + go get github.com/karlseguin/ccache + +## Configuration +Next, import and create a `Cache` instance: + + +```go +import ( + "github.com/karlseguin/ccache" +) + +var cache = ccache.New(ccache.Configure()) +``` + +`Configure` exposes a chainable API: + +```go +var cache = ccache.New(ccache.Configure().MaxSize(1000).ItemsToPrune(100)) +``` + +The most likely configuration options to tweak are: + +* `MaxSize(int)` - the maximum number size to store in the cache (default: 5000) +* `GetsPerPromote(int)` - the number of times an item is fetched before we promote it. For large caches with long TTLs, it normally isn't necessary to promote an item after every fetch (default: 3) +* `ItemsToPrune(int)` - the number of items to prune when we hit `MaxSize`. Freeing up more than 1 slot at a time improved performance (default: 500) + +Configurations that change the internals of the cache, which aren't as likely to need tweaking: + +* `Buckets` - ccache shards its internal map to provide a greater amount of concurrency. Must be a power of 2 (default: 16). +* `PromoteBuffer(int)` - the size of the buffer to use to queue promotions (default: 1024) +* `DeleteBuffer(int)` the size of the buffer to use to queue deletions (default: 1024) + +## Usage + +Once the cache is setup, you can `Get`, `Set` and `Delete` items from it. A `Get` returns an `*Item`: + +### Get +```go +item := cache.Get("user:4") +if item == nil { + //handle +} else { + user := item.Value().(*User) +} +``` +The returned `*Item` exposes a number of methods: + +* `Value() interface{}` - the value cached +* `Expired() bool` - whether the item is expired or not +* `TTL() time.Duration` - the duration before the item expires (will be a negative value for expired items) +* `Expires() time.Time` - the time the item will expire + +By returning expired items, CCache lets you decide if you want to serve stale content or not. For example, you might decide to serve up slightly stale content (< 30 seconds old) while re-fetching newer data in the background. You might also decide to serve up infinitely stale content if you're unable to get new data from your source. + +### Set +`Set` expects the key, value and ttl: + +```go +cache.Set("user:4", user, time.Minute * 10) +``` + +### Fetch +There's also a `Fetch` which mixes a `Get` and a `Set`: + +```go +item, err := cache.Fetch("user:4", time.Minute * 10, func() (interface{}, error) { + //code to fetch the data incase of a miss + //should return the data to cache and the error, if any +}) +``` + +### Delete +`Delete` expects the key to delete. It's ok to call `Delete` on a non-existant key: + +```go +cache.Delete("user:4") +``` + +### Extend +The life of an item can be changed via the `Extend` method. This will change the expiry of the item by the specified duration relative to the current time. + +### Replace +The value of an item can be updated to a new value without renewing the item's TTL or it's position in the LRU: + +```go +cache.Replace("user:4", user) +``` + +`Replace` returns true if the item existed (and thus was replaced). In the case where the key was not in the cache, the value *is not* inserted and false is returned. + +### Stop +The cache's background worker can be stopped by calling `Stop`. Once `Stop` is called +the cache should not be used (calls are likely to panic). Stop must be called in order to allow the garbage collector to reap the cache. + +## Tracking +CCache supports a special tracking mode which is meant to be used in conjunction with other pieces of your code that maintains a long-lived reference to data. + +When you configure your cache with `Track()`: + +```go +cache = ccache.New(ccache.Configure().Track()) +``` + +The items retrieved via `TrackingGet` will not be eligible for purge until `Release` is called on them: + +```go +item := cache.TrackingGet("user:4") +user := item.Value() //will be nil if "user:4" didn't exist in the cache +item.Release() //can be called even if item.Value() returned nil +``` + +In practive, `Release` wouldn't be called until later, at some other place in your code. + +There's a couple reason to use the tracking mode if other parts of your code also hold references to objects. First, if you're already going to hold a reference to these objects, there's really no reason not to have them in the cache - the memory is used up anyways. + +More important, it helps ensure that you're code returns consistent data. With tracking, "user:4" might be purged, and a subsequent `Fetch` would reload the data. This can result in different versions of "user:4" being returned by different parts of your system. + +## LayeredCache + +CCache's `LayeredCache` stores and retrieves values by both a primary and secondary key. Deletion can happen against either the primary and secondary key, or the primary key only (removing all values that share the same primary key). + +`LayeredCache` is useful for HTTP caching, when you want to purge all variations of a request. + +`LayeredCache` takes the same configuration object as the main cache, exposes the same optional tracking capabilities, but exposes a slightly different API: + +```go +cache := ccache.Layered(ccache.Configure()) + +cache.Set("/users/goku", "type:json", "{value_to_cache}", time.Minute * 5) +cache.Set("/users/goku", "type:xml", "", time.Minute * 5) + +json := cache.Get("/users/goku", "type:json") +xml := cache.Get("/users/goku", "type:xml") + +cache.Delete("/users/goku", "type:json") +cache.Delete("/users/goku", "type:xml") +// OR +cache.DeleteAll("/users/goku") +``` + +# SecondaryCache + +In some cases, when using a `LayeredCache`, it may be desirable to always be acting on the secondary portion of the cache entry. This could be the case where the primary key is used as a key elsewhere in your code. The `SecondaryCache` is retrieved with: + +```go +cache := ccache.Layered(ccache.Configure()) +sCache := cache.GetOrCreateSecondaryCache("/users/goku") +sCache.Set("type:json", "{value_to_cache}", time.Minute * 5) +``` + +The semantics for interacting with the `SecondaryCache` are exactly the same as for a regular `Cache`. However, one difference is that `Get` will not return nil, but will return an empty 'cache' for a non-existent primary key. + +## Size +By default, items added to a cache have a size of 1. This means that if you configure `MaxSize(10000)`, you'll be able to store 10000 items in the cache. + +However, if the values you set into the cache have a method `Size() int64`, this size will be used. Note that ccache has an overhead of ~350 bytes per entry, which isn't taken into account. In other words, given a filled up cache, with `MaxSize(4096000)` and items that return a `Size() int64` of 2048, we can expect to find 2000 items (4096000/2048) taking a total space of 4796000 bytes. + +## Want Something Simpler? +For a simpler cache, checkout out [rcache](https://github.com/karlseguin/rcache) diff --git a/vendor/github.com/karlseguin/ccache/secondarycache.go b/vendor/github.com/karlseguin/ccache/secondarycache.go new file mode 100644 index 000000000..f901fde0c --- /dev/null +++ b/vendor/github.com/karlseguin/ccache/secondarycache.go @@ -0,0 +1,72 @@ +package ccache + +import "time" + +type SecondaryCache struct { + bucket *bucket + pCache *LayeredCache +} + +// Get the secondary key. +// The semantics are the same as for LayeredCache.Get +func (s *SecondaryCache) Get(secondary string) *Item { + return s.bucket.get(secondary) +} + +// Set the secondary key to a value. +// The semantics are the same as for LayeredCache.Set +func (s *SecondaryCache) Set(secondary string, value interface{}, duration time.Duration) *Item { + item, existing := s.bucket.set(secondary, value, duration) + if existing != nil { + s.pCache.deletables <- existing + } + s.pCache.promote(item) + return item +} + +// Fetch or set a secondary key. +// The semantics are the same as for LayeredCache.Fetch +func (s *SecondaryCache) Fetch(secondary string, duration time.Duration, fetch func() (interface{}, error)) (*Item, error) { + item := s.Get(secondary) + if item != nil { + return item, nil + } + value, err := fetch() + if err != nil { + return nil, err + } + return s.Set(secondary, value, duration), nil +} + +// Delete a secondary key. +// The semantics are the same as for LayeredCache.Delete +func (s *SecondaryCache) Delete(secondary string) bool { + item := s.bucket.delete(secondary) + if item != nil { + s.pCache.deletables <- item + return true + } + return false +} + +// Replace a secondary key. +// The semantics are the same as for LayeredCache.Replace +func (s *SecondaryCache) Replace(secondary string, value interface{}) bool { + item := s.Get(secondary) + if item == nil { + return false + } + s.Set(secondary, value, item.TTL()) + return true +} + +// Track a secondary key. +// The semantics are the same as for LayeredCache.TrackingGet +func (c *SecondaryCache) TrackingGet(secondary string) TrackedItem { + item := c.Get(secondary) + if item == nil { + return NilTracked + } + item.track() + return item +} diff --git a/vendor/golang.org/x/net/http2/client_conn_pool.go b/vendor/golang.org/x/net/http2/client_conn_pool.go index 547e238a5..b13941258 100644 --- a/vendor/golang.org/x/net/http2/client_conn_pool.go +++ b/vendor/golang.org/x/net/http2/client_conn_pool.go @@ -53,13 +53,13 @@ const ( ) func (p *clientConnPool) getClientConn(req *http.Request, addr string, dialOnMiss bool) (*ClientConn, error) { - if req.Close && dialOnMiss { + if isConnectionCloseRequest(req) && dialOnMiss { // It gets its own connection. - cc, err := p.t.dialClientConn(addr) + const singleUse = true + cc, err := p.t.dialClientConn(addr, singleUse) if err != nil { return nil, err } - cc.singleUse = true return cc, nil } p.mu.Lock() @@ -104,7 +104,8 @@ func (p *clientConnPool) getStartDialLocked(addr string) *dialCall { // run in its own goroutine. func (c *dialCall) dial(addr string) { - c.res, c.err = c.p.t.dialClientConn(addr) + const singleUse = false // shared conn + c.res, c.err = c.p.t.dialClientConn(addr, singleUse) close(c.done) c.p.mu.Lock() diff --git a/vendor/golang.org/x/net/http2/errors.go b/vendor/golang.org/x/net/http2/errors.go index 71a4e2905..20fd7626a 100644 --- a/vendor/golang.org/x/net/http2/errors.go +++ b/vendor/golang.org/x/net/http2/errors.go @@ -64,9 +64,17 @@ func (e ConnectionError) Error() string { return fmt.Sprintf("connection error: type StreamError struct { StreamID uint32 Code ErrCode + Cause error // optional additional detail +} + +func streamError(id uint32, code ErrCode) StreamError { + return StreamError{StreamID: id, Code: code} } func (e StreamError) Error() string { + if e.Cause != nil { + return fmt.Sprintf("stream error: stream ID %d; %v; %v", e.StreamID, e.Code, e.Cause) + } return fmt.Sprintf("stream error: stream ID %d; %v", e.StreamID, e.Code) } diff --git a/vendor/golang.org/x/net/http2/frame.go b/vendor/golang.org/x/net/http2/frame.go index 981d407a7..358833fed 100644 --- a/vendor/golang.org/x/net/http2/frame.go +++ b/vendor/golang.org/x/net/http2/frame.go @@ -317,10 +317,12 @@ type Framer struct { // non-Continuation or Continuation on a different stream is // attempted to be written. - logReads bool + logReads, logWrites bool - debugFramer *Framer // only use for logging written writes - debugFramerBuf *bytes.Buffer + debugFramer *Framer // only use for logging written writes + debugFramerBuf *bytes.Buffer + debugReadLoggerf func(string, ...interface{}) + debugWriteLoggerf func(string, ...interface{}) } func (fr *Framer) maxHeaderListSize() uint32 { @@ -355,7 +357,7 @@ func (f *Framer) endWrite() error { byte(length>>16), byte(length>>8), byte(length)) - if logFrameWrites { + if f.logWrites { f.logWrite() } @@ -378,10 +380,10 @@ func (f *Framer) logWrite() { f.debugFramerBuf.Write(f.wbuf) fr, err := f.debugFramer.ReadFrame() if err != nil { - log.Printf("http2: Framer %p: failed to decode just-written frame", f) + f.debugWriteLoggerf("http2: Framer %p: failed to decode just-written frame", f) return } - log.Printf("http2: Framer %p: wrote %v", f, summarizeFrame(fr)) + f.debugWriteLoggerf("http2: Framer %p: wrote %v", f, summarizeFrame(fr)) } func (f *Framer) writeByte(v byte) { f.wbuf = append(f.wbuf, v) } @@ -399,9 +401,12 @@ const ( // NewFramer returns a Framer that writes frames to w and reads them from r. func NewFramer(w io.Writer, r io.Reader) *Framer { fr := &Framer{ - w: w, - r: r, - logReads: logFrameReads, + w: w, + r: r, + logReads: logFrameReads, + logWrites: logFrameWrites, + debugReadLoggerf: log.Printf, + debugWriteLoggerf: log.Printf, } fr.getReadBuf = func(size uint32) []byte { if cap(fr.readBuf) >= int(size) { @@ -483,7 +488,7 @@ func (fr *Framer) ReadFrame() (Frame, error) { return nil, err } if fr.logReads { - log.Printf("http2: Framer %p: read %v", fr, summarizeFrame(f)) + fr.debugReadLoggerf("http2: Framer %p: read %v", fr, summarizeFrame(f)) } if fh.Type == FrameHeaders && fr.ReadMetaHeaders != nil { return fr.readMetaFrame(f.(*HeadersFrame)) @@ -594,6 +599,7 @@ func parseDataFrame(fh FrameHeader, payload []byte) (Frame, error) { var ( errStreamID = errors.New("invalid stream ID") errDepStreamID = errors.New("invalid dependent stream ID") + errPadLength = errors.New("pad length too large") ) func validStreamIDOrZero(streamID uint32) bool { @@ -607,18 +613,40 @@ func validStreamID(streamID uint32) bool { // WriteData writes a DATA frame. // // It will perform exactly one Write to the underlying Writer. -// It is the caller's responsibility to not call other Write methods concurrently. +// It is the caller's responsibility not to violate the maximum frame size +// and to not call other Write methods concurrently. func (f *Framer) WriteData(streamID uint32, endStream bool, data []byte) error { - // TODO: ignoring padding for now. will add when somebody cares. + return f.WriteDataPadded(streamID, endStream, data, nil) +} + +// WriteData writes a DATA frame with optional padding. +// +// If pad is nil, the padding bit is not sent. +// The length of pad must not exceed 255 bytes. +// +// It will perform exactly one Write to the underlying Writer. +// It is the caller's responsibility not to violate the maximum frame size +// and to not call other Write methods concurrently. +func (f *Framer) WriteDataPadded(streamID uint32, endStream bool, data, pad []byte) error { if !validStreamID(streamID) && !f.AllowIllegalWrites { return errStreamID } + if len(pad) > 255 { + return errPadLength + } var flags Flags if endStream { flags |= FlagDataEndStream } + if pad != nil { + flags |= FlagDataPadded + } f.startWrite(FrameData, flags, streamID) + if pad != nil { + f.wbuf = append(f.wbuf, byte(len(pad))) + } f.wbuf = append(f.wbuf, data...) + f.wbuf = append(f.wbuf, pad...) return f.endWrite() } @@ -714,7 +742,7 @@ func (f *Framer) WriteSettings(settings ...Setting) error { return f.endWrite() } -// WriteSettings writes an empty SETTINGS frame with the ACK bit set. +// WriteSettingsAck writes an empty SETTINGS frame with the ACK bit set. // // It will perform exactly one Write to the underlying Writer. // It is the caller's responsibility to not call other Write methods concurrently. @@ -840,7 +868,7 @@ func parseWindowUpdateFrame(fh FrameHeader, p []byte) (Frame, error) { if fh.StreamID == 0 { return nil, ConnectionError(ErrCodeProtocol) } - return nil, StreamError{fh.StreamID, ErrCodeProtocol} + return nil, streamError(fh.StreamID, ErrCodeProtocol) } return &WindowUpdateFrame{ FrameHeader: fh, @@ -921,7 +949,7 @@ func parseHeadersFrame(fh FrameHeader, p []byte) (_ Frame, err error) { } } if len(p)-int(padLength) <= 0 { - return nil, StreamError{fh.StreamID, ErrCodeProtocol} + return nil, streamError(fh.StreamID, ErrCodeProtocol) } hf.headerFragBuf = p[:len(p)-int(padLength)] return hf, nil @@ -1396,6 +1424,9 @@ func (fr *Framer) readMetaFrame(hf *HeadersFrame) (*MetaHeadersFrame, error) { hdec.SetEmitEnabled(true) hdec.SetMaxStringLength(fr.maxHeaderStringLen()) hdec.SetEmitFunc(func(hf hpack.HeaderField) { + if VerboseLogs && fr.logReads { + fr.debugReadLoggerf("http2: decoded hpack field %+v", hf) + } if !httplex.ValidHeaderFieldValue(hf.Value) { invalid = headerFieldValueError(hf.Value) } @@ -1454,11 +1485,17 @@ func (fr *Framer) readMetaFrame(hf *HeadersFrame) (*MetaHeadersFrame, error) { } if invalid != nil { fr.errDetail = invalid - return nil, StreamError{mh.StreamID, ErrCodeProtocol} + if VerboseLogs { + log.Printf("http2: invalid header: %v", invalid) + } + return nil, StreamError{mh.StreamID, ErrCodeProtocol, invalid} } if err := mh.checkPseudos(); err != nil { fr.errDetail = err - return nil, StreamError{mh.StreamID, ErrCodeProtocol} + if VerboseLogs { + log.Printf("http2: invalid pseudo headers: %v", err) + } + return nil, StreamError{mh.StreamID, ErrCodeProtocol, err} } return mh, nil } diff --git a/vendor/golang.org/x/net/http2/go17.go b/vendor/golang.org/x/net/http2/go17.go index 730319dd5..47b7fae08 100644 --- a/vendor/golang.org/x/net/http2/go17.go +++ b/vendor/golang.org/x/net/http2/go17.go @@ -39,6 +39,13 @@ type clientTrace httptrace.ClientTrace func reqContext(r *http.Request) context.Context { return r.Context() } +func (t *Transport) idleConnTimeout() time.Duration { + if t.t1 != nil { + return t.t1.IdleConnTimeout + } + return 0 +} + func setResponseUncompressed(res *http.Response) { res.Uncompressed = true } func traceGotConn(req *http.Request, cc *ClientConn) { @@ -92,3 +99,8 @@ func requestTrace(req *http.Request) *clientTrace { trace := httptrace.ContextClientTrace(req.Context()) return (*clientTrace)(trace) } + +// Ping sends a PING frame to the server and waits for the ack. +func (cc *ClientConn) Ping(ctx context.Context) error { + return cc.ping(ctx) +} diff --git a/vendor/golang.org/x/net/http2/go17_not18.go b/vendor/golang.org/x/net/http2/go17_not18.go new file mode 100644 index 000000000..b4c52ecec --- /dev/null +++ b/vendor/golang.org/x/net/http2/go17_not18.go @@ -0,0 +1,36 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build go1.7,!go1.8 + +package http2 + +import "crypto/tls" + +// temporary copy of Go 1.7's private tls.Config.clone: +func cloneTLSConfig(c *tls.Config) *tls.Config { + return &tls.Config{ + Rand: c.Rand, + Time: c.Time, + Certificates: c.Certificates, + NameToCertificate: c.NameToCertificate, + GetCertificate: c.GetCertificate, + RootCAs: c.RootCAs, + NextProtos: c.NextProtos, + ServerName: c.ServerName, + ClientAuth: c.ClientAuth, + ClientCAs: c.ClientCAs, + InsecureSkipVerify: c.InsecureSkipVerify, + CipherSuites: c.CipherSuites, + PreferServerCipherSuites: c.PreferServerCipherSuites, + SessionTicketsDisabled: c.SessionTicketsDisabled, + SessionTicketKey: c.SessionTicketKey, + ClientSessionCache: c.ClientSessionCache, + MinVersion: c.MinVersion, + MaxVersion: c.MaxVersion, + CurvePreferences: c.CurvePreferences, + DynamicRecordSizingDisabled: c.DynamicRecordSizingDisabled, + Renegotiation: c.Renegotiation, + } +} diff --git a/vendor/golang.org/x/net/http2/go18.go b/vendor/golang.org/x/net/http2/go18.go new file mode 100644 index 000000000..633202c39 --- /dev/null +++ b/vendor/golang.org/x/net/http2/go18.go @@ -0,0 +1,50 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build go1.8 + +package http2 + +import ( + "crypto/tls" + "io" + "net/http" +) + +func cloneTLSConfig(c *tls.Config) *tls.Config { return c.Clone() } + +var _ http.Pusher = (*responseWriter)(nil) + +// Push implements http.Pusher. +func (w *responseWriter) Push(target string, opts *http.PushOptions) error { + internalOpts := pushOptions{} + if opts != nil { + internalOpts.Method = opts.Method + internalOpts.Header = opts.Header + } + return w.push(target, internalOpts) +} + +func configureServer18(h1 *http.Server, h2 *Server) error { + if h2.IdleTimeout == 0 { + if h1.IdleTimeout != 0 { + h2.IdleTimeout = h1.IdleTimeout + } else { + h2.IdleTimeout = h1.ReadTimeout + } + } + return nil +} + +func shouldLogPanic(panicValue interface{}) bool { + return panicValue != nil && panicValue != http.ErrAbortHandler +} + +func reqGetBody(req *http.Request) func() (io.ReadCloser, error) { + return req.GetBody +} + +func reqBodyIsNoBody(body io.ReadCloser) bool { + return body == http.NoBody +} diff --git a/vendor/golang.org/x/net/http2/hpack/hpack.go b/vendor/golang.org/x/net/http2/hpack/hpack.go index 8aa197ad6..135b9f62c 100644 --- a/vendor/golang.org/x/net/http2/hpack/hpack.go +++ b/vendor/golang.org/x/net/http2/hpack/hpack.go @@ -57,7 +57,7 @@ func (hf HeaderField) String() string { return fmt.Sprintf("header field %q = %q%s", hf.Name, hf.Value, suffix) } -// Size returns the size of an entry per RFC 7540 section 5.2. +// Size returns the size of an entry per RFC 7541 section 4.1. func (hf HeaderField) Size() uint32 { // http://http2.github.io/http2-spec/compression.html#rfc.section.4.1 // "The size of the dynamic table is the sum of the size of diff --git a/vendor/golang.org/x/net/http2/http2.go b/vendor/golang.org/x/net/http2/http2.go index 0173aed64..a91fed570 100644 --- a/vendor/golang.org/x/net/http2/http2.go +++ b/vendor/golang.org/x/net/http2/http2.go @@ -13,6 +13,7 @@ // See https://http2.github.io/ for more information on HTTP/2. // // See https://http2.golang.org/ for a test server running this code. +// package http2 import ( @@ -35,6 +36,7 @@ var ( VerboseLogs bool logFrameWrites bool logFrameReads bool + inTests bool ) func init() { @@ -76,13 +78,23 @@ var ( type streamState int +// HTTP/2 stream states. +// +// See http://tools.ietf.org/html/rfc7540#section-5.1. +// +// For simplicity, the server code merges "reserved (local)" into +// "half-closed (remote)". This is one less state transition to track. +// The only downside is that we send PUSH_PROMISEs slightly less +// liberally than allowable. More discussion here: +// https://lists.w3.org/Archives/Public/ietf-http-wg/2016JulSep/0599.html +// +// "reserved (remote)" is omitted since the client code does not +// support server push. const ( stateIdle streamState = iota stateOpen stateHalfClosedLocal stateHalfClosedRemote - stateResvLocal - stateResvRemote stateClosed ) @@ -91,8 +103,6 @@ var stateName = [...]string{ stateOpen: "Open", stateHalfClosedLocal: "HalfClosedLocal", stateHalfClosedRemote: "HalfClosedRemote", - stateResvLocal: "ResvLocal", - stateResvRemote: "ResvRemote", stateClosed: "Closed", } @@ -252,14 +262,27 @@ func newBufferedWriter(w io.Writer) *bufferedWriter { return &bufferedWriter{w: w} } +// bufWriterPoolBufferSize is the size of bufio.Writer's +// buffers created using bufWriterPool. +// +// TODO: pick a less arbitrary value? this is a bit under +// (3 x typical 1500 byte MTU) at least. Other than that, +// not much thought went into it. +const bufWriterPoolBufferSize = 4 << 10 + var bufWriterPool = sync.Pool{ New: func() interface{} { - // TODO: pick something better? this is a bit under - // (3 x typical 1500 byte MTU) at least. - return bufio.NewWriterSize(nil, 4<<10) + return bufio.NewWriterSize(nil, bufWriterPoolBufferSize) }, } +func (w *bufferedWriter) Available() int { + if w.bw == nil { + return bufWriterPoolBufferSize + } + return w.bw.Available() +} + func (w *bufferedWriter) Write(p []byte) (n int, err error) { if w.bw == nil { bw := bufWriterPool.Get().(*bufio.Writer) @@ -342,10 +365,23 @@ func (s *sorter) Keys(h http.Header) []string { } func (s *sorter) SortStrings(ss []string) { - // Our sorter works on s.v, which sorter owners, so + // Our sorter works on s.v, which sorter owns, so // stash it away while we sort the user's buffer. save := s.v s.v = ss sort.Sort(s) s.v = save } + +// validPseudoPath reports whether v is a valid :path pseudo-header +// value. It must be either: +// +// *) a non-empty string starting with '/', but not with with "//", +// *) the string '*', for OPTIONS requests. +// +// For now this is only used a quick check for deciding when to clean +// up Opaque URLs before sending requests from the Transport. +// See golang.org/issue/16847 +func validPseudoPath(v string) bool { + return (len(v) > 0 && v[0] == '/' && (len(v) == 1 || v[1] != '/')) || v == "*" +} diff --git a/vendor/golang.org/x/net/http2/not_go17.go b/vendor/golang.org/x/net/http2/not_go17.go index 28df0c16b..140434a79 100644 --- a/vendor/golang.org/x/net/http2/not_go17.go +++ b/vendor/golang.org/x/net/http2/not_go17.go @@ -7,11 +7,16 @@ package http2 import ( + "crypto/tls" "net" "net/http" + "time" ) -type contextContext interface{} +type contextContext interface { + Done() <-chan struct{} + Err() error +} type fakeContext struct{} @@ -49,3 +54,34 @@ func contextWithCancel(ctx contextContext) (_ contextContext, cancel func()) { func requestWithContext(req *http.Request, ctx contextContext) *http.Request { return req } + +// temporary copy of Go 1.6's private tls.Config.clone: +func cloneTLSConfig(c *tls.Config) *tls.Config { + return &tls.Config{ + Rand: c.Rand, + Time: c.Time, + Certificates: c.Certificates, + NameToCertificate: c.NameToCertificate, + GetCertificate: c.GetCertificate, + RootCAs: c.RootCAs, + NextProtos: c.NextProtos, + ServerName: c.ServerName, + ClientAuth: c.ClientAuth, + ClientCAs: c.ClientCAs, + InsecureSkipVerify: c.InsecureSkipVerify, + CipherSuites: c.CipherSuites, + PreferServerCipherSuites: c.PreferServerCipherSuites, + SessionTicketsDisabled: c.SessionTicketsDisabled, + SessionTicketKey: c.SessionTicketKey, + ClientSessionCache: c.ClientSessionCache, + MinVersion: c.MinVersion, + MaxVersion: c.MaxVersion, + CurvePreferences: c.CurvePreferences, + } +} + +func (cc *ClientConn) Ping(ctx contextContext) error { + return cc.ping(ctx) +} + +func (t *Transport) idleConnTimeout() time.Duration { return 0 } diff --git a/vendor/golang.org/x/net/http2/not_go18.go b/vendor/golang.org/x/net/http2/not_go18.go new file mode 100644 index 000000000..efbf83c32 --- /dev/null +++ b/vendor/golang.org/x/net/http2/not_go18.go @@ -0,0 +1,27 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build !go1.8 + +package http2 + +import ( + "io" + "net/http" +) + +func configureServer18(h1 *http.Server, h2 *Server) error { + // No IdleTimeout to sync prior to Go 1.8. + return nil +} + +func shouldLogPanic(panicValue interface{}) bool { + return panicValue != nil +} + +func reqGetBody(req *http.Request) func() (io.ReadCloser, error) { + return nil +} + +func reqBodyIsNoBody(io.ReadCloser) bool { return false } diff --git a/vendor/golang.org/x/net/http2/server.go b/vendor/golang.org/x/net/http2/server.go index f368738f7..3c6b90ccd 100644 --- a/vendor/golang.org/x/net/http2/server.go +++ b/vendor/golang.org/x/net/http2/server.go @@ -2,17 +2,6 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// TODO: replace all <-sc.doneServing with reads from the stream's cw -// instead, and make sure that on close we close all open -// streams. then remove doneServing? - -// TODO: re-audit GOAWAY support. Consider each incoming frame type and -// whether it should be ignored during graceful shutdown. - -// TODO: disconnect idle clients. GFE seems to do 4 minutes. make -// configurable? or maximum number of idle clients and remove the -// oldest? - // TODO: turn off the serve goroutine when idle, so // an idle conn only has the readFrames goroutine active. (which could // also be optimized probably to pin less memory in crypto/tls). This @@ -44,6 +33,7 @@ import ( "fmt" "io" "log" + "math" "net" "net/http" "net/textproto" @@ -114,6 +104,15 @@ type Server struct { // PermitProhibitedCipherSuites, if true, permits the use of // cipher suites prohibited by the HTTP/2 spec. PermitProhibitedCipherSuites bool + + // IdleTimeout specifies how long until idle clients should be + // closed with a GOAWAY frame. PING frames are not considered + // activity for the purposes of IdleTimeout. + IdleTimeout time.Duration + + // NewWriteScheduler constructs a write scheduler for a connection. + // If nil, a default scheduler is chosen. + NewWriteScheduler func() WriteScheduler } func (s *Server) maxReadFrameSize() uint32 { @@ -136,9 +135,15 @@ func (s *Server) maxConcurrentStreams() uint32 { // // ConfigureServer must be called before s begins serving. func ConfigureServer(s *http.Server, conf *Server) error { + if s == nil { + panic("nil *http.Server") + } if conf == nil { conf = new(Server) } + if err := configureServer18(s, conf); err != nil { + return err + } if s.TLSConfig == nil { s.TLSConfig = new(tls.Config) @@ -183,9 +188,6 @@ func ConfigureServer(s *http.Server, conf *Server) error { if !haveNPN { s.TLSConfig.NextProtos = append(s.TLSConfig.NextProtos, NextProtoTLS) } - // h2-14 is temporary (as of 2015-03-05) while we wait for all browsers - // to switch to "h2". - s.TLSConfig.NextProtos = append(s.TLSConfig.NextProtos, "h2-14") if s.TLSNextProto == nil { s.TLSNextProto = map[string]func(*http.Server, *tls.Conn, http.Handler){} @@ -200,7 +202,6 @@ func ConfigureServer(s *http.Server, conf *Server) error { }) } s.TLSNextProto[NextProtoTLS] = protoHandler - s.TLSNextProto["h2-14"] = protoHandler // temporary; see above. return nil } @@ -254,29 +255,45 @@ func (s *Server) ServeConn(c net.Conn, opts *ServeConnOpts) { defer cancel() sc := &serverConn{ - srv: s, - hs: opts.baseConfig(), - conn: c, - baseCtx: baseCtx, - remoteAddrStr: c.RemoteAddr().String(), - bw: newBufferedWriter(c), - handler: opts.handler(), - streams: make(map[uint32]*stream), - readFrameCh: make(chan readFrameResult), - wantWriteFrameCh: make(chan frameWriteMsg, 8), - wroteFrameCh: make(chan frameWriteResult, 1), // buffered; one send in writeFrameAsync - bodyReadCh: make(chan bodyReadMsg), // buffering doesn't matter either way - doneServing: make(chan struct{}), - advMaxStreams: s.maxConcurrentStreams(), - writeSched: writeScheduler{ - maxFrameSize: initialMaxFrameSize, - }, + srv: s, + hs: opts.baseConfig(), + conn: c, + baseCtx: baseCtx, + remoteAddrStr: c.RemoteAddr().String(), + bw: newBufferedWriter(c), + handler: opts.handler(), + streams: make(map[uint32]*stream), + readFrameCh: make(chan readFrameResult), + wantWriteFrameCh: make(chan FrameWriteRequest, 8), + wantStartPushCh: make(chan startPushRequest, 8), + wroteFrameCh: make(chan frameWriteResult, 1), // buffered; one send in writeFrameAsync + bodyReadCh: make(chan bodyReadMsg), // buffering doesn't matter either way + doneServing: make(chan struct{}), + clientMaxStreams: math.MaxUint32, // Section 6.5.2: "Initially, there is no limit to this value" + advMaxStreams: s.maxConcurrentStreams(), initialWindowSize: initialWindowSize, + maxFrameSize: initialMaxFrameSize, headerTableSize: initialHeaderTableSize, serveG: newGoroutineLock(), pushEnabled: true, } + // The net/http package sets the write deadline from the + // http.Server.WriteTimeout during the TLS handshake, but then + // passes the connection off to us with the deadline already + // set. Disarm it here so that it is not applied to additional + // streams opened on this connection. + // TODO: implement WriteTimeout fully. See Issue 18437. + if sc.hs.WriteTimeout != 0 { + sc.conn.SetWriteDeadline(time.Time{}) + } + + if s.NewWriteScheduler != nil { + sc.writeSched = s.NewWriteScheduler() + } else { + sc.writeSched = NewRandomWriteScheduler() + } + sc.flow.add(initialWindowSize) sc.inflow.add(initialWindowSize) sc.hpackEncoder = hpack.NewEncoder(&sc.headerWriteBuf) @@ -356,16 +373,18 @@ type serverConn struct { handler http.Handler baseCtx contextContext framer *Framer - doneServing chan struct{} // closed when serverConn.serve ends - readFrameCh chan readFrameResult // written by serverConn.readFrames - wantWriteFrameCh chan frameWriteMsg // from handlers -> serve - wroteFrameCh chan frameWriteResult // from writeFrameAsync -> serve, tickles more frame writes - bodyReadCh chan bodyReadMsg // from handlers -> serve - testHookCh chan func(int) // code to run on the serve loop - flow flow // conn-wide (not stream-specific) outbound flow control - inflow flow // conn-wide inbound flow control - tlsState *tls.ConnectionState // shared by all handlers, like net/http + doneServing chan struct{} // closed when serverConn.serve ends + readFrameCh chan readFrameResult // written by serverConn.readFrames + wantWriteFrameCh chan FrameWriteRequest // from handlers -> serve + wantStartPushCh chan startPushRequest // from handlers -> serve + wroteFrameCh chan frameWriteResult // from writeFrameAsync -> serve, tickles more frame writes + bodyReadCh chan bodyReadMsg // from handlers -> serve + testHookCh chan func(int) // code to run on the serve loop + flow flow // conn-wide (not stream-specific) outbound flow control + inflow flow // conn-wide inbound flow control + tlsState *tls.ConnectionState // shared by all handlers, like net/http remoteAddrStr string + writeSched WriteScheduler // Everything following is owned by the serve loop; use serveG.check(): serveG goroutineLock // used to verify funcs are on serve() @@ -375,22 +394,27 @@ type serverConn struct { unackedSettings int // how many SETTINGS have we sent without ACKs? clientMaxStreams uint32 // SETTINGS_MAX_CONCURRENT_STREAMS from client (our PUSH_PROMISE limit) advMaxStreams uint32 // our SETTINGS_MAX_CONCURRENT_STREAMS advertised the client - curOpenStreams uint32 // client's number of open streams - maxStreamID uint32 // max ever seen + curClientStreams uint32 // number of open streams initiated by the client + curPushedStreams uint32 // number of open streams initiated by server push + maxClientStreamID uint32 // max ever seen from client (odd), or 0 if there have been no client requests + maxPushPromiseID uint32 // ID of the last push promise (even), or 0 if there have been no pushes streams map[uint32]*stream initialWindowSize int32 + maxFrameSize int32 headerTableSize uint32 peerMaxHeaderListSize uint32 // zero means unknown (default) canonHeader map[string]string // http2-lower-case -> Go-Canonical-Case - writingFrame bool // started write goroutine but haven't heard back on wroteFrameCh + writingFrame bool // started writing a frame (on serve goroutine or separate) + writingFrameAsync bool // started a frame on its own goroutine but haven't heard back on wroteFrameCh needsFrameFlush bool // last frame write wasn't a flush - writeSched writeScheduler - inGoAway bool // we've started to or sent GOAWAY - needToSendGoAway bool // we need to schedule a GOAWAY frame write + inGoAway bool // we've started to or sent GOAWAY + inFrameScheduleLoop bool // whether we're in the scheduleFrameWrite loop + needToSendGoAway bool // we need to schedule a GOAWAY frame write goAwayCode ErrCode shutdownTimerCh <-chan time.Time // nil until used shutdownTimer *time.Timer // nil until used - freeRequestBodyBuf []byte // if non-nil, a free initialWindowSize buffer for getRequestBodyBuf + idleTimer *time.Timer // nil if unused + idleTimerCh <-chan time.Time // nil if unused // Owned by the writeFrameAsync goroutine: headerWriteBuf bytes.Buffer @@ -409,6 +433,11 @@ func (sc *serverConn) maxHeaderListSize() uint32 { return uint32(n + typicalHeaders*perFieldOverhead) } +func (sc *serverConn) curOpenStreams() uint32 { + sc.serveG.check() + return sc.curClientStreams + sc.curPushedStreams +} + // stream represents a stream. This is the minimal metadata needed by // the serve goroutine. Most of the actual stream state is owned by // the http.Handler's goroutine in the responseWriter. Because the @@ -434,11 +463,10 @@ type stream struct { numTrailerValues int64 weight uint8 state streamState - sentReset bool // only true once detached from streams map - gotReset bool // only true once detacted from streams map - gotTrailerHeader bool // HEADER frame for trailers was seen - wroteHeaders bool // whether we wrote headers (not status 100) - reqBuf []byte + resetQueued bool // RST_STREAM queued for write; set by sc.resetStream + gotTrailerHeader bool // HEADER frame for trailers was seen + wroteHeaders bool // whether we wrote headers (not status 100) + reqBuf []byte // if non-nil, body pipe buffer to return later at EOF trailer http.Header // accumulated trailers reqTrailer http.Header // handler's Request.Trailer @@ -453,7 +481,7 @@ func (sc *serverConn) HeaderEncoder() (*hpack.Encoder, *bytes.Buffer) { func (sc *serverConn) state(streamID uint32) (streamState, *stream) { sc.serveG.check() - // http://http2.github.io/http2-spec/#rfc.section.5.1 + // http://tools.ietf.org/html/rfc7540#section-5.1 if st, ok := sc.streams[streamID]; ok { return st.state, st } @@ -463,8 +491,14 @@ func (sc *serverConn) state(streamID uint32) (streamState, *stream) { // a client sends a HEADERS frame on stream 7 without ever sending a // frame on stream 5, then stream 5 transitions to the "closed" // state when the first frame for stream 7 is sent or received." - if streamID <= sc.maxStreamID { - return stateClosed, nil + if streamID%2 == 1 { + if streamID <= sc.maxClientStreamID { + return stateClosed, nil + } + } else { + if streamID <= sc.maxPushPromiseID { + return stateClosed, nil + } } return stateIdle, nil } @@ -603,17 +637,17 @@ func (sc *serverConn) readFrames() { // frameWriteResult is the message passed from writeFrameAsync to the serve goroutine. type frameWriteResult struct { - wm frameWriteMsg // what was written (or attempted) - err error // result of the writeFrame call + wr FrameWriteRequest // what was written (or attempted) + err error // result of the writeFrame call } // writeFrameAsync runs in its own goroutine and writes a single frame // and then reports when it's done. // At most one goroutine can be running writeFrameAsync at a time per // serverConn. -func (sc *serverConn) writeFrameAsync(wm frameWriteMsg) { - err := wm.write.writeFrame(sc) - sc.wroteFrameCh <- frameWriteResult{wm, err} +func (sc *serverConn) writeFrameAsync(wr FrameWriteRequest) { + err := wr.write.writeFrame(sc) + sc.wroteFrameCh <- frameWriteResult{wr, err} } func (sc *serverConn) closeAllStreamsOnConnClose() { @@ -657,7 +691,7 @@ func (sc *serverConn) serve() { sc.vlogf("http2: server connection from %v on %p", sc.conn.RemoteAddr(), sc.hs) } - sc.writeFrame(frameWriteMsg{ + sc.writeFrame(FrameWriteRequest{ write: writeSettings{ {SettingMaxFrameSize, sc.srv.maxReadFrameSize()}, {SettingMaxConcurrentStreams, sc.advMaxStreams}, @@ -682,6 +716,17 @@ func (sc *serverConn) serve() { sc.setConnState(http.StateActive) sc.setConnState(http.StateIdle) + if sc.srv.IdleTimeout != 0 { + sc.idleTimer = time.NewTimer(sc.srv.IdleTimeout) + defer sc.idleTimer.Stop() + sc.idleTimerCh = sc.idleTimer.C + } + + var gracefulShutdownCh <-chan struct{} + if sc.hs != nil { + gracefulShutdownCh = h1ServerShutdownChan(sc.hs) + } + go sc.readFrames() // closed by defer sc.conn.Close above settingsTimer := time.NewTimer(firstSettingsTimeout) @@ -689,8 +734,10 @@ func (sc *serverConn) serve() { for { loopNum++ select { - case wm := <-sc.wantWriteFrameCh: - sc.writeFrame(wm) + case wr := <-sc.wantWriteFrameCh: + sc.writeFrame(wr) + case spr := <-sc.wantStartPushCh: + sc.startPush(spr) case res := <-sc.wroteFrameCh: sc.wroteFrame(res) case res := <-sc.readFrameCh: @@ -707,12 +754,22 @@ func (sc *serverConn) serve() { case <-settingsTimer.C: sc.logf("timeout waiting for SETTINGS frames from %v", sc.conn.RemoteAddr()) return + case <-gracefulShutdownCh: + gracefulShutdownCh = nil + sc.startGracefulShutdown() case <-sc.shutdownTimerCh: sc.vlogf("GOAWAY close timer fired; closing conn from %v", sc.conn.RemoteAddr()) return + case <-sc.idleTimerCh: + sc.vlogf("connection is idle") + sc.goAway(ErrCodeNo) case fn := <-sc.testHookCh: fn(loopNum) } + + if sc.inGoAway && sc.curOpenStreams() == 0 && !sc.needToSendGoAway && !sc.writingFrame { + return + } } } @@ -760,7 +817,7 @@ func (sc *serverConn) writeDataFromHandler(stream *stream, data []byte, endStrea ch := errChanPool.Get().(chan error) writeArg := writeDataPool.Get().(*writeData) *writeArg = writeData{stream.id, data, endStream} - err := sc.writeFrameFromHandler(frameWriteMsg{ + err := sc.writeFrameFromHandler(FrameWriteRequest{ write: writeArg, stream: stream, done: ch, @@ -796,17 +853,17 @@ func (sc *serverConn) writeDataFromHandler(stream *stream, data []byte, endStrea return err } -// writeFrameFromHandler sends wm to sc.wantWriteFrameCh, but aborts +// writeFrameFromHandler sends wr to sc.wantWriteFrameCh, but aborts // if the connection has gone away. // // This must not be run from the serve goroutine itself, else it might // deadlock writing to sc.wantWriteFrameCh (which is only mildly // buffered and is read by serve itself). If you're on the serve // goroutine, call writeFrame instead. -func (sc *serverConn) writeFrameFromHandler(wm frameWriteMsg) error { +func (sc *serverConn) writeFrameFromHandler(wr FrameWriteRequest) error { sc.serveG.checkNotOn() // NOT select { - case sc.wantWriteFrameCh <- wm: + case sc.wantWriteFrameCh <- wr: return nil case <-sc.doneServing: // Serve loop is gone. @@ -823,55 +880,103 @@ func (sc *serverConn) writeFrameFromHandler(wm frameWriteMsg) error { // make it onto the wire // // If you're not on the serve goroutine, use writeFrameFromHandler instead. -func (sc *serverConn) writeFrame(wm frameWriteMsg) { +func (sc *serverConn) writeFrame(wr FrameWriteRequest) { sc.serveG.check() + // If true, wr will not be written and wr.done will not be signaled. var ignoreWrite bool + // We are not allowed to write frames on closed streams. RFC 7540 Section + // 5.1.1 says: "An endpoint MUST NOT send frames other than PRIORITY on + // a closed stream." Our server never sends PRIORITY, so that exception + // does not apply. + // + // The serverConn might close an open stream while the stream's handler + // is still running. For example, the server might close a stream when it + // receives bad data from the client. If this happens, the handler might + // attempt to write a frame after the stream has been closed (since the + // handler hasn't yet been notified of the close). In this case, we simply + // ignore the frame. The handler will notice that the stream is closed when + // it waits for the frame to be written. + // + // As an exception to this rule, we allow sending RST_STREAM after close. + // This allows us to immediately reject new streams without tracking any + // state for those streams (except for the queued RST_STREAM frame). This + // may result in duplicate RST_STREAMs in some cases, but the client should + // ignore those. + if wr.StreamID() != 0 { + _, isReset := wr.write.(StreamError) + if state, _ := sc.state(wr.StreamID()); state == stateClosed && !isReset { + ignoreWrite = true + } + } + // Don't send a 100-continue response if we've already sent headers. // See golang.org/issue/14030. - switch wm.write.(type) { + switch wr.write.(type) { case *writeResHeaders: - wm.stream.wroteHeaders = true + wr.stream.wroteHeaders = true case write100ContinueHeadersFrame: - if wm.stream.wroteHeaders { + if wr.stream.wroteHeaders { + // We do not need to notify wr.done because this frame is + // never written with wr.done != nil. + if wr.done != nil { + panic("wr.done != nil for write100ContinueHeadersFrame") + } ignoreWrite = true } } if !ignoreWrite { - sc.writeSched.add(wm) + sc.writeSched.Push(wr) } sc.scheduleFrameWrite() } -// startFrameWrite starts a goroutine to write wm (in a separate +// startFrameWrite starts a goroutine to write wr (in a separate // goroutine since that might block on the network), and updates the -// serve goroutine's state about the world, updated from info in wm. -func (sc *serverConn) startFrameWrite(wm frameWriteMsg) { +// serve goroutine's state about the world, updated from info in wr. +func (sc *serverConn) startFrameWrite(wr FrameWriteRequest) { sc.serveG.check() if sc.writingFrame { panic("internal error: can only be writing one frame at a time") } - st := wm.stream + st := wr.stream if st != nil { switch st.state { case stateHalfClosedLocal: - panic("internal error: attempt to send frame on half-closed-local stream") - case stateClosed: - if st.sentReset || st.gotReset { - // Skip this frame. - sc.scheduleFrameWrite() - return + switch wr.write.(type) { + case StreamError, handlerPanicRST, writeWindowUpdate: + // RFC 7540 Section 5.1 allows sending RST_STREAM, PRIORITY, and WINDOW_UPDATE + // in this state. (We never send PRIORITY from the server, so that is not checked.) + default: + panic(fmt.Sprintf("internal error: attempt to send frame on a half-closed-local stream: %v", wr)) } - panic(fmt.Sprintf("internal error: attempt to send a write %v on a closed stream", wm)) + case stateClosed: + panic(fmt.Sprintf("internal error: attempt to send frame on a closed stream: %v", wr)) + } + } + if wpp, ok := wr.write.(*writePushPromise); ok { + var err error + wpp.promisedID, err = wpp.allocatePromisedID() + if err != nil { + sc.writingFrameAsync = false + wr.replyToWriter(err) + return } } sc.writingFrame = true sc.needsFrameFlush = true - go sc.writeFrameAsync(wm) + if wr.write.staysWithinBuffer(sc.bw.Available()) { + sc.writingFrameAsync = false + err := wr.write.writeFrame(sc) + sc.wroteFrame(frameWriteResult{wr, err}) + } else { + sc.writingFrameAsync = true + go sc.writeFrameAsync(wr) + } } // errHandlerPanicked is the error given to any callers blocked in a read from @@ -887,27 +992,12 @@ func (sc *serverConn) wroteFrame(res frameWriteResult) { panic("internal error: expected to be already writing a frame") } sc.writingFrame = false + sc.writingFrameAsync = false - wm := res.wm - st := wm.stream + wr := res.wr - closeStream := endsStream(wm.write) - - if _, ok := wm.write.(handlerPanicRST); ok { - sc.closeStream(st, errHandlerPanicked) - } - - // Reply (if requested) to the blocked ServeHTTP goroutine. - if ch := wm.done; ch != nil { - select { - case ch <- res.err: - default: - panic(fmt.Sprintf("unbuffered done channel passed in for type %T", wm.write)) - } - } - wm.write = nil // prevent use (assume it's tainted after wm.done send) - - if closeStream { + if writeEndsStream(wr.write) { + st := wr.stream if st == nil { panic("internal error: expecting non-nil stream") } @@ -916,19 +1006,33 @@ func (sc *serverConn) wroteFrame(res frameWriteResult) { // Here we would go to stateHalfClosedLocal in // theory, but since our handler is done and // the net/http package provides no mechanism - // for finishing writing to a ResponseWriter - // while still reading data (see possible TODO - // at top of this file), we go into closed - // state here anyway, after telling the peer - // we're hanging up on them. - st.state = stateHalfClosedLocal // won't last long, but necessary for closeStream via resetStream - errCancel := StreamError{st.id, ErrCodeCancel} - sc.resetStream(errCancel) + // for closing a ResponseWriter while still + // reading data (see possible TODO at top of + // this file), we go into closed state here + // anyway, after telling the peer we're + // hanging up on them. We'll transition to + // stateClosed after the RST_STREAM frame is + // written. + st.state = stateHalfClosedLocal + sc.resetStream(streamError(st.id, ErrCodeCancel)) case stateHalfClosedRemote: sc.closeStream(st, errHandlerComplete) } + } else { + switch v := wr.write.(type) { + case StreamError: + // st may be unknown if the RST_STREAM was generated to reject bad input. + if st, ok := sc.streams[v.StreamID]; ok { + sc.closeStream(st, v) + } + case handlerPanicRST: + sc.closeStream(wr.stream, errHandlerPanicked) + } } + // Reply (if requested) to unblock the ServeHTTP goroutine. + wr.replyToWriter(res.err) + sc.scheduleFrameWrite() } @@ -946,47 +1050,68 @@ func (sc *serverConn) wroteFrame(res frameWriteResult) { // flush the write buffer. func (sc *serverConn) scheduleFrameWrite() { sc.serveG.check() - if sc.writingFrame { + if sc.writingFrame || sc.inFrameScheduleLoop { return } - if sc.needToSendGoAway { - sc.needToSendGoAway = false - sc.startFrameWrite(frameWriteMsg{ - write: &writeGoAway{ - maxStreamID: sc.maxStreamID, - code: sc.goAwayCode, - }, - }) - return - } - if sc.needToSendSettingsAck { - sc.needToSendSettingsAck = false - sc.startFrameWrite(frameWriteMsg{write: writeSettingsAck{}}) - return - } - if !sc.inGoAway { - if wm, ok := sc.writeSched.take(); ok { - sc.startFrameWrite(wm) - return + sc.inFrameScheduleLoop = true + for !sc.writingFrameAsync { + if sc.needToSendGoAway { + sc.needToSendGoAway = false + sc.startFrameWrite(FrameWriteRequest{ + write: &writeGoAway{ + maxStreamID: sc.maxClientStreamID, + code: sc.goAwayCode, + }, + }) + continue } + if sc.needToSendSettingsAck { + sc.needToSendSettingsAck = false + sc.startFrameWrite(FrameWriteRequest{write: writeSettingsAck{}}) + continue + } + if !sc.inGoAway || sc.goAwayCode == ErrCodeNo { + if wr, ok := sc.writeSched.Pop(); ok { + sc.startFrameWrite(wr) + continue + } + } + if sc.needsFrameFlush { + sc.startFrameWrite(FrameWriteRequest{write: flushFrameWriter{}}) + sc.needsFrameFlush = false // after startFrameWrite, since it sets this true + continue + } + break } - if sc.needsFrameFlush { - sc.startFrameWrite(frameWriteMsg{write: flushFrameWriter{}}) - sc.needsFrameFlush = false // after startFrameWrite, since it sets this true - return - } + sc.inFrameScheduleLoop = false +} + +// startGracefulShutdown sends a GOAWAY with ErrCodeNo to tell the +// client we're gracefully shutting down. The connection isn't closed +// until all current streams are done. +func (sc *serverConn) startGracefulShutdown() { + sc.goAwayIn(ErrCodeNo, 0) } func (sc *serverConn) goAway(code ErrCode) { + sc.serveG.check() + var forceCloseIn time.Duration + if code != ErrCodeNo { + forceCloseIn = 250 * time.Millisecond + } else { + // TODO: configurable + forceCloseIn = 1 * time.Second + } + sc.goAwayIn(code, forceCloseIn) +} + +func (sc *serverConn) goAwayIn(code ErrCode, forceCloseIn time.Duration) { sc.serveG.check() if sc.inGoAway { return } - if code != ErrCodeNo { - sc.shutDownIn(250 * time.Millisecond) - } else { - // TODO: configurable - sc.shutDownIn(1 * time.Second) + if forceCloseIn != 0 { + sc.shutDownIn(forceCloseIn) } sc.inGoAway = true sc.needToSendGoAway = true @@ -1002,10 +1127,9 @@ func (sc *serverConn) shutDownIn(d time.Duration) { func (sc *serverConn) resetStream(se StreamError) { sc.serveG.check() - sc.writeFrame(frameWriteMsg{write: se}) + sc.writeFrame(FrameWriteRequest{write: se}) if st, ok := sc.streams[se.StreamID]; ok { - st.sentReset = true - sc.closeStream(st, se) + st.resetQueued = true } } @@ -1090,6 +1214,8 @@ func (sc *serverConn) processFrame(f Frame) error { return sc.processResetStream(f) case *PriorityFrame: return sc.processPriority(f) + case *GoAwayFrame: + return sc.processGoAway(f) case *PushPromiseFrame: // A client cannot push. Thus, servers MUST treat the receipt of a PUSH_PROMISE // frame as a connection error (Section 5.4.1) of type PROTOCOL_ERROR. @@ -1115,7 +1241,10 @@ func (sc *serverConn) processPing(f *PingFrame) error { // PROTOCOL_ERROR." return ConnectionError(ErrCodeProtocol) } - sc.writeFrame(frameWriteMsg{write: writePingAck{f}}) + if sc.inGoAway && sc.goAwayCode != ErrCodeNo { + return nil + } + sc.writeFrame(FrameWriteRequest{write: writePingAck{f}}) return nil } @@ -1123,7 +1252,14 @@ func (sc *serverConn) processWindowUpdate(f *WindowUpdateFrame) error { sc.serveG.check() switch { case f.StreamID != 0: // stream-level flow control - st := sc.streams[f.StreamID] + state, st := sc.state(f.StreamID) + if state == stateIdle { + // Section 5.1: "Receiving any frame other than HEADERS + // or PRIORITY on a stream in this state MUST be + // treated as a connection error (Section 5.4.1) of + // type PROTOCOL_ERROR." + return ConnectionError(ErrCodeProtocol) + } if st == nil { // "WINDOW_UPDATE can be sent by a peer that has sent a // frame bearing the END_STREAM flag. This means that a @@ -1133,7 +1269,7 @@ func (sc *serverConn) processWindowUpdate(f *WindowUpdateFrame) error { return nil } if !st.flow.add(int32(f.Increment)) { - return StreamError{f.StreamID, ErrCodeFlowControl} + return streamError(f.StreamID, ErrCodeFlowControl) } default: // connection-level flow control if !sc.flow.add(int32(f.Increment)) { @@ -1157,9 +1293,8 @@ func (sc *serverConn) processResetStream(f *RSTStreamFrame) error { return ConnectionError(ErrCodeProtocol) } if st != nil { - st.gotReset = true st.cancelCtx() - sc.closeStream(st, StreamError{f.StreamID, f.ErrCode}) + sc.closeStream(st, streamError(f.StreamID, f.ErrCode)) } return nil } @@ -1170,28 +1305,30 @@ func (sc *serverConn) closeStream(st *stream, err error) { panic(fmt.Sprintf("invariant; can't close stream in state %v", st.state)) } st.state = stateClosed - sc.curOpenStreams-- - if sc.curOpenStreams == 0 { - sc.setConnState(http.StateIdle) + if st.isPushed() { + sc.curPushedStreams-- + } else { + sc.curClientStreams-- } delete(sc.streams, st.id) + if len(sc.streams) == 0 { + sc.setConnState(http.StateIdle) + if sc.srv.IdleTimeout != 0 { + sc.idleTimer.Reset(sc.srv.IdleTimeout) + } + if h1ServerKeepAlivesDisabled(sc.hs) { + sc.startGracefulShutdown() + } + } if p := st.body; p != nil { + // Return any buffered unread bytes worth of conn-level flow control. + // See golang.org/issue/16481 + sc.sendWindowUpdate(nil, p.Len()) + p.CloseWithError(err) } st.cw.Close() // signals Handler's CloseNotifier, unblocks writes, etc - sc.writeSched.forgetStream(st.id) - if st.reqBuf != nil { - // Stash this request body buffer (64k) away for reuse - // by a future POST/PUT/etc. - // - // TODO(bradfitz): share on the server? sync.Pool? - // Server requires locks and might hurt contention. - // sync.Pool might work, or might be worse, depending - // on goroutine CPU migrations. (get and put on - // separate CPUs). Maybe a mix of strategies. But - // this is an easy win for now. - sc.freeRequestBodyBuf = st.reqBuf - } + sc.writeSched.CloseStream(st.id) } func (sc *serverConn) processSettings(f *SettingsFrame) error { @@ -1233,7 +1370,7 @@ func (sc *serverConn) processSetting(s Setting) error { case SettingInitialWindowSize: return sc.processSettingInitialWindowSize(s.Val) case SettingMaxFrameSize: - sc.writeSched.maxFrameSize = s.Val + sc.maxFrameSize = int32(s.Val) // the maximum valid s.Val is < 2^31 case SettingMaxHeaderListSize: sc.peerMaxHeaderListSize = s.Val default: @@ -1277,43 +1414,82 @@ func (sc *serverConn) processSettingInitialWindowSize(val uint32) error { func (sc *serverConn) processData(f *DataFrame) error { sc.serveG.check() + if sc.inGoAway && sc.goAwayCode != ErrCodeNo { + return nil + } + data := f.Data() + // "If a DATA frame is received whose stream is not in "open" // or "half closed (local)" state, the recipient MUST respond // with a stream error (Section 5.4.2) of type STREAM_CLOSED." id := f.Header().StreamID - st, ok := sc.streams[id] - if !ok || st.state != stateOpen || st.gotTrailerHeader { + state, st := sc.state(id) + if id == 0 || state == stateIdle { + // Section 5.1: "Receiving any frame other than HEADERS + // or PRIORITY on a stream in this state MUST be + // treated as a connection error (Section 5.4.1) of + // type PROTOCOL_ERROR." + return ConnectionError(ErrCodeProtocol) + } + if st == nil || state != stateOpen || st.gotTrailerHeader || st.resetQueued { // This includes sending a RST_STREAM if the stream is // in stateHalfClosedLocal (which currently means that // the http.Handler returned, so it's done reading & // done writing). Try to stop the client from sending // more DATA. - return StreamError{id, ErrCodeStreamClosed} + + // But still enforce their connection-level flow control, + // and return any flow control bytes since we're not going + // to consume them. + if sc.inflow.available() < int32(f.Length) { + return streamError(id, ErrCodeFlowControl) + } + // Deduct the flow control from inflow, since we're + // going to immediately add it back in + // sendWindowUpdate, which also schedules sending the + // frames. + sc.inflow.take(int32(f.Length)) + sc.sendWindowUpdate(nil, int(f.Length)) // conn-level + + if st != nil && st.resetQueued { + // Already have a stream error in flight. Don't send another. + return nil + } + return streamError(id, ErrCodeStreamClosed) } if st.body == nil { panic("internal error: should have a body in this state") } - data := f.Data() // Sender sending more than they'd declared? if st.declBodyBytes != -1 && st.bodyBytes+int64(len(data)) > st.declBodyBytes { st.body.CloseWithError(fmt.Errorf("sender tried to send more than declared Content-Length of %d bytes", st.declBodyBytes)) - return StreamError{id, ErrCodeStreamClosed} + return streamError(id, ErrCodeStreamClosed) } - if len(data) > 0 { + if f.Length > 0 { // Check whether the client has flow control quota. - if int(st.inflow.available()) < len(data) { - return StreamError{id, ErrCodeFlowControl} + if st.inflow.available() < int32(f.Length) { + return streamError(id, ErrCodeFlowControl) } - st.inflow.take(int32(len(data))) - wrote, err := st.body.Write(data) - if err != nil { - return StreamError{id, ErrCodeStreamClosed} + st.inflow.take(int32(f.Length)) + + if len(data) > 0 { + wrote, err := st.body.Write(data) + if err != nil { + return streamError(id, ErrCodeStreamClosed) + } + if wrote != len(data) { + panic("internal error: bad Writer") + } + st.bodyBytes += int64(len(data)) } - if wrote != len(data) { - panic("internal error: bad Writer") + + // Return any padded flow control now, since we won't + // refund it later on body reads. + if pad := int32(f.Length) - int32(len(data)); pad > 0 { + sc.sendWindowUpdate32(nil, pad) + sc.sendWindowUpdate32(st, pad) } - st.bodyBytes += int64(len(data)) } if f.StreamEnded() { st.endStream() @@ -1321,6 +1497,25 @@ func (sc *serverConn) processData(f *DataFrame) error { return nil } +func (sc *serverConn) processGoAway(f *GoAwayFrame) error { + sc.serveG.check() + if f.ErrCode != ErrCodeNo { + sc.logf("http2: received GOAWAY %+v, starting graceful shutdown", f) + } else { + sc.vlogf("http2: received GOAWAY %+v, starting graceful shutdown", f) + } + sc.startGracefulShutdown() + // http://tools.ietf.org/html/rfc7540#section-6.8 + // We should not create any new streams, which means we should disable push. + sc.pushEnabled = false + return nil +} + +// isPushed reports whether the stream is server-initiated. +func (st *stream) isPushed() bool { + return st.id%2 == 0 +} + // endStream closes a Request.Body's pipe. It is called when a DATA // frame says a request body is over (or after trailers). func (st *stream) endStream() { @@ -1350,12 +1545,12 @@ func (st *stream) copyTrailersToHandlerRequest() { func (sc *serverConn) processHeaders(f *MetaHeadersFrame) error { sc.serveG.check() - id := f.Header().StreamID + id := f.StreamID if sc.inGoAway { // Ignore. return nil } - // http://http2.github.io/http2-spec/#rfc.section.5.1.1 + // http://tools.ietf.org/html/rfc7540#section-5.1.1 // Streams initiated by a client MUST use odd-numbered stream // identifiers. [...] An endpoint that receives an unexpected // stream identifier MUST respond with a connection error @@ -1367,8 +1562,12 @@ func (sc *serverConn) processHeaders(f *MetaHeadersFrame) error { // send a trailer for an open one. If we already have a stream // open, let it process its own HEADERS frame (trailers at this // point, if it's valid). - st := sc.streams[f.Header().StreamID] - if st != nil { + if st := sc.streams[f.StreamID]; st != nil { + if st.resetQueued { + // We're sending RST_STREAM to close the stream, so don't bother + // processing this frame. + return nil + } return st.processTrailerHeaders(f) } @@ -1377,54 +1576,45 @@ func (sc *serverConn) processHeaders(f *MetaHeadersFrame) error { // endpoint has opened or reserved. [...] An endpoint that // receives an unexpected stream identifier MUST respond with // a connection error (Section 5.4.1) of type PROTOCOL_ERROR. - if id <= sc.maxStreamID { + if id <= sc.maxClientStreamID { return ConnectionError(ErrCodeProtocol) } - sc.maxStreamID = id + sc.maxClientStreamID = id - ctx, cancelCtx := contextWithCancel(sc.baseCtx) - st = &stream{ - sc: sc, - id: id, - state: stateOpen, - ctx: ctx, - cancelCtx: cancelCtx, + if sc.idleTimer != nil { + sc.idleTimer.Stop() } - if f.StreamEnded() { - st.state = stateHalfClosedRemote - } - st.cw.Init() - st.flow.conn = &sc.flow // link to conn-level counter - st.flow.add(sc.initialWindowSize) - st.inflow.conn = &sc.inflow // link to conn-level counter - st.inflow.add(initialWindowSize) // TODO: update this when we send a higher initial window size in the initial settings - - sc.streams[id] = st - if f.HasPriority() { - adjustStreamPriority(sc.streams, st.id, f.Priority) - } - sc.curOpenStreams++ - if sc.curOpenStreams == 1 { - sc.setConnState(http.StateActive) - } - if sc.curOpenStreams > sc.advMaxStreams { - // "Endpoints MUST NOT exceed the limit set by their - // peer. An endpoint that receives a HEADERS frame - // that causes their advertised concurrent stream - // limit to be exceeded MUST treat this as a stream - // error (Section 5.4.2) of type PROTOCOL_ERROR or - // REFUSED_STREAM." + // http://tools.ietf.org/html/rfc7540#section-5.1.2 + // [...] Endpoints MUST NOT exceed the limit set by their peer. An + // endpoint that receives a HEADERS frame that causes their + // advertised concurrent stream limit to be exceeded MUST treat + // this as a stream error (Section 5.4.2) of type PROTOCOL_ERROR + // or REFUSED_STREAM. + if sc.curClientStreams+1 > sc.advMaxStreams { if sc.unackedSettings == 0 { // They should know better. - return StreamError{st.id, ErrCodeProtocol} + return streamError(id, ErrCodeProtocol) } // Assume it's a network race, where they just haven't // received our last SETTINGS update. But actually // this can't happen yet, because we don't yet provide // a way for users to adjust server parameters at // runtime. - return StreamError{st.id, ErrCodeRefusedStream} + return streamError(id, ErrCodeRefusedStream) + } + + initialState := stateOpen + if f.StreamEnded() { + initialState = stateHalfClosedRemote + } + st := sc.newStream(id, 0, initialState) + + if f.HasPriority() { + if err := checkPriority(f.StreamID, f.Priority); err != nil { + return err + } + sc.writeSched.AdjustStream(st.id, f.Priority) } rw, req, err := sc.newWriterAndRequest(st, f) @@ -1442,10 +1632,21 @@ func (sc *serverConn) processHeaders(f *MetaHeadersFrame) error { if f.Truncated { // Their header list was too long. Send a 431 error. handler = handleHeaderListTooLong - } else if err := checkValidHTTP2Request(req); err != nil { + } else if err := checkValidHTTP2RequestHeaders(req.Header); err != nil { handler = new400Handler(err) } + // The net/http package sets the read deadline from the + // http.Server.ReadTimeout during the TLS handshake, but then + // passes the connection off to us with the deadline already + // set. Disarm it here after the request headers are read, + // similar to how the http1 server works. Here it's + // technically more like the http1 Server's ReadHeaderTimeout + // (in Go 1.8), though. That's a more sane option anyway. + if sc.hs.ReadTimeout != 0 { + sc.conn.SetReadDeadline(time.Time{}) + } + go sc.runHandler(rw, req, handler) return nil } @@ -1458,11 +1659,11 @@ func (st *stream) processTrailerHeaders(f *MetaHeadersFrame) error { } st.gotTrailerHeader = true if !f.StreamEnded() { - return StreamError{st.id, ErrCodeProtocol} + return streamError(st.id, ErrCodeProtocol) } if len(f.PseudoFields()) > 0 { - return StreamError{st.id, ErrCodeProtocol} + return streamError(st.id, ErrCodeProtocol) } if st.trailer != nil { for _, hf := range f.RegularFields() { @@ -1471,7 +1672,7 @@ func (st *stream) processTrailerHeaders(f *MetaHeadersFrame) error { // TODO: send more details to the peer somehow. But http2 has // no way to send debug data at a stream level. Discuss with // HTTP folk. - return StreamError{st.id, ErrCodeProtocol} + return streamError(st.id, ErrCodeProtocol) } st.trailer[key] = append(st.trailer[key], hf.Value) } @@ -1480,62 +1681,78 @@ func (st *stream) processTrailerHeaders(f *MetaHeadersFrame) error { return nil } -func (sc *serverConn) processPriority(f *PriorityFrame) error { - adjustStreamPriority(sc.streams, f.StreamID, f.PriorityParam) +func checkPriority(streamID uint32, p PriorityParam) error { + if streamID == p.StreamDep { + // Section 5.3.1: "A stream cannot depend on itself. An endpoint MUST treat + // this as a stream error (Section 5.4.2) of type PROTOCOL_ERROR." + // Section 5.3.3 says that a stream can depend on one of its dependencies, + // so it's only self-dependencies that are forbidden. + return streamError(streamID, ErrCodeProtocol) + } return nil } -func adjustStreamPriority(streams map[uint32]*stream, streamID uint32, priority PriorityParam) { - st, ok := streams[streamID] - if !ok { - // TODO: not quite correct (this streamID might - // already exist in the dep tree, but be closed), but - // close enough for now. - return +func (sc *serverConn) processPriority(f *PriorityFrame) error { + if sc.inGoAway { + return nil } - st.weight = priority.Weight - parent := streams[priority.StreamDep] // might be nil - if parent == st { - // if client tries to set this stream to be the parent of itself - // ignore and keep going - return + if err := checkPriority(f.StreamID, f.PriorityParam); err != nil { + return err + } + sc.writeSched.AdjustStream(f.StreamID, f.PriorityParam) + return nil +} + +func (sc *serverConn) newStream(id, pusherID uint32, state streamState) *stream { + sc.serveG.check() + if id == 0 { + panic("internal error: cannot create stream with id 0") } - // section 5.3.3: If a stream is made dependent on one of its - // own dependencies, the formerly dependent stream is first - // moved to be dependent on the reprioritized stream's previous - // parent. The moved dependency retains its weight. - for piter := parent; piter != nil; piter = piter.parent { - if piter == st { - parent.parent = st.parent - break - } + ctx, cancelCtx := contextWithCancel(sc.baseCtx) + st := &stream{ + sc: sc, + id: id, + state: state, + ctx: ctx, + cancelCtx: cancelCtx, } - st.parent = parent - if priority.Exclusive && (st.parent != nil || priority.StreamDep == 0) { - for _, openStream := range streams { - if openStream != st && openStream.parent == st.parent { - openStream.parent = st - } - } + st.cw.Init() + st.flow.conn = &sc.flow // link to conn-level counter + st.flow.add(sc.initialWindowSize) + st.inflow.conn = &sc.inflow // link to conn-level counter + st.inflow.add(initialWindowSize) // TODO: update this when we send a higher initial window size in the initial settings + + sc.streams[id] = st + sc.writeSched.OpenStream(st.id, OpenStreamOptions{PusherID: pusherID}) + if st.isPushed() { + sc.curPushedStreams++ + } else { + sc.curClientStreams++ } + if sc.curOpenStreams() == 1 { + sc.setConnState(http.StateActive) + } + + return st } func (sc *serverConn) newWriterAndRequest(st *stream, f *MetaHeadersFrame) (*responseWriter, *http.Request, error) { sc.serveG.check() - method := f.PseudoValue("method") - path := f.PseudoValue("path") - scheme := f.PseudoValue("scheme") - authority := f.PseudoValue("authority") + rp := requestParam{ + method: f.PseudoValue("method"), + scheme: f.PseudoValue("scheme"), + authority: f.PseudoValue("authority"), + path: f.PseudoValue("path"), + } - isConnect := method == "CONNECT" + isConnect := rp.method == "CONNECT" if isConnect { - if path != "" || scheme != "" || authority == "" { - return nil, nil, StreamError{f.StreamID, ErrCodeProtocol} + if rp.path != "" || rp.scheme != "" || rp.authority == "" { + return nil, nil, streamError(f.StreamID, ErrCodeProtocol) } - } else if method == "" || path == "" || - (scheme != "https" && scheme != "http") { + } else if rp.method == "" || rp.path == "" || (rp.scheme != "https" && rp.scheme != "http") { // See 8.1.2.6 Malformed Requests and Responses: // // Malformed requests or responses that are detected @@ -1546,40 +1763,68 @@ func (sc *serverConn) newWriterAndRequest(st *stream, f *MetaHeadersFrame) (*res // "All HTTP/2 requests MUST include exactly one valid // value for the :method, :scheme, and :path // pseudo-header fields" - return nil, nil, StreamError{f.StreamID, ErrCodeProtocol} + return nil, nil, streamError(f.StreamID, ErrCodeProtocol) } bodyOpen := !f.StreamEnded() - if method == "HEAD" && bodyOpen { + if rp.method == "HEAD" && bodyOpen { // HEAD requests can't have bodies - return nil, nil, StreamError{f.StreamID, ErrCodeProtocol} + return nil, nil, streamError(f.StreamID, ErrCodeProtocol) } - var tlsState *tls.ConnectionState // nil if not scheme https - if scheme == "https" { + rp.header = make(http.Header) + for _, hf := range f.RegularFields() { + rp.header.Add(sc.canonicalHeader(hf.Name), hf.Value) + } + if rp.authority == "" { + rp.authority = rp.header.Get("Host") + } + + rw, req, err := sc.newWriterAndRequestNoBody(st, rp) + if err != nil { + return nil, nil, err + } + if bodyOpen { + st.reqBuf = getRequestBodyBuf() + req.Body.(*requestBody).pipe = &pipe{ + b: &fixedBuffer{buf: st.reqBuf}, + } + + if vv, ok := rp.header["Content-Length"]; ok { + req.ContentLength, _ = strconv.ParseInt(vv[0], 10, 64) + } else { + req.ContentLength = -1 + } + } + return rw, req, nil +} + +type requestParam struct { + method string + scheme, authority, path string + header http.Header +} + +func (sc *serverConn) newWriterAndRequestNoBody(st *stream, rp requestParam) (*responseWriter, *http.Request, error) { + sc.serveG.check() + + var tlsState *tls.ConnectionState // nil if not scheme https + if rp.scheme == "https" { tlsState = sc.tlsState } - header := make(http.Header) - for _, hf := range f.RegularFields() { - header.Add(sc.canonicalHeader(hf.Name), hf.Value) - } - - if authority == "" { - authority = header.Get("Host") - } - needsContinue := header.Get("Expect") == "100-continue" + needsContinue := rp.header.Get("Expect") == "100-continue" if needsContinue { - header.Del("Expect") + rp.header.Del("Expect") } // Merge Cookie headers into one "; "-delimited value. - if cookies := header["Cookie"]; len(cookies) > 1 { - header.Set("Cookie", strings.Join(cookies, "; ")) + if cookies := rp.header["Cookie"]; len(cookies) > 1 { + rp.header.Set("Cookie", strings.Join(cookies, "; ")) } // Setup Trailers var trailer http.Header - for _, v := range header["Trailer"] { + for _, v := range rp.header["Trailer"] { for _, key := range strings.Split(v, ",") { key = http.CanonicalHeaderKey(strings.TrimSpace(key)) switch key { @@ -1594,57 +1839,42 @@ func (sc *serverConn) newWriterAndRequest(st *stream, f *MetaHeadersFrame) (*res } } } - delete(header, "Trailer") + delete(rp.header, "Trailer") + + var url_ *url.URL + var requestURI string + if rp.method == "CONNECT" { + url_ = &url.URL{Host: rp.authority} + requestURI = rp.authority // mimic HTTP/1 server behavior + } else { + var err error + url_, err = url.ParseRequestURI(rp.path) + if err != nil { + return nil, nil, streamError(st.id, ErrCodeProtocol) + } + requestURI = rp.path + } body := &requestBody{ conn: sc, stream: st, needsContinue: needsContinue, } - var url_ *url.URL - var requestURI string - if isConnect { - url_ = &url.URL{Host: authority} - requestURI = authority // mimic HTTP/1 server behavior - } else { - var err error - url_, err = url.ParseRequestURI(path) - if err != nil { - return nil, nil, StreamError{f.StreamID, ErrCodeProtocol} - } - requestURI = path - } req := &http.Request{ - Method: method, + Method: rp.method, URL: url_, RemoteAddr: sc.remoteAddrStr, - Header: header, + Header: rp.header, RequestURI: requestURI, Proto: "HTTP/2.0", ProtoMajor: 2, ProtoMinor: 0, TLS: tlsState, - Host: authority, + Host: rp.authority, Body: body, Trailer: trailer, } req = requestWithContext(req, st.ctx) - if bodyOpen { - // Disabled, per golang.org/issue/14960: - // st.reqBuf = sc.getRequestBodyBuf() - // TODO: remove this 64k of garbage per request (again, but without a data race): - buf := make([]byte, initialWindowSize) - - body.pipe = &pipe{ - b: &fixedBuffer{buf: buf}, - } - - if vv, ok := header["Content-Length"]; ok { - req.ContentLength, _ = strconv.ParseInt(vv[0], 10, 64) - } else { - req.ContentLength = -1 - } - } rws := responseWriterStatePool.Get().(*responseWriterState) bwSave := rws.bw @@ -1660,13 +1890,22 @@ func (sc *serverConn) newWriterAndRequest(st *stream, f *MetaHeadersFrame) (*res return rw, req, nil } -func (sc *serverConn) getRequestBodyBuf() []byte { - sc.serveG.check() - if buf := sc.freeRequestBodyBuf; buf != nil { - sc.freeRequestBodyBuf = nil - return buf +var reqBodyCache = make(chan []byte, 8) + +func getRequestBodyBuf() []byte { + select { + case b := <-reqBodyCache: + return b + default: + return make([]byte, initialWindowSize) + } +} + +func putRequestBodyBuf(b []byte) { + select { + case reqBodyCache <- b: + default: } - return make([]byte, initialWindowSize) } // Run on its own goroutine. @@ -1676,15 +1915,17 @@ func (sc *serverConn) runHandler(rw *responseWriter, req *http.Request, handler rw.rws.stream.cancelCtx() if didPanic { e := recover() - // Same as net/http: - const size = 64 << 10 - buf := make([]byte, size) - buf = buf[:runtime.Stack(buf, false)] - sc.writeFrameFromHandler(frameWriteMsg{ + sc.writeFrameFromHandler(FrameWriteRequest{ write: handlerPanicRST{rw.rws.stream.id}, stream: rw.rws.stream, }) - sc.logf("http2: panic serving %v: %v\n%s", sc.conn.RemoteAddr(), e, buf) + // Same as net/http: + if shouldLogPanic(e) { + const size = 64 << 10 + buf := make([]byte, size) + buf = buf[:runtime.Stack(buf, false)] + sc.logf("http2: panic serving %v: %v\n%s", sc.conn.RemoteAddr(), e, buf) + } return } rw.handlerDone() @@ -1715,7 +1956,7 @@ func (sc *serverConn) writeHeaders(st *stream, headerData *writeResHeaders) erro // mutates it. errc = errChanPool.Get().(chan error) } - if err := sc.writeFrameFromHandler(frameWriteMsg{ + if err := sc.writeFrameFromHandler(FrameWriteRequest{ write: headerData, stream: st, done: errc, @@ -1738,7 +1979,7 @@ func (sc *serverConn) writeHeaders(st *stream, headerData *writeResHeaders) erro // called from handler goroutines. func (sc *serverConn) write100ContinueHeaders(st *stream) { - sc.writeFrameFromHandler(frameWriteMsg{ + sc.writeFrameFromHandler(FrameWriteRequest{ write: write100ContinueHeadersFrame{st.id}, stream: st, }) @@ -1754,11 +1995,19 @@ type bodyReadMsg struct { // called from handler goroutines. // Notes that the handler for the given stream ID read n bytes of its body // and schedules flow control tokens to be sent. -func (sc *serverConn) noteBodyReadFromHandler(st *stream, n int) { +func (sc *serverConn) noteBodyReadFromHandler(st *stream, n int, err error) { sc.serveG.checkNotOn() // NOT on - select { - case sc.bodyReadCh <- bodyReadMsg{st, n}: - case <-sc.doneServing: + if n > 0 { + select { + case sc.bodyReadCh <- bodyReadMsg{st, n}: + case <-sc.doneServing: + } + } + if err == io.EOF { + if buf := st.reqBuf; buf != nil { + st.reqBuf = nil // shouldn't matter; field unused by other + putRequestBodyBuf(buf) + } } } @@ -1801,7 +2050,7 @@ func (sc *serverConn) sendWindowUpdate32(st *stream, n int32) { if st != nil { streamID = st.id } - sc.writeFrame(frameWriteMsg{ + sc.writeFrame(FrameWriteRequest{ write: writeWindowUpdate{streamID: streamID, n: uint32(n)}, stream: st, }) @@ -1816,16 +2065,19 @@ func (sc *serverConn) sendWindowUpdate32(st *stream, n int32) { } } +// requestBody is the Handler's Request.Body type. +// Read and Close may be called concurrently. type requestBody struct { stream *stream conn *serverConn - closed bool + closed bool // for use by Close only + sawEOF bool // for use by Read only pipe *pipe // non-nil if we have a HTTP entity message body needsContinue bool // need to send a 100-continue } func (b *requestBody) Close() error { - if b.pipe != nil { + if b.pipe != nil && !b.closed { b.pipe.BreakWithError(errClosedBody) } b.closed = true @@ -1837,13 +2089,17 @@ func (b *requestBody) Read(p []byte) (n int, err error) { b.needsContinue = false b.conn.write100ContinueHeaders(b.stream) } - if b.pipe == nil { + if b.pipe == nil || b.sawEOF { return 0, io.EOF } n, err = b.pipe.Read(p) - if n > 0 { - b.conn.noteBodyReadFromHandler(b.stream, n) + if err == io.EOF { + b.sawEOF = true } + if b.conn == nil && inTests { + return + } + b.conn.noteBodyReadFromHandler(b.stream, n, err) return } @@ -2081,8 +2337,9 @@ func (w *responseWriter) CloseNotify() <-chan bool { if ch == nil { ch = make(chan bool, 1) rws.closeNotifierCh = ch + cw := rws.stream.cw go func() { - rws.stream.cw.Wait() // wait for close + cw.Wait() // wait for close ch <- true }() } @@ -2178,6 +2435,200 @@ func (w *responseWriter) handlerDone() { responseWriterStatePool.Put(rws) } +// Push errors. +var ( + ErrRecursivePush = errors.New("http2: recursive push not allowed") + ErrPushLimitReached = errors.New("http2: push would exceed peer's SETTINGS_MAX_CONCURRENT_STREAMS") +) + +// pushOptions is the internal version of http.PushOptions, which we +// cannot include here because it's only defined in Go 1.8 and later. +type pushOptions struct { + Method string + Header http.Header +} + +func (w *responseWriter) push(target string, opts pushOptions) error { + st := w.rws.stream + sc := st.sc + sc.serveG.checkNotOn() + + // No recursive pushes: "PUSH_PROMISE frames MUST only be sent on a peer-initiated stream." + // http://tools.ietf.org/html/rfc7540#section-6.6 + if st.isPushed() { + return ErrRecursivePush + } + + // Default options. + if opts.Method == "" { + opts.Method = "GET" + } + if opts.Header == nil { + opts.Header = http.Header{} + } + wantScheme := "http" + if w.rws.req.TLS != nil { + wantScheme = "https" + } + + // Validate the request. + u, err := url.Parse(target) + if err != nil { + return err + } + if u.Scheme == "" { + if !strings.HasPrefix(target, "/") { + return fmt.Errorf("target must be an absolute URL or an absolute path: %q", target) + } + u.Scheme = wantScheme + u.Host = w.rws.req.Host + } else { + if u.Scheme != wantScheme { + return fmt.Errorf("cannot push URL with scheme %q from request with scheme %q", u.Scheme, wantScheme) + } + if u.Host == "" { + return errors.New("URL must have a host") + } + } + for k := range opts.Header { + if strings.HasPrefix(k, ":") { + return fmt.Errorf("promised request headers cannot include pseudo header %q", k) + } + // These headers are meaningful only if the request has a body, + // but PUSH_PROMISE requests cannot have a body. + // http://tools.ietf.org/html/rfc7540#section-8.2 + // Also disallow Host, since the promised URL must be absolute. + switch strings.ToLower(k) { + case "content-length", "content-encoding", "trailer", "te", "expect", "host": + return fmt.Errorf("promised request headers cannot include %q", k) + } + } + if err := checkValidHTTP2RequestHeaders(opts.Header); err != nil { + return err + } + + // The RFC effectively limits promised requests to GET and HEAD: + // "Promised requests MUST be cacheable [GET, HEAD, or POST], and MUST be safe [GET or HEAD]" + // http://tools.ietf.org/html/rfc7540#section-8.2 + if opts.Method != "GET" && opts.Method != "HEAD" { + return fmt.Errorf("method %q must be GET or HEAD", opts.Method) + } + + msg := startPushRequest{ + parent: st, + method: opts.Method, + url: u, + header: cloneHeader(opts.Header), + done: errChanPool.Get().(chan error), + } + + select { + case <-sc.doneServing: + return errClientDisconnected + case <-st.cw: + return errStreamClosed + case sc.wantStartPushCh <- msg: + } + + select { + case <-sc.doneServing: + return errClientDisconnected + case <-st.cw: + return errStreamClosed + case err := <-msg.done: + errChanPool.Put(msg.done) + return err + } +} + +type startPushRequest struct { + parent *stream + method string + url *url.URL + header http.Header + done chan error +} + +func (sc *serverConn) startPush(msg startPushRequest) { + sc.serveG.check() + + // http://tools.ietf.org/html/rfc7540#section-6.6. + // PUSH_PROMISE frames MUST only be sent on a peer-initiated stream that + // is in either the "open" or "half-closed (remote)" state. + if msg.parent.state != stateOpen && msg.parent.state != stateHalfClosedRemote { + // responseWriter.Push checks that the stream is peer-initiaed. + msg.done <- errStreamClosed + return + } + + // http://tools.ietf.org/html/rfc7540#section-6.6. + if !sc.pushEnabled { + msg.done <- http.ErrNotSupported + return + } + + // PUSH_PROMISE frames must be sent in increasing order by stream ID, so + // we allocate an ID for the promised stream lazily, when the PUSH_PROMISE + // is written. Once the ID is allocated, we start the request handler. + allocatePromisedID := func() (uint32, error) { + sc.serveG.check() + + // Check this again, just in case. Technically, we might have received + // an updated SETTINGS by the time we got around to writing this frame. + if !sc.pushEnabled { + return 0, http.ErrNotSupported + } + // http://tools.ietf.org/html/rfc7540#section-6.5.2. + if sc.curPushedStreams+1 > sc.clientMaxStreams { + return 0, ErrPushLimitReached + } + + // http://tools.ietf.org/html/rfc7540#section-5.1.1. + // Streams initiated by the server MUST use even-numbered identifiers. + // A server that is unable to establish a new stream identifier can send a GOAWAY + // frame so that the client is forced to open a new connection for new streams. + if sc.maxPushPromiseID+2 >= 1<<31 { + sc.startGracefulShutdown() + return 0, ErrPushLimitReached + } + sc.maxPushPromiseID += 2 + promisedID := sc.maxPushPromiseID + + // http://tools.ietf.org/html/rfc7540#section-8.2. + // Strictly speaking, the new stream should start in "reserved (local)", then + // transition to "half closed (remote)" after sending the initial HEADERS, but + // we start in "half closed (remote)" for simplicity. + // See further comments at the definition of stateHalfClosedRemote. + promised := sc.newStream(promisedID, msg.parent.id, stateHalfClosedRemote) + rw, req, err := sc.newWriterAndRequestNoBody(promised, requestParam{ + method: msg.method, + scheme: msg.url.Scheme, + authority: msg.url.Host, + path: msg.url.RequestURI(), + header: cloneHeader(msg.header), // clone since handler runs concurrently with writing the PUSH_PROMISE + }) + if err != nil { + // Should not happen, since we've already validated msg.url. + panic(fmt.Sprintf("newWriterAndRequestNoBody(%+v): %v", msg.url, err)) + } + + go sc.runHandler(rw, req, sc.handler.ServeHTTP) + return promisedID, nil + } + + sc.writeFrame(FrameWriteRequest{ + write: &writePushPromise{ + streamID: msg.parent.id, + method: msg.method, + url: msg.url, + h: msg.header, + allocatePromisedID: allocatePromisedID, + }, + stream: msg.parent, + done: msg.done, + }) +} + // foreachHeaderElement splits v according to the "#rule" construction // in RFC 2616 section 2.1 and calls fn for each non-empty element. func foreachHeaderElement(v string, fn func(string)) { @@ -2205,16 +2656,16 @@ var connHeaders = []string{ "Upgrade", } -// checkValidHTTP2Request checks whether req is a valid HTTP/2 request, +// checkValidHTTP2RequestHeaders checks whether h is a valid HTTP/2 request, // per RFC 7540 Section 8.1.2.2. // The returned error is reported to users. -func checkValidHTTP2Request(req *http.Request) error { - for _, h := range connHeaders { - if _, ok := req.Header[h]; ok { - return fmt.Errorf("request header %q is not valid in HTTP/2", h) +func checkValidHTTP2RequestHeaders(h http.Header) error { + for _, k := range connHeaders { + if _, ok := h[k]; ok { + return fmt.Errorf("request header %q is not valid in HTTP/2", k) } } - te := req.Header["Te"] + te := h["Te"] if len(te) > 0 && (len(te) > 1 || (te[0] != "trailers" && te[0] != "")) { return errors.New(`request header "TE" may only be "trailers" in HTTP/2`) } @@ -2261,3 +2712,42 @@ var badTrailer = map[string]bool{ "Transfer-Encoding": true, "Www-Authenticate": true, } + +// h1ServerShutdownChan returns a channel that will be closed when the +// provided *http.Server wants to shut down. +// +// This is a somewhat hacky way to get at http1 innards. It works +// when the http2 code is bundled into the net/http package in the +// standard library. The alternatives ended up making the cmd/go tool +// depend on http Servers. This is the lightest option for now. +// This is tested via the TestServeShutdown* tests in net/http. +func h1ServerShutdownChan(hs *http.Server) <-chan struct{} { + if fn := testh1ServerShutdownChan; fn != nil { + return fn(hs) + } + var x interface{} = hs + type I interface { + getDoneChan() <-chan struct{} + } + if hs, ok := x.(I); ok { + return hs.getDoneChan() + } + return nil +} + +// optional test hook for h1ServerShutdownChan. +var testh1ServerShutdownChan func(hs *http.Server) <-chan struct{} + +// h1ServerKeepAlivesDisabled reports whether hs has its keep-alives +// disabled. See comments on h1ServerShutdownChan above for why +// the code is written this way. +func h1ServerKeepAlivesDisabled(hs *http.Server) bool { + var x interface{} = hs + type I interface { + doKeepAlives() bool + } + if hs, ok := x.(I); ok { + return !hs.doKeepAlives() + } + return false +} diff --git a/vendor/golang.org/x/net/http2/transport.go b/vendor/golang.org/x/net/http2/transport.go index fb8dd997b..0c7e859db 100644 --- a/vendor/golang.org/x/net/http2/transport.go +++ b/vendor/golang.org/x/net/http2/transport.go @@ -10,12 +10,14 @@ import ( "bufio" "bytes" "compress/gzip" + "crypto/rand" "crypto/tls" "errors" "fmt" "io" "io/ioutil" "log" + "math" "net" "net/http" "sort" @@ -25,6 +27,7 @@ import ( "time" "golang.org/x/net/http2/hpack" + "golang.org/x/net/idna" "golang.org/x/net/lex/httplex" ) @@ -148,27 +151,32 @@ type ClientConn struct { readerDone chan struct{} // closed on error readerErr error // set before readerDone is closed - mu sync.Mutex // guards following - cond *sync.Cond // hold mu; broadcast on flow/closed changes - flow flow // our conn-level flow control quota (cs.flow is per stream) - inflow flow // peer's conn-level flow control - closed bool - goAway *GoAwayFrame // if non-nil, the GoAwayFrame we received - goAwayDebug string // goAway frame's debug data, retained as a string - streams map[uint32]*clientStream // client-initiated - nextStreamID uint32 - bw *bufio.Writer - br *bufio.Reader - fr *Framer - lastActive time.Time + idleTimeout time.Duration // or 0 for never + idleTimer *time.Timer - // Settings from peer: + mu sync.Mutex // guards following + cond *sync.Cond // hold mu; broadcast on flow/closed changes + flow flow // our conn-level flow control quota (cs.flow is per stream) + inflow flow // peer's conn-level flow control + closed bool + wantSettingsAck bool // we sent a SETTINGS frame and haven't heard back + goAway *GoAwayFrame // if non-nil, the GoAwayFrame we received + goAwayDebug string // goAway frame's debug data, retained as a string + streams map[uint32]*clientStream // client-initiated + nextStreamID uint32 + pings map[[8]byte]chan struct{} // in flight ping data to notification channel + bw *bufio.Writer + br *bufio.Reader + fr *Framer + lastActive time.Time + // Settings from peer: (also guarded by mu) maxFrameSize uint32 maxConcurrentStreams uint32 initialWindowSize uint32 - hbuf bytes.Buffer // HPACK encoder writes into this - henc *hpack.Encoder - freeBuf [][]byte + + hbuf bytes.Buffer // HPACK encoder writes into this + henc *hpack.Encoder + freeBuf [][]byte wmu sync.Mutex // held while writing; acquire AFTER mu if holding both werr error // first write error that has occurred @@ -183,6 +191,7 @@ type clientStream struct { ID uint32 resc chan resAndError bufPipe pipe // buffered pipe with the flow-controlled response payload + startedWrite bool // started request body write; guarded by cc.mu requestedGzip bool on100 func() // optional code to run if get a 100 continue response @@ -191,6 +200,7 @@ type clientStream struct { bytesRemain int64 // -1 means unknown; owned by transportResponseBody.Read readErr error // sticky read error; owned by transportResponseBody.Read stopReqBody error // if non-nil, stop writing req body; guarded by cc.mu + didReset bool // whether we sent a RST_STREAM to the server; guarded by cc.mu peerReset chan struct{} // closed on peer reset resetErr error // populated before peerReset is closed @@ -218,15 +228,26 @@ func (cs *clientStream) awaitRequestCancel(req *http.Request) { } select { case <-req.Cancel: + cs.cancelStream() cs.bufPipe.CloseWithError(errRequestCanceled) - cs.cc.writeStreamReset(cs.ID, ErrCodeCancel, nil) case <-ctx.Done(): + cs.cancelStream() cs.bufPipe.CloseWithError(ctx.Err()) - cs.cc.writeStreamReset(cs.ID, ErrCodeCancel, nil) case <-cs.done: } } +func (cs *clientStream) cancelStream() { + cs.cc.mu.Lock() + didReset := cs.didReset + cs.didReset = true + cs.cc.mu.Unlock() + + if !didReset { + cs.cc.writeStreamReset(cs.ID, ErrCodeCancel, nil) + } +} + // checkResetOrDone reports any error sent in a RST_STREAM frame by the // server, or errStreamClosed if the stream is complete. func (cs *clientStream) checkResetOrDone() error { @@ -283,14 +304,22 @@ func (t *Transport) RoundTrip(req *http.Request) (*http.Response, error) { // authorityAddr returns a given authority (a host/IP, or host:port / ip:port) // and returns a host:port. The port 443 is added if needed. func authorityAddr(scheme string, authority string) (addr string) { - if _, _, err := net.SplitHostPort(authority); err == nil { - return authority + host, port, err := net.SplitHostPort(authority) + if err != nil { // authority didn't have a port + port = "443" + if scheme == "http" { + port = "80" + } + host = authority } - port := "443" - if scheme == "http" { - port = "80" + if a, err := idna.ToASCII(host); err == nil { + host = a } - return net.JoinHostPort(authority, port) + // IPv6 address literal, without a port: + if strings.HasPrefix(host, "[") && strings.HasSuffix(host, "]") { + return host + ":" + port + } + return net.JoinHostPort(host, port) } // RoundTripOpt is like RoundTrip, but takes options. @@ -308,8 +337,10 @@ func (t *Transport) RoundTripOpt(req *http.Request, opt RoundTripOpt) (*http.Res } traceGotConn(req, cc) res, err := cc.RoundTrip(req) - if shouldRetryRequest(req, err) { - continue + if err != nil { + if req, err = shouldRetryRequest(req, err); err == nil { + continue + } } if err != nil { t.vlogf("RoundTrip failure: %v", err) @@ -331,15 +362,44 @@ func (t *Transport) CloseIdleConnections() { var ( errClientConnClosed = errors.New("http2: client conn is closed") errClientConnUnusable = errors.New("http2: client conn not usable") + + errClientConnGotGoAway = errors.New("http2: Transport received Server's graceful shutdown GOAWAY") + errClientConnGotGoAwayAfterSomeReqBody = errors.New("http2: Transport received Server's graceful shutdown GOAWAY; some request body already written") ) -func shouldRetryRequest(req *http.Request, err error) bool { - // TODO: retry GET requests (no bodies) more aggressively, if shutdown - // before response. - return err == errClientConnUnusable +// shouldRetryRequest is called by RoundTrip when a request fails to get +// response headers. It is always called with a non-nil error. +// It returns either a request to retry (either the same request, or a +// modified clone), or an error if the request can't be replayed. +func shouldRetryRequest(req *http.Request, err error) (*http.Request, error) { + switch err { + default: + return nil, err + case errClientConnUnusable, errClientConnGotGoAway: + return req, nil + case errClientConnGotGoAwayAfterSomeReqBody: + // If the Body is nil (or http.NoBody), it's safe to reuse + // this request and its Body. + if req.Body == nil || reqBodyIsNoBody(req.Body) { + return req, nil + } + // Otherwise we depend on the Request having its GetBody + // func defined. + getBody := reqGetBody(req) // Go 1.8: getBody = req.GetBody + if getBody == nil { + return nil, errors.New("http2: Transport: peer server initiated graceful shutdown after some of Request.Body was written; define Request.GetBody to avoid this error") + } + body, err := getBody() + if err != nil { + return nil, err + } + newReq := *req + newReq.Body = body + return &newReq, nil + } } -func (t *Transport) dialClientConn(addr string) (*ClientConn, error) { +func (t *Transport) dialClientConn(addr string, singleUse bool) (*ClientConn, error) { host, _, err := net.SplitHostPort(addr) if err != nil { return nil, err @@ -348,13 +408,13 @@ func (t *Transport) dialClientConn(addr string) (*ClientConn, error) { if err != nil { return nil, err } - return t.NewClientConn(tconn) + return t.newClientConn(tconn, singleUse) } func (t *Transport) newTLSConfig(host string) *tls.Config { cfg := new(tls.Config) if t.TLSClientConfig != nil { - *cfg = *t.TLSClientConfig + *cfg = *cloneTLSConfig(t.TLSClientConfig) } if !strSliceContains(cfg.NextProtos, NextProtoTLS) { cfg.NextProtos = append([]string{NextProtoTLS}, cfg.NextProtos...) @@ -409,14 +469,10 @@ func (t *Transport) expectContinueTimeout() time.Duration { } func (t *Transport) NewClientConn(c net.Conn) (*ClientConn, error) { - if VerboseLogs { - t.vlogf("http2: Transport creating client conn to %v", c.RemoteAddr()) - } - if _, err := c.Write(clientPreface); err != nil { - t.vlogf("client preface write error: %v", err) - return nil, err - } + return t.newClientConn(c, false) +} +func (t *Transport) newClientConn(c net.Conn, singleUse bool) (*ClientConn, error) { cc := &ClientConn{ t: t, tconn: c, @@ -426,7 +482,18 @@ func (t *Transport) NewClientConn(c net.Conn) (*ClientConn, error) { initialWindowSize: 65535, // spec default maxConcurrentStreams: 1000, // "infinite", per spec. 1000 seems good enough. streams: make(map[uint32]*clientStream), + singleUse: singleUse, + wantSettingsAck: true, + pings: make(map[[8]byte]chan struct{}), } + if d := t.idleConnTimeout(); d != 0 { + cc.idleTimeout = d + cc.idleTimer = time.AfterFunc(d, cc.onIdleTimeout) + } + if VerboseLogs { + t.vlogf("http2: Transport creating client conn %p to %v", cc, c.RemoteAddr()) + } + cc.cond = sync.NewCond(&cc.mu) cc.flow.add(int32(initialWindowSize)) @@ -454,6 +521,8 @@ func (t *Transport) NewClientConn(c net.Conn) (*ClientConn, error) { if max := t.maxHeaderListSize(); max != 0 { initialSettings = append(initialSettings, Setting{ID: SettingMaxHeaderListSize, Val: max}) } + + cc.bw.Write(clientPreface) cc.fr.WriteSettings(initialSettings...) cc.fr.WriteWindowUpdate(0, transportDefaultConnFlow) cc.inflow.add(transportDefaultConnFlow + initialWindowSize) @@ -462,33 +531,6 @@ func (t *Transport) NewClientConn(c net.Conn) (*ClientConn, error) { return nil, cc.werr } - // Read the obligatory SETTINGS frame - f, err := cc.fr.ReadFrame() - if err != nil { - return nil, err - } - sf, ok := f.(*SettingsFrame) - if !ok { - return nil, fmt.Errorf("expected settings frame, got: %T", f) - } - cc.fr.WriteSettingsAck() - cc.bw.Flush() - - sf.ForeachSetting(func(s Setting) error { - switch s.ID { - case SettingMaxFrameSize: - cc.maxFrameSize = s.Val - case SettingMaxConcurrentStreams: - cc.maxConcurrentStreams = s.Val - case SettingInitialWindowSize: - cc.initialWindowSize = s.Val - default: - // TODO(bradfitz): handle more; at least SETTINGS_HEADER_TABLE_SIZE? - t.vlogf("Unhandled Setting: %v", s) - } - return nil - }) - go cc.readLoop() return cc, nil } @@ -507,6 +549,15 @@ func (cc *ClientConn) setGoAway(f *GoAwayFrame) { if old != nil && old.ErrCode != ErrCodeNo { cc.goAway.ErrCode = old.ErrCode } + last := f.LastStreamID + for streamID, cs := range cc.streams { + if streamID > last { + select { + case cs.resc <- resAndError{err: errClientConnGotGoAway}: + default: + } + } + } } func (cc *ClientConn) CanTakeNewRequest() bool { @@ -521,7 +572,17 @@ func (cc *ClientConn) canTakeNewRequestLocked() bool { } return cc.goAway == nil && !cc.closed && int64(len(cc.streams)+1) < int64(cc.maxConcurrentStreams) && - cc.nextStreamID < 2147483647 + cc.nextStreamID < math.MaxInt32 +} + +// onIdleTimeout is called from a time.AfterFunc goroutine. It will +// only be called when we're idle, but because we're coming from a new +// goroutine, there could be a new request coming in at the same time, +// so this simply calls the synchronized closeIfIdle to shut down this +// connection. The timer could just call closeIfIdle, but this is more +// clear. +func (cc *ClientConn) onIdleTimeout() { + cc.closeIfIdle() } func (cc *ClientConn) closeIfIdle() { @@ -531,9 +592,13 @@ func (cc *ClientConn) closeIfIdle() { return } cc.closed = true + nextID := cc.nextStreamID // TODO: do clients send GOAWAY too? maybe? Just Close: cc.mu.Unlock() + if VerboseLogs { + cc.vlogf("http2: Transport closing idle conn %p (forSingleUse=%v, maxStream=%v)", cc, cc.singleUse, nextID-2) + } cc.tconn.Close() } @@ -593,8 +658,6 @@ func commaSeparatedTrailers(req *http.Request) (string, error) { } if len(keys) > 0 { sort.Strings(keys) - // TODO: could do better allocation-wise here, but trailers are rare, - // so being lazy for now. return strings.Join(keys, ","), nil } return "", nil @@ -616,48 +679,37 @@ func (cc *ClientConn) responseHeaderTimeout() time.Duration { // Certain headers are special-cased as okay but not transmitted later. func checkConnHeaders(req *http.Request) error { if v := req.Header.Get("Upgrade"); v != "" { - return errors.New("http2: invalid Upgrade request header") + return fmt.Errorf("http2: invalid Upgrade request header: %q", req.Header["Upgrade"]) } - if v := req.Header.Get("Transfer-Encoding"); (v != "" && v != "chunked") || len(req.Header["Transfer-Encoding"]) > 1 { - return errors.New("http2: invalid Transfer-Encoding request header") + if vv := req.Header["Transfer-Encoding"]; len(vv) > 0 && (len(vv) > 1 || vv[0] != "" && vv[0] != "chunked") { + return fmt.Errorf("http2: invalid Transfer-Encoding request header: %q", vv) } - if v := req.Header.Get("Connection"); (v != "" && v != "close" && v != "keep-alive") || len(req.Header["Connection"]) > 1 { - return errors.New("http2: invalid Connection request header") + if vv := req.Header["Connection"]; len(vv) > 0 && (len(vv) > 1 || vv[0] != "" && vv[0] != "close" && vv[0] != "keep-alive") { + return fmt.Errorf("http2: invalid Connection request header: %q", vv) } return nil } -func bodyAndLength(req *http.Request) (body io.Reader, contentLen int64) { - body = req.Body - if body == nil { - return nil, 0 +// actualContentLength returns a sanitized version of +// req.ContentLength, where 0 actually means zero (not unknown) and -1 +// means unknown. +func actualContentLength(req *http.Request) int64 { + if req.Body == nil { + return 0 } if req.ContentLength != 0 { - return req.Body, req.ContentLength + return req.ContentLength } - - // We have a body but a zero content length. Test to see if - // it's actually zero or just unset. - var buf [1]byte - n, rerr := io.ReadFull(body, buf[:]) - if rerr != nil && rerr != io.EOF { - return errorReader{rerr}, -1 - } - if n == 1 { - // Oh, guess there is data in this Body Reader after all. - // The ContentLength field just wasn't set. - // Stich the Body back together again, re-attaching our - // consumed byte. - return io.MultiReader(bytes.NewReader(buf[:]), body), -1 - } - // Body is actually zero bytes. - return nil, 0 + return -1 } func (cc *ClientConn) RoundTrip(req *http.Request) (*http.Response, error) { if err := checkConnHeaders(req); err != nil { return nil, err } + if cc.idleTimer != nil { + cc.idleTimer.Stop() + } trailers, err := commaSeparatedTrailers(req) if err != nil { @@ -665,9 +717,6 @@ func (cc *ClientConn) RoundTrip(req *http.Request) (*http.Response, error) { } hasTrailers := trailers != "" - body, contentLen := bodyAndLength(req) - hasBody := body != nil - cc.mu.Lock() cc.lastActive = time.Now() if cc.closed || !cc.canTakeNewRequestLocked() { @@ -675,6 +724,10 @@ func (cc *ClientConn) RoundTrip(req *http.Request) (*http.Response, error) { return nil, errClientConnUnusable } + body := req.Body + hasBody := body != nil + contentLen := actualContentLength(req) + // TODO(bradfitz): this is a copy of the logic in net/http. Unify somewhere? var requestedGzip bool if !cc.t.disableCompression() && @@ -747,30 +800,41 @@ func (cc *ClientConn) RoundTrip(req *http.Request) (*http.Response, error) { bodyWritten := false ctx := reqContext(req) + handleReadLoopResponse := func(re resAndError) (*http.Response, error) { + res := re.res + if re.err != nil || res.StatusCode > 299 { + // On error or status code 3xx, 4xx, 5xx, etc abort any + // ongoing write, assuming that the server doesn't care + // about our request body. If the server replied with 1xx or + // 2xx, however, then assume the server DOES potentially + // want our body (e.g. full-duplex streaming: + // golang.org/issue/13444). If it turns out the server + // doesn't, they'll RST_STREAM us soon enough. This is a + // heuristic to avoid adding knobs to Transport. Hopefully + // we can keep it. + bodyWriter.cancel() + cs.abortRequestBodyWrite(errStopReqBodyWrite) + } + if re.err != nil { + if re.err == errClientConnGotGoAway { + cc.mu.Lock() + if cs.startedWrite { + re.err = errClientConnGotGoAwayAfterSomeReqBody + } + cc.mu.Unlock() + } + cc.forgetStreamID(cs.ID) + return nil, re.err + } + res.Request = req + res.TLS = cc.tlsState + return res, nil + } + for { select { case re := <-readLoopResCh: - res := re.res - if re.err != nil || res.StatusCode > 299 { - // On error or status code 3xx, 4xx, 5xx, etc abort any - // ongoing write, assuming that the server doesn't care - // about our request body. If the server replied with 1xx or - // 2xx, however, then assume the server DOES potentially - // want our body (e.g. full-duplex streaming: - // golang.org/issue/13444). If it turns out the server - // doesn't, they'll RST_STREAM us soon enough. This is a - // heuristic to avoid adding knobs to Transport. Hopefully - // we can keep it. - bodyWriter.cancel() - cs.abortRequestBodyWrite(errStopReqBodyWrite) - } - if re.err != nil { - cc.forgetStreamID(cs.ID) - return nil, re.err - } - res.Request = req - res.TLS = cc.tlsState - return res, nil + return handleReadLoopResponse(re) case <-respHeaderTimer: cc.forgetStreamID(cs.ID) if !hasBody || bodyWritten { @@ -804,6 +868,12 @@ func (cc *ClientConn) RoundTrip(req *http.Request) (*http.Response, error) { // forgetStreamID. return nil, cs.resetErr case err := <-bodyWriter.resc: + // Prefer the read loop's response, if available. Issue 16102. + select { + case re := <-readLoopResCh: + return handleReadLoopResponse(re) + default: + } if err != nil { return nil, err } @@ -908,10 +978,11 @@ func (cs *clientStream) writeRequestBody(body io.Reader, bodyCloser io.Closer) ( err = cc.fr.WriteData(cs.ID, sentEnd, data) if err == nil { // TODO(bradfitz): this flush is for latency, not bandwidth. - // Most requests won't need this. Make this opt-in or opt-out? - // Use some heuristic on the body type? Nagel-like timers? - // Based on 'n'? Only last chunk of this for loop, unless flow control - // tokens are low? For now, always: + // Most requests won't need this. Make this opt-in or + // opt-out? Use some heuristic on the body type? Nagel-like + // timers? Based on 'n'? Only last chunk of this for loop, + // unless flow control tokens are low? For now, always. + // If we change this, see comment below. err = cc.bw.Flush() } cc.wmu.Unlock() @@ -921,28 +992,33 @@ func (cs *clientStream) writeRequestBody(body io.Reader, bodyCloser io.Closer) ( } } - cc.wmu.Lock() - if !sentEnd { - var trls []byte - if hasTrailers { - cc.mu.Lock() - trls = cc.encodeTrailers(req) - cc.mu.Unlock() - } + if sentEnd { + // Already sent END_STREAM (which implies we have no + // trailers) and flushed, because currently all + // WriteData frames above get a flush. So we're done. + return nil + } - // Avoid forgetting to send an END_STREAM if the encoded - // trailers are 0 bytes. Both results produce and END_STREAM. - if len(trls) > 0 { - err = cc.writeHeaders(cs.ID, true, trls) - } else { - err = cc.fr.WriteData(cs.ID, true, nil) - } + var trls []byte + if hasTrailers { + cc.mu.Lock() + defer cc.mu.Unlock() + trls = cc.encodeTrailers(req) + } + + cc.wmu.Lock() + defer cc.wmu.Unlock() + + // Two ways to send END_STREAM: either with trailers, or + // with an empty DATA frame. + if len(trls) > 0 { + err = cc.writeHeaders(cs.ID, true, trls) + } else { + err = cc.fr.WriteData(cs.ID, true, nil) } if ferr := cc.bw.Flush(); ferr != nil && err == nil { err = ferr } - cc.wmu.Unlock() - return err } @@ -995,6 +1071,26 @@ func (cc *ClientConn) encodeHeaders(req *http.Request, addGzipHeader bool, trail if host == "" { host = req.URL.Host } + host, err := httplex.PunycodeHostPort(host) + if err != nil { + return nil, err + } + + var path string + if req.Method != "CONNECT" { + path = req.URL.RequestURI() + if !validPseudoPath(path) { + orig := path + path = strings.TrimPrefix(path, req.URL.Scheme+"://"+host) + if !validPseudoPath(path) { + if req.URL.Opaque != "" { + return nil, fmt.Errorf("invalid request :path %q from URL.Opaque = %q", orig, req.URL.Opaque) + } else { + return nil, fmt.Errorf("invalid request :path %q", orig) + } + } + } + } // Check for any invalid headers and return an error before we // potentially pollute our hpack state. (We want to be able to @@ -1018,8 +1114,8 @@ func (cc *ClientConn) encodeHeaders(req *http.Request, addGzipHeader bool, trail cc.writeHeader(":authority", host) cc.writeHeader(":method", req.Method) if req.Method != "CONNECT" { - cc.writeHeader(":path", req.URL.RequestURI()) - cc.writeHeader(":scheme", "https") + cc.writeHeader(":path", path) + cc.writeHeader(":scheme", req.URL.Scheme) } if trailers != "" { cc.writeHeader("trailer", trailers) @@ -1146,6 +1242,9 @@ func (cc *ClientConn) streamByID(id uint32, andRemove bool) *clientStream { if andRemove && cs != nil && !cc.closed { cc.lastActive = time.Now() delete(cc.streams, id) + if len(cc.streams) == 0 && cc.idleTimer != nil { + cc.idleTimer.Reset(cc.idleTimeout) + } close(cs.done) cc.cond.Broadcast() // wake up checkResetOrDone via clientStream.awaitFlowControl } @@ -1188,27 +1287,37 @@ func (e GoAwayError) Error() string { e.LastStreamID, e.ErrCode, e.DebugData) } +func isEOFOrNetReadError(err error) bool { + if err == io.EOF { + return true + } + ne, ok := err.(*net.OpError) + return ok && ne.Op == "read" +} + func (rl *clientConnReadLoop) cleanup() { cc := rl.cc defer cc.tconn.Close() defer cc.t.connPool().MarkDead(cc) defer close(cc.readerDone) + if cc.idleTimer != nil { + cc.idleTimer.Stop() + } + // Close any response bodies if the server closes prematurely. // TODO: also do this if we've written the headers but not // gotten a response yet. err := cc.readerErr cc.mu.Lock() - if err == io.EOF { - if cc.goAway != nil { - err = GoAwayError{ - LastStreamID: cc.goAway.LastStreamID, - ErrCode: cc.goAway.ErrCode, - DebugData: cc.goAwayDebug, - } - } else { - err = io.ErrUnexpectedEOF + if cc.goAway != nil && isEOFOrNetReadError(err) { + err = GoAwayError{ + LastStreamID: cc.goAway.LastStreamID, + ErrCode: cc.goAway.ErrCode, + DebugData: cc.goAwayDebug, } + } else if err == io.EOF { + err = io.ErrUnexpectedEOF } for _, cs := range rl.activeRes { cs.bufPipe.CloseWithError(err) @@ -1228,15 +1337,20 @@ func (rl *clientConnReadLoop) cleanup() { func (rl *clientConnReadLoop) run() error { cc := rl.cc rl.closeWhenIdle = cc.t.disableKeepAlives() || cc.singleUse - gotReply := false // ever saw a reply + gotReply := false // ever saw a HEADERS reply + gotSettings := false for { f, err := cc.fr.ReadFrame() if err != nil { - cc.vlogf("Transport readFrame error: (%T) %v", err, err) + cc.vlogf("http2: Transport readFrame error on conn %p: (%T) %v", cc, err, err) } if se, ok := err.(StreamError); ok { if cs := cc.streamByID(se.StreamID, true /*ended; remove it*/); cs != nil { - rl.endStreamError(cs, cc.fr.errDetail) + cs.cc.writeStreamReset(cs.ID, se.Code, err) + if se.Cause == nil { + se.Cause = cc.fr.errDetail + } + rl.endStreamError(cs, se) } continue } else if err != nil { @@ -1245,6 +1359,13 @@ func (rl *clientConnReadLoop) run() error { if VerboseLogs { cc.vlogf("http2: Transport received %s", summarizeFrame(f)) } + if !gotSettings { + if _, ok := f.(*SettingsFrame); !ok { + cc.logf("protocol error: received %T before a SETTINGS frame", f) + return ConnectionError(ErrCodeProtocol) + } + gotSettings = true + } maybeIdle := false // whether frame might transition us to idle switch f := f.(type) { @@ -1273,6 +1394,9 @@ func (rl *clientConnReadLoop) run() error { cc.logf("Transport: unhandled response frame type %T", f) } if err != nil { + if VerboseLogs { + cc.vlogf("http2: Transport conn %p received error from processing frame %v: %v", cc, summarizeFrame(f), err) + } return err } if rl.closeWhenIdle && gotReply && maybeIdle && len(rl.activeRes) == 0 { @@ -1522,10 +1646,27 @@ var errClosedResponseBody = errors.New("http2: response body closed") func (b transportResponseBody) Close() error { cs := b.cs - if cs.bufPipe.Err() != io.EOF { - // TODO: write test for this - cs.cc.writeStreamReset(cs.ID, ErrCodeCancel, nil) + cc := cs.cc + + serverSentStreamEnd := cs.bufPipe.Err() == io.EOF + unread := cs.bufPipe.Len() + + if unread > 0 || !serverSentStreamEnd { + cc.mu.Lock() + cc.wmu.Lock() + if !serverSentStreamEnd { + cc.fr.WriteRSTStream(cs.ID, ErrCodeCancel) + } + // Return connection-level flow control. + if unread > 0 { + cc.inflow.add(int32(unread)) + cc.fr.WriteWindowUpdate(0, uint32(unread)) + } + cc.bw.Flush() + cc.wmu.Unlock() + cc.mu.Unlock() } + cs.bufPipe.BreakWithError(errClosedResponseBody) return nil } @@ -1533,6 +1674,7 @@ func (b transportResponseBody) Close() error { func (rl *clientConnReadLoop) processData(f *DataFrame) error { cc := rl.cc cs := cc.streamByID(f.StreamID, f.StreamEnded()) + data := f.Data() if cs == nil { cc.mu.Lock() neverSent := cc.nextStreamID @@ -1546,10 +1688,22 @@ func (rl *clientConnReadLoop) processData(f *DataFrame) error { // TODO: be stricter here? only silently ignore things which // we canceled, but not things which were closed normally // by the peer? Tough without accumulating too much state. + + // But at least return their flow control: + if f.Length > 0 { + cc.mu.Lock() + cc.inflow.add(int32(f.Length)) + cc.mu.Unlock() + + cc.wmu.Lock() + cc.fr.WriteWindowUpdate(0, uint32(f.Length)) + cc.bw.Flush() + cc.wmu.Unlock() + } return nil } - if data := f.Data(); len(data) > 0 { - if cs.bufPipe.b == nil { + if f.Length > 0 { + if len(data) > 0 && cs.bufPipe.b == nil { // Data frame after it's already closed? cc.logf("http2: Transport received DATA frame for closed stream; closing connection") return ConnectionError(ErrCodeProtocol) @@ -1557,17 +1711,31 @@ func (rl *clientConnReadLoop) processData(f *DataFrame) error { // Check connection-level flow control. cc.mu.Lock() - if cs.inflow.available() >= int32(len(data)) { - cs.inflow.take(int32(len(data))) + if cs.inflow.available() >= int32(f.Length) { + cs.inflow.take(int32(f.Length)) } else { cc.mu.Unlock() return ConnectionError(ErrCodeFlowControl) } + // Return any padded flow control now, since we won't + // refund it later on body reads. + if pad := int32(f.Length) - int32(len(data)); pad > 0 { + cs.inflow.add(pad) + cc.inflow.add(pad) + cc.wmu.Lock() + cc.fr.WriteWindowUpdate(0, uint32(pad)) + cc.fr.WriteWindowUpdate(cs.ID, uint32(pad)) + cc.bw.Flush() + cc.wmu.Unlock() + } + didReset := cs.didReset cc.mu.Unlock() - if _, err := cs.bufPipe.Write(data); err != nil { - rl.endStreamError(cs, err) - return err + if len(data) > 0 && !didReset { + if _, err := cs.bufPipe.Write(data); err != nil { + rl.endStreamError(cs, err) + return err + } } } @@ -1593,9 +1761,14 @@ func (rl *clientConnReadLoop) endStreamError(cs *clientStream, err error) { } cs.bufPipe.closeWithErrorAndCode(err, code) delete(rl.activeRes, cs.ID) - if cs.req.Close || cs.req.Header.Get("Connection") == "close" { + if isConnectionCloseRequest(cs.req) { rl.closeWhenIdle = true } + + select { + case cs.resc <- resAndError{err: err}: + default: + } } func (cs *clientStream) copyTrailers() { @@ -1623,18 +1796,39 @@ func (rl *clientConnReadLoop) processSettings(f *SettingsFrame) error { cc := rl.cc cc.mu.Lock() defer cc.mu.Unlock() - return f.ForeachSetting(func(s Setting) error { + + if f.IsAck() { + if cc.wantSettingsAck { + cc.wantSettingsAck = false + return nil + } + return ConnectionError(ErrCodeProtocol) + } + + err := f.ForeachSetting(func(s Setting) error { switch s.ID { case SettingMaxFrameSize: cc.maxFrameSize = s.Val case SettingMaxConcurrentStreams: cc.maxConcurrentStreams = s.Val case SettingInitialWindowSize: - // TODO: error if this is too large. + // Values above the maximum flow-control + // window size of 2^31-1 MUST be treated as a + // connection error (Section 5.4.1) of type + // FLOW_CONTROL_ERROR. + if s.Val > math.MaxInt32 { + return ConnectionError(ErrCodeFlowControl) + } - // TODO: adjust flow control of still-open + // Adjust flow control of currently-open // frames by the difference of the old initial // window size and this one. + delta := int32(s.Val) - int32(cc.initialWindowSize) + for _, cs := range cc.streams { + cs.flow.add(delta) + } + cc.cond.Broadcast() + cc.initialWindowSize = s.Val default: // TODO(bradfitz): handle more settings? SETTINGS_HEADER_TABLE_SIZE probably. @@ -1642,6 +1836,16 @@ func (rl *clientConnReadLoop) processSettings(f *SettingsFrame) error { } return nil }) + if err != nil { + return err + } + + cc.wmu.Lock() + defer cc.wmu.Unlock() + + cc.fr.WriteSettingsAck() + cc.bw.Flush() + return cc.werr } func (rl *clientConnReadLoop) processWindowUpdate(f *WindowUpdateFrame) error { @@ -1678,7 +1882,7 @@ func (rl *clientConnReadLoop) processResetStream(f *RSTStreamFrame) error { // which closes this, so there // isn't a race. default: - err := StreamError{cs.ID, f.ErrCode} + err := streamError(cs.ID, f.ErrCode) cs.resetErr = err close(cs.peerReset) cs.bufPipe.CloseWithError(err) @@ -1688,10 +1892,56 @@ func (rl *clientConnReadLoop) processResetStream(f *RSTStreamFrame) error { return nil } +// Ping sends a PING frame to the server and waits for the ack. +// Public implementation is in go17.go and not_go17.go +func (cc *ClientConn) ping(ctx contextContext) error { + c := make(chan struct{}) + // Generate a random payload + var p [8]byte + for { + if _, err := rand.Read(p[:]); err != nil { + return err + } + cc.mu.Lock() + // check for dup before insert + if _, found := cc.pings[p]; !found { + cc.pings[p] = c + cc.mu.Unlock() + break + } + cc.mu.Unlock() + } + cc.wmu.Lock() + if err := cc.fr.WritePing(false, p); err != nil { + cc.wmu.Unlock() + return err + } + if err := cc.bw.Flush(); err != nil { + cc.wmu.Unlock() + return err + } + cc.wmu.Unlock() + select { + case <-c: + return nil + case <-ctx.Done(): + return ctx.Err() + case <-cc.readerDone: + // connection closed + return cc.readerErr + } +} + func (rl *clientConnReadLoop) processPing(f *PingFrame) error { if f.IsAck() { - // 6.7 PING: " An endpoint MUST NOT respond to PING frames - // containing this flag." + cc := rl.cc + cc.mu.Lock() + defer cc.mu.Unlock() + // If ack, notify listener if any + if c, ok := cc.pings[f.Data]; ok { + close(c) + delete(cc.pings, f.Data) + } return nil } cc := rl.cc @@ -1715,8 +1965,10 @@ func (rl *clientConnReadLoop) processPushPromise(f *PushPromiseFrame) error { } func (cc *ClientConn) writeStreamReset(streamID uint32, code ErrCode, err error) { - // TODO: do something with err? send it as a debug frame to the peer? - // But that's only in GOAWAY. Invent a new frame type? Is there one already? + // TODO: map err to more interesting error codes, once the + // HTTP community comes up with some. But currently for + // RST_STREAM there's no equivalent to GOAWAY frame's debug + // data, and the error codes are all pretty vague ("cancel"). cc.wmu.Lock() cc.fr.WriteRSTStream(streamID, code) cc.bw.Flush() @@ -1811,6 +2063,9 @@ func (t *Transport) getBodyWriterState(cs *clientStream, body io.Reader) (s body resc := make(chan error, 1) s.resc = resc s.fn = func() { + cs.cc.mu.Lock() + cs.startedWrite = true + cs.cc.mu.Unlock() resc <- cs.writeRequestBody(body, cs.req.Body) } s.delay = t.expectContinueTimeout() @@ -1866,3 +2121,9 @@ func (s bodyWriterState) scheduleBodyWrite() { s.timer.Reset(s.delay) } } + +// isConnectionCloseRequest reports whether req should use its own +// connection for a single request and then close the connection. +func isConnectionCloseRequest(req *http.Request) bool { + return req.Close || httplex.HeaderValuesContainsToken(req.Header["Connection"], "close") +} diff --git a/vendor/golang.org/x/net/http2/write.go b/vendor/golang.org/x/net/http2/write.go index 27ef0dd4d..6b0dfae31 100644 --- a/vendor/golang.org/x/net/http2/write.go +++ b/vendor/golang.org/x/net/http2/write.go @@ -9,6 +9,7 @@ import ( "fmt" "log" "net/http" + "net/url" "time" "golang.org/x/net/http2/hpack" @@ -18,6 +19,11 @@ import ( // writeFramer is implemented by any type that is used to write frames. type writeFramer interface { writeFrame(writeContext) error + + // staysWithinBuffer reports whether this writer promises that + // it will only write less than or equal to size bytes, and it + // won't Flush the write context. + staysWithinBuffer(size int) bool } // writeContext is the interface needed by the various frame writer @@ -39,9 +45,10 @@ type writeContext interface { HeaderEncoder() (*hpack.Encoder, *bytes.Buffer) } -// endsStream reports whether the given frame writer w will locally -// close the stream. -func endsStream(w writeFramer) bool { +// writeEndsStream reports whether w writes a frame that will transition +// the stream to a half-closed local state. This returns false for RST_STREAM, +// which closes the entire stream (not just the local half). +func writeEndsStream(w writeFramer) bool { switch v := w.(type) { case *writeData: return v.endStream @@ -51,7 +58,7 @@ func endsStream(w writeFramer) bool { // This can only happen if the caller reuses w after it's // been intentionally nil'ed out to prevent use. Keep this // here to catch future refactoring breaking it. - panic("endsStream called on nil writeFramer") + panic("writeEndsStream called on nil writeFramer") } return false } @@ -62,8 +69,16 @@ func (flushFrameWriter) writeFrame(ctx writeContext) error { return ctx.Flush() } +func (flushFrameWriter) staysWithinBuffer(max int) bool { return false } + type writeSettings []Setting +func (s writeSettings) staysWithinBuffer(max int) bool { + const settingSize = 6 // uint16 + uint32 + return frameHeaderLen+settingSize*len(s) <= max + +} + func (s writeSettings) writeFrame(ctx writeContext) error { return ctx.Framer().WriteSettings([]Setting(s)...) } @@ -83,6 +98,8 @@ func (p *writeGoAway) writeFrame(ctx writeContext) error { return err } +func (*writeGoAway) staysWithinBuffer(max int) bool { return false } // flushes + type writeData struct { streamID uint32 p []byte @@ -97,6 +114,10 @@ func (w *writeData) writeFrame(ctx writeContext) error { return ctx.Framer().WriteData(w.streamID, w.endStream, w.p) } +func (w *writeData) staysWithinBuffer(max int) bool { + return frameHeaderLen+len(w.p) <= max +} + // handlerPanicRST is the message sent from handler goroutines when // the handler panics. type handlerPanicRST struct { @@ -107,22 +128,57 @@ func (hp handlerPanicRST) writeFrame(ctx writeContext) error { return ctx.Framer().WriteRSTStream(hp.StreamID, ErrCodeInternal) } +func (hp handlerPanicRST) staysWithinBuffer(max int) bool { return frameHeaderLen+4 <= max } + func (se StreamError) writeFrame(ctx writeContext) error { return ctx.Framer().WriteRSTStream(se.StreamID, se.Code) } +func (se StreamError) staysWithinBuffer(max int) bool { return frameHeaderLen+4 <= max } + type writePingAck struct{ pf *PingFrame } func (w writePingAck) writeFrame(ctx writeContext) error { return ctx.Framer().WritePing(true, w.pf.Data) } +func (w writePingAck) staysWithinBuffer(max int) bool { return frameHeaderLen+len(w.pf.Data) <= max } + type writeSettingsAck struct{} func (writeSettingsAck) writeFrame(ctx writeContext) error { return ctx.Framer().WriteSettingsAck() } +func (writeSettingsAck) staysWithinBuffer(max int) bool { return frameHeaderLen <= max } + +// splitHeaderBlock splits headerBlock into fragments so that each fragment fits +// in a single frame, then calls fn for each fragment. firstFrag/lastFrag are true +// for the first/last fragment, respectively. +func splitHeaderBlock(ctx writeContext, headerBlock []byte, fn func(ctx writeContext, frag []byte, firstFrag, lastFrag bool) error) error { + // For now we're lazy and just pick the minimum MAX_FRAME_SIZE + // that all peers must support (16KB). Later we could care + // more and send larger frames if the peer advertised it, but + // there's little point. Most headers are small anyway (so we + // generally won't have CONTINUATION frames), and extra frames + // only waste 9 bytes anyway. + const maxFrameSize = 16384 + + first := true + for len(headerBlock) > 0 { + frag := headerBlock + if len(frag) > maxFrameSize { + frag = frag[:maxFrameSize] + } + headerBlock = headerBlock[len(frag):] + if err := fn(ctx, frag, first, len(headerBlock) == 0); err != nil { + return err + } + first = false + } + return nil +} + // writeResHeaders is a request to write a HEADERS and 0+ CONTINUATION frames // for HTTP response headers or trailers from a server handler. type writeResHeaders struct { @@ -144,6 +200,17 @@ func encKV(enc *hpack.Encoder, k, v string) { enc.WriteField(hpack.HeaderField{Name: k, Value: v}) } +func (w *writeResHeaders) staysWithinBuffer(max int) bool { + // TODO: this is a common one. It'd be nice to return true + // here and get into the fast path if we could be clever and + // calculate the size fast enough, or at least a conservative + // uppper bound that usually fires. (Maybe if w.h and + // w.trailers are nil, so we don't need to enumerate it.) + // Otherwise I'm afraid that just calculating the length to + // answer this question would be slower than the ~2µs benefit. + return false +} + func (w *writeResHeaders) writeFrame(ctx writeContext) error { enc, buf := ctx.HeaderEncoder() buf.Reset() @@ -169,39 +236,69 @@ func (w *writeResHeaders) writeFrame(ctx writeContext) error { panic("unexpected empty hpack") } - // For now we're lazy and just pick the minimum MAX_FRAME_SIZE - // that all peers must support (16KB). Later we could care - // more and send larger frames if the peer advertised it, but - // there's little point. Most headers are small anyway (so we - // generally won't have CONTINUATION frames), and extra frames - // only waste 9 bytes anyway. - const maxFrameSize = 16384 + return splitHeaderBlock(ctx, headerBlock, w.writeHeaderBlock) +} - first := true - for len(headerBlock) > 0 { - frag := headerBlock - if len(frag) > maxFrameSize { - frag = frag[:maxFrameSize] - } - headerBlock = headerBlock[len(frag):] - endHeaders := len(headerBlock) == 0 - var err error - if first { - first = false - err = ctx.Framer().WriteHeaders(HeadersFrameParam{ - StreamID: w.streamID, - BlockFragment: frag, - EndStream: w.endStream, - EndHeaders: endHeaders, - }) - } else { - err = ctx.Framer().WriteContinuation(w.streamID, endHeaders, frag) - } - if err != nil { - return err - } +func (w *writeResHeaders) writeHeaderBlock(ctx writeContext, frag []byte, firstFrag, lastFrag bool) error { + if firstFrag { + return ctx.Framer().WriteHeaders(HeadersFrameParam{ + StreamID: w.streamID, + BlockFragment: frag, + EndStream: w.endStream, + EndHeaders: lastFrag, + }) + } else { + return ctx.Framer().WriteContinuation(w.streamID, lastFrag, frag) + } +} + +// writePushPromise is a request to write a PUSH_PROMISE and 0+ CONTINUATION frames. +type writePushPromise struct { + streamID uint32 // pusher stream + method string // for :method + url *url.URL // for :scheme, :authority, :path + h http.Header + + // Creates an ID for a pushed stream. This runs on serveG just before + // the frame is written. The returned ID is copied to promisedID. + allocatePromisedID func() (uint32, error) + promisedID uint32 +} + +func (w *writePushPromise) staysWithinBuffer(max int) bool { + // TODO: see writeResHeaders.staysWithinBuffer + return false +} + +func (w *writePushPromise) writeFrame(ctx writeContext) error { + enc, buf := ctx.HeaderEncoder() + buf.Reset() + + encKV(enc, ":method", w.method) + encKV(enc, ":scheme", w.url.Scheme) + encKV(enc, ":authority", w.url.Host) + encKV(enc, ":path", w.url.RequestURI()) + encodeHeaders(enc, w.h, nil) + + headerBlock := buf.Bytes() + if len(headerBlock) == 0 { + panic("unexpected empty hpack") + } + + return splitHeaderBlock(ctx, headerBlock, w.writeHeaderBlock) +} + +func (w *writePushPromise) writeHeaderBlock(ctx writeContext, frag []byte, firstFrag, lastFrag bool) error { + if firstFrag { + return ctx.Framer().WritePushPromise(PushPromiseParam{ + StreamID: w.streamID, + PromiseID: w.promisedID, + BlockFragment: frag, + EndHeaders: lastFrag, + }) + } else { + return ctx.Framer().WriteContinuation(w.streamID, lastFrag, frag) } - return nil } type write100ContinueHeadersFrame struct { @@ -220,15 +317,24 @@ func (w write100ContinueHeadersFrame) writeFrame(ctx writeContext) error { }) } +func (w write100ContinueHeadersFrame) staysWithinBuffer(max int) bool { + // Sloppy but conservative: + return 9+2*(len(":status")+len("100")) <= max +} + type writeWindowUpdate struct { streamID uint32 // or 0 for conn-level n uint32 } +func (wu writeWindowUpdate) staysWithinBuffer(max int) bool { return frameHeaderLen+4 <= max } + func (wu writeWindowUpdate) writeFrame(ctx writeContext) error { return ctx.Framer().WriteWindowUpdate(wu.streamID, wu.n) } +// encodeHeaders encodes an http.Header. If keys is not nil, then (k, h[k]) +// is encoded only only if k is in keys. func encodeHeaders(enc *hpack.Encoder, h http.Header, keys []string) { if keys == nil { sorter := sorterPool.Get().(*sorter) diff --git a/vendor/golang.org/x/net/http2/writesched.go b/vendor/golang.org/x/net/http2/writesched.go index c24316ce7..4fe307307 100644 --- a/vendor/golang.org/x/net/http2/writesched.go +++ b/vendor/golang.org/x/net/http2/writesched.go @@ -6,14 +6,53 @@ package http2 import "fmt" -// frameWriteMsg is a request to write a frame. -type frameWriteMsg struct { +// WriteScheduler is the interface implemented by HTTP/2 write schedulers. +// Methods are never called concurrently. +type WriteScheduler interface { + // OpenStream opens a new stream in the write scheduler. + // It is illegal to call this with streamID=0 or with a streamID that is + // already open -- the call may panic. + OpenStream(streamID uint32, options OpenStreamOptions) + + // CloseStream closes a stream in the write scheduler. Any frames queued on + // this stream should be discarded. It is illegal to call this on a stream + // that is not open -- the call may panic. + CloseStream(streamID uint32) + + // AdjustStream adjusts the priority of the given stream. This may be called + // on a stream that has not yet been opened or has been closed. Note that + // RFC 7540 allows PRIORITY frames to be sent on streams in any state. See: + // https://tools.ietf.org/html/rfc7540#section-5.1 + AdjustStream(streamID uint32, priority PriorityParam) + + // Push queues a frame in the scheduler. In most cases, this will not be + // called with wr.StreamID()!=0 unless that stream is currently open. The one + // exception is RST_STREAM frames, which may be sent on idle or closed streams. + Push(wr FrameWriteRequest) + + // Pop dequeues the next frame to write. Returns false if no frames can + // be written. Frames with a given wr.StreamID() are Pop'd in the same + // order they are Push'd. + Pop() (wr FrameWriteRequest, ok bool) +} + +// OpenStreamOptions specifies extra options for WriteScheduler.OpenStream. +type OpenStreamOptions struct { + // PusherID is zero if the stream was initiated by the client. Otherwise, + // PusherID names the stream that pushed the newly opened stream. + PusherID uint32 +} + +// FrameWriteRequest is a request to write a frame. +type FrameWriteRequest struct { // write is the interface value that does the writing, once the - // writeScheduler (below) has decided to select this frame - // to write. The write functions are all defined in write.go. + // WriteScheduler has selected this frame to write. The write + // functions are all defined in write.go. write writeFramer - stream *stream // used for prioritization. nil for non-stream frames. + // stream is the stream on which this frame will be written. + // nil for non-stream frames like PING and SETTINGS. + stream *stream // done, if non-nil, must be a buffered channel with space for // 1 message and is sent the return value from write (or an @@ -21,263 +60,183 @@ type frameWriteMsg struct { done chan error } -// for debugging only: -func (wm frameWriteMsg) String() string { - var streamID uint32 - if wm.stream != nil { - streamID = wm.stream.id - } - var des string - if s, ok := wm.write.(fmt.Stringer); ok { - des = s.String() - } else { - des = fmt.Sprintf("%T", wm.write) - } - return fmt.Sprintf("[frameWriteMsg stream=%d, ch=%v, type: %v]", streamID, wm.done != nil, des) -} - -// writeScheduler tracks pending frames to write, priorities, and decides -// the next one to use. It is not thread-safe. -type writeScheduler struct { - // zero are frames not associated with a specific stream. - // They're sent before any stream-specific freams. - zero writeQueue - - // maxFrameSize is the maximum size of a DATA frame - // we'll write. Must be non-zero and between 16K-16M. - maxFrameSize uint32 - - // sq contains the stream-specific queues, keyed by stream ID. - // when a stream is idle, it's deleted from the map. - sq map[uint32]*writeQueue - - // canSend is a slice of memory that's reused between frame - // scheduling decisions to hold the list of writeQueues (from sq) - // which have enough flow control data to send. After canSend is - // built, the best is selected. - canSend []*writeQueue - - // pool of empty queues for reuse. - queuePool []*writeQueue -} - -func (ws *writeScheduler) putEmptyQueue(q *writeQueue) { - if len(q.s) != 0 { - panic("queue must be empty") - } - ws.queuePool = append(ws.queuePool, q) -} - -func (ws *writeScheduler) getEmptyQueue() *writeQueue { - ln := len(ws.queuePool) - if ln == 0 { - return new(writeQueue) - } - q := ws.queuePool[ln-1] - ws.queuePool = ws.queuePool[:ln-1] - return q -} - -func (ws *writeScheduler) empty() bool { return ws.zero.empty() && len(ws.sq) == 0 } - -func (ws *writeScheduler) add(wm frameWriteMsg) { - st := wm.stream - if st == nil { - ws.zero.push(wm) - } else { - ws.streamQueue(st.id).push(wm) - } -} - -func (ws *writeScheduler) streamQueue(streamID uint32) *writeQueue { - if q, ok := ws.sq[streamID]; ok { - return q - } - if ws.sq == nil { - ws.sq = make(map[uint32]*writeQueue) - } - q := ws.getEmptyQueue() - ws.sq[streamID] = q - return q -} - -// take returns the most important frame to write and removes it from the scheduler. -// It is illegal to call this if the scheduler is empty or if there are no connection-level -// flow control bytes available. -func (ws *writeScheduler) take() (wm frameWriteMsg, ok bool) { - if ws.maxFrameSize == 0 { - panic("internal error: ws.maxFrameSize not initialized or invalid") - } - - // If there any frames not associated with streams, prefer those first. - // These are usually SETTINGS, etc. - if !ws.zero.empty() { - return ws.zero.shift(), true - } - if len(ws.sq) == 0 { - return - } - - // Next, prioritize frames on streams that aren't DATA frames (no cost). - for id, q := range ws.sq { - if q.firstIsNoCost() { - return ws.takeFrom(id, q) +// StreamID returns the id of the stream this frame will be written to. +// 0 is used for non-stream frames such as PING and SETTINGS. +func (wr FrameWriteRequest) StreamID() uint32 { + if wr.stream == nil { + if se, ok := wr.write.(StreamError); ok { + // (*serverConn).resetStream doesn't set + // stream because it doesn't necessarily have + // one. So special case this type of write + // message. + return se.StreamID } - } - - // Now, all that remains are DATA frames with non-zero bytes to - // send. So pick the best one. - if len(ws.canSend) != 0 { - panic("should be empty") - } - for _, q := range ws.sq { - if n := ws.streamWritableBytes(q); n > 0 { - ws.canSend = append(ws.canSend, q) - } - } - if len(ws.canSend) == 0 { - return - } - defer ws.zeroCanSend() - - // TODO: find the best queue - q := ws.canSend[0] - - return ws.takeFrom(q.streamID(), q) -} - -// zeroCanSend is defered from take. -func (ws *writeScheduler) zeroCanSend() { - for i := range ws.canSend { - ws.canSend[i] = nil - } - ws.canSend = ws.canSend[:0] -} - -// streamWritableBytes returns the number of DATA bytes we could write -// from the given queue's stream, if this stream/queue were -// selected. It is an error to call this if q's head isn't a -// *writeData. -func (ws *writeScheduler) streamWritableBytes(q *writeQueue) int32 { - wm := q.head() - ret := wm.stream.flow.available() // max we can write - if ret == 0 { return 0 } - if int32(ws.maxFrameSize) < ret { - ret = int32(ws.maxFrameSize) - } - if ret == 0 { - panic("internal error: ws.maxFrameSize not initialized or invalid") - } - wd := wm.write.(*writeData) - if len(wd.p) < int(ret) { - ret = int32(len(wd.p)) - } - return ret + return wr.stream.id } -func (ws *writeScheduler) takeFrom(id uint32, q *writeQueue) (wm frameWriteMsg, ok bool) { - wm = q.head() - // If the first item in this queue costs flow control tokens - // and we don't have enough, write as much as we can. - if wd, ok := wm.write.(*writeData); ok && len(wd.p) > 0 { - allowed := wm.stream.flow.available() // max we can write - if allowed == 0 { - // No quota available. Caller can try the next stream. - return frameWriteMsg{}, false - } - if int32(ws.maxFrameSize) < allowed { - allowed = int32(ws.maxFrameSize) - } - // TODO: further restrict the allowed size, because even if - // the peer says it's okay to write 16MB data frames, we might - // want to write smaller ones to properly weight competing - // streams' priorities. - - if len(wd.p) > int(allowed) { - wm.stream.flow.take(allowed) - chunk := wd.p[:allowed] - wd.p = wd.p[allowed:] - // Make up a new write message of a valid size, rather - // than shifting one off the queue. - return frameWriteMsg{ - stream: wm.stream, - write: &writeData{ - streamID: wd.streamID, - p: chunk, - // even if the original had endStream set, there - // arebytes remaining because len(wd.p) > allowed, - // so we know endStream is false: - endStream: false, - }, - // our caller is blocking on the final DATA frame, not - // these intermediates, so no need to wait: - done: nil, - }, true - } - wm.stream.flow.take(int32(len(wd.p))) +// DataSize returns the number of flow control bytes that must be consumed +// to write this entire frame. This is 0 for non-DATA frames. +func (wr FrameWriteRequest) DataSize() int { + if wd, ok := wr.write.(*writeData); ok { + return len(wd.p) } - - q.shift() - if q.empty() { - ws.putEmptyQueue(q) - delete(ws.sq, id) - } - return wm, true + return 0 } -func (ws *writeScheduler) forgetStream(id uint32) { - q, ok := ws.sq[id] - if !ok { +// Consume consumes min(n, available) bytes from this frame, where available +// is the number of flow control bytes available on the stream. Consume returns +// 0, 1, or 2 frames, where the integer return value gives the number of frames +// returned. +// +// If flow control prevents consuming any bytes, this returns (_, _, 0). If +// the entire frame was consumed, this returns (wr, _, 1). Otherwise, this +// returns (consumed, rest, 2), where 'consumed' contains the consumed bytes and +// 'rest' contains the remaining bytes. The consumed bytes are deducted from the +// underlying stream's flow control budget. +func (wr FrameWriteRequest) Consume(n int32) (FrameWriteRequest, FrameWriteRequest, int) { + var empty FrameWriteRequest + + // Non-DATA frames are always consumed whole. + wd, ok := wr.write.(*writeData) + if !ok || len(wd.p) == 0 { + return wr, empty, 1 + } + + // Might need to split after applying limits. + allowed := wr.stream.flow.available() + if n < allowed { + allowed = n + } + if wr.stream.sc.maxFrameSize < allowed { + allowed = wr.stream.sc.maxFrameSize + } + if allowed <= 0 { + return empty, empty, 0 + } + if len(wd.p) > int(allowed) { + wr.stream.flow.take(allowed) + consumed := FrameWriteRequest{ + stream: wr.stream, + write: &writeData{ + streamID: wd.streamID, + p: wd.p[:allowed], + // Even if the original had endStream set, there + // are bytes remaining because len(wd.p) > allowed, + // so we know endStream is false. + endStream: false, + }, + // Our caller is blocking on the final DATA frame, not + // this intermediate frame, so no need to wait. + done: nil, + } + rest := FrameWriteRequest{ + stream: wr.stream, + write: &writeData{ + streamID: wd.streamID, + p: wd.p[allowed:], + endStream: wd.endStream, + }, + done: wr.done, + } + return consumed, rest, 2 + } + + // The frame is consumed whole. + // NB: This cast cannot overflow because allowed is <= math.MaxInt32. + wr.stream.flow.take(int32(len(wd.p))) + return wr, empty, 1 +} + +// String is for debugging only. +func (wr FrameWriteRequest) String() string { + var des string + if s, ok := wr.write.(fmt.Stringer); ok { + des = s.String() + } else { + des = fmt.Sprintf("%T", wr.write) + } + return fmt.Sprintf("[FrameWriteRequest stream=%d, ch=%v, writer=%v]", wr.StreamID(), wr.done != nil, des) +} + +// replyToWriter sends err to wr.done and panics if the send must block +// This does nothing if wr.done is nil. +func (wr *FrameWriteRequest) replyToWriter(err error) { + if wr.done == nil { return } - delete(ws.sq, id) - - // But keep it for others later. - for i := range q.s { - q.s[i] = frameWriteMsg{} + select { + case wr.done <- err: + default: + panic(fmt.Sprintf("unbuffered done channel passed in for type %T", wr.write)) } - q.s = q.s[:0] - ws.putEmptyQueue(q) + wr.write = nil // prevent use (assume it's tainted after wr.done send) } +// writeQueue is used by implementations of WriteScheduler. type writeQueue struct { - s []frameWriteMsg + s []FrameWriteRequest } -// streamID returns the stream ID for a non-empty stream-specific queue. -func (q *writeQueue) streamID() uint32 { return q.s[0].stream.id } - func (q *writeQueue) empty() bool { return len(q.s) == 0 } -func (q *writeQueue) push(wm frameWriteMsg) { - q.s = append(q.s, wm) +func (q *writeQueue) push(wr FrameWriteRequest) { + q.s = append(q.s, wr) } -// head returns the next item that would be removed by shift. -func (q *writeQueue) head() frameWriteMsg { +func (q *writeQueue) shift() FrameWriteRequest { if len(q.s) == 0 { panic("invalid use of queue") } - return q.s[0] -} - -func (q *writeQueue) shift() frameWriteMsg { - if len(q.s) == 0 { - panic("invalid use of queue") - } - wm := q.s[0] + wr := q.s[0] // TODO: less copy-happy queue. copy(q.s, q.s[1:]) - q.s[len(q.s)-1] = frameWriteMsg{} + q.s[len(q.s)-1] = FrameWriteRequest{} q.s = q.s[:len(q.s)-1] - return wm + return wr } -func (q *writeQueue) firstIsNoCost() bool { - if df, ok := q.s[0].write.(*writeData); ok { - return len(df.p) == 0 +// consume consumes up to n bytes from q.s[0]. If the frame is +// entirely consumed, it is removed from the queue. If the frame +// is partially consumed, the frame is kept with the consumed +// bytes removed. Returns true iff any bytes were consumed. +func (q *writeQueue) consume(n int32) (FrameWriteRequest, bool) { + if len(q.s) == 0 { + return FrameWriteRequest{}, false } - return true + consumed, rest, numresult := q.s[0].Consume(n) + switch numresult { + case 0: + return FrameWriteRequest{}, false + case 1: + q.shift() + case 2: + q.s[0] = rest + } + return consumed, true +} + +type writeQueuePool []*writeQueue + +// put inserts an unused writeQueue into the pool. +func (p *writeQueuePool) put(q *writeQueue) { + for i := range q.s { + q.s[i] = FrameWriteRequest{} + } + q.s = q.s[:0] + *p = append(*p, q) +} + +// get returns an empty writeQueue. +func (p *writeQueuePool) get() *writeQueue { + ln := len(*p) + if ln == 0 { + return new(writeQueue) + } + x := ln - 1 + q := (*p)[x] + (*p)[x] = nil + *p = (*p)[:x] + return q } diff --git a/vendor/golang.org/x/net/http2/writesched_priority.go b/vendor/golang.org/x/net/http2/writesched_priority.go new file mode 100644 index 000000000..01132721b --- /dev/null +++ b/vendor/golang.org/x/net/http2/writesched_priority.go @@ -0,0 +1,452 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package http2 + +import ( + "fmt" + "math" + "sort" +) + +// RFC 7540, Section 5.3.5: the default weight is 16. +const priorityDefaultWeight = 15 // 16 = 15 + 1 + +// PriorityWriteSchedulerConfig configures a priorityWriteScheduler. +type PriorityWriteSchedulerConfig struct { + // MaxClosedNodesInTree controls the maximum number of closed streams to + // retain in the priority tree. Setting this to zero saves a small amount + // of memory at the cost of performance. + // + // See RFC 7540, Section 5.3.4: + // "It is possible for a stream to become closed while prioritization + // information ... is in transit. ... This potentially creates suboptimal + // prioritization, since the stream could be given a priority that is + // different from what is intended. To avoid these problems, an endpoint + // SHOULD retain stream prioritization state for a period after streams + // become closed. The longer state is retained, the lower the chance that + // streams are assigned incorrect or default priority values." + MaxClosedNodesInTree int + + // MaxIdleNodesInTree controls the maximum number of idle streams to + // retain in the priority tree. Setting this to zero saves a small amount + // of memory at the cost of performance. + // + // See RFC 7540, Section 5.3.4: + // Similarly, streams that are in the "idle" state can be assigned + // priority or become a parent of other streams. This allows for the + // creation of a grouping node in the dependency tree, which enables + // more flexible expressions of priority. Idle streams begin with a + // default priority (Section 5.3.5). + MaxIdleNodesInTree int + + // ThrottleOutOfOrderWrites enables write throttling to help ensure that + // data is delivered in priority order. This works around a race where + // stream B depends on stream A and both streams are about to call Write + // to queue DATA frames. If B wins the race, a naive scheduler would eagerly + // write as much data from B as possible, but this is suboptimal because A + // is a higher-priority stream. With throttling enabled, we write a small + // amount of data from B to minimize the amount of bandwidth that B can + // steal from A. + ThrottleOutOfOrderWrites bool +} + +// NewPriorityWriteScheduler constructs a WriteScheduler that schedules +// frames by following HTTP/2 priorities as described in RFC 7340 Section 5.3. +// If cfg is nil, default options are used. +func NewPriorityWriteScheduler(cfg *PriorityWriteSchedulerConfig) WriteScheduler { + if cfg == nil { + // For justification of these defaults, see: + // https://docs.google.com/document/d/1oLhNg1skaWD4_DtaoCxdSRN5erEXrH-KnLrMwEpOtFY + cfg = &PriorityWriteSchedulerConfig{ + MaxClosedNodesInTree: 10, + MaxIdleNodesInTree: 10, + ThrottleOutOfOrderWrites: false, + } + } + + ws := &priorityWriteScheduler{ + nodes: make(map[uint32]*priorityNode), + maxClosedNodesInTree: cfg.MaxClosedNodesInTree, + maxIdleNodesInTree: cfg.MaxIdleNodesInTree, + enableWriteThrottle: cfg.ThrottleOutOfOrderWrites, + } + ws.nodes[0] = &ws.root + if cfg.ThrottleOutOfOrderWrites { + ws.writeThrottleLimit = 1024 + } else { + ws.writeThrottleLimit = math.MaxInt32 + } + return ws +} + +type priorityNodeState int + +const ( + priorityNodeOpen priorityNodeState = iota + priorityNodeClosed + priorityNodeIdle +) + +// priorityNode is a node in an HTTP/2 priority tree. +// Each node is associated with a single stream ID. +// See RFC 7540, Section 5.3. +type priorityNode struct { + q writeQueue // queue of pending frames to write + id uint32 // id of the stream, or 0 for the root of the tree + weight uint8 // the actual weight is weight+1, so the value is in [1,256] + state priorityNodeState // open | closed | idle + bytes int64 // number of bytes written by this node, or 0 if closed + subtreeBytes int64 // sum(node.bytes) of all nodes in this subtree + + // These links form the priority tree. + parent *priorityNode + kids *priorityNode // start of the kids list + prev, next *priorityNode // doubly-linked list of siblings +} + +func (n *priorityNode) setParent(parent *priorityNode) { + if n == parent { + panic("setParent to self") + } + if n.parent == parent { + return + } + // Unlink from current parent. + if parent := n.parent; parent != nil { + if n.prev == nil { + parent.kids = n.next + } else { + n.prev.next = n.next + } + if n.next != nil { + n.next.prev = n.prev + } + } + // Link to new parent. + // If parent=nil, remove n from the tree. + // Always insert at the head of parent.kids (this is assumed by walkReadyInOrder). + n.parent = parent + if parent == nil { + n.next = nil + n.prev = nil + } else { + n.next = parent.kids + n.prev = nil + if n.next != nil { + n.next.prev = n + } + parent.kids = n + } +} + +func (n *priorityNode) addBytes(b int64) { + n.bytes += b + for ; n != nil; n = n.parent { + n.subtreeBytes += b + } +} + +// walkReadyInOrder iterates over the tree in priority order, calling f for each node +// with a non-empty write queue. When f returns true, this funcion returns true and the +// walk halts. tmp is used as scratch space for sorting. +// +// f(n, openParent) takes two arguments: the node to visit, n, and a bool that is true +// if any ancestor p of n is still open (ignoring the root node). +func (n *priorityNode) walkReadyInOrder(openParent bool, tmp *[]*priorityNode, f func(*priorityNode, bool) bool) bool { + if !n.q.empty() && f(n, openParent) { + return true + } + if n.kids == nil { + return false + } + + // Don't consider the root "open" when updating openParent since + // we can't send data frames on the root stream (only control frames). + if n.id != 0 { + openParent = openParent || (n.state == priorityNodeOpen) + } + + // Common case: only one kid or all kids have the same weight. + // Some clients don't use weights; other clients (like web browsers) + // use mostly-linear priority trees. + w := n.kids.weight + needSort := false + for k := n.kids.next; k != nil; k = k.next { + if k.weight != w { + needSort = true + break + } + } + if !needSort { + for k := n.kids; k != nil; k = k.next { + if k.walkReadyInOrder(openParent, tmp, f) { + return true + } + } + return false + } + + // Uncommon case: sort the child nodes. We remove the kids from the parent, + // then re-insert after sorting so we can reuse tmp for future sort calls. + *tmp = (*tmp)[:0] + for n.kids != nil { + *tmp = append(*tmp, n.kids) + n.kids.setParent(nil) + } + sort.Sort(sortPriorityNodeSiblings(*tmp)) + for i := len(*tmp) - 1; i >= 0; i-- { + (*tmp)[i].setParent(n) // setParent inserts at the head of n.kids + } + for k := n.kids; k != nil; k = k.next { + if k.walkReadyInOrder(openParent, tmp, f) { + return true + } + } + return false +} + +type sortPriorityNodeSiblings []*priorityNode + +func (z sortPriorityNodeSiblings) Len() int { return len(z) } +func (z sortPriorityNodeSiblings) Swap(i, k int) { z[i], z[k] = z[k], z[i] } +func (z sortPriorityNodeSiblings) Less(i, k int) bool { + // Prefer the subtree that has sent fewer bytes relative to its weight. + // See sections 5.3.2 and 5.3.4. + wi, bi := float64(z[i].weight+1), float64(z[i].subtreeBytes) + wk, bk := float64(z[k].weight+1), float64(z[k].subtreeBytes) + if bi == 0 && bk == 0 { + return wi >= wk + } + if bk == 0 { + return false + } + return bi/bk <= wi/wk +} + +type priorityWriteScheduler struct { + // root is the root of the priority tree, where root.id = 0. + // The root queues control frames that are not associated with any stream. + root priorityNode + + // nodes maps stream ids to priority tree nodes. + nodes map[uint32]*priorityNode + + // maxID is the maximum stream id in nodes. + maxID uint32 + + // lists of nodes that have been closed or are idle, but are kept in + // the tree for improved prioritization. When the lengths exceed either + // maxClosedNodesInTree or maxIdleNodesInTree, old nodes are discarded. + closedNodes, idleNodes []*priorityNode + + // From the config. + maxClosedNodesInTree int + maxIdleNodesInTree int + writeThrottleLimit int32 + enableWriteThrottle bool + + // tmp is scratch space for priorityNode.walkReadyInOrder to reduce allocations. + tmp []*priorityNode + + // pool of empty queues for reuse. + queuePool writeQueuePool +} + +func (ws *priorityWriteScheduler) OpenStream(streamID uint32, options OpenStreamOptions) { + // The stream may be currently idle but cannot be opened or closed. + if curr := ws.nodes[streamID]; curr != nil { + if curr.state != priorityNodeIdle { + panic(fmt.Sprintf("stream %d already opened", streamID)) + } + curr.state = priorityNodeOpen + return + } + + // RFC 7540, Section 5.3.5: + // "All streams are initially assigned a non-exclusive dependency on stream 0x0. + // Pushed streams initially depend on their associated stream. In both cases, + // streams are assigned a default weight of 16." + parent := ws.nodes[options.PusherID] + if parent == nil { + parent = &ws.root + } + n := &priorityNode{ + q: *ws.queuePool.get(), + id: streamID, + weight: priorityDefaultWeight, + state: priorityNodeOpen, + } + n.setParent(parent) + ws.nodes[streamID] = n + if streamID > ws.maxID { + ws.maxID = streamID + } +} + +func (ws *priorityWriteScheduler) CloseStream(streamID uint32) { + if streamID == 0 { + panic("violation of WriteScheduler interface: cannot close stream 0") + } + if ws.nodes[streamID] == nil { + panic(fmt.Sprintf("violation of WriteScheduler interface: unknown stream %d", streamID)) + } + if ws.nodes[streamID].state != priorityNodeOpen { + panic(fmt.Sprintf("violation of WriteScheduler interface: stream %d already closed", streamID)) + } + + n := ws.nodes[streamID] + n.state = priorityNodeClosed + n.addBytes(-n.bytes) + + q := n.q + ws.queuePool.put(&q) + n.q.s = nil + if ws.maxClosedNodesInTree > 0 { + ws.addClosedOrIdleNode(&ws.closedNodes, ws.maxClosedNodesInTree, n) + } else { + ws.removeNode(n) + } +} + +func (ws *priorityWriteScheduler) AdjustStream(streamID uint32, priority PriorityParam) { + if streamID == 0 { + panic("adjustPriority on root") + } + + // If streamID does not exist, there are two cases: + // - A closed stream that has been removed (this will have ID <= maxID) + // - An idle stream that is being used for "grouping" (this will have ID > maxID) + n := ws.nodes[streamID] + if n == nil { + if streamID <= ws.maxID || ws.maxIdleNodesInTree == 0 { + return + } + ws.maxID = streamID + n = &priorityNode{ + q: *ws.queuePool.get(), + id: streamID, + weight: priorityDefaultWeight, + state: priorityNodeIdle, + } + n.setParent(&ws.root) + ws.nodes[streamID] = n + ws.addClosedOrIdleNode(&ws.idleNodes, ws.maxIdleNodesInTree, n) + } + + // Section 5.3.1: A dependency on a stream that is not currently in the tree + // results in that stream being given a default priority (Section 5.3.5). + parent := ws.nodes[priority.StreamDep] + if parent == nil { + n.setParent(&ws.root) + n.weight = priorityDefaultWeight + return + } + + // Ignore if the client tries to make a node its own parent. + if n == parent { + return + } + + // Section 5.3.3: + // "If a stream is made dependent on one of its own dependencies, the + // formerly dependent stream is first moved to be dependent on the + // reprioritized stream's previous parent. The moved dependency retains + // its weight." + // + // That is: if parent depends on n, move parent to depend on n.parent. + for x := parent.parent; x != nil; x = x.parent { + if x == n { + parent.setParent(n.parent) + break + } + } + + // Section 5.3.3: The exclusive flag causes the stream to become the sole + // dependency of its parent stream, causing other dependencies to become + // dependent on the exclusive stream. + if priority.Exclusive { + k := parent.kids + for k != nil { + next := k.next + if k != n { + k.setParent(n) + } + k = next + } + } + + n.setParent(parent) + n.weight = priority.Weight +} + +func (ws *priorityWriteScheduler) Push(wr FrameWriteRequest) { + var n *priorityNode + if id := wr.StreamID(); id == 0 { + n = &ws.root + } else { + n = ws.nodes[id] + if n == nil { + // id is an idle or closed stream. wr should not be a HEADERS or + // DATA frame. However, wr can be a RST_STREAM. In this case, we + // push wr onto the root, rather than creating a new priorityNode, + // since RST_STREAM is tiny and the stream's priority is unknown + // anyway. See issue #17919. + if wr.DataSize() > 0 { + panic("add DATA on non-open stream") + } + n = &ws.root + } + } + n.q.push(wr) +} + +func (ws *priorityWriteScheduler) Pop() (wr FrameWriteRequest, ok bool) { + ws.root.walkReadyInOrder(false, &ws.tmp, func(n *priorityNode, openParent bool) bool { + limit := int32(math.MaxInt32) + if openParent { + limit = ws.writeThrottleLimit + } + wr, ok = n.q.consume(limit) + if !ok { + return false + } + n.addBytes(int64(wr.DataSize())) + // If B depends on A and B continuously has data available but A + // does not, gradually increase the throttling limit to allow B to + // steal more and more bandwidth from A. + if openParent { + ws.writeThrottleLimit += 1024 + if ws.writeThrottleLimit < 0 { + ws.writeThrottleLimit = math.MaxInt32 + } + } else if ws.enableWriteThrottle { + ws.writeThrottleLimit = 1024 + } + return true + }) + return wr, ok +} + +func (ws *priorityWriteScheduler) addClosedOrIdleNode(list *[]*priorityNode, maxSize int, n *priorityNode) { + if maxSize == 0 { + return + } + if len(*list) == maxSize { + // Remove the oldest node, then shift left. + ws.removeNode((*list)[0]) + x := (*list)[1:] + copy(*list, x) + *list = (*list)[:len(x)] + } + *list = append(*list, n) +} + +func (ws *priorityWriteScheduler) removeNode(n *priorityNode) { + for k := n.kids; k != nil; k = k.next { + k.setParent(n.parent) + } + n.setParent(nil) + delete(ws.nodes, n.id) +} diff --git a/vendor/golang.org/x/net/http2/writesched_random.go b/vendor/golang.org/x/net/http2/writesched_random.go new file mode 100644 index 000000000..36d7919f1 --- /dev/null +++ b/vendor/golang.org/x/net/http2/writesched_random.go @@ -0,0 +1,72 @@ +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package http2 + +import "math" + +// NewRandomWriteScheduler constructs a WriteScheduler that ignores HTTP/2 +// priorities. Control frames like SETTINGS and PING are written before DATA +// frames, but if no control frames are queued and multiple streams have queued +// HEADERS or DATA frames, Pop selects a ready stream arbitrarily. +func NewRandomWriteScheduler() WriteScheduler { + return &randomWriteScheduler{sq: make(map[uint32]*writeQueue)} +} + +type randomWriteScheduler struct { + // zero are frames not associated with a specific stream. + zero writeQueue + + // sq contains the stream-specific queues, keyed by stream ID. + // When a stream is idle or closed, it's deleted from the map. + sq map[uint32]*writeQueue + + // pool of empty queues for reuse. + queuePool writeQueuePool +} + +func (ws *randomWriteScheduler) OpenStream(streamID uint32, options OpenStreamOptions) { + // no-op: idle streams are not tracked +} + +func (ws *randomWriteScheduler) CloseStream(streamID uint32) { + q, ok := ws.sq[streamID] + if !ok { + return + } + delete(ws.sq, streamID) + ws.queuePool.put(q) +} + +func (ws *randomWriteScheduler) AdjustStream(streamID uint32, priority PriorityParam) { + // no-op: priorities are ignored +} + +func (ws *randomWriteScheduler) Push(wr FrameWriteRequest) { + id := wr.StreamID() + if id == 0 { + ws.zero.push(wr) + return + } + q, ok := ws.sq[id] + if !ok { + q = ws.queuePool.get() + ws.sq[id] = q + } + q.push(wr) +} + +func (ws *randomWriteScheduler) Pop() (FrameWriteRequest, bool) { + // Control frames first. + if !ws.zero.empty() { + return ws.zero.shift(), true + } + // Iterate over all non-idle streams until finding one that can be consumed. + for _, q := range ws.sq { + if wr, ok := q.consume(math.MaxInt32); ok { + return wr, true + } + } + return FrameWriteRequest{}, false +} diff --git a/vendor/golang.org/x/net/lex/httplex/httplex.go b/vendor/golang.org/x/net/lex/httplex/httplex.go index bd0ec24f4..20f2b8940 100644 --- a/vendor/golang.org/x/net/lex/httplex/httplex.go +++ b/vendor/golang.org/x/net/lex/httplex/httplex.go @@ -10,8 +10,11 @@ package httplex import ( + "net" "strings" "unicode/utf8" + + "golang.org/x/net/idna" ) var isTokenTable = [127]bool{ @@ -310,3 +313,39 @@ func ValidHeaderFieldValue(v string) bool { } return true } + +func isASCII(s string) bool { + for i := 0; i < len(s); i++ { + if s[i] >= utf8.RuneSelf { + return false + } + } + return true +} + +// PunycodeHostPort returns the IDNA Punycode version +// of the provided "host" or "host:port" string. +func PunycodeHostPort(v string) (string, error) { + if isASCII(v) { + return v, nil + } + + host, port, err := net.SplitHostPort(v) + if err != nil { + // The input 'v' argument was just a "host" argument, + // without a port. This error should not be returned + // to the caller. + host = v + port = "" + } + host, err = idna.ToASCII(host) + if err != nil { + // Non-UTF-8? Not representable in Punycode, in any + // case. + return "", err + } + if port == "" { + return host, nil + } + return net.JoinHostPort(host, port), nil +} diff --git a/vendor/golang.org/x/net/trace/events.go b/vendor/golang.org/x/net/trace/events.go index e66c7e328..d8daec1a7 100644 --- a/vendor/golang.org/x/net/trace/events.go +++ b/vendor/golang.org/x/net/trace/events.go @@ -21,11 +21,6 @@ import ( "time" ) -var eventsTmpl = template.Must(template.New("events").Funcs(template.FuncMap{ - "elapsed": elapsed, - "trimSpace": strings.TrimSpace, -}).Parse(eventsHTML)) - const maxEventsPerLog = 100 type bucket struct { @@ -101,7 +96,7 @@ func RenderEvents(w http.ResponseWriter, req *http.Request, sensitive bool) { famMu.RLock() defer famMu.RUnlock() - if err := eventsTmpl.Execute(w, data); err != nil { + if err := eventsTmpl().Execute(w, data); err != nil { log.Printf("net/trace: Failed executing template: %v", err) } } @@ -421,6 +416,19 @@ func freeEventLog(el *eventLog) { } } +var eventsTmplCache *template.Template +var eventsTmplOnce sync.Once + +func eventsTmpl() *template.Template { + eventsTmplOnce.Do(func() { + eventsTmplCache = template.Must(template.New("events").Funcs(template.FuncMap{ + "elapsed": elapsed, + "trimSpace": strings.TrimSpace, + }).Parse(eventsHTML)) + }) + return eventsTmplCache +} + const eventsHTML = ` diff --git a/vendor/golang.org/x/net/trace/histogram.go b/vendor/golang.org/x/net/trace/histogram.go index bb42aa532..9bf4286c7 100644 --- a/vendor/golang.org/x/net/trace/histogram.go +++ b/vendor/golang.org/x/net/trace/histogram.go @@ -12,6 +12,7 @@ import ( "html/template" "log" "math" + "sync" "golang.org/x/net/internal/timeseries" ) @@ -320,15 +321,20 @@ func (h *histogram) newData() *data { func (h *histogram) html() template.HTML { buf := new(bytes.Buffer) - if err := distTmpl.Execute(buf, h.newData()); err != nil { + if err := distTmpl().Execute(buf, h.newData()); err != nil { buf.Reset() log.Printf("net/trace: couldn't execute template: %v", err) } return template.HTML(buf.String()) } -// Input: data -var distTmpl = template.Must(template.New("distTmpl").Parse(` +var distTmplCache *template.Template +var distTmplOnce sync.Once + +func distTmpl() *template.Template { + distTmplOnce.Do(func() { + // Input: data + distTmplCache = template.Must(template.New("distTmpl").Parse(` @@ -354,3 +360,6 @@ var distTmpl = template.Must(template.New("distTmpl").Parse(` {{end}}
Count: {{.Count}}
`)) + }) + return distTmplCache +} diff --git a/vendor/golang.org/x/net/trace/trace.go b/vendor/golang.org/x/net/trace/trace.go index 877dfb32b..9eb55e7fd 100644 --- a/vendor/golang.org/x/net/trace/trace.go +++ b/vendor/golang.org/x/net/trace/trace.go @@ -91,7 +91,7 @@ var DebugUseAfterFinish = false // It returns two bools; the first indicates whether the page may be viewed at all, // and the second indicates whether sensitive events will be shown. // -// AuthRequest may be replaced by a program to customise its authorisation requirements. +// AuthRequest may be replaced by a program to customize its authorization requirements. // // The default AuthRequest function returns (true, true) if and only if the request // comes from localhost/127.0.0.1/[::1]. @@ -238,7 +238,7 @@ func Render(w io.Writer, req *http.Request, sensitive bool) { completedMu.RLock() defer completedMu.RUnlock() - if err := pageTmpl.ExecuteTemplate(w, "Page", data); err != nil { + if err := pageTmpl().ExecuteTemplate(w, "Page", data); err != nil { log.Printf("net/trace: Failed executing template: %v", err) } } @@ -333,7 +333,8 @@ func New(family, title string) Trace { tr.ref() tr.Family, tr.Title = family, title tr.Start = time.Now() - tr.events = make([]event, 0, maxEventsPerTrace) + tr.maxEvents = maxEventsPerTrace + tr.events = tr.eventsBuf[:0] activeMu.RLock() s := activeTraces[tr.Family] @@ -650,8 +651,8 @@ type event struct { Elapsed time.Duration // since previous event in trace NewDay bool // whether this event is on a different day to the previous event Recyclable bool // whether this event was passed via LazyLog - What interface{} // string or fmt.Stringer Sensitive bool // whether this event contains sensitive information + What interface{} // string or fmt.Stringer } // WhenString returns a string representation of the elapsed time of the event. @@ -692,14 +693,17 @@ type trace struct { IsError bool // Append-only sequence of events (modulo discards). - mu sync.RWMutex - events []event + mu sync.RWMutex + events []event + maxEvents int refs int32 // how many buckets this is in recycler func(interface{}) disc discarded // scratch space to avoid allocation finishStack []byte // where finish was called, if DebugUseAfterFinish is set + + eventsBuf [4]event // preallocated buffer in case we only log a few events } func (tr *trace) reset() { @@ -711,11 +715,15 @@ func (tr *trace) reset() { tr.traceID = 0 tr.spanID = 0 tr.IsError = false + tr.maxEvents = 0 tr.events = nil tr.refs = 0 tr.recycler = nil tr.disc = 0 tr.finishStack = nil + for i := range tr.eventsBuf { + tr.eventsBuf[i] = event{} + } } // delta returns the elapsed time since the last event or the trace start, @@ -744,7 +752,7 @@ func (tr *trace) addEvent(x interface{}, recyclable, sensitive bool) { and very unlikely to be the fault of this code. The most likely scenario is that some code elsewhere is using - a requestz.Trace after its Finish method is called. + a trace.Trace after its Finish method is called. You can temporarily set the DebugUseAfterFinish var to help discover where that is; do not leave that var set, since it makes this package much less efficient. @@ -753,11 +761,11 @@ func (tr *trace) addEvent(x interface{}, recyclable, sensitive bool) { e := event{When: time.Now(), What: x, Recyclable: recyclable, Sensitive: sensitive} tr.mu.Lock() e.Elapsed, e.NewDay = tr.delta(e.When) - if len(tr.events) < cap(tr.events) { + if len(tr.events) < tr.maxEvents { tr.events = append(tr.events, e) } else { // Discard the middle events. - di := int((cap(tr.events) - 1) / 2) + di := int((tr.maxEvents - 1) / 2) if d, ok := tr.events[di].What.(*discarded); ok { (*d)++ } else { @@ -777,7 +785,7 @@ func (tr *trace) addEvent(x interface{}, recyclable, sensitive bool) { go tr.recycler(tr.events[di+1].What) } copy(tr.events[di+1:], tr.events[di+2:]) - tr.events[cap(tr.events)-1] = e + tr.events[tr.maxEvents-1] = e } tr.mu.Unlock() } @@ -803,7 +811,7 @@ func (tr *trace) SetTraceInfo(traceID, spanID uint64) { func (tr *trace) SetMaxEvents(m int) { // Always keep at least three events: first, discarded count, last. if len(tr.events) == 0 && m > 3 { - tr.events = make([]event, 0, m) + tr.maxEvents = m } } @@ -894,10 +902,18 @@ func elapsed(d time.Duration) string { return string(b) } -var pageTmpl = template.Must(template.New("Page").Funcs(template.FuncMap{ - "elapsed": elapsed, - "add": func(a, b int) int { return a + b }, -}).Parse(pageHTML)) +var pageTmplCache *template.Template +var pageTmplOnce sync.Once + +func pageTmpl() *template.Template { + pageTmplOnce.Do(func() { + pageTmplCache = template.Must(template.New("Page").Funcs(template.FuncMap{ + "elapsed": elapsed, + "add": func(a, b int) int { return a + b }, + }).Parse(pageHTML)) + }) + return pageTmplCache +} const pageHTML = ` {{template "Prolog" .}} diff --git a/vendor/golang.org/x/net/websocket/client.go b/vendor/golang.org/x/net/websocket/client.go index 20d1e1e38..69a4ac7ee 100644 --- a/vendor/golang.org/x/net/websocket/client.go +++ b/vendor/golang.org/x/net/websocket/client.go @@ -6,7 +6,6 @@ package websocket import ( "bufio" - "crypto/tls" "io" "net" "net/http" @@ -87,20 +86,14 @@ func DialConfig(config *Config) (ws *Conn, err error) { if config.Origin == nil { return nil, &DialError{config, ErrBadWebSocketOrigin} } - switch config.Location.Scheme { - case "ws": - client, err = net.Dial("tcp", parseAuthority(config.Location)) - - case "wss": - client, err = tls.Dial("tcp", parseAuthority(config.Location), config.TlsConfig) - - default: - err = ErrBadScheme + dialer := config.Dialer + if dialer == nil { + dialer = &net.Dialer{} } + client, err = dialWithDialer(dialer, config) if err != nil { goto Error } - ws, err = NewClient(config, client) if err != nil { client.Close() diff --git a/vendor/golang.org/x/net/websocket/dial.go b/vendor/golang.org/x/net/websocket/dial.go new file mode 100644 index 000000000..2dab943a4 --- /dev/null +++ b/vendor/golang.org/x/net/websocket/dial.go @@ -0,0 +1,24 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package websocket + +import ( + "crypto/tls" + "net" +) + +func dialWithDialer(dialer *net.Dialer, config *Config) (conn net.Conn, err error) { + switch config.Location.Scheme { + case "ws": + conn, err = dialer.Dial("tcp", parseAuthority(config.Location)) + + case "wss": + conn, err = tls.DialWithDialer(dialer, "tcp", parseAuthority(config.Location), config.TlsConfig) + + default: + err = ErrBadScheme + } + return +} diff --git a/vendor/golang.org/x/net/websocket/websocket.go b/vendor/golang.org/x/net/websocket/websocket.go index 9f9b9a52d..8d46bbd1e 100644 --- a/vendor/golang.org/x/net/websocket/websocket.go +++ b/vendor/golang.org/x/net/websocket/websocket.go @@ -4,6 +4,12 @@ // Package websocket implements a client and server for the WebSocket protocol // as specified in RFC 6455. +// +// This package currently lacks some features found in an alternative +// and more actively maintained WebSocket package: +// +// https://godoc.org/github.com/gorilla/websocket +// package websocket import ( @@ -32,6 +38,8 @@ const ( PingFrame = 9 PongFrame = 10 UnknownFrame = 255 + + DefaultMaxPayloadBytes = 32 << 20 // 32MB ) // ProtocolError represents WebSocket protocol errors. @@ -58,6 +66,10 @@ var ( ErrNotSupported = &ProtocolError{"not supported"} ) +// ErrFrameTooLarge is returned by Codec's Receive method if payload size +// exceeds limit set by Conn.MaxPayloadBytes +var ErrFrameTooLarge = errors.New("websocket: frame payload size exceeds limit") + // Addr is an implementation of net.Addr for WebSocket. type Addr struct { *url.URL @@ -86,6 +98,9 @@ type Config struct { // Additional header fields to be sent in WebSocket opening handshake. Header http.Header + // Dialer used when opening websocket connections. + Dialer *net.Dialer + handshakeData map[string]string } @@ -163,6 +178,10 @@ type Conn struct { frameHandler PayloadType byte defaultCloseStatus int + + // MaxPayloadBytes limits the size of frame payload received over Conn + // by Codec's Receive method. If zero, DefaultMaxPayloadBytes is used. + MaxPayloadBytes int } // Read implements the io.Reader interface: @@ -299,7 +318,12 @@ func (cd Codec) Send(ws *Conn, v interface{}) (err error) { return err } -// Receive receives single frame from ws, unmarshaled by cd.Unmarshal and stores in v. +// Receive receives single frame from ws, unmarshaled by cd.Unmarshal and stores +// in v. The whole frame payload is read to an in-memory buffer; max size of +// payload is defined by ws.MaxPayloadBytes. If frame payload size exceeds +// limit, ErrFrameTooLarge is returned; in this case frame is not read off wire +// completely. The next call to Receive would read and discard leftover data of +// previous oversized frame before processing next frame. func (cd Codec) Receive(ws *Conn, v interface{}) (err error) { ws.rio.Lock() defer ws.rio.Unlock() @@ -322,6 +346,19 @@ again: if frame == nil { goto again } + maxPayloadBytes := ws.MaxPayloadBytes + if maxPayloadBytes == 0 { + maxPayloadBytes = DefaultMaxPayloadBytes + } + if hf, ok := frame.(*hybiFrameReader); ok && hf.header.Length > int64(maxPayloadBytes) { + // payload size exceeds limit, no need to call Unmarshal + // + // set frameReader to current oversized frame so that + // the next call to this function can drain leftover + // data before processing the next frame + ws.frameReader = frame + return ErrFrameTooLarge + } payloadType := frame.PayloadType() data, err := ioutil.ReadAll(frame) if err != nil { diff --git a/vendor/golang.org/x/time/AUTHORS b/vendor/golang.org/x/time/AUTHORS new file mode 100644 index 000000000..15167cd74 --- /dev/null +++ b/vendor/golang.org/x/time/AUTHORS @@ -0,0 +1,3 @@ +# This source code refers to The Go Authors for copyright purposes. +# The master list of authors is in the main Go distribution, +# visible at http://tip.golang.org/AUTHORS. diff --git a/vendor/golang.org/x/time/CONTRIBUTORS b/vendor/golang.org/x/time/CONTRIBUTORS new file mode 100644 index 000000000..1c4577e96 --- /dev/null +++ b/vendor/golang.org/x/time/CONTRIBUTORS @@ -0,0 +1,3 @@ +# This source code was written by the Go contributors. +# The master list of contributors is in the main Go distribution, +# visible at http://tip.golang.org/CONTRIBUTORS. diff --git a/vendor/golang.org/x/time/LICENSE b/vendor/golang.org/x/time/LICENSE new file mode 100644 index 000000000..6a66aea5e --- /dev/null +++ b/vendor/golang.org/x/time/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2009 The Go Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/golang.org/x/time/PATENTS b/vendor/golang.org/x/time/PATENTS new file mode 100644 index 000000000..733099041 --- /dev/null +++ b/vendor/golang.org/x/time/PATENTS @@ -0,0 +1,22 @@ +Additional IP Rights Grant (Patents) + +"This implementation" means the copyrightable works distributed by +Google as part of the Go project. + +Google hereby grants to You a perpetual, worldwide, non-exclusive, +no-charge, royalty-free, irrevocable (except as stated in this section) +patent license to make, have made, use, offer to sell, sell, import, +transfer and otherwise run, modify and propagate the contents of this +implementation of Go, where such license applies only to those patent +claims, both currently owned or controlled by Google and acquired in +the future, licensable by Google that are necessarily infringed by this +implementation of Go. This grant does not include claims that would be +infringed only as a consequence of further modification of this +implementation. If you or your agent or exclusive licensee institute or +order or agree to the institution of patent litigation against any +entity (including a cross-claim or counterclaim in a lawsuit) alleging +that this implementation of Go or any code incorporated within this +implementation of Go constitutes direct or contributory patent +infringement, or inducement of patent infringement, then any patent +rights granted to you under this License for this implementation of Go +shall terminate as of the date such litigation is filed. diff --git a/vendor/golang.org/x/time/rate/rate.go b/vendor/golang.org/x/time/rate/rate.go new file mode 100644 index 000000000..938feaffe --- /dev/null +++ b/vendor/golang.org/x/time/rate/rate.go @@ -0,0 +1,371 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package rate provides a rate limiter. +package rate + +import ( + "fmt" + "math" + "sync" + "time" + + "golang.org/x/net/context" +) + +// Limit defines the maximum frequency of some events. +// Limit is represented as number of events per second. +// A zero Limit allows no events. +type Limit float64 + +// Inf is the infinite rate limit; it allows all events (even if burst is zero). +const Inf = Limit(math.MaxFloat64) + +// Every converts a minimum time interval between events to a Limit. +func Every(interval time.Duration) Limit { + if interval <= 0 { + return Inf + } + return 1 / Limit(interval.Seconds()) +} + +// A Limiter controls how frequently events are allowed to happen. +// It implements a "token bucket" of size b, initially full and refilled +// at rate r tokens per second. +// Informally, in any large enough time interval, the Limiter limits the +// rate to r tokens per second, with a maximum burst size of b events. +// As a special case, if r == Inf (the infinite rate), b is ignored. +// See https://en.wikipedia.org/wiki/Token_bucket for more about token buckets. +// +// The zero value is a valid Limiter, but it will reject all events. +// Use NewLimiter to create non-zero Limiters. +// +// Limiter has three main methods, Allow, Reserve, and Wait. +// Most callers should use Wait. +// +// Each of the three methods consumes a single token. +// They differ in their behavior when no token is available. +// If no token is available, Allow returns false. +// If no token is available, Reserve returns a reservation for a future token +// and the amount of time the caller must wait before using it. +// If no token is available, Wait blocks until one can be obtained +// or its associated context.Context is canceled. +// +// The methods AllowN, ReserveN, and WaitN consume n tokens. +type Limiter struct { + limit Limit + burst int + + mu sync.Mutex + tokens float64 + // last is the last time the limiter's tokens field was updated + last time.Time + // lastEvent is the latest time of a rate-limited event (past or future) + lastEvent time.Time +} + +// Limit returns the maximum overall event rate. +func (lim *Limiter) Limit() Limit { + lim.mu.Lock() + defer lim.mu.Unlock() + return lim.limit +} + +// Burst returns the maximum burst size. Burst is the maximum number of tokens +// that can be consumed in a single call to Allow, Reserve, or Wait, so higher +// Burst values allow more events to happen at once. +// A zero Burst allows no events, unless limit == Inf. +func (lim *Limiter) Burst() int { + return lim.burst +} + +// NewLimiter returns a new Limiter that allows events up to rate r and permits +// bursts of at most b tokens. +func NewLimiter(r Limit, b int) *Limiter { + return &Limiter{ + limit: r, + burst: b, + } +} + +// Allow is shorthand for AllowN(time.Now(), 1). +func (lim *Limiter) Allow() bool { + return lim.AllowN(time.Now(), 1) +} + +// AllowN reports whether n events may happen at time now. +// Use this method if you intend to drop / skip events that exceed the rate limit. +// Otherwise use Reserve or Wait. +func (lim *Limiter) AllowN(now time.Time, n int) bool { + return lim.reserveN(now, n, 0).ok +} + +// A Reservation holds information about events that are permitted by a Limiter to happen after a delay. +// A Reservation may be canceled, which may enable the Limiter to permit additional events. +type Reservation struct { + ok bool + lim *Limiter + tokens int + timeToAct time.Time + // This is the Limit at reservation time, it can change later. + limit Limit +} + +// OK returns whether the limiter can provide the requested number of tokens +// within the maximum wait time. If OK is false, Delay returns InfDuration, and +// Cancel does nothing. +func (r *Reservation) OK() bool { + return r.ok +} + +// Delay is shorthand for DelayFrom(time.Now()). +func (r *Reservation) Delay() time.Duration { + return r.DelayFrom(time.Now()) +} + +// InfDuration is the duration returned by Delay when a Reservation is not OK. +const InfDuration = time.Duration(1<<63 - 1) + +// DelayFrom returns the duration for which the reservation holder must wait +// before taking the reserved action. Zero duration means act immediately. +// InfDuration means the limiter cannot grant the tokens requested in this +// Reservation within the maximum wait time. +func (r *Reservation) DelayFrom(now time.Time) time.Duration { + if !r.ok { + return InfDuration + } + delay := r.timeToAct.Sub(now) + if delay < 0 { + return 0 + } + return delay +} + +// Cancel is shorthand for CancelAt(time.Now()). +func (r *Reservation) Cancel() { + r.CancelAt(time.Now()) + return +} + +// CancelAt indicates that the reservation holder will not perform the reserved action +// and reverses the effects of this Reservation on the rate limit as much as possible, +// considering that other reservations may have already been made. +func (r *Reservation) CancelAt(now time.Time) { + if !r.ok { + return + } + + r.lim.mu.Lock() + defer r.lim.mu.Unlock() + + if r.lim.limit == Inf || r.tokens == 0 || r.timeToAct.Before(now) { + return + } + + // calculate tokens to restore + // The duration between lim.lastEvent and r.timeToAct tells us how many tokens were reserved + // after r was obtained. These tokens should not be restored. + restoreTokens := float64(r.tokens) - r.limit.tokensFromDuration(r.lim.lastEvent.Sub(r.timeToAct)) + if restoreTokens <= 0 { + return + } + // advance time to now + now, _, tokens := r.lim.advance(now) + // calculate new number of tokens + tokens += restoreTokens + if burst := float64(r.lim.burst); tokens > burst { + tokens = burst + } + // update state + r.lim.last = now + r.lim.tokens = tokens + if r.timeToAct == r.lim.lastEvent { + prevEvent := r.timeToAct.Add(r.limit.durationFromTokens(float64(-r.tokens))) + if !prevEvent.Before(now) { + r.lim.lastEvent = prevEvent + } + } + + return +} + +// Reserve is shorthand for ReserveN(time.Now(), 1). +func (lim *Limiter) Reserve() *Reservation { + return lim.ReserveN(time.Now(), 1) +} + +// ReserveN returns a Reservation that indicates how long the caller must wait before n events happen. +// The Limiter takes this Reservation into account when allowing future events. +// ReserveN returns false if n exceeds the Limiter's burst size. +// Usage example: +// r := lim.ReserveN(time.Now(), 1) +// if !r.OK() { +// // Not allowed to act! Did you remember to set lim.burst to be > 0 ? +// return +// } +// time.Sleep(r.Delay()) +// Act() +// Use this method if you wish to wait and slow down in accordance with the rate limit without dropping events. +// If you need to respect a deadline or cancel the delay, use Wait instead. +// To drop or skip events exceeding rate limit, use Allow instead. +func (lim *Limiter) ReserveN(now time.Time, n int) *Reservation { + r := lim.reserveN(now, n, InfDuration) + return &r +} + +// Wait is shorthand for WaitN(ctx, 1). +func (lim *Limiter) Wait(ctx context.Context) (err error) { + return lim.WaitN(ctx, 1) +} + +// WaitN blocks until lim permits n events to happen. +// It returns an error if n exceeds the Limiter's burst size, the Context is +// canceled, or the expected wait time exceeds the Context's Deadline. +// The burst limit is ignored if the rate limit is Inf. +func (lim *Limiter) WaitN(ctx context.Context, n int) (err error) { + if n > lim.burst && lim.limit != Inf { + return fmt.Errorf("rate: Wait(n=%d) exceeds limiter's burst %d", n, lim.burst) + } + // Check if ctx is already cancelled + select { + case <-ctx.Done(): + return ctx.Err() + default: + } + // Determine wait limit + now := time.Now() + waitLimit := InfDuration + if deadline, ok := ctx.Deadline(); ok { + waitLimit = deadline.Sub(now) + } + // Reserve + r := lim.reserveN(now, n, waitLimit) + if !r.ok { + return fmt.Errorf("rate: Wait(n=%d) would exceed context deadline", n) + } + // Wait + t := time.NewTimer(r.DelayFrom(now)) + defer t.Stop() + select { + case <-t.C: + // We can proceed. + return nil + case <-ctx.Done(): + // Context was canceled before we could proceed. Cancel the + // reservation, which may permit other events to proceed sooner. + r.Cancel() + return ctx.Err() + } +} + +// SetLimit is shorthand for SetLimitAt(time.Now(), newLimit). +func (lim *Limiter) SetLimit(newLimit Limit) { + lim.SetLimitAt(time.Now(), newLimit) +} + +// SetLimitAt sets a new Limit for the limiter. The new Limit, and Burst, may be violated +// or underutilized by those which reserved (using Reserve or Wait) but did not yet act +// before SetLimitAt was called. +func (lim *Limiter) SetLimitAt(now time.Time, newLimit Limit) { + lim.mu.Lock() + defer lim.mu.Unlock() + + now, _, tokens := lim.advance(now) + + lim.last = now + lim.tokens = tokens + lim.limit = newLimit +} + +// reserveN is a helper method for AllowN, ReserveN, and WaitN. +// maxFutureReserve specifies the maximum reservation wait duration allowed. +// reserveN returns Reservation, not *Reservation, to avoid allocation in AllowN and WaitN. +func (lim *Limiter) reserveN(now time.Time, n int, maxFutureReserve time.Duration) Reservation { + lim.mu.Lock() + + if lim.limit == Inf { + lim.mu.Unlock() + return Reservation{ + ok: true, + lim: lim, + tokens: n, + timeToAct: now, + } + } + + now, last, tokens := lim.advance(now) + + // Calculate the remaining number of tokens resulting from the request. + tokens -= float64(n) + + // Calculate the wait duration + var waitDuration time.Duration + if tokens < 0 { + waitDuration = lim.limit.durationFromTokens(-tokens) + } + + // Decide result + ok := n <= lim.burst && waitDuration <= maxFutureReserve + + // Prepare reservation + r := Reservation{ + ok: ok, + lim: lim, + limit: lim.limit, + } + if ok { + r.tokens = n + r.timeToAct = now.Add(waitDuration) + } + + // Update state + if ok { + lim.last = now + lim.tokens = tokens + lim.lastEvent = r.timeToAct + } else { + lim.last = last + } + + lim.mu.Unlock() + return r +} + +// advance calculates and returns an updated state for lim resulting from the passage of time. +// lim is not changed. +func (lim *Limiter) advance(now time.Time) (newNow time.Time, newLast time.Time, newTokens float64) { + last := lim.last + if now.Before(last) { + last = now + } + + // Avoid making delta overflow below when last is very old. + maxElapsed := lim.limit.durationFromTokens(float64(lim.burst) - lim.tokens) + elapsed := now.Sub(last) + if elapsed > maxElapsed { + elapsed = maxElapsed + } + + // Calculate the new number of tokens, due to time that passed. + delta := lim.limit.tokensFromDuration(elapsed) + tokens := lim.tokens + delta + if burst := float64(lim.burst); tokens > burst { + tokens = burst + } + + return now, last, tokens +} + +// durationFromTokens is a unit conversion function from the number of tokens to the duration +// of time it takes to accumulate them at a rate of limit tokens per second. +func (limit Limit) durationFromTokens(tokens float64) time.Duration { + seconds := tokens / float64(limit) + return time.Nanosecond * time.Duration(1e9*seconds) +} + +// tokensFromDuration is a unit conversion function from a time duration to the number of tokens +// which could be accumulated during that duration at a rate of limit tokens per second. +func (limit Limit) tokensFromDuration(d time.Duration) float64 { + return d.Seconds() * float64(limit) +} diff --git a/vendor/google.golang.org/grpc/.travis.yml b/vendor/google.golang.org/grpc/.travis.yml index d7108cd64..0c1a96c68 100644 --- a/vendor/google.golang.org/grpc/.travis.yml +++ b/vendor/google.golang.org/grpc/.travis.yml @@ -3,19 +3,17 @@ language: go go: - 1.5.4 - 1.6.3 + - 1.7 go_import_path: google.golang.org/grpc before_install: - - go get golang.org/x/tools/cmd/goimports - - go get github.com/golang/lint/golint - - go get github.com/axw/gocov/gocov - - go get github.com/mattn/goveralls - - go get golang.org/x/tools/cmd/cover + - if [[ $TRAVIS_GO_VERSION != 1.5* ]]; then go get github.com/golang/lint/golint; fi + - go get -u golang.org/x/tools/cmd/goimports github.com/axw/gocov/gocov github.com/mattn/goveralls golang.org/x/tools/cmd/cover script: - '! gofmt -s -d -l . 2>&1 | read' - '! goimports -l . | read' - - '! golint ./... | grep -vE "(_string|\.pb)\.go:"' - - '! go tool vet -all . 2>&1 | grep -vE "constant [0-9]+ not a string in call to Errorf"' + - 'if [[ $TRAVIS_GO_VERSION != 1.5* ]]; then ! golint ./... | grep -vE "(_string|\.pb)\.go:"; fi' + - '! go tool vet -all . 2>&1 | grep -vE "constant [0-9]+ not a string in call to Errorf" | grep -vF .pb.go:' # https://github.com/golang/protobuf/issues/214 - make test testrace diff --git a/vendor/google.golang.org/grpc/README.md b/vendor/google.golang.org/grpc/README.md index 90e9453d5..110a8cf42 100644 --- a/vendor/google.golang.org/grpc/README.md +++ b/vendor/google.golang.org/grpc/README.md @@ -16,7 +16,7 @@ $ go get google.golang.org/grpc Prerequisites ------------- -This requires Go 1.5 or later . +This requires Go 1.5 or later. Constraints ----------- @@ -28,5 +28,5 @@ See [API documentation](https://godoc.org/google.golang.org/grpc) for package an Status ------ -Beta release +GA diff --git a/vendor/google.golang.org/grpc/backoff.go b/vendor/google.golang.org/grpc/backoff.go index 52f4f10fc..c99024ee3 100644 --- a/vendor/google.golang.org/grpc/backoff.go +++ b/vendor/google.golang.org/grpc/backoff.go @@ -58,7 +58,7 @@ func setDefaults(bc *BackoffConfig) { } } -func (bc BackoffConfig) backoff(retries int) (t time.Duration) { +func (bc BackoffConfig) backoff(retries int) time.Duration { if retries == 0 { return bc.baseDelay } diff --git a/vendor/google.golang.org/grpc/balancer.go b/vendor/google.golang.org/grpc/balancer.go index 419e21461..9d943fbad 100644 --- a/vendor/google.golang.org/grpc/balancer.go +++ b/vendor/google.golang.org/grpc/balancer.go @@ -38,6 +38,8 @@ import ( "sync" "golang.org/x/net/context" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/credentials" "google.golang.org/grpc/grpclog" "google.golang.org/grpc/naming" ) @@ -52,6 +54,14 @@ type Address struct { Metadata interface{} } +// BalancerConfig specifies the configurations for Balancer. +type BalancerConfig struct { + // DialCreds is the transport credential the Balancer implementation can + // use to dial to a remote load balancer server. The Balancer implementations + // can ignore this if it does not need to talk to another party securely. + DialCreds credentials.TransportCredentials +} + // BalancerGetOptions configures a Get call. // This is the EXPERIMENTAL API and may be changed or extended in the future. type BalancerGetOptions struct { @@ -66,11 +76,11 @@ type Balancer interface { // Start does the initialization work to bootstrap a Balancer. For example, // this function may start the name resolution and watch the updates. It will // be called when dialing. - Start(target string) error + Start(target string, config BalancerConfig) error // Up informs the Balancer that gRPC has a connection to the server at // addr. It returns down which is called once the connection to addr gets // lost or closed. - // TODO: It is not clear how to construct and take advantage the meaningful error + // TODO: It is not clear how to construct and take advantage of the meaningful error // parameter for down. Need realistic demands to guide. Up(addr Address) (down func(error)) // Get gets the address of a server for the RPC corresponding to ctx. @@ -205,7 +215,12 @@ func (rr *roundRobin) watchAddrUpdates() error { return nil } -func (rr *roundRobin) Start(target string) error { +func (rr *roundRobin) Start(target string, config BalancerConfig) error { + rr.mu.Lock() + defer rr.mu.Unlock() + if rr.done { + return ErrClientConnClosing + } if rr.r == nil { // If there is no name resolver installed, it is not needed to // do name resolution. In this case, target is added into rr.addrs @@ -301,7 +316,7 @@ func (rr *roundRobin) Get(ctx context.Context, opts BalancerGetOptions) (addr Ad if !opts.BlockingWait { if len(rr.addrs) == 0 { rr.mu.Unlock() - err = fmt.Errorf("there is no address available") + err = Errorf(codes.Unavailable, "there is no address available") return } // Returns the next addr on rr.addrs for failfast RPCs. diff --git a/vendor/google.golang.org/grpc/call.go b/vendor/google.golang.org/grpc/call.go index fea07998d..772c817ed 100644 --- a/vendor/google.golang.org/grpc/call.go +++ b/vendor/google.golang.org/grpc/call.go @@ -49,9 +49,8 @@ import ( // On error, it returns the error and indicates whether the call should be retried. // // TODO(zhaoq): Check whether the received message sequence is valid. -func recvResponse(dopts dialOptions, t transport.ClientTransport, c *callInfo, stream *transport.Stream, reply interface{}) error { +func recvResponse(dopts dialOptions, t transport.ClientTransport, c *callInfo, stream *transport.Stream, reply interface{}) (err error) { // Try to acquire header metadata from the server if there is any. - var err error defer func() { if err != nil { if _, ok := err.(transport.ConnectionError); !ok { @@ -61,7 +60,7 @@ func recvResponse(dopts dialOptions, t transport.ClientTransport, c *callInfo, s }() c.headerMD, err = stream.Header() if err != nil { - return err + return } p := &parser{r: stream} for { @@ -69,7 +68,7 @@ func recvResponse(dopts dialOptions, t transport.ClientTransport, c *callInfo, s if err == io.EOF { break } - return err + return } } c.trailerMD = stream.Trailer() @@ -96,7 +95,7 @@ func sendRequest(ctx context.Context, codec Codec, compressor Compressor, callHd } outBuf, err := encode(codec, args, compressor, cbuf) if err != nil { - return nil, transport.StreamErrorf(codes.Internal, "grpc: %v", err) + return nil, Errorf(codes.Internal, "grpc: %v", err) } err = t.Write(stream, outBuf, opts) // t.NewStream(...) could lead to an early rejection of the RPC (e.g., the service/method @@ -112,7 +111,14 @@ func sendRequest(ctx context.Context, codec Codec, compressor Compressor, callHd // Invoke sends the RPC request on the wire and returns after response is received. // Invoke is called by generated code. Also users can call Invoke directly when it // is really needed in their use cases. -func Invoke(ctx context.Context, method string, args, reply interface{}, cc *ClientConn, opts ...CallOption) (err error) { +func Invoke(ctx context.Context, method string, args, reply interface{}, cc *ClientConn, opts ...CallOption) error { + if cc.dopts.unaryInt != nil { + return cc.dopts.unaryInt(ctx, method, args, reply, cc, invoke, opts...) + } + return invoke(ctx, method, args, reply, cc, opts...) +} + +func invoke(ctx context.Context, method string, args, reply interface{}, cc *ClientConn, opts ...CallOption) (err error) { c := defaultCallInfo for _, o := range opts { if err := o.before(&c); err != nil { diff --git a/vendor/google.golang.org/grpc/clientconn.go b/vendor/google.golang.org/grpc/clientconn.go index 27e74e6f2..61674729a 100644 --- a/vendor/google.golang.org/grpc/clientconn.go +++ b/vendor/google.golang.org/grpc/clientconn.go @@ -83,15 +83,17 @@ var ( // dialOptions configure a Dial call. dialOptions are set by the DialOption // values passed to Dial. type dialOptions struct { - codec Codec - cp Compressor - dc Decompressor - bs backoffStrategy - balancer Balancer - block bool - insecure bool - timeout time.Duration - copts transport.ConnectOptions + unaryInt UnaryClientInterceptor + streamInt StreamClientInterceptor + codec Codec + cp Compressor + dc Decompressor + bs backoffStrategy + balancer Balancer + block bool + insecure bool + timeout time.Duration + copts transport.ConnectOptions } // DialOption configures how we set up the connection. @@ -215,19 +217,48 @@ func WithUserAgent(s string) DialOption { } } +// WithUnaryInterceptor returns a DialOption that specifies the interceptor for unary RPCs. +func WithUnaryInterceptor(f UnaryClientInterceptor) DialOption { + return func(o *dialOptions) { + o.unaryInt = f + } +} + +// WithStreamInterceptor returns a DialOption that specifies the interceptor for streaming RPCs. +func WithStreamInterceptor(f StreamClientInterceptor) DialOption { + return func(o *dialOptions) { + o.streamInt = f + } +} + // Dial creates a client connection to the given target. func Dial(target string, opts ...DialOption) (*ClientConn, error) { return DialContext(context.Background(), target, opts...) } -// DialContext creates a client connection to the given target -// using the supplied context. -func DialContext(ctx context.Context, target string, opts ...DialOption) (*ClientConn, error) { +// DialContext creates a client connection to the given target. ctx can be used to +// cancel or expire the pending connecting. Once this function returns, the +// cancellation and expiration of ctx will be noop. Users should call ClientConn.Close +// to terminate all the pending operations after this function returns. +// This is the EXPERIMENTAL API. +func DialContext(ctx context.Context, target string, opts ...DialOption) (conn *ClientConn, err error) { cc := &ClientConn{ target: target, conns: make(map[Address]*addrConn), } - cc.ctx, cc.cancel = context.WithCancel(ctx) + cc.ctx, cc.cancel = context.WithCancel(context.Background()) + defer func() { + select { + case <-ctx.Done(): + conn, err = nil, ctx.Err() + default: + } + + if err != nil { + cc.Close() + } + }() + for _, opt := range opts { opt(&cc.dopts) } @@ -239,31 +270,47 @@ func DialContext(ctx context.Context, target string, opts ...DialOption) (*Clien if cc.dopts.bs == nil { cc.dopts.bs = DefaultBackoffConfig } - - var ( - ok bool - addrs []Address - ) - if cc.dopts.balancer == nil { - // Connect to target directly if balancer is nil. - addrs = append(addrs, Address{Addr: target}) + creds := cc.dopts.copts.TransportCredentials + if creds != nil && creds.Info().ServerName != "" { + cc.authority = creds.Info().ServerName } else { - if err := cc.dopts.balancer.Start(target); err != nil { - return nil, err - } - ch := cc.dopts.balancer.Notify() - if ch == nil { - // There is no name resolver installed. - addrs = append(addrs, Address{Addr: target}) - } else { - addrs, ok = <-ch - if !ok || len(addrs) == 0 { - return nil, errNoAddr - } + colonPos := strings.LastIndex(target, ":") + if colonPos == -1 { + colonPos = len(target) } + cc.authority = target[:colonPos] } + var ok bool waitC := make(chan error, 1) go func() { + var addrs []Address + if cc.dopts.balancer == nil { + // Connect to target directly if balancer is nil. + addrs = append(addrs, Address{Addr: target}) + } else { + var credsClone credentials.TransportCredentials + if creds != nil { + credsClone = creds.Clone() + } + config := BalancerConfig{ + DialCreds: credsClone, + } + if err := cc.dopts.balancer.Start(target, config); err != nil { + waitC <- err + return + } + ch := cc.dopts.balancer.Notify() + if ch == nil { + // There is no name resolver installed. + addrs = append(addrs, Address{Addr: target}) + } else { + addrs, ok = <-ch + if !ok || len(addrs) == 0 { + waitC <- errNoAddr + return + } + } + } for _, a := range addrs { if err := cc.resetAddrConn(a, false, nil); err != nil { waitC <- err @@ -277,16 +324,13 @@ func DialContext(ctx context.Context, target string, opts ...DialOption) (*Clien timeoutCh = time.After(cc.dopts.timeout) } select { + case <-ctx.Done(): + return nil, ctx.Err() case err := <-waitC: if err != nil { - cc.Close() return nil, err } - case <-cc.ctx.Done(): - cc.Close() - return nil, cc.ctx.Err() case <-timeoutCh: - cc.Close() return nil, ErrClientConnTimeout } // If balancer is nil or balancer.Notify() is nil, ok will be false here. @@ -294,11 +338,6 @@ func DialContext(ctx context.Context, target string, opts ...DialOption) (*Clien if ok { go cc.lbWatcher() } - colonPos := strings.LastIndex(target, ":") - if colonPos == -1 { - colonPos = len(target) - } - cc.authority = target[:colonPos] return cc, nil } @@ -645,14 +684,18 @@ func (ac *addrConn) resetTransport(closeTransport bool) error { } ctx, cancel := context.WithTimeout(ac.ctx, timeout) connectTime := time.Now() - newTransport, err := transport.NewClientTransport(ctx, ac.addr.Addr, ac.dopts.copts) + sinfo := transport.TargetInfo{ + Addr: ac.addr.Addr, + Metadata: ac.addr.Metadata, + } + newTransport, err := transport.NewClientTransport(ctx, sinfo, ac.dopts.copts) if err != nil { cancel() if e, ok := err.(transport.ConnectionError); ok && !e.Temporary() { return err } - grpclog.Printf("grpc: addrConn.resetTransport failed to create client transport: %v; Reconnecting to %q", err, ac.addr) + grpclog.Printf("grpc: addrConn.resetTransport failed to create client transport: %v; Reconnecting to %v", err, ac.addr) ac.mu.Lock() if ac.state == Shutdown { // ac.tearDown(...) has been invoked. @@ -764,7 +807,7 @@ func (ac *addrConn) transportMonitor() { } // wait blocks until i) the new transport is up or ii) ctx is done or iii) ac is closed or -// iv) transport is in TransientFailure and there's no balancer/failfast is true. +// iv) transport is in TransientFailure and there is a balancer/failfast is true. func (ac *addrConn) wait(ctx context.Context, hasBalancer, failfast bool) (transport.ClientTransport, error) { for { ac.mu.Lock() diff --git a/vendor/google.golang.org/grpc/credentials/credentials.go b/vendor/google.golang.org/grpc/credentials/credentials.go index 001f134d7..4154f1eeb 100644 --- a/vendor/google.golang.org/grpc/credentials/credentials.go +++ b/vendor/google.golang.org/grpc/credentials/credentials.go @@ -40,6 +40,7 @@ package credentials import ( "crypto/tls" "crypto/x509" + "errors" "fmt" "io/ioutil" "net" @@ -71,7 +72,7 @@ type PerRPCCredentials interface { } // ProtocolInfo provides information regarding the gRPC wire protocol version, -// security protocol, security protocol version in use, etc. +// security protocol, security protocol version in use, server name, etc. type ProtocolInfo struct { // ProtocolVersion is the gRPC wire protocol version. ProtocolVersion string @@ -79,6 +80,8 @@ type ProtocolInfo struct { SecurityProtocol string // SecurityVersion is the security protocol version. SecurityVersion string + // ServerName is the user-configured server name. + ServerName string } // AuthInfo defines the common interface for the auth information the users are interested in. @@ -86,6 +89,12 @@ type AuthInfo interface { AuthType() string } +var ( + // ErrConnDispatched indicates that rawConn has been dispatched out of gRPC + // and the caller should not close rawConn. + ErrConnDispatched = errors.New("credentials: rawConn is dispatched out of gRPC") +) + // TransportCredentials defines the common interface for all the live gRPC wire // protocols and supported transport security protocols (e.g., TLS, SSL). type TransportCredentials interface { @@ -100,6 +109,12 @@ type TransportCredentials interface { ServerHandshake(net.Conn) (net.Conn, AuthInfo, error) // Info provides the ProtocolInfo of this TransportCredentials. Info() ProtocolInfo + // Clone makes a copy of this TransportCredentials. + Clone() TransportCredentials + // OverrideServerName overrides the server name used to verify the hostname on the returned certificates from the server. + // gRPC internals also use it to override the virtual hosting name if it is set. + // It must be called before dialing. Currently, this is only used by grpclb. + OverrideServerName(string) error } // TLSInfo contains the auth information for a TLS authenticated connection. @@ -123,19 +138,10 @@ func (c tlsCreds) Info() ProtocolInfo { return ProtocolInfo{ SecurityProtocol: "tls", SecurityVersion: "1.2", + ServerName: c.config.ServerName, } } -// GetRequestMetadata returns nil, nil since TLS credentials does not have -// metadata. -func (c *tlsCreds) GetRequestMetadata(ctx context.Context, uri ...string) (map[string]string, error) { - return nil, nil -} - -func (c *tlsCreds) RequireTransportSecurity() bool { - return true -} - func (c *tlsCreds) ClientHandshake(ctx context.Context, addr string, rawConn net.Conn) (_ net.Conn, _ AuthInfo, err error) { // use local cfg to avoid clobbering ServerName if using multiple endpoints cfg := cloneTLSConfig(c.config) @@ -172,6 +178,15 @@ func (c *tlsCreds) ServerHandshake(rawConn net.Conn) (net.Conn, AuthInfo, error) return conn, TLSInfo{conn.ConnectionState()}, nil } +func (c *tlsCreds) Clone() TransportCredentials { + return NewTLS(c.config) +} + +func (c *tlsCreds) OverrideServerName(serverNameOverride string) error { + c.config.ServerName = serverNameOverride + return nil +} + // NewTLS uses c to construct a TransportCredentials based on TLS. func NewTLS(c *tls.Config) TransportCredentials { tc := &tlsCreds{cloneTLSConfig(c)} @@ -180,12 +195,16 @@ func NewTLS(c *tls.Config) TransportCredentials { } // NewClientTLSFromCert constructs a TLS from the input certificate for client. -func NewClientTLSFromCert(cp *x509.CertPool, serverName string) TransportCredentials { - return NewTLS(&tls.Config{ServerName: serverName, RootCAs: cp}) +// serverNameOverride is for testing only. If set to a non empty string, +// it will override the virtual host name of authority (e.g. :authority header field) in requests. +func NewClientTLSFromCert(cp *x509.CertPool, serverNameOverride string) TransportCredentials { + return NewTLS(&tls.Config{ServerName: serverNameOverride, RootCAs: cp}) } // NewClientTLSFromFile constructs a TLS from the input certificate file for client. -func NewClientTLSFromFile(certFile, serverName string) (TransportCredentials, error) { +// serverNameOverride is for testing only. If set to a non empty string, +// it will override the virtual host name of authority (e.g. :authority header field) in requests. +func NewClientTLSFromFile(certFile, serverNameOverride string) (TransportCredentials, error) { b, err := ioutil.ReadFile(certFile) if err != nil { return nil, err @@ -194,7 +213,7 @@ func NewClientTLSFromFile(certFile, serverName string) (TransportCredentials, er if !cp.AppendCertsFromPEM(b) { return nil, fmt.Errorf("credentials: failed to append certificates") } - return NewTLS(&tls.Config{ServerName: serverName, RootCAs: cp}), nil + return NewTLS(&tls.Config{ServerName: serverNameOverride, RootCAs: cp}), nil } // NewServerTLSFromCert constructs a TLS from the input certificate for server. diff --git a/vendor/google.golang.org/grpc/interceptor.go b/vendor/google.golang.org/grpc/interceptor.go index 588f59e5a..8d932efed 100644 --- a/vendor/google.golang.org/grpc/interceptor.go +++ b/vendor/google.golang.org/grpc/interceptor.go @@ -37,6 +37,22 @@ import ( "golang.org/x/net/context" ) +// UnaryInvoker is called by UnaryClientInterceptor to complete RPCs. +type UnaryInvoker func(ctx context.Context, method string, req, reply interface{}, cc *ClientConn, opts ...CallOption) error + +// UnaryClientInterceptor intercepts the execution of a unary RPC on the client. inovker is the handler to complete the RPC +// and it is the responsibility of the interceptor to call it. +// This is the EXPERIMENTAL API. +type UnaryClientInterceptor func(ctx context.Context, method string, req, reply interface{}, cc *ClientConn, invoker UnaryInvoker, opts ...CallOption) error + +// Streamer is called by StreamClientInterceptor to create a ClientStream. +type Streamer func(ctx context.Context, desc *StreamDesc, cc *ClientConn, method string, opts ...CallOption) (ClientStream, error) + +// StreamClientInterceptor intercepts the creation of ClientStream. It may return a custom ClientStream to intercept all I/O +// operations. streamer is the handlder to create a ClientStream and it is the responsibility of the interceptor to call it. +// This is the EXPERIMENTAL API. +type StreamClientInterceptor func(ctx context.Context, desc *StreamDesc, cc *ClientConn, method string, streamer Streamer, opts ...CallOption) (ClientStream, error) + // UnaryServerInfo consists of various information about a unary RPC on // server side. All per-rpc information may be mutated by the interceptor. type UnaryServerInfo struct { diff --git a/vendor/google.golang.org/grpc/metadata/metadata.go b/vendor/google.golang.org/grpc/metadata/metadata.go index b32001568..cb29bf945 100644 --- a/vendor/google.golang.org/grpc/metadata/metadata.go +++ b/vendor/google.golang.org/grpc/metadata/metadata.go @@ -117,10 +117,17 @@ func (md MD) Len() int { // Copy returns a copy of md. func (md MD) Copy() MD { + return Join(md) +} + +// Join joins any number of MDs into a single MD. +// The order of values for each key is determined by the order in which +// the MDs containing those values are presented to Join. +func Join(mds ...MD) MD { out := MD{} - for k, v := range md { - for _, i := range v { - out[k] = append(out[k], i) + for _, md := range mds { + for k, v := range md { + out[k] = append(out[k], v...) } } return out diff --git a/vendor/google.golang.org/grpc/rpc_util.go b/vendor/google.golang.org/grpc/rpc_util.go index 35ac9cc7b..a25eaa8a2 100644 --- a/vendor/google.golang.org/grpc/rpc_util.go +++ b/vendor/google.golang.org/grpc/rpc_util.go @@ -303,10 +303,10 @@ func checkRecvPayload(pf payloadFormat, recvCompress string, dc Decompressor) er case compressionNone: case compressionMade: if dc == nil || recvCompress != dc.Type() { - return transport.StreamErrorf(codes.Unimplemented, "grpc: Decompressor is not installed for grpc-encoding %q", recvCompress) + return Errorf(codes.Unimplemented, "grpc: Decompressor is not installed for grpc-encoding %q", recvCompress) } default: - return transport.StreamErrorf(codes.Internal, "grpc: received unexpected payload format %d", pf) + return Errorf(codes.Internal, "grpc: received unexpected payload format %d", pf) } return nil } @@ -448,10 +448,10 @@ func convertCode(err error) codes.Code { return codes.Unknown } -// SupportPackageIsVersion3 is referenced from generated protocol buffer files +// SupportPackageIsVersion4 is referenced from generated protocol buffer files // to assert that that code is compatible with this version of the grpc package. // // This constant may be renamed in the future if a change in the generated code // requires a synchronised update of grpc-go and protoc-gen-go. This constant // should not be referenced from any other code. -const SupportPackageIsVersion3 = true +const SupportPackageIsVersion4 = true diff --git a/vendor/google.golang.org/grpc/server.go b/vendor/google.golang.org/grpc/server.go index 1ed8aac9e..e0bb187ef 100644 --- a/vendor/google.golang.org/grpc/server.go +++ b/vendor/google.golang.org/grpc/server.go @@ -89,10 +89,12 @@ type service struct { type Server struct { opts options - mu sync.Mutex // guards following - lis map[net.Listener]bool - conns map[io.Closer]bool - drain bool + mu sync.Mutex // guards following + lis map[net.Listener]bool + conns map[io.Closer]bool + drain bool + ctx context.Context + cancel context.CancelFunc // A CondVar to let GracefulStop() blocks until all the pending RPCs are finished // and all the transport goes away. cv *sync.Cond @@ -203,6 +205,7 @@ func NewServer(opt ...ServerOption) *Server { m: make(map[string]*service), } s.cv = sync.NewCond(&s.mu) + s.ctx, s.cancel = context.WithCancel(context.Background()) if EnableTracing { _, file, line, _ := runtime.Caller(1) s.events = trace.NewEventLog("grpc.Server", fmt.Sprintf("%s:%d", file, line)) @@ -324,7 +327,7 @@ func (s *Server) useTransportAuthenticator(rawConn net.Conn) (net.Conn, credenti // Serve accepts incoming connections on the listener lis, creating a new // ServerTransport and service goroutine for each. The service goroutines // read gRPC requests and then call the registered handlers to reply to them. -// Service returns when lis.Accept fails. lis will be closed when +// Serve returns when lis.Accept fails with fatal errors. lis will be closed when // this method returns. func (s *Server) Serve(lis net.Listener) error { s.mu.Lock() @@ -344,14 +347,38 @@ func (s *Server) Serve(lis net.Listener) error { } s.mu.Unlock() }() + + var tempDelay time.Duration // how long to sleep on accept failure + for { rawConn, err := lis.Accept() if err != nil { + if ne, ok := err.(interface { + Temporary() bool + }); ok && ne.Temporary() { + if tempDelay == 0 { + tempDelay = 5 * time.Millisecond + } else { + tempDelay *= 2 + } + if max := 1 * time.Second; tempDelay > max { + tempDelay = max + } + s.mu.Lock() + s.printf("Accept error: %v; retrying in %v", err, tempDelay) + s.mu.Unlock() + select { + case <-time.After(tempDelay): + case <-s.ctx.Done(): + } + continue + } s.mu.Lock() s.printf("done serving; Accept = %v", err) s.mu.Unlock() return err } + tempDelay = 0 // Start a new goroutine to deal with rawConn // so we don't stall this Accept loop goroutine. go s.handleRawConn(rawConn) @@ -367,7 +394,10 @@ func (s *Server) handleRawConn(rawConn net.Conn) { s.errorf("ServerHandshake(%q) failed: %v", rawConn.RemoteAddr(), err) s.mu.Unlock() grpclog.Printf("grpc: Server.Serve failed to complete security handshake from %q: %v", rawConn.RemoteAddr(), err) - rawConn.Close() + // If serverHandShake returns ErrConnDispatched, keep rawConn open. + if err != credentials.ErrConnDispatched { + rawConn.Close() + } return } @@ -497,7 +527,7 @@ func (s *Server) removeConn(c io.Closer) { defer s.mu.Unlock() if s.conns != nil { delete(s.conns, c) - s.cv.Signal() + s.cv.Broadcast() } } @@ -544,7 +574,7 @@ func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport. return err } if err == io.ErrUnexpectedEOF { - err = transport.StreamError{Code: codes.Internal, Desc: "io.ErrUnexpectedEOF"} + err = Errorf(codes.Internal, io.ErrUnexpectedEOF.Error()) } if err != nil { switch err := err.(type) { @@ -566,8 +596,8 @@ func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport. if err := checkRecvPayload(pf, stream.RecvCompress(), s.opts.dc); err != nil { switch err := err.(type) { - case transport.StreamError: - if err := t.WriteStatus(stream, err.Code, err.Desc); err != nil { + case *rpcError: + if err := t.WriteStatus(stream, err.code, err.desc); err != nil { grpclog.Printf("grpc: Server.processUnaryRPC failed to write status %v", err) } default: @@ -798,7 +828,7 @@ func (s *Server) Stop() { st := s.conns s.conns = nil // interrupt GracefulStop if Stop and GracefulStop are called concurrently. - s.cv.Signal() + s.cv.Broadcast() s.mu.Unlock() for lis := range listeners { @@ -809,6 +839,7 @@ func (s *Server) Stop() { } s.mu.Lock() + s.cancel() if s.events != nil { s.events.Finish() s.events = nil @@ -821,16 +852,19 @@ func (s *Server) Stop() { func (s *Server) GracefulStop() { s.mu.Lock() defer s.mu.Unlock() - if s.drain == true || s.conns == nil { + if s.conns == nil { return } - s.drain = true for lis := range s.lis { lis.Close() } s.lis = nil - for c := range s.conns { - c.(transport.ServerTransport).Drain() + s.cancel() + if !s.drain { + for c := range s.conns { + c.(transport.ServerTransport).Drain() + } + s.drain = true } for len(s.conns) != 0 { s.cv.Wait() @@ -862,33 +896,49 @@ func (s *Server) testingCloseConns() { s.mu.Unlock() } -// SendHeader sends header metadata. It may be called at most once from a unary -// RPC handler. The ctx is the RPC handler's Context or one derived from it. -func SendHeader(ctx context.Context, md metadata.MD) error { +// SetHeader sets the header metadata. +// When called multiple times, all the provided metadata will be merged. +// All the metadata will be sent out when one of the following happens: +// - grpc.SendHeader() is called; +// - The first response is sent out; +// - An RPC status is sent out (error or success). +func SetHeader(ctx context.Context, md metadata.MD) error { if md.Len() == 0 { return nil } stream, ok := transport.StreamFromContext(ctx) if !ok { - return fmt.Errorf("grpc: failed to fetch the stream from the context %v", ctx) + return Errorf(codes.Internal, "grpc: failed to fetch the stream from the context %v", ctx) + } + return stream.SetHeader(md) +} + +// SendHeader sends header metadata. It may be called at most once. +// The provided md and headers set by SetHeader() will be sent. +func SendHeader(ctx context.Context, md metadata.MD) error { + stream, ok := transport.StreamFromContext(ctx) + if !ok { + return Errorf(codes.Internal, "grpc: failed to fetch the stream from the context %v", ctx) } t := stream.ServerTransport() if t == nil { grpclog.Fatalf("grpc: SendHeader: %v has no ServerTransport to send header metadata.", stream) } - return t.WriteHeader(stream, md) + if err := t.WriteHeader(stream, md); err != nil { + return toRPCErr(err) + } + return nil } // SetTrailer sets the trailer metadata that will be sent when an RPC returns. -// It may be called at most once from a unary RPC handler. The ctx is the RPC -// handler's Context or one derived from it. +// When called more than once, all the provided metadata will be merged. func SetTrailer(ctx context.Context, md metadata.MD) error { if md.Len() == 0 { return nil } stream, ok := transport.StreamFromContext(ctx) if !ok { - return fmt.Errorf("grpc: failed to fetch the stream from the context %v", ctx) + return Errorf(codes.Internal, "grpc: failed to fetch the stream from the context %v", ctx) } return stream.SetTrailer(md) } diff --git a/vendor/google.golang.org/grpc/stream.go b/vendor/google.golang.org/grpc/stream.go index 51df3f01d..46810544f 100644 --- a/vendor/google.golang.org/grpc/stream.go +++ b/vendor/google.golang.org/grpc/stream.go @@ -97,7 +97,14 @@ type ClientStream interface { // NewClientStream creates a new Stream for the client side. This is called // by generated code. -func NewClientStream(ctx context.Context, desc *StreamDesc, cc *ClientConn, method string, opts ...CallOption) (_ ClientStream, err error) { +func NewClientStream(ctx context.Context, desc *StreamDesc, cc *ClientConn, method string, opts ...CallOption) (ClientStream, error) { + if cc.dopts.streamInt != nil { + return cc.dopts.streamInt(ctx, desc, cc, method, newClientStream, opts...) + } + return newClientStream(ctx, desc, cc, method, opts...) +} + +func newClientStream(ctx context.Context, desc *StreamDesc, cc *ClientConn, method string, opts ...CallOption) (_ ClientStream, err error) { var ( t transport.ClientTransport s *transport.Stream @@ -296,7 +303,7 @@ func (cs *clientStream) SendMsg(m interface{}) (err error) { } }() if err != nil { - return transport.StreamErrorf(codes.Internal, "grpc: %v", err) + return Errorf(codes.Internal, "grpc: %v", err) } return cs.t.Write(cs.s, out, &transport.Options{Last: false}) } @@ -403,12 +410,19 @@ func (cs *clientStream) finish(err error) { // ServerStream defines the interface a server stream has to satisfy. type ServerStream interface { - // SendHeader sends the header metadata. It should not be called - // after SendProto. It fails if called multiple times or if - // called after SendProto. + // SetHeader sets the header metadata. It may be called multiple times. + // When call multiple times, all the provided metadata will be merged. + // All the metadata will be sent out when one of the following happens: + // - ServerStream.SendHeader() is called; + // - The first response is sent out; + // - An RPC status is sent out (error or success). + SetHeader(metadata.MD) error + // SendHeader sends the header metadata. + // The provided md and headers set by SetHeader() will be sent. + // It fails if called multiple times. SendHeader(metadata.MD) error - // SetTrailer sets the trailer metadata which will be sent with the - // RPC status. + // SetTrailer sets the trailer metadata which will be sent with the RPC status. + // When called more than once, all the provided metadata will be merged. SetTrailer(metadata.MD) Stream } @@ -434,6 +448,13 @@ func (ss *serverStream) Context() context.Context { return ss.s.Context() } +func (ss *serverStream) SetHeader(md metadata.MD) error { + if md.Len() == 0 { + return nil + } + return ss.s.SetHeader(md) +} + func (ss *serverStream) SendHeader(md metadata.MD) error { return ss.t.WriteHeader(ss.s, md) } @@ -468,10 +489,13 @@ func (ss *serverStream) SendMsg(m interface{}) (err error) { } }() if err != nil { - err = transport.StreamErrorf(codes.Internal, "grpc: %v", err) + err = Errorf(codes.Internal, "grpc: %v", err) return err } - return ss.t.Write(ss.s, out, &transport.Options{Last: false}) + if err := ss.t.Write(ss.s, out, &transport.Options{Last: false}); err != nil { + return toRPCErr(err) + } + return nil } func (ss *serverStream) RecvMsg(m interface{}) (err error) { @@ -489,5 +513,14 @@ func (ss *serverStream) RecvMsg(m interface{}) (err error) { ss.mu.Unlock() } }() - return recv(ss.p, ss.codec, ss.s, ss.dc, m, ss.maxMsgSize) + if err := recv(ss.p, ss.codec, ss.s, ss.dc, m, ss.maxMsgSize); err != nil { + if err == io.EOF { + return err + } + if err == io.ErrUnexpectedEOF { + err = Errorf(codes.Internal, io.ErrUnexpectedEOF.Error()) + } + return toRPCErr(err) + } + return nil } diff --git a/vendor/google.golang.org/grpc/transport/handler_server.go b/vendor/google.golang.org/grpc/transport/handler_server.go index 30e21ac0f..114e34906 100644 --- a/vendor/google.golang.org/grpc/transport/handler_server.go +++ b/vendor/google.golang.org/grpc/transport/handler_server.go @@ -85,7 +85,7 @@ func NewServerHandlerTransport(w http.ResponseWriter, r *http.Request) (ServerTr if v := r.Header.Get("grpc-timeout"); v != "" { to, err := decodeTimeout(v) if err != nil { - return nil, StreamErrorf(codes.Internal, "malformed time-out: %v", err) + return nil, streamErrorf(codes.Internal, "malformed time-out: %v", err) } st.timeoutSet = true st.timeout = to @@ -393,5 +393,5 @@ func mapRecvMsgError(err error) error { } } } - return ConnectionError{Desc: err.Error()} + return connectionErrorf(true, err, err.Error()) } diff --git a/vendor/google.golang.org/grpc/transport/http2_client.go b/vendor/google.golang.org/grpc/transport/http2_client.go index 5819cb8a4..2b0f68016 100644 --- a/vendor/google.golang.org/grpc/transport/http2_client.go +++ b/vendor/google.golang.org/grpc/transport/http2_client.go @@ -57,6 +57,7 @@ import ( type http2Client struct { target string // server name/addr userAgent string + md interface{} conn net.Conn // underlying communication channel authInfo credentials.AuthInfo // auth info about the connection nextID uint32 // the next stream ID to be used @@ -107,21 +108,49 @@ type http2Client struct { prevGoAwayID uint32 } -func dial(fn func(context.Context, string) (net.Conn, error), ctx context.Context, addr string) (net.Conn, error) { +func dial(ctx context.Context, fn func(context.Context, string) (net.Conn, error), addr string) (net.Conn, error) { if fn != nil { return fn(ctx, addr) } return dialContext(ctx, "tcp", addr) } +func isTemporary(err error) bool { + switch err { + case io.EOF: + // Connection closures may be resolved upon retry, and are thus + // treated as temporary. + return true + case context.DeadlineExceeded: + // In Go 1.7, context.DeadlineExceeded implements Timeout(), and this + // special case is not needed. Until then, we need to keep this + // clause. + return true + } + + switch err := err.(type) { + case interface { + Temporary() bool + }: + return err.Temporary() + case interface { + Timeout() bool + }: + // Timeouts may be resolved upon retry, and are thus treated as + // temporary. + return err.Timeout() + } + return false +} + // newHTTP2Client constructs a connected ClientTransport to addr based on HTTP2 // and starts to receive messages on it. Non-nil error returns if construction // fails. -func newHTTP2Client(ctx context.Context, addr string, opts ConnectOptions) (_ ClientTransport, err error) { +func newHTTP2Client(ctx context.Context, addr TargetInfo, opts ConnectOptions) (_ ClientTransport, err error) { scheme := "http" - conn, connErr := dial(opts.Dialer, ctx, addr) - if connErr != nil { - return nil, ConnectionErrorf(true, connErr, "transport: %v", connErr) + conn, err := dial(ctx, opts.Dialer, addr.Addr) + if err != nil { + return nil, connectionErrorf(true, err, "transport: %v", err) } // Any further errors will close the underlying connection defer func(conn net.Conn) { @@ -132,12 +161,13 @@ func newHTTP2Client(ctx context.Context, addr string, opts ConnectOptions) (_ Cl var authInfo credentials.AuthInfo if creds := opts.TransportCredentials; creds != nil { scheme = "https" - conn, authInfo, connErr = creds.ClientHandshake(ctx, addr, conn) - } - if connErr != nil { - // Credentials handshake error is not a temporary error (unless the error - // was the connection closing). - return nil, ConnectionErrorf(connErr == io.EOF, connErr, "transport: %v", connErr) + conn, authInfo, err = creds.ClientHandshake(ctx, addr.Addr, conn) + if err != nil { + // Credentials handshake errors are typically considered permanent + // to avoid retrying on e.g. bad certificates. + temp := isTemporary(err) + return nil, connectionErrorf(temp, err, "transport: %v", err) + } } ua := primaryUA if opts.UserAgent != "" { @@ -145,8 +175,9 @@ func newHTTP2Client(ctx context.Context, addr string, opts ConnectOptions) (_ Cl } var buf bytes.Buffer t := &http2Client{ - target: addr, + target: addr.Addr, userAgent: ua, + md: addr.Metadata, conn: conn, authInfo: authInfo, // The client initiated stream id is odd starting from 1. @@ -176,11 +207,11 @@ func newHTTP2Client(ctx context.Context, addr string, opts ConnectOptions) (_ Cl n, err := t.conn.Write(clientPreface) if err != nil { t.Close() - return nil, ConnectionErrorf(true, err, "transport: %v", err) + return nil, connectionErrorf(true, err, "transport: %v", err) } if n != len(clientPreface) { t.Close() - return nil, ConnectionErrorf(true, err, "transport: preface mismatch, wrote %d bytes; want %d", n, len(clientPreface)) + return nil, connectionErrorf(true, err, "transport: preface mismatch, wrote %d bytes; want %d", n, len(clientPreface)) } if initialWindowSize != defaultWindowSize { err = t.framer.writeSettings(true, http2.Setting{ @@ -192,13 +223,13 @@ func newHTTP2Client(ctx context.Context, addr string, opts ConnectOptions) (_ Cl } if err != nil { t.Close() - return nil, ConnectionErrorf(true, err, "transport: %v", err) + return nil, connectionErrorf(true, err, "transport: %v", err) } // Adjust the connection flow control window if needed. if delta := uint32(initialConnWindowSize - defaultWindowSize); delta > 0 { if err := t.framer.writeWindowUpdate(true, 0, delta); err != nil { t.Close() - return nil, ConnectionErrorf(true, err, "transport: %v", err) + return nil, connectionErrorf(true, err, "transport: %v", err) } } go t.controller() @@ -223,8 +254,10 @@ func (t *http2Client) newStream(ctx context.Context, callHdr *CallHdr) *Stream { s.windowHandler = func(n int) { t.updateWindow(s, uint32(n)) } - // Make a stream be able to cancel the pending operations by itself. - s.ctx, s.cancel = context.WithCancel(ctx) + // The client side stream context should have exactly the same life cycle with the user provided context. + // That means, s.ctx should be read-only. And s.ctx is done iff ctx is done. + // So we use the original context here instead of creating a copy. + s.ctx = ctx s.dec = &recvBufferReader{ ctx: s.ctx, goAway: s.goAway, @@ -236,16 +269,6 @@ func (t *http2Client) newStream(ctx context.Context, callHdr *CallHdr) *Stream { // NewStream creates a stream and register it into the transport as "active" // streams. func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (_ *Stream, err error) { - // Record the timeout value on the context. - var timeout time.Duration - if dl, ok := ctx.Deadline(); ok { - timeout = dl.Sub(time.Now()) - } - select { - case <-ctx.Done(): - return nil, ContextErr(ctx.Err()) - default: - } pr := &peer.Peer{ Addr: t.conn.RemoteAddr(), } @@ -266,12 +289,12 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (_ *Strea } pos := strings.LastIndex(callHdr.Method, "/") if pos == -1 { - return nil, StreamErrorf(codes.InvalidArgument, "transport: malformed method name: %q", callHdr.Method) + return nil, streamErrorf(codes.InvalidArgument, "transport: malformed method name: %q", callHdr.Method) } audience := "https://" + callHdr.Host + port + callHdr.Method[:pos] data, err := c.GetRequestMetadata(ctx, audience) if err != nil { - return nil, StreamErrorf(codes.InvalidArgument, "transport: %v", err) + return nil, streamErrorf(codes.InvalidArgument, "transport: %v", err) } for k, v := range data { authData[k] = v @@ -352,9 +375,12 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (_ *Strea if callHdr.SendCompress != "" { t.hEnc.WriteField(hpack.HeaderField{Name: "grpc-encoding", Value: callHdr.SendCompress}) } - if timeout > 0 { + if dl, ok := ctx.Deadline(); ok { + // Send out timeout regardless its value. The server can detect timeout context by itself. + timeout := dl.Sub(time.Now()) t.hEnc.WriteField(hpack.HeaderField{Name: "grpc-timeout", Value: encodeTimeout(timeout)}) } + for k, v := range authData { // Capital header names are illegal in HTTP/2. k = strings.ToLower(k) @@ -376,6 +402,16 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (_ *Strea } } } + if md, ok := t.md.(*metadata.MD); ok { + for k, v := range *md { + if isReservedHeader(k) { + continue + } + for _, entry := range v { + t.hEnc.WriteField(hpack.HeaderField{Name: k, Value: entry}) + } + } + } first := true // Sends the headers in a single batch even when they span multiple frames. for !endHeaders { @@ -408,7 +444,7 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (_ *Strea } if err != nil { t.notifyError(err) - return nil, ConnectionErrorf(true, err, "transport: %v", err) + return nil, connectionErrorf(true, err, "transport: %v", err) } } t.writableChan <- 0 @@ -454,7 +490,7 @@ func (t *http2Client) CloseStream(s *Stream, err error) { } s.state = streamDone s.mu.Unlock() - if _, ok := err.(StreamError); ok { + if se, ok := err.(StreamError); ok && se.Code != codes.DeadlineExceeded { t.controlBuf.put(&resetStream{s.id, http2.ErrCodeCancel}) } } @@ -622,7 +658,7 @@ func (t *http2Client) Write(s *Stream, data []byte, opts *Options) error { // invoked. if err := t.framer.writeData(forceFlush, s.id, endStream, p); err != nil { t.notifyError(err) - return ConnectionErrorf(true, err, "transport: %v", err) + return connectionErrorf(true, err, "transport: %v", err) } if t.framer.adjustNumWriters(-1) == 0 { t.framer.flushWrite() @@ -670,7 +706,7 @@ func (t *http2Client) updateWindow(s *Stream, n uint32) { func (t *http2Client) handleData(f *http2.DataFrame) { size := len(f.Data()) if err := t.fc.onData(uint32(size)); err != nil { - t.notifyError(ConnectionErrorf(true, err, "%v", err)) + t.notifyError(connectionErrorf(true, err, "%v", err)) return } // Select the right stream to dispatch. @@ -766,6 +802,9 @@ func (t *http2Client) handleSettings(f *http2.SettingsFrame) { } func (t *http2Client) handlePing(f *http2.PingFrame) { + if f.IsAck() { // Do nothing. + return + } pingAck := &ping{ack: true} copy(pingAck.data[:], f.Data[:]) t.controlBuf.put(pingAck) @@ -776,7 +815,7 @@ func (t *http2Client) handleGoAway(f *http2.GoAwayFrame) { if t.state == reachable || t.state == draining { if f.LastStreamID > 0 && f.LastStreamID%2 != 1 { t.mu.Unlock() - t.notifyError(ConnectionErrorf(true, nil, "received illegal http2 GOAWAY frame: stream ID %d is even", f.LastStreamID)) + t.notifyError(connectionErrorf(true, nil, "received illegal http2 GOAWAY frame: stream ID %d is even", f.LastStreamID)) return } select { @@ -785,7 +824,7 @@ func (t *http2Client) handleGoAway(f *http2.GoAwayFrame) { // t.goAway has been closed (i.e.,multiple GoAways). if id < f.LastStreamID { t.mu.Unlock() - t.notifyError(ConnectionErrorf(true, nil, "received illegal http2 GOAWAY frame: previously recv GOAWAY frame with LastStramID %d, currently recv %d", id, f.LastStreamID)) + t.notifyError(connectionErrorf(true, nil, "received illegal http2 GOAWAY frame: previously recv GOAWAY frame with LastStramID %d, currently recv %d", id, f.LastStreamID)) return } t.prevGoAwayID = id @@ -823,6 +862,12 @@ func (t *http2Client) operateHeaders(frame *http2.MetaHeadersFrame) { state.processHeaderField(hf) } if state.err != nil { + s.mu.Lock() + if !s.headerDone { + close(s.headerChan) + s.headerDone = true + } + s.mu.Unlock() s.write(recvMsg{err: state.err}) // Something wrong. Stops reading even when there is remaining. return @@ -900,7 +945,7 @@ func (t *http2Client) reader() { t.mu.Unlock() if s != nil { // use error detail to provide better err message - handleMalformedHTTP2(s, StreamErrorf(http2ErrConvTab[se.Code], "%v", t.framer.errorDetail())) + handleMalformedHTTP2(s, streamErrorf(http2ErrConvTab[se.Code], "%v", t.framer.errorDetail())) } continue } else { diff --git a/vendor/google.golang.org/grpc/transport/http2_server.go b/vendor/google.golang.org/grpc/transport/http2_server.go index 16010d55f..a62fb7c22 100644 --- a/vendor/google.golang.org/grpc/transport/http2_server.go +++ b/vendor/google.golang.org/grpc/transport/http2_server.go @@ -111,12 +111,12 @@ func newHTTP2Server(conn net.Conn, maxStreams uint32, authInfo credentials.AuthI Val: uint32(initialWindowSize)}) } if err := framer.writeSettings(true, settings...); err != nil { - return nil, ConnectionErrorf(true, err, "transport: %v", err) + return nil, connectionErrorf(true, err, "transport: %v", err) } // Adjust the connection flow control window if needed. if delta := uint32(initialConnWindowSize - defaultWindowSize); delta > 0 { if err := framer.writeWindowUpdate(true, 0, delta); err != nil { - return nil, ConnectionErrorf(true, err, "transport: %v", err) + return nil, connectionErrorf(true, err, "transport: %v", err) } } var buf bytes.Buffer @@ -405,6 +405,9 @@ func (t *http2Server) handleSettings(f *http2.SettingsFrame) { } func (t *http2Server) handlePing(f *http2.PingFrame) { + if f.IsAck() { // Do nothing. + return + } pingAck := &ping{ack: true} copy(pingAck.data[:], f.Data[:]) t.controlBuf.put(pingAck) @@ -448,7 +451,7 @@ func (t *http2Server) writeHeaders(s *Stream, b *bytes.Buffer, endStream bool) e } if err != nil { t.Close() - return ConnectionErrorf(true, err, "transport: %v", err) + return connectionErrorf(true, err, "transport: %v", err) } } return nil @@ -462,6 +465,14 @@ func (t *http2Server) WriteHeader(s *Stream, md metadata.MD) error { return ErrIllegalHeaderWrite } s.headerOk = true + if md.Len() > 0 { + if s.header.Len() > 0 { + s.header = metadata.Join(s.header, md) + } else { + s.header = md + } + } + md = s.header s.mu.Unlock() if _, err := wait(s.ctx, nil, nil, t.shutdownChan, t.writableChan); err != nil { return err @@ -493,7 +504,7 @@ func (t *http2Server) WriteHeader(s *Stream, md metadata.MD) error { // TODO(zhaoq): Now it indicates the end of entire stream. Revisit if early // OK is adopted. func (t *http2Server) WriteStatus(s *Stream, statusCode codes.Code, statusDesc string) error { - var headersSent bool + var headersSent, hasHeader bool s.mu.Lock() if s.state == streamDone { s.mu.Unlock() @@ -502,7 +513,16 @@ func (t *http2Server) WriteStatus(s *Stream, statusCode codes.Code, statusDesc s if s.headerOk { headersSent = true } + if s.header.Len() > 0 { + hasHeader = true + } s.mu.Unlock() + + if !headersSent && hasHeader { + t.WriteHeader(s, nil) + headersSent = true + } + if _, err := wait(s.ctx, nil, nil, t.shutdownChan, t.writableChan); err != nil { return err } @@ -544,33 +564,14 @@ func (t *http2Server) Write(s *Stream, data []byte, opts *Options) error { s.mu.Lock() if s.state == streamDone { s.mu.Unlock() - return StreamErrorf(codes.Unknown, "the stream has been done") + return streamErrorf(codes.Unknown, "the stream has been done") } if !s.headerOk { writeHeaderFrame = true - s.headerOk = true } s.mu.Unlock() if writeHeaderFrame { - if _, err := wait(s.ctx, nil, nil, t.shutdownChan, t.writableChan); err != nil { - return err - } - t.hBuf.Reset() - t.hEnc.WriteField(hpack.HeaderField{Name: ":status", Value: "200"}) - t.hEnc.WriteField(hpack.HeaderField{Name: "content-type", Value: "application/grpc"}) - if s.sendCompress != "" { - t.hEnc.WriteField(hpack.HeaderField{Name: "grpc-encoding", Value: s.sendCompress}) - } - p := http2.HeadersFrameParam{ - StreamID: s.id, - BlockFragment: t.hBuf.Bytes(), - EndHeaders: true, - } - if err := t.framer.writeHeaders(false, p); err != nil { - t.Close() - return ConnectionErrorf(true, err, "transport: %v", err) - } - t.writableChan <- 0 + t.WriteHeader(s, nil) } r := bytes.NewBuffer(data) for { @@ -642,7 +643,7 @@ func (t *http2Server) Write(s *Stream, data []byte, opts *Options) error { } if err := t.framer.writeData(forceFlush, s.id, false, p); err != nil { t.Close() - return ConnectionErrorf(true, err, "transport: %v", err) + return connectionErrorf(true, err, "transport: %v", err) } if t.framer.adjustNumWriters(-1) == 0 { t.framer.flushWrite() diff --git a/vendor/google.golang.org/grpc/transport/http_util.go b/vendor/google.golang.org/grpc/transport/http_util.go index 3e16e4df4..a3c68d4ca 100644 --- a/vendor/google.golang.org/grpc/transport/http_util.go +++ b/vendor/google.golang.org/grpc/transport/http_util.go @@ -53,7 +53,7 @@ import ( const ( // The primary user agent - primaryUA = "grpc-go/0.11" + primaryUA = "grpc-go/1.0" // http2MaxFrameLen specifies the max length of a HTTP2 frame. http2MaxFrameLen = 16384 // 16KB frame // http://http2.github.io/http2-spec/#SettingValues @@ -162,7 +162,7 @@ func (d *decodeState) processHeaderField(f hpack.HeaderField) { switch f.Name { case "content-type": if !validContentType(f.Value) { - d.setErr(StreamErrorf(codes.FailedPrecondition, "transport: received the unexpected content-type %q", f.Value)) + d.setErr(streamErrorf(codes.FailedPrecondition, "transport: received the unexpected content-type %q", f.Value)) return } case "grpc-encoding": @@ -170,7 +170,7 @@ func (d *decodeState) processHeaderField(f hpack.HeaderField) { case "grpc-status": code, err := strconv.Atoi(f.Value) if err != nil { - d.setErr(StreamErrorf(codes.Internal, "transport: malformed grpc-status: %v", err)) + d.setErr(streamErrorf(codes.Internal, "transport: malformed grpc-status: %v", err)) return } d.statusCode = codes.Code(code) @@ -181,7 +181,7 @@ func (d *decodeState) processHeaderField(f hpack.HeaderField) { var err error d.timeout, err = decodeTimeout(f.Value) if err != nil { - d.setErr(StreamErrorf(codes.Internal, "transport: malformed time-out: %v", err)) + d.setErr(streamErrorf(codes.Internal, "transport: malformed time-out: %v", err)) return } case ":path": @@ -253,6 +253,9 @@ func div(d, r time.Duration) int64 { // TODO(zhaoq): It is the simplistic and not bandwidth efficient. Improve it. func encodeTimeout(t time.Duration) string { + if t <= 0 { + return "0n" + } if d := div(t, time.Nanosecond); d <= maxTimeoutValue { return strconv.FormatInt(d, 10) + "n" } @@ -349,7 +352,7 @@ func decodeGrpcMessageUnchecked(msg string) string { for i := 0; i < lenMsg; i++ { c := msg[i] if c == percentByte && i+2 < lenMsg { - parsed, err := strconv.ParseInt(msg[i+1:i+3], 16, 8) + parsed, err := strconv.ParseUint(msg[i+1:i+3], 16, 8) if err != nil { buf.WriteByte(c) } else { diff --git a/vendor/google.golang.org/grpc/transport/transport.go b/vendor/google.golang.org/grpc/transport/transport.go index f0885da23..21f757ac6 100644 --- a/vendor/google.golang.org/grpc/transport/transport.go +++ b/vendor/google.golang.org/grpc/transport/transport.go @@ -39,7 +39,6 @@ package transport import ( "bytes" - "errors" "fmt" "io" "net" @@ -169,7 +168,8 @@ type Stream struct { // nil for client side Stream. st ServerTransport // ctx is the associated context of the stream. - ctx context.Context + ctx context.Context + // cancel is always nil for client side Stream. cancel context.CancelFunc // done is closed when the final status arrives. done chan struct{} @@ -286,19 +286,30 @@ func (s *Stream) StatusDesc() string { return s.statusDesc } -// ErrIllegalTrailerSet indicates that the trailer has already been set or it -// is too late to do so. -var ErrIllegalTrailerSet = errors.New("transport: trailer has been set") - -// SetTrailer sets the trailer metadata which will be sent with the RPC status -// by the server. This can only be called at most once. Server side only. -func (s *Stream) SetTrailer(md metadata.MD) error { +// SetHeader sets the header metadata. This can be called multiple times. +// Server side only. +func (s *Stream) SetHeader(md metadata.MD) error { s.mu.Lock() defer s.mu.Unlock() - if s.trailer != nil { - return ErrIllegalTrailerSet + if s.headerOk || s.state == streamDone { + return ErrIllegalHeaderWrite } - s.trailer = md.Copy() + if md.Len() == 0 { + return nil + } + s.header = metadata.Join(s.header, md) + return nil +} + +// SetTrailer sets the trailer metadata which will be sent with the RPC status +// by the server. This can be called multiple times. Server side only. +func (s *Stream) SetTrailer(md metadata.MD) error { + if md.Len() == 0 { + return nil + } + s.mu.Lock() + defer s.mu.Unlock() + s.trailer = metadata.Join(s.trailer, md) return nil } @@ -350,7 +361,7 @@ func NewServerTransport(protocol string, conn net.Conn, maxStreams uint32, authI return newHTTP2Server(conn, maxStreams, authInfo) } -// ConnectOptions covers all relevant options for dialing a server. +// ConnectOptions covers all relevant options for communicating with the server. type ConnectOptions struct { // UserAgent is the application user agent. UserAgent string @@ -362,9 +373,15 @@ type ConnectOptions struct { TransportCredentials credentials.TransportCredentials } +// TargetInfo contains the information of the target such as network address and metadata. +type TargetInfo struct { + Addr string + Metadata interface{} +} + // NewClientTransport establishes the transport with the required ConnectOptions // and returns it to the caller. -func NewClientTransport(ctx context.Context, target string, opts ConnectOptions) (ClientTransport, error) { +func NewClientTransport(ctx context.Context, target TargetInfo, opts ConnectOptions) (ClientTransport, error) { return newHTTP2Client(ctx, target, opts) } @@ -476,16 +493,16 @@ type ServerTransport interface { Drain() } -// StreamErrorf creates an StreamError with the specified error code and description. -func StreamErrorf(c codes.Code, format string, a ...interface{}) StreamError { +// streamErrorf creates an StreamError with the specified error code and description. +func streamErrorf(c codes.Code, format string, a ...interface{}) StreamError { return StreamError{ Code: c, Desc: fmt.Sprintf(format, a...), } } -// ConnectionErrorf creates an ConnectionError with the specified error description. -func ConnectionErrorf(temp bool, e error, format string, a ...interface{}) ConnectionError { +// connectionErrorf creates an ConnectionError with the specified error description. +func connectionErrorf(temp bool, e error, format string, a ...interface{}) ConnectionError { return ConnectionError{ Desc: fmt.Sprintf(format, a...), temp: temp, @@ -522,10 +539,10 @@ func (e ConnectionError) Origin() error { var ( // ErrConnClosing indicates that the transport is closing. - ErrConnClosing = ConnectionError{Desc: "transport is closing", temp: true} + ErrConnClosing = connectionErrorf(true, nil, "transport is closing") // ErrStreamDrain indicates that the stream is rejected by the server because // the server stops accepting new RPCs. - ErrStreamDrain = StreamErrorf(codes.Unavailable, "the server stops accepting new RPCs") + ErrStreamDrain = streamErrorf(codes.Unavailable, "the server stops accepting new RPCs") ) // StreamError is an error that only affects one stream within a connection. @@ -542,9 +559,9 @@ func (e StreamError) Error() string { func ContextErr(err error) StreamError { switch err { case context.DeadlineExceeded: - return StreamErrorf(codes.DeadlineExceeded, "%v", err) + return streamErrorf(codes.DeadlineExceeded, "%v", err) case context.Canceled: - return StreamErrorf(codes.Canceled, "%v", err) + return streamErrorf(codes.Canceled, "%v", err) } panic(fmt.Sprintf("Unexpected error from context packet: %v", err)) }