diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json index 1a2ac69d933..927dd9f4dbf 100644 --- a/Godeps/Godeps.json +++ b/Godeps/Godeps.json @@ -258,8 +258,8 @@ }, { "ImportPath": "github.com/boltdb/bolt", - "Comment": "v1.1.0-65-gee4a088", - "Rev": "ee4a0888a9abe7eefe5a0992ca4cb06864839873" + "Comment": "v1.2.1", + "Rev": "dfb21201d9270c1082d5fb0f07f500311ff72f18" }, { "ImportPath": "github.com/cloudflare/cfssl/auth", @@ -333,263 +333,263 @@ }, { "ImportPath": "github.com/coreos/etcd/alarm", - "Comment": "v2.3.0-282-g8b320e7", - "Rev": "8b320e7c550067b1dfb37bd1682e8067023e0751" + "Comment": "v3.0.4", + "Rev": "d53923c636e0e4ab7f00cb75681b97a8f11f5a9d" }, { "ImportPath": "github.com/coreos/etcd/auth", - "Comment": "v2.3.0-282-g8b320e7", - "Rev": "8b320e7c550067b1dfb37bd1682e8067023e0751" + "Comment": "v3.0.4", + "Rev": "d53923c636e0e4ab7f00cb75681b97a8f11f5a9d" }, { "ImportPath": "github.com/coreos/etcd/auth/authpb", - "Comment": "v2.3.0-282-g8b320e7", - "Rev": "8b320e7c550067b1dfb37bd1682e8067023e0751" + "Comment": "v3.0.4", + "Rev": "d53923c636e0e4ab7f00cb75681b97a8f11f5a9d" }, { "ImportPath": "github.com/coreos/etcd/client", - "Comment": "v2.3.0-282-g8b320e7", - "Rev": "8b320e7c550067b1dfb37bd1682e8067023e0751" + "Comment": "v3.0.4", + "Rev": "d53923c636e0e4ab7f00cb75681b97a8f11f5a9d" }, { "ImportPath": "github.com/coreos/etcd/clientv3", - "Comment": "v2.3.0-282-g8b320e7", - "Rev": "8b320e7c550067b1dfb37bd1682e8067023e0751" + "Comment": "v3.0.4", + "Rev": "d53923c636e0e4ab7f00cb75681b97a8f11f5a9d" }, { "ImportPath": "github.com/coreos/etcd/compactor", - "Comment": "v2.3.0-282-g8b320e7", - "Rev": "8b320e7c550067b1dfb37bd1682e8067023e0751" + "Comment": "v3.0.4", + "Rev": "d53923c636e0e4ab7f00cb75681b97a8f11f5a9d" }, { "ImportPath": "github.com/coreos/etcd/discovery", - "Comment": "v2.3.0-282-g8b320e7", - "Rev": "8b320e7c550067b1dfb37bd1682e8067023e0751" + "Comment": "v3.0.4", + "Rev": "d53923c636e0e4ab7f00cb75681b97a8f11f5a9d" }, { "ImportPath": "github.com/coreos/etcd/error", - "Comment": "v2.3.0-282-g8b320e7", - "Rev": "8b320e7c550067b1dfb37bd1682e8067023e0751" + "Comment": "v3.0.4", + "Rev": "d53923c636e0e4ab7f00cb75681b97a8f11f5a9d" }, { "ImportPath": "github.com/coreos/etcd/etcdserver", - "Comment": "v2.3.0-282-g8b320e7", - "Rev": "8b320e7c550067b1dfb37bd1682e8067023e0751" + "Comment": "v3.0.4", + "Rev": "d53923c636e0e4ab7f00cb75681b97a8f11f5a9d" }, { "ImportPath": "github.com/coreos/etcd/etcdserver/api", - "Comment": "v2.3.0-282-g8b320e7", - "Rev": "8b320e7c550067b1dfb37bd1682e8067023e0751" + "Comment": "v3.0.4", + "Rev": "d53923c636e0e4ab7f00cb75681b97a8f11f5a9d" }, { "ImportPath": "github.com/coreos/etcd/etcdserver/api/v2http", - "Comment": "v2.3.0-282-g8b320e7", - "Rev": "8b320e7c550067b1dfb37bd1682e8067023e0751" + "Comment": "v3.0.4", + "Rev": "d53923c636e0e4ab7f00cb75681b97a8f11f5a9d" }, { "ImportPath": "github.com/coreos/etcd/etcdserver/api/v2http/httptypes", - "Comment": "v2.3.0-282-g8b320e7", - "Rev": "8b320e7c550067b1dfb37bd1682e8067023e0751" + "Comment": "v3.0.4", + "Rev": "d53923c636e0e4ab7f00cb75681b97a8f11f5a9d" }, { "ImportPath": "github.com/coreos/etcd/etcdserver/api/v3rpc", - "Comment": "v2.3.0-282-g8b320e7", - "Rev": "8b320e7c550067b1dfb37bd1682e8067023e0751" + "Comment": "v3.0.4", + "Rev": "d53923c636e0e4ab7f00cb75681b97a8f11f5a9d" }, { "ImportPath": "github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes", - "Comment": "v2.3.0-282-g8b320e7", - "Rev": "8b320e7c550067b1dfb37bd1682e8067023e0751" + "Comment": "v3.0.4", + "Rev": "d53923c636e0e4ab7f00cb75681b97a8f11f5a9d" }, { "ImportPath": "github.com/coreos/etcd/etcdserver/auth", - "Comment": "v2.3.0-282-g8b320e7", - "Rev": "8b320e7c550067b1dfb37bd1682e8067023e0751" + "Comment": "v3.0.4", + "Rev": "d53923c636e0e4ab7f00cb75681b97a8f11f5a9d" }, { "ImportPath": "github.com/coreos/etcd/etcdserver/etcdserverpb", - "Comment": "v2.3.0-282-g8b320e7", - "Rev": "8b320e7c550067b1dfb37bd1682e8067023e0751" + "Comment": "v3.0.4", + "Rev": "d53923c636e0e4ab7f00cb75681b97a8f11f5a9d" }, { "ImportPath": "github.com/coreos/etcd/etcdserver/membership", - "Comment": "v2.3.0-282-g8b320e7", - "Rev": "8b320e7c550067b1dfb37bd1682e8067023e0751" + "Comment": "v3.0.4", + "Rev": "d53923c636e0e4ab7f00cb75681b97a8f11f5a9d" }, { "ImportPath": "github.com/coreos/etcd/etcdserver/stats", - "Comment": "v2.3.0-282-g8b320e7", - "Rev": "8b320e7c550067b1dfb37bd1682e8067023e0751" + "Comment": "v3.0.4", + "Rev": "d53923c636e0e4ab7f00cb75681b97a8f11f5a9d" }, { "ImportPath": "github.com/coreos/etcd/integration", - "Comment": "v2.3.0-282-g8b320e7", - "Rev": "8b320e7c550067b1dfb37bd1682e8067023e0751" + "Comment": "v3.0.4", + "Rev": "d53923c636e0e4ab7f00cb75681b97a8f11f5a9d" }, { "ImportPath": "github.com/coreos/etcd/lease", - "Comment": "v2.3.0-282-g8b320e7", - "Rev": "8b320e7c550067b1dfb37bd1682e8067023e0751" + "Comment": "v3.0.4", + "Rev": "d53923c636e0e4ab7f00cb75681b97a8f11f5a9d" }, { "ImportPath": "github.com/coreos/etcd/lease/leasehttp", - "Comment": "v2.3.0-282-g8b320e7", - "Rev": "8b320e7c550067b1dfb37bd1682e8067023e0751" + "Comment": "v3.0.4", + "Rev": "d53923c636e0e4ab7f00cb75681b97a8f11f5a9d" }, { "ImportPath": "github.com/coreos/etcd/lease/leasepb", - "Comment": "v2.3.0-282-g8b320e7", - "Rev": "8b320e7c550067b1dfb37bd1682e8067023e0751" + "Comment": "v3.0.4", + "Rev": "d53923c636e0e4ab7f00cb75681b97a8f11f5a9d" + }, + { + "ImportPath": "github.com/coreos/etcd/mvcc", + "Comment": "v3.0.4", + "Rev": "d53923c636e0e4ab7f00cb75681b97a8f11f5a9d" + }, + { + "ImportPath": "github.com/coreos/etcd/mvcc/backend", + "Comment": "v3.0.4", + "Rev": "d53923c636e0e4ab7f00cb75681b97a8f11f5a9d" + }, + { + "ImportPath": "github.com/coreos/etcd/mvcc/mvccpb", + "Comment": "v3.0.4", + "Rev": "d53923c636e0e4ab7f00cb75681b97a8f11f5a9d" }, { "ImportPath": "github.com/coreos/etcd/pkg/adt", - "Comment": "v2.3.0-282-g8b320e7", - "Rev": "8b320e7c550067b1dfb37bd1682e8067023e0751" + "Comment": "v3.0.4", + "Rev": "d53923c636e0e4ab7f00cb75681b97a8f11f5a9d" }, { "ImportPath": "github.com/coreos/etcd/pkg/contention", - "Comment": "v2.3.0-282-g8b320e7", - "Rev": "8b320e7c550067b1dfb37bd1682e8067023e0751" + "Comment": "v3.0.4", + "Rev": "d53923c636e0e4ab7f00cb75681b97a8f11f5a9d" }, { "ImportPath": "github.com/coreos/etcd/pkg/crc", - "Comment": "v2.3.0-282-g8b320e7", - "Rev": "8b320e7c550067b1dfb37bd1682e8067023e0751" + "Comment": "v3.0.4", + "Rev": "d53923c636e0e4ab7f00cb75681b97a8f11f5a9d" }, { "ImportPath": "github.com/coreos/etcd/pkg/fileutil", - "Comment": "v2.3.0-282-g8b320e7", - "Rev": "8b320e7c550067b1dfb37bd1682e8067023e0751" + "Comment": "v3.0.4", + "Rev": "d53923c636e0e4ab7f00cb75681b97a8f11f5a9d" }, { "ImportPath": "github.com/coreos/etcd/pkg/httputil", - "Comment": "v2.3.0-282-g8b320e7", - "Rev": "8b320e7c550067b1dfb37bd1682e8067023e0751" + "Comment": "v3.0.4", + "Rev": "d53923c636e0e4ab7f00cb75681b97a8f11f5a9d" }, { "ImportPath": "github.com/coreos/etcd/pkg/idutil", - "Comment": "v2.3.0-282-g8b320e7", - "Rev": "8b320e7c550067b1dfb37bd1682e8067023e0751" + "Comment": "v3.0.4", + "Rev": "d53923c636e0e4ab7f00cb75681b97a8f11f5a9d" }, { "ImportPath": "github.com/coreos/etcd/pkg/ioutil", - "Comment": "v2.3.0-282-g8b320e7", - "Rev": "8b320e7c550067b1dfb37bd1682e8067023e0751" + "Comment": "v3.0.4", + "Rev": "d53923c636e0e4ab7f00cb75681b97a8f11f5a9d" }, { "ImportPath": "github.com/coreos/etcd/pkg/logutil", - "Comment": "v2.3.0-282-g8b320e7", - "Rev": "8b320e7c550067b1dfb37bd1682e8067023e0751" + "Comment": "v3.0.4", + "Rev": "d53923c636e0e4ab7f00cb75681b97a8f11f5a9d" }, { "ImportPath": "github.com/coreos/etcd/pkg/netutil", - "Comment": "v2.3.0-282-g8b320e7", - "Rev": "8b320e7c550067b1dfb37bd1682e8067023e0751" + "Comment": "v3.0.4", + "Rev": "d53923c636e0e4ab7f00cb75681b97a8f11f5a9d" }, { "ImportPath": "github.com/coreos/etcd/pkg/pathutil", - "Comment": "v2.3.0-282-g8b320e7", - "Rev": "8b320e7c550067b1dfb37bd1682e8067023e0751" + "Comment": "v3.0.4", + "Rev": "d53923c636e0e4ab7f00cb75681b97a8f11f5a9d" }, { "ImportPath": "github.com/coreos/etcd/pkg/pbutil", - "Comment": "v2.3.0-282-g8b320e7", - "Rev": "8b320e7c550067b1dfb37bd1682e8067023e0751" + "Comment": "v3.0.4", + "Rev": "d53923c636e0e4ab7f00cb75681b97a8f11f5a9d" }, { "ImportPath": "github.com/coreos/etcd/pkg/runtime", - "Comment": "v2.3.0-282-g8b320e7", - "Rev": "8b320e7c550067b1dfb37bd1682e8067023e0751" + "Comment": "v3.0.4", + "Rev": "d53923c636e0e4ab7f00cb75681b97a8f11f5a9d" }, { "ImportPath": "github.com/coreos/etcd/pkg/schedule", - "Comment": "v2.3.0-282-g8b320e7", - "Rev": "8b320e7c550067b1dfb37bd1682e8067023e0751" + "Comment": "v3.0.4", + "Rev": "d53923c636e0e4ab7f00cb75681b97a8f11f5a9d" }, { "ImportPath": "github.com/coreos/etcd/pkg/testutil", - "Comment": "v2.3.0-282-g8b320e7", - "Rev": "8b320e7c550067b1dfb37bd1682e8067023e0751" + "Comment": "v3.0.4", + "Rev": "d53923c636e0e4ab7f00cb75681b97a8f11f5a9d" }, { "ImportPath": "github.com/coreos/etcd/pkg/tlsutil", - "Comment": "v2.3.0-282-g8b320e7", - "Rev": "8b320e7c550067b1dfb37bd1682e8067023e0751" + "Comment": "v3.0.4", + "Rev": "d53923c636e0e4ab7f00cb75681b97a8f11f5a9d" }, { "ImportPath": "github.com/coreos/etcd/pkg/transport", - "Comment": "v2.3.0-282-g8b320e7", - "Rev": "8b320e7c550067b1dfb37bd1682e8067023e0751" + "Comment": "v3.0.4", + "Rev": "d53923c636e0e4ab7f00cb75681b97a8f11f5a9d" }, { "ImportPath": "github.com/coreos/etcd/pkg/types", - "Comment": "v2.3.0-282-g8b320e7", - "Rev": "8b320e7c550067b1dfb37bd1682e8067023e0751" + "Comment": "v3.0.4", + "Rev": "d53923c636e0e4ab7f00cb75681b97a8f11f5a9d" }, { "ImportPath": "github.com/coreos/etcd/pkg/wait", - "Comment": "v2.3.0-282-g8b320e7", - "Rev": "8b320e7c550067b1dfb37bd1682e8067023e0751" + "Comment": "v3.0.4", + "Rev": "d53923c636e0e4ab7f00cb75681b97a8f11f5a9d" }, { "ImportPath": "github.com/coreos/etcd/raft", - "Comment": "v2.3.0-282-g8b320e7", - "Rev": "8b320e7c550067b1dfb37bd1682e8067023e0751" + "Comment": "v3.0.4", + "Rev": "d53923c636e0e4ab7f00cb75681b97a8f11f5a9d" }, { "ImportPath": "github.com/coreos/etcd/raft/raftpb", - "Comment": "v2.3.0-282-g8b320e7", - "Rev": "8b320e7c550067b1dfb37bd1682e8067023e0751" + "Comment": "v3.0.4", + "Rev": "d53923c636e0e4ab7f00cb75681b97a8f11f5a9d" }, { "ImportPath": "github.com/coreos/etcd/rafthttp", - "Comment": "v2.3.0-282-g8b320e7", - "Rev": "8b320e7c550067b1dfb37bd1682e8067023e0751" + "Comment": "v3.0.4", + "Rev": "d53923c636e0e4ab7f00cb75681b97a8f11f5a9d" }, { "ImportPath": "github.com/coreos/etcd/snap", - "Comment": "v2.3.0-282-g8b320e7", - "Rev": "8b320e7c550067b1dfb37bd1682e8067023e0751" + "Comment": "v3.0.4", + "Rev": "d53923c636e0e4ab7f00cb75681b97a8f11f5a9d" }, { "ImportPath": "github.com/coreos/etcd/snap/snappb", - "Comment": "v2.3.0-282-g8b320e7", - "Rev": "8b320e7c550067b1dfb37bd1682e8067023e0751" - }, - { - "ImportPath": "github.com/coreos/etcd/storage", - "Comment": "v2.3.0-282-g8b320e7", - "Rev": "8b320e7c550067b1dfb37bd1682e8067023e0751" - }, - { - "ImportPath": "github.com/coreos/etcd/storage/backend", - "Comment": "v2.3.0-282-g8b320e7", - "Rev": "8b320e7c550067b1dfb37bd1682e8067023e0751" - }, - { - "ImportPath": "github.com/coreos/etcd/storage/storagepb", - "Comment": "v2.3.0-282-g8b320e7", - "Rev": "8b320e7c550067b1dfb37bd1682e8067023e0751" + "Comment": "v3.0.4", + "Rev": "d53923c636e0e4ab7f00cb75681b97a8f11f5a9d" }, { "ImportPath": "github.com/coreos/etcd/store", - "Comment": "v2.3.0-282-g8b320e7", - "Rev": "8b320e7c550067b1dfb37bd1682e8067023e0751" + "Comment": "v3.0.4", + "Rev": "d53923c636e0e4ab7f00cb75681b97a8f11f5a9d" }, { "ImportPath": "github.com/coreos/etcd/version", - "Comment": "v2.3.0-282-g8b320e7", - "Rev": "8b320e7c550067b1dfb37bd1682e8067023e0751" + "Comment": "v3.0.4", + "Rev": "d53923c636e0e4ab7f00cb75681b97a8f11f5a9d" }, { "ImportPath": "github.com/coreos/etcd/wal", - "Comment": "v2.3.0-282-g8b320e7", - "Rev": "8b320e7c550067b1dfb37bd1682e8067023e0751" + "Comment": "v3.0.4", + "Rev": "d53923c636e0e4ab7f00cb75681b97a8f11f5a9d" }, { "ImportPath": "github.com/coreos/etcd/wal/walpb", - "Comment": "v2.3.0-282-g8b320e7", - "Rev": "8b320e7c550067b1dfb37bd1682e8067023e0751" + "Comment": "v3.0.4", + "Rev": "d53923c636e0e4ab7f00cb75681b97a8f11f5a9d" }, { "ImportPath": "github.com/coreos/go-oidc/http", @@ -613,7 +613,7 @@ }, { "ImportPath": "github.com/coreos/go-semver/semver", - "Rev": "d043ae190b3202550d026daf009359bb5d761672" + "Rev": "568e959cd89871e61434c1143528d9162da89ef2" }, { "ImportPath": "github.com/coreos/go-systemd/activation", @@ -647,33 +647,33 @@ }, { "ImportPath": "github.com/coreos/pkg/capnslog", - "Comment": "v2", - "Rev": "7f080b6c11ac2d2347c3cd7521e810207ea1a041" + "Comment": "v2-8-gfa29b1d", + "Rev": "fa29b1d70f0beaddd4c7021607cc3c3be8ce94b8" }, { "ImportPath": "github.com/coreos/pkg/dlopen", - "Comment": "v2", - "Rev": "7f080b6c11ac2d2347c3cd7521e810207ea1a041" + "Comment": "v2-8-gfa29b1d", + "Rev": "fa29b1d70f0beaddd4c7021607cc3c3be8ce94b8" }, { "ImportPath": "github.com/coreos/pkg/health", - "Comment": "v2", - "Rev": "7f080b6c11ac2d2347c3cd7521e810207ea1a041" + "Comment": "v2-8-gfa29b1d", + "Rev": "fa29b1d70f0beaddd4c7021607cc3c3be8ce94b8" }, { "ImportPath": "github.com/coreos/pkg/httputil", - "Comment": "v2", - "Rev": "7f080b6c11ac2d2347c3cd7521e810207ea1a041" + "Comment": "v2-8-gfa29b1d", + "Rev": "fa29b1d70f0beaddd4c7021607cc3c3be8ce94b8" }, { "ImportPath": "github.com/coreos/pkg/timeutil", - "Comment": "v2", - "Rev": "7f080b6c11ac2d2347c3cd7521e810207ea1a041" + "Comment": "v2-8-gfa29b1d", + "Rev": "fa29b1d70f0beaddd4c7021607cc3c3be8ce94b8" }, { "ImportPath": "github.com/coreos/rkt/api/v1alpha", - "Comment": "v1.6.0", - "Rev": "14437382a98e5ebeb6cafb57cff445370e3f7d56" + "Comment": "v1.11.0-59-ga83419b", + "Rev": "a83419be28ac626876f94a28b4df2dbc9eac7448" }, { "ImportPath": "github.com/cpuguy83/go-md2man/md2man", @@ -895,123 +895,128 @@ }, { "ImportPath": "github.com/gogo/protobuf/gogoproto", - "Comment": "v0.1-125-g82d16f7", - "Rev": "82d16f734d6d871204a3feb1a73cb220cc92574c" + "Comment": "v0.2-33-ge18d7aa", + "Rev": "e18d7aa8f8c624c915db340349aad4c49b10d173" + }, + { + "ImportPath": "github.com/gogo/protobuf/plugin/compare", + "Comment": "v0.2-33-ge18d7aa", + "Rev": "e18d7aa8f8c624c915db340349aad4c49b10d173" }, { "ImportPath": "github.com/gogo/protobuf/plugin/defaultcheck", - "Comment": "v0.1-125-g82d16f7", - "Rev": "82d16f734d6d871204a3feb1a73cb220cc92574c" + "Comment": "v0.2-33-ge18d7aa", + "Rev": "e18d7aa8f8c624c915db340349aad4c49b10d173" }, { "ImportPath": "github.com/gogo/protobuf/plugin/description", - "Comment": "v0.1-125-g82d16f7", - "Rev": "82d16f734d6d871204a3feb1a73cb220cc92574c" + "Comment": "v0.2-33-ge18d7aa", + "Rev": "e18d7aa8f8c624c915db340349aad4c49b10d173" }, { "ImportPath": "github.com/gogo/protobuf/plugin/embedcheck", - "Comment": "v0.1-125-g82d16f7", - "Rev": "82d16f734d6d871204a3feb1a73cb220cc92574c" + "Comment": "v0.2-33-ge18d7aa", + "Rev": "e18d7aa8f8c624c915db340349aad4c49b10d173" }, { "ImportPath": "github.com/gogo/protobuf/plugin/enumstringer", - "Comment": "v0.1-125-g82d16f7", - "Rev": "82d16f734d6d871204a3feb1a73cb220cc92574c" + "Comment": "v0.2-33-ge18d7aa", + "Rev": "e18d7aa8f8c624c915db340349aad4c49b10d173" }, { "ImportPath": "github.com/gogo/protobuf/plugin/equal", - "Comment": "v0.1-125-g82d16f7", - "Rev": "82d16f734d6d871204a3feb1a73cb220cc92574c" + "Comment": "v0.2-33-ge18d7aa", + "Rev": "e18d7aa8f8c624c915db340349aad4c49b10d173" }, { "ImportPath": "github.com/gogo/protobuf/plugin/face", - "Comment": "v0.1-125-g82d16f7", - "Rev": "82d16f734d6d871204a3feb1a73cb220cc92574c" + "Comment": "v0.2-33-ge18d7aa", + "Rev": "e18d7aa8f8c624c915db340349aad4c49b10d173" }, { "ImportPath": "github.com/gogo/protobuf/plugin/gostring", - "Comment": "v0.1-125-g82d16f7", - "Rev": "82d16f734d6d871204a3feb1a73cb220cc92574c" - }, - { - "ImportPath": "github.com/gogo/protobuf/plugin/grpc", - "Comment": "v0.1-125-g82d16f7", - "Rev": "82d16f734d6d871204a3feb1a73cb220cc92574c" + "Comment": "v0.2-33-ge18d7aa", + "Rev": "e18d7aa8f8c624c915db340349aad4c49b10d173" }, { "ImportPath": "github.com/gogo/protobuf/plugin/marshalto", - "Comment": "v0.1-125-g82d16f7", - "Rev": "82d16f734d6d871204a3feb1a73cb220cc92574c" + "Comment": "v0.2-33-ge18d7aa", + "Rev": "e18d7aa8f8c624c915db340349aad4c49b10d173" }, { "ImportPath": "github.com/gogo/protobuf/plugin/oneofcheck", - "Comment": "v0.1-125-g82d16f7", - "Rev": "82d16f734d6d871204a3feb1a73cb220cc92574c" + "Comment": "v0.2-33-ge18d7aa", + "Rev": "e18d7aa8f8c624c915db340349aad4c49b10d173" }, { "ImportPath": "github.com/gogo/protobuf/plugin/populate", - "Comment": "v0.1-125-g82d16f7", - "Rev": "82d16f734d6d871204a3feb1a73cb220cc92574c" + "Comment": "v0.2-33-ge18d7aa", + "Rev": "e18d7aa8f8c624c915db340349aad4c49b10d173" }, { "ImportPath": "github.com/gogo/protobuf/plugin/size", - "Comment": "v0.1-125-g82d16f7", - "Rev": "82d16f734d6d871204a3feb1a73cb220cc92574c" + "Comment": "v0.2-33-ge18d7aa", + "Rev": "e18d7aa8f8c624c915db340349aad4c49b10d173" }, { "ImportPath": "github.com/gogo/protobuf/plugin/stringer", - "Comment": "v0.1-125-g82d16f7", - "Rev": "82d16f734d6d871204a3feb1a73cb220cc92574c" + "Comment": "v0.2-33-ge18d7aa", + "Rev": "e18d7aa8f8c624c915db340349aad4c49b10d173" }, { "ImportPath": "github.com/gogo/protobuf/plugin/testgen", - "Comment": "v0.1-125-g82d16f7", - "Rev": "82d16f734d6d871204a3feb1a73cb220cc92574c" + "Comment": "v0.2-33-ge18d7aa", + "Rev": "e18d7aa8f8c624c915db340349aad4c49b10d173" }, { "ImportPath": "github.com/gogo/protobuf/plugin/union", - "Comment": "v0.1-125-g82d16f7", - "Rev": "82d16f734d6d871204a3feb1a73cb220cc92574c" + "Comment": "v0.2-33-ge18d7aa", + "Rev": "e18d7aa8f8c624c915db340349aad4c49b10d173" }, { "ImportPath": "github.com/gogo/protobuf/plugin/unmarshal", - "Comment": "v0.1-125-g82d16f7", - "Rev": "82d16f734d6d871204a3feb1a73cb220cc92574c" + "Comment": "v0.2-33-ge18d7aa", + "Rev": "e18d7aa8f8c624c915db340349aad4c49b10d173" }, { "ImportPath": "github.com/gogo/protobuf/proto", - "Comment": "v0.1-125-g82d16f7", - "Rev": "82d16f734d6d871204a3feb1a73cb220cc92574c" + "Comment": "v0.2-33-ge18d7aa", + "Rev": "e18d7aa8f8c624c915db340349aad4c49b10d173" }, { "ImportPath": "github.com/gogo/protobuf/protoc-gen-gogo/descriptor", - "Comment": "v0.1-125-g82d16f7", - "Rev": "82d16f734d6d871204a3feb1a73cb220cc92574c" + "Comment": "v0.2-33-ge18d7aa", + "Rev": "e18d7aa8f8c624c915db340349aad4c49b10d173" }, { "ImportPath": "github.com/gogo/protobuf/protoc-gen-gogo/generator", - "Comment": "v0.1-125-g82d16f7", - "Rev": "82d16f734d6d871204a3feb1a73cb220cc92574c" + "Comment": "v0.2-33-ge18d7aa", + "Rev": "e18d7aa8f8c624c915db340349aad4c49b10d173" + }, + { + "ImportPath": "github.com/gogo/protobuf/protoc-gen-gogo/grpc", + "Comment": "v0.2-33-ge18d7aa", + "Rev": "e18d7aa8f8c624c915db340349aad4c49b10d173" }, { "ImportPath": "github.com/gogo/protobuf/protoc-gen-gogo/plugin", - "Comment": "v0.1-125-g82d16f7", - "Rev": "82d16f734d6d871204a3feb1a73cb220cc92574c" + "Comment": "v0.2-33-ge18d7aa", + "Rev": "e18d7aa8f8c624c915db340349aad4c49b10d173" }, { "ImportPath": "github.com/gogo/protobuf/sortkeys", - "Comment": "v0.1-125-g82d16f7", - "Rev": "82d16f734d6d871204a3feb1a73cb220cc92574c" + "Comment": "v0.2-33-ge18d7aa", + "Rev": "e18d7aa8f8c624c915db340349aad4c49b10d173" }, { "ImportPath": "github.com/gogo/protobuf/vanity", - "Comment": "v0.1-125-g82d16f7", - "Rev": "82d16f734d6d871204a3feb1a73cb220cc92574c" + "Comment": "v0.2-33-ge18d7aa", + "Rev": "e18d7aa8f8c624c915db340349aad4c49b10d173" }, { "ImportPath": "github.com/gogo/protobuf/vanity/command", - "Comment": "v0.1-125-g82d16f7", - "Rev": "82d16f734d6d871204a3feb1a73cb220cc92574c" + "Comment": "v0.2-33-ge18d7aa", + "Rev": "e18d7aa8f8c624c915db340349aad4c49b10d173" }, { "ImportPath": "github.com/golang/glog", @@ -1019,19 +1024,23 @@ }, { "ImportPath": "github.com/golang/groupcache/lru", - "Rev": "604ed5785183e59ae2789449d89e73f3a2a77987" + "Rev": "02826c3e79038b59d737d3b1c0a1d937f71a4433" }, { "ImportPath": "github.com/golang/mock/gomock", "Rev": "bd3c8e81be01eef76d4b503f5e687d2d1354d2d9" }, + { + "ImportPath": "github.com/golang/protobuf/jsonpb", + "Rev": "8616e8ee5e20a1704615e6c8d7afcdac06087a67" + }, { "ImportPath": "github.com/golang/protobuf/proto", - "Rev": "b982704f8bb716bb608144408cff30e15fbde841" + "Rev": "8616e8ee5e20a1704615e6c8d7afcdac06087a67" }, { "ImportPath": "github.com/google/btree", - "Rev": "cc6329d4279e3f025a53a83c397d2339b5705c45" + "Rev": "7d79101e329e5a3adf994758c578dab82b90c017" }, { "ImportPath": "github.com/google/cadvisor/api", @@ -1270,6 +1279,21 @@ "ImportPath": "github.com/gorilla/mux", "Rev": "8096f47503459bcc74d1f4c487b7e6e42e5746b5" }, + { + "ImportPath": "github.com/grpc-ecosystem/grpc-gateway/runtime", + "Comment": "v1.0.0-8-gf52d055", + "Rev": "f52d055dc48aec25854ed7d31862f78913cf17d1" + }, + { + "ImportPath": "github.com/grpc-ecosystem/grpc-gateway/runtime/internal", + "Comment": "v1.0.0-8-gf52d055", + "Rev": "f52d055dc48aec25854ed7d31862f78913cf17d1" + }, + { + "ImportPath": "github.com/grpc-ecosystem/grpc-gateway/utilities", + "Comment": "v1.0.0-8-gf52d055", + "Rev": "f52d055dc48aec25854ed7d31862f78913cf17d1" + }, { "ImportPath": "github.com/hashicorp/go-msgpack/codec", "Rev": "fa3f63826f7c23912c15263591e65d54d080b458" @@ -1351,7 +1375,7 @@ }, { "ImportPath": "github.com/jonboulle/clockwork", - "Rev": "3f831b65b61282ba6bece21b91beea2edc4c887a" + "Rev": "72f9bd7c4e0c2a40055ab3d0f09654f730cce982" }, { "ImportPath": "github.com/juju/ratelimit", @@ -1736,8 +1760,8 @@ }, { "ImportPath": "github.com/prometheus/client_golang/prometheus", - "Comment": "0.7.0-39-g3b78d7a", - "Rev": "3b78d7a77f51ccbc364d4bc170920153022cfd08" + "Comment": "0.7.0-52-ge51041b", + "Rev": "e51041b3fa41cece0dca035740ba6411905be473" }, { "ImportPath": "github.com/prometheus/client_model/go", @@ -1746,19 +1770,15 @@ }, { "ImportPath": "github.com/prometheus/common/expfmt", - "Rev": "a6ab08426bb262e2d190097751f5cfd1cfdfd17d" - }, - { - "ImportPath": "github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg", - "Rev": "a6ab08426bb262e2d190097751f5cfd1cfdfd17d" + "Rev": "ffe929a3f4c4faeaa10f2b9535c2b1be3ad15650" }, { "ImportPath": "github.com/prometheus/common/model", - "Rev": "a6ab08426bb262e2d190097751f5cfd1cfdfd17d" + "Rev": "ffe929a3f4c4faeaa10f2b9535c2b1be3ad15650" }, { "ImportPath": "github.com/prometheus/procfs", - "Rev": "490cc6eb5fa45bf8a8b7b73c8bc82a8160e8531d" + "Rev": "454a56f35412459b5e684fd5ec0f9211b94f002a" }, { "ImportPath": "github.com/rackspace/gophercloud", @@ -1927,8 +1947,8 @@ }, { "ImportPath": "github.com/russross/blackfriday", - "Comment": "v1.2-42-g77efab5", - "Rev": "77efab57b2f74dd3f9051c79752b2e8995c8b789" + "Comment": "v1.4-2-g300106c", + "Rev": "300106c228d52c8941d4b3de6054a6062a86dda3" }, { "ImportPath": "github.com/samuel/go-zookeeper/zk", @@ -2004,11 +2024,11 @@ }, { "ImportPath": "github.com/ugorji/go/codec", - "Rev": "f4485b318aadd133842532f841dc205a8e339d74" + "Rev": "f1f1a805ed361a0e078bb537e4ea78cd37dcf065" }, { "ImportPath": "github.com/ugorji/go/codec/codecgen", - "Rev": "f4485b318aadd133842532f841dc205a8e339d74" + "Rev": "f1f1a805ed361a0e078bb537e4ea78cd37dcf065" }, { "ImportPath": "github.com/vishvananda/netlink", @@ -2200,7 +2220,7 @@ }, { "ImportPath": "golang.org/x/sys/unix", - "Rev": "833a04a10549a95dc34458c195cbad61bbb6cb4d" + "Rev": "9c60d1c508f5134d1ca726b4641db998f2523357" }, { "ImportPath": "google.golang.org/api/cloudmonitoring/v2beta2", @@ -2240,35 +2260,48 @@ }, { "ImportPath": "google.golang.org/grpc", - "Rev": "933601d8cd6418a8a891bd9075a7161b0a67badb" + "Comment": "v1.0.0-6-g02fca89", + "Rev": "02fca896ff5f50c6bbbee0860345a49344b37a03" }, { "ImportPath": "google.golang.org/grpc/codes", - "Rev": "933601d8cd6418a8a891bd9075a7161b0a67badb" + "Comment": "v1.0.0-6-g02fca89", + "Rev": "02fca896ff5f50c6bbbee0860345a49344b37a03" }, { "ImportPath": "google.golang.org/grpc/credentials", - "Rev": "933601d8cd6418a8a891bd9075a7161b0a67badb" + "Comment": "v1.0.0-6-g02fca89", + "Rev": "02fca896ff5f50c6bbbee0860345a49344b37a03" }, { "ImportPath": "google.golang.org/grpc/grpclog", - "Rev": "933601d8cd6418a8a891bd9075a7161b0a67badb" + "Comment": "v1.0.0-6-g02fca89", + "Rev": "02fca896ff5f50c6bbbee0860345a49344b37a03" + }, + { + "ImportPath": "google.golang.org/grpc/internal", + "Comment": "v1.0.0-6-g02fca89", + "Rev": "02fca896ff5f50c6bbbee0860345a49344b37a03" }, { "ImportPath": "google.golang.org/grpc/metadata", - "Rev": "933601d8cd6418a8a891bd9075a7161b0a67badb" + "Comment": "v1.0.0-6-g02fca89", + "Rev": "02fca896ff5f50c6bbbee0860345a49344b37a03" }, { "ImportPath": "google.golang.org/grpc/naming", - "Rev": "933601d8cd6418a8a891bd9075a7161b0a67badb" + "Comment": "v1.0.0-6-g02fca89", + "Rev": "02fca896ff5f50c6bbbee0860345a49344b37a03" }, { "ImportPath": "google.golang.org/grpc/peer", - "Rev": "933601d8cd6418a8a891bd9075a7161b0a67badb" + "Comment": "v1.0.0-6-g02fca89", + "Rev": "02fca896ff5f50c6bbbee0860345a49344b37a03" }, { "ImportPath": "google.golang.org/grpc/transport", - "Rev": "933601d8cd6418a8a891bd9075a7161b0a67badb" + "Comment": "v1.0.0-6-g02fca89", + "Rev": "02fca896ff5f50c6bbbee0860345a49344b37a03" }, { "ImportPath": "gopkg.in/gcfg.v1", @@ -2302,7 +2335,7 @@ }, { "ImportPath": "gopkg.in/yaml.v2", - "Rev": "a83829b6f1293c91addabc89d0571c246397bbf4" + "Rev": "53feefa2559fb8dfa8d81baad31be332c97d6c77" }, { "ImportPath": "k8s.io/heapster/metrics/api/v1/types", diff --git a/Godeps/LICENSES b/Godeps/LICENSES index 0c358708663..e779997b66c 100644 --- a/Godeps/LICENSES +++ b/Godeps/LICENSES @@ -14287,6 +14287,636 @@ SOFTWARE. ================================================================================ +================================================================================ += vendor/github.com/coreos/etcd/mvcc licensed under: = + + + 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. + += vendor/github.com/coreos/etcd/LICENSE 3b83ef96387f14655fc854ddc3c6bd57 - +================================================================================ + + +================================================================================ += vendor/github.com/coreos/etcd/mvcc/backend licensed under: = + + + 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. + += vendor/github.com/coreos/etcd/LICENSE 3b83ef96387f14655fc854ddc3c6bd57 - +================================================================================ + + +================================================================================ += vendor/github.com/coreos/etcd/mvcc/mvccpb licensed under: = + + + 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. + += vendor/github.com/coreos/etcd/LICENSE 3b83ef96387f14655fc854ddc3c6bd57 - +================================================================================ + + ================================================================================ = vendor/github.com/coreos/etcd/pkg/adt licensed under: = @@ -19117,636 +19747,6 @@ SOFTWARE. ================================================================================ -================================================================================ -= vendor/github.com/coreos/etcd/storage licensed under: = - - - 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. - -= vendor/github.com/coreos/etcd/LICENSE 3b83ef96387f14655fc854ddc3c6bd57 - -================================================================================ - - -================================================================================ -= vendor/github.com/coreos/etcd/storage/backend licensed under: = - - - 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. - -= vendor/github.com/coreos/etcd/LICENSE 3b83ef96387f14655fc854ddc3c6bd57 - -================================================================================ - - -================================================================================ -= vendor/github.com/coreos/etcd/storage/storagepb licensed under: = - - - 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. - -= vendor/github.com/coreos/etcd/LICENSE 3b83ef96387f14655fc854ddc3c6bd57 - -================================================================================ - - ================================================================================ = vendor/github.com/coreos/etcd/store licensed under: = @@ -31306,6 +31306,50 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ================================================================================ +================================================================================ += vendor/github.com/gogo/protobuf/plugin/compare licensed under: = + +Extensions for Protocol Buffers to create more go like structures. + +Copyright (c) 2013, Vastech SA (PTY) LTD. All rights reserved. +http://github.com/gogo/protobuf/gogoproto + +Go support for Protocol Buffers - Google's data interchange format + +Copyright 2010 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. + + += vendor/github.com/gogo/protobuf/LICENSE 4e3a8f29922ea8f0b9e84d8324c515a7 - +================================================================================ + + ================================================================================ = vendor/github.com/gogo/protobuf/plugin/defaultcheck licensed under: = @@ -31614,50 +31658,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ================================================================================ -================================================================================ -= vendor/github.com/gogo/protobuf/plugin/grpc licensed under: = - -Extensions for Protocol Buffers to create more go like structures. - -Copyright (c) 2013, Vastech SA (PTY) LTD. All rights reserved. -http://github.com/gogo/protobuf/gogoproto - -Go support for Protocol Buffers - Google's data interchange format - -Copyright 2010 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. - - -= vendor/github.com/gogo/protobuf/LICENSE 4e3a8f29922ea8f0b9e84d8324c515a7 - -================================================================================ - - ================================================================================ = vendor/github.com/gogo/protobuf/plugin/marshalto licensed under: = @@ -32142,6 +32142,50 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ================================================================================ +================================================================================ += vendor/github.com/gogo/protobuf/protoc-gen-gogo/grpc licensed under: = + +Extensions for Protocol Buffers to create more go like structures. + +Copyright (c) 2013, Vastech SA (PTY) LTD. All rights reserved. +http://github.com/gogo/protobuf/gogoproto + +Go support for Protocol Buffers - Google's data interchange format + +Copyright 2010 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. + + += vendor/github.com/gogo/protobuf/LICENSE 4e3a8f29922ea8f0b9e84d8324c515a7 - +================================================================================ + + ================================================================================ = vendor/github.com/gogo/protobuf/protoc-gen-gogo/plugin licensed under: = @@ -32926,6 +32970,45 @@ third-party archives. ================================================================================ +================================================================================ += vendor/github.com/golang/protobuf/jsonpb licensed under: = + +Go support for Protocol Buffers - Google's data interchange format + +Copyright 2010 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. + + += vendor/github.com/golang/protobuf/LICENSE 14db3a56c3796a940ba32948a15f97d0 - +================================================================================ + + ================================================================================ = vendor/github.com/golang/protobuf/proto licensed under: = @@ -42623,6 +42706,111 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ================================================================================ +================================================================================ += vendor/github.com/grpc-ecosystem/grpc-gateway/runtime licensed under: = + +Copyright (c) 2015, Gengo, Inc. +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 Gengo, 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. + += vendor/github.com/grpc-ecosystem/grpc-gateway/LICENSE.txt c510a2a01572b82d27f28fd4d02ca318 - +================================================================================ + + +================================================================================ += vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/internal licensed under: = + +Copyright (c) 2015, Gengo, Inc. +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 Gengo, 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. + += vendor/github.com/grpc-ecosystem/grpc-gateway/LICENSE.txt c510a2a01572b82d27f28fd4d02ca318 - +================================================================================ + + +================================================================================ += vendor/github.com/grpc-ecosystem/grpc-gateway/utilities licensed under: = + +Copyright (c) 2015, Gengo, Inc. +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 Gengo, 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. + += vendor/github.com/grpc-ecosystem/grpc-gateway/LICENSE.txt c510a2a01572b82d27f28fd4d02ca318 - +================================================================================ + + ================================================================================ = vendor/github.com/hashicorp/go-msgpack/codec licensed under: = @@ -53891,215 +54079,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ================================================================================ -================================================================================ -= vendor/github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg licensed under: = - - 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. - -= vendor/github.com/prometheus/common/LICENSE 86d3f3a95c324c9479bd8986968f4327 - -================================================================================ - - ================================================================================ = vendor/github.com/prometheus/common/model licensed under: = @@ -67127,6 +67106,42 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ================================================================================ +================================================================================ += vendor/google.golang.org/grpc/internal licensed under: = + +Copyright 2014, Google Inc. +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. + += vendor/google.golang.org/grpc/LICENSE a4bad33881612090c6035d8393175996 - +================================================================================ + + ================================================================================ = vendor/google.golang.org/grpc/metadata licensed under: = diff --git a/vendor/github.com/boltdb/bolt/README.md b/vendor/github.com/boltdb/bolt/README.md index 82e85742c04..3bff3cce4b0 100644 --- a/vendor/github.com/boltdb/bolt/README.md +++ b/vendor/github.com/boltdb/bolt/README.md @@ -1,4 +1,4 @@ -Bolt [![Build Status](https://drone.io/github.com/boltdb/bolt/status.png)](https://drone.io/github.com/boltdb/bolt/latest) [![Coverage Status](https://coveralls.io/repos/boltdb/bolt/badge.svg?branch=master)](https://coveralls.io/r/boltdb/bolt?branch=master) [![GoDoc](https://godoc.org/github.com/boltdb/bolt?status.svg)](https://godoc.org/github.com/boltdb/bolt) ![Version](https://img.shields.io/badge/version-1.0-green.svg) +Bolt [![Coverage Status](https://coveralls.io/repos/boltdb/bolt/badge.svg?branch=master)](https://coveralls.io/r/boltdb/bolt?branch=master) [![GoDoc](https://godoc.org/github.com/boltdb/bolt?status.svg)](https://godoc.org/github.com/boltdb/bolt) ![Version](https://img.shields.io/badge/version-1.0-green.svg) ==== Bolt is a pure Go key/value store inspired by [Howard Chu's][hyc_symas] @@ -427,6 +427,8 @@ db.View(func(tx *bolt.Tx) error { }) ``` +Note that, while RFC3339 is sortable, the Golang implementation of RFC3339Nano does not use a fixed number of digits after the decimal point and is therefore not sortable. + #### ForEach() @@ -437,7 +439,7 @@ all the keys in a bucket: db.View(func(tx *bolt.Tx) error { // Assume bucket exists and has keys b := tx.Bucket([]byte("MyBucket")) - + b.ForEach(func(k, v []byte) error { fmt.Printf("key=%s, value=%s\n", k, v) return nil @@ -617,7 +619,7 @@ Boltmobiledemo.BoltDB boltDB = Boltmobiledemo.NewBoltDB(path) { NSURL* URL= [NSURL fileURLWithPath: filePathString]; assert([[NSFileManager defaultManager] fileExistsAtPath: [URL path]]); - + NSError *error = nil; BOOL success = [URL setResourceValue: [NSNumber numberWithBool: YES] forKey: NSURLIsExcludedFromBackupKey error: &error]; @@ -835,6 +837,14 @@ Below is a list of public, open source projects that use Bolt: backed by boltdb. * [buckets](https://github.com/joyrexus/buckets) - a bolt wrapper streamlining simple tx and key scans. +* [mbuckets](https://github.com/abhigupta912/mbuckets) - A Bolt wrapper that allows easy operations on multi level (nested) buckets. * [Request Baskets](https://github.com/darklynx/request-baskets) - A web service to collect arbitrary HTTP requests and inspect them via REST API or simple web UI, similar to [RequestBin](http://requestb.in/) service +* [Go Report Card](https://goreportcard.com/) - Go code quality report cards as a (free and open source) service. +* [Boltdb Boilerplate](https://github.com/bobintornado/boltdb-boilerplate) - Boilerplate wrapper around bolt aiming to make simple calls one-liners. +* [lru](https://github.com/crowdriff/lru) - Easy to use Bolt-backed Least-Recently-Used (LRU) read-through cache with chainable remote stores. +* [Storm](https://github.com/asdine/storm) - A simple ORM around BoltDB. +* [GoWebApp](https://github.com/josephspurrier/gowebapp) - A basic MVC web application in Go using BoltDB. +* [SimpleBolt](https://github.com/xyproto/simplebolt) - A simple way to use BoltDB. Deals mainly with strings. +* [Algernon](https://github.com/xyproto/algernon) - A HTTP/2 web server with built-in support for Lua. Uses BoltDB as the default database backend. If you are using Bolt in a project please send a pull request to add it to the list. diff --git a/vendor/github.com/boltdb/bolt/appveyor.yml b/vendor/github.com/boltdb/bolt/appveyor.yml new file mode 100644 index 00000000000..6e26e941d68 --- /dev/null +++ b/vendor/github.com/boltdb/bolt/appveyor.yml @@ -0,0 +1,18 @@ +version: "{build}" + +os: Windows Server 2012 R2 + +clone_folder: c:\gopath\src\github.com\boltdb\bolt + +environment: + GOPATH: c:\gopath + +install: + - echo %PATH% + - echo %GOPATH% + - go version + - go env + - go get -v -t ./... + +build_script: + - go test -v ./... diff --git a/vendor/github.com/boltdb/bolt/bolt_ppc.go b/vendor/github.com/boltdb/bolt/bolt_ppc.go new file mode 100644 index 00000000000..645ddc3edc2 --- /dev/null +++ b/vendor/github.com/boltdb/bolt/bolt_ppc.go @@ -0,0 +1,9 @@ +// +build ppc + +package bolt + +// maxMapSize represents the largest mmap size supported by Bolt. +const maxMapSize = 0x7FFFFFFF // 2GB + +// maxAllocSize is the size used when creating array pointers. +const maxAllocSize = 0xFFFFFFF diff --git a/vendor/github.com/boltdb/bolt/bolt_ppc64.go b/vendor/github.com/boltdb/bolt/bolt_ppc64.go new file mode 100644 index 00000000000..2dc6be02e3e --- /dev/null +++ b/vendor/github.com/boltdb/bolt/bolt_ppc64.go @@ -0,0 +1,9 @@ +// +build ppc64 + +package bolt + +// maxMapSize represents the largest mmap size supported by Bolt. +const maxMapSize = 0xFFFFFFFFFFFF // 256TB + +// maxAllocSize is the size used when creating array pointers. +const maxAllocSize = 0x7FFFFFFF diff --git a/vendor/github.com/boltdb/bolt/bolt_unix.go b/vendor/github.com/boltdb/bolt/bolt_unix.go index 4b0723aac23..cad62dda1e3 100644 --- a/vendor/github.com/boltdb/bolt/bolt_unix.go +++ b/vendor/github.com/boltdb/bolt/bolt_unix.go @@ -11,7 +11,7 @@ import ( ) // flock acquires an advisory lock on a file descriptor. -func flock(f *os.File, exclusive bool, timeout time.Duration) error { +func flock(db *DB, mode os.FileMode, exclusive bool, timeout time.Duration) error { var t time.Time for { // If we're beyond our timeout then return an error. @@ -27,7 +27,7 @@ func flock(f *os.File, exclusive bool, timeout time.Duration) error { } // Otherwise attempt to obtain an exclusive lock. - err := syscall.Flock(int(f.Fd()), flag|syscall.LOCK_NB) + err := syscall.Flock(int(db.file.Fd()), flag|syscall.LOCK_NB) if err == nil { return nil } else if err != syscall.EWOULDBLOCK { @@ -40,8 +40,8 @@ func flock(f *os.File, exclusive bool, timeout time.Duration) error { } // funlock releases an advisory lock on a file descriptor. -func funlock(f *os.File) error { - return syscall.Flock(int(f.Fd()), syscall.LOCK_UN) +func funlock(db *DB) error { + return syscall.Flock(int(db.file.Fd()), syscall.LOCK_UN) } // mmap memory maps a DB's data file. diff --git a/vendor/github.com/boltdb/bolt/bolt_unix_solaris.go b/vendor/github.com/boltdb/bolt/bolt_unix_solaris.go index 1c4e48d63a0..307bf2b3ee9 100644 --- a/vendor/github.com/boltdb/bolt/bolt_unix_solaris.go +++ b/vendor/github.com/boltdb/bolt/bolt_unix_solaris.go @@ -11,7 +11,7 @@ import ( ) // flock acquires an advisory lock on a file descriptor. -func flock(f *os.File, exclusive bool, timeout time.Duration) error { +func flock(db *DB, mode os.FileMode, exclusive bool, timeout time.Duration) error { var t time.Time for { // If we're beyond our timeout then return an error. @@ -32,7 +32,7 @@ func flock(f *os.File, exclusive bool, timeout time.Duration) error { } else { lock.Type = syscall.F_RDLCK } - err := syscall.FcntlFlock(f.Fd(), syscall.F_SETLK, &lock) + err := syscall.FcntlFlock(db.file.Fd(), syscall.F_SETLK, &lock) if err == nil { return nil } else if err != syscall.EAGAIN { @@ -45,13 +45,13 @@ func flock(f *os.File, exclusive bool, timeout time.Duration) error { } // funlock releases an advisory lock on a file descriptor. -func funlock(f *os.File) error { +func funlock(db *DB) error { var lock syscall.Flock_t lock.Start = 0 lock.Len = 0 lock.Type = syscall.F_UNLCK lock.Whence = 0 - return syscall.FcntlFlock(uintptr(f.Fd()), syscall.F_SETLK, &lock) + return syscall.FcntlFlock(uintptr(db.file.Fd()), syscall.F_SETLK, &lock) } // mmap memory maps a DB's data file. diff --git a/vendor/github.com/boltdb/bolt/bolt_windows.go b/vendor/github.com/boltdb/bolt/bolt_windows.go index 91c4968f6a1..d538e6afd77 100644 --- a/vendor/github.com/boltdb/bolt/bolt_windows.go +++ b/vendor/github.com/boltdb/bolt/bolt_windows.go @@ -16,6 +16,8 @@ var ( ) const ( + lockExt = ".lock" + // see https://msdn.microsoft.com/en-us/library/windows/desktop/aa365203(v=vs.85).aspx flagLockExclusive = 2 flagLockFailImmediately = 1 @@ -46,7 +48,16 @@ func fdatasync(db *DB) error { } // flock acquires an advisory lock on a file descriptor. -func flock(f *os.File, exclusive bool, timeout time.Duration) error { +func flock(db *DB, mode os.FileMode, exclusive bool, timeout time.Duration) error { + // Create a separate lock file on windows because a process + // cannot share an exclusive lock on the same file. This is + // needed during Tx.WriteTo(). + f, err := os.OpenFile(db.path+lockExt, os.O_CREATE, mode) + if err != nil { + return err + } + db.lockfile = f + var t time.Time for { // If we're beyond our timeout then return an error. @@ -62,7 +73,7 @@ func flock(f *os.File, exclusive bool, timeout time.Duration) error { flag |= flagLockExclusive } - err := lockFileEx(syscall.Handle(f.Fd()), flag, 0, 1, 0, &syscall.Overlapped{}) + err := lockFileEx(syscall.Handle(db.lockfile.Fd()), flag, 0, 1, 0, &syscall.Overlapped{}) if err == nil { return nil } else if err != errLockViolation { @@ -75,8 +86,11 @@ func flock(f *os.File, exclusive bool, timeout time.Duration) error { } // funlock releases an advisory lock on a file descriptor. -func funlock(f *os.File) error { - return unlockFileEx(syscall.Handle(f.Fd()), 0, 1, 0, &syscall.Overlapped{}) +func funlock(db *DB) error { + err := unlockFileEx(syscall.Handle(db.lockfile.Fd()), 0, 1, 0, &syscall.Overlapped{}) + db.lockfile.Close() + os.Remove(db.path+lockExt) + return err } // mmap memory maps a DB's data file. diff --git a/vendor/github.com/boltdb/bolt/db.go b/vendor/github.com/boltdb/bolt/db.go index 0f1e1bc3d74..1223493ca7b 100644 --- a/vendor/github.com/boltdb/bolt/db.go +++ b/vendor/github.com/boltdb/bolt/db.go @@ -36,6 +36,9 @@ const ( DefaultAllocSize = 16 * 1024 * 1024 ) +// default page size for db is set to the OS page size. +var defaultPageSize = os.Getpagesize() + // DB represents a collection of buckets persisted to a file on disk. // All data access is performed through transactions which can be obtained through the DB. // All the functions on DB will return a ErrDatabaseNotOpen if accessed before Open() is called. @@ -93,7 +96,8 @@ type DB struct { path string file *os.File - dataref []byte // mmap'ed readonly, write throws SEGV + lockfile *os.File // windows only + dataref []byte // mmap'ed readonly, write throws SEGV data *[maxMapSize]byte datasz int filesz int // current on disk file size @@ -106,6 +110,8 @@ type DB struct { freelist *freelist stats Stats + pagePool sync.Pool + batchMu sync.Mutex batch *batch @@ -177,7 +183,7 @@ func Open(path string, mode os.FileMode, options *Options) (*DB, error) { // if !options.ReadOnly. // The database file is locked using the shared lock (more than one process may // hold a lock at the same time) otherwise (options.ReadOnly is set). - if err := flock(db.file, !db.readOnly, options.Timeout); err != nil { + if err := flock(db, mode, !db.readOnly, options.Timeout); err != nil { _ = db.close() return nil, err } @@ -199,12 +205,27 @@ func Open(path string, mode os.FileMode, options *Options) (*DB, error) { if _, err := db.file.ReadAt(buf[:], 0); err == nil { m := db.pageInBuffer(buf[:], 0).meta() if err := m.validate(); err != nil { - return nil, err + // If we can't read the page size, we can assume it's the same + // as the OS -- since that's how the page size was chosen in the + // first place. + // + // If the first page is invalid and this OS uses a different + // page size than what the database was created with then we + // are out of luck and cannot access the database. + db.pageSize = os.Getpagesize() + } else { + db.pageSize = int(m.pageSize) } - db.pageSize = int(m.pageSize) } } + // Initialize page pool. + db.pagePool = sync.Pool{ + New: func() interface{} { + return make([]byte, db.pageSize) + }, + } + // Memory map the data file. if err := db.mmap(options.InitialMmapSize); err != nil { _ = db.close() @@ -261,12 +282,13 @@ func (db *DB) mmap(minsz int) error { db.meta0 = db.page(0).meta() db.meta1 = db.page(1).meta() - // Validate the meta pages. - if err := db.meta0.validate(); err != nil { - return err - } - if err := db.meta1.validate(); err != nil { - return err + // Validate the meta pages. We only return an error if both meta pages fail + // validation, since meta0 failing validation means that it wasn't saved + // properly -- but we can recover using meta1. And vice-versa. + err0 := db.meta0.validate() + err1 := db.meta1.validate() + if err0 != nil && err1 != nil { + return err0 } return nil @@ -338,6 +360,7 @@ func (db *DB) init() error { m.root = bucket{root: 3} m.pgid = 4 m.txid = txid(i) + m.checksum = m.sum64() } // Write an empty freelist at page 3. @@ -379,10 +402,13 @@ func (db *DB) Close() error { } func (db *DB) close() error { + if !db.opened { + return nil + } + db.opened = false db.freelist = nil - db.path = "" // Clear ops. db.ops.writeAt = nil @@ -397,7 +423,7 @@ func (db *DB) close() error { // No need to unlock read-only file. if !db.readOnly { // Unlock the file. - if err := funlock(db.file); err != nil { + if err := funlock(db); err != nil { log.Printf("bolt.Close(): funlock error: %s", err) } } @@ -409,6 +435,7 @@ func (db *DB) close() error { db.file = nil } + db.path = "" return nil } @@ -773,16 +800,37 @@ func (db *DB) pageInBuffer(b []byte, id pgid) *page { // meta retrieves the current meta page reference. func (db *DB) meta() *meta { - if db.meta0.txid > db.meta1.txid { - return db.meta0 + // We have to return the meta with the highest txid which doesn't fail + // validation. Otherwise, we can cause errors when in fact the database is + // in a consistent state. metaA is the one with the higher txid. + metaA := db.meta0 + metaB := db.meta1 + if db.meta1.txid > db.meta0.txid { + metaA = db.meta1 + metaB = db.meta0 } - return db.meta1 + + // Use higher meta page if valid. Otherwise fallback to previous, if valid. + if err := metaA.validate(); err == nil { + return metaA + } else if err := metaB.validate(); err == nil { + return metaB + } + + // This should never be reached, because both meta1 and meta0 were validated + // on mmap() and we do fsync() on every write. + panic("bolt.DB.meta(): invalid meta pages") } // allocate returns a contiguous block of memory starting at a given page. func (db *DB) allocate(count int) (*page, error) { // Allocate a temporary buffer for the page. - buf := make([]byte, count*db.pageSize) + var buf []byte + if count == 1 { + buf = db.pagePool.Get().([]byte) + } else { + buf = make([]byte, count*db.pageSize) + } p := (*page)(unsafe.Pointer(&buf[0])) p.overflow = uint32(count - 1) @@ -824,8 +872,10 @@ func (db *DB) grow(sz int) error { // Truncate and fsync to ensure file size metadata is flushed. // https://github.com/boltdb/bolt/issues/284 if !db.NoGrowSync && !db.readOnly { - if err := db.file.Truncate(int64(sz)); err != nil { - return fmt.Errorf("file resize error: %s", err) + if runtime.GOOS != "windows" { + if err := db.file.Truncate(int64(sz)); err != nil { + return fmt.Errorf("file resize error: %s", err) + } } if err := db.file.Sync(); err != nil { return fmt.Errorf("file sync error: %s", err) @@ -930,12 +980,12 @@ type meta struct { // validate checks the marker bytes and version of the meta page to ensure it matches this binary. func (m *meta) validate() error { - if m.checksum != 0 && m.checksum != m.sum64() { - return ErrChecksum - } else if m.magic != magic { + if m.magic != magic { return ErrInvalid } else if m.version != version { return ErrVersionMismatch + } else if m.checksum != 0 && m.checksum != m.sum64() { + return ErrChecksum } return nil } diff --git a/vendor/github.com/boltdb/bolt/errors.go b/vendor/github.com/boltdb/bolt/errors.go index 6883786d5da..a3620a3ebb2 100644 --- a/vendor/github.com/boltdb/bolt/errors.go +++ b/vendor/github.com/boltdb/bolt/errors.go @@ -12,7 +12,8 @@ var ( // already open. ErrDatabaseOpen = errors.New("database already open") - // ErrInvalid is returned when a data file is not a Bolt-formatted database. + // ErrInvalid is returned when both meta pages on a database are invalid. + // This typically occurs when a file is not a bolt database. ErrInvalid = errors.New("invalid database") // ErrVersionMismatch is returned when the data file was created with a diff --git a/vendor/github.com/boltdb/bolt/node.go b/vendor/github.com/boltdb/bolt/node.go index c9fb21c7314..e9d64af81e3 100644 --- a/vendor/github.com/boltdb/bolt/node.go +++ b/vendor/github.com/boltdb/bolt/node.go @@ -463,43 +463,6 @@ func (n *node) rebalance() { target = n.prevSibling() } - // If target node has extra nodes then just move one over. - if target.numChildren() > target.minKeys() { - if useNextSibling { - // Reparent and move node. - if child, ok := n.bucket.nodes[target.inodes[0].pgid]; ok { - child.parent.removeChild(child) - child.parent = n - child.parent.children = append(child.parent.children, child) - } - n.inodes = append(n.inodes, target.inodes[0]) - target.inodes = target.inodes[1:] - - // Update target key on parent. - target.parent.put(target.key, target.inodes[0].key, nil, target.pgid, 0) - target.key = target.inodes[0].key - _assert(len(target.key) > 0, "rebalance(1): zero-length node key") - } else { - // Reparent and move node. - if child, ok := n.bucket.nodes[target.inodes[len(target.inodes)-1].pgid]; ok { - child.parent.removeChild(child) - child.parent = n - child.parent.children = append(child.parent.children, child) - } - n.inodes = append(n.inodes, inode{}) - copy(n.inodes[1:], n.inodes) - n.inodes[0] = target.inodes[len(target.inodes)-1] - target.inodes = target.inodes[:len(target.inodes)-1] - } - - // Update parent key for node. - n.parent.put(n.key, n.inodes[0].key, nil, n.pgid, 0) - n.key = n.inodes[0].key - _assert(len(n.key) > 0, "rebalance(2): zero-length node key") - - return - } - // If both this node and the target node are too small then merge them. if useNextSibling { // Reparent all child nodes being moved. diff --git a/vendor/github.com/boltdb/bolt/page.go b/vendor/github.com/boltdb/bolt/page.go index 818aa1b1531..4a555286a38 100644 --- a/vendor/github.com/boltdb/bolt/page.go +++ b/vendor/github.com/boltdb/bolt/page.go @@ -111,13 +111,13 @@ type leafPageElement struct { // key returns a byte slice of the node key. func (n *leafPageElement) key() []byte { buf := (*[maxAllocSize]byte)(unsafe.Pointer(n)) - return (*[maxAllocSize]byte)(unsafe.Pointer(&buf[n.pos]))[:n.ksize] + return (*[maxAllocSize]byte)(unsafe.Pointer(&buf[n.pos]))[:n.ksize:n.ksize] } // value returns a byte slice of the node value. func (n *leafPageElement) value() []byte { buf := (*[maxAllocSize]byte)(unsafe.Pointer(n)) - return (*[maxAllocSize]byte)(unsafe.Pointer(&buf[n.pos+n.ksize]))[:n.vsize] + return (*[maxAllocSize]byte)(unsafe.Pointer(&buf[n.pos+n.ksize]))[:n.vsize:n.vsize] } // PageInfo represents human readable information about a page. diff --git a/vendor/github.com/boltdb/bolt/tx.go b/vendor/github.com/boltdb/bolt/tx.go index e74d2cae760..1cfb4cde855 100644 --- a/vendor/github.com/boltdb/bolt/tx.go +++ b/vendor/github.com/boltdb/bolt/tx.go @@ -5,6 +5,7 @@ import ( "io" "os" "sort" + "strings" "time" "unsafe" ) @@ -202,8 +203,17 @@ func (tx *Tx) Commit() error { // If strict mode is enabled then perform a consistency check. // Only the first consistency error is reported in the panic. if tx.db.StrictMode { - if err, ok := <-tx.Check(); ok { - panic("check fail: " + err.Error()) + ch := tx.Check() + var errs []string + for { + err, ok := <-ch + if !ok { + break + } + errs = append(errs, err.Error()) + } + if len(errs) > 0 { + panic("check fail: " + strings.Join(errs, "\n")) } } @@ -297,12 +307,34 @@ func (tx *Tx) WriteTo(w io.Writer) (n int64, err error) { } defer func() { _ = f.Close() }() - // Copy the meta pages. - tx.db.metalock.Lock() - n, err = io.CopyN(w, f, int64(tx.db.pageSize*2)) - tx.db.metalock.Unlock() + // Generate a meta page. We use the same page data for both meta pages. + buf := make([]byte, tx.db.pageSize) + page := (*page)(unsafe.Pointer(&buf[0])) + page.flags = metaPageFlag + *page.meta() = *tx.meta + + // Write meta 0. + page.id = 0 + page.meta().checksum = page.meta().sum64() + nn, err := w.Write(buf) + n += int64(nn) if err != nil { - return n, fmt.Errorf("meta copy: %s", err) + return n, fmt.Errorf("meta 0 copy: %s", err) + } + + // Write meta 1 with a lower transaction id. + page.id = 1 + page.meta().txid -= 1 + page.meta().checksum = page.meta().sum64() + nn, err = w.Write(buf) + n += int64(nn) + if err != nil { + return n, fmt.Errorf("meta 1 copy: %s", err) + } + + // Move past the meta pages in the file. + if _, err := f.Seek(int64(tx.db.pageSize*2), os.SEEK_SET); err != nil { + return n, fmt.Errorf("seek: %s", err) } // Copy data pages. @@ -441,6 +473,8 @@ func (tx *Tx) write() error { for _, p := range tx.pages { pages = append(pages, p) } + // Clear out page cache early. + tx.pages = make(map[pgid]*page) sort.Sort(pages) // Write pages to disk in order. @@ -485,8 +519,22 @@ func (tx *Tx) write() error { } } - // Clear out page cache. - tx.pages = make(map[pgid]*page) + // Put small pages back to page pool. + for _, p := range pages { + // Ignore page sizes over 1 page. + // These are allocated using make() instead of the page pool. + if int(p.overflow) != 0 { + continue + } + + buf := (*[maxAllocSize]byte)(unsafe.Pointer(p))[:tx.db.pageSize] + + // See https://go.googlesource.com/go/+/f03c9202c43e0abb130669852082117ca50aa9b1 + for i := range buf { + buf[i] = 0 + } + tx.db.pagePool.Put(buf) + } return nil } diff --git a/vendor/github.com/coreos/etcd/alarm/alarms.go b/vendor/github.com/coreos/etcd/alarm/alarms.go index 5d5a1bcec9d..4f0ebe93f3b 100644 --- a/vendor/github.com/coreos/etcd/alarm/alarms.go +++ b/vendor/github.com/coreos/etcd/alarm/alarms.go @@ -1,4 +1,4 @@ -// Copyright 2016 CoreOS, Inc. +// 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. @@ -19,8 +19,8 @@ import ( "sync" pb "github.com/coreos/etcd/etcdserver/etcdserverpb" + "github.com/coreos/etcd/mvcc/backend" "github.com/coreos/etcd/pkg/types" - "github.com/coreos/etcd/storage/backend" "github.com/coreos/pkg/capnslog" ) 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 6f37933006e..448e1eaa0d5 100644 --- a/vendor/github.com/coreos/etcd/auth/authpb/auth.pb.go +++ b/vendor/github.com/coreos/etcd/auth/authpb/auth.pb.go @@ -10,6 +10,7 @@ It has these top-level messages: User + Permission Role */ package authpb @@ -17,7 +18,7 @@ package authpb import ( "fmt" - proto "github.com/gogo/protobuf/proto" + proto "github.com/golang/protobuf/proto" math "math" ) @@ -29,29 +30,74 @@ var _ = proto.Marshal var _ = fmt.Errorf var _ = math.Inf -// User is a single entry in the bucket authUsers -type User struct { - Name []byte `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - Password []byte `protobuf:"bytes,2,opt,name=password,proto3" json:"password,omitempty"` - Tombstone int64 `protobuf:"varint,3,opt,name=tombstone,proto3" json:"tombstone,omitempty"` +// 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 + +type Permission_Type int32 + +const ( + READ Permission_Type = 0 + WRITE Permission_Type = 1 + READWRITE Permission_Type = 2 +) + +var Permission_Type_name = map[int32]string{ + 0: "READ", + 1: "WRITE", + 2: "READWRITE", +} +var Permission_Type_value = map[string]int32{ + "READ": 0, + "WRITE": 1, + "READWRITE": 2, } -func (m *User) Reset() { *m = User{} } -func (m *User) String() string { return proto.CompactTextString(m) } -func (*User) ProtoMessage() {} +func (x Permission_Type) String() string { + return proto.EnumName(Permission_Type_name, int32(x)) +} +func (Permission_Type) EnumDescriptor() ([]byte, []int) { return fileDescriptorAuth, []int{1, 0} } + +// User is a single entry in the bucket authUsers +type User struct { + Name []byte `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Password []byte `protobuf:"bytes,2,opt,name=password,proto3" json:"password,omitempty"` + Roles []string `protobuf:"bytes,3,rep,name=roles" json:"roles,omitempty"` +} + +func (m *User) Reset() { *m = User{} } +func (m *User) String() string { return proto.CompactTextString(m) } +func (*User) ProtoMessage() {} +func (*User) Descriptor() ([]byte, []int) { return fileDescriptorAuth, []int{0} } + +// Permission is a single entity +type Permission struct { + PermType Permission_Type `protobuf:"varint,1,opt,name=permType,proto3,enum=authpb.Permission_Type" json:"permType,omitempty"` + Key []byte `protobuf:"bytes,2,opt,name=key,proto3" json:"key,omitempty"` + RangeEnd []byte `protobuf:"bytes,3,opt,name=range_end,json=rangeEnd,proto3" json:"range_end,omitempty"` +} + +func (m *Permission) Reset() { *m = Permission{} } +func (m *Permission) String() string { return proto.CompactTextString(m) } +func (*Permission) ProtoMessage() {} +func (*Permission) Descriptor() ([]byte, []int) { return fileDescriptorAuth, []int{1} } // Role is a single entry in the bucket authRoles type Role struct { - Name []byte `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + Name []byte `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + KeyPermission []*Permission `protobuf:"bytes,2,rep,name=keyPermission" json:"keyPermission,omitempty"` } -func (m *Role) Reset() { *m = Role{} } -func (m *Role) String() string { return proto.CompactTextString(m) } -func (*Role) ProtoMessage() {} +func (m *Role) Reset() { *m = Role{} } +func (m *Role) String() string { return proto.CompactTextString(m) } +func (*Role) ProtoMessage() {} +func (*Role) Descriptor() ([]byte, []int) { return fileDescriptorAuth, []int{2} } func init() { proto.RegisterType((*User)(nil), "authpb.User") + proto.RegisterType((*Permission)(nil), "authpb.Permission") 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) { size := m.Size() @@ -68,26 +114,67 @@ func (m *User) MarshalTo(data []byte) (int, error) { _ = i var l int _ = l - if m.Name != nil { - if len(m.Name) > 0 { - data[i] = 0xa - i++ - i = encodeVarintAuth(data, i, uint64(len(m.Name))) - i += copy(data[i:], m.Name) - } - } - if m.Password != nil { - if len(m.Password) > 0 { - data[i] = 0x12 - i++ - i = encodeVarintAuth(data, i, uint64(len(m.Password))) - i += copy(data[i:], m.Password) - } - } - if m.Tombstone != 0 { - data[i] = 0x18 + if len(m.Name) > 0 { + data[i] = 0xa i++ - i = encodeVarintAuth(data, i, uint64(m.Tombstone)) + i = encodeVarintAuth(data, i, uint64(len(m.Name))) + i += copy(data[i:], m.Name) + } + if len(m.Password) > 0 { + data[i] = 0x12 + i++ + 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 + 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 *Permission) 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 *Permission) MarshalTo(data []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.PermType != 0 { + data[i] = 0x8 + i++ + i = encodeVarintAuth(data, i, uint64(m.PermType)) + } + if len(m.Key) > 0 { + data[i] = 0x12 + i++ + i = encodeVarintAuth(data, i, uint64(len(m.Key))) + i += copy(data[i:], m.Key) + } + if len(m.RangeEnd) > 0 { + data[i] = 0x1a + i++ + i = encodeVarintAuth(data, i, uint64(len(m.RangeEnd))) + i += copy(data[i:], m.RangeEnd) } return i, nil } @@ -107,12 +194,22 @@ func (m *Role) MarshalTo(data []byte) (int, error) { _ = i var l int _ = l - if m.Name != nil { - if len(m.Name) > 0 { + if len(m.Name) > 0 { + data[i] = 0xa + i++ + 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 i++ - i = encodeVarintAuth(data, i, uint64(len(m.Name))) - i += copy(data[i:], m.Name) + i = encodeVarintAuth(data, i, uint64(msg.Size())) + n, err := msg.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += n } } return i, nil @@ -148,20 +245,36 @@ func encodeVarintAuth(data []byte, offset int, v uint64) int { func (m *User) Size() (n int) { var l int _ = l - if m.Name != nil { - l = len(m.Name) - if l > 0 { + l = len(m.Name) + if l > 0 { + n += 1 + l + sovAuth(uint64(l)) + } + l = len(m.Password) + if l > 0 { + n += 1 + l + sovAuth(uint64(l)) + } + if len(m.Roles) > 0 { + for _, s := range m.Roles { + l = len(s) n += 1 + l + sovAuth(uint64(l)) } } - if m.Password != nil { - l = len(m.Password) - if l > 0 { - n += 1 + l + sovAuth(uint64(l)) - } + return n +} + +func (m *Permission) Size() (n int) { + var l int + _ = l + if m.PermType != 0 { + n += 1 + sovAuth(uint64(m.PermType)) } - if m.Tombstone != 0 { - n += 1 + sovAuth(uint64(m.Tombstone)) + l = len(m.Key) + if l > 0 { + n += 1 + l + sovAuth(uint64(l)) + } + l = len(m.RangeEnd) + if l > 0 { + n += 1 + l + sovAuth(uint64(l)) } return n } @@ -169,9 +282,13 @@ func (m *User) Size() (n int) { func (m *Role) Size() (n int) { var l int _ = l - if m.Name != nil { - l = len(m.Name) - if l > 0 { + l = len(m.Name) + if l > 0 { + n += 1 + l + sovAuth(uint64(l)) + } + if len(m.KeyPermission) > 0 { + for _, e := range m.KeyPermission { + l = e.Size() n += 1 + l + sovAuth(uint64(l)) } } @@ -283,10 +400,10 @@ func (m *User) Unmarshal(data []byte) error { } iNdEx = postIndex case 3: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Tombstone", wireType) + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Roles", wireType) } - m.Tombstone = 0 + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowAuth @@ -296,11 +413,152 @@ func (m *User) Unmarshal(data []byte) error { } b := data[iNdEx] iNdEx++ - m.Tombstone |= (int64(b) & 0x7F) << shift + stringLen |= (uint64(b) & 0x7F) << shift if b < 0x80 { break } } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthAuth + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Roles = append(m.Roles, string(data[iNdEx:postIndex])) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipAuth(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthAuth + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Permission) 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 ErrIntOverflowAuth + } + 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: Permission: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Permission: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field PermType", wireType) + } + m.PermType = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuth + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + m.PermType |= (Permission_Type(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Key", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuth + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + byteLen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthAuth + } + postIndex := iNdEx + byteLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Key = append(m.Key[:0], data[iNdEx:postIndex]...) + if m.Key == nil { + m.Key = []byte{} + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field RangeEnd", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuth + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + byteLen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthAuth + } + postIndex := iNdEx + byteLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + 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:]) @@ -351,7 +609,7 @@ func (m *Role) Unmarshal(data []byte) error { return fmt.Errorf("proto: Role: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { - case 2: + case 1: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) } @@ -382,6 +640,37 @@ func (m *Role) Unmarshal(data []byte) error { m.Name = []byte{} } iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field KeyPermission", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuth + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthAuth + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.KeyPermission = append(m.KeyPermission, &Permission{}) + 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:]) @@ -507,3 +796,25 @@ var ( ErrInvalidLengthAuth = fmt.Errorf("proto: negative length found during unmarshaling") ErrIntOverflowAuth = fmt.Errorf("proto: integer overflow") ) + +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, + 0x1c, 0xc6, 0x9b, 0xb6, 0x1b, 0xed, 0x5f, 0x27, 0x25, 0x0c, 0x0c, 0x13, 0x42, 0xe9, 0xa9, 0x78, + 0xa8, 0xb0, 0x5d, 0xbc, 0x2a, 0xf6, 0x20, 0x78, 0x90, 0x50, 0xf1, 0x28, 0x1d, 0x0d, 0x75, 0x6c, + 0x6d, 0x4a, 0x32, 0x91, 0xbe, 0x89, 0x07, 0x1f, 0x68, 0xc7, 0x3d, 0x82, 0xab, 0x2f, 0x22, 0x4d, + 0x64, 0x43, 0xdc, 0xed, 0xfb, 0xbe, 0xff, 0x97, 0xe4, 0x97, 0x3f, 0x40, 0xfe, 0xb6, 0x7e, 0x4d, + 0x1a, 0x29, 0xd6, 0x02, 0x0f, 0x7b, 0xdd, 0xcc, 0x27, 0xe3, 0x52, 0x94, 0x42, 0x47, 0x57, 0xbd, + 0x32, 0xd3, 0xe8, 0x01, 0xdc, 0x27, 0xc5, 0x25, 0xc6, 0xe0, 0xd6, 0x79, 0xc5, 0x09, 0x0a, 0x51, + 0x7c, 0xca, 0xb4, 0xc6, 0x13, 0xf0, 0x9a, 0x5c, 0xa9, 0x77, 0x21, 0x0b, 0x62, 0xeb, 0x7c, 0xef, + 0xf1, 0x18, 0x06, 0x52, 0xac, 0xb8, 0x22, 0x4e, 0xe8, 0xc4, 0x3e, 0x33, 0x26, 0xfa, 0x44, 0x00, + 0x8f, 0x5c, 0x56, 0x0b, 0xa5, 0x16, 0xa2, 0xc6, 0x33, 0xf0, 0x1a, 0x2e, 0xab, 0xac, 0x6d, 0xcc, + 0xc5, 0x67, 0xd3, 0xf3, 0xc4, 0xd0, 0x24, 0x87, 0x56, 0xd2, 0x8f, 0xd9, 0xbe, 0x88, 0x03, 0x70, + 0x96, 0xbc, 0xfd, 0x7d, 0xb0, 0x97, 0xf8, 0x02, 0x7c, 0x99, 0xd7, 0x25, 0x7f, 0xe1, 0x75, 0x41, + 0x1c, 0x03, 0xa2, 0x83, 0xb4, 0x2e, 0xa2, 0x4b, 0x70, 0xf5, 0x31, 0x0f, 0x5c, 0x96, 0xde, 0xdc, + 0x05, 0x16, 0xf6, 0x61, 0xf0, 0xcc, 0xee, 0xb3, 0x34, 0x40, 0x78, 0x04, 0x7e, 0x1f, 0x1a, 0x6b, + 0x47, 0x19, 0xb8, 0x4c, 0xac, 0xf8, 0xd1, 0xcf, 0x5e, 0xc3, 0x68, 0xc9, 0xdb, 0x03, 0x16, 0xb1, + 0x43, 0x27, 0x3e, 0x99, 0xe2, 0xff, 0xc0, 0xec, 0x6f, 0xf1, 0x96, 0x6c, 0x76, 0xd4, 0xda, 0xee, + 0xa8, 0xb5, 0xe9, 0x28, 0xda, 0x76, 0x14, 0x7d, 0x75, 0x14, 0x7d, 0x7c, 0x53, 0x6b, 0x3e, 0xd4, + 0x3b, 0x9e, 0xfd, 0x04, 0x00, 0x00, 0xff, 0xff, 0xcc, 0x76, 0x8d, 0x4f, 0x8f, 0x01, 0x00, 0x00, +} diff --git a/vendor/github.com/coreos/etcd/auth/authpb/auth.proto b/vendor/github.com/coreos/etcd/auth/authpb/auth.proto index 00f94e71d03..001d3343548 100644 --- a/vendor/github.com/coreos/etcd/auth/authpb/auth.proto +++ b/vendor/github.com/coreos/etcd/auth/authpb/auth.proto @@ -13,10 +13,25 @@ option (gogoproto.goproto_enum_prefix_all) = false; message User { bytes name = 1; bytes password = 2; - int64 tombstone = 3; + repeated string roles = 3; +} + +// Permission is a single entity +message Permission { + enum Type { + READ = 0; + WRITE = 1; + READWRITE = 2; + } + Type permType = 1; + + bytes key = 2; + bytes range_end = 3; } // Role is a single entry in the bucket authRoles message Role { - bytes name = 2; + bytes name = 1; + + repeated Permission keyPermission = 2; } diff --git a/vendor/github.com/coreos/etcd/auth/doc.go b/vendor/github.com/coreos/etcd/auth/doc.go new file mode 100644 index 00000000000..72741a10774 --- /dev/null +++ b/vendor/github.com/coreos/etcd/auth/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 auth provides client role authentication for accessing keys in etcd. +package auth diff --git a/vendor/github.com/coreos/etcd/auth/range_perm_cache.go b/vendor/github.com/coreos/etcd/auth/range_perm_cache.go new file mode 100644 index 00000000000..e5525cd4bcb --- /dev/null +++ b/vendor/github.com/coreos/etcd/auth/range_perm_cache.go @@ -0,0 +1,219 @@ +// 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 auth + +import ( + "bytes" + "sort" + + "github.com/coreos/etcd/auth/authpb" + "github.com/coreos/etcd/mvcc/backend" +) + +// isSubset returns true if a is a subset of b +func isSubset(a, b *rangePerm) bool { + switch { + case len(a.end) == 0 && len(b.end) == 0: + // a, b are both keys + return bytes.Equal(a.begin, b.begin) + case len(b.end) == 0: + // b is a key, a is a range + return false + case len(a.end) == 0: + return 0 <= bytes.Compare(a.begin, b.begin) && bytes.Compare(a.begin, b.end) <= 0 + default: + return 0 <= bytes.Compare(a.begin, b.begin) && bytes.Compare(a.end, b.end) <= 0 + } +} + +func isRangeEqual(a, b *rangePerm) bool { + return bytes.Equal(a.begin, b.begin) && bytes.Equal(a.end, b.end) +} + +// 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) + + 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 { + continue + } + + newp = append(newp, perms[i]) + } + + return newp +} + +// mergeRangePerms merges adjacent rangePerms. +func mergeRangePerms(perms []*rangePerm) []*rangePerm { + merged := make([]*rangePerm, 0) + perms = removeSubsetRangePerms(perms) + sort.Sort(RangePermSliceByBegin(perms)) + + i := 0 + for i < len(perms) { + begin, next := i, i + for next+1 < len(perms) && bytes.Compare(perms[next].end, perms[next+1].begin) != -1 { + next++ + } + + merged = append(merged, &rangePerm{begin: perms[begin].begin, end: perms[next].end}) + + i = next + 1 + } + + return merged +} + +func getMergedPerms(tx backend.BatchTx, userName string) *unifiedRangePermissions { + user := getUser(tx, userName) + if user == nil { + plog.Errorf("invalid user name %s", userName) + return nil + } + + var readPerms, writePerms []*rangePerm + + for _, roleName := range user.Roles { + role := getRole(tx, roleName) + if role == nil { + continue + } + + for _, perm := range role.KeyPermission { + rp := &rangePerm{begin: perm.Key, end: perm.RangeEnd} + + switch perm.PermType { + case authpb.READWRITE: + readPerms = append(readPerms, rp) + writePerms = append(writePerms, rp) + + case authpb.READ: + readPerms = append(readPerms, rp) + + case authpb.WRITE: + writePerms = append(writePerms, rp) + } + } + } + + return &unifiedRangePermissions{ + readPerms: mergeRangePerms(readPerms), + writePerms: mergeRangePerms(writePerms), + } +} + +func checkKeyPerm(cachedPerms *unifiedRangePermissions, key, rangeEnd []byte, permtyp authpb.Permission_Type) bool { + var tocheck []*rangePerm + + switch permtyp { + case authpb.READ: + tocheck = cachedPerms.readPerms + case authpb.WRITE: + tocheck = cachedPerms.writePerms + default: + plog.Panicf("unknown auth type: %v", permtyp) + } + + requiredPerm := &rangePerm{begin: key, end: rangeEnd} + + for _, perm := range tocheck { + if isSubset(requiredPerm, perm) { + return true + } + } + + return false +} + +func (as *authStore) isRangeOpPermitted(tx backend.BatchTx, userName string, key, rangeEnd []byte, permtyp authpb.Permission_Type) bool { + // assumption: tx is Lock()ed + _, ok := as.rangePermCache[userName] + if !ok { + perms := getMergedPerms(tx, userName) + if perms == nil { + plog.Errorf("failed to create a unified permission of user %s", userName) + return false + } + as.rangePermCache[userName] = perms + } + + return checkKeyPerm(as.rangePermCache[userName], key, rangeEnd, permtyp) +} + +func (as *authStore) clearCachedPerm() { + as.rangePermCache = make(map[string]*unifiedRangePermissions) +} + +func (as *authStore) invalidateCachedPerm(userName string) { + delete(as.rangePermCache, userName) +} + +type unifiedRangePermissions struct { + // readPerms[i] and readPerms[j] (i != j) don't overlap + readPerms []*rangePerm + // writePerms[i] and writePerms[j] (i != j) don't overlap, too + writePerms []*rangePerm +} + +type rangePerm struct { + begin, end []byte +} + +type RangePermSliceByBegin []*rangePerm + +func (slice RangePermSliceByBegin) Len() int { + return len(slice) +} + +func (slice RangePermSliceByBegin) Less(i, j int) bool { + switch bytes.Compare(slice[i].begin, slice[j].begin) { + case 0: // begin(i) == begin(j) + return bytes.Compare(slice[i].end, slice[j].end) == -1 + + case -1: // begin(i) < begin(j) + return true + + default: + return false + } +} + +func (slice RangePermSliceByBegin) Swap(i, j int) { + slice[i], slice[j] = slice[j], slice[i] +} diff --git a/vendor/github.com/coreos/etcd/auth/simple_token.go b/vendor/github.com/coreos/etcd/auth/simple_token.go new file mode 100644 index 00000000000..df2a78e2a71 --- /dev/null +++ b/vendor/github.com/coreos/etcd/auth/simple_token.go @@ -0,0 +1,55 @@ +// 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 auth + +// CAUTION: This randum number based token mechanism is only for testing purpose. +// JWT based mechanism will be added in the near future. + +import ( + "crypto/rand" + "math/big" +) + +const ( + letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" + defaultSimpleTokenLength = 16 +) + +func (as *authStore) GenSimpleToken() (string, error) { + ret := make([]byte, defaultSimpleTokenLength) + + for i := 0; i < defaultSimpleTokenLength; i++ { + bInt, err := rand.Int(rand.Reader, big.NewInt(int64(len(letters)))) + if err != nil { + return "", err + } + + ret[i] = letters[bInt.Int64()] + } + + return string(ret), nil +} + +func (as *authStore) assignSimpleTokenToUser(username, token string) { + as.simpleTokensMu.Lock() + + _, ok := as.simpleTokens[token] + if ok { + plog.Panicf("token %s is alredy used", token) + } + + as.simpleTokens[token] = username + as.simpleTokensMu.Unlock() +} diff --git a/vendor/github.com/coreos/etcd/auth/store.go b/vendor/github.com/coreos/etcd/auth/store.go index 39cf96bb8e3..01c6c9905c8 100644 --- a/vendor/github.com/coreos/etcd/auth/store.go +++ b/vendor/github.com/coreos/etcd/auth/store.go @@ -1,4 +1,4 @@ -// Copyright 2016 Nippon Telegraph and Telephone Corporation. +// 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. @@ -15,17 +15,25 @@ package auth import ( + "bytes" "errors" + "fmt" + "sort" + "strings" + "sync" "github.com/coreos/etcd/auth/authpb" pb "github.com/coreos/etcd/etcdserver/etcdserverpb" - "github.com/coreos/etcd/storage/backend" + "github.com/coreos/etcd/mvcc/backend" "github.com/coreos/pkg/capnslog" "golang.org/x/crypto/bcrypt" + "golang.org/x/net/context" ) var ( enableFlagKey = []byte("authEnabled") + authEnabled = []byte{1} + authDisabled = []byte{0} authBucketName = []byte("auth") authUsersBucketName = []byte("authUsers") @@ -33,14 +41,32 @@ var ( plog = capnslog.NewPackageLogger("github.com/coreos/etcd", "auth") - ErrUserAlreadyExist = errors.New("auth: user already exists") - ErrUserNotFound = errors.New("auth: user not found") - ErrRoleAlreadyExist = errors.New("auth: role already exists") + 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") + ErrUserNotFound = errors.New("auth: user not found") + ErrRoleAlreadyExist = errors.New("auth: role already exists") + ErrRoleNotFound = errors.New("auth: role not found") + ErrAuthFailed = errors.New("auth: authentication failed, invalid user ID or password") + 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") +) + +const ( + rootUser = "root" + rootRole = "root" ) type AuthStore interface { - // AuthEnable() turns on the authentication feature - AuthEnable() + // AuthEnable turns on the authentication feature + AuthEnable() error + + // AuthDisable turns off the authentication feature + AuthDisable() + + // Authenticate does authentication based on given user name and password + Authenticate(ctx context.Context, username, password string) (*pb.AuthenticateResponse, error) // Recover recovers the state of auth store from the given backend Recover(b backend.Backend) @@ -54,35 +80,157 @@ type AuthStore interface { // UserChangePassword changes a password of a user UserChangePassword(r *pb.AuthUserChangePasswordRequest) (*pb.AuthUserChangePasswordResponse, error) + // UserGrantRole grants a role to the user + UserGrantRole(r *pb.AuthUserGrantRoleRequest) (*pb.AuthUserGrantRoleResponse, error) + + // UserGet gets the detailed information of a users + UserGet(r *pb.AuthUserGetRequest) (*pb.AuthUserGetResponse, error) + + // UserRevokeRole revokes a role of a user + UserRevokeRole(r *pb.AuthUserRevokeRoleRequest) (*pb.AuthUserRevokeRoleResponse, error) + // RoleAdd adds a new role RoleAdd(r *pb.AuthRoleAddRequest) (*pb.AuthRoleAddResponse, error) + + // RoleGrantPermission grants a permission to a role + RoleGrantPermission(r *pb.AuthRoleGrantPermissionRequest) (*pb.AuthRoleGrantPermissionResponse, error) + + // RoleGet gets the detailed information of a role + RoleGet(r *pb.AuthRoleGetRequest) (*pb.AuthRoleGetResponse, error) + + // RoleRevokePermission gets the detailed information of a role + RoleRevokePermission(r *pb.AuthRoleRevokePermissionRequest) (*pb.AuthRoleRevokePermissionResponse, error) + + // RoleDelete gets the detailed information of a role + RoleDelete(r *pb.AuthRoleDeleteRequest) (*pb.AuthRoleDeleteResponse, error) + + // UserList gets a list of all users + UserList(r *pb.AuthUserListRequest) (*pb.AuthUserListResponse, error) + + // 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) + + // IsPutPermitted checks put permission of the user + IsPutPermitted(username string, key []byte) bool + + // IsRangePermitted checks range permission of the user + IsRangePermitted(username string, key, rangeEnd []byte) bool + + // IsDeleteRangePermitted checks delete-range permission of the user + IsDeleteRangePermitted(username string, key, rangeEnd []byte) bool + + // IsAdminPermitted checks admin permission of the user + IsAdminPermitted(username string) bool + + // GenSimpleToken produces a simple random string + GenSimpleToken() (string, error) } type authStore struct { - be backend.Backend + be backend.Backend + enabled bool + enabledMu sync.RWMutex + + rangePermCache map[string]*unifiedRangePermissions // username -> unifiedRangePermissions + + simpleTokensMu sync.RWMutex + simpleTokens map[string]string // token -> username } -func (as *authStore) AuthEnable() { - value := []byte{1} - +func (as *authStore) AuthEnable() error { b := as.be tx := b.BatchTx() tx.Lock() - tx.UnsafePut(authBucketName, enableFlagKey, value) + defer func() { + tx.Unlock() + b.ForceCommit() + }() + + u := getUser(tx, rootUser) + if u == nil { + return ErrRootUserNotExist + } + + if !hasRootRole(u) { + return ErrRootRoleNotExist + } + + tx.UnsafePut(authBucketName, enableFlagKey, authEnabled) + + as.enabledMu.Lock() + as.enabled = true + as.enabledMu.Unlock() + + as.rangePermCache = make(map[string]*unifiedRangePermissions) + + plog.Noticef("Authentication enabled") + + return nil +} + +func (as *authStore) AuthDisable() { + b := as.be + tx := b.BatchTx() + tx.Lock() + tx.UnsafePut(authBucketName, enableFlagKey, authDisabled) tx.Unlock() b.ForceCommit() - plog.Noticef("Authentication enabled") + as.enabledMu.Lock() + as.enabled = false + as.enabledMu.Unlock() + + plog.Noticef("Authentication disabled") +} + +func (as *authStore) Authenticate(ctx context.Context, username, password string) (*pb.AuthenticateResponse, error) { + // TODO(mitake): after adding jwt support, branching based on values of ctx is required + index := ctx.Value("index").(uint64) + simpleToken := ctx.Value("simpleToken").(string) + + tx := as.be.BatchTx() + tx.Lock() + defer tx.Unlock() + + user := getUser(tx, username) + if user == nil { + 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) + + plog.Infof("authorized %s, token is %s", username, token) + return &pb.AuthenticateResponse{Token: token}, nil } func (as *authStore) Recover(be backend.Backend) { + enabled := false as.be = be - // TODO(mitake): recovery process + tx := be.BatchTx() + tx.Lock() + _, vs := tx.UnsafeRange(authBucketName, enableFlagKey, nil, 0) + if len(vs) == 1 { + if bytes.Equal(vs[0], authEnabled) { + enabled = true + } + } + tx.Unlock() + + as.enabledMu.Lock() + as.enabled = enabled + as.enabledMu.Unlock() } func (as *authStore) UserAdd(r *pb.AuthUserAddRequest) (*pb.AuthUserAddResponse, error) { - plog.Noticef("adding a new user: %s", r.Name) - hashed, err := bcrypt.GenerateFromPassword([]byte(r.Password), bcrypt.DefaultCost) if err != nil { plog.Errorf("failed to hash password: %s", err) @@ -93,23 +241,17 @@ func (as *authStore) UserAdd(r *pb.AuthUserAddRequest) (*pb.AuthUserAddResponse, tx.Lock() defer tx.Unlock() - _, vs := tx.UnsafeRange(authUsersBucketName, []byte(r.Name), nil, 0) - if len(vs) != 0 { - return &pb.AuthUserAddResponse{}, ErrUserAlreadyExist + user := getUser(tx, r.Name) + if user != nil { + return nil, ErrUserAlreadyExist } - newUser := authpb.User{ + newUser := &authpb.User{ Name: []byte(r.Name), Password: hashed, } - marshaledUser, merr := newUser.Marshal() - if merr != nil { - plog.Errorf("failed to marshal a new user data: %s", merr) - return nil, merr - } - - tx.UnsafePut(authUsersBucketName, []byte(r.Name), marshaledUser) + putUser(tx, newUser) plog.Noticef("added a new user: %s", r.Name) @@ -121,12 +263,12 @@ func (as *authStore) UserDelete(r *pb.AuthUserDeleteRequest) (*pb.AuthUserDelete tx.Lock() defer tx.Unlock() - _, vs := tx.UnsafeRange(authUsersBucketName, []byte(r.Name), nil, 0) - if len(vs) != 1 { - return &pb.AuthUserDeleteResponse{}, ErrUserNotFound + user := getUser(tx, r.Name) + if user == nil { + return nil, ErrUserNotFound } - tx.UnsafeDelete(authUsersBucketName, []byte(r.Name)) + delUser(tx, r.Name) plog.Noticef("deleted a user: %s", r.Name) @@ -146,36 +288,230 @@ func (as *authStore) UserChangePassword(r *pb.AuthUserChangePasswordRequest) (*p tx.Lock() defer tx.Unlock() - _, vs := tx.UnsafeRange(authUsersBucketName, []byte(r.Name), nil, 0) - if len(vs) != 1 { - return &pb.AuthUserChangePasswordResponse{}, ErrUserNotFound + user := getUser(tx, r.Name) + if user == nil { + return nil, ErrUserNotFound } - updatedUser := authpb.User{ + updatedUser := &authpb.User{ Name: []byte(r.Name), + Roles: user.Roles, Password: hashed, } - marshaledUser, merr := updatedUser.Marshal() - if merr != nil { - plog.Errorf("failed to marshal a new user data: %s", merr) - return nil, merr - } - - tx.UnsafePut(authUsersBucketName, []byte(r.Name), marshaledUser) + putUser(tx, updatedUser) plog.Noticef("changed a password of a user: %s", r.Name) return &pb.AuthUserChangePasswordResponse{}, nil } +func (as *authStore) UserGrantRole(r *pb.AuthUserGrantRoleRequest) (*pb.AuthUserGrantRoleResponse, error) { + tx := as.be.BatchTx() + tx.Lock() + defer tx.Unlock() + + user := getUser(tx, r.User) + if user == nil { + return nil, ErrUserNotFound + } + + if r.Role != rootRole { + role := getRole(tx, r.Role) + if role == nil { + return nil, ErrRoleNotFound + } + } + + idx := sort.SearchStrings(user.Roles, r.Role) + if idx < len(user.Roles) && strings.Compare(user.Roles[idx], r.Role) == 0 { + plog.Warningf("user %s is already granted role %s", r.User, r.Role) + return &pb.AuthUserGrantRoleResponse{}, nil + } + + user.Roles = append(user.Roles, r.Role) + sort.Sort(sort.StringSlice(user.Roles)) + + putUser(tx, user) + + as.invalidateCachedPerm(r.User) + + plog.Noticef("granted role %s to user %s", r.Role, r.User) + return &pb.AuthUserGrantRoleResponse{}, nil +} + +func (as *authStore) UserGet(r *pb.AuthUserGetRequest) (*pb.AuthUserGetResponse, error) { + tx := as.be.BatchTx() + tx.Lock() + defer tx.Unlock() + + var resp pb.AuthUserGetResponse + + user := getUser(tx, r.Name) + if user == nil { + return nil, ErrUserNotFound + } + + for _, role := range user.Roles { + resp.Roles = append(resp.Roles, role) + } + + return &resp, nil +} + +func (as *authStore) UserList(r *pb.AuthUserListRequest) (*pb.AuthUserListResponse, error) { + tx := as.be.BatchTx() + tx.Lock() + defer tx.Unlock() + + var resp pb.AuthUserListResponse + + users := getAllUsers(tx) + + for _, u := range users { + resp.Users = append(resp.Users, string(u.Name)) + } + + return &resp, nil +} + +func (as *authStore) UserRevokeRole(r *pb.AuthUserRevokeRoleRequest) (*pb.AuthUserRevokeRoleResponse, error) { + tx := as.be.BatchTx() + tx.Lock() + defer tx.Unlock() + + user := getUser(tx, r.Name) + if user == nil { + return nil, ErrUserNotFound + } + + updatedUser := &authpb.User{ + Name: user.Name, + Password: user.Password, + } + + for _, role := range user.Roles { + if strings.Compare(role, r.Role) != 0 { + updatedUser.Roles = append(updatedUser.Roles, role) + } + } + + if len(updatedUser.Roles) == len(user.Roles) { + return nil, ErrRoleNotGranted + } + + putUser(tx, updatedUser) + + as.invalidateCachedPerm(r.Name) + + plog.Noticef("revoked role %s from user %s", r.Role, r.Name) + return &pb.AuthUserRevokeRoleResponse{}, nil +} + +func (as *authStore) RoleGet(r *pb.AuthRoleGetRequest) (*pb.AuthRoleGetResponse, error) { + tx := as.be.BatchTx() + tx.Lock() + defer tx.Unlock() + + var resp pb.AuthRoleGetResponse + + role := getRole(tx, r.Role) + if role == nil { + return nil, ErrRoleNotFound + } + + for _, perm := range role.KeyPermission { + resp.Perm = append(resp.Perm, perm) + } + + return &resp, nil +} + +func (as *authStore) RoleList(r *pb.AuthRoleListRequest) (*pb.AuthRoleListResponse, error) { + tx := as.be.BatchTx() + tx.Lock() + defer tx.Unlock() + + var resp pb.AuthRoleListResponse + + roles := getAllRoles(tx) + + for _, r := range roles { + resp.Roles = append(resp.Roles, string(r.Name)) + } + + return &resp, nil +} + +func (as *authStore) RoleRevokePermission(r *pb.AuthRoleRevokePermissionRequest) (*pb.AuthRoleRevokePermissionResponse, error) { + tx := as.be.BatchTx() + tx.Lock() + defer tx.Unlock() + + role := getRole(tx, r.Role) + if role == nil { + return nil, ErrRoleNotFound + } + + updatedRole := &authpb.Role{ + Name: role.Name, + } + + for _, perm := range role.KeyPermission { + if !bytes.Equal(perm.Key, []byte(r.Key)) || !bytes.Equal(perm.RangeEnd, []byte(r.RangeEnd)) { + updatedRole.KeyPermission = append(updatedRole.KeyPermission, perm) + } + } + + if len(role.KeyPermission) == len(updatedRole.KeyPermission) { + return nil, ErrPermissionNotGranted + } + + putRole(tx, updatedRole) + + // TODO(mitake): currently single role update invalidates every cache + // It should be optimized. + as.clearCachedPerm() + + plog.Noticef("revoked key %s from role %s", r.Key, r.Role) + return &pb.AuthRoleRevokePermissionResponse{}, nil +} + +func (as *authStore) RoleDelete(r *pb.AuthRoleDeleteRequest) (*pb.AuthRoleDeleteResponse, error) { + // TODO(mitake): current scheme of role deletion allows existing users to have the deleted roles + // + // Assume a case like below: + // create a role r1 + // create a user u1 and grant r1 to u1 + // delete r1 + // + // After this sequence, u1 is still granted the role r1. So if admin create a new role with the name r1, + // the new r1 is automatically granted u1. + // In some cases, it would be confusing. So we need to provide an option for deleting the grant relation + // from all users. + + tx := as.be.BatchTx() + tx.Lock() + defer tx.Unlock() + + role := getRole(tx, r.Role) + if role == nil { + return nil, ErrRoleNotFound + } + + delRole(tx, r.Role) + + plog.Noticef("deleted role %s", r.Role) + return &pb.AuthRoleDeleteResponse{}, nil +} + func (as *authStore) RoleAdd(r *pb.AuthRoleAddRequest) (*pb.AuthRoleAddResponse, error) { tx := as.be.BatchTx() tx.Lock() defer tx.Unlock() - _, vs := tx.UnsafeRange(authRolesBucketName, []byte(r.Name), nil, 0) - if len(vs) != 0 { + role := getRole(tx, r.Name) + if role != nil { return nil, ErrRoleAlreadyExist } @@ -183,18 +519,227 @@ func (as *authStore) RoleAdd(r *pb.AuthRoleAddRequest) (*pb.AuthRoleAddResponse, Name: []byte(r.Name), } - marshaledRole, err := newRole.Marshal() - if err != nil { - return nil, err - } - - tx.UnsafePut(authRolesBucketName, []byte(r.Name), marshaledRole) + putRole(tx, newRole) 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 +} + +type permSlice []*authpb.Permission + +func (perms permSlice) Len() int { + return len(perms) +} + +func (perms permSlice) Less(i, j int) bool { + return bytes.Compare(perms[i].Key, perms[j].Key) < 0 +} + +func (perms permSlice) Swap(i, j int) { + perms[i], perms[j] = perms[j], perms[i] +} + +func (as *authStore) RoleGrantPermission(r *pb.AuthRoleGrantPermissionRequest) (*pb.AuthRoleGrantPermissionResponse, error) { + tx := as.be.BatchTx() + tx.Lock() + defer tx.Unlock() + + role := getRole(tx, r.Name) + if role == nil { + return nil, ErrRoleNotFound + } + + idx := sort.Search(len(role.KeyPermission), func(i int) bool { + return bytes.Compare(role.KeyPermission[i].Key, []byte(r.Perm.Key)) >= 0 + }) + + if idx < len(role.KeyPermission) && bytes.Equal(role.KeyPermission[idx].Key, r.Perm.Key) && bytes.Equal(role.KeyPermission[idx].RangeEnd, r.Perm.RangeEnd) { + // update existing permission + role.KeyPermission[idx].PermType = r.Perm.PermType + } else { + // append new permission to the role + newPerm := &authpb.Permission{ + Key: []byte(r.Perm.Key), + RangeEnd: []byte(r.Perm.RangeEnd), + PermType: r.Perm.PermType, + } + + role.KeyPermission = append(role.KeyPermission, newPerm) + sort.Sort(permSlice(role.KeyPermission)) + } + + putRole(tx, role) + + // TODO(mitake): currently single role update invalidates every cache + // It should be optimized. + as.clearCachedPerm() + + 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 { + // TODO(mitake): this function would be costly so we need a caching mechanism + if !as.isAuthEnabled() { + return true + } + + tx := as.be.BatchTx() + tx.Lock() + defer tx.Unlock() + + user := getUser(tx, userName) + if user == nil { + plog.Errorf("invalid user name %s for permission checking", userName) + return false + } + + if as.isRangeOpPermitted(tx, userName, key, rangeEnd, permTyp) { + return true + } + + return false +} + +func (as *authStore) IsPutPermitted(username string, key []byte) bool { + return as.isOpPermitted(username, 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) IsDeleteRangePermitted(username string, key, rangeEnd []byte) bool { + return as.isOpPermitted(username, key, rangeEnd, authpb.WRITE) +} + +func (as *authStore) IsAdminPermitted(username string) bool { + if !as.isAuthEnabled() { + return true + } + + tx := as.be.BatchTx() + tx.Lock() + defer tx.Unlock() + + u := getUser(tx, username) + if u == nil { + return false + } + + return hasRootRole(u) +} + +func getUser(tx backend.BatchTx, username string) *authpb.User { + _, vs := tx.UnsafeRange(authUsersBucketName, []byte(username), nil, 0) + if len(vs) == 0 { + return nil + } + + user := &authpb.User{} + err := user.Unmarshal(vs[0]) + if err != nil { + plog.Panicf("failed to unmarshal user struct (name: %s): %s", username, err) + } + return user +} + +func getAllUsers(tx backend.BatchTx) []*authpb.User { + _, vs := tx.UnsafeRange(authUsersBucketName, []byte{0}, []byte{0xff}, -1) + if len(vs) == 0 { + return nil + } + + var users []*authpb.User + + for _, v := range vs { + user := &authpb.User{} + err := user.Unmarshal(v) + if err != nil { + plog.Panicf("failed to unmarshal user struct: %s", err) + } + + users = append(users, user) + } + + return users +} + +func putUser(tx backend.BatchTx, user *authpb.User) { + b, err := user.Marshal() + if err != nil { + plog.Panicf("failed to marshal user struct (name: %s): %s", user.Name, err) + } + tx.UnsafePut(authUsersBucketName, user.Name, b) +} + +func delUser(tx backend.BatchTx, username string) { + tx.UnsafeDelete(authUsersBucketName, []byte(username)) +} + +func getRole(tx backend.BatchTx, rolename string) *authpb.Role { + _, vs := tx.UnsafeRange(authRolesBucketName, []byte(rolename), nil, 0) + if len(vs) == 0 { + return nil + } + + role := &authpb.Role{} + err := role.Unmarshal(vs[0]) + if err != nil { + plog.Panicf("failed to unmarshal role struct (name: %s): %s", rolename, err) + } + return role +} + +func getAllRoles(tx backend.BatchTx) []*authpb.Role { + _, vs := tx.UnsafeRange(authRolesBucketName, []byte{0}, []byte{0xff}, -1) + if len(vs) == 0 { + return nil + } + + var roles []*authpb.Role + + for _, v := range vs { + role := &authpb.Role{} + err := role.Unmarshal(v) + if err != nil { + plog.Panicf("failed to unmarshal role struct: %s", err) + } + + roles = append(roles, role) + } + + return roles +} + +func putRole(tx backend.BatchTx, role *authpb.Role) { + b, err := role.Marshal() + if err != nil { + plog.Panicf("failed to marshal role struct (name: %s): %s", role.Name, err) + } + + tx.UnsafePut(authRolesBucketName, []byte(role.Name), b) +} + +func delRole(tx backend.BatchTx, rolename string) { + tx.UnsafeDelete(authRolesBucketName, []byte(rolename)) +} + +func (as *authStore) isAuthEnabled() bool { + as.enabledMu.RLock() + defer as.enabledMu.RUnlock() + return as.enabled +} + func NewAuthStore(be backend.Backend) *authStore { tx := be.BatchTx() tx.Lock() @@ -207,6 +752,16 @@ func NewAuthStore(be backend.Backend) *authStore { be.ForceCommit() return &authStore{ - be: be, + be: be, + simpleTokens: make(map[string]string), } } + +func hasRootRole(u *authpb.User) bool { + for _, r := range u.Roles { + if r == rootRole { + return true + } + } + return false +} diff --git a/vendor/github.com/coreos/etcd/client/README.md b/vendor/github.com/coreos/etcd/client/README.md index 16f7f9d19f6..0bab9589cc3 100644 --- a/vendor/github.com/coreos/etcd/client/README.md +++ b/vendor/github.com/coreos/etcd/client/README.md @@ -4,9 +4,11 @@ etcd/client is the Go client library for etcd. [![GoDoc](https://godoc.org/github.com/coreos/etcd/client?status.png)](https://godoc.org/github.com/coreos/etcd/client) -etcd uses go's `vendor` directory to manage external dependencies. If `client` is imported -outside of etcd, simply copy `client` to the `vendor` directory or use tools like godep to -manage your own dependency, as in [vendor directories](https://golang.org/cmd/go/#hdr-Vendor_Directories). +etcd uses `cmd/vendor` directory to store external dependencies, which are +to be compiled into etcd release binaries. `client` can be imported without +vendoring. For full compatibility, it is recommended to vendor builds using +etcd's vendored packages, using tools like godep, as in +[vendor directories](https://golang.org/cmd/go/#hdr-Vendor_Directories). For more detail, please read [Go vendor design](https://golang.org/s/go15vendor). ## Install diff --git a/vendor/github.com/coreos/etcd/client/auth_role.go b/vendor/github.com/coreos/etcd/client/auth_role.go index 0f6748bdfa2..d15e00dd716 100644 --- a/vendor/github.com/coreos/etcd/client/auth_role.go +++ b/vendor/github.com/coreos/etcd/client/auth_role.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. diff --git a/vendor/github.com/coreos/etcd/client/auth_user.go b/vendor/github.com/coreos/etcd/client/auth_user.go index 6af1c2886a9..97c3f31813b 100644 --- a/vendor/github.com/coreos/etcd/client/auth_user.go +++ b/vendor/github.com/coreos/etcd/client/auth_user.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. @@ -36,6 +36,12 @@ type User struct { Revoke []string `json:"revoke,omitempty"` } +// userListEntry is the user representation given by the server for ListUsers +type userListEntry struct { + User string `json:"user"` + Roles []Role `json:"roles"` +} + type UserRoles struct { User string `json:"user"` Roles []Role `json:"roles"` @@ -194,7 +200,7 @@ func (u *httpAuthUserAPI) ListUsers(ctx context.Context) ([]string, error) { } var userList struct { - Users []User `json:"users"` + Users []userListEntry `json:"users"` } if err = json.Unmarshal(body, &userList); err != nil { diff --git a/vendor/github.com/coreos/etcd/client/client.go b/vendor/github.com/coreos/etcd/client/client.go index 2aaa112ed30..eeeb8b57a2c 100644 --- a/vendor/github.com/coreos/etcd/client/client.go +++ b/vendor/github.com/coreos/etcd/client/client.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. @@ -37,6 +37,10 @@ var ( ErrClusterUnavailable = errors.New("client: etcd cluster is unavailable or misconfigured") ErrNoLeaderEndpoint = errors.New("client: no leader endpoint available") errTooManyRedirectChecks = errors.New("client: too many redirect checks") + + // oneShotCtxValue is set on a context using WithValue(&oneShotValue) so + // that Do() will not retry a request + oneShotCtxValue interface{} ) var DefaultRequestTimeout = 5 * time.Second @@ -335,6 +339,7 @@ func (c *httpClusterClient) Do(ctx context.Context, act httpAction) (*http.Respo var body []byte var err error cerr := &ClusterError{} + isOneShot := ctx.Value(&oneShotCtxValue) != nil for i := pinned; i < leps+pinned; i++ { k := i % leps @@ -348,6 +353,9 @@ func (c *httpClusterClient) Do(ctx context.Context, act httpAction) (*http.Respo if err == context.Canceled || err == context.DeadlineExceeded { return nil, nil, err } + if isOneShot { + return nil, nil, err + } continue } if resp.StatusCode/100 == 5 { @@ -358,6 +366,9 @@ func (c *httpClusterClient) Do(ctx context.Context, act httpAction) (*http.Respo default: cerr.Errors = append(cerr.Errors, fmt.Errorf("client: etcd member %s returns server error [%s]", eps[k].String(), http.StatusText(resp.StatusCode))) } + if isOneShot { + return nil, nil, cerr.Errors[0] + } continue } if k != pinned { diff --git a/vendor/github.com/coreos/etcd/client/cluster_error.go b/vendor/github.com/coreos/etcd/client/cluster_error.go index 957ed462458..aef5bf755b5 100644 --- a/vendor/github.com/coreos/etcd/client/cluster_error.go +++ b/vendor/github.com/coreos/etcd/client/cluster_error.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. diff --git a/vendor/github.com/coreos/etcd/client/curl.go b/vendor/github.com/coreos/etcd/client/curl.go index 5a5a69a9411..c8bc9fba20e 100644 --- a/vendor/github.com/coreos/etcd/client/curl.go +++ b/vendor/github.com/coreos/etcd/client/curl.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. diff --git a/vendor/github.com/coreos/etcd/client/discover.go b/vendor/github.com/coreos/etcd/client/discover.go index ae88659f425..bfd7aec93f5 100644 --- a/vendor/github.com/coreos/etcd/client/discover.go +++ b/vendor/github.com/coreos/etcd/client/discover.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. diff --git a/vendor/github.com/coreos/etcd/client/doc.go b/vendor/github.com/coreos/etcd/client/doc.go index 36c3d8c9dc3..32fdfb52c67 100644 --- a/vendor/github.com/coreos/etcd/client/doc.go +++ b/vendor/github.com/coreos/etcd/client/doc.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. diff --git a/vendor/github.com/coreos/etcd/client/keys.go b/vendor/github.com/coreos/etcd/client/keys.go index 1f2574cdc22..62d5d506ec9 100644 --- a/vendor/github.com/coreos/etcd/client/keys.go +++ b/vendor/github.com/coreos/etcd/client/keys.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. @@ -337,7 +337,11 @@ func (k *httpKeysAPI) Set(ctx context.Context, key, val string, opts *SetOptions act.Dir = opts.Dir } - resp, body, err := k.client.Do(ctx, act) + doCtx := ctx + if act.PrevExist == PrevNoExist { + doCtx = context.WithValue(doCtx, &oneShotCtxValue, &oneShotCtxValue) + } + resp, body, err := k.client.Do(doCtx, act) if err != nil { return nil, err } @@ -385,7 +389,8 @@ func (k *httpKeysAPI) Delete(ctx context.Context, key string, opts *DeleteOption act.Recursive = opts.Recursive } - resp, body, err := k.client.Do(ctx, act) + doCtx := context.WithValue(ctx, &oneShotCtxValue, &oneShotCtxValue) + resp, body, err := k.client.Do(doCtx, act) if err != nil { return nil, err } diff --git a/vendor/github.com/coreos/etcd/client/members.go b/vendor/github.com/coreos/etcd/client/members.go index 8b602db54b8..23adf07ad91 100644 --- a/vendor/github.com/coreos/etcd/client/members.go +++ b/vendor/github.com/coreos/etcd/client/members.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. diff --git a/vendor/github.com/coreos/etcd/client/srv.go b/vendor/github.com/coreos/etcd/client/srv.go index 06197967ca2..fdfa3435921 100644 --- a/vendor/github.com/coreos/etcd/client/srv.go +++ b/vendor/github.com/coreos/etcd/client/srv.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. diff --git a/vendor/github.com/coreos/etcd/client/util.go b/vendor/github.com/coreos/etcd/client/util.go index fc0800b3d21..198bff9654d 100644 --- a/vendor/github.com/coreos/etcd/client/util.go +++ b/vendor/github.com/coreos/etcd/client/util.go @@ -1,4 +1,4 @@ -// Copyright 2016 CoreOS, Inc. +// 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. diff --git a/vendor/github.com/coreos/etcd/clientv3/README.md b/vendor/github.com/coreos/etcd/clientv3/README.md index e67d68a1117..e434f999430 100644 --- a/vendor/github.com/coreos/etcd/clientv3/README.md +++ b/vendor/github.com/coreos/etcd/clientv3/README.md @@ -40,9 +40,11 @@ if err != nil { // use the response ``` -etcd uses go's `vendor` directory to manage external dependencies. If `clientv3` is imported -outside of etcd, simply copy `clientv3` to the `vendor` directory or use tools like godep to -manage your own dependency, as in [vendor directories](https://golang.org/cmd/go/#hdr-Vendor_Directories). +etcd uses `cmd/vendor` directory to store external dependencies, which are +to be compiled into etcd release binaries. `client` can be imported without +vendoring. For full compatibility, it is recommended to vendor builds using +etcd's vendored packages, using tools like godep, as in +[vendor directories](https://golang.org/cmd/go/#hdr-Vendor_Directories). For more detail, please read [Go vendor design](https://golang.org/s/go15vendor). ## Error Handling @@ -50,21 +52,22 @@ For more detail, please read [Go vendor design](https://golang.org/s/go15vendor) etcd client returns 2 types of errors: 1. context error: canceled or deadline exceeded. -2. gRPC error: see [v3rpc/error](https://github.com/coreos/etcd/blob/master/etcdserver/api/v3rpc/error.go). +2. gRPC error: see [api/v3rpc/rpctypes](https://godoc.org/github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes). Here is the example code to handle client errors: ```go resp, err := kvc.Put(ctx, "", "") if err != nil { - if err == context.Canceled { - // ctx is canceled by another routine - } else if err == context.DeadlineExceeded { - // ctx is attached with a deadline and it exceeded - } else if verr, ok := err.(*v3rpc.ErrEmptyKey); ok { - // process (verr.Errors) - } else { - // bad cluster endpoints, which are not etcd servers + switch err { + case context.Canceled: + log.Fatalf("ctx is canceled by another routine: %v", err) + case context.DeadlineExceeded: + log.Fatalf("ctx is attached with a deadline is exceeded: %v", err) + case rpctypes.ErrEmptyKey: + log.Fatalf("client-side error: %v", err) + default: + log.Fatalf("bad cluster endpoints, which are not etcd servers: %v", err) } } ``` diff --git a/vendor/github.com/coreos/etcd/clientv3/auth.go b/vendor/github.com/coreos/etcd/clientv3/auth.go index fceea770be7..1839042430b 100644 --- a/vendor/github.com/coreos/etcd/clientv3/auth.go +++ b/vendor/github.com/coreos/etcd/clientv3/auth.go @@ -1,4 +1,4 @@ -// Copyright 2016 Nippon Telegraph and Telephone Corporation. +// 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. @@ -15,23 +15,49 @@ package clientv3 import ( + "fmt" + "strings" + + "github.com/coreos/etcd/auth/authpb" pb "github.com/coreos/etcd/etcdserver/etcdserverpb" "golang.org/x/net/context" "google.golang.org/grpc" ) type ( - AuthEnableResponse pb.AuthEnableResponse - AuthUserAddResponse pb.AuthUserAddResponse - AuthUserDeleteResponse pb.AuthUserDeleteResponse - AuthUserChangePasswordResponse pb.AuthUserChangePasswordResponse - AuthRoleAddResponse pb.AuthRoleAddResponse + AuthEnableResponse pb.AuthEnableResponse + AuthDisableResponse pb.AuthDisableResponse + AuthenticateResponse pb.AuthenticateResponse + AuthUserAddResponse pb.AuthUserAddResponse + AuthUserDeleteResponse pb.AuthUserDeleteResponse + AuthUserChangePasswordResponse pb.AuthUserChangePasswordResponse + AuthUserGrantRoleResponse pb.AuthUserGrantRoleResponse + AuthUserGetResponse pb.AuthUserGetResponse + AuthUserRevokeRoleResponse pb.AuthUserRevokeRoleResponse + AuthRoleAddResponse pb.AuthRoleAddResponse + AuthRoleGrantPermissionResponse pb.AuthRoleGrantPermissionResponse + AuthRoleGetResponse pb.AuthRoleGetResponse + AuthRoleRevokePermissionResponse pb.AuthRoleRevokePermissionResponse + AuthRoleDeleteResponse pb.AuthRoleDeleteResponse + AuthUserListResponse pb.AuthUserListResponse + AuthRoleListResponse pb.AuthRoleListResponse + + PermissionType authpb.Permission_Type +) + +const ( + PermRead = authpb.READ + PermWrite = authpb.WRITE + PermReadWrite = authpb.READWRITE ) type Auth interface { // AuthEnable enables auth of an etcd cluster. AuthEnable(ctx context.Context) (*AuthEnableResponse, error) + // AuthDisable disables auth of an etcd cluster. + AuthDisable(ctx context.Context) (*AuthDisableResponse, error) + // UserAdd adds a new user to an etcd cluster. UserAdd(ctx context.Context, name string, password string) (*AuthUserAddResponse, error) @@ -41,8 +67,35 @@ type Auth interface { // UserChangePassword changes a password of a user. UserChangePassword(ctx context.Context, name string, password string) (*AuthUserChangePasswordResponse, error) - // RoleAdd adds a new user to an etcd cluster. + // UserGrantRole grants a role to a user. + UserGrantRole(ctx context.Context, user string, role string) (*AuthUserGrantRoleResponse, error) + + // UserGet gets a detailed information of a user. + UserGet(ctx context.Context, name string) (*AuthUserGetResponse, error) + + // UserList gets a list of all users. + UserList(ctx context.Context) (*AuthUserListResponse, error) + + // UserRevokeRole revokes a role of a user. + UserRevokeRole(ctx context.Context, name string, role string) (*AuthUserRevokeRoleResponse, error) + + // RoleAdd adds a new role to an etcd cluster. RoleAdd(ctx context.Context, name string) (*AuthRoleAddResponse, error) + + // RoleGrantPermission grants a permission to a role. + RoleGrantPermission(ctx context.Context, name string, key, rangeEnd string, permType PermissionType) (*AuthRoleGrantPermissionResponse, error) + + // RoleGet gets a detailed information of a role. + RoleGet(ctx context.Context, role string) (*AuthRoleGetResponse, error) + + // RoleList gets a list of all roles. + RoleList(ctx context.Context) (*AuthRoleListResponse, error) + + // RoleRevokePermission revokes a permission from a role. + RoleRevokePermission(ctx context.Context, role string, key, rangeEnd string) (*AuthRoleRevokePermissionResponse, error) + + // RoleDelete deletes a role. + RoleDelete(ctx context.Context, role string) (*AuthRoleDeleteResponse, error) } type auth struct { @@ -62,26 +115,115 @@ func NewAuth(c *Client) Auth { } func (auth *auth) AuthEnable(ctx context.Context) (*AuthEnableResponse, error) { - resp, err := auth.remote.AuthEnable(ctx, &pb.AuthEnableRequest{}) - return (*AuthEnableResponse)(resp), err + 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{}, grpc.FailFast(false)) + return (*AuthDisableResponse)(resp), toErr(ctx, err) } func (auth *auth) UserAdd(ctx context.Context, name string, password string) (*AuthUserAddResponse, error) { - resp, err := auth.remote.UserAdd(ctx, &pb.AuthUserAddRequest{Name: name, Password: password}) - return (*AuthUserAddResponse)(resp), err + resp, err := auth.remote.UserAdd(ctx, &pb.AuthUserAddRequest{Name: name, Password: password}, grpc.FailFast(false)) + return (*AuthUserAddResponse)(resp), toErr(ctx, err) } func (auth *auth) UserDelete(ctx context.Context, name string) (*AuthUserDeleteResponse, error) { - resp, err := auth.remote.UserDelete(ctx, &pb.AuthUserDeleteRequest{Name: name}) - return (*AuthUserDeleteResponse)(resp), err + resp, err := auth.remote.UserDelete(ctx, &pb.AuthUserDeleteRequest{Name: name}, grpc.FailFast(false)) + return (*AuthUserDeleteResponse)(resp), toErr(ctx, err) } func (auth *auth) UserChangePassword(ctx context.Context, name string, password string) (*AuthUserChangePasswordResponse, error) { - resp, err := auth.remote.UserChangePassword(ctx, &pb.AuthUserChangePasswordRequest{Name: name, Password: password}) - return (*AuthUserChangePasswordResponse)(resp), err + resp, err := auth.remote.UserChangePassword(ctx, &pb.AuthUserChangePasswordRequest{Name: name, Password: password}, grpc.FailFast(false)) + return (*AuthUserChangePasswordResponse)(resp), toErr(ctx, err) +} + +func (auth *auth) UserGrantRole(ctx context.Context, user string, role string) (*AuthUserGrantRoleResponse, error) { + resp, err := auth.remote.UserGrantRole(ctx, &pb.AuthUserGrantRoleRequest{User: user, Role: role}, grpc.FailFast(false)) + return (*AuthUserGrantRoleResponse)(resp), toErr(ctx, err) +} + +func (auth *auth) UserGet(ctx context.Context, name string) (*AuthUserGetResponse, error) { + resp, err := auth.remote.UserGet(ctx, &pb.AuthUserGetRequest{Name: name}, grpc.FailFast(false)) + return (*AuthUserGetResponse)(resp), toErr(ctx, err) +} + +func (auth *auth) UserList(ctx context.Context) (*AuthUserListResponse, error) { + resp, err := auth.remote.UserList(ctx, &pb.AuthUserListRequest{}, grpc.FailFast(false)) + return (*AuthUserListResponse)(resp), toErr(ctx, err) +} + +func (auth *auth) UserRevokeRole(ctx context.Context, name string, role string) (*AuthUserRevokeRoleResponse, error) { + resp, err := auth.remote.UserRevokeRole(ctx, &pb.AuthUserRevokeRoleRequest{Name: name, Role: role}, grpc.FailFast(false)) + return (*AuthUserRevokeRoleResponse)(resp), toErr(ctx, err) } func (auth *auth) RoleAdd(ctx context.Context, name string) (*AuthRoleAddResponse, error) { - resp, err := auth.remote.RoleAdd(ctx, &pb.AuthRoleAddRequest{Name: name}) - return (*AuthRoleAddResponse)(resp), err + resp, err := auth.remote.RoleAdd(ctx, &pb.AuthRoleAddRequest{Name: name}, grpc.FailFast(false)) + return (*AuthRoleAddResponse)(resp), toErr(ctx, err) +} + +func (auth *auth) RoleGrantPermission(ctx context.Context, name string, key, rangeEnd string, permType PermissionType) (*AuthRoleGrantPermissionResponse, error) { + perm := &authpb.Permission{ + Key: []byte(key), + RangeEnd: []byte(rangeEnd), + PermType: authpb.Permission_Type(permType), + } + resp, err := auth.remote.RoleGrantPermission(ctx, &pb.AuthRoleGrantPermissionRequest{Name: name, Perm: perm}, grpc.FailFast(false)) + return (*AuthRoleGrantPermissionResponse)(resp), toErr(ctx, err) +} + +func (auth *auth) RoleGet(ctx context.Context, role string) (*AuthRoleGetResponse, error) { + resp, err := auth.remote.RoleGet(ctx, &pb.AuthRoleGetRequest{Role: role}, grpc.FailFast(false)) + return (*AuthRoleGetResponse)(resp), toErr(ctx, err) +} + +func (auth *auth) RoleList(ctx context.Context) (*AuthRoleListResponse, error) { + resp, err := auth.remote.RoleList(ctx, &pb.AuthRoleListRequest{}, grpc.FailFast(false)) + return (*AuthRoleListResponse)(resp), toErr(ctx, err) +} + +func (auth *auth) RoleRevokePermission(ctx context.Context, role string, key, rangeEnd string) (*AuthRoleRevokePermissionResponse, error) { + resp, err := auth.remote.RoleRevokePermission(ctx, &pb.AuthRoleRevokePermissionRequest{Role: role, Key: key, RangeEnd: rangeEnd}, grpc.FailFast(false)) + return (*AuthRoleRevokePermissionResponse)(resp), toErr(ctx, err) +} + +func (auth *auth) RoleDelete(ctx context.Context, role string) (*AuthRoleDeleteResponse, error) { + resp, err := auth.remote.RoleDelete(ctx, &pb.AuthRoleDeleteRequest{Role: role}, grpc.FailFast(false)) + return (*AuthRoleDeleteResponse)(resp), toErr(ctx, err) +} + +func StrToPermissionType(s string) (PermissionType, error) { + val, ok := authpb.Permission_Type_value[strings.ToUpper(s)] + if ok { + return PermissionType(val), nil + } + return PermissionType(-1), fmt.Errorf("invalid permission type: %s", s) +} + +type authenticator struct { + conn *grpc.ClientConn // conn in-use + remote pb.AuthClient +} + +func (auth *authenticator) authenticate(ctx context.Context, name string, password string) (*AuthenticateResponse, error) { + resp, err := auth.remote.Authenticate(ctx, &pb.AuthenticateRequest{Name: name, Password: password}, grpc.FailFast(false)) + return (*AuthenticateResponse)(resp), toErr(ctx, err) +} + +func (auth *authenticator) close() { + auth.conn.Close() +} + +func newAuthenticator(endpoint string, opts []grpc.DialOption) (*authenticator, error) { + conn, err := grpc.Dial(endpoint, opts...) + if err != nil { + return nil, err + } + + return &authenticator{ + conn: conn, + remote: pb.NewAuthClient(conn), + }, nil } diff --git a/vendor/github.com/coreos/etcd/clientv3/balancer.go b/vendor/github.com/coreos/etcd/clientv3/balancer.go new file mode 100644 index 00000000000..31871b8a4b6 --- /dev/null +++ b/vendor/github.com/coreos/etcd/clientv3/balancer.go @@ -0,0 +1,64 @@ +// 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 clientv3 + +import ( + "net/url" + "strings" + "sync/atomic" + + "golang.org/x/net/context" + "google.golang.org/grpc" +) + +// simpleBalancer does the bare minimum to expose multiple eps +// to the grpc reconnection code path +type simpleBalancer struct { + // eps are the client's endpoints stripped of any URL scheme + eps []string + ch chan []grpc.Address + numGets uint32 +} + +func newSimpleBalancer(eps []string) grpc.Balancer { + ch := make(chan []grpc.Address, 1) + addrs := make([]grpc.Address, len(eps)) + for i := range eps { + addrs[i].Addr = getHost(eps[i]) + } + ch <- addrs + return &simpleBalancer{eps: eps, ch: ch} +} + +func (b *simpleBalancer) Start(target string) error { return nil } +func (b *simpleBalancer) Up(addr grpc.Address) func(error) { return func(error) {} } +func (b *simpleBalancer) Get(ctx context.Context, opts grpc.BalancerGetOptions) (grpc.Address, func(), error) { + v := atomic.AddUint32(&b.numGets, 1) + ep := b.eps[v%uint32(len(b.eps))] + return grpc.Address{Addr: getHost(ep)}, func() {}, nil +} +func (b *simpleBalancer) Notify() <-chan []grpc.Address { return b.ch } +func (b *simpleBalancer) Close() error { + close(b.ch) + return nil +} + +func getHost(ep string) string { + url, uerr := url.Parse(ep) + if uerr != nil || !strings.Contains(ep, "://") { + return ep + } + return url.Host +} diff --git a/vendor/github.com/coreos/etcd/clientv3/client.go b/vendor/github.com/coreos/etcd/clientv3/client.go index 71c64ef0fad..66d5a3c0f96 100644 --- a/vendor/github.com/coreos/etcd/clientv3/client.go +++ b/vendor/github.com/coreos/etcd/clientv3/client.go @@ -1,4 +1,4 @@ -// Copyright 2016 CoreOS, Inc. +// 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. @@ -15,18 +15,22 @@ package clientv3 import ( + "crypto/tls" "errors" + "fmt" "io/ioutil" "log" "net" "net/url" "strings" - "sync" "time" + "github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes" + "golang.org/x/net/context" "google.golang.org/grpc" "google.golang.org/grpc/credentials" + "google.golang.org/grpc/metadata" ) var ( @@ -42,21 +46,21 @@ type Client struct { Auth Maintenance - conn *grpc.ClientConn - cfg Config - creds *credentials.TransportAuthenticator - mu sync.RWMutex // protects connection selection and error list - errors []error // errors passed to retryConnection + conn *grpc.ClientConn + cfg Config + creds *credentials.TransportCredentials ctx context.Context cancel context.CancelFunc + + // Username is a username for authentication + Username string + // Password is a password for authentication + Password string } // New creates a new etcdv3 client from a given configuration. func New(cfg Config) (*Client, error) { - if cfg.RetryDialer == nil { - cfg.RetryDialer = dialEndpointList - } if len(cfg.Endpoints) == 0 { return nil, ErrNoAvailableEndpoints } @@ -80,17 +84,8 @@ func NewFromConfigFile(path string) (*Client, error) { // Close shuts down the client's etcd connections. func (c *Client) Close() error { - c.mu.Lock() - if c.cancel == nil { - c.mu.Unlock() - return nil - } c.cancel() - c.cancel = nil - c.mu.Unlock() - c.Watcher.Close() - c.Lease.Close() - return c.conn.Close() + return toErr(c.ctx, c.conn.Close()) } // Ctx is a context for "out of band" messages (e.g., for sending @@ -101,72 +96,157 @@ 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 } -// Errors returns all errors that have been observed since called last. -func (c *Client) Errors() (errs []error) { - c.mu.Lock() - defer c.mu.Unlock() - errs = c.errors - c.errors = nil - return errs +type authTokenCredential struct { + token string } -// Dial establishes a connection for a given endpoint using the client's config -func (c *Client) Dial(endpoint string) (*grpc.ClientConn, error) { +func (cred authTokenCredential) RequireTransportSecurity() bool { + return false +} + +func (cred authTokenCredential) GetRequestMetadata(ctx context.Context, s ...string) (map[string]string, error) { + return map[string]string{ + "token": cred.token, + }, nil +} + +func (c *Client) dialTarget(endpoint string) (proto string, host string, creds *credentials.TransportCredentials) { + proto = "tcp" + host = endpoint + creds = c.creds + url, uerr := url.Parse(endpoint) + if uerr != nil || !strings.Contains(endpoint, "://") { + return + } + // strip scheme:// prefix since grpc dials by host + host = url.Host + switch url.Scheme { + case "unix": + proto = "unix" + case "http": + creds = nil + case "https": + if creds != nil { + break + } + tlsconfig := &tls.Config{} + emptyCreds := credentials.NewTLS(tlsconfig) + creds = &emptyCreds + default: + return "", "", nil + } + return +} + +// dialSetupOpts gives the dial opts prioer to any authentication +func (c *Client) dialSetupOpts(endpoint string, dopts ...grpc.DialOption) []grpc.DialOption { opts := []grpc.DialOption{ grpc.WithBlock(), grpc.WithTimeout(c.cfg.DialTimeout), } - if c.creds != nil { - opts = append(opts, grpc.WithTransportCredentials(*c.creds)) - } else { - opts = append(opts, grpc.WithInsecure()) + 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] } - proto := "tcp" - if url, uerr := url.Parse(endpoint); uerr == nil && url.Scheme == "unix" { - proto = "unix" - // strip unix:// prefix so certs work - endpoint = url.Host - } - f := func(a string, t time.Duration) (net.Conn, error) { + f := func(host string, t time.Duration) (net.Conn, error) { + proto, host, _ := c.dialTarget(host2ep[host]) + if proto == "" { + return nil, fmt.Errorf("unknown scheme for %q", host) + } select { case <-c.ctx.Done(): return nil, c.ctx.Err() default: } - return net.DialTimeout(proto, a, t) + return net.DialTimeout(proto, host, t) } opts = append(opts, grpc.WithDialer(f)) - conn, err := grpc.Dial(endpoint, opts...) + _, _, creds := c.dialTarget(endpoint) + if creds != nil { + opts = append(opts, grpc.WithTransportCredentials(*creds)) + } else { + opts = append(opts, grpc.WithInsecure()) + } + + return opts +} + +// Dial connects to a single endpoint using the client's config. +func (c *Client) Dial(endpoint string) (*grpc.ClientConn, error) { + return c.dial(endpoint) +} + +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 + } + defer auth.close() + + resp, err := auth.authenticate(c.ctx, c.Username, c.Password) + if err != nil { + return nil, err + } + opts = append(opts, grpc.WithPerRPCCredentials(authTokenCredential{token: resp.Token})) + } + + conn, err := grpc.Dial(host, opts...) if err != nil { return nil, err } return conn, nil } +// WithRequireLeader requires client requests to only succeed +// when the cluster has a leader. +func WithRequireLeader(ctx context.Context) context.Context { + md := metadata.Pairs(rpctypes.MetadataRequireLeaderKey, rpctypes.MetadataHasLeader) + return metadata.NewContext(ctx, md) +} + func newClient(cfg *Config) (*Client, error) { if cfg == nil { - cfg = &Config{RetryDialer: dialEndpointList} + cfg = &Config{} } - var creds *credentials.TransportAuthenticator + var creds *credentials.TransportCredentials if cfg.TLS != nil { c := credentials.NewTLS(cfg.TLS) creds = &c } + // use a temporary skeleton client to bootstrap first connection ctx, cancel := context.WithCancel(context.TODO()) - conn, err := cfg.RetryDialer(&Client{cfg: *cfg, creds: creds, ctx: ctx}) - if err != nil { - return nil, err - } client := &Client{ - conn: conn, + conn: nil, cfg: *cfg, creds: creds, ctx: ctx, cancel: cancel, } + if cfg.Username != "" && cfg.Password != "" { + client.Username = cfg.Username + client.Password = cfg.Password + } + + b := newSimpleBalancer(cfg.Endpoints) + conn, err := client.dial(cfg.Endpoints[0], grpc.WithBalancer(b)) + if err != nil { + return nil, err + } + client.conn = conn + client.Cluster = NewCluster(client) client.KV = NewKV(client) client.Lease = NewLease(client) @@ -184,60 +264,35 @@ func newClient(cfg *Config) (*Client, error) { } // ActiveConnection returns the current in-use connection -func (c *Client) ActiveConnection() *grpc.ClientConn { - c.mu.RLock() - defer c.mu.RUnlock() - return c.conn -} +func (c *Client) ActiveConnection() *grpc.ClientConn { return c.conn } -// retryConnection establishes a new connection -func (c *Client) retryConnection(oldConn *grpc.ClientConn, err error) (*grpc.ClientConn, error) { - c.mu.Lock() - defer c.mu.Unlock() - if err != nil { - c.errors = append(c.errors, err) - } - if c.cancel == nil { - return nil, c.ctx.Err() - } - if oldConn != c.conn { - // conn has already been updated - return c.conn, nil - } - - oldConn.Close() - if st, _ := oldConn.State(); st != grpc.Shutdown { - // wait for shutdown so grpc doesn't leak sleeping goroutines - oldConn.WaitForStateChange(c.ctx, st) - } - - conn, dialErr := c.cfg.RetryDialer(c) - if dialErr != nil { - c.errors = append(c.errors, dialErr) - return nil, dialErr - } - c.conn = conn - return c.conn, nil -} - -// dialEndpointList attempts to connect to each endpoint in order until a -// connection is established. -func dialEndpointList(c *Client) (*grpc.ClientConn, error) { - var err error - for _, ep := range c.Endpoints() { - conn, curErr := c.Dial(ep) - if curErr != nil { - err = curErr - } else { - return conn, nil - } - } - return nil, err -} - -// isHalted returns true if the given error and context indicate no forward +// isHaltErr returns true if the given error and context indicate no forward // progress can be made, even after reconnecting. -func isHalted(ctx context.Context, err error) bool { - isRPCError := strings.HasPrefix(grpc.ErrorDesc(err), "etcdserver: ") - return isRPCError || ctx.Err() != nil +func isHaltErr(ctx context.Context, err error) bool { + if ctx != nil && ctx.Err() != nil { + return true + } + 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 strings.Contains(err.Error(), grpc.ErrClientConnClosing.Error()) || + strings.Contains(err.Error(), "etcdserver:") +} + +func toErr(ctx context.Context, err error) error { + if err == nil { + return nil + } + err = rpctypes.Error(err) + if ctx.Err() != nil && strings.Contains(err.Error(), "context") { + err = ctx.Err() + } else if strings.Contains(err.Error(), grpc.ErrClientConnClosing.Error()) { + 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 8d1369cb3f4..ee0244e4ee8 100644 --- a/vendor/github.com/coreos/etcd/clientv3/cluster.go +++ b/vendor/github.com/coreos/etcd/clientv3/cluster.go @@ -1,4 +1,4 @@ -// Copyright 2016 CoreOS, Inc. +// 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. @@ -15,8 +15,6 @@ package clientv3 import ( - "sync" - pb "github.com/coreos/etcd/etcdserver/etcdserverpb" "golang.org/x/net/context" "google.golang.org/grpc" @@ -34,9 +32,6 @@ type Cluster interface { // MemberList lists the current cluster membership. MemberList(ctx context.Context) (*MemberListResponse, error) - // MemberLeader returns the current leader member. - MemberLeader(ctx context.Context) (*Member, error) - // MemberAdd adds a new member into the cluster. MemberAdd(ctx context.Context, peerAddrs []string) (*MemberAddResponse, error) @@ -48,70 +43,47 @@ type Cluster interface { } type cluster struct { - c *Client - - mu sync.Mutex - conn *grpc.ClientConn // conn in-use remote pb.ClusterClient } func NewCluster(c *Client) Cluster { - conn := c.ActiveConnection() - - return &cluster{ - c: c, - - conn: conn, - remote: pb.NewClusterClient(conn), - } + return &cluster{remote: pb.NewClusterClient(c.conn)} } func (c *cluster) MemberAdd(ctx context.Context, peerAddrs []string) (*MemberAddResponse, error) { r := &pb.MemberAddRequest{PeerURLs: peerAddrs} - resp, err := c.getRemote().MemberAdd(ctx, r) + resp, err := c.remote.MemberAdd(ctx, r, grpc.FailFast(false)) if err == nil { return (*MemberAddResponse)(resp), nil } - - if isHalted(ctx, err) { - return nil, err + if isHaltErr(ctx, err) { + return nil, toErr(ctx, err) } - - go c.switchRemote(err) - return nil, err + return nil, toErr(ctx, err) } func (c *cluster) MemberRemove(ctx context.Context, id uint64) (*MemberRemoveResponse, error) { r := &pb.MemberRemoveRequest{ID: id} - resp, err := c.getRemote().MemberRemove(ctx, r) + resp, err := c.remote.MemberRemove(ctx, r, grpc.FailFast(false)) if err == nil { return (*MemberRemoveResponse)(resp), nil } - - if isHalted(ctx, err) { - return nil, err + if isHaltErr(ctx, err) { + return nil, toErr(ctx, err) } - - go c.switchRemote(err) - return nil, err + return nil, toErr(ctx, err) } func (c *cluster) MemberUpdate(ctx context.Context, id uint64, peerAddrs []string) (*MemberUpdateResponse, error) { // it is safe to retry on update. for { r := &pb.MemberUpdateRequest{ID: id, PeerURLs: peerAddrs} - resp, err := c.getRemote().MemberUpdate(ctx, r) + resp, err := c.remote.MemberUpdate(ctx, r, grpc.FailFast(false)) if err == nil { return (*MemberUpdateResponse)(resp), nil } - - if isHalted(ctx, err) { - return nil, err - } - - err = c.switchRemote(err) - if err != nil { - return nil, err + if isHaltErr(ctx, err) { + return nil, toErr(ctx, err) } } } @@ -119,52 +91,12 @@ func (c *cluster) MemberUpdate(ctx context.Context, id uint64, peerAddrs []strin func (c *cluster) MemberList(ctx context.Context) (*MemberListResponse, error) { // it is safe to retry on list. for { - resp, err := c.getRemote().MemberList(ctx, &pb.MemberListRequest{}) + resp, err := c.remote.MemberList(ctx, &pb.MemberListRequest{}, grpc.FailFast(false)) if err == nil { return (*MemberListResponse)(resp), nil } - - if isHalted(ctx, err) { - return nil, err - } - - err = c.switchRemote(err) - if err != nil { - return nil, err + if isHaltErr(ctx, err) { + return nil, toErr(ctx, err) } } } - -func (c *cluster) MemberLeader(ctx context.Context) (*Member, error) { - resp, err := c.MemberList(ctx) - if err != nil { - return nil, err - } - for _, m := range resp.Members { - if m.IsLeader { - return (*Member)(m), nil - } - } - return nil, nil -} - -func (c *cluster) getRemote() pb.ClusterClient { - c.mu.Lock() - defer c.mu.Unlock() - - return c.remote -} - -func (c *cluster) switchRemote(prevErr error) error { - newConn, err := c.c.retryConnection(c.conn, prevErr) - if err != nil { - return err - } - - c.mu.Lock() - defer c.mu.Unlock() - - c.conn = newConn - c.remote = pb.NewClusterClient(c.conn) - return nil -} diff --git a/vendor/github.com/coreos/etcd/clientv3/compact_op.go b/vendor/github.com/coreos/etcd/clientv3/compact_op.go new file mode 100644 index 00000000000..32d97eb0cc1 --- /dev/null +++ b/vendor/github.com/coreos/etcd/clientv3/compact_op.go @@ -0,0 +1,53 @@ +// 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 clientv3 + +import ( + pb "github.com/coreos/etcd/etcdserver/etcdserverpb" +) + +// CompactOp represents a compact operation. +type CompactOp struct { + revision int64 + physical bool +} + +// CompactOption configures compact operation. +type CompactOption func(*CompactOp) + +func (op *CompactOp) applyCompactOpts(opts []CompactOption) { + for _, opt := range opts { + opt(op) + } +} + +// OpCompact wraps slice CompactOption to create a CompactOp. +func OpCompact(rev int64, opts ...CompactOption) CompactOp { + ret := CompactOp{revision: rev} + ret.applyCompactOpts(opts) + return ret +} + +func (op CompactOp) toRequest() *pb.CompactionRequest { + return &pb.CompactionRequest{Revision: op.revision, Physical: op.physical} +} + +// WithCompactPhysical makes compact RPC call wait until +// the compaction is physically applied to the local database +// such that compacted entries are totally removed from the +// backend database. +func WithCompactPhysical() CompactOption { + return func(op *CompactOp) { op.physical = true } +} diff --git a/vendor/github.com/coreos/etcd/clientv3/compare.go b/vendor/github.com/coreos/etcd/clientv3/compare.go index d74db77958f..601349431e9 100644 --- a/vendor/github.com/coreos/etcd/clientv3/compare.go +++ b/vendor/github.com/coreos/etcd/clientv3/compare.go @@ -1,4 +1,4 @@ -// Copyright 2016 CoreOS, Inc. +// 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. diff --git a/vendor/github.com/coreos/etcd/clientv3/config.go b/vendor/github.com/coreos/etcd/clientv3/config.go index 34cec6d642a..066b41ecef9 100644 --- a/vendor/github.com/coreos/etcd/clientv3/config.go +++ b/vendor/github.com/coreos/etcd/clientv3/config.go @@ -1,4 +1,4 @@ -// Copyright 2016 CoreOS, Inc. +// 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. @@ -22,19 +22,12 @@ import ( "github.com/coreos/etcd/pkg/tlsutil" "github.com/ghodss/yaml" - "google.golang.org/grpc" ) -// EndpointDialer is a policy for choosing which endpoint to dial next -type EndpointDialer func(*Client) (*grpc.ClientConn, error) - type Config struct { // Endpoints is a list of URLs Endpoints []string - // RetryDialer chooses the next endpoint to use - RetryDialer EndpointDialer - // DialTimeout is the timeout for failing to establish a connection. DialTimeout time.Duration @@ -43,9 +36,15 @@ type Config struct { // Logger is the logger used by client library. Logger Logger + + // Username is a username for authentication + Username string + + // Password is a password for authentication + Password string } -type YamlConfig struct { +type yamlConfig struct { Endpoints []string `json:"endpoints"` DialTimeout time.Duration `json:"dial-timeout"` InsecureTransport bool `json:"insecure-transport"` @@ -61,7 +60,7 @@ func configFromFile(fpath string) (*Config, error) { return nil, err } - yc := &YamlConfig{} + yc := &yamlConfig{} err = yaml.Unmarshal(b, yc) if err != nil { diff --git a/vendor/github.com/coreos/etcd/clientv3/doc.go b/vendor/github.com/coreos/etcd/clientv3/doc.go index 641dea3516e..9ce84aa57c1 100644 --- a/vendor/github.com/coreos/etcd/clientv3/doc.go +++ b/vendor/github.com/coreos/etcd/clientv3/doc.go @@ -1,4 +1,4 @@ -// Copyright 2016 CoreOS, Inc. +// 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. diff --git a/vendor/github.com/coreos/etcd/clientv3/kv.go b/vendor/github.com/coreos/etcd/clientv3/kv.go index 04e33688b4c..ff68f73f4a6 100644 --- a/vendor/github.com/coreos/etcd/clientv3/kv.go +++ b/vendor/github.com/coreos/etcd/clientv3/kv.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. @@ -15,18 +15,17 @@ package clientv3 import ( - "sync" - pb "github.com/coreos/etcd/etcdserver/etcdserverpb" "golang.org/x/net/context" "google.golang.org/grpc" ) type ( - PutResponse pb.PutResponse - GetResponse pb.RangeResponse - DeleteResponse pb.DeleteRangeResponse - TxnResponse pb.TxnResponse + CompactResponse pb.CompactionResponse + PutResponse pb.PutResponse + GetResponse pb.RangeResponse + DeleteResponse pb.DeleteRangeResponse + TxnResponse pb.TxnResponse ) type KV interface { @@ -50,7 +49,7 @@ type KV interface { Delete(ctx context.Context, key string, opts ...OpOption) (*DeleteResponse, error) // Compact compacts etcd KV history before the given rev. - Compact(ctx context.Context, rev int64) error + Compact(ctx context.Context, rev int64, opts ...CompactOption) (*CompactResponse, error) // Do applies a single Op on KV without a transaction. // Do is useful when declaring operations to be issued at a later time @@ -61,7 +60,7 @@ type KV interface { // Do is useful when creating arbitrary operations to be issued at a // later time; the user can range over the operations, calling Do to // execute them. Get/Put/Delete, on the other hand, are best suited - // for when the operation should be issued at the time of declaration. + // for when the operation should be issued at the time of declaration. Do(ctx context.Context, op Op) (OpResponse, error) // Txn creates a transaction. @@ -74,54 +73,39 @@ type OpResponse struct { del *DeleteResponse } -type kv struct { - c *Client +func (op OpResponse) Put() *PutResponse { return op.put } +func (op OpResponse) Get() *GetResponse { return op.get } +func (op OpResponse) Del() *DeleteResponse { return op.del } - mu sync.Mutex // guards all fields - conn *grpc.ClientConn // conn in-use +type kv struct { remote pb.KVClient } func NewKV(c *Client) KV { - conn := c.ActiveConnection() - remote := pb.NewKVClient(conn) - - return &kv{ - conn: c.ActiveConnection(), - remote: remote, - - c: c, - } + return &kv{remote: pb.NewKVClient(c.conn)} } 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, err + return r.put, toErr(ctx, err) } func (kv *kv) Get(ctx context.Context, key string, opts ...OpOption) (*GetResponse, error) { r, err := kv.Do(ctx, OpGet(key, opts...)) - return r.get, err + return r.get, toErr(ctx, err) } func (kv *kv) Delete(ctx context.Context, key string, opts ...OpOption) (*DeleteResponse, error) { r, err := kv.Do(ctx, OpDelete(key, opts...)) - return r.del, err + return r.del, toErr(ctx, err) } -func (kv *kv) Compact(ctx context.Context, rev int64) error { - r := &pb.CompactionRequest{Revision: rev} - _, err := kv.getRemote().Compact(ctx, r) - if err == nil { - return nil +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)) + if err != nil { + return nil, toErr(ctx, err) } - - if isHalted(ctx, err) { - return err - } - - go kv.switchRemote(err) - return err + return (*CompactResponse)(resp), err } func (kv *kv) Txn(ctx context.Context) Txn { @@ -133,75 +117,60 @@ func (kv *kv) Txn(ctx context.Context) Txn { func (kv *kv) Do(ctx context.Context, op Op) (OpResponse, error) { for { - var err error - switch op.t { - // 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} - if op.sort != nil { - r.SortOrder = pb.RangeRequest_SortOrder(op.sort.Order) - r.SortTarget = pb.RangeRequest_SortTarget(op.sort.Target) - } - - resp, err = kv.getRemote().Range(ctx, r) - if err == nil { - return OpResponse{get: (*GetResponse)(resp)}, nil - } - case tPut: - var resp *pb.PutResponse - r := &pb.PutRequest{Key: op.key, Value: op.val, Lease: int64(op.leaseID)} - resp, err = kv.getRemote().Put(ctx, r) - if err == nil { - return OpResponse{put: (*PutResponse)(resp)}, nil - } - case tDeleteRange: - var resp *pb.DeleteRangeResponse - r := &pb.DeleteRangeRequest{Key: op.key, RangeEnd: op.end} - resp, err = kv.getRemote().DeleteRange(ctx, r) - if err == nil { - return OpResponse{del: (*DeleteResponse)(resp)}, nil - } - default: - panic("Unknown op") + resp, err := kv.do(ctx, op) + if err == nil { + return resp, nil } - - if isHalted(ctx, err) { - return OpResponse{}, err + if isHaltErr(ctx, err) { + return resp, toErr(ctx, err) } - // do not retry on modifications if op.isWrite() { - go kv.switchRemote(err) - return OpResponse{}, err - } - - if nerr := kv.switchRemote(err); nerr != nil { - return OpResponse{}, nerr + return resp, toErr(ctx, err) } } } -func (kv *kv) switchRemote(prevErr error) error { - // Usually it's a bad idea to lock on network i/o but here it's OK - // since the link is down and new requests can't be processed anyway. - // Likewise, if connecting stalls, closing the Client can break the - // lock via context cancelation. - kv.mu.Lock() - defer kv.mu.Unlock() +func (kv *kv) do(ctx context.Context, op Op) (OpResponse, error) { + var err error + switch op.t { + // 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) + } - newConn, err := kv.c.retryConnection(kv.conn, prevErr) - if err != nil { - return err + resp, err = kv.remote.Range(ctx, r, grpc.FailFast(false)) + if err == nil { + return OpResponse{get: (*GetResponse)(resp)}, nil + } + case tPut: + var resp *pb.PutResponse + r := &pb.PutRequest{Key: op.key, Value: op.val, Lease: int64(op.leaseID)} + resp, err = kv.remote.Put(ctx, r, grpc.FailFast(false)) + if err == nil { + return OpResponse{put: (*PutResponse)(resp)}, nil + } + case tDeleteRange: + var resp *pb.DeleteRangeResponse + r := &pb.DeleteRangeRequest{Key: op.key, RangeEnd: op.end} + resp, err = kv.remote.DeleteRange(ctx, r, grpc.FailFast(false)) + if err == nil { + return OpResponse{del: (*DeleteResponse)(resp)}, nil + } + default: + panic("Unknown op") } - - kv.conn = newConn - kv.remote = pb.NewKVClient(kv.conn) - return nil -} - -func (kv *kv) getRemote() pb.KVClient { - kv.mu.Lock() - defer kv.mu.Unlock() - return kv.remote + return OpResponse{}, err } diff --git a/vendor/github.com/coreos/etcd/clientv3/lease.go b/vendor/github.com/coreos/etcd/clientv3/lease.go index e719de6c737..18bfc3c8703 100644 --- a/vendor/github.com/coreos/etcd/clientv3/lease.go +++ b/vendor/github.com/coreos/etcd/clientv3/lease.go @@ -1,4 +1,4 @@ -// Copyright 2016 CoreOS, Inc. +// 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. @@ -18,19 +18,36 @@ import ( "sync" "time" + "github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes" pb "github.com/coreos/etcd/etcdserver/etcdserverpb" "golang.org/x/net/context" "google.golang.org/grpc" ) type ( - LeaseGrantResponse pb.LeaseGrantResponse - LeaseRevokeResponse pb.LeaseRevokeResponse - LeaseKeepAliveResponse pb.LeaseKeepAliveResponse - LeaseID int64 + LeaseRevokeResponse pb.LeaseRevokeResponse + LeaseID int64 ) +// LeaseGrantResponse is used to convert the protobuf grant response. +type LeaseGrantResponse struct { + *pb.ResponseHeader + ID LeaseID + TTL int64 + Error string +} + +// LeaseKeepAliveResponse is used to convert the protobuf keepalive response. +type LeaseKeepAliveResponse struct { + *pb.ResponseHeader + ID LeaseID + TTL int64 +} + const ( + // defaultTTL is the assumed lease TTL used for the first keepalive + // deadline before the actual TTL is known to the client. + defaultTTL = 5 * time.Second // a small buffer to store unsent lease responses. leaseResponseChSize = 16 // NoLease is a lease ID for the absence of a lease. @@ -57,10 +74,7 @@ type Lease interface { } type lessor struct { - c *Client - - mu sync.Mutex // guards all fields - conn *grpc.ClientConn // conn in-use + mu sync.Mutex // guards all fields // donec is closed when recvKeepAliveLoop stops donec chan struct{} @@ -74,32 +88,38 @@ type lessor struct { stopCancel context.CancelFunc keepAlives map[LeaseID]*keepAlive + + // firstKeepAliveTimeout is the timeout for the first keepalive request + // before the actual TTL is known to the lease client + firstKeepAliveTimeout time.Duration } // keepAlive multiplexes a keepalive for a lease over multiple channels type keepAlive struct { chs []chan<- *LeaseKeepAliveResponse ctxs []context.Context - // deadline is the next time to send a keep alive message + // deadline is the time the keep alive channels close if no response deadline time.Time + // nextKeepAlive is when to send the next keep alive message + nextKeepAlive time.Time // donec is closed on lease revoke, expiration, or cancel. donec chan struct{} } func NewLease(c *Client) Lease { l := &lessor{ - c: c, - conn: c.ActiveConnection(), - - donec: make(chan struct{}), - keepAlives: make(map[LeaseID]*keepAlive), + donec: make(chan struct{}), + keepAlives: make(map[LeaseID]*keepAlive), + remote: pb.NewLeaseClient(c.conn), + firstKeepAliveTimeout: c.cfg.DialTimeout + time.Second, + } + if l.firstKeepAliveTimeout == time.Second { + l.firstKeepAliveTimeout = defaultTTL } - l.remote = pb.NewLeaseClient(l.conn) l.stopCtx, l.stopCancel = context.WithCancel(context.Background()) - go l.recvKeepAliveLoop() - + go l.deadlineLoop() return l } @@ -110,14 +130,20 @@ func (l *lessor) Grant(ctx context.Context, ttl int64) (*LeaseGrantResponse, err for { r := &pb.LeaseGrantRequest{TTL: ttl} - resp, err := l.getRemote().LeaseGrant(cctx, r) + resp, err := l.remote.LeaseGrant(cctx, r, grpc.FailFast(false)) if err == nil { - return (*LeaseGrantResponse)(resp), nil + gresp := &LeaseGrantResponse{ + ResponseHeader: resp.GetHeader(), + ID: LeaseID(resp.ID), + TTL: resp.TTL, + Error: resp.Error, + } + return gresp, nil } - if isHalted(cctx, err) { - return nil, err + if isHaltErr(cctx, err) { + return nil, toErr(ctx, err) } - if nerr := l.switchRemoteAndStream(err); nerr != nil { + if nerr := l.newStream(); nerr != nil { return nil, nerr } } @@ -130,16 +156,15 @@ func (l *lessor) Revoke(ctx context.Context, id LeaseID) (*LeaseRevokeResponse, for { r := &pb.LeaseRevokeRequest{ID: int64(id)} - resp, err := l.getRemote().LeaseRevoke(cctx, r) + resp, err := l.remote.LeaseRevoke(cctx, r, grpc.FailFast(false)) if err == nil { return (*LeaseRevokeResponse)(resp), nil } - if isHalted(ctx, err) { - return nil, err + if isHaltErr(ctx, err) { + return nil, toErr(ctx, err) } - - if nerr := l.switchRemoteAndStream(err); nerr != nil { + if nerr := l.newStream(); nerr != nil { return nil, nerr } } @@ -153,10 +178,11 @@ func (l *lessor) KeepAlive(ctx context.Context, id LeaseID) (<-chan *LeaseKeepAl if !ok { // create fresh keep alive ka = &keepAlive{ - chs: []chan<- *LeaseKeepAliveResponse{ch}, - ctxs: []context.Context{ctx}, - deadline: time.Now(), - donec: make(chan struct{}), + chs: []chan<- *LeaseKeepAliveResponse{ch}, + ctxs: []context.Context{ctx}, + deadline: time.Now().Add(l.firstKeepAliveTimeout), + nextKeepAlive: time.Now(), + donec: make(chan struct{}), } l.keepAlives[id] = ka } else { @@ -179,11 +205,16 @@ func (l *lessor) KeepAliveOnce(ctx context.Context, id LeaseID) (*LeaseKeepAlive for { resp, err := l.keepAliveOnce(cctx, id) if err == nil { + if resp.TTL == 0 { + err = rpctypes.ErrLeaseNotFound + } return resp, err } + if isHaltErr(ctx, err) { + return nil, toErr(ctx, err) + } - nerr := l.switchRemoteAndStream(err) - if nerr != nil { + if nerr := l.newStream(); nerr != nil { return nil, nerr } } @@ -228,26 +259,34 @@ func (l *lessor) keepAliveCtxCloser(id LeaseID, ctx context.Context, donec <-cha } func (l *lessor) keepAliveOnce(ctx context.Context, id LeaseID) (*LeaseKeepAliveResponse, error) { - stream, err := l.getRemote().LeaseKeepAlive(ctx) + cctx, cancel := context.WithCancel(ctx) + defer cancel() + + stream, err := l.remote.LeaseKeepAlive(cctx, grpc.FailFast(false)) if err != nil { - return nil, err + return nil, toErr(ctx, err) } err = stream.Send(&pb.LeaseKeepAliveRequest{ID: int64(id)}) if err != nil { - return nil, err + return nil, toErr(ctx, err) } resp, rerr := stream.Recv() if rerr != nil { - return nil, rerr + return nil, toErr(ctx, rerr) } - return (*LeaseKeepAliveResponse)(resp), nil + + karesp := &LeaseKeepAliveResponse{ + ResponseHeader: resp.GetHeader(), + ID: LeaseID(resp.ID), + TTL: resp.TTL, + } + return karesp, nil } func (l *lessor) recvKeepAliveLoop() { defer func() { - l.stopCancel() l.mu.Lock() close(l.donec) for _, ka := range l.keepAlives { @@ -261,7 +300,7 @@ func (l *lessor) recvKeepAliveLoop() { for serr == nil { resp, err := stream.Recv() if err != nil { - if isHalted(l.stopCtx, err) { + if isHaltErr(l.stopCtx, err) { return } stream, serr = l.resetRecv() @@ -273,7 +312,7 @@ func (l *lessor) recvKeepAliveLoop() { // resetRecv opens a new lease stream and starts sending LeaseKeepAliveRequests func (l *lessor) resetRecv() (pb.Lease_LeaseKeepAliveClient, error) { - if err := l.switchRemoteAndStream(nil); err != nil { + if err := l.newStream(); err != nil { return nil, err } stream := l.getKeepAliveStream() @@ -283,39 +322,68 @@ func (l *lessor) resetRecv() (pb.Lease_LeaseKeepAliveClient, error) { // recvKeepAlive updates a lease based on its LeaseKeepAliveResponse func (l *lessor) recvKeepAlive(resp *pb.LeaseKeepAliveResponse) { - id := LeaseID(resp.ID) + karesp := &LeaseKeepAliveResponse{ + ResponseHeader: resp.GetHeader(), + ID: LeaseID(resp.ID), + TTL: resp.TTL, + } l.mu.Lock() defer l.mu.Unlock() - ka, ok := l.keepAlives[id] + ka, ok := l.keepAlives[karesp.ID] if !ok { return } - if resp.TTL <= 0 { + if karesp.TTL <= 0 { // lease expired; close all keep alive channels - delete(l.keepAlives, id) + delete(l.keepAlives, karesp.ID) ka.Close() return } // send update to all channels - nextDeadline := time.Now().Add(1 + time.Duration(resp.TTL/3)*time.Second) + nextKeepAlive := time.Now().Add(1 + time.Duration(karesp.TTL/3)*time.Second) + ka.deadline = time.Now().Add(time.Duration(karesp.TTL) * time.Second) for _, ch := range ka.chs { select { - case ch <- (*LeaseKeepAliveResponse)(resp): - ka.deadline = nextDeadline + case ch <- karesp: + ka.nextKeepAlive = nextKeepAlive default: } } } +// deadlineLoop reaps any keep alive channels that have not received a response +// within the lease TTL +func (l *lessor) deadlineLoop() { + for { + select { + case <-time.After(time.Second): + case <-l.donec: + return + } + now := time.Now() + l.mu.Lock() + for id, ka := range l.keepAlives { + if ka.deadline.Before(now) { + // waited too long for response; lease may be expired + ka.Close() + delete(l.keepAlives, id) + } + } + l.mu.Unlock() + } +} + // sendKeepAliveLoop sends LeaseKeepAliveRequests for the lifetime of a lease stream func (l *lessor) sendKeepAliveLoop(stream pb.Lease_LeaseKeepAliveClient) { for { select { case <-time.After(500 * time.Millisecond): + case <-stream.Context().Done(): + return case <-l.donec: return case <-l.stopCtx.Done(): @@ -327,7 +395,7 @@ func (l *lessor) sendKeepAliveLoop(stream pb.Lease_LeaseKeepAliveClient) { now := time.Now() l.mu.Lock() for id, ka := range l.keepAlives { - if ka.deadline.Before(now) { + if ka.nextKeepAlive.Before(now) { tosend = append(tosend, id) } } @@ -343,57 +411,18 @@ func (l *lessor) sendKeepAliveLoop(stream pb.Lease_LeaseKeepAliveClient) { } } -func (l *lessor) getRemote() pb.LeaseClient { - l.mu.Lock() - defer l.mu.Unlock() - return l.remote -} - func (l *lessor) getKeepAliveStream() pb.Lease_LeaseKeepAliveClient { l.mu.Lock() defer l.mu.Unlock() return l.stream } -func (l *lessor) switchRemoteAndStream(prevErr error) error { - l.mu.Lock() - conn := l.conn - l.mu.Unlock() - - var ( - err error - newConn *grpc.ClientConn - ) - - if prevErr != nil { - conn.Close() - newConn, err = l.c.retryConnection(conn, prevErr) - if err != nil { - return err - } - } - - l.mu.Lock() - if newConn != nil { - l.conn = newConn - } - - l.remote = pb.NewLeaseClient(l.conn) - l.mu.Unlock() - - serr := l.newStream() - if serr != nil { - return serr - } - return nil -} - func (l *lessor) newStream() error { sctx, cancel := context.WithCancel(l.stopCtx) - stream, err := l.getRemote().LeaseKeepAlive(sctx) + stream, err := l.remote.LeaseKeepAlive(sctx, grpc.FailFast(false)) if err != nil { cancel() - return err + return toErr(sctx, err) } l.mu.Lock() diff --git a/vendor/github.com/coreos/etcd/clientv3/logger.go b/vendor/github.com/coreos/etcd/clientv3/logger.go index 47a31ff05eb..6e57c4e7cc5 100644 --- a/vendor/github.com/coreos/etcd/clientv3/logger.go +++ b/vendor/github.com/coreos/etcd/clientv3/logger.go @@ -1,4 +1,4 @@ -// Copyright 2016 CoreOS, Inc. +// 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. diff --git a/vendor/github.com/coreos/etcd/clientv3/maintenance.go b/vendor/github.com/coreos/etcd/clientv3/maintenance.go index f200cc3b580..718356250be 100644 --- a/vendor/github.com/coreos/etcd/clientv3/maintenance.go +++ b/vendor/github.com/coreos/etcd/clientv3/maintenance.go @@ -1,4 +1,4 @@ -// Copyright 2016 CoreOS, Inc. +// 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. @@ -15,7 +15,7 @@ package clientv3 import ( - "sync" + "io" pb "github.com/coreos/etcd/etcdserver/etcdserverpb" "golang.org/x/net/context" @@ -45,25 +45,20 @@ type Maintenance interface { // times with different endpoints. Defragment(ctx context.Context, endpoint string) (*DefragmentResponse, error) - // Status gets the status of the member. + // Status gets the status of the endpoint. Status(ctx context.Context, endpoint string) (*StatusResponse, error) + + // Snapshot provides a reader for a snapshot of a backend. + Snapshot(ctx context.Context) (io.ReadCloser, error) } type maintenance struct { - c *Client - - mu sync.Mutex - conn *grpc.ClientConn // conn in-use + c *Client remote pb.MaintenanceClient } func NewMaintenance(c *Client) Maintenance { - conn := c.ActiveConnection() - return &maintenance{ - c: c, - conn: conn, - remote: pb.NewMaintenanceClient(conn), - } + return &maintenance{c: c, remote: pb.NewMaintenanceClient(c.conn)} } func (m *maintenance) AlarmList(ctx context.Context) (*AlarmResponse, error) { @@ -73,15 +68,12 @@ func (m *maintenance) AlarmList(ctx context.Context) (*AlarmResponse, error) { Alarm: pb.AlarmType_NONE, // all } for { - resp, err := m.getRemote().Alarm(ctx, req) + resp, err := m.remote.Alarm(ctx, req, grpc.FailFast(false)) if err == nil { return (*AlarmResponse)(resp), nil } - if isHalted(ctx, err) { - return nil, err - } - if err = m.switchRemote(err); err != nil { - return nil, err + if isHaltErr(ctx, err) { + return nil, toErr(ctx, err) } } } @@ -96,38 +88,36 @@ func (m *maintenance) AlarmDisarm(ctx context.Context, am *AlarmMember) (*AlarmR if req.MemberID == 0 && req.Alarm == pb.AlarmType_NONE { ar, err := m.AlarmList(ctx) if err != nil { - return nil, err + return nil, toErr(ctx, err) } ret := AlarmResponse{} for _, am := range ar.Alarms { dresp, derr := m.AlarmDisarm(ctx, (*AlarmMember)(am)) if derr != nil { - return nil, derr + return nil, toErr(ctx, derr) } ret.Alarms = append(ret.Alarms, dresp.Alarms...) } return &ret, nil } - resp, err := m.getRemote().Alarm(ctx, req) + resp, err := m.remote.Alarm(ctx, req, grpc.FailFast(false)) if err == nil { return (*AlarmResponse)(resp), nil } - if !isHalted(ctx, err) { - go m.switchRemote(err) - } - return nil, err + return nil, toErr(ctx, err) } func (m *maintenance) Defragment(ctx context.Context, endpoint string) (*DefragmentResponse, error) { conn, err := m.c.Dial(endpoint) if err != nil { - return nil, err + return nil, toErr(ctx, err) } + defer conn.Close() remote := pb.NewMaintenanceClient(conn) - resp, err := remote.Defragment(ctx, &pb.DefragmentRequest{}) + resp, err := remote.Defragment(ctx, &pb.DefragmentRequest{}, grpc.FailFast(false)) if err != nil { - return nil, err + return nil, toErr(ctx, err) } return (*DefragmentResponse)(resp), nil } @@ -135,30 +125,40 @@ func (m *maintenance) Defragment(ctx context.Context, endpoint string) (*Defragm func (m *maintenance) Status(ctx context.Context, endpoint string) (*StatusResponse, error) { conn, err := m.c.Dial(endpoint) if err != nil { - return nil, err + return nil, toErr(ctx, err) } + defer conn.Close() remote := pb.NewMaintenanceClient(conn) - resp, err := remote.Status(ctx, &pb.StatusRequest{}) + resp, err := remote.Status(ctx, &pb.StatusRequest{}, grpc.FailFast(false)) if err != nil { - return nil, err + return nil, toErr(ctx, err) } return (*StatusResponse)(resp), nil } -func (m *maintenance) getRemote() pb.MaintenanceClient { - m.mu.Lock() - defer m.mu.Unlock() - return m.remote -} - -func (m *maintenance) switchRemote(prevErr error) error { - m.mu.Lock() - defer m.mu.Unlock() - newConn, err := m.c.retryConnection(m.conn, prevErr) +func (m *maintenance) Snapshot(ctx context.Context) (io.ReadCloser, error) { + ss, err := m.remote.Snapshot(ctx, &pb.SnapshotRequest{}, grpc.FailFast(false)) if err != nil { - return err + return nil, toErr(ctx, err) } - m.conn = newConn - m.remote = pb.NewMaintenanceClient(m.conn) - return nil + + pr, pw := io.Pipe() + go func() { + for { + resp, err := ss.Recv() + if err != nil { + pw.CloseWithError(err) + return + } + if resp == nil && err == nil { + break + } + if _, werr := pw.Write(resp.Blob); werr != nil { + pw.CloseWithError(werr) + return + } + } + pw.Close() + }() + return pr, nil } diff --git a/vendor/github.com/coreos/etcd/clientv3/op.go b/vendor/github.com/coreos/etcd/clientv3/op.go index fb29f47c02e..89698be2341 100644 --- a/vendor/github.com/coreos/etcd/clientv3/op.go +++ b/vendor/github.com/coreos/etcd/clientv3/op.go @@ -1,4 +1,4 @@ -// Copyright 2016 CoreOS, Inc. +// 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. @@ -41,6 +41,8 @@ type Op struct { limit int64 sort *SortOption serializable bool + keysOnly bool + countOnly bool // for range, watch rev int64 @@ -53,21 +55,29 @@ type Op struct { leaseID LeaseID } -func (op Op) toRequestUnion() *pb.RequestUnion { +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} + 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.RequestUnion{Request: &pb.RequestUnion_RequestRange{RequestRange: r}} + return &pb.RequestOp{Request: &pb.RequestOp_RequestRange{RequestRange: r}} case tPut: r := &pb.PutRequest{Key: op.key, Value: op.val, Lease: int64(op.leaseID)} - return &pb.RequestUnion{Request: &pb.RequestUnion_RequestPut{RequestPut: r}} + return &pb.RequestOp{Request: &pb.RequestOp_RequestPut{RequestPut: r}} case tDeleteRange: r := &pb.DeleteRangeRequest{Key: op.key, RangeEnd: op.end} - return &pb.RequestUnion{Request: &pb.RequestUnion_RequestDeleteRange{RequestDeleteRange: r}} + return &pb.RequestOp{Request: &pb.RequestOp_RequestDeleteRange{RequestDeleteRange: r}} default: panic("Unknown Op") } @@ -97,6 +107,8 @@ func OpDelete(key string, opts ...OpOption) Op { panic("unexpected sort in delete") case ret.serializable: panic("unexpected serializable in delete") + case ret.countOnly: + panic("unexpected countOnly in delete") } return ret } @@ -114,7 +126,9 @@ func OpPut(key, val string, opts ...OpOption) Op { case ret.sort != nil: panic("unexpected sort in put") case ret.serializable: - panic("unexpected serializable in delete") + panic("unexpected serializable in put") + case ret.countOnly: + panic("unexpected countOnly in delete") } return ret } @@ -131,6 +145,8 @@ func opWatch(key string, opts ...OpOption) Op { panic("unexpected sort in watch") case ret.serializable: panic("unexpected serializable in watch") + case ret.countOnly: + panic("unexpected countOnly in delete") } return ret } @@ -166,6 +182,12 @@ func WithSort(target SortTarget, order SortOrder) OpOption { } } +// GetPrefixRangeEnd gets the range end of the prefix. +// 'Get(foo, WithPrefix())' is equal to 'Get(foo, WithRange(GetPrefixRangeEnd(foo))'. +func GetPrefixRangeEnd(prefix string) string { + return string(getPrefix([]byte(prefix))) +} + func getPrefix(key []byte) []byte { end := make([]byte, len(key)) copy(end, key) @@ -198,7 +220,7 @@ func WithRange(endKey string) OpOption { } // WithFromKey specifies the range of 'Get' or 'Delete' requests -// to be equal or greater than they key in the argument. +// to be equal or greater than the key in the argument. func WithFromKey() OpOption { return WithRange("\x00") } // WithSerializable makes 'Get' request serializable. By default, @@ -208,6 +230,17 @@ func WithSerializable() OpOption { return func(op *Op) { op.serializable = true } } +// WithKeysOnly makes the 'Get' request return only the keys and the corresponding +// values will be omitted. +func WithKeysOnly() OpOption { + return func(op *Op) { op.keysOnly = true } +} + +// WithCountOnly makes the 'Get' request return only the count of keys. +func WithCountOnly() OpOption { + return func(op *Op) { op.countOnly = true } +} + // WithFirstCreate gets the key with the oldest creation revision in the request range. func WithFirstCreate() []OpOption { return withTop(SortByCreateRevision, SortAscend) } diff --git a/vendor/github.com/coreos/etcd/clientv3/sort.go b/vendor/github.com/coreos/etcd/clientv3/sort.go index 06a23be7bb2..2bb9d9a13b7 100644 --- a/vendor/github.com/coreos/etcd/clientv3/sort.go +++ b/vendor/github.com/coreos/etcd/clientv3/sort.go @@ -1,4 +1,4 @@ -// Copyright 2016 CoreOS, Inc. +// 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. diff --git a/vendor/github.com/coreos/etcd/clientv3/txn.go b/vendor/github.com/coreos/etcd/clientv3/txn.go index f664ee63996..a76bd174c2e 100644 --- a/vendor/github.com/coreos/etcd/clientv3/txn.go +++ b/vendor/github.com/coreos/etcd/clientv3/txn.go @@ -1,4 +1,4 @@ -// Copyright 2016 CoreOS, Inc. +// 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. @@ -19,17 +19,20 @@ 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. +// +// Tx.If( +// Compare(Value(k1), ">", v1), +// Compare(Version(k1), "=", 2) +// ).Then( +// OpPut(k2,v2), OpPut(k3,v3) +// ).Else( +// OpPut(k4,v4), OpPut(k5,v5) +// ).Commit() // -// Tx.If( -// Compare(Value(k1), ">", v1), -// Compare(Version(k1), "=", 2) -// ).Then( -// OpPut(k2,v2), OpPut(k3,v3) -// ).Else( -// OpPut(k4,v4), OpPut(k5,v5) -// ).Commit() type Txn interface { // If takes a list of comparison. If all comparisons passed in succeed, // the operations passed into Then() will be executed. Or the operations @@ -63,8 +66,8 @@ type txn struct { cmps []*pb.Compare - sus []*pb.RequestUnion - fas []*pb.RequestUnion + sus []*pb.RequestOp + fas []*pb.RequestOp } func (txn *txn) If(cs ...Cmp) Txn { @@ -107,7 +110,7 @@ func (txn *txn) Then(ops ...Op) Txn { for _, op := range ops { txn.isWrite = txn.isWrite || op.isWrite() - txn.sus = append(txn.sus, op.toRequestUnion()) + txn.sus = append(txn.sus, op.toRequestOp()) } return txn @@ -125,7 +128,7 @@ func (txn *txn) Else(ops ...Op) Txn { for _, op := range ops { txn.isWrite = txn.isWrite || op.isWrite() - txn.fas = append(txn.fas, op.toRequestUnion()) + txn.fas = append(txn.fas, op.toRequestOp()) } return txn @@ -134,27 +137,25 @@ func (txn *txn) Else(ops ...Op) Txn { func (txn *txn) Commit() (*TxnResponse, error) { txn.mu.Lock() defer txn.mu.Unlock() - - kv := txn.kv - for { - r := &pb.TxnRequest{Compare: txn.cmps, Success: txn.sus, Failure: txn.fas} - resp, err := kv.getRemote().Txn(txn.ctx, r) + resp, err := txn.commit() if err == nil { - return (*TxnResponse)(resp), nil + return resp, err } - - if isHalted(txn.ctx, err) { - return nil, err + if isHaltErr(txn.ctx, err) { + return nil, toErr(txn.ctx, err) } - if txn.isWrite { - go kv.switchRemote(err) - return nil, err - } - - if nerr := kv.switchRemote(err); nerr != nil { - return nil, nerr + return nil, toErr(txn.ctx, err) } } } + +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, grpc.FailFast(false)) + if err != nil { + return nil, err + } + return (*TxnResponse)(resp), nil +} diff --git a/vendor/github.com/coreos/etcd/clientv3/watch.go b/vendor/github.com/coreos/etcd/clientv3/watch.go index f9bdaff547b..aa2e6c351b0 100644 --- a/vendor/github.com/coreos/etcd/clientv3/watch.go +++ b/vendor/github.com/coreos/etcd/clientv3/watch.go @@ -1,4 +1,4 @@ -// Copyright 2016 CoreOS, Inc. +// 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. @@ -17,20 +17,23 @@ package clientv3 import ( "fmt" "sync" + "time" v3rpc "github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes" pb "github.com/coreos/etcd/etcdserver/etcdserverpb" - storagepb "github.com/coreos/etcd/storage/storagepb" + mvccpb "github.com/coreos/etcd/mvcc/mvccpb" "golang.org/x/net/context" "google.golang.org/grpc" ) const ( - EventTypeDelete = storagepb.DELETE - EventTypePut = storagepb.PUT + EventTypeDelete = mvccpb.DELETE + EventTypePut = mvccpb.PUT + + closeSendErrTimeout = 250 * time.Millisecond ) -type Event storagepb.Event +type Event mvccpb.Event type WatchChan <-chan WatchResponse @@ -39,7 +42,7 @@ type Watcher interface { // through the returned channel. // If the watch is slow or the required rev is compacted, the watch request // might be canceled from the server-side and the chan will be closed. - // 'opts' can be: 'WithRev' and/or 'WitchPrefix'. + // 'opts' can be: 'WithRev' and/or 'WithPrefix'. Watch(ctx context.Context, key string, opts ...OpOption) WatchChan // Close closes the watcher and cancels all watch requests. @@ -57,6 +60,8 @@ type WatchResponse struct { // If the watch failed and the stream was about to close, before the channel is closed, // the channel sends a final response that has Canceled set to true with a non-nil Err(). Canceled bool + + closeErr error } // IsCreate returns true if the event tells that the key is newly created. @@ -71,10 +76,12 @@ func (e *Event) IsModify() bool { // Err is the error value if this WatchResponse holds an error. func (wr *WatchResponse) Err() error { - if wr.CompactRevision != 0 { + switch { + case wr.closeErr != nil: + return v3rpc.Error(wr.closeErr) + case wr.CompactRevision != 0: return v3rpc.ErrCompacted - } - if wr.Canceled { + case wr.Canceled: return v3rpc.ErrFutureRev } return nil @@ -87,18 +94,28 @@ func (wr *WatchResponse) IsProgressNotify() bool { // watcher implements the Watcher interface type watcher struct { - c *Client - conn *grpc.ClientConn + remote pb.WatchClient + + // mu protects the grpc streams map + mu sync.RWMutex + // streams holds all the active grpc streams keyed by ctx value. + streams map[string]*watchGrpcStream +} + +type watchGrpcStream struct { + owner *watcher remote pb.WatchClient // ctx controls internal remote.Watch requests - ctx context.Context + ctx context.Context + // ctxKey is the key used when looking up this stream's context + ctxKey string cancel context.CancelFunc - // streams holds all active watchers - streams map[int64]*watcherStream // mu protects the streams map mu sync.RWMutex + // streams holds all active watchers + streams map[int64]*watcherStream // reqc sends a watch request from Watch() to the main goroutine reqc chan *watchRequest @@ -108,8 +125,11 @@ type watcher struct { stopc chan struct{} // donec closes to broadcast shutdown donec chan struct{} - // errc transmits errors from grpc Recv + // errc transmits errors from grpc Recv to the watch stream reconn logic errc chan error + + // the error that closed the watch stream + closeErr error } // watchRequest is issued by the subscriber to start a new watcher @@ -126,6 +146,7 @@ type watchRequest struct { // watcherStream represents a registered watcher type watcherStream struct { + // initReq is the request that initiated this request initReq watchRequest // outc publishes watch responses to subscriber @@ -141,15 +162,30 @@ type watcherStream struct { } func NewWatcher(c *Client) Watcher { - ctx, cancel := context.WithCancel(context.Background()) - conn := c.ActiveConnection() + return &watcher{ + remote: pb.NewWatchClient(c.conn), + streams: make(map[string]*watchGrpcStream), + } +} - w := &watcher{ - c: c, - conn: conn, - remote: pb.NewWatchClient(conn), +// never closes +var valCtxCh = make(chan struct{}) +var zeroTime = time.Unix(0, 0) +// ctx with only the values; never Done +type valCtx struct{ context.Context } + +func (vc *valCtx) Deadline() (time.Time, bool) { return zeroTime, false } +func (vc *valCtx) Done() <-chan struct{} { return valCtxCh } +func (vc *valCtx) Err() error { return nil } + +func (w *watcher) newWatcherGrpcStream(inctx context.Context) *watchGrpcStream { + ctx, cancel := context.WithCancel(&valCtx{inctx}) + wgs := &watchGrpcStream{ + owner: w, + remote: w.remote, ctx: ctx, + ctxKey: fmt.Sprintf("%v", inctx), cancel: cancel, streams: make(map[int64]*watcherStream), @@ -159,8 +195,8 @@ func NewWatcher(c *Client) Watcher { donec: make(chan struct{}), errc: make(chan error, 1), } - go w.run() - return w + go wgs.run() + return wgs } // Watch posts a watch request to run() and waits for a new watcher channel @@ -178,13 +214,41 @@ func (w *watcher) Watch(ctx context.Context, key string, opts ...OpOption) Watch } ok := false + ctxKey := fmt.Sprintf("%v", ctx) + + // find or allocate appropriate grpc watch stream + w.mu.Lock() + if w.streams == nil { + // closed + w.mu.Unlock() + ch := make(chan WatchResponse) + close(ch) + return ch + } + wgs := w.streams[ctxKey] + if wgs == nil { + wgs = w.newWatcherGrpcStream(ctx) + w.streams[ctxKey] = wgs + } + donec := wgs.donec + reqc := wgs.reqc + w.mu.Unlock() + + // couldn't create channel; return closed channel + closeCh := make(chan WatchResponse, 1) // submit request select { - case w.reqc <- wr: + case reqc <- wr: ok = true case <-wr.ctx.Done(): - case <-w.donec: + case <-donec: + if wgs.closeErr != nil { + closeCh <- WatchResponse{closeErr: wgs.closeErr} + break + } + // retry; may have dropped stream from no ctxs + return w.Watch(ctx, key, opts...) } // receive channel @@ -193,26 +257,44 @@ func (w *watcher) Watch(ctx context.Context, key string, opts ...OpOption) Watch case ret := <-retc: return ret case <-ctx.Done(): - case <-w.donec: + case <-donec: + if wgs.closeErr != nil { + closeCh <- WatchResponse{closeErr: wgs.closeErr} + break + } + // retry; may have dropped stream from no ctxs + return w.Watch(ctx, key, opts...) } } - // couldn't create channel; return closed channel - ch := make(chan WatchResponse) - close(ch) - return ch + close(closeCh) + return closeCh } -func (w *watcher) Close() error { - select { - case w.stopc <- struct{}{}: - case <-w.donec: +func (w *watcher) Close() (err error) { + w.mu.Lock() + streams := w.streams + w.streams = nil + w.mu.Unlock() + for _, wgs := range streams { + if werr := wgs.Close(); werr != nil { + err = werr + } } - <-w.donec - return <-w.errc + return err } -func (w *watcher) addStream(resp *pb.WatchResponse, pendingReq *watchRequest) { +func (w *watchGrpcStream) Close() (err error) { + close(w.stopc) + <-w.donec + select { + case err = <-w.errc: + default: + } + return toErr(w.ctx, err) +} + +func (w *watchGrpcStream) addStream(resp *pb.WatchResponse, pendingReq *watchRequest) { if pendingReq == nil { // no pending request; ignore return @@ -265,27 +347,32 @@ func (w *watcher) addStream(resp *pb.WatchResponse, pendingReq *watchRequest) { } // closeStream closes the watcher resources and removes it -func (w *watcher) closeStream(ws *watcherStream) { +func (w *watchGrpcStream) closeStream(ws *watcherStream) { // cancels request stream; subscriber receives nil channel close(ws.initReq.retc) // close subscriber's channel close(ws.outc) - // shutdown serveStream - close(ws.recvc) delete(w.streams, ws.id) } // run is the root of the goroutines for managing a watcher client -func (w *watcher) run() { +func (w *watchGrpcStream) run() { + var wc pb.Watch_WatchClient + var closeErr error + defer func() { + w.owner.mu.Lock() + w.closeErr = closeErr + if w.owner.streams != nil { + delete(w.owner.streams, w.ctxKey) + } close(w.donec) + w.owner.mu.Unlock() w.cancel() }() // start a stream with the etcd grpc server - wc, wcerr := w.newWatchClient() - if wcerr != nil { - w.errc <- wcerr + if wc, closeErr = w.newWatchClient(); closeErr != nil { return } @@ -314,6 +401,18 @@ func (w *watcher) run() { curReqC = w.reqc case pbresp.Canceled: delete(cancelSet, pbresp.WatchId) + // shutdown serveStream, if any + w.mu.Lock() + if ws, ok := w.streams[pbresp.WatchId]; ok { + close(ws.recvc) + delete(w.streams, ws.id) + } + numStreams := len(w.streams) + w.mu.Unlock() + if numStreams == 0 { + // don't leak watcher streams + return + } default: // dispatch to appropriate watch stream if ok := w.dispatchEvent(pbresp); ok { @@ -334,9 +433,12 @@ func (w *watcher) run() { } // watch client failed to recv; spawn another if possible // TODO report watch client errors from errc? - case <-w.errc: - if wc, wcerr = w.newWatchClient(); wcerr != nil { - w.errc <- wcerr + case err := <-w.errc: + if toErr(w.ctx, err) == v3rpc.ErrNoLeader { + closeErr = err + return + } + if wc, closeErr = w.newWatchClient(); closeErr != nil { return } curReqC = w.reqc @@ -345,7 +447,6 @@ func (w *watcher) run() { } cancelSet = make(map[int64]struct{}) case <-w.stopc: - w.errc <- nil return } @@ -365,7 +466,7 @@ func (w *watcher) run() { } // dispatchEvent sends a WatchResponse to the appropriate watcher stream -func (w *watcher) dispatchEvent(pbresp *pb.WatchResponse) bool { +func (w *watchGrpcStream) dispatchEvent(pbresp *pb.WatchResponse) bool { w.mu.RLock() defer w.mu.RUnlock() ws, ok := w.streams[pbresp.WatchId] @@ -385,7 +486,7 @@ func (w *watcher) dispatchEvent(pbresp *pb.WatchResponse) bool { } // serveWatchClient forwards messages from the grpc stream to run() -func (w *watcher) serveWatchClient(wc pb.Watch_WatchClient) { +func (w *watchGrpcStream) serveWatchClient(wc pb.Watch_WatchClient) { for { resp, err := wc.Recv() if err != nil { @@ -404,7 +505,8 @@ func (w *watcher) serveWatchClient(wc pb.Watch_WatchClient) { } // serveStream forwards watch responses from run() to the subscriber -func (w *watcher) serveStream(ws *watcherStream) { +func (w *watchGrpcStream) serveStream(ws *watcherStream) { + var closeErr error emptyWr := &WatchResponse{} wrs := []*WatchResponse{} resuming := false @@ -440,7 +542,7 @@ func (w *watcher) serveStream(ws *watcherStream) { return } // resume up to last seen event if disconnected - if resuming { + if resuming && wr.Err() == nil { resuming = false // trim events already seen for i := 0; i < len(wr.Events); i++ { @@ -454,6 +556,7 @@ func (w *watcher) serveStream(ws *watcherStream) { break } } + resuming = false // TODO don't keep buffering if subscriber stops reading wrs = append(wrs, wr) case resumeRev := <-ws.resumec: @@ -468,17 +571,28 @@ func (w *watcher) serveStream(ws *watcherStream) { } case <-w.donec: closing = true + closeErr = w.closeErr case <-ws.initReq.ctx.Done(): closing = true } } + + // try to send off close error + if closeErr != nil { + select { + case ws.outc <- WatchResponse{closeErr: w.closeErr}: + case <-w.donec: + case <-time.After(closeSendErrTimeout): + } + } + w.mu.Lock() w.closeStream(ws) w.mu.Unlock() // lazily send cancel message if events on missing id } -func (w *watcher) newWatchClient() (pb.Watch_WatchClient, error) { +func (w *watchGrpcStream) newWatchClient() (pb.Watch_WatchClient, error) { ws, rerr := w.resume() if rerr != nil { return nil, rerr @@ -488,7 +602,7 @@ func (w *watcher) newWatchClient() (pb.Watch_WatchClient, error) { } // resume creates a new WatchClient with all current watchers reestablished -func (w *watcher) resume() (ws pb.Watch_WatchClient, err error) { +func (w *watchGrpcStream) resume() (ws pb.Watch_WatchClient, err error) { for { if ws, err = w.openWatchClient(); err != nil { break @@ -496,31 +610,34 @@ func (w *watcher) resume() (ws pb.Watch_WatchClient, err error) { break } } - return ws, err + return ws, v3rpc.Error(err) } // openWatchClient retries opening a watchclient until retryConnection fails -func (w *watcher) openWatchClient() (ws pb.Watch_WatchClient, err error) { +func (w *watchGrpcStream) openWatchClient() (ws pb.Watch_WatchClient, err error) { for { - if ws, err = w.remote.Watch(w.ctx); ws != nil { - break - } else if isHalted(w.ctx, err) { + select { + case <-w.stopc: + if err == nil { + err = context.Canceled + } return nil, err + default: } - newConn, nerr := w.c.retryConnection(w.conn, nil) - if nerr != nil { - return nil, nerr + if ws, err = w.remote.Watch(w.ctx, grpc.FailFast(false)); ws != nil && err == nil { + break + } + if isHaltErr(w.ctx, err) { + return nil, v3rpc.Error(err) } - w.conn = newConn - w.remote = pb.NewWatchClient(w.conn) } return ws, nil } // resumeWatchers rebuilds every registered watcher on a new client -func (w *watcher) resumeWatchers(wc pb.Watch_WatchClient) error { - streams := []*watcherStream{} +func (w *watchGrpcStream) resumeWatchers(wc pb.Watch_WatchClient) error { w.mu.RLock() + streams := make([]*watcherStream, 0, len(w.streams)) for _, ws := range w.streams { streams = append(streams, ws) } diff --git a/vendor/github.com/coreos/etcd/compactor/compactor.go b/vendor/github.com/coreos/etcd/compactor/compactor.go index 7519b5379d4..ad9be6e3112 100644 --- a/vendor/github.com/coreos/etcd/compactor/compactor.go +++ b/vendor/github.com/coreos/etcd/compactor/compactor.go @@ -1,4 +1,4 @@ -// Copyright 2016 CoreOS, Inc. +// 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. @@ -19,7 +19,7 @@ import ( "time" pb "github.com/coreos/etcd/etcdserver/etcdserverpb" - "github.com/coreos/etcd/storage" + "github.com/coreos/etcd/mvcc" "github.com/coreos/pkg/capnslog" "github.com/jonboulle/clockwork" "golang.org/x/net/context" @@ -96,7 +96,7 @@ func (t *Periodic) Run() { plog.Noticef("Starting auto-compaction at revision %d", rev) _, err := t.c.Compact(t.ctx, &pb.CompactionRequest{Revision: rev}) - if err == nil || err == storage.ErrCompacted { + if err == nil || err == mvcc.ErrCompacted { t.revs = make([]int64, 0) last = clock.Now() plog.Noticef("Finished auto-compaction at revision %d", rev) diff --git a/vendor/github.com/coreos/etcd/compactor/doc.go b/vendor/github.com/coreos/etcd/compactor/doc.go new file mode 100644 index 00000000000..cb158340e49 --- /dev/null +++ b/vendor/github.com/coreos/etcd/compactor/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 compactor implements automated policies for compacting etcd's mvcc storage. +package compactor diff --git a/vendor/github.com/coreos/etcd/discovery/discovery.go b/vendor/github.com/coreos/etcd/discovery/discovery.go index 1cd4ee4da2a..d53c461143f 100644 --- a/vendor/github.com/coreos/etcd/discovery/discovery.go +++ b/vendor/github.com/coreos/etcd/discovery/discovery.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. @@ -20,7 +20,6 @@ import ( "errors" "fmt" "math" - "net" "net/http" "net/url" "path" @@ -30,6 +29,7 @@ import ( "time" "github.com/coreos/etcd/client" + "github.com/coreos/etcd/pkg/transport" "github.com/coreos/etcd/pkg/types" "github.com/coreos/pkg/capnslog" "github.com/jonboulle/clockwork" @@ -124,16 +124,15 @@ func newDiscovery(durl, dproxyurl string, id types.ID) (*discovery, error) { if err != nil { return nil, err } + + // TODO: add ResponseHeaderTimeout back when watch on discovery service writes header early + tr, err := transport.NewTransport(transport.TLSInfo{}, 30*time.Second) + if err != nil { + return nil, err + } + tr.Proxy = pf cfg := client.Config{ - Transport: &http.Transport{ - Proxy: pf, - Dial: (&net.Dialer{ - Timeout: 30 * time.Second, - KeepAlive: 30 * time.Second, - }).Dial, - TLSHandshakeTimeout: 10 * time.Second, - // TODO: add ResponseHeaderTimeout back when watch on discovery service writes header early - }, + Transport: tr, Endpoints: []string{u.String()}, } c, err := client.New(cfg) diff --git a/vendor/github.com/coreos/etcd/discovery/srv.go b/vendor/github.com/coreos/etcd/discovery/srv.go index ed67a41ffb0..4dab356693e 100644 --- a/vendor/github.com/coreos/etcd/discovery/srv.go +++ b/vendor/github.com/coreos/etcd/discovery/srv.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. diff --git a/vendor/github.com/coreos/etcd/error/error.go b/vendor/github.com/coreos/etcd/error/error.go index c5cf8ffb482..8cf83cc716a 100644 --- a/vendor/github.com/coreos/etcd/error/error.go +++ b/vendor/github.com/coreos/etcd/error/error.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. @@ -13,7 +13,7 @@ // limitations under the License. // Package error describes errors in etcd project. When any change happens, -// Documentation/errorcode.md needs to be updated correspondingly. +// Documentation/v2/errorcode.md needs to be updated correspondingly. package error import ( diff --git a/vendor/github.com/coreos/etcd/etcdserver/api/capability.go b/vendor/github.com/coreos/etcd/etcdserver/api/capability.go new file mode 100644 index 00000000000..768111eafc6 --- /dev/null +++ b/vendor/github.com/coreos/etcd/etcdserver/api/capability.go @@ -0,0 +1,85 @@ +// Copyright 2015 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 api + +import ( + "sync" + + "github.com/coreos/etcd/version" + "github.com/coreos/go-semver/semver" + "github.com/coreos/pkg/capnslog" +) + +type Capability string + +const ( + AuthCapability Capability = "auth" + V3rpcCapability Capability = "v3rpc" +) + +var ( + plog = capnslog.NewPackageLogger("github.com/coreos/etcd/etcdserver", "api") + + // capabilityMaps is a static map of version to capability map. + // the base capabilities is the set of capability 2.0 supports. + capabilityMaps = map[string]map[Capability]bool{ + "2.1.0": {AuthCapability: true}, + "2.2.0": {AuthCapability: true}, + "2.3.0": {AuthCapability: true}, + "3.0.0": {AuthCapability: true, V3rpcCapability: true}, + } + + enableMapMu sync.RWMutex + // enabledMap points to a map in capabilityMaps + enabledMap map[Capability]bool + + curVersion *semver.Version +) + +func init() { + enabledMap = make(map[Capability]bool) +} + +// UpdateCapability updates the enabledMap when the cluster version increases. +func UpdateCapability(v *semver.Version) { + if v == nil { + // if recovered but version was never set by cluster + return + } + enableMapMu.Lock() + if curVersion != nil && !curVersion.LessThan(*v) { + enableMapMu.Unlock() + return + } + curVersion = v + enabledMap = capabilityMaps[curVersion.String()] + enableMapMu.Unlock() + plog.Infof("enabled capabilities for version %s", version.Cluster(v.String())) +} + +func IsCapabilityEnabled(c Capability) bool { + enableMapMu.RLock() + defer enableMapMu.RUnlock() + if enabledMap == nil { + return false + } + return enabledMap[c] +} + +func EnableCapability(c Capability) { + enableMapMu.Lock() + defer enableMapMu.Unlock() + enabledMap[c] = true +} diff --git a/vendor/github.com/coreos/etcd/etcdserver/api/cluster.go b/vendor/github.com/coreos/etcd/etcdserver/api/cluster.go index c21eccba316..87face4a139 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/api/cluster.go +++ b/vendor/github.com/coreos/etcd/etcdserver/api/cluster.go @@ -1,4 +1,4 @@ -// Copyright 2016 CoreOS, Inc. +// 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. diff --git a/vendor/github.com/coreos/etcd/etcdserver/api/doc.go b/vendor/github.com/coreos/etcd/etcdserver/api/doc.go new file mode 100644 index 00000000000..f44881be663 --- /dev/null +++ b/vendor/github.com/coreos/etcd/etcdserver/api/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 api manages the capabilities and features that are exposed to clients by the etcd cluster. +package api diff --git a/vendor/github.com/coreos/etcd/etcdserver/api/v2http/capability.go b/vendor/github.com/coreos/etcd/etcdserver/api/v2http/capability.go index 40477cac09a..fa0bcca5e84 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/api/v2http/capability.go +++ b/vendor/github.com/coreos/etcd/etcdserver/api/v2http/capability.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. @@ -17,75 +17,14 @@ package v2http import ( "fmt" "net/http" - "sync" - "time" - "github.com/coreos/etcd/etcdserver" + "github.com/coreos/etcd/etcdserver/api" "github.com/coreos/etcd/etcdserver/api/v2http/httptypes" - "github.com/coreos/go-semver/semver" ) -type capability string - -const ( - authCapability capability = "auth" -) - -var ( - // capabilityMaps is a static map of version to capability map. - // the base capabilities is the set of capability 2.0 supports. - capabilityMaps = map[string]map[capability]bool{ - "2.1.0": {authCapability: true}, - "2.2.0": {authCapability: true}, - "2.3.0": {authCapability: true}, - } - - enableMapMu sync.Mutex - // enabledMap points to a map in capabilityMaps - enabledMap map[capability]bool -) - -// capabilityLoop checks the cluster version every 500ms and updates -// the enabledMap when the cluster version increased. -// capabilityLoop MUST be ran in a goroutine before checking capability -// or using capabilityHandler. -func capabilityLoop(s *etcdserver.EtcdServer) { - stopped := s.StopNotify() - - var pv *semver.Version - for { - if v := s.ClusterVersion(); v != pv { - if pv == nil { - pv = v - } else if v != nil && pv.LessThan(*v) { - pv = v - } - enableMapMu.Lock() - enabledMap = capabilityMaps[pv.String()] - enableMapMu.Unlock() - plog.Infof("enabled capabilities for version %s", pv) - } - - select { - case <-stopped: - return - case <-time.After(500 * time.Millisecond): - } - } -} - -func isCapabilityEnabled(c capability) bool { - enableMapMu.Lock() - defer enableMapMu.Unlock() - if enabledMap == nil { - return false - } - return enabledMap[c] -} - -func capabilityHandler(c capability, fn func(http.ResponseWriter, *http.Request)) http.HandlerFunc { +func capabilityHandler(c api.Capability, fn func(http.ResponseWriter, *http.Request)) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { - if !isCapabilityEnabled(c) { + if !api.IsCapabilityEnabled(c) { notCapable(w, r, c) return } @@ -93,7 +32,7 @@ func capabilityHandler(c capability, fn func(http.ResponseWriter, *http.Request) } } -func notCapable(w http.ResponseWriter, r *http.Request, c capability) { +func notCapable(w http.ResponseWriter, r *http.Request, c api.Capability) { herr := httptypes.NewHTTPError(http.StatusInternalServerError, fmt.Sprintf("Not capable of accessing %s feature during rolling upgrades.", c)) if err := herr.WriteTo(w); err != nil { plog.Debugf("error writing HTTPError (%v) to %s", err, r.RemoteAddr) diff --git a/vendor/github.com/coreos/etcd/etcdserver/api/v2http/client.go b/vendor/github.com/coreos/etcd/etcdserver/api/v2http/client.go index 9f6e3b5e4de..68be8082203 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/api/v2http/client.go +++ b/vendor/github.com/coreos/etcd/etcdserver/api/v2http/client.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. @@ -62,16 +62,15 @@ const ( // NewClientHandler generates a muxed http.Handler with the given parameters to serve etcd client requests. func NewClientHandler(server *etcdserver.EtcdServer, timeout time.Duration) http.Handler { - go capabilityLoop(server) - sec := auth.NewStore(server, timeout) kh := &keysHandler{ - sec: sec, - server: server, - cluster: server.Cluster(), - timer: server, - timeout: timeout, + sec: sec, + server: server, + cluster: server.Cluster(), + timer: server, + timeout: timeout, + clientCertAuthEnabled: server.Cfg.ClientCertAuthEnabled, } sh := &statsHandler{ @@ -84,6 +83,7 @@ func NewClientHandler(server *etcdserver.EtcdServer, timeout time.Duration) http cluster: server.Cluster(), timeout: timeout, clock: clockwork.NewRealClock(), + clientCertAuthEnabled: server.Cfg.ClientCertAuthEnabled, } dmh := &deprecatedMachinesHandler{ @@ -91,8 +91,9 @@ func NewClientHandler(server *etcdserver.EtcdServer, timeout time.Duration) http } sech := &authHandler{ - sec: sec, - cluster: server.Cluster(), + sec: sec, + cluster: server.Cluster(), + clientCertAuthEnabled: server.Cfg.ClientCertAuthEnabled, } mux := http.NewServeMux() @@ -133,11 +134,12 @@ func NewClientHandler(server *etcdserver.EtcdServer, timeout time.Duration) http } type keysHandler struct { - sec auth.Store - server etcdserver.Server - cluster api.Cluster - timer etcdserver.RaftTimer - timeout time.Duration + sec auth.Store + server etcdserver.Server + cluster api.Cluster + timer etcdserver.RaftTimer + timeout time.Duration + clientCertAuthEnabled bool } func (h *keysHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { @@ -157,7 +159,7 @@ func (h *keysHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { return } // The path must be valid at this point (we've parsed the request successfully). - if !hasKeyPrefixAccess(h.sec, r, r.URL.Path[len(keysPrefix):], rr.Recursive) { + if !hasKeyPrefixAccess(h.sec, r, r.URL.Path[len(keysPrefix):], rr.Recursive, h.clientCertAuthEnabled) { writeKeyNoAuth(w) return } @@ -200,18 +202,19 @@ func (h *deprecatedMachinesHandler) ServeHTTP(w http.ResponseWriter, r *http.Req } type membersHandler struct { - sec auth.Store - server etcdserver.Server - cluster api.Cluster - timeout time.Duration - clock clockwork.Clock + sec auth.Store + server etcdserver.Server + cluster api.Cluster + timeout time.Duration + clock clockwork.Clock + clientCertAuthEnabled bool } func (h *membersHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { if !allowMethod(w, r.Method, "GET", "POST", "DELETE", "PUT") { return } - if !hasWriteRootAccess(h.sec, r) { + if !hasWriteRootAccess(h.sec, r, h.clientCertAuthEnabled) { writeNoAuth(w, r) return } @@ -720,20 +723,19 @@ func trimEventPrefix(ev *store.Event, prefix string) *store.Event { // Since the *Event may reference one in the store history // history, we must copy it before modifying e := ev.Clone() - e.Node = trimNodeExternPrefix(e.Node, prefix) - e.PrevNode = trimNodeExternPrefix(e.PrevNode, prefix) + trimNodeExternPrefix(e.Node, prefix) + trimNodeExternPrefix(e.PrevNode, prefix) return e } -func trimNodeExternPrefix(n *store.NodeExtern, prefix string) *store.NodeExtern { +func trimNodeExternPrefix(n *store.NodeExtern, prefix string) { if n == nil { - return nil + return } n.Key = strings.TrimPrefix(n.Key, prefix) for _, nn := range n.Nodes { - nn = trimNodeExternPrefix(nn, prefix) + trimNodeExternPrefix(nn, prefix) } - return n } func trimErrorPrefix(err error, prefix string) error { diff --git a/vendor/github.com/coreos/etcd/etcdserver/api/v2http/client_auth.go b/vendor/github.com/coreos/etcd/etcdserver/api/v2http/client_auth.go index 83706f04fe9..2b3278528f1 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/api/v2http/client_auth.go +++ b/vendor/github.com/coreos/etcd/etcdserver/api/v2http/client_auth.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. @@ -26,18 +26,56 @@ import ( ) type authHandler struct { - sec auth.Store - cluster api.Cluster + sec auth.Store + cluster api.Cluster + clientCertAuthEnabled bool } -func hasWriteRootAccess(sec auth.Store, r *http.Request) bool { +func hasWriteRootAccess(sec auth.Store, r *http.Request, clientCertAuthEnabled bool) bool { if r.Method == "GET" || r.Method == "HEAD" { return true } - return hasRootAccess(sec, r) + return hasRootAccess(sec, r, clientCertAuthEnabled) } -func hasRootAccess(sec auth.Store, r *http.Request) bool { +func userFromBasicAuth(sec auth.Store, r *http.Request) *auth.User { + username, password, ok := r.BasicAuth() + if !ok { + plog.Warningf("auth: malformed basic auth encoding") + return nil + } + user, err := sec.GetUser(username) + if err != nil { + return nil + } + + ok = sec.CheckPassword(user, password) + if !ok { + plog.Warningf("auth: incorrect password for user: %s", username) + return nil + } + return &user +} + +func userFromClientCertificate(sec auth.Store, r *http.Request) *auth.User { + if r.TLS == nil { + return nil + } + + for _, chains := range r.TLS.VerifiedChains { + for _, chain := range chains { + plog.Debugf("auth: found common name %s.\n", chain.Subject.CommonName) + user, err := sec.GetUser(chain.Subject.CommonName) + if err == nil { + plog.Debugf("auth: authenticated user %s by cert common name.", user.User) + return &user + } + } + } + return nil +} + +func hasRootAccess(sec auth.Store, r *http.Request, clientCertAuthEnabled bool) bool { if sec == nil { // No store means no auth available, eg, tests. return true @@ -45,30 +83,30 @@ func hasRootAccess(sec auth.Store, r *http.Request) bool { if !sec.AuthEnabled() { return true } - username, password, ok := r.BasicAuth() - if !ok { - return false - } - rootUser, err := sec.GetUser(username) - if err != nil { - return false + + var rootUser *auth.User + if r.Header.Get("Authorization") == "" && clientCertAuthEnabled { + rootUser = userFromClientCertificate(sec, r) + if rootUser == nil { + return false + } + } else { + rootUser = userFromBasicAuth(sec, r) + if rootUser == nil { + return false + } } - ok = sec.CheckPassword(rootUser, password) - if !ok { - plog.Warningf("auth: wrong password for user %s", username) - return false - } for _, role := range rootUser.Roles { if role == auth.RootRoleName { return true } } - plog.Warningf("auth: user %s does not have the %s role for resource %s.", username, auth.RootRoleName, r.URL.Path) + plog.Warningf("auth: user %s does not have the %s role for resource %s.", rootUser.User, auth.RootRoleName, r.URL.Path) return false } -func hasKeyPrefixAccess(sec auth.Store, r *http.Request, key string, recursive bool) bool { +func hasKeyPrefixAccess(sec auth.Store, r *http.Request, key string, recursive, clientCertAuthEnabled bool) bool { if sec == nil { // No store means no auth available, eg, tests. return true @@ -76,25 +114,21 @@ func hasKeyPrefixAccess(sec auth.Store, r *http.Request, key string, recursive b if !sec.AuthEnabled() { return true } - if r.Header.Get("Authorization") == "" { - plog.Warningf("auth: no authorization provided, checking guest access") - return hasGuestAccess(sec, r, key) - } - username, password, ok := r.BasicAuth() - if !ok { - plog.Warningf("auth: malformed basic auth encoding") - return false - } - user, err := sec.GetUser(username) - if err != nil { - plog.Warningf("auth: no such user: %s.", username) - return false - } - authAsUser := sec.CheckPassword(user, password) - if !authAsUser { - plog.Warningf("auth: incorrect password for user: %s.", username) - return false + + var user *auth.User + if r.Header.Get("Authorization") == "" && clientCertAuthEnabled { + user = userFromClientCertificate(sec, r) + if user == nil { + plog.Warningf("auth: no authorization provided, checking guest access") + return hasGuestAccess(sec, r, key) + } + } else { + user = userFromBasicAuth(sec, r) + if user == nil { + return false + } } + writeAccess := r.Method != "GET" && r.Method != "HEAD" for _, roleName := range user.Roles { role, err := sec.GetRole(roleName) @@ -109,7 +143,7 @@ func hasKeyPrefixAccess(sec auth.Store, r *http.Request, key string, recursive b return true } } - plog.Warningf("auth: invalid access for user %s on key %s.", username, key) + plog.Warningf("auth: invalid access for user %s on key %s.", user.User, key) return false } @@ -134,18 +168,18 @@ func writeNoAuth(w http.ResponseWriter, r *http.Request) { } func handleAuth(mux *http.ServeMux, sh *authHandler) { - mux.HandleFunc(authPrefix+"/roles", capabilityHandler(authCapability, sh.baseRoles)) - mux.HandleFunc(authPrefix+"/roles/", capabilityHandler(authCapability, sh.handleRoles)) - mux.HandleFunc(authPrefix+"/users", capabilityHandler(authCapability, sh.baseUsers)) - mux.HandleFunc(authPrefix+"/users/", capabilityHandler(authCapability, sh.handleUsers)) - mux.HandleFunc(authPrefix+"/enable", capabilityHandler(authCapability, sh.enableDisable)) + mux.HandleFunc(authPrefix+"/roles", capabilityHandler(api.AuthCapability, sh.baseRoles)) + mux.HandleFunc(authPrefix+"/roles/", capabilityHandler(api.AuthCapability, sh.handleRoles)) + mux.HandleFunc(authPrefix+"/users", capabilityHandler(api.AuthCapability, sh.baseUsers)) + mux.HandleFunc(authPrefix+"/users/", capabilityHandler(api.AuthCapability, sh.handleUsers)) + mux.HandleFunc(authPrefix+"/enable", capabilityHandler(api.AuthCapability, sh.enableDisable)) } func (sh *authHandler) baseRoles(w http.ResponseWriter, r *http.Request) { if !allowMethod(w, r.Method, "GET") { return } - if !hasRootAccess(sh.sec, r) { + if !hasRootAccess(sh.sec, r, sh.clientCertAuthEnabled) { writeNoAuth(w, r) return } @@ -209,7 +243,7 @@ func (sh *authHandler) forRole(w http.ResponseWriter, r *http.Request, role stri if !allowMethod(w, r.Method, "GET", "PUT", "DELETE") { return } - if !hasRootAccess(sh.sec, r) { + if !hasRootAccess(sh.sec, r, sh.clientCertAuthEnabled) { writeNoAuth(w, r) return } @@ -285,11 +319,15 @@ type userWithRoles struct { Roles []auth.Role `json:"roles,omitempty"` } +type usersCollections struct { + Users []userWithRoles `json:"users"` +} + func (sh *authHandler) baseUsers(w http.ResponseWriter, r *http.Request) { if !allowMethod(w, r.Method, "GET") { return } - if !hasRootAccess(sh.sec, r) { + if !hasRootAccess(sh.sec, r, sh.clientCertAuthEnabled) { writeNoAuth(w, r) return } @@ -311,9 +349,7 @@ func (sh *authHandler) baseUsers(w http.ResponseWriter, r *http.Request) { return } - var usersCollections struct { - Users []userWithRoles `json:"users"` - } + ucs := usersCollections{} for _, userName := range users { var user auth.User user, err = sh.sec.GetUser(userName) @@ -327,15 +363,14 @@ func (sh *authHandler) baseUsers(w http.ResponseWriter, r *http.Request) { var role auth.Role role, err = sh.sec.GetRole(roleName) if err != nil { - writeError(w, r, err) - return + continue } uwr.Roles = append(uwr.Roles, role) } - usersCollections.Users = append(usersCollections.Users, uwr) + ucs.Users = append(ucs.Users, uwr) } - err = json.NewEncoder(w).Encode(usersCollections) + err = json.NewEncoder(w).Encode(ucs) if err != nil { plog.Warningf("baseUsers error encoding on %s", r.URL) @@ -364,7 +399,7 @@ func (sh *authHandler) forUser(w http.ResponseWriter, r *http.Request, user stri if !allowMethod(w, r.Method, "GET", "PUT", "DELETE") { return } - if !hasRootAccess(sh.sec, r) { + if !hasRootAccess(sh.sec, r, sh.clientCertAuthEnabled) { writeNoAuth(w, r) return } @@ -477,7 +512,7 @@ func (sh *authHandler) enableDisable(w http.ResponseWriter, r *http.Request) { if !allowMethod(w, r.Method, "GET", "PUT", "DELETE") { return } - if !hasWriteRootAccess(sh.sec, r) { + if !hasWriteRootAccess(sh.sec, r, sh.clientCertAuthEnabled) { writeNoAuth(w, r) return } diff --git a/vendor/github.com/coreos/etcd/etcdserver/api/v2http/doc.go b/vendor/github.com/coreos/etcd/etcdserver/api/v2http/doc.go index 3b306ef076b..475c4b1f95a 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/api/v2http/doc.go +++ b/vendor/github.com/coreos/etcd/etcdserver/api/v2http/doc.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. 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 ba44d95142f..cad9ec80da8 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/api/v2http/http.go +++ b/vendor/github.com/coreos/etcd/etcdserver/api/v2http/http.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. 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 396dc59a31b..a6c0f6d0b02 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 @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. diff --git a/vendor/github.com/coreos/etcd/etcdserver/api/v2http/httptypes/member.go b/vendor/github.com/coreos/etcd/etcdserver/api/v2http/httptypes/member.go index 432f73a4f37..738d74432f8 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/api/v2http/httptypes/member.go +++ b/vendor/github.com/coreos/etcd/etcdserver/api/v2http/httptypes/member.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. diff --git a/vendor/github.com/coreos/etcd/etcdserver/api/v2http/metrics.go b/vendor/github.com/coreos/etcd/etcdserver/api/v2http/metrics.go index c6b4a5378be..fdfb0c6070f 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/api/v2http/metrics.go +++ b/vendor/github.com/coreos/etcd/etcdserver/api/v2http/metrics.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. @@ -48,7 +48,7 @@ var ( prometheus.HistogramOpts{ Namespace: "etcd", Subsystem: "http", - Name: "successful_duration_second", + Name: "successful_duration_seconds", Help: "Bucketed histogram of processing time (s) of successfully handled requests (non-watches), by method (GET/PUT etc.).", Buckets: prometheus.ExponentialBuckets(0.0005, 2, 13), }, []string{"method"}) 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 fe5857a3970..e8fa3b60a53 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/api/v2http/peer.go +++ b/vendor/github.com/coreos/etcd/etcdserver/api/v2http/peer.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. diff --git a/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/auth.go b/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/auth.go index b07112f3fdb..e66c5261d0a 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/auth.go +++ b/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/auth.go @@ -1,4 +1,4 @@ -// Copyright 2016 Nippon Telegraph and Telephone Corporation. +// 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. @@ -37,13 +37,19 @@ func (as *AuthServer) AuthEnable(ctx context.Context, r *pb.AuthEnableRequest) ( } func (as *AuthServer) AuthDisable(ctx context.Context, r *pb.AuthDisableRequest) (*pb.AuthDisableResponse, error) { - plog.Info("not implemented yet") - return nil, nil + resp, err := as.authenticator.AuthDisable(ctx, r) + if err != nil { + return nil, togRPCError(err) + } + return resp, nil } func (as *AuthServer) Authenticate(ctx context.Context, r *pb.AuthenticateRequest) (*pb.AuthenticateResponse, error) { - plog.Info("not implemented yet") - return nil, nil + resp, err := as.authenticator.Authenticate(ctx, r) + if err != nil { + return nil, togRPCError(err) + } + return resp, nil } func (as *AuthServer) RoleAdd(ctx context.Context, r *pb.AuthRoleAddRequest) (*pb.AuthRoleAddResponse, error) { @@ -55,23 +61,43 @@ func (as *AuthServer) RoleAdd(ctx context.Context, r *pb.AuthRoleAddRequest) (*p } func (as *AuthServer) RoleDelete(ctx context.Context, r *pb.AuthRoleDeleteRequest) (*pb.AuthRoleDeleteResponse, error) { - plog.Info("not implemented yet") - return nil, nil + resp, err := as.authenticator.RoleDelete(ctx, r) + if err != nil { + return nil, togRPCError(err) + } + return resp, nil } func (as *AuthServer) RoleGet(ctx context.Context, r *pb.AuthRoleGetRequest) (*pb.AuthRoleGetResponse, error) { - plog.Info("not implemented yet") - return nil, nil + resp, err := as.authenticator.RoleGet(ctx, r) + if err != nil { + return nil, togRPCError(err) + } + return resp, nil } -func (as *AuthServer) RoleRevoke(ctx context.Context, r *pb.AuthRoleRevokeRequest) (*pb.AuthRoleRevokeResponse, error) { - plog.Info("not implemented yet") - return nil, nil +func (as *AuthServer) RoleList(ctx context.Context, r *pb.AuthRoleListRequest) (*pb.AuthRoleListResponse, error) { + resp, err := as.authenticator.RoleList(ctx, r) + if err != nil { + return nil, togRPCError(err) + } + return resp, nil } -func (as *AuthServer) RoleGrant(ctx context.Context, r *pb.AuthRoleGrantRequest) (*pb.AuthRoleGrantResponse, error) { - plog.Info("not implemented yet") - return nil, nil +func (as *AuthServer) RoleRevokePermission(ctx context.Context, r *pb.AuthRoleRevokePermissionRequest) (*pb.AuthRoleRevokePermissionResponse, error) { + resp, err := as.authenticator.RoleRevokePermission(ctx, r) + if err != nil { + return nil, togRPCError(err) + } + return resp, nil +} + +func (as *AuthServer) RoleGrantPermission(ctx context.Context, r *pb.AuthRoleGrantPermissionRequest) (*pb.AuthRoleGrantPermissionResponse, error) { + resp, err := as.authenticator.RoleGrantPermission(ctx, r) + if err != nil { + return nil, togRPCError(err) + } + return resp, nil } func (as *AuthServer) UserAdd(ctx context.Context, r *pb.AuthUserAddRequest) (*pb.AuthUserAddResponse, error) { @@ -91,18 +117,35 @@ func (as *AuthServer) UserDelete(ctx context.Context, r *pb.AuthUserDeleteReques } func (as *AuthServer) UserGet(ctx context.Context, r *pb.AuthUserGetRequest) (*pb.AuthUserGetResponse, error) { - plog.Info("not implemented yet") - return nil, nil + resp, err := as.authenticator.UserGet(ctx, r) + if err != nil { + return nil, togRPCError(err) + } + return resp, nil } -func (as *AuthServer) UserGrant(ctx context.Context, r *pb.AuthUserGrantRequest) (*pb.AuthUserGrantResponse, error) { - plog.Info("not implemented yet") - return nil, nil +func (as *AuthServer) UserList(ctx context.Context, r *pb.AuthUserListRequest) (*pb.AuthUserListResponse, error) { + resp, err := as.authenticator.UserList(ctx, r) + if err != nil { + return nil, togRPCError(err) + } + return resp, nil } -func (as *AuthServer) UserRevoke(ctx context.Context, r *pb.AuthUserRevokeRequest) (*pb.AuthUserRevokeResponse, error) { - plog.Info("not implemented yet") - return nil, nil +func (as *AuthServer) UserGrantRole(ctx context.Context, r *pb.AuthUserGrantRoleRequest) (*pb.AuthUserGrantRoleResponse, error) { + resp, err := as.authenticator.UserGrantRole(ctx, r) + if err != nil { + return nil, togRPCError(err) + } + return resp, nil +} + +func (as *AuthServer) UserRevokeRole(ctx context.Context, r *pb.AuthUserRevokeRoleRequest) (*pb.AuthUserRevokeRoleResponse, error) { + resp, err := as.authenticator.UserRevokeRole(ctx, r) + if err != nil { + return nil, togRPCError(err) + } + return resp, nil } func (as *AuthServer) UserChangePassword(ctx context.Context, r *pb.AuthUserChangePasswordRequest) (*pb.AuthUserChangePasswordResponse, error) { diff --git a/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/codec.go b/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/codec.go new file mode 100644 index 00000000000..17a2c87ae61 --- /dev/null +++ b/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/codec.go @@ -0,0 +1,34 @@ +// 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 v3rpc + +import "github.com/gogo/protobuf/proto" + +type codec struct{} + +func (c *codec) Marshal(v interface{}) ([]byte, error) { + b, err := proto.Marshal(v.(proto.Message)) + sentBytes.Add(float64(len(b))) + return b, err +} + +func (c *codec) Unmarshal(data []byte, v interface{}) error { + receivedBytes.Add(float64(len(data))) + return proto.Unmarshal(data, v.(proto.Message)) +} + +func (c *codec) String() string { + return "proto" +} 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 7515363ab28..07c65320bd0 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/grpc.go +++ b/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/grpc.go @@ -1,4 +1,4 @@ -// Copyright 2016 CoreOS, Inc. +// 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. @@ -19,15 +19,24 @@ 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")) +} + func Server(s *etcdserver.EtcdServer, tls *tls.Config) *grpc.Server { var opts []grpc.ServerOption + opts = append(opts, grpc.CustomCodec(&codec{})) if tls != nil { opts = append(opts, grpc.Creds(credentials.NewTLS(tls))) } + opts = append(opts, grpc.UnaryInterceptor(newUnaryInterceptor(s))) + opts = append(opts, grpc.StreamInterceptor(newStreamInterceptor(s))) grpcServer := grpc.NewServer(opts...) pb.RegisterKVServer(grpcServer, NewQuotaKVServer(s)) @@ -36,5 +45,6 @@ func Server(s *etcdserver.EtcdServer, tls *tls.Config) *grpc.Server { pb.RegisterClusterServer(grpcServer, NewClusterServer(s)) pb.RegisterAuthServer(grpcServer, NewAuthServer(s)) pb.RegisterMaintenanceServer(grpcServer, NewMaintenanceServer(s)) + return grpcServer } diff --git a/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/header.go b/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/header.go index dcb559219f7..d6d7f35d50f 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/header.go +++ b/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/header.go @@ -1,4 +1,4 @@ -// Copyright 2016 CoreOS, Inc. +// 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. @@ -40,4 +40,7 @@ func (h *header) fill(rh *pb.ResponseHeader) { rh.ClusterId = uint64(h.clusterID) rh.MemberId = uint64(h.memberID) rh.RaftTerm = h.raftTimer.Term() + if rh.Revision == 0 { + rh.Revision = h.rev() + } } diff --git a/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/interceptor.go b/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/interceptor.go new file mode 100644 index 00000000000..f18f1362628 --- /dev/null +++ b/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/interceptor.go @@ -0,0 +1,176 @@ +// 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 v3rpc + +import ( + "strings" + "sync" + "time" + + "github.com/coreos/etcd/etcdserver" + "github.com/coreos/etcd/etcdserver/api" + "github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes" + "github.com/coreos/etcd/pkg/types" + "github.com/coreos/etcd/raft" + + "golang.org/x/net/context" + "google.golang.org/grpc" + "google.golang.org/grpc/metadata" +) + +const ( + maxNoLeaderCnt = 3 +) + +type streamsMap struct { + mu sync.Mutex + streams map[grpc.ServerStream]struct{} +} + +func newUnaryInterceptor(s *etcdserver.EtcdServer) grpc.UnaryServerInterceptor { + return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp interface{}, err error) { + if !api.IsCapabilityEnabled(api.V3rpcCapability) { + return nil, rpctypes.ErrGRPCNotCapable + } + + md, ok := metadata.FromContext(ctx) + if ok { + if ks := md[rpctypes.MetadataRequireLeaderKey]; len(ks) > 0 && ks[0] == rpctypes.MetadataHasLeader { + if s.Leader() == types.ID(raft.None) { + return nil, rpctypes.ErrGRPCNoLeader + } + } + } + return metricsUnaryInterceptor(ctx, req, info, handler) + } +} + +func newStreamInterceptor(s *etcdserver.EtcdServer) grpc.StreamServerInterceptor { + smap := monitorLeader(s) + + return func(srv interface{}, ss grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error { + if !api.IsCapabilityEnabled(api.V3rpcCapability) { + return rpctypes.ErrGRPCNotCapable + } + + md, ok := metadata.FromContext(ss.Context()) + if ok { + if ks := md[rpctypes.MetadataRequireLeaderKey]; len(ks) > 0 && ks[0] == rpctypes.MetadataHasLeader { + if s.Leader() == types.ID(raft.None) { + return rpctypes.ErrGRPCNoLeader + } + + cctx, cancel := context.WithCancel(ss.Context()) + ss = serverStreamWithCtx{ctx: cctx, cancel: &cancel, ServerStream: ss} + + smap.mu.Lock() + smap.streams[ss] = struct{}{} + smap.mu.Unlock() + + defer func() { + smap.mu.Lock() + delete(smap.streams, ss) + smap.mu.Unlock() + cancel() + }() + + } + } + return metricsStreamInterceptor(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 + cancel *context.CancelFunc +} + +func (ssc serverStreamWithCtx) Context() context.Context { return ssc.ctx } + +func monitorLeader(s *etcdserver.EtcdServer) *streamsMap { + smap := &streamsMap{ + streams: make(map[grpc.ServerStream]struct{}), + } + + go func() { + election := time.Duration(s.Cfg.TickMs) * time.Duration(s.Cfg.ElectionTicks) * time.Millisecond + noLeaderCnt := 0 + + for { + select { + case <-s.StopNotify(): + return + case <-time.After(election): + if s.Leader() == types.ID(raft.None) { + noLeaderCnt++ + } else { + noLeaderCnt = 0 + } + + // We are more conservative on canceling existing streams. Reconnecting streams + // cost much more than just rejecting new requests. So we wait until the member + // cannot find a leader for maxNoLeaderCnt election timeouts to cancel existing streams. + if noLeaderCnt >= maxNoLeaderCnt { + smap.mu.Lock() + for ss := range smap.streams { + if ssWithCtx, ok := ss.(serverStreamWithCtx); ok { + (*ssWithCtx.cancel)() + <-ss.Context().Done() + } + } + smap.streams = make(map[grpc.ServerStream]struct{}) + smap.mu.Unlock() + } + } + } + }() + + return smap +} 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 c7f2f9d563d..94875ff2bc3 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/key.go +++ b/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/key.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. @@ -125,38 +125,38 @@ func (s *kvServer) Compact(ctx context.Context, r *pb.CompactionRequest) (*pb.Co func checkRangeRequest(r *pb.RangeRequest) error { if len(r.Key) == 0 { - return rpctypes.ErrEmptyKey + return rpctypes.ErrGRPCEmptyKey } return nil } func checkPutRequest(r *pb.PutRequest) error { if len(r.Key) == 0 { - return rpctypes.ErrEmptyKey + return rpctypes.ErrGRPCEmptyKey } return nil } func checkDeleteRequest(r *pb.DeleteRangeRequest) error { if len(r.Key) == 0 { - return rpctypes.ErrEmptyKey + return rpctypes.ErrGRPCEmptyKey } return nil } func checkTxnRequest(r *pb.TxnRequest) error { if len(r.Compare) > MaxOpsPerTxn || len(r.Success) > MaxOpsPerTxn || len(r.Failure) > MaxOpsPerTxn { - return rpctypes.ErrTooManyOps + return rpctypes.ErrGRPCTooManyOps } for _, c := range r.Compare { if len(c.Key) == 0 { - return rpctypes.ErrEmptyKey + return rpctypes.ErrGRPCEmptyKey } } for _, u := range r.Success { - if err := checkRequestUnion(u); err != nil { + if err := checkRequestOp(u); err != nil { return err } } @@ -165,23 +165,19 @@ func checkTxnRequest(r *pb.TxnRequest) error { } for _, u := range r.Failure { - if err := checkRequestUnion(u); err != nil { + if err := checkRequestOp(u); err != nil { return err } } - if err := checkRequestDupKeys(r.Failure); err != nil { - return err - } - - return nil + return checkRequestDupKeys(r.Failure) } -// checkRequestDupKeys gives rpctypes.ErrDuplicateKey if the same key is modified twice -func checkRequestDupKeys(reqs []*pb.RequestUnion) error { +// checkRequestDupKeys gives rpctypes.ErrGRPCDuplicateKey if the same key is modified twice +func checkRequestDupKeys(reqs []*pb.RequestOp) error { // check put overlap keys := make(map[string]struct{}) for _, requ := range reqs { - tv, ok := requ.Request.(*pb.RequestUnion_RequestPut) + tv, ok := requ.Request.(*pb.RequestOp_RequestPut) if !ok { continue } @@ -189,11 +185,10 @@ func checkRequestDupKeys(reqs []*pb.RequestUnion) error { if preq == nil { continue } - key := string(preq.Key) - if _, ok := keys[key]; ok { - return rpctypes.ErrDuplicateKey + if _, ok := keys[string(preq.Key)]; ok { + return rpctypes.ErrGRPCDuplicateKey } - keys[key] = struct{}{} + keys[string(preq.Key)] = struct{}{} } // no need to check deletes if no puts; delete overlaps are permitted @@ -210,7 +205,7 @@ func checkRequestDupKeys(reqs []*pb.RequestUnion) error { // check put overlap with deletes for _, requ := range reqs { - tv, ok := requ.Request.(*pb.RequestUnion_RequestDeleteRange) + tv, ok := requ.Request.(*pb.RequestOp_RequestDeleteRange) if !ok { continue } @@ -218,17 +213,16 @@ func checkRequestDupKeys(reqs []*pb.RequestUnion) error { if dreq == nil { continue } - key := string(dreq.Key) if dreq.RangeEnd == nil { - if _, found := keys[key]; found { - return rpctypes.ErrDuplicateKey + if _, found := keys[string(dreq.Key)]; found { + return rpctypes.ErrGRPCDuplicateKey } } else { - lo := sort.SearchStrings(sortedKeys, key) + lo := sort.SearchStrings(sortedKeys, string(dreq.Key)) hi := sort.SearchStrings(sortedKeys, string(dreq.RangeEnd)) if lo != hi { // element between lo and hi => overlap - return rpctypes.ErrDuplicateKey + return rpctypes.ErrGRPCDuplicateKey } } } @@ -236,23 +230,23 @@ func checkRequestDupKeys(reqs []*pb.RequestUnion) error { return nil } -func checkRequestUnion(u *pb.RequestUnion) error { +func checkRequestOp(u *pb.RequestOp) error { // TODO: ensure only one of the field is set. switch uv := u.Request.(type) { - case *pb.RequestUnion_RequestRange: + case *pb.RequestOp_RequestRange: if uv.RequestRange != nil { return checkRangeRequest(uv.RequestRange) } - case *pb.RequestUnion_RequestPut: + case *pb.RequestOp_RequestPut: if uv.RequestPut != nil { return checkPutRequest(uv.RequestPut) } - case *pb.RequestUnion_RequestDeleteRange: + case *pb.RequestOp_RequestDeleteRange: if uv.RequestDeleteRange != nil { return checkDeleteRequest(uv.RequestDeleteRange) } default: - // empty union + // empty op return nil } return nil 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 b21b1d1112c..108e1387ad0 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/lease.go +++ b/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/lease.go @@ -1,4 +1,4 @@ -// Copyright 2016 CoreOS, Inc. +// 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. @@ -25,27 +25,33 @@ import ( ) type LeaseServer struct { - le etcdserver.Lessor + hdr header + le etcdserver.Lessor } -func NewLeaseServer(le etcdserver.Lessor) pb.LeaseServer { - return &LeaseServer{le: le} +func NewLeaseServer(s *etcdserver.EtcdServer) pb.LeaseServer { + return &LeaseServer{le: s, hdr: newHeader(s)} } 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.ErrLeaseExist + return nil, rpctypes.ErrGRPCLeaseExist } + if err != nil { + return nil, err + } + ls.hdr.fill(resp.Header) return resp, err } func (ls *LeaseServer) LeaseRevoke(ctx context.Context, rr *pb.LeaseRevokeRequest) (*pb.LeaseRevokeResponse, error) { - r, err := ls.le.LeaseRevoke(ctx, rr) + resp, err := ls.le.LeaseRevoke(ctx, rr) if err != nil { - return nil, rpctypes.ErrLeaseNotFound + return nil, rpctypes.ErrGRPCLeaseNotFound } - return r, nil + ls.hdr.fill(resp.Header) + return resp, nil } func (ls *LeaseServer) LeaseKeepAlive(stream pb.Lease_LeaseKeepAliveServer) error { @@ -58,16 +64,26 @@ func (ls *LeaseServer) LeaseKeepAlive(stream pb.Lease_LeaseKeepAliveServer) erro return err } + // Create header before we sent out the renew request. + // This can make sure that the revision is strictly smaller or equal to + // when the keepalive happened at the local server (when the local server is the leader) + // or remote leader. + // Without this, a lease might be revoked at rev 3 but client can see the keepalive succeeded + // at rev 4. + resp := &pb.LeaseKeepAliveResponse{ID: req.ID, Header: &pb.ResponseHeader{}} + ls.hdr.fill(resp.Header) + ttl, err := ls.le.LeaseRenew(lease.LeaseID(req.ID)) if err == lease.ErrLeaseNotFound { - return rpctypes.ErrLeaseNotFound + err = nil + ttl = 0 } - if err != nil && err != lease.ErrLeaseNotFound { + if err != nil { return err } - resp := &pb.LeaseKeepAliveResponse{ID: req.ID, TTL: ttl} + resp.TTL = ttl err = stream.Send(resp) if err != nil { return err 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 5dae0c45279..20af20fc311 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/maintenance.go +++ b/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/maintenance.go @@ -1,4 +1,4 @@ -// Copyright 2016 CoreOS, Inc. +// 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. @@ -15,13 +15,22 @@ package v3rpc import ( + "crypto/sha256" + "io" + "github.com/coreos/etcd/etcdserver" pb "github.com/coreos/etcd/etcdserver/etcdserverpb" - "github.com/coreos/etcd/storage/backend" + "github.com/coreos/etcd/mvcc" + "github.com/coreos/etcd/mvcc/backend" + "github.com/coreos/etcd/pkg/types" "github.com/coreos/etcd/version" "golang.org/x/net/context" ) +type KVGetter interface { + KV() mvcc.ConsistentWatchableKV +} + type BackendGetter interface { Backend() backend.Backend } @@ -30,33 +39,86 @@ type Alarmer interface { Alarm(ctx context.Context, ar *pb.AlarmRequest) (*pb.AlarmResponse, error) } +type RaftStatusGetter interface { + Index() uint64 + Term() uint64 + Leader() types.ID +} + type maintenanceServer struct { + rg RaftStatusGetter + kg KVGetter bg BackendGetter a Alarmer hdr header } func NewMaintenanceServer(s *etcdserver.EtcdServer) pb.MaintenanceServer { - return &maintenanceServer{bg: s, a: s, hdr: newHeader(s)} + return &maintenanceServer{rg: s, kg: s, bg: s, a: s, hdr: newHeader(s)} } func (ms *maintenanceServer) Defragment(ctx context.Context, sr *pb.DefragmentRequest) (*pb.DefragmentResponse, error) { plog.Noticef("starting to defragment the storage backend...") err := ms.bg.Backend().Defrag() if err != nil { - plog.Errorf("failed to deframent the storage backend (%v)", err) + plog.Errorf("failed to defragment the storage backend (%v)", err) return nil, err } plog.Noticef("finished defragmenting the storage backend") return &pb.DefragmentResponse{}, nil } +func (ms *maintenanceServer) Snapshot(sr *pb.SnapshotRequest, srv pb.Maintenance_SnapshotServer) error { + snap := ms.bg.Backend().Snapshot() + pr, pw := io.Pipe() + + defer pr.Close() + + go func() { + snap.WriteTo(pw) + if err := snap.Close(); err != nil { + plog.Errorf("error closing snapshot (%v)", err) + } + pw.Close() + }() + + // send file data + h := sha256.New() + br := int64(0) + buf := make([]byte, 32*1024) + sz := snap.Size() + for br < sz { + n, err := io.ReadFull(pr, buf) + if err != nil && err != io.EOF && err != io.ErrUnexpectedEOF { + return togRPCError(err) + } + br += int64(n) + resp := &pb.SnapshotResponse{ + RemainingBytes: uint64(sz - br), + Blob: buf[:n], + } + if err = srv.Send(resp); err != nil { + return togRPCError(err) + } + h.Write(buf[:n]) + } + + // send sha + sha := h.Sum(nil) + hresp := &pb.SnapshotResponse{RemainingBytes: 0, Blob: sha} + if err := srv.Send(hresp); err != nil { + return togRPCError(err) + } + + return nil +} + func (ms *maintenanceServer) Hash(ctx context.Context, r *pb.HashRequest) (*pb.HashResponse, error) { - h, err := ms.bg.Backend().Hash() + h, rev, err := ms.kg.KV().Hash() if err != nil { return nil, togRPCError(err) } - resp := &pb.HashResponse{Header: &pb.ResponseHeader{Revision: ms.hdr.rev()}, Hash: h} + resp := &pb.HashResponse{Header: &pb.ResponseHeader{Revision: rev}, Hash: h} ms.hdr.fill(resp.Header) return resp, nil } @@ -66,7 +128,14 @@ func (ms *maintenanceServer) Alarm(ctx context.Context, ar *pb.AlarmRequest) (*p } func (ms *maintenanceServer) Status(ctx context.Context, ar *pb.StatusRequest) (*pb.StatusResponse, error) { - resp := &pb.StatusResponse{Header: &pb.ResponseHeader{Revision: ms.hdr.rev()}, Version: version.Version} + resp := &pb.StatusResponse{ + Header: &pb.ResponseHeader{Revision: ms.hdr.rev()}, + Version: version.Version, + DbSize: ms.bg.Backend().Size(), + Leader: uint64(ms.rg.Leader()), + RaftIndex: ms.rg.Index(), + RaftTerm: ms.rg.Term(), + } ms.hdr.fill(resp.Header) return resp, nil } 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 351a998c265..e5e76923680 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/member.go +++ b/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/member.go @@ -1,4 +1,4 @@ -// Copyright 2016 CoreOS, Inc. +// 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. @@ -45,7 +45,7 @@ func NewClusterServer(s *etcdserver.EtcdServer) *ClusterServer { func (cs *ClusterServer) MemberAdd(ctx context.Context, r *pb.MemberAddRequest) (*pb.MemberAddResponse, error) { urls, err := types.NewURLs(r.PeerURLs) if err != nil { - return nil, rpctypes.ErrMemberBadURLs + return nil, rpctypes.ErrGRPCMemberBadURLs } now := time.Now() @@ -53,16 +53,16 @@ func (cs *ClusterServer) MemberAdd(ctx context.Context, r *pb.MemberAddRequest) err = cs.server.AddMember(ctx, *m) switch { case err == membership.ErrIDExists: - return nil, rpctypes.ErrMemberExist + return nil, rpctypes.ErrGRPCMemberExist case err == membership.ErrPeerURLexists: - return nil, rpctypes.ErrPeerURLExist + return nil, rpctypes.ErrGRPCPeerURLExist case err != nil: return nil, grpc.Errorf(codes.Internal, err.Error()) } return &pb.MemberAddResponse{ Header: cs.header(), - Member: &pb.Member{ID: uint64(m.ID), IsLeader: m.ID == cs.server.Leader(), PeerURLs: m.PeerURLs}, + Member: &pb.Member{ID: uint64(m.ID), PeerURLs: m.PeerURLs}, }, nil } @@ -72,7 +72,7 @@ func (cs *ClusterServer) MemberRemove(ctx context.Context, r *pb.MemberRemoveReq case err == membership.ErrIDRemoved: fallthrough case err == membership.ErrIDNotFound: - return nil, rpctypes.ErrMemberNotFound + return nil, rpctypes.ErrGRPCMemberNotFound case err != nil: return nil, grpc.Errorf(codes.Internal, err.Error()) } @@ -88,9 +88,9 @@ func (cs *ClusterServer) MemberUpdate(ctx context.Context, r *pb.MemberUpdateReq err := cs.server.UpdateMember(ctx, m) switch { case err == membership.ErrPeerURLexists: - return nil, rpctypes.ErrPeerURLExist + return nil, rpctypes.ErrGRPCPeerURLExist case err == membership.ErrIDNotFound: - return nil, rpctypes.ErrMemberNotFound + return nil, rpctypes.ErrGRPCMemberNotFound case err != nil: return nil, grpc.Errorf(codes.Internal, err.Error()) } @@ -106,7 +106,6 @@ func (cs *ClusterServer) MemberList(ctx context.Context, r *pb.MemberListRequest protoMembs[i] = &pb.Member{ Name: membs[i].Name, ID: uint64(membs[i].ID), - IsLeader: membs[i].ID == cs.server.Leader(), PeerURLs: membs[i].PeerURLs, ClientURLs: membs[i].ClientURLs, } diff --git a/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/metrics.go b/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/metrics.go new file mode 100644 index 00000000000..cce80b435b5 --- /dev/null +++ b/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/metrics.go @@ -0,0 +1,67 @@ +// 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 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", + Name: "client_grpc_sent_bytes_total", + Help: "The total number of bytes sent to grpc clients.", + }) + + receivedBytes = prometheus.NewCounter(prometheus.CounterOpts{ + Namespace: "etcd", + Subsystem: "network", + Name: "client_grpc_received_bytes_total", + Help: "The total number of bytes received from grpc clients.", + }) +) + +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/quota.go b/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/quota.go index aa7794f967a..836f2fd3f43 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/quota.go +++ b/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/quota.go @@ -1,4 +1,4 @@ -// Copyright 2016 CoreOS, Inc. +// 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. @@ -45,7 +45,7 @@ func (qa *quotaAlarmer) check(ctx context.Context, r interface{}) error { Alarm: pb.AlarmType_NOSPACE, } qa.a.Alarm(ctx, req) - return rpctypes.ErrNoSpace + return rpctypes.ErrGRPCNoSpace } func NewQuotaKVServer(s *etcdserver.EtcdServer) pb.KVServer { diff --git a/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes/doc.go b/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes/doc.go new file mode 100644 index 00000000000..f72c6a644f3 --- /dev/null +++ b/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes/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 rpctypes has types and values shared by the etcd server and client for v3 RPC interaction. +package rpctypes 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 5e174b4b3de..ecf5a20674b 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 @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. @@ -20,24 +20,131 @@ import ( ) var ( - ErrEmptyKey = grpc.Errorf(codes.InvalidArgument, "etcdserver: key is not provided") - ErrTooManyOps = grpc.Errorf(codes.InvalidArgument, "etcdserver: too many operations in txn request") - ErrDuplicateKey = grpc.Errorf(codes.InvalidArgument, "etcdserver: duplicate key given in txn request") - ErrCompacted = grpc.Errorf(codes.OutOfRange, "etcdserver: storage: required revision has been compacted") - ErrFutureRev = grpc.Errorf(codes.OutOfRange, "etcdserver: storage: required revision is a future revision") - ErrNoSpace = grpc.Errorf(codes.ResourceExhausted, "etcdserver: storage: database space exceeded") + // server-side error + ErrGRPCEmptyKey = grpc.Errorf(codes.InvalidArgument, "etcdserver: key is not provided") + ErrGRPCTooManyOps = grpc.Errorf(codes.InvalidArgument, "etcdserver: too many operations in txn request") + ErrGRPCDuplicateKey = grpc.Errorf(codes.InvalidArgument, "etcdserver: duplicate key given in txn request") + ErrGRPCCompacted = grpc.Errorf(codes.OutOfRange, "etcdserver: mvcc: required revision has been compacted") + ErrGRPCFutureRev = grpc.Errorf(codes.OutOfRange, "etcdserver: mvcc: required revision is a future revision") + ErrGRPCNoSpace = grpc.Errorf(codes.ResourceExhausted, "etcdserver: mvcc: database space exceeded") - ErrLeaseNotFound = grpc.Errorf(codes.NotFound, "etcdserver: requested lease not found") - ErrLeaseExist = grpc.Errorf(codes.FailedPrecondition, "etcdserver: lease already exists") + ErrGRPCLeaseNotFound = grpc.Errorf(codes.NotFound, "etcdserver: requested lease not found") + ErrGRPCLeaseExist = grpc.Errorf(codes.FailedPrecondition, "etcdserver: lease already exists") - ErrMemberExist = grpc.Errorf(codes.FailedPrecondition, "etcdserver: member ID already exist") - ErrPeerURLExist = grpc.Errorf(codes.FailedPrecondition, "etcdserver: Peer URLs already exists") - ErrMemberBadURLs = grpc.Errorf(codes.InvalidArgument, "etcdserver: given member URLs are invalid") - ErrMemberNotFound = 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") + ErrGRPCMemberBadURLs = grpc.Errorf(codes.InvalidArgument, "etcdserver: given member URLs are invalid") + ErrGRPCMemberNotFound = grpc.Errorf(codes.NotFound, "etcdserver: member not found") - ErrRequestTooLarge = grpc.Errorf(codes.InvalidArgument, "etcdserver: request is too large") + ErrGRPCRequestTooLarge = grpc.Errorf(codes.InvalidArgument, "etcdserver: request is too large") - ErrUserAlreadyExist = grpc.Errorf(codes.FailedPrecondition, "etcdserver: user name already exists") - ErrUserNotFound = grpc.Errorf(codes.FailedPrecondition, "etcdserver: user name not found") - ErrRoleAlreadyExist = grpc.Errorf(codes.FailedPrecondition, "etcdserver: role name already exists") + 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") + 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") + 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") + + ErrGRPCNoLeader = grpc.Errorf(codes.Unavailable, "etcdserver: no leader") + ErrGRPCNotCapable = grpc.Errorf(codes.Unavailable, "etcdserver: not capable") + ErrGRPCStopped = grpc.Errorf(codes.Unavailable, "etcdserver: server stopped") + + errStringToError = map[string]error{ + grpc.ErrorDesc(ErrGRPCEmptyKey): ErrGRPCEmptyKey, + grpc.ErrorDesc(ErrGRPCTooManyOps): ErrGRPCTooManyOps, + grpc.ErrorDesc(ErrGRPCDuplicateKey): ErrGRPCDuplicateKey, + grpc.ErrorDesc(ErrGRPCCompacted): ErrGRPCCompacted, + grpc.ErrorDesc(ErrGRPCFutureRev): ErrGRPCFutureRev, + grpc.ErrorDesc(ErrGRPCNoSpace): ErrGRPCNoSpace, + + 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(ErrGRPCRequestTooLarge): ErrGRPCRequestTooLarge, + + grpc.ErrorDesc(ErrGRPCRootUserNotExist): ErrGRPCRootUserNotExist, + grpc.ErrorDesc(ErrGRPCRootRoleNotExist): ErrGRPCRootRoleNotExist, + grpc.ErrorDesc(ErrGRPCUserAlreadyExist): ErrGRPCUserAlreadyExist, + grpc.ErrorDesc(ErrGRPCUserNotFound): ErrGRPCUserNotFound, + grpc.ErrorDesc(ErrGRPCRoleAlreadyExist): ErrGRPCRoleAlreadyExist, + grpc.ErrorDesc(ErrGRPCRoleNotFound): ErrGRPCRoleNotFound, + grpc.ErrorDesc(ErrGRPCAuthFailed): ErrGRPCAuthFailed, + grpc.ErrorDesc(ErrGRPCPermissionDenied): ErrGRPCPermissionDenied, + grpc.ErrorDesc(ErrGRPCRoleNotGranted): ErrGRPCRoleNotGranted, + grpc.ErrorDesc(ErrGRPCPermissionNotGranted): ErrGRPCPermissionNotGranted, + + grpc.ErrorDesc(ErrGRPCNoLeader): ErrGRPCNoLeader, + grpc.ErrorDesc(ErrGRPCNotCapable): ErrGRPCNotCapable, + grpc.ErrorDesc(ErrGRPCStopped): ErrGRPCStopped, + } + + // client-side error + ErrEmptyKey = Error(ErrGRPCEmptyKey) + ErrTooManyOps = Error(ErrGRPCTooManyOps) + ErrDuplicateKey = Error(ErrGRPCDuplicateKey) + ErrCompacted = Error(ErrGRPCCompacted) + ErrFutureRev = Error(ErrGRPCFutureRev) + ErrNoSpace = Error(ErrGRPCNoSpace) + + ErrLeaseNotFound = Error(ErrGRPCLeaseNotFound) + ErrLeaseExist = Error(ErrGRPCLeaseExist) + + ErrMemberExist = Error(ErrGRPCMemberExist) + ErrPeerURLExist = Error(ErrGRPCPeerURLExist) + ErrMemberBadURLs = Error(ErrGRPCMemberBadURLs) + ErrMemberNotFound = Error(ErrGRPCMemberNotFound) + + ErrRequestTooLarge = Error(ErrGRPCRequestTooLarge) + + ErrRootUserNotExist = Error(ErrGRPCRootUserNotExist) + ErrRootRoleNotExist = Error(ErrGRPCRootRoleNotExist) + ErrUserAlreadyExist = Error(ErrGRPCUserAlreadyExist) + ErrUserNotFound = Error(ErrGRPCUserNotFound) + ErrRoleAlreadyExist = Error(ErrGRPCRoleAlreadyExist) + ErrRoleNotFound = Error(ErrGRPCRoleNotFound) + ErrAuthFailed = Error(ErrGRPCAuthFailed) + ErrPermissionDenied = Error(ErrGRPCPermissionDenied) + ErrRoleNotGranted = Error(ErrGRPCRoleNotGranted) + ErrPermissionNotGranted = Error(ErrGRPCPermissionNotGranted) + + ErrNoLeader = Error(ErrGRPCNoLeader) + ErrNotCapable = Error(ErrGRPCNotCapable) + ErrStopped = Error(ErrGRPCStopped) ) + +// EtcdError defines gRPC server errors. +// (https://github.com/grpc/grpc-go/blob/master/rpc_util.go#L319-L323) +type EtcdError struct { + code codes.Code + desc string +} + +// Code returns grpc/codes.Code. +// TODO: define clientv3/codes.Code. +func (e EtcdError) Code() codes.Code { + return e.code +} + +func (e EtcdError) Error() string { + return e.desc +} + +func Error(err error) error { + if err == nil { + return nil + } + verr, ok := errStringToError[grpc.ErrorDesc(err)] + if !ok { // not gRPC error + return err + } + return EtcdError{code: grpc.Code(verr), desc: grpc.ErrorDesc(verr)} +} diff --git a/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes/md.go b/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes/md.go new file mode 100644 index 00000000000..5c590e1aec9 --- /dev/null +++ b/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes/md.go @@ -0,0 +1,20 @@ +// 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 rpctypes + +var ( + MetadataRequireLeaderKey = "hasleader" + MetadataHasLeader = "true" +) 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 982627a008b..997e57892f0 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/util.go +++ b/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/util.go @@ -1,4 +1,4 @@ -// Copyright 2016 Nippon Telegraph and Telephone Corporation. +// 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. @@ -19,30 +19,45 @@ import ( "github.com/coreos/etcd/etcdserver" "github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes" "github.com/coreos/etcd/lease" - "github.com/coreos/etcd/storage" + "github.com/coreos/etcd/mvcc" "google.golang.org/grpc" "google.golang.org/grpc/codes" ) func togRPCError(err error) error { switch err { - case storage.ErrCompacted: - return rpctypes.ErrCompacted - case storage.ErrFutureRev: - return rpctypes.ErrFutureRev + case mvcc.ErrCompacted: + return rpctypes.ErrGRPCCompacted + case mvcc.ErrFutureRev: + return rpctypes.ErrGRPCFutureRev case lease.ErrLeaseNotFound: - return rpctypes.ErrLeaseNotFound + return rpctypes.ErrGRPCLeaseNotFound // TODO: handle error from raft and timeout case etcdserver.ErrRequestTooLarge: - return rpctypes.ErrRequestTooLarge + return rpctypes.ErrGRPCRequestTooLarge case etcdserver.ErrNoSpace: - return rpctypes.ErrNoSpace + return rpctypes.ErrGRPCNoSpace + + case auth.ErrRootUserNotExist: + return rpctypes.ErrGRPCRootUserNotExist + case auth.ErrRootRoleNotExist: + return rpctypes.ErrGRPCRootRoleNotExist case auth.ErrUserAlreadyExist: - return rpctypes.ErrUserAlreadyExist + return rpctypes.ErrGRPCUserAlreadyExist case auth.ErrUserNotFound: - return rpctypes.ErrUserNotFound + return rpctypes.ErrGRPCUserNotFound case auth.ErrRoleAlreadyExist: - return rpctypes.ErrRoleAlreadyExist + return rpctypes.ErrGRPCRoleAlreadyExist + case auth.ErrRoleNotFound: + return rpctypes.ErrGRPCRoleNotFound + case auth.ErrAuthFailed: + return rpctypes.ErrGRPCAuthFailed + case auth.ErrPermissionDenied: + return rpctypes.ErrGRPCPermissionDenied + case auth.ErrRoleNotGranted: + return rpctypes.ErrGRPCRoleNotGranted + case auth.ErrPermissionNotGranted: + return rpctypes.ErrGRPCPermissionNotGranted default: return grpc.Errorf(codes.Internal, 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 2f380a58db4..dba0646795b 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/watch.go +++ b/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/watch.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. @@ -19,17 +19,20 @@ import ( "sync" "time" + "golang.org/x/net/context" + "github.com/coreos/etcd/etcdserver" + "github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes" pb "github.com/coreos/etcd/etcdserver/etcdserverpb" - "github.com/coreos/etcd/storage" - "github.com/coreos/etcd/storage/storagepb" + "github.com/coreos/etcd/mvcc" + "github.com/coreos/etcd/mvcc/mvccpb" ) type watchServer struct { clusterID int64 memberID int64 raftTimer etcdserver.RaftTimer - watchable storage.Watchable + watchable mvcc.Watchable } func NewWatchServer(s *etcdserver.EtcdServer) pb.WatchServer { @@ -71,7 +74,7 @@ const ( ) // serverWatchStream is an etcd server side stream. It receives requests -// from client side gRPC stream. It receives watch events from storage.WatchStream, +// from client side gRPC stream. It receives watch events from mvcc.WatchStream, // and creates responses that forwarded to gRPC stream. // It also forwards control message like watch created and canceled. type serverWatchStream struct { @@ -80,20 +83,23 @@ type serverWatchStream struct { raftTimer etcdserver.RaftTimer gRPCStream pb.Watch_WatchServer - watchStream storage.WatchStream + watchStream mvcc.WatchStream ctrlStream chan *pb.WatchResponse + // mu protects progress, prevKV + mu sync.Mutex // progress tracks the watchID that stream might need to send // progress to. - progress map[storage.WatchID]bool - // mu protects progress - mu sync.Mutex + progress map[mvcc.WatchID]bool // closec indicates the stream is closed. closec chan struct{} + + // wg waits for the send loop to complete + wg sync.WaitGroup } -func (ws *watchServer) Watch(stream pb.Watch_WatchServer) error { +func (ws *watchServer) Watch(stream pb.Watch_WatchServer) (err error) { sws := serverWatchStream{ clusterID: ws.clusterID, memberID: ws.memberID, @@ -102,16 +108,38 @@ func (ws *watchServer) Watch(stream pb.Watch_WatchServer) error { watchStream: ws.watchable.NewWatchStream(), // chan for sending control response like watcher created and canceled. ctrlStream: make(chan *pb.WatchResponse, ctrlStreamBufLen), - progress: make(map[storage.WatchID]bool), + progress: make(map[mvcc.WatchID]bool), closec: make(chan struct{}), } - defer sws.close() - go sws.sendLoop() - return sws.recvLoop() + sws.wg.Add(1) + go func() { + sws.sendLoop() + sws.wg.Done() + }() + + errc := make(chan error, 1) + // Ideally recvLoop would also use sws.wg to signal its completion + // 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() }() + + select { + case err = <-errc: + case <-stream.Context().Done(): + err = stream.Context().Err() + // the only server-side cancellation is noleader for now. + if err == context.Canceled { + err = rpctypes.ErrGRPCNoLeader + } + } + sws.close() + return err } func (sws *serverWatchStream) recvLoop() error { + defer close(sws.ctrlStream) for { req, err := sws.gRPCStream.Recv() if err == io.EOF { @@ -143,18 +171,25 @@ func (sws *serverWatchStream) recvLoop() error { } id := sws.watchStream.Watch(creq.Key, creq.RangeEnd, rev) if id != -1 && creq.ProgressNotify { + sws.mu.Lock() sws.progress[id] = true + sws.mu.Unlock() } - sws.ctrlStream <- &pb.WatchResponse{ + wr := &pb.WatchResponse{ Header: sws.newResponseHeader(wsrev), WatchId: int64(id), Created: true, Canceled: id == -1, } + select { + case sws.ctrlStream <- wr: + case <-sws.closec: + return nil + } case *pb.WatchRequest_CancelRequest: if uv.CancelRequest != nil { id := uv.CancelRequest.WatchId - err := sws.watchStream.Cancel(storage.WatchID(id)) + err := sws.watchStream.Cancel(mvcc.WatchID(id)) if err == nil { sws.ctrlStream <- &pb.WatchResponse{ Header: sws.newResponseHeader(sws.watchStream.Rev()), @@ -162,26 +197,40 @@ func (sws *serverWatchStream) recvLoop() error { Canceled: true, } sws.mu.Lock() - delete(sws.progress, storage.WatchID(id)) + delete(sws.progress, mvcc.WatchID(id)) sws.mu.Unlock() } } - // TODO: do we need to return error back to client? default: - panic("not implemented") + // we probably should not shutdown the entire stream when + // receive an valid command. + // so just do nothing instead. + continue } } } func (sws *serverWatchStream) sendLoop() { // watch ids that are currently active - ids := make(map[storage.WatchID]struct{}) + ids := make(map[mvcc.WatchID]struct{}) // watch responses pending on a watch id creation message - pending := make(map[storage.WatchID][]*pb.WatchResponse) + pending := make(map[mvcc.WatchID][]*pb.WatchResponse) interval := GetProgressReportInterval() progressTicker := time.NewTicker(interval) - defer progressTicker.Stop() + + defer func() { + progressTicker.Stop() + // drain the chan to clean up pending events + for ws := range sws.watchStream.Chan() { + mvcc.ReportEventReceived(len(ws.Events)) + } + for _, wrs := range pending { + for _, ws := range wrs { + mvcc.ReportEventReceived(len(ws.Events)) + } + } + }() for { select { @@ -190,11 +239,11 @@ func (sws *serverWatchStream) sendLoop() { return } - // TODO: evs is []storagepb.Event type - // either return []*storagepb.Event from storage package - // or define protocol buffer with []storagepb.Event. + // TODO: evs is []mvccpb.Event type + // either return []*mvccpb.Event from the mvcc package + // or define protocol buffer with []mvccpb.Event. evs := wresp.Events - events := make([]*storagepb.Event, len(evs)) + events := make([]*mvccpb.Event, len(evs)) for i := range evs { events[i] = &evs[i] } @@ -213,13 +262,14 @@ func (sws *serverWatchStream) sendLoop() { continue } - storage.ReportEventReceived() + mvcc.ReportEventReceived(len(evs)) if err := sws.gRPCStream.Send(wr); err != nil { return } sws.mu.Lock() - if _, ok := sws.progress[wresp.WatchID]; ok { + if len(evs) > 0 && sws.progress[wresp.WatchID] { + // elide next progress update if sent a key update sws.progress[wresp.WatchID] = false } sws.mu.Unlock() @@ -234,7 +284,7 @@ func (sws *serverWatchStream) sendLoop() { } // track id creation - wid := storage.WatchID(c.WatchId) + wid := mvcc.WatchID(c.WatchId) if c.Canceled { delete(ids, wid) continue @@ -243,7 +293,7 @@ func (sws *serverWatchStream) sendLoop() { // flush buffered events ids[wid] = struct{}{} for _, v := range pending[wid] { - storage.ReportEventReceived() + mvcc.ReportEventReceived(len(v.Events)) if err := sws.gRPCStream.Send(v); err != nil { return } @@ -251,22 +301,16 @@ func (sws *serverWatchStream) sendLoop() { delete(pending, wid) } case <-progressTicker.C: + sws.mu.Lock() for id, ok := range sws.progress { if ok { sws.watchStream.RequestProgress(id) } sws.progress[id] = true } + sws.mu.Unlock() case <-sws.closec: - // drain the chan to clean up pending events - for range sws.watchStream.Chan() { - storage.ReportEventReceived() - } - for _, wrs := range pending { - for range wrs { - storage.ReportEventReceived() - } - } + return } } } @@ -274,7 +318,7 @@ func (sws *serverWatchStream) sendLoop() { func (sws *serverWatchStream) close() { sws.watchStream.Close() close(sws.closec) - close(sws.ctrlStream) + sws.wg.Wait() } func (sws *serverWatchStream) newResponseHeader(rev int64) *pb.ResponseHeader { diff --git a/vendor/github.com/coreos/etcd/etcdserver/apply.go b/vendor/github.com/coreos/etcd/etcdserver/apply.go index da327985192..820b4fc527e 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/apply.go +++ b/vendor/github.com/coreos/etcd/etcdserver/apply.go @@ -1,4 +1,4 @@ -// Copyright 2016 CoreOS, Inc. +// 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. @@ -18,13 +18,15 @@ import ( "bytes" "fmt" "sort" + "time" pb "github.com/coreos/etcd/etcdserver/etcdserverpb" "github.com/coreos/etcd/lease" + "github.com/coreos/etcd/mvcc" + "github.com/coreos/etcd/mvcc/mvccpb" "github.com/coreos/etcd/pkg/types" - dstorage "github.com/coreos/etcd/storage" - "github.com/coreos/etcd/storage/storagepb" "github.com/gogo/protobuf/proto" + "golang.org/x/net/context" ) const ( @@ -32,6 +34,8 @@ const ( // To apply with independent Range, Put, Delete, you can pass noTxn // to apply functions instead of a valid txn ID. noTxn = -1 + + warnApplyDuration = 10 * time.Millisecond ) type applyResult struct { @@ -45,54 +49,103 @@ type applyResult struct { // applierV3 is the interface for processing V3 raft messages type applierV3 interface { + Apply(r *pb.InternalRaftRequest) *applyResult + Put(txnID int64, p *pb.PutRequest) (*pb.PutResponse, error) Range(txnID int64, r *pb.RangeRequest) (*pb.RangeResponse, error) DeleteRange(txnID int64, dr *pb.DeleteRangeRequest) (*pb.DeleteRangeResponse, error) Txn(rt *pb.TxnRequest) (*pb.TxnResponse, error) Compaction(compaction *pb.CompactionRequest) (*pb.CompactionResponse, <-chan struct{}, error) + LeaseGrant(lc *pb.LeaseGrantRequest) (*pb.LeaseGrantResponse, error) LeaseRevoke(lc *pb.LeaseRevokeRequest) (*pb.LeaseRevokeResponse, error) + Alarm(*pb.AlarmRequest) (*pb.AlarmResponse, error) + + Authenticate(r *pb.InternalAuthenticateRequest) (*pb.AuthenticateResponse, error) + AuthEnable() (*pb.AuthEnableResponse, error) + AuthDisable() (*pb.AuthDisableResponse, error) + UserAdd(ua *pb.AuthUserAddRequest) (*pb.AuthUserAddResponse, error) UserDelete(ua *pb.AuthUserDeleteRequest) (*pb.AuthUserDeleteResponse, error) UserChangePassword(ua *pb.AuthUserChangePasswordRequest) (*pb.AuthUserChangePasswordResponse, error) + UserGrantRole(ua *pb.AuthUserGrantRoleRequest) (*pb.AuthUserGrantRoleResponse, error) + UserGet(ua *pb.AuthUserGetRequest) (*pb.AuthUserGetResponse, error) + UserRevokeRole(ua *pb.AuthUserRevokeRoleRequest) (*pb.AuthUserRevokeRoleResponse, error) RoleAdd(ua *pb.AuthRoleAddRequest) (*pb.AuthRoleAddResponse, error) + RoleGrantPermission(ua *pb.AuthRoleGrantPermissionRequest) (*pb.AuthRoleGrantPermissionResponse, error) + RoleGet(ua *pb.AuthRoleGetRequest) (*pb.AuthRoleGetResponse, error) + RoleRevokePermission(ua *pb.AuthRoleRevokePermissionRequest) (*pb.AuthRoleRevokePermissionResponse, error) + RoleDelete(ua *pb.AuthRoleDeleteRequest) (*pb.AuthRoleDeleteResponse, error) + UserList(ua *pb.AuthUserListRequest) (*pb.AuthUserListResponse, error) + RoleList(ua *pb.AuthRoleListRequest) (*pb.AuthRoleListResponse, error) } type applierV3backend struct { s *EtcdServer } -func (s *EtcdServer) applyV3Request(r *pb.InternalRaftRequest) *applyResult { +func (s *EtcdServer) newApplierV3() applierV3 { + return newAuthApplierV3( + s.AuthStore(), + newQuotaApplierV3(s, &applierV3backend{s}), + ) +} + +func (a *applierV3backend) Apply(r *pb.InternalRaftRequest) *applyResult { ar := &applyResult{} + + // call into a.s.applyV3.F instead of a.F so upper appliers can check individual calls switch { case r.Range != nil: - ar.resp, ar.err = s.applyV3.Range(noTxn, r.Range) + ar.resp, ar.err = a.s.applyV3.Range(noTxn, r.Range) case r.Put != nil: - ar.resp, ar.err = s.applyV3.Put(noTxn, r.Put) + ar.resp, ar.err = a.s.applyV3.Put(noTxn, r.Put) case r.DeleteRange != nil: - ar.resp, ar.err = s.applyV3.DeleteRange(noTxn, r.DeleteRange) + ar.resp, ar.err = a.s.applyV3.DeleteRange(noTxn, r.DeleteRange) case r.Txn != nil: - ar.resp, ar.err = s.applyV3.Txn(r.Txn) + ar.resp, ar.err = a.s.applyV3.Txn(r.Txn) case r.Compaction != nil: - ar.resp, ar.physc, ar.err = s.applyV3.Compaction(r.Compaction) + ar.resp, ar.physc, ar.err = a.s.applyV3.Compaction(r.Compaction) case r.LeaseGrant != nil: - ar.resp, ar.err = s.applyV3.LeaseGrant(r.LeaseGrant) + ar.resp, ar.err = a.s.applyV3.LeaseGrant(r.LeaseGrant) case r.LeaseRevoke != nil: - ar.resp, ar.err = s.applyV3.LeaseRevoke(r.LeaseRevoke) + ar.resp, ar.err = a.s.applyV3.LeaseRevoke(r.LeaseRevoke) case r.Alarm != nil: - ar.resp, ar.err = s.applyV3.Alarm(r.Alarm) + ar.resp, ar.err = a.s.applyV3.Alarm(r.Alarm) + case r.Authenticate != nil: + ar.resp, ar.err = a.s.applyV3.Authenticate(r.Authenticate) case r.AuthEnable != nil: - ar.resp, ar.err = s.applyV3.AuthEnable() + ar.resp, ar.err = a.s.applyV3.AuthEnable() + case r.AuthDisable != nil: + ar.resp, ar.err = a.s.applyV3.AuthDisable() case r.AuthUserAdd != nil: - ar.resp, ar.err = s.applyV3.UserAdd(r.AuthUserAdd) + ar.resp, ar.err = a.s.applyV3.UserAdd(r.AuthUserAdd) case r.AuthUserDelete != nil: - ar.resp, ar.err = s.applyV3.UserDelete(r.AuthUserDelete) + ar.resp, ar.err = a.s.applyV3.UserDelete(r.AuthUserDelete) case r.AuthUserChangePassword != nil: - ar.resp, ar.err = s.applyV3.UserChangePassword(r.AuthUserChangePassword) + ar.resp, ar.err = a.s.applyV3.UserChangePassword(r.AuthUserChangePassword) + case r.AuthUserGrantRole != nil: + ar.resp, ar.err = a.s.applyV3.UserGrantRole(r.AuthUserGrantRole) + case r.AuthUserGet != nil: + ar.resp, ar.err = a.s.applyV3.UserGet(r.AuthUserGet) + case r.AuthUserRevokeRole != nil: + ar.resp, ar.err = a.s.applyV3.UserRevokeRole(r.AuthUserRevokeRole) case r.AuthRoleAdd != nil: - ar.resp, ar.err = s.applyV3.RoleAdd(r.AuthRoleAdd) + ar.resp, ar.err = a.s.applyV3.RoleAdd(r.AuthRoleAdd) + case r.AuthRoleGrantPermission != nil: + ar.resp, ar.err = a.s.applyV3.RoleGrantPermission(r.AuthRoleGrantPermission) + case r.AuthRoleGet != nil: + ar.resp, ar.err = a.s.applyV3.RoleGet(r.AuthRoleGet) + case r.AuthRoleRevokePermission != nil: + ar.resp, ar.err = a.s.applyV3.RoleRevokePermission(r.AuthRoleRevokePermission) + case r.AuthRoleDelete != nil: + ar.resp, ar.err = a.s.applyV3.RoleDelete(r.AuthRoleDelete) + case r.AuthUserList != nil: + ar.resp, ar.err = a.s.applyV3.UserList(r.AuthUserList) + case r.AuthRoleList != nil: + ar.resp, ar.err = a.s.applyV3.RoleList(r.AuthRoleList) default: panic("not implemented") } @@ -157,8 +210,7 @@ func (a *applierV3backend) Range(txnID int64, r *pb.RangeRequest) (*pb.RangeResp resp.Header = &pb.ResponseHeader{} var ( - kvs []storagepb.KeyValue - rev int64 + rr *mvcc.RangeResult err error ) @@ -176,13 +228,19 @@ func (a *applierV3backend) Range(txnID int64, r *pb.RangeRequest) (*pb.RangeResp limit = limit + 1 } + ro := mvcc.RangeOptions{ + Limit: limit, + Rev: r.Revision, + Count: r.CountOnly, + } + if txnID != noTxn { - kvs, rev, err = a.s.KV().TxnRange(txnID, r.Key, r.RangeEnd, limit, r.Revision) + rr, err = a.s.KV().TxnRange(txnID, r.Key, r.RangeEnd, ro) if err != nil { return nil, err } } else { - kvs, rev, err = a.s.KV().Range(r.Key, r.RangeEnd, limit, r.Revision) + rr, err = a.s.KV().Range(r.Key, r.RangeEnd, ro) if err != nil { return nil, err } @@ -192,15 +250,15 @@ func (a *applierV3backend) Range(txnID int64, r *pb.RangeRequest) (*pb.RangeResp var sorter sort.Interface switch { case r.SortTarget == pb.RangeRequest_KEY: - sorter = &kvSortByKey{&kvSort{kvs}} + sorter = &kvSortByKey{&kvSort{rr.KVs}} case r.SortTarget == pb.RangeRequest_VERSION: - sorter = &kvSortByVersion{&kvSort{kvs}} + sorter = &kvSortByVersion{&kvSort{rr.KVs}} case r.SortTarget == pb.RangeRequest_CREATE: - sorter = &kvSortByCreate{&kvSort{kvs}} + sorter = &kvSortByCreate{&kvSort{rr.KVs}} case r.SortTarget == pb.RangeRequest_MOD: - sorter = &kvSortByMod{&kvSort{kvs}} + sorter = &kvSortByMod{&kvSort{rr.KVs}} case r.SortTarget == pb.RangeRequest_VALUE: - sorter = &kvSortByValue{&kvSort{kvs}} + sorter = &kvSortByValue{&kvSort{rr.KVs}} } switch { case r.SortOrder == pb.RangeRequest_ASCEND: @@ -210,29 +268,31 @@ func (a *applierV3backend) Range(txnID int64, r *pb.RangeRequest) (*pb.RangeResp } } - if r.Limit > 0 && len(kvs) > int(r.Limit) { - kvs = kvs[:r.Limit] + if r.Limit > 0 && len(rr.KVs) > int(r.Limit) { + rr.KVs = rr.KVs[:r.Limit] resp.More = true } - resp.Header.Revision = rev - for i := range kvs { - resp.Kvs = append(resp.Kvs, &kvs[i]) + resp.Header.Revision = rr.Rev + resp.Count = int64(rr.Count) + for i := range rr.KVs { + if r.KeysOnly { + rr.KVs[i].Value = nil + } + resp.Kvs = append(resp.Kvs, &rr.KVs[i]) } return resp, nil } func (a *applierV3backend) Txn(rt *pb.TxnRequest) (*pb.TxnResponse, error) { - var revision int64 - ok := true for _, c := range rt.Compare { - if revision, ok = a.applyCompare(c); !ok { + if _, ok = a.applyCompare(c); !ok { break } } - var reqs []*pb.RequestUnion + var reqs []*pb.RequestOp if ok { reqs = rt.Success } else { @@ -246,6 +306,8 @@ 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() @@ -256,12 +318,16 @@ func (a *applierV3backend) Txn(rt *pb.TxnRequest) (*pb.TxnResponse, error) { } }() - resps := make([]*pb.ResponseUnion, len(reqs)) + 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 len(resps) != 0 { + if changedKV { revision += 1 } @@ -277,16 +343,18 @@ func (a *applierV3backend) Txn(rt *pb.TxnRequest) (*pb.TxnResponse, error) { // It returns the revision at which the comparison happens. If the comparison // succeeds, the it returns true. Otherwise it returns false. func (a *applierV3backend) applyCompare(c *pb.Compare) (int64, bool) { - ckvs, rev, err := a.s.KV().Range(c.Key, nil, 1, 0) + rr, err := a.s.KV().Range(c.Key, nil, mvcc.RangeOptions{}) + rev := rr.Rev + if err != nil { - if err == dstorage.ErrTxnIDMismatch { + if err == mvcc.ErrTxnIDMismatch { panic("unexpected txn ID mismatch error") } return rev, false } - var ckv storagepb.KeyValue - if len(ckvs) != 0 { - ckv = ckvs[0] + var ckv mvccpb.KeyValue + if len(rr.KVs) != 0 { + ckv = rr.KVs[0] } else { // Use the zero value of ckv normally. However... if c.Target == pb.Compare_VALUE { @@ -341,31 +409,31 @@ func (a *applierV3backend) applyCompare(c *pb.Compare) (int64, bool) { return rev, true } -func (a *applierV3backend) applyUnion(txnID int64, union *pb.RequestUnion) *pb.ResponseUnion { +func (a *applierV3backend) applyUnion(txnID int64, union *pb.RequestOp) *pb.ResponseOp { switch tv := union.Request.(type) { - case *pb.RequestUnion_RequestRange: + case *pb.RequestOp_RequestRange: if tv.RequestRange != nil { resp, err := a.Range(txnID, tv.RequestRange) if err != nil { panic("unexpected error during txn") } - return &pb.ResponseUnion{Response: &pb.ResponseUnion_ResponseRange{ResponseRange: resp}} + return &pb.ResponseOp{Response: &pb.ResponseOp_ResponseRange{ResponseRange: resp}} } - case *pb.RequestUnion_RequestPut: + case *pb.RequestOp_RequestPut: if tv.RequestPut != nil { resp, err := a.Put(txnID, tv.RequestPut) if err != nil { panic("unexpected error during txn") } - return &pb.ResponseUnion{Response: &pb.ResponseUnion_ResponsePut{ResponsePut: resp}} + return &pb.ResponseOp{Response: &pb.ResponseOp_ResponsePut{ResponsePut: resp}} } - case *pb.RequestUnion_RequestDeleteRange: + case *pb.RequestOp_RequestDeleteRange: if tv.RequestDeleteRange != nil { resp, err := a.DeleteRange(txnID, tv.RequestDeleteRange) if err != nil { panic("unexpected error during txn") } - return &pb.ResponseUnion{Response: &pb.ResponseUnion_ResponseDeleteRange{ResponseDeleteRange: resp}} + return &pb.ResponseOp{Response: &pb.ResponseOp_ResponseDeleteRange{ResponseDeleteRange: resp}} } default: // empty union @@ -383,7 +451,8 @@ func (a *applierV3backend) Compaction(compaction *pb.CompactionRequest) (*pb.Com return nil, ch, err } // get the current revision. which key to get is not important. - _, resp.Header.Revision, _ = a.s.KV().Range([]byte("compaction"), nil, 1, 0) + rr, _ := a.s.KV().Range([]byte("compaction"), nil, mvcc.RangeOptions{}) + resp.Header.Revision = rr.Rev return resp, ch, err } @@ -393,13 +462,15 @@ func (a *applierV3backend) LeaseGrant(lc *pb.LeaseGrantRequest) (*pb.LeaseGrantR if err == nil { resp.ID = int64(l.ID) resp.TTL = l.TTL + resp.Header = &pb.ResponseHeader{Revision: a.s.KV().Rev()} } + return resp, err } func (a *applierV3backend) LeaseRevoke(lc *pb.LeaseRevokeRequest) (*pb.LeaseRevokeResponse, error) { err := a.s.lessor.Revoke(lease.LeaseID(lc.ID)) - return &pb.LeaseRevokeResponse{}, err + return &pb.LeaseRevokeResponse{Header: &pb.ResponseHeader{Revision: a.s.KV().Rev()}}, err } func (a *applierV3backend) Alarm(ar *pb.AlarmRequest) (*pb.AlarmResponse, error) { @@ -441,7 +512,7 @@ func (a *applierV3backend) Alarm(ar *pb.AlarmRequest) (*pb.AlarmResponse, error) switch m.Alarm { case pb.AlarmType_NOSPACE: plog.Infof("alarm disarmed %+v", ar) - a.s.applyV3 = newQuotaApplierV3(a.s, &applierV3backend{a.s}) + a.s.applyV3 = a.s.newApplierV3() default: plog.Errorf("unimplemented alarm deactivation (%+v)", m) } @@ -476,10 +547,23 @@ func (a *applierV3Capped) LeaseGrant(lc *pb.LeaseGrantRequest) (*pb.LeaseGrantRe } func (a *applierV3backend) AuthEnable() (*pb.AuthEnableResponse, error) { - a.s.AuthStore().AuthEnable() + err := a.s.AuthStore().AuthEnable() + if err != nil { + return nil, err + } return &pb.AuthEnableResponse{}, nil } +func (a *applierV3backend) AuthDisable() (*pb.AuthDisableResponse, error) { + a.s.AuthStore().AuthDisable() + return &pb.AuthDisableResponse{}, nil +} + +func (a *applierV3backend) Authenticate(r *pb.InternalAuthenticateRequest) (*pb.AuthenticateResponse, error) { + ctx := context.WithValue(context.WithValue(context.TODO(), "index", a.s.consistIndex.ConsistentIndex()), "simpleToken", r.SimpleToken) + return a.s.AuthStore().Authenticate(ctx, r.Name, r.Password) +} + func (a *applierV3backend) UserAdd(r *pb.AuthUserAddRequest) (*pb.AuthUserAddResponse, error) { return a.s.AuthStore().UserAdd(r) } @@ -492,10 +576,46 @@ func (a *applierV3backend) UserChangePassword(r *pb.AuthUserChangePasswordReques return a.s.AuthStore().UserChangePassword(r) } +func (a *applierV3backend) UserGrantRole(r *pb.AuthUserGrantRoleRequest) (*pb.AuthUserGrantRoleResponse, error) { + return a.s.AuthStore().UserGrantRole(r) +} + +func (a *applierV3backend) UserGet(r *pb.AuthUserGetRequest) (*pb.AuthUserGetResponse, error) { + return a.s.AuthStore().UserGet(r) +} + +func (a *applierV3backend) UserRevokeRole(r *pb.AuthUserRevokeRoleRequest) (*pb.AuthUserRevokeRoleResponse, error) { + return a.s.AuthStore().UserRevokeRole(r) +} + func (a *applierV3backend) RoleAdd(r *pb.AuthRoleAddRequest) (*pb.AuthRoleAddResponse, error) { return a.s.AuthStore().RoleAdd(r) } +func (a *applierV3backend) RoleGrantPermission(r *pb.AuthRoleGrantPermissionRequest) (*pb.AuthRoleGrantPermissionResponse, error) { + return a.s.AuthStore().RoleGrantPermission(r) +} + +func (a *applierV3backend) RoleGet(r *pb.AuthRoleGetRequest) (*pb.AuthRoleGetResponse, error) { + return a.s.AuthStore().RoleGet(r) +} + +func (a *applierV3backend) RoleRevokePermission(r *pb.AuthRoleRevokePermissionRequest) (*pb.AuthRoleRevokePermissionResponse, error) { + return a.s.AuthStore().RoleRevokePermission(r) +} + +func (a *applierV3backend) RoleDelete(r *pb.AuthRoleDeleteRequest) (*pb.AuthRoleDeleteResponse, error) { + return a.s.AuthStore().RoleDelete(r) +} + +func (a *applierV3backend) UserList(r *pb.AuthUserListRequest) (*pb.AuthUserListResponse, error) { + return a.s.AuthStore().UserList(r) +} + +func (a *applierV3backend) RoleList(r *pb.AuthRoleListRequest) (*pb.AuthRoleListResponse, error) { + return a.s.AuthStore().RoleList(r) +} + type quotaApplierV3 struct { applierV3 q Quota @@ -532,7 +652,7 @@ func (a *quotaApplierV3) LeaseGrant(lc *pb.LeaseGrantRequest) (*pb.LeaseGrantRes return resp, err } -type kvSort struct{ kvs []storagepb.KeyValue } +type kvSort struct{ kvs []mvccpb.KeyValue } func (s *kvSort) Swap(i, j int) { t := s.kvs[i] @@ -571,9 +691,9 @@ func (s *kvSortByValue) Less(i, j int) bool { return bytes.Compare(s.kvs[i].Value, s.kvs[j].Value) < 0 } -func (a *applierV3backend) checkRequestLeases(reqs []*pb.RequestUnion) error { +func (a *applierV3backend) checkRequestLeases(reqs []*pb.RequestOp) error { for _, requ := range reqs { - tv, ok := requ.Request.(*pb.RequestUnion_RequestPut) + tv, ok := requ.Request.(*pb.RequestOp_RequestPut) if !ok { continue } @@ -588,9 +708,9 @@ func (a *applierV3backend) checkRequestLeases(reqs []*pb.RequestUnion) error { return nil } -func (a *applierV3backend) checkRequestRange(reqs []*pb.RequestUnion) error { +func (a *applierV3backend) checkRequestRange(reqs []*pb.RequestOp) error { for _, requ := range reqs { - tv, ok := requ.Request.(*pb.RequestUnion_RequestRange) + tv, ok := requ.Request.(*pb.RequestOp_RequestRange) if !ok { continue } @@ -600,10 +720,10 @@ func (a *applierV3backend) checkRequestRange(reqs []*pb.RequestUnion) error { } if greq.Revision > a.s.KV().Rev() { - return dstorage.ErrFutureRev + return mvcc.ErrFutureRev } if greq.Revision < a.s.KV().FirstRev() { - return dstorage.ErrCompacted + return mvcc.ErrCompacted } } return nil diff --git a/vendor/github.com/coreos/etcd/etcdserver/apply_auth.go b/vendor/github.com/coreos/etcd/etcdserver/apply_auth.go new file mode 100644 index 00000000000..1a45788950e --- /dev/null +++ b/vendor/github.com/coreos/etcd/etcdserver/apply_auth.go @@ -0,0 +1,163 @@ +// 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 etcdserver + +import ( + "sync" + + "github.com/coreos/etcd/auth" + pb "github.com/coreos/etcd/etcdserver/etcdserverpb" +) + +type authApplierV3 struct { + applierV3 + as auth.AuthStore + + // 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 +} + +func newAuthApplierV3(as auth.AuthStore, base applierV3) *authApplierV3 { + return &authApplierV3{applierV3: base, as: as} +} + +func (aa *authApplierV3) Apply(r *pb.InternalRaftRequest) *applyResult { + aa.mu.Lock() + defer aa.mu.Unlock() + if r.Header != nil { + // backward-compatible with pre-3.0 releases when internalRaftRequest + // does not have header field + aa.user = r.Header.Username + } + if needAdminPermission(r) && !aa.as.IsAdminPermitted(aa.user) { + aa.user = "" + return &applyResult{err: auth.ErrPermissionDenied} + } + ret := aa.applierV3.Apply(r) + aa.user = "" + 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 + } + 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 + } + 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 + } + return aa.applierV3.DeleteRange(txnID, r) +} + +func (aa *authApplierV3) checkTxnReqsPermission(reqs []*pb.RequestOp) bool { + for _, requ := range reqs { + switch tv := requ.Request.(type) { + case *pb.RequestOp_RequestRange: + if tv.RequestRange == nil { + continue + } + + if !aa.as.IsRangePermitted(aa.user, tv.RequestRange.Key, tv.RequestRange.RangeEnd) { + return false + } + + case *pb.RequestOp_RequestPut: + if tv.RequestPut == nil { + continue + } + + if !aa.as.IsPutPermitted(aa.user, tv.RequestPut.Key) { + return false + } + + case *pb.RequestOp_RequestDeleteRange: + if tv.RequestDeleteRange == nil { + continue + } + + if !aa.as.IsDeleteRangePermitted(aa.user, tv.RequestDeleteRange.Key, tv.RequestDeleteRange.RangeEnd) { + return false + } + } + } + + return true +} + +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 !aa.checkTxnReqsPermission(rt.Success) { + return nil, auth.ErrPermissionDenied + } + if !aa.checkTxnReqsPermission(rt.Failure) { + return nil, auth.ErrPermissionDenied + } + + return aa.applierV3.Txn(rt) +} + +func needAdminPermission(r *pb.InternalRaftRequest) bool { + switch { + case r.AuthEnable != nil: + return true + case r.AuthDisable != nil: + return true + case r.AuthUserAdd != nil: + return true + case r.AuthUserDelete != nil: + return true + case r.AuthUserChangePassword != nil: + return true + case r.AuthUserGrantRole != nil: + return true + case r.AuthUserGet != nil: + return true + case r.AuthUserRevokeRole != nil: + return true + case r.AuthRoleAdd != nil: + return true + case r.AuthRoleGrantPermission != nil: + return true + case r.AuthRoleGet != nil: + return true + case r.AuthRoleRevokePermission != nil: + return true + case r.AuthRoleDelete != nil: + return true + case r.AuthUserList != nil: + return true + case r.AuthRoleList != nil: + return true + default: + return false + } +} diff --git a/vendor/github.com/coreos/etcd/etcdserver/apply_v2.go b/vendor/github.com/coreos/etcd/etcdserver/apply_v2.go new file mode 100644 index 00000000000..f278efca88e --- /dev/null +++ b/vendor/github.com/coreos/etcd/etcdserver/apply_v2.go @@ -0,0 +1,140 @@ +// 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 etcdserver + +import ( + "encoding/json" + "path" + "time" + + "github.com/coreos/etcd/etcdserver/api" + pb "github.com/coreos/etcd/etcdserver/etcdserverpb" + "github.com/coreos/etcd/etcdserver/membership" + "github.com/coreos/etcd/pkg/pbutil" + "github.com/coreos/etcd/store" + "github.com/coreos/go-semver/semver" +) + +// ApplierV2 is the interface for processing V2 raft messages +type ApplierV2 interface { + Delete(r *pb.Request) Response + Post(r *pb.Request) Response + Put(r *pb.Request) Response + QGet(r *pb.Request) Response + Sync(r *pb.Request) Response +} + +func NewApplierV2(s store.Store, c *membership.RaftCluster) ApplierV2 { + return &applierV2store{store: s, cluster: c} +} + +type applierV2store struct { + store store.Store + cluster *membership.RaftCluster +} + +func (a *applierV2store) Delete(r *pb.Request) Response { + switch { + case r.PrevIndex > 0 || r.PrevValue != "": + return toResponse(a.store.CompareAndDelete(r.Path, r.PrevValue, r.PrevIndex)) + default: + return toResponse(a.store.Delete(r.Path, r.Dir, r.Recursive)) + } +} + +func (a *applierV2store) Post(r *pb.Request) Response { + return toResponse(a.store.Create(r.Path, r.Dir, r.Val, true, toTTLOptions(r))) +} + +func (a *applierV2store) Put(r *pb.Request) Response { + ttlOptions := toTTLOptions(r) + exists, existsSet := pbutil.GetBool(r.PrevExist) + switch { + case existsSet: + if exists { + if r.PrevIndex == 0 && r.PrevValue == "" { + return toResponse(a.store.Update(r.Path, r.Val, ttlOptions)) + } + return toResponse(a.store.CompareAndSwap(r.Path, r.PrevValue, r.PrevIndex, r.Val, ttlOptions)) + } + return toResponse(a.store.Create(r.Path, r.Dir, r.Val, false, ttlOptions)) + case r.PrevIndex > 0 || r.PrevValue != "": + return toResponse(a.store.CompareAndSwap(r.Path, r.PrevValue, r.PrevIndex, r.Val, ttlOptions)) + default: + if storeMemberAttributeRegexp.MatchString(r.Path) { + id := membership.MustParseMemberIDFromKey(path.Dir(r.Path)) + var attr membership.Attributes + if err := json.Unmarshal([]byte(r.Val), &attr); err != nil { + plog.Panicf("unmarshal %s should never fail: %v", r.Val, err) + } + if a.cluster != nil { + a.cluster.UpdateAttributes(id, attr) + } + // return an empty response since there is no consumer. + return Response{} + } + if r.Path == membership.StoreClusterVersionKey() { + if a.cluster != nil { + a.cluster.SetVersion(semver.Must(semver.NewVersion(r.Val)), api.UpdateCapability) + } + // return an empty response since there is no consumer. + return Response{} + } + return toResponse(a.store.Set(r.Path, r.Dir, r.Val, ttlOptions)) + } +} + +func (a *applierV2store) QGet(r *pb.Request) Response { + return toResponse(a.store.Get(r.Path, r.Recursive, r.Sorted)) +} + +func (a *applierV2store) Sync(r *pb.Request) Response { + a.store.DeleteExpiredKeys(time.Unix(0, r.Time)) + return Response{} +} + +// applyV2Request interprets r as a call to store.X and returns a Response interpreted +// from store.Event +func (s *EtcdServer) applyV2Request(r *pb.Request) Response { + toTTLOptions(r) + switch r.Method { + case "POST": + return s.applyV2.Post(r) + case "PUT": + return s.applyV2.Put(r) + case "DELETE": + return s.applyV2.Delete(r) + case "QGET": + return s.applyV2.QGet(r) + case "SYNC": + return s.applyV2.Sync(r) + default: + // This should never be reached, but just in case: + return Response{err: ErrUnknownMethod} + } +} + +func toTTLOptions(r *pb.Request) store.TTLOptionSet { + refresh, _ := pbutil.GetBool(r.Refresh) + ttlOptions := store.TTLOptionSet{Refresh: refresh} + if r.Expiration != 0 { + ttlOptions.ExpireTime = time.Unix(0, r.Expiration) + } + return ttlOptions +} + +func toResponse(ev *store.Event, err error) Response { + return Response{Event: ev, err: err} +} diff --git a/vendor/github.com/coreos/etcd/etcdserver/auth/auth.go b/vendor/github.com/coreos/etcd/etcdserver/auth/auth.go index 94922b76716..d747ba0fc74 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/auth/auth.go +++ b/vendor/github.com/coreos/etcd/etcdserver/auth/auth.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. @@ -281,13 +281,7 @@ func (s *store) UpdateUser(user User) (User, error) { return old, err } - hash, err := s.HashPassword(user.Password) - if err != nil { - return old, err - } - user.Password = hash - - newUser, err := old.merge(user) + newUser, err := old.merge(user, s.PasswordStore) if err != nil { return old, err } @@ -335,11 +329,7 @@ func (s *store) GetRole(name string) (Role, error) { } var r Role err = json.Unmarshal([]byte(*resp.Event.Node.Value), &r) - if err != nil { - return r, err - } - - return r, nil + return r, err } func (s *store) CreateRole(role Role) error { @@ -452,29 +442,33 @@ func (s *store) DisableAuth() error { // is called and returns a new User with these modifications applied. Think of // all Users as immutable sets of data. Merge allows you to perform the set // operations (desired grants and revokes) atomically -func (u User) merge(n User) (User, error) { +func (ou User) merge(nu User, s PasswordStore) (User, error) { var out User - if u.User != n.User { - return out, authErr(http.StatusConflict, "Merging user data with conflicting usernames: %s %s", u.User, n.User) + if ou.User != nu.User { + return out, authErr(http.StatusConflict, "Merging user data with conflicting usernames: %s %s", ou.User, nu.User) } - out.User = u.User - if n.Password != "" { - out.Password = n.Password + out.User = ou.User + if nu.Password != "" { + hash, err := s.HashPassword(nu.Password) + if err != nil { + return ou, err + } + out.Password = hash } else { - out.Password = u.Password + out.Password = ou.Password } - currentRoles := types.NewUnsafeSet(u.Roles...) - for _, g := range n.Grant { + currentRoles := types.NewUnsafeSet(ou.Roles...) + for _, g := range nu.Grant { if currentRoles.Contains(g) { - plog.Noticef("granting duplicate role %s for user %s", g, n.User) - return User{}, authErr(http.StatusConflict, fmt.Sprintf("Granting duplicate role %s for user %s", g, n.User)) + plog.Noticef("granting duplicate role %s for user %s", g, nu.User) + return User{}, authErr(http.StatusConflict, fmt.Sprintf("Granting duplicate role %s for user %s", g, nu.User)) } currentRoles.Add(g) } - for _, r := range n.Revoke { + for _, r := range nu.Revoke { if !currentRoles.Contains(r) { - plog.Noticef("revoking ungranted role %s for user %s", r, n.User) - return User{}, authErr(http.StatusConflict, fmt.Sprintf("Revoking ungranted role %s for user %s", r, n.User)) + plog.Noticef("revoking ungranted role %s for user %s", r, nu.User) + return User{}, authErr(http.StatusConflict, fmt.Sprintf("Revoking ungranted role %s for user %s", r, nu.User)) } currentRoles.Remove(r) } @@ -497,10 +491,7 @@ func (r Role) merge(n Role) (Role, error) { return out, err } out.Permissions, err = out.Permissions.Revoke(n.Revoke) - if err != nil { - return out, err - } - return out, nil + return out, err } func (r Role) HasKeyAccess(key string, write bool) bool { 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 0761121d747..36bed20d07f 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/auth/auth_requests.go +++ b/vendor/github.com/coreos/etcd/etcdserver/auth/auth_requests.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. diff --git a/vendor/github.com/coreos/etcd/etcdserver/cluster_util.go b/vendor/github.com/coreos/etcd/etcdserver/cluster_util.go index cd456f92e03..e70f104a25d 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/cluster_util.go +++ b/vendor/github.com/coreos/etcd/etcdserver/cluster_util.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. @@ -73,6 +73,7 @@ func getClusterFromRemotePeers(urls []string, timeout time.Duration, logerr bool continue } b, err := ioutil.ReadAll(resp.Body) + resp.Body.Close() if err != nil { if logerr { plog.Warningf("could not read the body of cluster response: %v", err) diff --git a/vendor/github.com/coreos/etcd/etcdserver/config.go b/vendor/github.com/coreos/etcd/etcdserver/config.go index 3fc8eea3eff..b66a63323d7 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/config.go +++ b/vendor/github.com/coreos/etcd/etcdserver/config.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. @@ -56,6 +56,9 @@ type ServerConfig struct { StrictReconfigCheck bool EnablePprof bool + + // ClientCertAuthEnabled is true when cert has been signed by the client CA. + ClientCertAuthEnabled bool } // VerifyBootstrap sanity-checks the initial config for bootstrap case diff --git a/vendor/github.com/coreos/etcd/etcdserver/consistent_index.go b/vendor/github.com/coreos/etcd/etcdserver/consistent_index.go index e631266929d..d513f6708d3 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/consistent_index.go +++ b/vendor/github.com/coreos/etcd/etcdserver/consistent_index.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. @@ -14,12 +14,20 @@ package etcdserver +import ( + "sync/atomic" +) + // consistentIndex represents the offset of an entry in a consistent replica log. -// It implements the storage.ConsistentIndexGetter interface. +// It implements the mvcc.ConsistentIndexGetter interface. // It is always set to the offset of current entry before executing the entry, // so ConsistentWatchableKV could get the consistent index from it. type consistentIndex uint64 -func (i *consistentIndex) setConsistentIndex(v uint64) { *i = consistentIndex(v) } +func (i *consistentIndex) setConsistentIndex(v uint64) { + atomic.StoreUint64((*uint64)(i), v) +} -func (i *consistentIndex) ConsistentIndex() uint64 { return uint64(*i) } +func (i *consistentIndex) ConsistentIndex() uint64 { + return atomic.LoadUint64((*uint64)(i)) +} diff --git a/vendor/github.com/coreos/etcd/etcdserver/doc.go b/vendor/github.com/coreos/etcd/etcdserver/doc.go index a444d528db5..b195d2d167a 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/doc.go +++ b/vendor/github.com/coreos/etcd/etcdserver/doc.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. diff --git a/vendor/github.com/coreos/etcd/etcdserver/errors.go b/vendor/github.com/coreos/etcd/etcdserver/errors.go index 6731c117e44..1b9789fc827 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/errors.go +++ b/vendor/github.com/coreos/etcd/etcdserver/errors.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. @@ -30,6 +30,7 @@ var ( 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") ) 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 6ab9804c621..746e9a116a0 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/etcdserverpb/etcdserver.pb.go +++ b/vendor/github.com/coreos/etcd/etcdserver/etcdserverpb/etcdserver.pb.go @@ -13,8 +13,10 @@ It has these top-level messages: Request Metadata + RequestHeader InternalRaftRequest EmptyResponse + InternalAuthenticateRequest ResponseHeader RangeRequest RangeResponse @@ -22,8 +24,8 @@ PutResponse DeleteRangeRequest DeleteRangeResponse - RequestUnion - ResponseUnion + RequestOp + ResponseOp Compare TxnRequest TxnResponse @@ -31,6 +33,8 @@ CompactionResponse HashRequest HashResponse + SnapshotRequest + SnapshotResponse WatchRequest WatchCreateRequest WatchCancelRequest @@ -64,13 +68,15 @@ AuthUserGetRequest AuthUserDeleteRequest AuthUserChangePasswordRequest - AuthUserGrantRequest - AuthUserRevokeRequest + AuthUserGrantRoleRequest + AuthUserRevokeRoleRequest AuthRoleAddRequest AuthRoleGetRequest + AuthUserListRequest + AuthRoleListRequest AuthRoleDeleteRequest - AuthRoleGrantRequest - AuthRoleRevokeRequest + AuthRoleGrantPermissionRequest + AuthRoleRevokePermissionRequest AuthEnableResponse AuthDisableResponse AuthenticateResponse @@ -78,20 +84,22 @@ AuthUserGetResponse AuthUserDeleteResponse AuthUserChangePasswordResponse - AuthUserGrantResponse - AuthUserRevokeResponse + AuthUserGrantRoleResponse + AuthUserRevokeRoleResponse AuthRoleAddResponse AuthRoleGetResponse + AuthRoleListResponse + AuthUserListResponse AuthRoleDeleteResponse - AuthRoleGrantResponse - AuthRoleRevokeResponse + AuthRoleGrantPermissionResponse + AuthRoleRevokePermissionResponse */ package etcdserverpb import ( "fmt" - proto "github.com/gogo/protobuf/proto" + proto "github.com/golang/protobuf/proto" math "math" ) @@ -103,40 +111,46 @@ var _ = proto.Marshal var _ = fmt.Errorf 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 + type Request struct { - 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"` + 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"` XXX_unrecognized []byte `json:"-"` } -func (m *Request) Reset() { *m = Request{} } -func (m *Request) String() string { return proto.CompactTextString(m) } -func (*Request) ProtoMessage() {} +func (m *Request) Reset() { *m = Request{} } +func (m *Request) String() string { return proto.CompactTextString(m) } +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"` - ClusterID uint64 `protobuf:"varint,2,opt,name=ClusterID" json:"ClusterID"` + NodeID uint64 `protobuf:"varint,1,opt,name=NodeID,json=nodeID" json:"NodeID"` + ClusterID uint64 `protobuf:"varint,2,opt,name=ClusterID,json=clusterID" json:"ClusterID"` XXX_unrecognized []byte `json:"-"` } -func (m *Metadata) Reset() { *m = Metadata{} } -func (m *Metadata) String() string { return proto.CompactTextString(m) } -func (*Metadata) ProtoMessage() {} +func (m *Metadata) Reset() { *m = Metadata{} } +func (m *Metadata) String() string { return proto.CompactTextString(m) } +func (*Metadata) ProtoMessage() {} +func (*Metadata) Descriptor() ([]byte, []int) { return fileDescriptorEtcdserver, []int{1} } func init() { proto.RegisterType((*Request)(nil), "etcdserverpb.Request") @@ -995,3 +1009,33 @@ var ( ErrInvalidLengthEtcdserver = fmt.Errorf("proto: negative length found during unmarshaling") ErrIntOverflowEtcdserver = fmt.Errorf("proto: integer overflow") ) + +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, +} 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 4c66129d785..068aefff0b9 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 @@ -7,7 +7,7 @@ package etcdserverpb import ( "fmt" - proto "github.com/gogo/protobuf/proto" + proto "github.com/golang/protobuf/proto" math "math" ) @@ -19,41 +19,114 @@ var _ = proto.Marshal var _ = fmt.Errorf var _ = math.Inf +type RequestHeader struct { + ID uint64 `protobuf:"varint,1,opt,name=ID,json=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"` +} + +func (m *RequestHeader) Reset() { *m = RequestHeader{} } +func (m *RequestHeader) String() string { return proto.CompactTextString(m) } +func (*RequestHeader) ProtoMessage() {} +func (*RequestHeader) Descriptor() ([]byte, []int) { return fileDescriptorRaftInternal, []int{0} } + // An InternalRaftRequest is the union of all requests which can be // sent via raft. type InternalRaftRequest struct { - 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"` - DeleteRange *DeleteRangeRequest `protobuf:"bytes,5,opt,name=delete_range" json:"delete_range,omitempty"` - Txn *TxnRequest `protobuf:"bytes,6,opt,name=txn" json:"txn,omitempty"` - Compaction *CompactionRequest `protobuf:"bytes,7,opt,name=compaction" json:"compaction,omitempty"` - LeaseGrant *LeaseGrantRequest `protobuf:"bytes,8,opt,name=lease_grant" json:"lease_grant,omitempty"` - LeaseRevoke *LeaseRevokeRequest `protobuf:"bytes,9,opt,name=lease_revoke" json:"lease_revoke,omitempty"` - AuthEnable *AuthEnableRequest `protobuf:"bytes,10,opt,name=auth_enable" json:"auth_enable,omitempty"` - AuthUserAdd *AuthUserAddRequest `protobuf:"bytes,11,opt,name=auth_user_add" json:"auth_user_add,omitempty"` - AuthUserDelete *AuthUserDeleteRequest `protobuf:"bytes,12,opt,name=auth_user_delete" json:"auth_user_delete,omitempty"` - AuthUserChangePassword *AuthUserChangePasswordRequest `protobuf:"bytes,13,opt,name=auth_user_change_password" json:"auth_user_change_password,omitempty"` - AuthRoleAdd *AuthRoleAddRequest `protobuf:"bytes,14,opt,name=auth_role_add" json:"auth_role_add,omitempty"` - Alarm *AlarmRequest `protobuf:"bytes,15,opt,name=alarm" json:"alarm,omitempty"` + 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"` + 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"` + DeleteRange *DeleteRangeRequest `protobuf:"bytes,5,opt,name=delete_range,json=deleteRange" json:"delete_range,omitempty"` + Txn *TxnRequest `protobuf:"bytes,6,opt,name=txn" json:"txn,omitempty"` + Compaction *CompactionRequest `protobuf:"bytes,7,opt,name=compaction" json:"compaction,omitempty"` + LeaseGrant *LeaseGrantRequest `protobuf:"bytes,8,opt,name=lease_grant,json=leaseGrant" json:"lease_grant,omitempty"` + LeaseRevoke *LeaseRevokeRequest `protobuf:"bytes,9,opt,name=lease_revoke,json=leaseRevoke" json:"lease_revoke,omitempty"` + Alarm *AlarmRequest `protobuf:"bytes,10,opt,name=alarm" json:"alarm,omitempty"` + AuthEnable *AuthEnableRequest `protobuf:"bytes,1000,opt,name=auth_enable,json=authEnable" json:"auth_enable,omitempty"` + AuthDisable *AuthDisableRequest `protobuf:"bytes,1011,opt,name=auth_disable,json=authDisable" json:"auth_disable,omitempty"` + Authenticate *InternalAuthenticateRequest `protobuf:"bytes,1012,opt,name=authenticate" json:"authenticate,omitempty"` + AuthUserAdd *AuthUserAddRequest `protobuf:"bytes,1100,opt,name=auth_user_add,json=authUserAdd" json:"auth_user_add,omitempty"` + AuthUserDelete *AuthUserDeleteRequest `protobuf:"bytes,1101,opt,name=auth_user_delete,json=authUserDelete" json:"auth_user_delete,omitempty"` + AuthUserGet *AuthUserGetRequest `protobuf:"bytes,1102,opt,name=auth_user_get,json=authUserGet" json:"auth_user_get,omitempty"` + AuthUserChangePassword *AuthUserChangePasswordRequest `protobuf:"bytes,1103,opt,name=auth_user_change_password,json=authUserChangePassword" json:"auth_user_change_password,omitempty"` + AuthUserGrantRole *AuthUserGrantRoleRequest `protobuf:"bytes,1104,opt,name=auth_user_grant_role,json=authUserGrantRole" json:"auth_user_grant_role,omitempty"` + AuthUserRevokeRole *AuthUserRevokeRoleRequest `protobuf:"bytes,1105,opt,name=auth_user_revoke_role,json=authUserRevokeRole" json:"auth_user_revoke_role,omitempty"` + AuthUserList *AuthUserListRequest `protobuf:"bytes,1106,opt,name=auth_user_list,json=authUserList" json:"auth_user_list,omitempty"` + AuthRoleList *AuthRoleListRequest `protobuf:"bytes,1107,opt,name=auth_role_list,json=authRoleList" json:"auth_role_list,omitempty"` + AuthRoleAdd *AuthRoleAddRequest `protobuf:"bytes,1200,opt,name=auth_role_add,json=authRoleAdd" json:"auth_role_add,omitempty"` + AuthRoleDelete *AuthRoleDeleteRequest `protobuf:"bytes,1201,opt,name=auth_role_delete,json=authRoleDelete" json:"auth_role_delete,omitempty"` + AuthRoleGet *AuthRoleGetRequest `protobuf:"bytes,1202,opt,name=auth_role_get,json=authRoleGet" json:"auth_role_get,omitempty"` + AuthRoleGrantPermission *AuthRoleGrantPermissionRequest `protobuf:"bytes,1203,opt,name=auth_role_grant_permission,json=authRoleGrantPermission" json:"auth_role_grant_permission,omitempty"` + AuthRoleRevokePermission *AuthRoleRevokePermissionRequest `protobuf:"bytes,1204,opt,name=auth_role_revoke_permission,json=authRoleRevokePermission" json:"auth_role_revoke_permission,omitempty"` } -func (m *InternalRaftRequest) Reset() { *m = InternalRaftRequest{} } -func (m *InternalRaftRequest) String() string { return proto.CompactTextString(m) } -func (*InternalRaftRequest) ProtoMessage() {} +func (m *InternalRaftRequest) Reset() { *m = InternalRaftRequest{} } +func (m *InternalRaftRequest) String() string { return proto.CompactTextString(m) } +func (*InternalRaftRequest) ProtoMessage() {} +func (*InternalRaftRequest) Descriptor() ([]byte, []int) { return fileDescriptorRaftInternal, []int{1} } type EmptyResponse struct { } -func (m *EmptyResponse) Reset() { *m = EmptyResponse{} } -func (m *EmptyResponse) String() string { return proto.CompactTextString(m) } -func (*EmptyResponse) ProtoMessage() {} +func (m *EmptyResponse) Reset() { *m = EmptyResponse{} } +func (m *EmptyResponse) String() string { return proto.CompactTextString(m) } +func (*EmptyResponse) ProtoMessage() {} +func (*EmptyResponse) Descriptor() ([]byte, []int) { return fileDescriptorRaftInternal, []int{2} } + +// What is the difference between AuthenticateRequest (defined in rpc.proto) and InternalAuthenticateRequest? +// InternalAuthenticateRequest has a member that is filled by etcdserver and shouldn't be user-facing. +// For avoiding misusage the field, we have an internal version of AuthenticateRequest. +type InternalAuthenticateRequest struct { + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Password string `protobuf:"bytes,2,opt,name=password,proto3" json:"password,omitempty"` + // simple_token is generated in API layer (etcdserver/v3_server.go) + SimpleToken string `protobuf:"bytes,3,opt,name=simple_token,json=simpleToken,proto3" json:"simple_token,omitempty"` +} + +func (m *InternalAuthenticateRequest) Reset() { *m = InternalAuthenticateRequest{} } +func (m *InternalAuthenticateRequest) String() string { return proto.CompactTextString(m) } +func (*InternalAuthenticateRequest) ProtoMessage() {} +func (*InternalAuthenticateRequest) Descriptor() ([]byte, []int) { + return fileDescriptorRaftInternal, []int{3} +} func init() { + proto.RegisterType((*RequestHeader)(nil), "etcdserverpb.RequestHeader") proto.RegisterType((*InternalRaftRequest)(nil), "etcdserverpb.InternalRaftRequest") proto.RegisterType((*EmptyResponse)(nil), "etcdserverpb.EmptyResponse") + proto.RegisterType((*InternalAuthenticateRequest)(nil), "etcdserverpb.InternalAuthenticateRequest") } +func (m *RequestHeader) 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 *RequestHeader) MarshalTo(data []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.ID != 0 { + data[i] = 0x8 + i++ + i = encodeVarintRaftInternal(data, i, uint64(m.ID)) + } + if len(m.Username) > 0 { + data[i] = 0x12 + i++ + i = encodeVarintRaftInternal(data, i, uint64(len(m.Username))) + i += copy(data[i:], m.Username) + } + return i, nil +} + func (m *InternalRaftRequest) Marshal() (data []byte, err error) { size := m.Size() data = make([]byte, size) @@ -154,66 +227,220 @@ func (m *InternalRaftRequest) MarshalTo(data []byte) (int, error) { } i += n8 } - if m.AuthEnable != nil { + if m.Alarm != nil { data[i] = 0x52 i++ - i = encodeVarintRaftInternal(data, i, uint64(m.AuthEnable.Size())) - n9, err := m.AuthEnable.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.AuthUserAdd != nil { - data[i] = 0x5a + if m.Header != nil { + data[i] = 0xa2 i++ - i = encodeVarintRaftInternal(data, i, uint64(m.AuthUserAdd.Size())) - n10, err := m.AuthUserAdd.MarshalTo(data[i:]) + data[i] = 0x6 + 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.AuthUserDelete != nil { - data[i] = 0x62 + if m.AuthEnable != nil { + data[i] = 0xc2 i++ - i = encodeVarintRaftInternal(data, i, uint64(m.AuthUserDelete.Size())) - n11, err := m.AuthUserDelete.MarshalTo(data[i:]) + data[i] = 0x3e + 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.AuthUserChangePassword != nil { - data[i] = 0x6a + if m.AuthDisable != nil { + data[i] = 0x9a i++ - i = encodeVarintRaftInternal(data, i, uint64(m.AuthUserChangePassword.Size())) - n12, err := m.AuthUserChangePassword.MarshalTo(data[i:]) + data[i] = 0x3f + 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.AuthRoleAdd != nil { - data[i] = 0x72 + if m.Authenticate != nil { + data[i] = 0xa2 i++ - i = encodeVarintRaftInternal(data, i, uint64(m.AuthRoleAdd.Size())) - n13, err := m.AuthRoleAdd.MarshalTo(data[i:]) + data[i] = 0x3f + 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.Alarm != nil { - data[i] = 0x7a + if m.AuthUserAdd != nil { + data[i] = 0xe2 i++ - i = encodeVarintRaftInternal(data, i, uint64(m.Alarm.Size())) - n14, err := m.Alarm.MarshalTo(data[i:]) + data[i] = 0x44 + 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 + i++ + data[i] = 0x44 + 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 + i++ + data[i] = 0x44 + 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 + i++ + data[i] = 0x44 + 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 + i++ + data[i] = 0x45 + 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 + i++ + data[i] = 0x45 + 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 + i++ + data[i] = 0x45 + 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 + i++ + data[i] = 0x45 + 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 + i++ + data[i] = 0x4b + 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 + i++ + data[i] = 0x4b + 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 + i++ + data[i] = 0x4b + 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 + i++ + data[i] = 0x4b + 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 + i++ + data[i] = 0x4b + i++ + i = encodeVarintRaftInternal(data, i, uint64(m.AuthRoleRevokePermission.Size())) + n26, err := m.AuthRoleRevokePermission.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += n26 + } return i, nil } @@ -235,6 +462,42 @@ func (m *EmptyResponse) MarshalTo(data []byte) (int, error) { return i, nil } +func (m *InternalAuthenticateRequest) 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 *InternalAuthenticateRequest) MarshalTo(data []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Name) > 0 { + data[i] = 0xa + i++ + i = encodeVarintRaftInternal(data, i, uint64(len(m.Name))) + i += copy(data[i:], m.Name) + } + if len(m.Password) > 0 { + data[i] = 0x12 + i++ + i = encodeVarintRaftInternal(data, i, uint64(len(m.Password))) + i += copy(data[i:], m.Password) + } + if len(m.SimpleToken) > 0 { + data[i] = 0x1a + i++ + 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) @@ -262,6 +525,19 @@ func encodeVarintRaftInternal(data []byte, offset int, v uint64) int { data[offset] = uint8(v) return offset + 1 } +func (m *RequestHeader) Size() (n int) { + var l int + _ = l + if m.ID != 0 { + n += 1 + sovRaftInternal(uint64(m.ID)) + } + l = len(m.Username) + if l > 0 { + n += 1 + l + sovRaftInternal(uint64(l)) + } + return n +} + func (m *InternalRaftRequest) Size() (n int) { var l int _ = l @@ -300,30 +576,78 @@ func (m *InternalRaftRequest) Size() (n int) { l = m.LeaseRevoke.Size() n += 1 + l + sovRaftInternal(uint64(l)) } - if m.AuthEnable != nil { - l = m.AuthEnable.Size() - n += 1 + l + sovRaftInternal(uint64(l)) - } - if m.AuthUserAdd != nil { - l = m.AuthUserAdd.Size() - n += 1 + l + sovRaftInternal(uint64(l)) - } - if m.AuthUserDelete != nil { - l = m.AuthUserDelete.Size() - n += 1 + l + sovRaftInternal(uint64(l)) - } - if m.AuthUserChangePassword != nil { - l = m.AuthUserChangePassword.Size() - n += 1 + l + sovRaftInternal(uint64(l)) - } - if m.AuthRoleAdd != nil { - l = m.AuthRoleAdd.Size() - n += 1 + l + sovRaftInternal(uint64(l)) - } if m.Alarm != nil { l = m.Alarm.Size() n += 1 + l + sovRaftInternal(uint64(l)) } + if m.Header != nil { + l = m.Header.Size() + n += 2 + l + sovRaftInternal(uint64(l)) + } + if m.AuthEnable != nil { + l = m.AuthEnable.Size() + n += 2 + l + sovRaftInternal(uint64(l)) + } + if m.AuthDisable != nil { + l = m.AuthDisable.Size() + n += 2 + l + sovRaftInternal(uint64(l)) + } + if m.Authenticate != nil { + l = m.Authenticate.Size() + n += 2 + l + sovRaftInternal(uint64(l)) + } + if m.AuthUserAdd != nil { + l = m.AuthUserAdd.Size() + n += 2 + l + sovRaftInternal(uint64(l)) + } + if m.AuthUserDelete != nil { + l = m.AuthUserDelete.Size() + n += 2 + l + sovRaftInternal(uint64(l)) + } + if m.AuthUserGet != nil { + l = m.AuthUserGet.Size() + n += 2 + l + sovRaftInternal(uint64(l)) + } + if m.AuthUserChangePassword != nil { + l = m.AuthUserChangePassword.Size() + n += 2 + l + sovRaftInternal(uint64(l)) + } + if m.AuthUserGrantRole != nil { + l = m.AuthUserGrantRole.Size() + n += 2 + l + sovRaftInternal(uint64(l)) + } + if m.AuthUserRevokeRole != nil { + l = m.AuthUserRevokeRole.Size() + n += 2 + l + sovRaftInternal(uint64(l)) + } + if m.AuthUserList != nil { + l = m.AuthUserList.Size() + n += 2 + l + sovRaftInternal(uint64(l)) + } + if m.AuthRoleList != nil { + l = m.AuthRoleList.Size() + n += 2 + l + sovRaftInternal(uint64(l)) + } + if m.AuthRoleAdd != nil { + l = m.AuthRoleAdd.Size() + n += 2 + l + sovRaftInternal(uint64(l)) + } + if m.AuthRoleDelete != nil { + l = m.AuthRoleDelete.Size() + n += 2 + l + sovRaftInternal(uint64(l)) + } + if m.AuthRoleGet != nil { + l = m.AuthRoleGet.Size() + n += 2 + l + sovRaftInternal(uint64(l)) + } + if m.AuthRoleGrantPermission != nil { + l = m.AuthRoleGrantPermission.Size() + n += 2 + l + sovRaftInternal(uint64(l)) + } + if m.AuthRoleRevokePermission != nil { + l = m.AuthRoleRevokePermission.Size() + n += 2 + l + sovRaftInternal(uint64(l)) + } return n } @@ -333,6 +657,24 @@ func (m *EmptyResponse) Size() (n int) { return n } +func (m *InternalAuthenticateRequest) Size() (n int) { + var l int + _ = l + l = len(m.Name) + if l > 0 { + n += 1 + l + sovRaftInternal(uint64(l)) + } + l = len(m.Password) + if l > 0 { + n += 1 + l + sovRaftInternal(uint64(l)) + } + l = len(m.SimpleToken) + if l > 0 { + n += 1 + l + sovRaftInternal(uint64(l)) + } + return n +} + func sovRaftInternal(x uint64) (n int) { for { n++ @@ -346,6 +688,104 @@ 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) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRaftInternal + } + 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: RequestHeader: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: RequestHeader: 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 ErrIntOverflowRaftInternal + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + m.ID |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Username", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRaftInternal + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthRaftInternal + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Username = string(data[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipRaftInternal(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthRaftInternal + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *InternalRaftRequest) Unmarshal(data []byte) error { l := len(data) iNdEx := 0 @@ -659,6 +1099,72 @@ func (m *InternalRaftRequest) Unmarshal(data []byte) error { } iNdEx = postIndex case 10: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Alarm", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRaftInternal + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthRaftInternal + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Alarm == nil { + m.Alarm = &AlarmRequest{} + } + if err := m.Alarm.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 100: + 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 ErrIntOverflowRaftInternal + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthRaftInternal + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Header == nil { + m.Header = &RequestHeader{} + } + if err := m.Header.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 1000: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field AuthEnable", wireType) } @@ -691,7 +1197,73 @@ func (m *InternalRaftRequest) Unmarshal(data []byte) error { return err } iNdEx = postIndex - case 11: + case 1011: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AuthDisable", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRaftInternal + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthRaftInternal + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.AuthDisable == nil { + m.AuthDisable = &AuthDisableRequest{} + } + if err := m.AuthDisable.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 1012: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Authenticate", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRaftInternal + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthRaftInternal + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Authenticate == nil { + m.Authenticate = &InternalAuthenticateRequest{} + } + if err := m.Authenticate.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 1100: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field AuthUserAdd", wireType) } @@ -724,7 +1296,7 @@ func (m *InternalRaftRequest) Unmarshal(data []byte) error { return err } iNdEx = postIndex - case 12: + case 1101: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field AuthUserDelete", wireType) } @@ -757,7 +1329,40 @@ func (m *InternalRaftRequest) Unmarshal(data []byte) error { return err } iNdEx = postIndex - case 13: + case 1102: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AuthUserGet", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRaftInternal + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthRaftInternal + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.AuthUserGet == nil { + m.AuthUserGet = &AuthUserGetRequest{} + } + if err := m.AuthUserGet.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 1103: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field AuthUserChangePassword", wireType) } @@ -790,7 +1395,139 @@ func (m *InternalRaftRequest) Unmarshal(data []byte) error { return err } iNdEx = postIndex - case 14: + case 1104: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AuthUserGrantRole", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRaftInternal + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthRaftInternal + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.AuthUserGrantRole == nil { + m.AuthUserGrantRole = &AuthUserGrantRoleRequest{} + } + if err := m.AuthUserGrantRole.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 1105: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AuthUserRevokeRole", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRaftInternal + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthRaftInternal + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.AuthUserRevokeRole == nil { + m.AuthUserRevokeRole = &AuthUserRevokeRoleRequest{} + } + if err := m.AuthUserRevokeRole.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 1106: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AuthUserList", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRaftInternal + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthRaftInternal + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.AuthUserList == nil { + m.AuthUserList = &AuthUserListRequest{} + } + if err := m.AuthUserList.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 1107: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AuthRoleList", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRaftInternal + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthRaftInternal + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.AuthRoleList == nil { + m.AuthRoleList = &AuthRoleListRequest{} + } + if err := m.AuthRoleList.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 1200: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field AuthRoleAdd", wireType) } @@ -823,9 +1560,9 @@ func (m *InternalRaftRequest) Unmarshal(data []byte) error { return err } iNdEx = postIndex - case 15: + case 1201: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Alarm", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field AuthRoleDelete", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -849,10 +1586,109 @@ func (m *InternalRaftRequest) Unmarshal(data []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.Alarm == nil { - m.Alarm = &AlarmRequest{} + if m.AuthRoleDelete == nil { + m.AuthRoleDelete = &AuthRoleDeleteRequest{} } - if err := m.Alarm.Unmarshal(data[iNdEx:postIndex]); err != nil { + if err := m.AuthRoleDelete.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 1202: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AuthRoleGet", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRaftInternal + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthRaftInternal + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.AuthRoleGet == nil { + m.AuthRoleGet = &AuthRoleGetRequest{} + } + if err := m.AuthRoleGet.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 1203: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AuthRoleGrantPermission", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRaftInternal + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthRaftInternal + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.AuthRoleGrantPermission == nil { + m.AuthRoleGrantPermission = &AuthRoleGrantPermissionRequest{} + } + if err := m.AuthRoleGrantPermission.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 1204: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AuthRoleRevokePermission", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRaftInternal + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthRaftInternal + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.AuthRoleRevokePermission == nil { + m.AuthRoleRevokePermission = &AuthRoleRevokePermissionRequest{} + } + if err := m.AuthRoleRevokePermission.Unmarshal(data[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -927,6 +1763,143 @@ func (m *EmptyResponse) Unmarshal(data []byte) error { } return nil } +func (m *InternalAuthenticateRequest) 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 ErrIntOverflowRaftInternal + } + 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: InternalAuthenticateRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: InternalAuthenticateRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRaftInternal + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthRaftInternal + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(data[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Password", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRaftInternal + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthRaftInternal + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Password = string(data[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SimpleToken", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRaftInternal + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthRaftInternal + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.SimpleToken = string(data[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipRaftInternal(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthRaftInternal + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func skipRaftInternal(data []byte) (n int, err error) { l := len(data) iNdEx := 0 @@ -1031,3 +2004,59 @@ var ( ErrInvalidLengthRaftInternal = fmt.Errorf("proto: negative length found during unmarshaling") ErrIntOverflowRaftInternal = fmt.Errorf("proto: integer overflow") ) + +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, +} 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 1fe517f5ce4..3ad0d1b3783 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/etcdserverpb/raft_internal.proto +++ b/vendor/github.com/coreos/etcd/etcdserver/etcdserverpb/raft_internal.proto @@ -10,10 +10,18 @@ option (gogoproto.sizer_all) = true; option (gogoproto.unmarshaler_all) = true; option (gogoproto.goproto_getters_all) = false; +message RequestHeader { + uint64 ID = 1; + // username is a username that is associated with an auth token of gRPC connection + string username = 2; +} + // An InternalRaftRequest is the union of all requests which can be // sent via raft. message InternalRaftRequest { + RequestHeader header = 100; uint64 ID = 1; + Request v2 = 2; RangeRequest range = 3; @@ -25,14 +33,40 @@ message InternalRaftRequest { LeaseGrantRequest lease_grant = 8; LeaseRevokeRequest lease_revoke = 9; - AuthEnableRequest auth_enable = 10; - AuthUserAddRequest auth_user_add = 11; - AuthUserDeleteRequest auth_user_delete = 12; - AuthUserChangePasswordRequest auth_user_change_password = 13; - AuthRoleAddRequest auth_role_add = 14; + AlarmRequest alarm = 10; - AlarmRequest alarm = 15; + AuthEnableRequest auth_enable = 1000; + AuthDisableRequest auth_disable = 1011; + + InternalAuthenticateRequest authenticate = 1012; + + AuthUserAddRequest auth_user_add = 1100; + AuthUserDeleteRequest auth_user_delete = 1101; + AuthUserGetRequest auth_user_get = 1102; + AuthUserChangePasswordRequest auth_user_change_password = 1103; + AuthUserGrantRoleRequest auth_user_grant_role = 1104; + AuthUserRevokeRoleRequest auth_user_revoke_role = 1105; + AuthUserListRequest auth_user_list = 1106; + AuthRoleListRequest auth_role_list = 1107; + + AuthRoleAddRequest auth_role_add = 1200; + AuthRoleDeleteRequest auth_role_delete = 1201; + AuthRoleGetRequest auth_role_get = 1202; + AuthRoleGrantPermissionRequest auth_role_grant_permission = 1203; + AuthRoleRevokePermissionRequest auth_role_revoke_permission = 1204; } message EmptyResponse { } + +// What is the difference between AuthenticateRequest (defined in rpc.proto) and InternalAuthenticateRequest? +// InternalAuthenticateRequest has a member that is filled by etcdserver and shouldn't be user-facing. +// For avoiding misusage the field, we have an internal version of AuthenticateRequest. +message InternalAuthenticateRequest { + string name = 1; + string password = 2; + + // simple_token is generated in API layer (etcdserver/v3_server.go) + string simple_token = 3; +} + 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 ac5de8cfe68..213d5442682 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/etcdserverpb/rpc.pb.go +++ b/vendor/github.com/coreos/etcd/etcdserver/etcdserverpb/rpc.pb.go @@ -7,18 +7,21 @@ package etcdserverpb import ( "fmt" - proto "github.com/gogo/protobuf/proto" + proto "github.com/golang/protobuf/proto" math "math" - context "golang.org/x/net/context" + authpb "github.com/coreos/etcd/auth/authpb" - grpc "google.golang.org/grpc" + io "io" ) -import storagepb "github.com/coreos/etcd/storage/storagepb" +import mvccpb "github.com/coreos/etcd/mvcc/mvccpb" -import io "io" +import ( + context "golang.org/x/net/context" + grpc "google.golang.org/grpc" +) // Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal @@ -44,6 +47,7 @@ var AlarmType_value = map[string]int32{ func (x AlarmType) String() string { return proto.EnumName(AlarmType_name, int32(x)) } +func (AlarmType) EnumDescriptor() ([]byte, []int) { return fileDescriptorRpc, []int{0} } type RangeRequest_SortOrder int32 @@ -67,6 +71,7 @@ var RangeRequest_SortOrder_value = map[string]int32{ func (x RangeRequest_SortOrder) String() string { return proto.EnumName(RangeRequest_SortOrder_name, int32(x)) } +func (RangeRequest_SortOrder) EnumDescriptor() ([]byte, []int) { return fileDescriptorRpc, []int{1, 0} } type RangeRequest_SortTarget int32 @@ -96,6 +101,7 @@ var RangeRequest_SortTarget_value = map[string]int32{ func (x RangeRequest_SortTarget) String() string { return proto.EnumName(RangeRequest_SortTarget_name, int32(x)) } +func (RangeRequest_SortTarget) EnumDescriptor() ([]byte, []int) { return fileDescriptorRpc, []int{1, 1} } type Compare_CompareResult int32 @@ -119,6 +125,7 @@ var Compare_CompareResult_value = map[string]int32{ func (x Compare_CompareResult) String() string { return proto.EnumName(Compare_CompareResult_name, int32(x)) } +func (Compare_CompareResult) EnumDescriptor() ([]byte, []int) { return fileDescriptorRpc, []int{9, 0} } type Compare_CompareTarget int32 @@ -145,6 +152,7 @@ var Compare_CompareTarget_value = map[string]int32{ func (x Compare_CompareTarget) String() string { return proto.EnumName(Compare_CompareTarget_name, int32(x)) } +func (Compare_CompareTarget) EnumDescriptor() ([]byte, []int) { return fileDescriptorRpc, []int{9, 1} } type AlarmRequest_AlarmAction int32 @@ -168,59 +176,78 @@ var AlarmRequest_AlarmAction_value = map[string]int32{ 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} +} type ResponseHeader struct { - ClusterId uint64 `protobuf:"varint,1,opt,name=cluster_id,proto3" json:"cluster_id,omitempty"` - MemberId uint64 `protobuf:"varint,2,opt,name=member_id,proto3" json:"member_id,omitempty"` - // revision of the store when the request was applied. + // cluster_id is the ID of the cluster which sent the response. + ClusterId uint64 `protobuf:"varint,1,opt,name=cluster_id,json=clusterId,proto3" json:"cluster_id,omitempty"` + // member_id is the ID of the member which sent the response. + MemberId uint64 `protobuf:"varint,2,opt,name=member_id,json=memberId,proto3" json:"member_id,omitempty"` + // revision is the key-value store revision when the request was applied. Revision int64 `protobuf:"varint,3,opt,name=revision,proto3" json:"revision,omitempty"` - // term of raft when the request was applied. - RaftTerm uint64 `protobuf:"varint,4,opt,name=raft_term,proto3" json:"raft_term,omitempty"` + // raft_term is the raft term when the request was applied. + RaftTerm uint64 `protobuf:"varint,4,opt,name=raft_term,json=raftTerm,proto3" json:"raft_term,omitempty"` } -func (m *ResponseHeader) Reset() { *m = ResponseHeader{} } -func (m *ResponseHeader) String() string { return proto.CompactTextString(m) } -func (*ResponseHeader) ProtoMessage() {} +func (m *ResponseHeader) Reset() { *m = ResponseHeader{} } +func (m *ResponseHeader) String() string { return proto.CompactTextString(m) } +func (*ResponseHeader) ProtoMessage() {} +func (*ResponseHeader) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{0} } type RangeRequest struct { - // if the range_end is not given, the request returns the key. + // key is the first key for the range. If range_end is not given, the request only looks up key. Key []byte `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` - // if the range_end is given, it gets the keys in range [key, range_end) - // if range_end is nonempty, otherwise it returns all keys >= key. - RangeEnd []byte `protobuf:"bytes,2,opt,name=range_end,proto3" json:"range_end,omitempty"` - // limit the number of keys returned. + // range_end is the upper bound on the requested range [key, range_end). + // If range_end is '\0', the range is all keys >= key. + // If the range_end is one bit larger than the given key, + // then the range requests get the all keys with the prefix (the given key). + // If both key and range_end are '\0', then range requests returns all keys. + RangeEnd []byte `protobuf:"bytes,2,opt,name=range_end,json=rangeEnd,proto3" json:"range_end,omitempty"` + // limit is a limit on the number of keys returned for the request. Limit int64 `protobuf:"varint,3,opt,name=limit,proto3" json:"limit,omitempty"` - // range over the store at the given revision. - // if revision is less or equal to zero, range over the newest store. - // if the revision has been compacted, ErrCompaction will be returned in - // response. + // revision is the point-in-time of the key-value store to use for the range. + // If revision is less or equal to zero, the range is over the newest key-value store. + // If the revision has been compacted, ErrCompacted is returned as a response. Revision int64 `protobuf:"varint,4,opt,name=revision,proto3" json:"revision,omitempty"` - // sort_order is the requested order for returned the results - SortOrder RangeRequest_SortOrder `protobuf:"varint,5,opt,name=sort_order,proto3,enum=etcdserverpb.RangeRequest_SortOrder" json:"sort_order,omitempty"` - // sort_target is the kv field to use for sorting - SortTarget RangeRequest_SortTarget `protobuf:"varint,6,opt,name=sort_target,proto3,enum=etcdserverpb.RangeRequest_SortTarget" json:"sort_target,omitempty"` - // range request is linearizable by default. Linearizable requests has a higher - // latency and lower throughput than serializable request. - // To reduce latency, serializable can be set. If serializable is set, range request - // will be serializable, but not linearizable with other requests. - // Serializable range can be served locally without waiting for other nodes in the cluster. + // sort_order is the order for returned sorted results. + SortOrder RangeRequest_SortOrder `protobuf:"varint,5,opt,name=sort_order,json=sortOrder,proto3,enum=etcdserverpb.RangeRequest_SortOrder" json:"sort_order,omitempty"` + // sort_target is the key-value field to use for sorting. + SortTarget RangeRequest_SortTarget `protobuf:"varint,6,opt,name=sort_target,json=sortTarget,proto3,enum=etcdserverpb.RangeRequest_SortTarget" json:"sort_target,omitempty"` + // serializable sets the range request to use serializable member-local reads. + // Range requests are linearizable by default; linearizable requests have higher + // latency and lower throughput than serializable requests but reflect the current + // consensus of the cluster. For better performance, in exchange for possible stale reads, + // a serializable range request is served locally without needing to reach consensus + // with other nodes in the cluster. Serializable bool `protobuf:"varint,7,opt,name=serializable,proto3" json:"serializable,omitempty"` + // keys_only when set returns only the keys and not the values. + 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"` } -func (m *RangeRequest) Reset() { *m = RangeRequest{} } -func (m *RangeRequest) String() string { return proto.CompactTextString(m) } -func (*RangeRequest) ProtoMessage() {} +func (m *RangeRequest) Reset() { *m = RangeRequest{} } +func (m *RangeRequest) String() string { return proto.CompactTextString(m) } +func (*RangeRequest) ProtoMessage() {} +func (*RangeRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{1} } type RangeResponse struct { - Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"` - Kvs []*storagepb.KeyValue `protobuf:"bytes,2,rep,name=kvs" json:"kvs,omitempty"` + Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"` + // kvs is the list of key-value pairs matched by the range request. + // kvs is empty when count is requested. + Kvs []*mvccpb.KeyValue `protobuf:"bytes,2,rep,name=kvs" json:"kvs,omitempty"` // more indicates if there are more keys to return in the requested range. More bool `protobuf:"varint,3,opt,name=more,proto3" json:"more,omitempty"` + // count is set to the number of keys within the range when requested. + Count int64 `protobuf:"varint,4,opt,name=count,proto3" json:"count,omitempty"` } -func (m *RangeResponse) Reset() { *m = RangeResponse{} } -func (m *RangeResponse) String() string { return proto.CompactTextString(m) } -func (*RangeResponse) ProtoMessage() {} +func (m *RangeResponse) Reset() { *m = RangeResponse{} } +func (m *RangeResponse) String() string { return proto.CompactTextString(m) } +func (*RangeResponse) ProtoMessage() {} +func (*RangeResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{2} } func (m *RangeResponse) GetHeader() *ResponseHeader { if m != nil { @@ -229,7 +256,7 @@ func (m *RangeResponse) GetHeader() *ResponseHeader { return nil } -func (m *RangeResponse) GetKvs() []*storagepb.KeyValue { +func (m *RangeResponse) GetKvs() []*mvccpb.KeyValue { if m != nil { return m.Kvs } @@ -237,22 +264,28 @@ func (m *RangeResponse) GetKvs() []*storagepb.KeyValue { } type PutRequest struct { - Key []byte `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` + // key is the key, in bytes, to put into the key-value store. + Key []byte `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` + // value is the value, in bytes, to associate with the key in the key-value store. Value []byte `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` - Lease int64 `protobuf:"varint,3,opt,name=lease,proto3" json:"lease,omitempty"` + // lease is the lease ID to associate with the key in the key-value store. A lease + // value of 0 indicates no lease. + Lease int64 `protobuf:"varint,3,opt,name=lease,proto3" json:"lease,omitempty"` } -func (m *PutRequest) Reset() { *m = PutRequest{} } -func (m *PutRequest) String() string { return proto.CompactTextString(m) } -func (*PutRequest) ProtoMessage() {} +func (m *PutRequest) Reset() { *m = PutRequest{} } +func (m *PutRequest) String() string { return proto.CompactTextString(m) } +func (*PutRequest) ProtoMessage() {} +func (*PutRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{3} } type PutResponse struct { Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"` } -func (m *PutResponse) Reset() { *m = PutResponse{} } -func (m *PutResponse) String() string { return proto.CompactTextString(m) } -func (*PutResponse) ProtoMessage() {} +func (m *PutResponse) Reset() { *m = PutResponse{} } +func (m *PutResponse) String() string { return proto.CompactTextString(m) } +func (*PutResponse) ProtoMessage() {} +func (*PutResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{4} } func (m *PutResponse) GetHeader() *ResponseHeader { if m != nil { @@ -262,25 +295,29 @@ func (m *PutResponse) GetHeader() *ResponseHeader { } type DeleteRangeRequest struct { - // if the range_end is not given, the request deletes the key. + // key is the first key to delete in the range. Key []byte `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` - // if the range_end is given, it deletes the keys in range [key, range_end). - RangeEnd []byte `protobuf:"bytes,2,opt,name=range_end,proto3" json:"range_end,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 '\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"` } -func (m *DeleteRangeRequest) Reset() { *m = DeleteRangeRequest{} } -func (m *DeleteRangeRequest) String() string { return proto.CompactTextString(m) } -func (*DeleteRangeRequest) ProtoMessage() {} +func (m *DeleteRangeRequest) Reset() { *m = DeleteRangeRequest{} } +func (m *DeleteRangeRequest) String() string { return proto.CompactTextString(m) } +func (*DeleteRangeRequest) ProtoMessage() {} +func (*DeleteRangeRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{5} } type DeleteRangeResponse struct { Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"` - // Deleted is the number of keys that got deleted. + // deleted is the number of keys deleted by the delete range request. Deleted int64 `protobuf:"varint,2,opt,name=deleted,proto3" json:"deleted,omitempty"` } -func (m *DeleteRangeResponse) Reset() { *m = DeleteRangeResponse{} } -func (m *DeleteRangeResponse) String() string { return proto.CompactTextString(m) } -func (*DeleteRangeResponse) ProtoMessage() {} +func (m *DeleteRangeResponse) Reset() { *m = DeleteRangeResponse{} } +func (m *DeleteRangeResponse) String() string { return proto.CompactTextString(m) } +func (*DeleteRangeResponse) ProtoMessage() {} +func (*DeleteRangeResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{6} } func (m *DeleteRangeResponse) GetHeader() *ResponseHeader { if m != nil { @@ -289,103 +326,106 @@ func (m *DeleteRangeResponse) GetHeader() *ResponseHeader { return nil } -type RequestUnion struct { +type RequestOp struct { + // request is a union of request types accepted by a transaction. + // // Types that are valid to be assigned to Request: - // *RequestUnion_RequestRange - // *RequestUnion_RequestPut - // *RequestUnion_RequestDeleteRange - Request isRequestUnion_Request `protobuf_oneof:"request"` + // *RequestOp_RequestRange + // *RequestOp_RequestPut + // *RequestOp_RequestDeleteRange + Request isRequestOp_Request `protobuf_oneof:"request"` } -func (m *RequestUnion) Reset() { *m = RequestUnion{} } -func (m *RequestUnion) String() string { return proto.CompactTextString(m) } -func (*RequestUnion) ProtoMessage() {} +func (m *RequestOp) Reset() { *m = RequestOp{} } +func (m *RequestOp) String() string { return proto.CompactTextString(m) } +func (*RequestOp) ProtoMessage() {} +func (*RequestOp) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{7} } -type isRequestUnion_Request interface { - isRequestUnion_Request() +type isRequestOp_Request interface { + isRequestOp_Request() MarshalTo([]byte) (int, error) Size() int } -type RequestUnion_RequestRange struct { - RequestRange *RangeRequest `protobuf:"bytes,1,opt,name=request_range,oneof"` +type RequestOp_RequestRange struct { + RequestRange *RangeRequest `protobuf:"bytes,1,opt,name=request_range,json=requestRange,oneof"` } -type RequestUnion_RequestPut struct { - RequestPut *PutRequest `protobuf:"bytes,2,opt,name=request_put,oneof"` +type RequestOp_RequestPut struct { + RequestPut *PutRequest `protobuf:"bytes,2,opt,name=request_put,json=requestPut,oneof"` } -type RequestUnion_RequestDeleteRange struct { - RequestDeleteRange *DeleteRangeRequest `protobuf:"bytes,3,opt,name=request_delete_range,oneof"` +type RequestOp_RequestDeleteRange struct { + RequestDeleteRange *DeleteRangeRequest `protobuf:"bytes,3,opt,name=request_delete_range,json=requestDeleteRange,oneof"` } -func (*RequestUnion_RequestRange) isRequestUnion_Request() {} -func (*RequestUnion_RequestPut) isRequestUnion_Request() {} -func (*RequestUnion_RequestDeleteRange) isRequestUnion_Request() {} +func (*RequestOp_RequestRange) isRequestOp_Request() {} +func (*RequestOp_RequestPut) isRequestOp_Request() {} +func (*RequestOp_RequestDeleteRange) isRequestOp_Request() {} -func (m *RequestUnion) GetRequest() isRequestUnion_Request { +func (m *RequestOp) GetRequest() isRequestOp_Request { if m != nil { return m.Request } return nil } -func (m *RequestUnion) GetRequestRange() *RangeRequest { - if x, ok := m.GetRequest().(*RequestUnion_RequestRange); ok { +func (m *RequestOp) GetRequestRange() *RangeRequest { + if x, ok := m.GetRequest().(*RequestOp_RequestRange); ok { return x.RequestRange } return nil } -func (m *RequestUnion) GetRequestPut() *PutRequest { - if x, ok := m.GetRequest().(*RequestUnion_RequestPut); ok { +func (m *RequestOp) GetRequestPut() *PutRequest { + if x, ok := m.GetRequest().(*RequestOp_RequestPut); ok { return x.RequestPut } return nil } -func (m *RequestUnion) GetRequestDeleteRange() *DeleteRangeRequest { - if x, ok := m.GetRequest().(*RequestUnion_RequestDeleteRange); ok { +func (m *RequestOp) GetRequestDeleteRange() *DeleteRangeRequest { + if x, ok := m.GetRequest().(*RequestOp_RequestDeleteRange); ok { return x.RequestDeleteRange } return nil } // XXX_OneofFuncs is for the internal use of the proto package. -func (*RequestUnion) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), []interface{}) { - return _RequestUnion_OneofMarshaler, _RequestUnion_OneofUnmarshaler, []interface{}{ - (*RequestUnion_RequestRange)(nil), - (*RequestUnion_RequestPut)(nil), - (*RequestUnion_RequestDeleteRange)(nil), +func (*RequestOp) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) { + return _RequestOp_OneofMarshaler, _RequestOp_OneofUnmarshaler, _RequestOp_OneofSizer, []interface{}{ + (*RequestOp_RequestRange)(nil), + (*RequestOp_RequestPut)(nil), + (*RequestOp_RequestDeleteRange)(nil), } } -func _RequestUnion_OneofMarshaler(msg proto.Message, b *proto.Buffer) error { - m := msg.(*RequestUnion) +func _RequestOp_OneofMarshaler(msg proto.Message, b *proto.Buffer) error { + m := msg.(*RequestOp) // request switch x := m.Request.(type) { - case *RequestUnion_RequestRange: + case *RequestOp_RequestRange: _ = b.EncodeVarint(1<<3 | proto.WireBytes) if err := b.EncodeMessage(x.RequestRange); err != nil { return err } - case *RequestUnion_RequestPut: + case *RequestOp_RequestPut: _ = b.EncodeVarint(2<<3 | proto.WireBytes) if err := b.EncodeMessage(x.RequestPut); err != nil { return err } - case *RequestUnion_RequestDeleteRange: + case *RequestOp_RequestDeleteRange: _ = b.EncodeVarint(3<<3 | proto.WireBytes) if err := b.EncodeMessage(x.RequestDeleteRange); err != nil { return err } case nil: default: - return fmt.Errorf("RequestUnion.Request has unexpected type %T", x) + return fmt.Errorf("RequestOp.Request has unexpected type %T", x) } return nil } -func _RequestUnion_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error) { - m := msg.(*RequestUnion) +func _RequestOp_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error) { + m := msg.(*RequestOp) switch tag { case 1: // request.request_range if wire != proto.WireBytes { @@ -393,7 +433,7 @@ func _RequestUnion_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.B } msg := new(RangeRequest) err := b.DecodeMessage(msg) - m.Request = &RequestUnion_RequestRange{msg} + m.Request = &RequestOp_RequestRange{msg} return true, err case 2: // request.request_put if wire != proto.WireBytes { @@ -401,7 +441,7 @@ func _RequestUnion_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.B } msg := new(PutRequest) err := b.DecodeMessage(msg) - m.Request = &RequestUnion_RequestPut{msg} + m.Request = &RequestOp_RequestPut{msg} return true, err case 3: // request.request_delete_range if wire != proto.WireBytes { @@ -409,110 +449,139 @@ func _RequestUnion_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.B } msg := new(DeleteRangeRequest) err := b.DecodeMessage(msg) - m.Request = &RequestUnion_RequestDeleteRange{msg} + m.Request = &RequestOp_RequestDeleteRange{msg} return true, err default: return false, nil } } -type ResponseUnion struct { - // Types that are valid to be assigned to Response: - // *ResponseUnion_ResponseRange - // *ResponseUnion_ResponsePut - // *ResponseUnion_ResponseDeleteRange - Response isResponseUnion_Response `protobuf_oneof:"response"` +func _RequestOp_OneofSizer(msg proto.Message) (n int) { + m := msg.(*RequestOp) + // request + switch x := m.Request.(type) { + case *RequestOp_RequestRange: + s := proto.Size(x.RequestRange) + n += proto.SizeVarint(1<<3 | proto.WireBytes) + n += proto.SizeVarint(uint64(s)) + n += s + case *RequestOp_RequestPut: + s := proto.Size(x.RequestPut) + n += proto.SizeVarint(2<<3 | proto.WireBytes) + n += proto.SizeVarint(uint64(s)) + n += s + case *RequestOp_RequestDeleteRange: + s := proto.Size(x.RequestDeleteRange) + n += proto.SizeVarint(3<<3 | proto.WireBytes) + n += proto.SizeVarint(uint64(s)) + n += s + case nil: + default: + panic(fmt.Sprintf("proto: unexpected type %T in oneof", x)) + } + return n } -func (m *ResponseUnion) Reset() { *m = ResponseUnion{} } -func (m *ResponseUnion) String() string { return proto.CompactTextString(m) } -func (*ResponseUnion) ProtoMessage() {} +type ResponseOp struct { + // response is a union of response types returned by a transaction. + // + // Types that are valid to be assigned to Response: + // *ResponseOp_ResponseRange + // *ResponseOp_ResponsePut + // *ResponseOp_ResponseDeleteRange + Response isResponseOp_Response `protobuf_oneof:"response"` +} -type isResponseUnion_Response interface { - isResponseUnion_Response() +func (m *ResponseOp) Reset() { *m = ResponseOp{} } +func (m *ResponseOp) String() string { return proto.CompactTextString(m) } +func (*ResponseOp) ProtoMessage() {} +func (*ResponseOp) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{8} } + +type isResponseOp_Response interface { + isResponseOp_Response() MarshalTo([]byte) (int, error) Size() int } -type ResponseUnion_ResponseRange struct { - ResponseRange *RangeResponse `protobuf:"bytes,1,opt,name=response_range,oneof"` +type ResponseOp_ResponseRange struct { + ResponseRange *RangeResponse `protobuf:"bytes,1,opt,name=response_range,json=responseRange,oneof"` } -type ResponseUnion_ResponsePut struct { - ResponsePut *PutResponse `protobuf:"bytes,2,opt,name=response_put,oneof"` +type ResponseOp_ResponsePut struct { + ResponsePut *PutResponse `protobuf:"bytes,2,opt,name=response_put,json=responsePut,oneof"` } -type ResponseUnion_ResponseDeleteRange struct { - ResponseDeleteRange *DeleteRangeResponse `protobuf:"bytes,3,opt,name=response_delete_range,oneof"` +type ResponseOp_ResponseDeleteRange struct { + ResponseDeleteRange *DeleteRangeResponse `protobuf:"bytes,3,opt,name=response_delete_range,json=responseDeleteRange,oneof"` } -func (*ResponseUnion_ResponseRange) isResponseUnion_Response() {} -func (*ResponseUnion_ResponsePut) isResponseUnion_Response() {} -func (*ResponseUnion_ResponseDeleteRange) isResponseUnion_Response() {} +func (*ResponseOp_ResponseRange) isResponseOp_Response() {} +func (*ResponseOp_ResponsePut) isResponseOp_Response() {} +func (*ResponseOp_ResponseDeleteRange) isResponseOp_Response() {} -func (m *ResponseUnion) GetResponse() isResponseUnion_Response { +func (m *ResponseOp) GetResponse() isResponseOp_Response { if m != nil { return m.Response } return nil } -func (m *ResponseUnion) GetResponseRange() *RangeResponse { - if x, ok := m.GetResponse().(*ResponseUnion_ResponseRange); ok { +func (m *ResponseOp) GetResponseRange() *RangeResponse { + if x, ok := m.GetResponse().(*ResponseOp_ResponseRange); ok { return x.ResponseRange } return nil } -func (m *ResponseUnion) GetResponsePut() *PutResponse { - if x, ok := m.GetResponse().(*ResponseUnion_ResponsePut); ok { +func (m *ResponseOp) GetResponsePut() *PutResponse { + if x, ok := m.GetResponse().(*ResponseOp_ResponsePut); ok { return x.ResponsePut } return nil } -func (m *ResponseUnion) GetResponseDeleteRange() *DeleteRangeResponse { - if x, ok := m.GetResponse().(*ResponseUnion_ResponseDeleteRange); ok { +func (m *ResponseOp) GetResponseDeleteRange() *DeleteRangeResponse { + if x, ok := m.GetResponse().(*ResponseOp_ResponseDeleteRange); ok { return x.ResponseDeleteRange } return nil } // XXX_OneofFuncs is for the internal use of the proto package. -func (*ResponseUnion) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), []interface{}) { - return _ResponseUnion_OneofMarshaler, _ResponseUnion_OneofUnmarshaler, []interface{}{ - (*ResponseUnion_ResponseRange)(nil), - (*ResponseUnion_ResponsePut)(nil), - (*ResponseUnion_ResponseDeleteRange)(nil), +func (*ResponseOp) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) { + return _ResponseOp_OneofMarshaler, _ResponseOp_OneofUnmarshaler, _ResponseOp_OneofSizer, []interface{}{ + (*ResponseOp_ResponseRange)(nil), + (*ResponseOp_ResponsePut)(nil), + (*ResponseOp_ResponseDeleteRange)(nil), } } -func _ResponseUnion_OneofMarshaler(msg proto.Message, b *proto.Buffer) error { - m := msg.(*ResponseUnion) +func _ResponseOp_OneofMarshaler(msg proto.Message, b *proto.Buffer) error { + m := msg.(*ResponseOp) // response switch x := m.Response.(type) { - case *ResponseUnion_ResponseRange: + case *ResponseOp_ResponseRange: _ = b.EncodeVarint(1<<3 | proto.WireBytes) if err := b.EncodeMessage(x.ResponseRange); err != nil { return err } - case *ResponseUnion_ResponsePut: + case *ResponseOp_ResponsePut: _ = b.EncodeVarint(2<<3 | proto.WireBytes) if err := b.EncodeMessage(x.ResponsePut); err != nil { return err } - case *ResponseUnion_ResponseDeleteRange: + case *ResponseOp_ResponseDeleteRange: _ = b.EncodeVarint(3<<3 | proto.WireBytes) if err := b.EncodeMessage(x.ResponseDeleteRange); err != nil { return err } case nil: default: - return fmt.Errorf("ResponseUnion.Response has unexpected type %T", x) + return fmt.Errorf("ResponseOp.Response has unexpected type %T", x) } return nil } -func _ResponseUnion_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error) { - m := msg.(*ResponseUnion) +func _ResponseOp_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error) { + m := msg.(*ResponseOp) switch tag { case 1: // response.response_range if wire != proto.WireBytes { @@ -520,7 +589,7 @@ func _ResponseUnion_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto. } msg := new(RangeResponse) err := b.DecodeMessage(msg) - m.Response = &ResponseUnion_ResponseRange{msg} + m.Response = &ResponseOp_ResponseRange{msg} return true, err case 2: // response.response_put if wire != proto.WireBytes { @@ -528,7 +597,7 @@ func _ResponseUnion_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto. } msg := new(PutResponse) err := b.DecodeMessage(msg) - m.Response = &ResponseUnion_ResponsePut{msg} + m.Response = &ResponseOp_ResponsePut{msg} return true, err case 3: // response.response_delete_range if wire != proto.WireBytes { @@ -536,17 +605,45 @@ func _ResponseUnion_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto. } msg := new(DeleteRangeResponse) err := b.DecodeMessage(msg) - m.Response = &ResponseUnion_ResponseDeleteRange{msg} + m.Response = &ResponseOp_ResponseDeleteRange{msg} return true, err default: return false, nil } } +func _ResponseOp_OneofSizer(msg proto.Message) (n int) { + m := msg.(*ResponseOp) + // response + switch x := m.Response.(type) { + case *ResponseOp_ResponseRange: + s := proto.Size(x.ResponseRange) + n += proto.SizeVarint(1<<3 | proto.WireBytes) + n += proto.SizeVarint(uint64(s)) + n += s + case *ResponseOp_ResponsePut: + s := proto.Size(x.ResponsePut) + n += proto.SizeVarint(2<<3 | proto.WireBytes) + n += proto.SizeVarint(uint64(s)) + n += s + case *ResponseOp_ResponseDeleteRange: + s := proto.Size(x.ResponseDeleteRange) + n += proto.SizeVarint(3<<3 | proto.WireBytes) + n += proto.SizeVarint(uint64(s)) + n += s + case nil: + default: + panic(fmt.Sprintf("proto: unexpected type %T in oneof", x)) + } + return n +} + type Compare struct { + // result is logical comparison operation for this comparison. Result Compare_CompareResult `protobuf:"varint,1,opt,name=result,proto3,enum=etcdserverpb.Compare_CompareResult" json:"result,omitempty"` + // target is the key-value field to inspect for the comparison. Target Compare_CompareTarget `protobuf:"varint,2,opt,name=target,proto3,enum=etcdserverpb.Compare_CompareTarget" json:"target,omitempty"` - // key path + // key is the subject key for the comparison operation. Key []byte `protobuf:"bytes,3,opt,name=key,proto3" json:"key,omitempty"` // Types that are valid to be assigned to TargetUnion: // *Compare_Version @@ -556,9 +653,10 @@ type Compare struct { TargetUnion isCompare_TargetUnion `protobuf_oneof:"target_union"` } -func (m *Compare) Reset() { *m = Compare{} } -func (m *Compare) String() string { return proto.CompactTextString(m) } -func (*Compare) ProtoMessage() {} +func (m *Compare) Reset() { *m = Compare{} } +func (m *Compare) String() string { return proto.CompactTextString(m) } +func (*Compare) ProtoMessage() {} +func (*Compare) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{9} } type isCompare_TargetUnion interface { isCompare_TargetUnion() @@ -570,10 +668,10 @@ type Compare_Version struct { Version int64 `protobuf:"varint,4,opt,name=version,proto3,oneof"` } type Compare_CreateRevision struct { - CreateRevision int64 `protobuf:"varint,5,opt,name=create_revision,proto3,oneof"` + CreateRevision int64 `protobuf:"varint,5,opt,name=create_revision,json=createRevision,proto3,oneof"` } type Compare_ModRevision struct { - ModRevision int64 `protobuf:"varint,6,opt,name=mod_revision,proto3,oneof"` + ModRevision int64 `protobuf:"varint,6,opt,name=mod_revision,json=modRevision,proto3,oneof"` } type Compare_Value struct { Value []byte `protobuf:"bytes,7,opt,name=value,proto3,oneof"` @@ -620,8 +718,8 @@ func (m *Compare) GetValue() []byte { } // XXX_OneofFuncs is for the internal use of the proto package. -func (*Compare) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), []interface{}) { - return _Compare_OneofMarshaler, _Compare_OneofUnmarshaler, []interface{}{ +func (*Compare) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) { + return _Compare_OneofMarshaler, _Compare_OneofUnmarshaler, _Compare_OneofSizer, []interface{}{ (*Compare_Version)(nil), (*Compare_CreateRevision)(nil), (*Compare_ModRevision)(nil), @@ -688,6 +786,30 @@ func _Compare_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer } } +func _Compare_OneofSizer(msg proto.Message) (n int) { + m := msg.(*Compare) + // target_union + switch x := m.TargetUnion.(type) { + case *Compare_Version: + n += proto.SizeVarint(4<<3 | proto.WireVarint) + n += proto.SizeVarint(uint64(x.Version)) + case *Compare_CreateRevision: + n += proto.SizeVarint(5<<3 | proto.WireVarint) + n += proto.SizeVarint(uint64(x.CreateRevision)) + case *Compare_ModRevision: + n += proto.SizeVarint(6<<3 | proto.WireVarint) + n += proto.SizeVarint(uint64(x.ModRevision)) + case *Compare_Value: + n += proto.SizeVarint(7<<3 | proto.WireBytes) + n += proto.SizeVarint(uint64(len(x.Value))) + n += len(x.Value) + case nil: + default: + panic(fmt.Sprintf("proto: unexpected type %T in oneof", x)) + } + return n +} + // From google paxosdb paper: // Our implementation hinges around a powerful primitive which we call MultiOp. All other database // operations except for iteration are implemented as a single call to MultiOp. A MultiOp is applied atomically @@ -704,14 +826,22 @@ func _Compare_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer // true. // 3. A list of database operations called f op. Like t op, but executed if guard evaluates to false. type TxnRequest struct { - Compare []*Compare `protobuf:"bytes,1,rep,name=compare" json:"compare,omitempty"` - Success []*RequestUnion `protobuf:"bytes,2,rep,name=success" json:"success,omitempty"` - Failure []*RequestUnion `protobuf:"bytes,3,rep,name=failure" json:"failure,omitempty"` + // compare is a list of predicates representing a conjunction of terms. + // If the comparisons succeed, then the success requests will be processed in order, + // and the response will contain their respective responses in order. + // If the comparisons fail, then the failure requests will be processed in order, + // and the response will contain their respective responses in order. + Compare []*Compare `protobuf:"bytes,1,rep,name=compare" json:"compare,omitempty"` + // success is a list of requests which will be applied when compare evaluates to true. + Success []*RequestOp `protobuf:"bytes,2,rep,name=success" json:"success,omitempty"` + // failure is a list of requests which will be applied when compare evaluates to false. + Failure []*RequestOp `protobuf:"bytes,3,rep,name=failure" json:"failure,omitempty"` } -func (m *TxnRequest) Reset() { *m = TxnRequest{} } -func (m *TxnRequest) String() string { return proto.CompactTextString(m) } -func (*TxnRequest) ProtoMessage() {} +func (m *TxnRequest) Reset() { *m = TxnRequest{} } +func (m *TxnRequest) String() string { return proto.CompactTextString(m) } +func (*TxnRequest) ProtoMessage() {} +func (*TxnRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{10} } func (m *TxnRequest) GetCompare() []*Compare { if m != nil { @@ -720,14 +850,14 @@ func (m *TxnRequest) GetCompare() []*Compare { return nil } -func (m *TxnRequest) GetSuccess() []*RequestUnion { +func (m *TxnRequest) GetSuccess() []*RequestOp { if m != nil { return m.Success } return nil } -func (m *TxnRequest) GetFailure() []*RequestUnion { +func (m *TxnRequest) GetFailure() []*RequestOp { if m != nil { return m.Failure } @@ -735,14 +865,18 @@ func (m *TxnRequest) GetFailure() []*RequestUnion { } type TxnResponse struct { - Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"` - Succeeded bool `protobuf:"varint,2,opt,name=succeeded,proto3" json:"succeeded,omitempty"` - Responses []*ResponseUnion `protobuf:"bytes,3,rep,name=responses" json:"responses,omitempty"` + Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"` + // succeeded is set to true if the compare evaluated to true or false otherwise. + Succeeded bool `protobuf:"varint,2,opt,name=succeeded,proto3" json:"succeeded,omitempty"` + // responses is a list of responses corresponding to the results from applying + // success if succeeded is true or failure if succeeded is false. + Responses []*ResponseOp `protobuf:"bytes,3,rep,name=responses" json:"responses,omitempty"` } -func (m *TxnResponse) Reset() { *m = TxnResponse{} } -func (m *TxnResponse) String() string { return proto.CompactTextString(m) } -func (*TxnResponse) ProtoMessage() {} +func (m *TxnResponse) Reset() { *m = TxnResponse{} } +func (m *TxnResponse) String() string { return proto.CompactTextString(m) } +func (*TxnResponse) ProtoMessage() {} +func (*TxnResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{11} } func (m *TxnResponse) GetHeader() *ResponseHeader { if m != nil { @@ -751,36 +885,37 @@ func (m *TxnResponse) GetHeader() *ResponseHeader { return nil } -func (m *TxnResponse) GetResponses() []*ResponseUnion { +func (m *TxnResponse) GetResponses() []*ResponseOp { if m != nil { return m.Responses } return nil } -// Compaction compacts the kv store upto the given revision (including). -// It removes the old versions of a key. It keeps the newest version of -// the key even if its latest modification revision is smaller than the given -// revision. +// CompactionRequest compacts the key-value store up to a given revision. All superseded keys +// with a revision less than the compaction revision will be removed. type CompactionRequest struct { + // revision is the key-value store revision for the compaction operation. Revision int64 `protobuf:"varint,1,opt,name=revision,proto3" json:"revision,omitempty"` // physical is set so the RPC will wait until the compaction is physically // applied to the local database such that compacted entries are totally - // removed from the backing store. + // removed from the backend database. Physical bool `protobuf:"varint,2,opt,name=physical,proto3" json:"physical,omitempty"` } -func (m *CompactionRequest) Reset() { *m = CompactionRequest{} } -func (m *CompactionRequest) String() string { return proto.CompactTextString(m) } -func (*CompactionRequest) ProtoMessage() {} +func (m *CompactionRequest) Reset() { *m = CompactionRequest{} } +func (m *CompactionRequest) String() string { return proto.CompactTextString(m) } +func (*CompactionRequest) ProtoMessage() {} +func (*CompactionRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{12} } type CompactionResponse struct { Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"` } -func (m *CompactionResponse) Reset() { *m = CompactionResponse{} } -func (m *CompactionResponse) String() string { return proto.CompactTextString(m) } -func (*CompactionResponse) ProtoMessage() {} +func (m *CompactionResponse) Reset() { *m = CompactionResponse{} } +func (m *CompactionResponse) String() string { return proto.CompactTextString(m) } +func (*CompactionResponse) ProtoMessage() {} +func (*CompactionResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{13} } func (m *CompactionResponse) GetHeader() *ResponseHeader { if m != nil { @@ -792,18 +927,21 @@ func (m *CompactionResponse) GetHeader() *ResponseHeader { type HashRequest struct { } -func (m *HashRequest) Reset() { *m = HashRequest{} } -func (m *HashRequest) String() string { return proto.CompactTextString(m) } -func (*HashRequest) ProtoMessage() {} +func (m *HashRequest) Reset() { *m = HashRequest{} } +func (m *HashRequest) String() string { return proto.CompactTextString(m) } +func (*HashRequest) ProtoMessage() {} +func (*HashRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{14} } type HashResponse struct { Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"` - Hash uint32 `protobuf:"varint,2,opt,name=hash,proto3" json:"hash,omitempty"` + // hash is the hash value computed from the responding member's key-value store. + Hash uint32 `protobuf:"varint,2,opt,name=hash,proto3" json:"hash,omitempty"` } -func (m *HashResponse) Reset() { *m = HashResponse{} } -func (m *HashResponse) String() string { return proto.CompactTextString(m) } -func (*HashResponse) ProtoMessage() {} +func (m *HashResponse) Reset() { *m = HashResponse{} } +func (m *HashResponse) String() string { return proto.CompactTextString(m) } +func (*HashResponse) ProtoMessage() {} +func (*HashResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{15} } func (m *HashResponse) GetHeader() *ResponseHeader { if m != nil { @@ -812,16 +950,49 @@ func (m *HashResponse) GetHeader() *ResponseHeader { return nil } +type SnapshotRequest struct { +} + +func (m *SnapshotRequest) Reset() { *m = SnapshotRequest{} } +func (m *SnapshotRequest) String() string { return proto.CompactTextString(m) } +func (*SnapshotRequest) ProtoMessage() {} +func (*SnapshotRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{16} } + +type SnapshotResponse struct { + // header has the current key-value store information. The first header in the snapshot + // stream indicates the point in time of the snapshot. + Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"` + // remaining_bytes is the number of blob bytes to be sent after this message + RemainingBytes uint64 `protobuf:"varint,2,opt,name=remaining_bytes,json=remainingBytes,proto3" json:"remaining_bytes,omitempty"` + // blob contains the next chunk of the snapshot in the snapshot stream. + Blob []byte `protobuf:"bytes,3,opt,name=blob,proto3" json:"blob,omitempty"` +} + +func (m *SnapshotResponse) Reset() { *m = SnapshotResponse{} } +func (m *SnapshotResponse) String() string { return proto.CompactTextString(m) } +func (*SnapshotResponse) ProtoMessage() {} +func (*SnapshotResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{17} } + +func (m *SnapshotResponse) GetHeader() *ResponseHeader { + if m != nil { + return m.Header + } + return nil +} + type WatchRequest struct { + // request_union is a request to either create a new watcher or cancel an existing watcher. + // // Types that are valid to be assigned to RequestUnion: // *WatchRequest_CreateRequest // *WatchRequest_CancelRequest RequestUnion isWatchRequest_RequestUnion `protobuf_oneof:"request_union"` } -func (m *WatchRequest) Reset() { *m = WatchRequest{} } -func (m *WatchRequest) String() string { return proto.CompactTextString(m) } -func (*WatchRequest) ProtoMessage() {} +func (m *WatchRequest) Reset() { *m = WatchRequest{} } +func (m *WatchRequest) String() string { return proto.CompactTextString(m) } +func (*WatchRequest) ProtoMessage() {} +func (*WatchRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{18} } type isWatchRequest_RequestUnion interface { isWatchRequest_RequestUnion() @@ -830,10 +1001,10 @@ type isWatchRequest_RequestUnion interface { } type WatchRequest_CreateRequest struct { - CreateRequest *WatchCreateRequest `protobuf:"bytes,1,opt,name=create_request,oneof"` + CreateRequest *WatchCreateRequest `protobuf:"bytes,1,opt,name=create_request,json=createRequest,oneof"` } type WatchRequest_CancelRequest struct { - CancelRequest *WatchCancelRequest `protobuf:"bytes,2,opt,name=cancel_request,oneof"` + CancelRequest *WatchCancelRequest `protobuf:"bytes,2,opt,name=cancel_request,json=cancelRequest,oneof"` } func (*WatchRequest_CreateRequest) isWatchRequest_RequestUnion() {} @@ -861,8 +1032,8 @@ func (m *WatchRequest) GetCancelRequest() *WatchCancelRequest { } // XXX_OneofFuncs is for the internal use of the proto package. -func (*WatchRequest) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), []interface{}) { - return _WatchRequest_OneofMarshaler, _WatchRequest_OneofUnmarshaler, []interface{}{ +func (*WatchRequest) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) { + return _WatchRequest_OneofMarshaler, _WatchRequest_OneofUnmarshaler, _WatchRequest_OneofSizer, []interface{}{ (*WatchRequest_CreateRequest)(nil), (*WatchRequest_CancelRequest)(nil), } @@ -913,60 +1084,86 @@ func _WatchRequest_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.B } } -type WatchCreateRequest struct { - // the key to be watched - Key []byte `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` - // if the range_end is given, keys in [key, range_end) are watched - // NOTE: only range_end == prefixEnd(key) is accepted now - RangeEnd []byte `protobuf:"bytes,2,opt,name=range_end,proto3" json:"range_end,omitempty"` - // start_revision is an optional revision (including) to watch from. No start_revision is "now". - StartRevision int64 `protobuf:"varint,3,opt,name=start_revision,proto3" json:"start_revision,omitempty"` - // if progress_notify is set, etcd server sends WatchResponse with empty events to the - // created watcher when there are no recent events. It is useful when clients want always to be - // able to recover a disconnected watcher from a recent known revision. - // etcdsever can decide how long it should send a notification based on current load. - ProgressNotify bool `protobuf:"varint,4,opt,name=progress_notify,proto3" json:"progress_notify,omitempty"` +func _WatchRequest_OneofSizer(msg proto.Message) (n int) { + m := msg.(*WatchRequest) + // request_union + switch x := m.RequestUnion.(type) { + case *WatchRequest_CreateRequest: + s := proto.Size(x.CreateRequest) + n += proto.SizeVarint(1<<3 | proto.WireBytes) + n += proto.SizeVarint(uint64(s)) + n += s + case *WatchRequest_CancelRequest: + s := proto.Size(x.CancelRequest) + n += proto.SizeVarint(2<<3 | proto.WireBytes) + n += proto.SizeVarint(uint64(s)) + n += s + case nil: + default: + panic(fmt.Sprintf("proto: unexpected type %T in oneof", x)) + } + return n } -func (m *WatchCreateRequest) Reset() { *m = WatchCreateRequest{} } -func (m *WatchCreateRequest) String() string { return proto.CompactTextString(m) } -func (*WatchCreateRequest) ProtoMessage() {} +type WatchCreateRequest struct { + // key is the key to register for watching. + Key []byte `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` + // 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. + 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"` + // progress_notify is set so that the etcd server will periodically send a WatchResponse with + // no events to the new watcher if there are no recent events. It is useful when clients + // 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"` +} + +func (m *WatchCreateRequest) Reset() { *m = WatchCreateRequest{} } +func (m *WatchCreateRequest) String() string { return proto.CompactTextString(m) } +func (*WatchCreateRequest) ProtoMessage() {} +func (*WatchCreateRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{19} } type WatchCancelRequest struct { - WatchId int64 `protobuf:"varint,1,opt,name=watch_id,proto3" json:"watch_id,omitempty"` + // watch_id is the watcher id to cancel so that no more events are transmitted. + WatchId int64 `protobuf:"varint,1,opt,name=watch_id,json=watchId,proto3" json:"watch_id,omitempty"` } -func (m *WatchCancelRequest) Reset() { *m = WatchCancelRequest{} } -func (m *WatchCancelRequest) String() string { return proto.CompactTextString(m) } -func (*WatchCancelRequest) ProtoMessage() {} +func (m *WatchCancelRequest) Reset() { *m = WatchCancelRequest{} } +func (m *WatchCancelRequest) String() string { return proto.CompactTextString(m) } +func (*WatchCancelRequest) ProtoMessage() {} +func (*WatchCancelRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{20} } type WatchResponse struct { Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"` - // watch_id is the ID of the watching the response sent to. - WatchId int64 `protobuf:"varint,2,opt,name=watch_id,proto3" json:"watch_id,omitempty"` - // If the response is for a create watch request, created is set to true. - // Client should record the watch_id and prepare for receiving events for - // that watching from the same stream. - // All events sent to the created watching will attach with the same watch_id. + // watch_id is the ID of the watcher that corresponds to the response. + WatchId int64 `protobuf:"varint,2,opt,name=watch_id,json=watchId,proto3" json:"watch_id,omitempty"` + // created is set to true if the response is for a create watch request. + // The client should record the watch_id and expect to receive events for + // the created watcher from the same stream. + // All events sent to the created watcher will attach with the same watch_id. Created bool `protobuf:"varint,3,opt,name=created,proto3" json:"created,omitempty"` - // If the response is for a cancel watch request, cancel is set to true. - // No further events will be sent to the canceled watching. + // canceled is set to true if the response is for a cancel watch request. + // No further events will be sent to the canceled watcher. Canceled bool `protobuf:"varint,4,opt,name=canceled,proto3" json:"canceled,omitempty"` - // CompactRevision is set to the minimum index if a watching tries to watch + // compact_revision is set to the minimum index if a watcher tries to watch // at a compacted index. // - // This happens when creating a watching at a compacted revision or the watching cannot - // catch up with the progress of the KV. + // This happens when creating a watcher at a compacted revision or the watcher cannot + // catch up with the progress of the key-value store. // - // Client should treat the watching as canceled and should not try to create any - // watching with same start_revision again. - CompactRevision int64 `protobuf:"varint,5,opt,name=compact_revision,proto3" json:"compact_revision,omitempty"` - Events []*storagepb.Event `protobuf:"bytes,11,rep,name=events" json:"events,omitempty"` + // The client should treat the watcher as canceled and should not try to create any + // watcher with the same start_revision again. + CompactRevision int64 `protobuf:"varint,5,opt,name=compact_revision,json=compactRevision,proto3" json:"compact_revision,omitempty"` + Events []*mvccpb.Event `protobuf:"bytes,11,rep,name=events" json:"events,omitempty"` } -func (m *WatchResponse) Reset() { *m = WatchResponse{} } -func (m *WatchResponse) String() string { return proto.CompactTextString(m) } -func (*WatchResponse) ProtoMessage() {} +func (m *WatchResponse) Reset() { *m = WatchResponse{} } +func (m *WatchResponse) String() string { return proto.CompactTextString(m) } +func (*WatchResponse) ProtoMessage() {} +func (*WatchResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{21} } func (m *WatchResponse) GetHeader() *ResponseHeader { if m != nil { @@ -975,7 +1172,7 @@ func (m *WatchResponse) GetHeader() *ResponseHeader { return nil } -func (m *WatchResponse) GetEvents() []*storagepb.Event { +func (m *WatchResponse) GetEvents() []*mvccpb.Event { if m != nil { return m.Events } @@ -983,27 +1180,30 @@ func (m *WatchResponse) GetEvents() []*storagepb.Event { } type LeaseGrantRequest struct { - // advisory ttl in seconds - TTL int64 `protobuf:"varint,1,opt,name=TTL,proto3" json:"TTL,omitempty"` - // requested ID to create; 0 lets lessor choose - ID int64 `protobuf:"varint,2,opt,name=ID,proto3" json:"ID,omitempty"` + // TTL is the advisory time-to-live in seconds. + TTL int64 `protobuf:"varint,1,opt,name=TTL,json=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"` } -func (m *LeaseGrantRequest) Reset() { *m = LeaseGrantRequest{} } -func (m *LeaseGrantRequest) String() string { return proto.CompactTextString(m) } -func (*LeaseGrantRequest) ProtoMessage() {} +func (m *LeaseGrantRequest) Reset() { *m = LeaseGrantRequest{} } +func (m *LeaseGrantRequest) String() string { return proto.CompactTextString(m) } +func (*LeaseGrantRequest) ProtoMessage() {} +func (*LeaseGrantRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{22} } type LeaseGrantResponse struct { Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"` - ID int64 `protobuf:"varint,2,opt,name=ID,proto3" json:"ID,omitempty"` - // server decided ttl in second - TTL int64 `protobuf:"varint,3,opt,name=TTL,proto3" json:"TTL,omitempty"` + // ID is the lease ID for the granted lease. + ID int64 `protobuf:"varint,2,opt,name=ID,json=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"` Error string `protobuf:"bytes,4,opt,name=error,proto3" json:"error,omitempty"` } -func (m *LeaseGrantResponse) Reset() { *m = LeaseGrantResponse{} } -func (m *LeaseGrantResponse) String() string { return proto.CompactTextString(m) } -func (*LeaseGrantResponse) ProtoMessage() {} +func (m *LeaseGrantResponse) Reset() { *m = LeaseGrantResponse{} } +func (m *LeaseGrantResponse) String() string { return proto.CompactTextString(m) } +func (*LeaseGrantResponse) ProtoMessage() {} +func (*LeaseGrantResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{23} } func (m *LeaseGrantResponse) GetHeader() *ResponseHeader { if m != nil { @@ -1013,20 +1213,23 @@ func (m *LeaseGrantResponse) GetHeader() *ResponseHeader { } type LeaseRevokeRequest struct { - ID int64 `protobuf:"varint,1,opt,name=ID,proto3" json:"ID,omitempty"` + // 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"` } -func (m *LeaseRevokeRequest) Reset() { *m = LeaseRevokeRequest{} } -func (m *LeaseRevokeRequest) String() string { return proto.CompactTextString(m) } -func (*LeaseRevokeRequest) ProtoMessage() {} +func (m *LeaseRevokeRequest) Reset() { *m = LeaseRevokeRequest{} } +func (m *LeaseRevokeRequest) String() string { return proto.CompactTextString(m) } +func (*LeaseRevokeRequest) ProtoMessage() {} +func (*LeaseRevokeRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{24} } type LeaseRevokeResponse struct { Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"` } -func (m *LeaseRevokeResponse) Reset() { *m = LeaseRevokeResponse{} } -func (m *LeaseRevokeResponse) String() string { return proto.CompactTextString(m) } -func (*LeaseRevokeResponse) ProtoMessage() {} +func (m *LeaseRevokeResponse) Reset() { *m = LeaseRevokeResponse{} } +func (m *LeaseRevokeResponse) String() string { return proto.CompactTextString(m) } +func (*LeaseRevokeResponse) ProtoMessage() {} +func (*LeaseRevokeResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{25} } func (m *LeaseRevokeResponse) GetHeader() *ResponseHeader { if m != nil { @@ -1036,22 +1239,27 @@ func (m *LeaseRevokeResponse) GetHeader() *ResponseHeader { } type LeaseKeepAliveRequest struct { - ID int64 `protobuf:"varint,1,opt,name=ID,proto3" json:"ID,omitempty"` + // 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"` } -func (m *LeaseKeepAliveRequest) Reset() { *m = LeaseKeepAliveRequest{} } -func (m *LeaseKeepAliveRequest) String() string { return proto.CompactTextString(m) } -func (*LeaseKeepAliveRequest) ProtoMessage() {} +func (m *LeaseKeepAliveRequest) Reset() { *m = LeaseKeepAliveRequest{} } +func (m *LeaseKeepAliveRequest) String() string { return proto.CompactTextString(m) } +func (*LeaseKeepAliveRequest) ProtoMessage() {} +func (*LeaseKeepAliveRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{26} } type LeaseKeepAliveResponse struct { Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"` - ID int64 `protobuf:"varint,2,opt,name=ID,proto3" json:"ID,omitempty"` - TTL int64 `protobuf:"varint,3,opt,name=TTL,proto3" json:"TTL,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"` + // TTL is the new time-to-live for the lease. + TTL int64 `protobuf:"varint,3,opt,name=TTL,json=tTL,proto3" json:"TTL,omitempty"` } -func (m *LeaseKeepAliveResponse) Reset() { *m = LeaseKeepAliveResponse{} } -func (m *LeaseKeepAliveResponse) String() string { return proto.CompactTextString(m) } -func (*LeaseKeepAliveResponse) ProtoMessage() {} +func (m *LeaseKeepAliveResponse) Reset() { *m = LeaseKeepAliveResponse{} } +func (m *LeaseKeepAliveResponse) String() string { return proto.CompactTextString(m) } +func (*LeaseKeepAliveResponse) ProtoMessage() {} +func (*LeaseKeepAliveResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{27} } func (m *LeaseKeepAliveResponse) GetHeader() *ResponseHeader { if m != nil { @@ -1061,36 +1269,41 @@ func (m *LeaseKeepAliveResponse) GetHeader() *ResponseHeader { } type Member struct { - ID uint64 `protobuf:"varint,1,opt,name=ID,proto3" json:"ID,omitempty"` - // If the member is not started, name will be an empty string. - Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` - IsLeader bool `protobuf:"varint,3,opt,name=IsLeader,proto3" json:"IsLeader,omitempty"` - PeerURLs []string `protobuf:"bytes,4,rep,name=peerURLs" json:"peerURLs,omitempty"` - // If the member is not started, client_URLs will be an zero length - // string array. - ClientURLs []string `protobuf:"bytes,5,rep,name=clientURLs" json:"clientURLs,omitempty"` + // ID is the member ID for this member. + ID uint64 `protobuf:"varint,1,opt,name=ID,json=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. + PeerURLs []string `protobuf:"bytes,3,rep,name=peerURLs" json:"peerURLs,omitempty"` + // clientURLs is the list of URLs the member exposes to clients for communication. If the member is not started, clientURLs will be empty. + ClientURLs []string `protobuf:"bytes,4,rep,name=clientURLs" json:"clientURLs,omitempty"` } -func (m *Member) Reset() { *m = Member{} } -func (m *Member) String() string { return proto.CompactTextString(m) } -func (*Member) ProtoMessage() {} +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} } type MemberAddRequest struct { + // peerURLs is the list of URLs the added member will use to communicate with the cluster. PeerURLs []string `protobuf:"bytes,1,rep,name=peerURLs" json:"peerURLs,omitempty"` } -func (m *MemberAddRequest) Reset() { *m = MemberAddRequest{} } -func (m *MemberAddRequest) String() string { return proto.CompactTextString(m) } -func (*MemberAddRequest) ProtoMessage() {} +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} } type MemberAddResponse struct { Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"` - Member *Member `protobuf:"bytes,2,opt,name=member" json:"member,omitempty"` + // member is the member information for the added member. + Member *Member `protobuf:"bytes,2,opt,name=member" json:"member,omitempty"` } -func (m *MemberAddResponse) Reset() { *m = MemberAddResponse{} } -func (m *MemberAddResponse) String() string { return proto.CompactTextString(m) } -func (*MemberAddResponse) ProtoMessage() {} +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 (m *MemberAddResponse) GetHeader() *ResponseHeader { if m != nil { @@ -1107,20 +1320,23 @@ func (m *MemberAddResponse) GetMember() *Member { } type MemberRemoveRequest struct { - ID uint64 `protobuf:"varint,1,opt,name=ID,proto3" json:"ID,omitempty"` + // ID is the member ID of the member to remove. + ID uint64 `protobuf:"varint,1,opt,name=ID,json=iD,proto3" json:"ID,omitempty"` } -func (m *MemberRemoveRequest) Reset() { *m = MemberRemoveRequest{} } -func (m *MemberRemoveRequest) String() string { return proto.CompactTextString(m) } -func (*MemberRemoveRequest) ProtoMessage() {} +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} } type MemberRemoveResponse struct { Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"` } -func (m *MemberRemoveResponse) Reset() { *m = MemberRemoveResponse{} } -func (m *MemberRemoveResponse) String() string { return proto.CompactTextString(m) } -func (*MemberRemoveResponse) ProtoMessage() {} +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 (m *MemberRemoveResponse) GetHeader() *ResponseHeader { if m != nil { @@ -1130,21 +1346,25 @@ func (m *MemberRemoveResponse) GetHeader() *ResponseHeader { } type MemberUpdateRequest struct { - ID uint64 `protobuf:"varint,1,opt,name=ID,proto3" json:"ID,omitempty"` + // ID is the member ID of the member to update. + ID uint64 `protobuf:"varint,1,opt,name=ID,json=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"` } -func (m *MemberUpdateRequest) Reset() { *m = MemberUpdateRequest{} } -func (m *MemberUpdateRequest) String() string { return proto.CompactTextString(m) } -func (*MemberUpdateRequest) ProtoMessage() {} +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} } type MemberUpdateResponse struct { Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"` } -func (m *MemberUpdateResponse) Reset() { *m = MemberUpdateResponse{} } -func (m *MemberUpdateResponse) String() string { return proto.CompactTextString(m) } -func (*MemberUpdateResponse) ProtoMessage() {} +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 (m *MemberUpdateResponse) GetHeader() *ResponseHeader { if m != nil { @@ -1156,18 +1376,21 @@ func (m *MemberUpdateResponse) GetHeader() *ResponseHeader { type MemberListRequest struct { } -func (m *MemberListRequest) Reset() { *m = MemberListRequest{} } -func (m *MemberListRequest) String() string { return proto.CompactTextString(m) } -func (*MemberListRequest) ProtoMessage() {} +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} } type MemberListResponse struct { - Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"` - Members []*Member `protobuf:"bytes,2,rep,name=members" json:"members,omitempty"` + Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"` + // members is a list of all members associated with the cluster. + Members []*Member `protobuf:"bytes,2,rep,name=members" json:"members,omitempty"` } -func (m *MemberListResponse) Reset() { *m = MemberListResponse{} } -func (m *MemberListResponse) String() string { return proto.CompactTextString(m) } -func (*MemberListResponse) ProtoMessage() {} +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 (m *MemberListResponse) GetHeader() *ResponseHeader { if m != nil { @@ -1186,17 +1409,19 @@ func (m *MemberListResponse) GetMembers() []*Member { type DefragmentRequest struct { } -func (m *DefragmentRequest) Reset() { *m = DefragmentRequest{} } -func (m *DefragmentRequest) String() string { return proto.CompactTextString(m) } -func (*DefragmentRequest) ProtoMessage() {} +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} } type DefragmentResponse struct { Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"` } -func (m *DefragmentResponse) Reset() { *m = DefragmentResponse{} } -func (m *DefragmentResponse) String() string { return proto.CompactTextString(m) } -func (*DefragmentResponse) ProtoMessage() {} +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 (m *DefragmentResponse) GetHeader() *ResponseHeader { if m != nil { @@ -1206,33 +1431,44 @@ func (m *DefragmentResponse) GetHeader() *ResponseHeader { } type AlarmRequest struct { + // action is the kind of alarm request to issue. The action + // may GET alarm statuses, ACTIVATE an alarm, or DEACTIVATE a + // raised alarm. Action AlarmRequest_AlarmAction `protobuf:"varint,1,opt,name=action,proto3,enum=etcdserverpb.AlarmRequest_AlarmAction" json:"action,omitempty"` - // MemberID is the member raising the alarm request - MemberID uint64 `protobuf:"varint,2,opt,name=memberID,proto3" json:"memberID,omitempty"` - Alarm AlarmType `protobuf:"varint,3,opt,name=alarm,proto3,enum=etcdserverpb.AlarmType" json:"alarm,omitempty"` + // memberID is the ID of the member associated with the alarm. If memberID is 0, the + // alarm request covers all members. + MemberID uint64 `protobuf:"varint,2,opt,name=memberID,proto3" json:"memberID,omitempty"` + // alarm is the type of alarm to consider for this request. + Alarm AlarmType `protobuf:"varint,3,opt,name=alarm,proto3,enum=etcdserverpb.AlarmType" json:"alarm,omitempty"` } -func (m *AlarmRequest) Reset() { *m = AlarmRequest{} } -func (m *AlarmRequest) String() string { return proto.CompactTextString(m) } -func (*AlarmRequest) ProtoMessage() {} +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} } type AlarmMember struct { - MemberID uint64 `protobuf:"varint,1,opt,name=memberID,proto3" json:"memberID,omitempty"` - Alarm AlarmType `protobuf:"varint,2,opt,name=alarm,proto3,enum=etcdserverpb.AlarmType" json:"alarm,omitempty"` + // memberID is the ID of the member associated with the raised alarm. + MemberID uint64 `protobuf:"varint,1,opt,name=memberID,proto3" json:"memberID,omitempty"` + // alarm is the type of alarm which has been raised. + Alarm AlarmType `protobuf:"varint,2,opt,name=alarm,proto3,enum=etcdserverpb.AlarmType" json:"alarm,omitempty"` } -func (m *AlarmMember) Reset() { *m = AlarmMember{} } -func (m *AlarmMember) String() string { return proto.CompactTextString(m) } -func (*AlarmMember) ProtoMessage() {} +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} } type AlarmResponse struct { Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"` - Alarms []*AlarmMember `protobuf:"bytes,2,rep,name=alarms" json:"alarms,omitempty"` + // alarms is a list of alarms associated with the alarm request. + Alarms []*AlarmMember `protobuf:"bytes,2,rep,name=alarms" json:"alarms,omitempty"` } -func (m *AlarmResponse) Reset() { *m = AlarmResponse{} } -func (m *AlarmResponse) String() string { return proto.CompactTextString(m) } -func (*AlarmResponse) ProtoMessage() {} +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 (m *AlarmResponse) GetHeader() *ResponseHeader { if m != nil { @@ -1251,18 +1487,29 @@ func (m *AlarmResponse) GetAlarms() []*AlarmMember { type StatusRequest struct { } -func (m *StatusRequest) Reset() { *m = StatusRequest{} } -func (m *StatusRequest) String() string { return proto.CompactTextString(m) } -func (*StatusRequest) ProtoMessage() {} +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} } type StatusResponse struct { - Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"` - Version string `protobuf:"bytes,2,opt,name=version,proto3" json:"version,omitempty"` + Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"` + // version is the cluster protocol version used by the responding member. + Version string `protobuf:"bytes,2,opt,name=version,proto3" json:"version,omitempty"` + // dbSize is the size of the backend database, in bytes, of the responding member. + DbSize int64 `protobuf:"varint,3,opt,name=dbSize,proto3" json:"dbSize,omitempty"` + // leader is the member ID which the responding member believes is the current leader. + Leader uint64 `protobuf:"varint,4,opt,name=leader,proto3" json:"leader,omitempty"` + // raftIndex is the current raft index of the responding member. + RaftIndex uint64 `protobuf:"varint,5,opt,name=raftIndex,proto3" json:"raftIndex,omitempty"` + // raftTerm is the current raft term of the responding member. + RaftTerm uint64 `protobuf:"varint,6,opt,name=raftTerm,proto3" json:"raftTerm,omitempty"` } -func (m *StatusResponse) Reset() { *m = StatusResponse{} } -func (m *StatusResponse) String() string { return proto.CompactTextString(m) } -func (*StatusResponse) ProtoMessage() {} +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 (m *StatusResponse) GetHeader() *ResponseHeader { if m != nil { @@ -1274,114 +1521,180 @@ func (m *StatusResponse) GetHeader() *ResponseHeader { type AuthEnableRequest struct { } -func (m *AuthEnableRequest) Reset() { *m = AuthEnableRequest{} } -func (m *AuthEnableRequest) String() string { return proto.CompactTextString(m) } -func (*AuthEnableRequest) ProtoMessage() {} +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} } type AuthDisableRequest struct { } -func (m *AuthDisableRequest) Reset() { *m = AuthDisableRequest{} } -func (m *AuthDisableRequest) String() string { return proto.CompactTextString(m) } -func (*AuthDisableRequest) ProtoMessage() {} +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} } type AuthenticateRequest struct { + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Password string `protobuf:"bytes,2,opt,name=password,proto3" json:"password,omitempty"` } -func (m *AuthenticateRequest) Reset() { *m = AuthenticateRequest{} } -func (m *AuthenticateRequest) String() string { return proto.CompactTextString(m) } -func (*AuthenticateRequest) ProtoMessage() {} +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} } type AuthUserAddRequest struct { Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` Password string `protobuf:"bytes,2,opt,name=password,proto3" json:"password,omitempty"` } -func (m *AuthUserAddRequest) Reset() { *m = AuthUserAddRequest{} } -func (m *AuthUserAddRequest) String() string { return proto.CompactTextString(m) } -func (*AuthUserAddRequest) ProtoMessage() {} +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} } type AuthUserGetRequest struct { -} - -func (m *AuthUserGetRequest) Reset() { *m = AuthUserGetRequest{} } -func (m *AuthUserGetRequest) String() string { return proto.CompactTextString(m) } -func (*AuthUserGetRequest) ProtoMessage() {} - -type AuthUserDeleteRequest struct { Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` } -func (m *AuthUserDeleteRequest) Reset() { *m = AuthUserDeleteRequest{} } -func (m *AuthUserDeleteRequest) String() string { return proto.CompactTextString(m) } -func (*AuthUserDeleteRequest) ProtoMessage() {} +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} } + +type AuthUserDeleteRequest struct { + // name is the name of the user to delete. + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` +} + +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} } type AuthUserChangePasswordRequest struct { - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + // name is the name of the user whose password is being changed. + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + // password is the new password for the user. Password string `protobuf:"bytes,2,opt,name=password,proto3" json:"password,omitempty"` } func (m *AuthUserChangePasswordRequest) Reset() { *m = AuthUserChangePasswordRequest{} } func (m *AuthUserChangePasswordRequest) String() string { return proto.CompactTextString(m) } func (*AuthUserChangePasswordRequest) ProtoMessage() {} - -type AuthUserGrantRequest struct { +func (*AuthUserChangePasswordRequest) Descriptor() ([]byte, []int) { + return fileDescriptorRpc, []int{50} } -func (m *AuthUserGrantRequest) Reset() { *m = AuthUserGrantRequest{} } -func (m *AuthUserGrantRequest) String() string { return proto.CompactTextString(m) } -func (*AuthUserGrantRequest) ProtoMessage() {} - -type AuthUserRevokeRequest struct { +type AuthUserGrantRoleRequest struct { + // user is the name of the user which should be granted a given role. + User string `protobuf:"bytes,1,opt,name=user,proto3" json:"user,omitempty"` + // role is the name of the role to grant to the user. + Role string `protobuf:"bytes,2,opt,name=role,proto3" json:"role,omitempty"` } -func (m *AuthUserRevokeRequest) Reset() { *m = AuthUserRevokeRequest{} } -func (m *AuthUserRevokeRequest) String() string { return proto.CompactTextString(m) } -func (*AuthUserRevokeRequest) ProtoMessage() {} +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} } + +type AuthUserRevokeRoleRequest struct { + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Role string `protobuf:"bytes,2,opt,name=role,proto3" json:"role,omitempty"` +} + +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} } type AuthRoleAddRequest struct { + // name is the name of the role to add to the authentication system. Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` } -func (m *AuthRoleAddRequest) Reset() { *m = AuthRoleAddRequest{} } -func (m *AuthRoleAddRequest) String() string { return proto.CompactTextString(m) } -func (*AuthRoleAddRequest) ProtoMessage() {} +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} } type AuthRoleGetRequest struct { + Role string `protobuf:"bytes,1,opt,name=role,proto3" json:"role,omitempty"` } -func (m *AuthRoleGetRequest) Reset() { *m = AuthRoleGetRequest{} } -func (m *AuthRoleGetRequest) String() string { return proto.CompactTextString(m) } -func (*AuthRoleGetRequest) ProtoMessage() {} +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} } + +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} } + +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} } type AuthRoleDeleteRequest struct { + Role string `protobuf:"bytes,1,opt,name=role,proto3" json:"role,omitempty"` } -func (m *AuthRoleDeleteRequest) Reset() { *m = AuthRoleDeleteRequest{} } -func (m *AuthRoleDeleteRequest) String() string { return proto.CompactTextString(m) } -func (*AuthRoleDeleteRequest) ProtoMessage() {} +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} } -type AuthRoleGrantRequest struct { +type AuthRoleGrantPermissionRequest struct { + // name is the name of the role which will be granted the permission. + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + // perm is the permission to grant to the role. + Perm *authpb.Permission `protobuf:"bytes,2,opt,name=perm" json:"perm,omitempty"` } -func (m *AuthRoleGrantRequest) Reset() { *m = AuthRoleGrantRequest{} } -func (m *AuthRoleGrantRequest) String() string { return proto.CompactTextString(m) } -func (*AuthRoleGrantRequest) ProtoMessage() {} - -type AuthRoleRevokeRequest struct { +func (m *AuthRoleGrantPermissionRequest) Reset() { *m = AuthRoleGrantPermissionRequest{} } +func (m *AuthRoleGrantPermissionRequest) String() string { return proto.CompactTextString(m) } +func (*AuthRoleGrantPermissionRequest) ProtoMessage() {} +func (*AuthRoleGrantPermissionRequest) Descriptor() ([]byte, []int) { + return fileDescriptorRpc, []int{58} } -func (m *AuthRoleRevokeRequest) Reset() { *m = AuthRoleRevokeRequest{} } -func (m *AuthRoleRevokeRequest) String() string { return proto.CompactTextString(m) } -func (*AuthRoleRevokeRequest) ProtoMessage() {} +func (m *AuthRoleGrantPermissionRequest) GetPerm() *authpb.Permission { + if m != nil { + return m.Perm + } + return nil +} + +type AuthRoleRevokePermissionRequest struct { + Role string `protobuf:"bytes,1,opt,name=role,proto3" json:"role,omitempty"` + Key string `protobuf:"bytes,2,opt,name=key,proto3" json:"key,omitempty"` + RangeEnd string `protobuf:"bytes,3,opt,name=range_end,json=rangeEnd,proto3" json:"range_end,omitempty"` +} + +func (m *AuthRoleRevokePermissionRequest) Reset() { *m = AuthRoleRevokePermissionRequest{} } +func (m *AuthRoleRevokePermissionRequest) String() string { return proto.CompactTextString(m) } +func (*AuthRoleRevokePermissionRequest) ProtoMessage() {} +func (*AuthRoleRevokePermissionRequest) Descriptor() ([]byte, []int) { + return fileDescriptorRpc, []int{59} +} type AuthEnableResponse struct { Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"` } -func (m *AuthEnableResponse) Reset() { *m = AuthEnableResponse{} } -func (m *AuthEnableResponse) String() string { return proto.CompactTextString(m) } -func (*AuthEnableResponse) ProtoMessage() {} +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 (m *AuthEnableResponse) GetHeader() *ResponseHeader { if m != nil { @@ -1394,9 +1707,10 @@ type AuthDisableResponse struct { Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"` } -func (m *AuthDisableResponse) Reset() { *m = AuthDisableResponse{} } -func (m *AuthDisableResponse) String() string { return proto.CompactTextString(m) } -func (*AuthDisableResponse) ProtoMessage() {} +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 (m *AuthDisableResponse) GetHeader() *ResponseHeader { if m != nil { @@ -1407,11 +1721,14 @@ func (m *AuthDisableResponse) GetHeader() *ResponseHeader { type AuthenticateResponse struct { Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"` + // token is an authorized token that can be used in succeeding RPCs + Token string `protobuf:"bytes,2,opt,name=token,proto3" json:"token,omitempty"` } -func (m *AuthenticateResponse) Reset() { *m = AuthenticateResponse{} } -func (m *AuthenticateResponse) String() string { return proto.CompactTextString(m) } -func (*AuthenticateResponse) ProtoMessage() {} +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 (m *AuthenticateResponse) GetHeader() *ResponseHeader { if m != nil { @@ -1424,9 +1741,10 @@ type AuthUserAddResponse struct { Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"` } -func (m *AuthUserAddResponse) Reset() { *m = AuthUserAddResponse{} } -func (m *AuthUserAddResponse) String() string { return proto.CompactTextString(m) } -func (*AuthUserAddResponse) ProtoMessage() {} +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 (m *AuthUserAddResponse) GetHeader() *ResponseHeader { if m != nil { @@ -1437,11 +1755,13 @@ func (m *AuthUserAddResponse) GetHeader() *ResponseHeader { type AuthUserGetResponse struct { Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"` + Roles []string `protobuf:"bytes,2,rep,name=roles" json:"roles,omitempty"` } -func (m *AuthUserGetResponse) Reset() { *m = AuthUserGetResponse{} } -func (m *AuthUserGetResponse) String() string { return proto.CompactTextString(m) } -func (*AuthUserGetResponse) ProtoMessage() {} +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 (m *AuthUserGetResponse) GetHeader() *ResponseHeader { if m != nil { @@ -1454,9 +1774,10 @@ type AuthUserDeleteResponse struct { Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"` } -func (m *AuthUserDeleteResponse) Reset() { *m = AuthUserDeleteResponse{} } -func (m *AuthUserDeleteResponse) String() string { return proto.CompactTextString(m) } -func (*AuthUserDeleteResponse) ProtoMessage() {} +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 (m *AuthUserDeleteResponse) GetHeader() *ResponseHeader { if m != nil { @@ -1472,6 +1793,9 @@ type AuthUserChangePasswordResponse struct { func (m *AuthUserChangePasswordResponse) Reset() { *m = AuthUserChangePasswordResponse{} } func (m *AuthUserChangePasswordResponse) String() string { return proto.CompactTextString(m) } func (*AuthUserChangePasswordResponse) ProtoMessage() {} +func (*AuthUserChangePasswordResponse) Descriptor() ([]byte, []int) { + return fileDescriptorRpc, []int{66} +} func (m *AuthUserChangePasswordResponse) GetHeader() *ResponseHeader { if m != nil { @@ -1480,30 +1804,32 @@ func (m *AuthUserChangePasswordResponse) GetHeader() *ResponseHeader { return nil } -type AuthUserGrantResponse struct { +type AuthUserGrantRoleResponse struct { Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"` } -func (m *AuthUserGrantResponse) Reset() { *m = AuthUserGrantResponse{} } -func (m *AuthUserGrantResponse) String() string { return proto.CompactTextString(m) } -func (*AuthUserGrantResponse) ProtoMessage() {} +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 (m *AuthUserGrantResponse) GetHeader() *ResponseHeader { +func (m *AuthUserGrantRoleResponse) GetHeader() *ResponseHeader { if m != nil { return m.Header } return nil } -type AuthUserRevokeResponse struct { +type AuthUserRevokeRoleResponse struct { Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"` } -func (m *AuthUserRevokeResponse) Reset() { *m = AuthUserRevokeResponse{} } -func (m *AuthUserRevokeResponse) String() string { return proto.CompactTextString(m) } -func (*AuthUserRevokeResponse) ProtoMessage() {} +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 (m *AuthUserRevokeResponse) GetHeader() *ResponseHeader { +func (m *AuthUserRevokeRoleResponse) GetHeader() *ResponseHeader { if m != nil { return m.Header } @@ -1514,9 +1840,10 @@ type AuthRoleAddResponse struct { Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"` } -func (m *AuthRoleAddResponse) Reset() { *m = AuthRoleAddResponse{} } -func (m *AuthRoleAddResponse) String() string { return proto.CompactTextString(m) } -func (*AuthRoleAddResponse) ProtoMessage() {} +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 (m *AuthRoleAddResponse) GetHeader() *ResponseHeader { if m != nil { @@ -1526,12 +1853,14 @@ func (m *AuthRoleAddResponse) GetHeader() *ResponseHeader { } type AuthRoleGetResponse struct { - Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"` + Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"` + Perm []*authpb.Permission `protobuf:"bytes,2,rep,name=perm" json:"perm,omitempty"` } -func (m *AuthRoleGetResponse) Reset() { *m = AuthRoleGetResponse{} } -func (m *AuthRoleGetResponse) String() string { return proto.CompactTextString(m) } -func (*AuthRoleGetResponse) ProtoMessage() {} +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 (m *AuthRoleGetResponse) GetHeader() *ResponseHeader { if m != nil { @@ -1540,13 +1869,55 @@ func (m *AuthRoleGetResponse) GetHeader() *ResponseHeader { return nil } +func (m *AuthRoleGetResponse) GetPerm() []*authpb.Permission { + if m != nil { + return m.Perm + } + return nil +} + +type AuthRoleListResponse struct { + Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"` + Roles []string `protobuf:"bytes,2,rep,name=roles" json:"roles,omitempty"` +} + +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 (m *AuthRoleListResponse) GetHeader() *ResponseHeader { + if m != nil { + return m.Header + } + return nil +} + +type AuthUserListResponse struct { + Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"` + Users []string `protobuf:"bytes,2,rep,name=users" json:"users,omitempty"` +} + +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 (m *AuthUserListResponse) GetHeader() *ResponseHeader { + if m != nil { + return m.Header + } + return nil +} + type AuthRoleDeleteResponse struct { Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"` } -func (m *AuthRoleDeleteResponse) Reset() { *m = AuthRoleDeleteResponse{} } -func (m *AuthRoleDeleteResponse) String() string { return proto.CompactTextString(m) } -func (*AuthRoleDeleteResponse) ProtoMessage() {} +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 (m *AuthRoleDeleteResponse) GetHeader() *ResponseHeader { if m != nil { @@ -1555,30 +1926,36 @@ func (m *AuthRoleDeleteResponse) GetHeader() *ResponseHeader { return nil } -type AuthRoleGrantResponse struct { +type AuthRoleGrantPermissionResponse struct { Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"` } -func (m *AuthRoleGrantResponse) Reset() { *m = AuthRoleGrantResponse{} } -func (m *AuthRoleGrantResponse) String() string { return proto.CompactTextString(m) } -func (*AuthRoleGrantResponse) ProtoMessage() {} +func (m *AuthRoleGrantPermissionResponse) Reset() { *m = AuthRoleGrantPermissionResponse{} } +func (m *AuthRoleGrantPermissionResponse) String() string { return proto.CompactTextString(m) } +func (*AuthRoleGrantPermissionResponse) ProtoMessage() {} +func (*AuthRoleGrantPermissionResponse) Descriptor() ([]byte, []int) { + return fileDescriptorRpc, []int{74} +} -func (m *AuthRoleGrantResponse) GetHeader() *ResponseHeader { +func (m *AuthRoleGrantPermissionResponse) GetHeader() *ResponseHeader { if m != nil { return m.Header } return nil } -type AuthRoleRevokeResponse struct { +type AuthRoleRevokePermissionResponse struct { Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"` } -func (m *AuthRoleRevokeResponse) Reset() { *m = AuthRoleRevokeResponse{} } -func (m *AuthRoleRevokeResponse) String() string { return proto.CompactTextString(m) } -func (*AuthRoleRevokeResponse) ProtoMessage() {} +func (m *AuthRoleRevokePermissionResponse) Reset() { *m = AuthRoleRevokePermissionResponse{} } +func (m *AuthRoleRevokePermissionResponse) String() string { return proto.CompactTextString(m) } +func (*AuthRoleRevokePermissionResponse) ProtoMessage() {} +func (*AuthRoleRevokePermissionResponse) Descriptor() ([]byte, []int) { + return fileDescriptorRpc, []int{75} +} -func (m *AuthRoleRevokeResponse) GetHeader() *ResponseHeader { +func (m *AuthRoleRevokePermissionResponse) GetHeader() *ResponseHeader { if m != nil { return m.Header } @@ -1593,8 +1970,8 @@ func init() { proto.RegisterType((*PutResponse)(nil), "etcdserverpb.PutResponse") proto.RegisterType((*DeleteRangeRequest)(nil), "etcdserverpb.DeleteRangeRequest") proto.RegisterType((*DeleteRangeResponse)(nil), "etcdserverpb.DeleteRangeResponse") - proto.RegisterType((*RequestUnion)(nil), "etcdserverpb.RequestUnion") - proto.RegisterType((*ResponseUnion)(nil), "etcdserverpb.ResponseUnion") + proto.RegisterType((*RequestOp)(nil), "etcdserverpb.RequestOp") + proto.RegisterType((*ResponseOp)(nil), "etcdserverpb.ResponseOp") proto.RegisterType((*Compare)(nil), "etcdserverpb.Compare") proto.RegisterType((*TxnRequest)(nil), "etcdserverpb.TxnRequest") proto.RegisterType((*TxnResponse)(nil), "etcdserverpb.TxnResponse") @@ -1602,6 +1979,8 @@ func init() { proto.RegisterType((*CompactionResponse)(nil), "etcdserverpb.CompactionResponse") proto.RegisterType((*HashRequest)(nil), "etcdserverpb.HashRequest") proto.RegisterType((*HashResponse)(nil), "etcdserverpb.HashResponse") + proto.RegisterType((*SnapshotRequest)(nil), "etcdserverpb.SnapshotRequest") + proto.RegisterType((*SnapshotResponse)(nil), "etcdserverpb.SnapshotResponse") proto.RegisterType((*WatchRequest)(nil), "etcdserverpb.WatchRequest") proto.RegisterType((*WatchCreateRequest)(nil), "etcdserverpb.WatchCreateRequest") proto.RegisterType((*WatchCancelRequest)(nil), "etcdserverpb.WatchCancelRequest") @@ -1635,13 +2014,15 @@ func init() { proto.RegisterType((*AuthUserGetRequest)(nil), "etcdserverpb.AuthUserGetRequest") proto.RegisterType((*AuthUserDeleteRequest)(nil), "etcdserverpb.AuthUserDeleteRequest") proto.RegisterType((*AuthUserChangePasswordRequest)(nil), "etcdserverpb.AuthUserChangePasswordRequest") - proto.RegisterType((*AuthUserGrantRequest)(nil), "etcdserverpb.AuthUserGrantRequest") - proto.RegisterType((*AuthUserRevokeRequest)(nil), "etcdserverpb.AuthUserRevokeRequest") + proto.RegisterType((*AuthUserGrantRoleRequest)(nil), "etcdserverpb.AuthUserGrantRoleRequest") + proto.RegisterType((*AuthUserRevokeRoleRequest)(nil), "etcdserverpb.AuthUserRevokeRoleRequest") proto.RegisterType((*AuthRoleAddRequest)(nil), "etcdserverpb.AuthRoleAddRequest") proto.RegisterType((*AuthRoleGetRequest)(nil), "etcdserverpb.AuthRoleGetRequest") + proto.RegisterType((*AuthUserListRequest)(nil), "etcdserverpb.AuthUserListRequest") + proto.RegisterType((*AuthRoleListRequest)(nil), "etcdserverpb.AuthRoleListRequest") proto.RegisterType((*AuthRoleDeleteRequest)(nil), "etcdserverpb.AuthRoleDeleteRequest") - proto.RegisterType((*AuthRoleGrantRequest)(nil), "etcdserverpb.AuthRoleGrantRequest") - proto.RegisterType((*AuthRoleRevokeRequest)(nil), "etcdserverpb.AuthRoleRevokeRequest") + proto.RegisterType((*AuthRoleGrantPermissionRequest)(nil), "etcdserverpb.AuthRoleGrantPermissionRequest") + proto.RegisterType((*AuthRoleRevokePermissionRequest)(nil), "etcdserverpb.AuthRoleRevokePermissionRequest") proto.RegisterType((*AuthEnableResponse)(nil), "etcdserverpb.AuthEnableResponse") proto.RegisterType((*AuthDisableResponse)(nil), "etcdserverpb.AuthDisableResponse") proto.RegisterType((*AuthenticateResponse)(nil), "etcdserverpb.AuthenticateResponse") @@ -1649,13 +2030,15 @@ func init() { proto.RegisterType((*AuthUserGetResponse)(nil), "etcdserverpb.AuthUserGetResponse") proto.RegisterType((*AuthUserDeleteResponse)(nil), "etcdserverpb.AuthUserDeleteResponse") proto.RegisterType((*AuthUserChangePasswordResponse)(nil), "etcdserverpb.AuthUserChangePasswordResponse") - proto.RegisterType((*AuthUserGrantResponse)(nil), "etcdserverpb.AuthUserGrantResponse") - proto.RegisterType((*AuthUserRevokeResponse)(nil), "etcdserverpb.AuthUserRevokeResponse") + proto.RegisterType((*AuthUserGrantRoleResponse)(nil), "etcdserverpb.AuthUserGrantRoleResponse") + proto.RegisterType((*AuthUserRevokeRoleResponse)(nil), "etcdserverpb.AuthUserRevokeRoleResponse") proto.RegisterType((*AuthRoleAddResponse)(nil), "etcdserverpb.AuthRoleAddResponse") proto.RegisterType((*AuthRoleGetResponse)(nil), "etcdserverpb.AuthRoleGetResponse") + proto.RegisterType((*AuthRoleListResponse)(nil), "etcdserverpb.AuthRoleListResponse") + proto.RegisterType((*AuthUserListResponse)(nil), "etcdserverpb.AuthUserListResponse") proto.RegisterType((*AuthRoleDeleteResponse)(nil), "etcdserverpb.AuthRoleDeleteResponse") - proto.RegisterType((*AuthRoleGrantResponse)(nil), "etcdserverpb.AuthRoleGrantResponse") - proto.RegisterType((*AuthRoleRevokeResponse)(nil), "etcdserverpb.AuthRoleRevokeResponse") + proto.RegisterType((*AuthRoleGrantPermissionResponse)(nil), "etcdserverpb.AuthRoleGrantPermissionResponse") + proto.RegisterType((*AuthRoleRevokePermissionResponse)(nil), "etcdserverpb.AuthRoleRevokePermissionResponse") proto.RegisterEnum("etcdserverpb.AlarmType", AlarmType_name, AlarmType_value) proto.RegisterEnum("etcdserverpb.RangeRequest_SortOrder", RangeRequest_SortOrder_name, RangeRequest_SortOrder_value) proto.RegisterEnum("etcdserverpb.RangeRequest_SortTarget", RangeRequest_SortTarget_name, RangeRequest_SortTarget_value) @@ -1668,26 +2051,31 @@ func init() { var _ context.Context 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 + // Client API for KV service type KVClient interface { - // Range gets the keys in the range from the store. + // Range gets the keys in the range from the key-value store. Range(ctx context.Context, in *RangeRequest, opts ...grpc.CallOption) (*RangeResponse, error) - // Put puts the given key into the store. - // A put request increases the revision of the store, + // Put puts the given key into the key-value store. + // A put request increments the revision of the key-value store // and generates one event in the event history. Put(ctx context.Context, in *PutRequest, opts ...grpc.CallOption) (*PutResponse, error) - // Delete deletes the given range from the store. - // A delete request increase the revision of the store, - // and generates one event in the event history. + // DeleteRange deletes the given range from the key-value store. + // A delete request increments the revision of the key-value store + // and generates a delete event in the event history for every deleted key. DeleteRange(ctx context.Context, in *DeleteRangeRequest, opts ...grpc.CallOption) (*DeleteRangeResponse, error) - // Txn processes all the requests in one transaction. - // A txn request increases the revision of the store, - // and generates events with the same revision in the event history. + // Txn processes multiple requests in a single transaction. + // A txn request increments the revision of the key-value store + // and generates events with the same revision for every completed request. // It is not allowed to modify the same key several times within one txn. Txn(ctx context.Context, in *TxnRequest, opts ...grpc.CallOption) (*TxnResponse, error) - // Compact compacts the event history in etcd. User should compact the - // event history periodically, or it will grow infinitely. + // Compact compacts the event history in the etcd key-value store. The key-value + // store should be periodically compacted or the event history will continue to grow + // indefinitely. Compact(ctx context.Context, in *CompactionRequest, opts ...grpc.CallOption) (*CompactionResponse, error) } @@ -1747,23 +2135,24 @@ func (c *kVClient) Compact(ctx context.Context, in *CompactionRequest, opts ...g // Server API for KV service type KVServer interface { - // Range gets the keys in the range from the store. + // Range gets the keys in the range from the key-value store. Range(context.Context, *RangeRequest) (*RangeResponse, error) - // Put puts the given key into the store. - // A put request increases the revision of the store, + // Put puts the given key into the key-value store. + // A put request increments the revision of the key-value store // and generates one event in the event history. Put(context.Context, *PutRequest) (*PutResponse, error) - // Delete deletes the given range from the store. - // A delete request increase the revision of the store, - // and generates one event in the event history. + // DeleteRange deletes the given range from the key-value store. + // A delete request increments the revision of the key-value store + // and generates a delete event in the event history for every deleted key. DeleteRange(context.Context, *DeleteRangeRequest) (*DeleteRangeResponse, error) - // Txn processes all the requests in one transaction. - // A txn request increases the revision of the store, - // and generates events with the same revision in the event history. + // Txn processes multiple requests in a single transaction. + // A txn request increments the revision of the key-value store + // and generates events with the same revision for every completed request. // It is not allowed to modify the same key several times within one txn. Txn(context.Context, *TxnRequest) (*TxnResponse, error) - // Compact compacts the event history in etcd. User should compact the - // event history periodically, or it will grow infinitely. + // Compact compacts the event history in the etcd key-value store. The key-value + // store should be periodically compacted or the event history will continue to grow + // indefinitely. Compact(context.Context, *CompactionRequest) (*CompactionResponse, error) } @@ -1771,64 +2160,94 @@ func RegisterKVServer(s *grpc.Server, srv KVServer) { s.RegisterService(&_KV_serviceDesc, srv) } -func _KV_Range_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) { +func _KV_Range_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(RangeRequest) if err := dec(in); err != nil { return nil, err } - out, err := srv.(KVServer).Range(ctx, in) - if err != nil { - return nil, err + if interceptor == nil { + return srv.(KVServer).Range(ctx, in) } - return out, nil + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/etcdserverpb.KV/Range", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(KVServer).Range(ctx, req.(*RangeRequest)) + } + return interceptor(ctx, in, info, handler) } -func _KV_Put_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) { +func _KV_Put_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(PutRequest) if err := dec(in); err != nil { return nil, err } - out, err := srv.(KVServer).Put(ctx, in) - if err != nil { - return nil, err + if interceptor == nil { + return srv.(KVServer).Put(ctx, in) } - return out, nil + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/etcdserverpb.KV/Put", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(KVServer).Put(ctx, req.(*PutRequest)) + } + return interceptor(ctx, in, info, handler) } -func _KV_DeleteRange_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) { +func _KV_DeleteRange_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(DeleteRangeRequest) if err := dec(in); err != nil { return nil, err } - out, err := srv.(KVServer).DeleteRange(ctx, in) - if err != nil { - return nil, err + if interceptor == nil { + return srv.(KVServer).DeleteRange(ctx, in) } - return out, nil + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/etcdserverpb.KV/DeleteRange", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(KVServer).DeleteRange(ctx, req.(*DeleteRangeRequest)) + } + return interceptor(ctx, in, info, handler) } -func _KV_Txn_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) { +func _KV_Txn_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(TxnRequest) if err := dec(in); err != nil { return nil, err } - out, err := srv.(KVServer).Txn(ctx, in) - if err != nil { - return nil, err + if interceptor == nil { + return srv.(KVServer).Txn(ctx, in) } - return out, nil + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/etcdserverpb.KV/Txn", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(KVServer).Txn(ctx, req.(*TxnRequest)) + } + return interceptor(ctx, in, info, handler) } -func _KV_Compact_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) { +func _KV_Compact_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(CompactionRequest) if err := dec(in); err != nil { return nil, err } - out, err := srv.(KVServer).Compact(ctx, in) - if err != nil { - return nil, err + if interceptor == nil { + return srv.(KVServer).Compact(ctx, in) } - return out, nil + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/etcdserverpb.KV/Compact", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(KVServer).Compact(ctx, req.(*CompactionRequest)) + } + return interceptor(ctx, in, info, handler) } var _KV_serviceDesc = grpc.ServiceDesc{ @@ -1856,16 +2275,18 @@ var _KV_serviceDesc = grpc.ServiceDesc{ Handler: _KV_Compact_Handler, }, }, - Streams: []grpc.StreamDesc{}, + Streams: []grpc.StreamDesc{}, + Metadata: fileDescriptorRpc, } // Client API for Watch service type WatchClient interface { - // Watch watches the events happening or happened. Both input and output - // are stream. One watch rpc can watch for multiple keys or prefixs and - // get a stream of events. The whole events history can be watched unless - // compacted. + // Watch watches for events happening or that have happened. Both input and output + // are streams; the input stream is for creating and canceling watchers and the output + // stream sends events. One watch RPC can watch on multiple key ranges, streaming events + // for several watches at once. The entire event history can be watched starting from the + // last compaction revision. Watch(ctx context.Context, opts ...grpc.CallOption) (Watch_WatchClient, error) } @@ -1911,10 +2332,11 @@ func (x *watchWatchClient) Recv() (*WatchResponse, error) { // Server API for Watch service type WatchServer interface { - // Watch watches the events happening or happened. Both input and output - // are stream. One watch rpc can watch for multiple keys or prefixs and - // get a stream of events. The whole events history can be watched unless - // compacted. + // Watch watches for events happening or that have happened. Both input and output + // are streams; the input stream is for creating and canceling watchers and the output + // stream sends events. One watch RPC can watch on multiple key ranges, streaming events + // for several watches at once. The entire event history can be watched starting from the + // last compaction revision. Watch(Watch_WatchServer) error } @@ -1960,19 +2382,20 @@ var _Watch_serviceDesc = grpc.ServiceDesc{ ClientStreams: true, }, }, + Metadata: fileDescriptorRpc, } // Client API for Lease service type LeaseClient interface { - // LeaseGrant creates a lease. A lease has a TTL. The lease will expire if the - // server does not receive a keepAlive within TTL from the lease holder. - // All keys attached to the lease will be expired and deleted if the lease expires. - // The key expiration generates an event in event history. + // LeaseGrant creates a lease which expires if the server does not receive a keepAlive + // within a given time to live period. All keys attached to the lease will be expired and + // deleted if the lease expires. Each expired key generates a delete event in the event history. LeaseGrant(ctx context.Context, in *LeaseGrantRequest, opts ...grpc.CallOption) (*LeaseGrantResponse, error) - // LeaseRevoke revokes a lease. All the key attached to the lease will be expired and deleted. + // LeaseRevoke revokes a lease. All keys attached to the lease will expire and be deleted. LeaseRevoke(ctx context.Context, in *LeaseRevokeRequest, opts ...grpc.CallOption) (*LeaseRevokeResponse, error) - // KeepAlive keeps the lease alive. + // 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) } @@ -2036,14 +2459,14 @@ func (x *leaseLeaseKeepAliveClient) Recv() (*LeaseKeepAliveResponse, error) { // Server API for Lease service type LeaseServer interface { - // LeaseGrant creates a lease. A lease has a TTL. The lease will expire if the - // server does not receive a keepAlive within TTL from the lease holder. - // All keys attached to the lease will be expired and deleted if the lease expires. - // The key expiration generates an event in event history. + // LeaseGrant creates a lease which expires if the server does not receive a keepAlive + // within a given time to live period. All keys attached to the lease will be expired and + // deleted if the lease expires. Each expired key generates a delete event in the event history. LeaseGrant(context.Context, *LeaseGrantRequest) (*LeaseGrantResponse, error) - // LeaseRevoke revokes a lease. All the key attached to the lease will be expired and deleted. + // LeaseRevoke revokes a lease. All keys attached to the lease will expire and be deleted. LeaseRevoke(context.Context, *LeaseRevokeRequest) (*LeaseRevokeResponse, error) - // KeepAlive keeps the lease alive. + // 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 } @@ -2051,28 +2474,40 @@ func RegisterLeaseServer(s *grpc.Server, srv LeaseServer) { s.RegisterService(&_Lease_serviceDesc, srv) } -func _Lease_LeaseGrant_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) { +func _Lease_LeaseGrant_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(LeaseGrantRequest) if err := dec(in); err != nil { return nil, err } - out, err := srv.(LeaseServer).LeaseGrant(ctx, in) - if err != nil { - return nil, err + if interceptor == nil { + return srv.(LeaseServer).LeaseGrant(ctx, in) } - return out, nil + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/etcdserverpb.Lease/LeaseGrant", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(LeaseServer).LeaseGrant(ctx, req.(*LeaseGrantRequest)) + } + return interceptor(ctx, in, info, handler) } -func _Lease_LeaseRevoke_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) { +func _Lease_LeaseRevoke_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(LeaseRevokeRequest) if err := dec(in); err != nil { return nil, err } - out, err := srv.(LeaseServer).LeaseRevoke(ctx, in) - if err != nil { - return nil, err + if interceptor == nil { + return srv.(LeaseServer).LeaseRevoke(ctx, in) } - return out, nil + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/etcdserverpb.Lease/LeaseRevoke", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(LeaseServer).LeaseRevoke(ctx, req.(*LeaseRevokeRequest)) + } + return interceptor(ctx, in, info, handler) } func _Lease_LeaseKeepAlive_Handler(srv interface{}, stream grpc.ServerStream) error { @@ -2122,6 +2557,7 @@ var _Lease_serviceDesc = grpc.ServiceDesc{ ClientStreams: true, }, }, + Metadata: fileDescriptorRpc, } // Client API for Cluster service @@ -2198,52 +2634,76 @@ func RegisterClusterServer(s *grpc.Server, srv ClusterServer) { s.RegisterService(&_Cluster_serviceDesc, srv) } -func _Cluster_MemberAdd_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) { +func _Cluster_MemberAdd_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(MemberAddRequest) if err := dec(in); err != nil { return nil, err } - out, err := srv.(ClusterServer).MemberAdd(ctx, in) - if err != nil { - return nil, err + if interceptor == nil { + return srv.(ClusterServer).MemberAdd(ctx, in) } - return out, nil + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/etcdserverpb.Cluster/MemberAdd", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ClusterServer).MemberAdd(ctx, req.(*MemberAddRequest)) + } + return interceptor(ctx, in, info, handler) } -func _Cluster_MemberRemove_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) { +func _Cluster_MemberRemove_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(MemberRemoveRequest) if err := dec(in); err != nil { return nil, err } - out, err := srv.(ClusterServer).MemberRemove(ctx, in) - if err != nil { - return nil, err + if interceptor == nil { + return srv.(ClusterServer).MemberRemove(ctx, in) } - return out, nil + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/etcdserverpb.Cluster/MemberRemove", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ClusterServer).MemberRemove(ctx, req.(*MemberRemoveRequest)) + } + return interceptor(ctx, in, info, handler) } -func _Cluster_MemberUpdate_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) { +func _Cluster_MemberUpdate_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(MemberUpdateRequest) if err := dec(in); err != nil { return nil, err } - out, err := srv.(ClusterServer).MemberUpdate(ctx, in) - if err != nil { - return nil, err + if interceptor == nil { + return srv.(ClusterServer).MemberUpdate(ctx, in) } - return out, nil + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/etcdserverpb.Cluster/MemberUpdate", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ClusterServer).MemberUpdate(ctx, req.(*MemberUpdateRequest)) + } + return interceptor(ctx, in, info, handler) } -func _Cluster_MemberList_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) { +func _Cluster_MemberList_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(MemberListRequest) if err := dec(in); err != nil { return nil, err } - out, err := srv.(ClusterServer).MemberList(ctx, in) - if err != nil { - return nil, err + if interceptor == nil { + return srv.(ClusterServer).MemberList(ctx, in) } - return out, nil + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/etcdserverpb.Cluster/MemberList", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ClusterServer).MemberList(ctx, req.(*MemberListRequest)) + } + return interceptor(ctx, in, info, handler) } var _Cluster_serviceDesc = grpc.ServiceDesc{ @@ -2267,7 +2727,8 @@ var _Cluster_serviceDesc = grpc.ServiceDesc{ Handler: _Cluster_MemberList_Handler, }, }, - Streams: []grpc.StreamDesc{}, + Streams: []grpc.StreamDesc{}, + Metadata: fileDescriptorRpc, } // Client API for Maintenance service @@ -2277,11 +2738,14 @@ type MaintenanceClient interface { Alarm(ctx context.Context, in *AlarmRequest, opts ...grpc.CallOption) (*AlarmResponse, error) // Status gets the status of the member. Status(ctx context.Context, in *StatusRequest, opts ...grpc.CallOption) (*StatusResponse, error) + // Defragment defragments a member's backend database to recover storage space. Defragment(ctx context.Context, in *DefragmentRequest, opts ...grpc.CallOption) (*DefragmentResponse, error) // Hash returns the hash of the local KV state for consistency checking purpose. // This is designed for testing; do not use this in production when there // are ongoing transactions. Hash(ctx context.Context, in *HashRequest, opts ...grpc.CallOption) (*HashResponse, error) + // Snapshot sends a snapshot of the entire backend from a member over a stream to a client. + Snapshot(ctx context.Context, in *SnapshotRequest, opts ...grpc.CallOption) (Maintenance_SnapshotClient, error) } type maintenanceClient struct { @@ -2328,6 +2792,38 @@ func (c *maintenanceClient) Hash(ctx context.Context, in *HashRequest, opts ...g return out, nil } +func (c *maintenanceClient) Snapshot(ctx context.Context, in *SnapshotRequest, opts ...grpc.CallOption) (Maintenance_SnapshotClient, error) { + stream, err := grpc.NewClientStream(ctx, &_Maintenance_serviceDesc.Streams[0], c.cc, "/etcdserverpb.Maintenance/Snapshot", opts...) + if err != nil { + return nil, err + } + x := &maintenanceSnapshotClient{stream} + if err := x.ClientStream.SendMsg(in); err != nil { + return nil, err + } + if err := x.ClientStream.CloseSend(); err != nil { + return nil, err + } + return x, nil +} + +type Maintenance_SnapshotClient interface { + Recv() (*SnapshotResponse, error) + grpc.ClientStream +} + +type maintenanceSnapshotClient struct { + grpc.ClientStream +} + +func (x *maintenanceSnapshotClient) Recv() (*SnapshotResponse, error) { + m := new(SnapshotResponse) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + // Server API for Maintenance service type MaintenanceServer interface { @@ -2335,63 +2831,111 @@ type MaintenanceServer interface { Alarm(context.Context, *AlarmRequest) (*AlarmResponse, error) // Status gets the status of the member. Status(context.Context, *StatusRequest) (*StatusResponse, error) + // Defragment defragments a member's backend database to recover storage space. Defragment(context.Context, *DefragmentRequest) (*DefragmentResponse, error) // Hash returns the hash of the local KV state for consistency checking purpose. // This is designed for testing; do not use this in production when there // are ongoing transactions. Hash(context.Context, *HashRequest) (*HashResponse, error) + // Snapshot sends a snapshot of the entire backend from a member over a stream to a client. + Snapshot(*SnapshotRequest, Maintenance_SnapshotServer) error } func RegisterMaintenanceServer(s *grpc.Server, srv MaintenanceServer) { s.RegisterService(&_Maintenance_serviceDesc, srv) } -func _Maintenance_Alarm_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) { +func _Maintenance_Alarm_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(AlarmRequest) if err := dec(in); err != nil { return nil, err } - out, err := srv.(MaintenanceServer).Alarm(ctx, in) - if err != nil { - return nil, err + if interceptor == nil { + return srv.(MaintenanceServer).Alarm(ctx, in) } - return out, nil + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/etcdserverpb.Maintenance/Alarm", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MaintenanceServer).Alarm(ctx, req.(*AlarmRequest)) + } + return interceptor(ctx, in, info, handler) } -func _Maintenance_Status_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) { +func _Maintenance_Status_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(StatusRequest) if err := dec(in); err != nil { return nil, err } - out, err := srv.(MaintenanceServer).Status(ctx, in) - if err != nil { - return nil, err + if interceptor == nil { + return srv.(MaintenanceServer).Status(ctx, in) } - return out, nil + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/etcdserverpb.Maintenance/Status", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MaintenanceServer).Status(ctx, req.(*StatusRequest)) + } + return interceptor(ctx, in, info, handler) } -func _Maintenance_Defragment_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) { +func _Maintenance_Defragment_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(DefragmentRequest) if err := dec(in); err != nil { return nil, err } - out, err := srv.(MaintenanceServer).Defragment(ctx, in) - if err != nil { - return nil, err + if interceptor == nil { + return srv.(MaintenanceServer).Defragment(ctx, in) } - return out, nil + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/etcdserverpb.Maintenance/Defragment", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MaintenanceServer).Defragment(ctx, req.(*DefragmentRequest)) + } + return interceptor(ctx, in, info, handler) } -func _Maintenance_Hash_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) { +func _Maintenance_Hash_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(HashRequest) if err := dec(in); err != nil { return nil, err } - out, err := srv.(MaintenanceServer).Hash(ctx, in) - if err != nil { - return nil, err + if interceptor == nil { + return srv.(MaintenanceServer).Hash(ctx, in) } - return out, nil + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/etcdserverpb.Maintenance/Hash", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MaintenanceServer).Hash(ctx, req.(*HashRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Maintenance_Snapshot_Handler(srv interface{}, stream grpc.ServerStream) error { + m := new(SnapshotRequest) + if err := stream.RecvMsg(m); err != nil { + return err + } + return srv.(MaintenanceServer).Snapshot(m, &maintenanceSnapshotServer{stream}) +} + +type Maintenance_SnapshotServer interface { + Send(*SnapshotResponse) error + grpc.ServerStream +} + +type maintenanceSnapshotServer struct { + grpc.ServerStream +} + +func (x *maintenanceSnapshotServer) Send(m *SnapshotResponse) error { + return x.ServerStream.SendMsg(m) } var _Maintenance_serviceDesc = grpc.ServiceDesc{ @@ -2415,7 +2959,14 @@ var _Maintenance_serviceDesc = grpc.ServiceDesc{ Handler: _Maintenance_Hash_Handler, }, }, - Streams: []grpc.StreamDesc{}, + Streams: []grpc.StreamDesc{ + { + StreamName: "Snapshot", + Handler: _Maintenance_Snapshot_Handler, + ServerStreams: true, + }, + }, + Metadata: fileDescriptorRpc, } // Client API for Auth service @@ -2425,30 +2976,34 @@ type AuthClient interface { AuthEnable(ctx context.Context, in *AuthEnableRequest, opts ...grpc.CallOption) (*AuthEnableResponse, error) // AuthDisable disables authentication. AuthDisable(ctx context.Context, in *AuthDisableRequest, opts ...grpc.CallOption) (*AuthDisableResponse, error) - // Authenticate processes authenticate request. + // Authenticate processes an authenticate request. Authenticate(ctx context.Context, in *AuthenticateRequest, opts ...grpc.CallOption) (*AuthenticateResponse, error) // UserAdd adds a new user. UserAdd(ctx context.Context, in *AuthUserAddRequest, opts ...grpc.CallOption) (*AuthUserAddResponse, error) - // UserGet gets a detailed information of a user or lists entire users. + // UserGet gets detailed user information. UserGet(ctx context.Context, in *AuthUserGetRequest, opts ...grpc.CallOption) (*AuthUserGetResponse, error) + // UserList gets a list of all users. + UserList(ctx context.Context, in *AuthUserListRequest, opts ...grpc.CallOption) (*AuthUserListResponse, error) // UserDelete deletes a specified user. UserDelete(ctx context.Context, in *AuthUserDeleteRequest, opts ...grpc.CallOption) (*AuthUserDeleteResponse, error) - // UserChangePassword changes password of a specified user. + // UserChangePassword changes the password of a specified user. UserChangePassword(ctx context.Context, in *AuthUserChangePasswordRequest, opts ...grpc.CallOption) (*AuthUserChangePasswordResponse, error) // UserGrant grants a role to a specified user. - UserGrant(ctx context.Context, in *AuthUserGrantRequest, opts ...grpc.CallOption) (*AuthUserGrantResponse, error) - // UserRevoke revokes a role of specified user. - UserRevoke(ctx context.Context, in *AuthUserRevokeRequest, opts ...grpc.CallOption) (*AuthUserRevokeResponse, error) + UserGrantRole(ctx context.Context, in *AuthUserGrantRoleRequest, opts ...grpc.CallOption) (*AuthUserGrantRoleResponse, error) + // UserRevokeRole revokes a role of specified user. + UserRevokeRole(ctx context.Context, in *AuthUserRevokeRoleRequest, opts ...grpc.CallOption) (*AuthUserRevokeRoleResponse, error) // RoleAdd adds a new role. RoleAdd(ctx context.Context, in *AuthRoleAddRequest, opts ...grpc.CallOption) (*AuthRoleAddResponse, error) - // RoleGet gets a detailed information of a role or lists entire roles. + // RoleGet gets detailed role information. RoleGet(ctx context.Context, in *AuthRoleGetRequest, opts ...grpc.CallOption) (*AuthRoleGetResponse, error) + // RoleList gets lists of all roles. + RoleList(ctx context.Context, in *AuthRoleListRequest, opts ...grpc.CallOption) (*AuthRoleListResponse, error) // RoleDelete deletes a specified role. RoleDelete(ctx context.Context, in *AuthRoleDeleteRequest, opts ...grpc.CallOption) (*AuthRoleDeleteResponse, error) - // RoleGrant grants a permission of a specified key or range to a specified role. - RoleGrant(ctx context.Context, in *AuthRoleGrantRequest, opts ...grpc.CallOption) (*AuthRoleGrantResponse, error) - // RoleRevoke revokes a key or range permission of a specified role. - RoleRevoke(ctx context.Context, in *AuthRoleRevokeRequest, opts ...grpc.CallOption) (*AuthRoleRevokeResponse, error) + // RoleGrantPermission grants a permission of a specified key or range to a specified role. + RoleGrantPermission(ctx context.Context, in *AuthRoleGrantPermissionRequest, opts ...grpc.CallOption) (*AuthRoleGrantPermissionResponse, error) + // RoleRevokePermission revokes a key or range permission of a specified role. + RoleRevokePermission(ctx context.Context, in *AuthRoleRevokePermissionRequest, opts ...grpc.CallOption) (*AuthRoleRevokePermissionResponse, error) } type authClient struct { @@ -2504,6 +3059,15 @@ func (c *authClient) UserGet(ctx context.Context, in *AuthUserGetRequest, opts . return out, nil } +func (c *authClient) UserList(ctx context.Context, in *AuthUserListRequest, opts ...grpc.CallOption) (*AuthUserListResponse, error) { + out := new(AuthUserListResponse) + err := grpc.Invoke(ctx, "/etcdserverpb.Auth/UserList", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *authClient) UserDelete(ctx context.Context, in *AuthUserDeleteRequest, opts ...grpc.CallOption) (*AuthUserDeleteResponse, error) { out := new(AuthUserDeleteResponse) err := grpc.Invoke(ctx, "/etcdserverpb.Auth/UserDelete", in, out, c.cc, opts...) @@ -2522,18 +3086,18 @@ func (c *authClient) UserChangePassword(ctx context.Context, in *AuthUserChangeP return out, nil } -func (c *authClient) UserGrant(ctx context.Context, in *AuthUserGrantRequest, opts ...grpc.CallOption) (*AuthUserGrantResponse, error) { - out := new(AuthUserGrantResponse) - err := grpc.Invoke(ctx, "/etcdserverpb.Auth/UserGrant", in, out, c.cc, opts...) +func (c *authClient) UserGrantRole(ctx context.Context, in *AuthUserGrantRoleRequest, opts ...grpc.CallOption) (*AuthUserGrantRoleResponse, error) { + out := new(AuthUserGrantRoleResponse) + err := grpc.Invoke(ctx, "/etcdserverpb.Auth/UserGrantRole", in, out, c.cc, opts...) if err != nil { return nil, err } return out, nil } -func (c *authClient) UserRevoke(ctx context.Context, in *AuthUserRevokeRequest, opts ...grpc.CallOption) (*AuthUserRevokeResponse, error) { - out := new(AuthUserRevokeResponse) - err := grpc.Invoke(ctx, "/etcdserverpb.Auth/UserRevoke", in, out, c.cc, opts...) +func (c *authClient) UserRevokeRole(ctx context.Context, in *AuthUserRevokeRoleRequest, opts ...grpc.CallOption) (*AuthUserRevokeRoleResponse, error) { + out := new(AuthUserRevokeRoleResponse) + err := grpc.Invoke(ctx, "/etcdserverpb.Auth/UserRevokeRole", in, out, c.cc, opts...) if err != nil { return nil, err } @@ -2558,6 +3122,15 @@ func (c *authClient) RoleGet(ctx context.Context, in *AuthRoleGetRequest, opts . return out, nil } +func (c *authClient) RoleList(ctx context.Context, in *AuthRoleListRequest, opts ...grpc.CallOption) (*AuthRoleListResponse, error) { + out := new(AuthRoleListResponse) + err := grpc.Invoke(ctx, "/etcdserverpb.Auth/RoleList", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *authClient) RoleDelete(ctx context.Context, in *AuthRoleDeleteRequest, opts ...grpc.CallOption) (*AuthRoleDeleteResponse, error) { out := new(AuthRoleDeleteResponse) err := grpc.Invoke(ctx, "/etcdserverpb.Auth/RoleDelete", in, out, c.cc, opts...) @@ -2567,18 +3140,18 @@ func (c *authClient) RoleDelete(ctx context.Context, in *AuthRoleDeleteRequest, return out, nil } -func (c *authClient) RoleGrant(ctx context.Context, in *AuthRoleGrantRequest, opts ...grpc.CallOption) (*AuthRoleGrantResponse, error) { - out := new(AuthRoleGrantResponse) - err := grpc.Invoke(ctx, "/etcdserverpb.Auth/RoleGrant", in, out, c.cc, opts...) +func (c *authClient) RoleGrantPermission(ctx context.Context, in *AuthRoleGrantPermissionRequest, opts ...grpc.CallOption) (*AuthRoleGrantPermissionResponse, error) { + out := new(AuthRoleGrantPermissionResponse) + err := grpc.Invoke(ctx, "/etcdserverpb.Auth/RoleGrantPermission", in, out, c.cc, opts...) if err != nil { return nil, err } return out, nil } -func (c *authClient) RoleRevoke(ctx context.Context, in *AuthRoleRevokeRequest, opts ...grpc.CallOption) (*AuthRoleRevokeResponse, error) { - out := new(AuthRoleRevokeResponse) - err := grpc.Invoke(ctx, "/etcdserverpb.Auth/RoleRevoke", in, out, c.cc, opts...) +func (c *authClient) RoleRevokePermission(ctx context.Context, in *AuthRoleRevokePermissionRequest, opts ...grpc.CallOption) (*AuthRoleRevokePermissionResponse, error) { + out := new(AuthRoleRevokePermissionResponse) + err := grpc.Invoke(ctx, "/etcdserverpb.Auth/RoleRevokePermission", in, out, c.cc, opts...) if err != nil { return nil, err } @@ -2592,202 +3165,326 @@ type AuthServer interface { AuthEnable(context.Context, *AuthEnableRequest) (*AuthEnableResponse, error) // AuthDisable disables authentication. AuthDisable(context.Context, *AuthDisableRequest) (*AuthDisableResponse, error) - // Authenticate processes authenticate request. + // Authenticate processes an authenticate request. Authenticate(context.Context, *AuthenticateRequest) (*AuthenticateResponse, error) // UserAdd adds a new user. UserAdd(context.Context, *AuthUserAddRequest) (*AuthUserAddResponse, error) - // UserGet gets a detailed information of a user or lists entire users. + // UserGet gets detailed user information. UserGet(context.Context, *AuthUserGetRequest) (*AuthUserGetResponse, error) + // UserList gets a list of all users. + UserList(context.Context, *AuthUserListRequest) (*AuthUserListResponse, error) // UserDelete deletes a specified user. UserDelete(context.Context, *AuthUserDeleteRequest) (*AuthUserDeleteResponse, error) - // UserChangePassword changes password of a specified user. + // UserChangePassword changes the password of a specified user. UserChangePassword(context.Context, *AuthUserChangePasswordRequest) (*AuthUserChangePasswordResponse, error) // UserGrant grants a role to a specified user. - UserGrant(context.Context, *AuthUserGrantRequest) (*AuthUserGrantResponse, error) - // UserRevoke revokes a role of specified user. - UserRevoke(context.Context, *AuthUserRevokeRequest) (*AuthUserRevokeResponse, error) + UserGrantRole(context.Context, *AuthUserGrantRoleRequest) (*AuthUserGrantRoleResponse, error) + // UserRevokeRole revokes a role of specified user. + UserRevokeRole(context.Context, *AuthUserRevokeRoleRequest) (*AuthUserRevokeRoleResponse, error) // RoleAdd adds a new role. RoleAdd(context.Context, *AuthRoleAddRequest) (*AuthRoleAddResponse, error) - // RoleGet gets a detailed information of a role or lists entire roles. + // RoleGet gets detailed role information. RoleGet(context.Context, *AuthRoleGetRequest) (*AuthRoleGetResponse, error) + // RoleList gets lists of all roles. + RoleList(context.Context, *AuthRoleListRequest) (*AuthRoleListResponse, error) // RoleDelete deletes a specified role. RoleDelete(context.Context, *AuthRoleDeleteRequest) (*AuthRoleDeleteResponse, error) - // RoleGrant grants a permission of a specified key or range to a specified role. - RoleGrant(context.Context, *AuthRoleGrantRequest) (*AuthRoleGrantResponse, error) - // RoleRevoke revokes a key or range permission of a specified role. - RoleRevoke(context.Context, *AuthRoleRevokeRequest) (*AuthRoleRevokeResponse, error) + // RoleGrantPermission grants a permission of a specified key or range to a specified role. + RoleGrantPermission(context.Context, *AuthRoleGrantPermissionRequest) (*AuthRoleGrantPermissionResponse, error) + // RoleRevokePermission revokes a key or range permission of a specified role. + RoleRevokePermission(context.Context, *AuthRoleRevokePermissionRequest) (*AuthRoleRevokePermissionResponse, error) } func RegisterAuthServer(s *grpc.Server, srv AuthServer) { s.RegisterService(&_Auth_serviceDesc, srv) } -func _Auth_AuthEnable_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) { +func _Auth_AuthEnable_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(AuthEnableRequest) if err := dec(in); err != nil { return nil, err } - out, err := srv.(AuthServer).AuthEnable(ctx, in) - if err != nil { - return nil, err + if interceptor == nil { + return srv.(AuthServer).AuthEnable(ctx, in) } - return out, nil + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/etcdserverpb.Auth/AuthEnable", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AuthServer).AuthEnable(ctx, req.(*AuthEnableRequest)) + } + return interceptor(ctx, in, info, handler) } -func _Auth_AuthDisable_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) { +func _Auth_AuthDisable_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(AuthDisableRequest) if err := dec(in); err != nil { return nil, err } - out, err := srv.(AuthServer).AuthDisable(ctx, in) - if err != nil { - return nil, err + if interceptor == nil { + return srv.(AuthServer).AuthDisable(ctx, in) } - return out, nil + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/etcdserverpb.Auth/AuthDisable", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AuthServer).AuthDisable(ctx, req.(*AuthDisableRequest)) + } + return interceptor(ctx, in, info, handler) } -func _Auth_Authenticate_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) { +func _Auth_Authenticate_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(AuthenticateRequest) if err := dec(in); err != nil { return nil, err } - out, err := srv.(AuthServer).Authenticate(ctx, in) - if err != nil { - return nil, err + if interceptor == nil { + return srv.(AuthServer).Authenticate(ctx, in) } - return out, nil + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/etcdserverpb.Auth/Authenticate", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AuthServer).Authenticate(ctx, req.(*AuthenticateRequest)) + } + return interceptor(ctx, in, info, handler) } -func _Auth_UserAdd_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) { +func _Auth_UserAdd_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(AuthUserAddRequest) if err := dec(in); err != nil { return nil, err } - out, err := srv.(AuthServer).UserAdd(ctx, in) - if err != nil { - return nil, err + if interceptor == nil { + return srv.(AuthServer).UserAdd(ctx, in) } - return out, nil + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/etcdserverpb.Auth/UserAdd", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AuthServer).UserAdd(ctx, req.(*AuthUserAddRequest)) + } + return interceptor(ctx, in, info, handler) } -func _Auth_UserGet_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) { +func _Auth_UserGet_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(AuthUserGetRequest) if err := dec(in); err != nil { return nil, err } - out, err := srv.(AuthServer).UserGet(ctx, in) - if err != nil { - return nil, err + if interceptor == nil { + return srv.(AuthServer).UserGet(ctx, in) } - return out, nil + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/etcdserverpb.Auth/UserGet", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AuthServer).UserGet(ctx, req.(*AuthUserGetRequest)) + } + return interceptor(ctx, in, info, handler) } -func _Auth_UserDelete_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) { +func _Auth_UserList_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(AuthUserListRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AuthServer).UserList(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/etcdserverpb.Auth/UserList", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AuthServer).UserList(ctx, req.(*AuthUserListRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Auth_UserDelete_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(AuthUserDeleteRequest) if err := dec(in); err != nil { return nil, err } - out, err := srv.(AuthServer).UserDelete(ctx, in) - if err != nil { - return nil, err + if interceptor == nil { + return srv.(AuthServer).UserDelete(ctx, in) } - return out, nil + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/etcdserverpb.Auth/UserDelete", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AuthServer).UserDelete(ctx, req.(*AuthUserDeleteRequest)) + } + return interceptor(ctx, in, info, handler) } -func _Auth_UserChangePassword_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) { +func _Auth_UserChangePassword_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(AuthUserChangePasswordRequest) if err := dec(in); err != nil { return nil, err } - out, err := srv.(AuthServer).UserChangePassword(ctx, in) - if err != nil { - return nil, err + if interceptor == nil { + return srv.(AuthServer).UserChangePassword(ctx, in) } - return out, nil + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/etcdserverpb.Auth/UserChangePassword", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AuthServer).UserChangePassword(ctx, req.(*AuthUserChangePasswordRequest)) + } + return interceptor(ctx, in, info, handler) } -func _Auth_UserGrant_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) { - in := new(AuthUserGrantRequest) +func _Auth_UserGrantRole_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(AuthUserGrantRoleRequest) if err := dec(in); err != nil { return nil, err } - out, err := srv.(AuthServer).UserGrant(ctx, in) - if err != nil { - return nil, err + if interceptor == nil { + return srv.(AuthServer).UserGrantRole(ctx, in) } - return out, nil + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/etcdserverpb.Auth/UserGrantRole", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AuthServer).UserGrantRole(ctx, req.(*AuthUserGrantRoleRequest)) + } + return interceptor(ctx, in, info, handler) } -func _Auth_UserRevoke_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) { - in := new(AuthUserRevokeRequest) +func _Auth_UserRevokeRole_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(AuthUserRevokeRoleRequest) if err := dec(in); err != nil { return nil, err } - out, err := srv.(AuthServer).UserRevoke(ctx, in) - if err != nil { - return nil, err + if interceptor == nil { + return srv.(AuthServer).UserRevokeRole(ctx, in) } - return out, nil + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/etcdserverpb.Auth/UserRevokeRole", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AuthServer).UserRevokeRole(ctx, req.(*AuthUserRevokeRoleRequest)) + } + return interceptor(ctx, in, info, handler) } -func _Auth_RoleAdd_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) { +func _Auth_RoleAdd_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(AuthRoleAddRequest) if err := dec(in); err != nil { return nil, err } - out, err := srv.(AuthServer).RoleAdd(ctx, in) - if err != nil { - return nil, err + if interceptor == nil { + return srv.(AuthServer).RoleAdd(ctx, in) } - return out, nil + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/etcdserverpb.Auth/RoleAdd", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AuthServer).RoleAdd(ctx, req.(*AuthRoleAddRequest)) + } + return interceptor(ctx, in, info, handler) } -func _Auth_RoleGet_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) { +func _Auth_RoleGet_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(AuthRoleGetRequest) if err := dec(in); err != nil { return nil, err } - out, err := srv.(AuthServer).RoleGet(ctx, in) - if err != nil { - return nil, err + if interceptor == nil { + return srv.(AuthServer).RoleGet(ctx, in) } - return out, nil + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/etcdserverpb.Auth/RoleGet", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AuthServer).RoleGet(ctx, req.(*AuthRoleGetRequest)) + } + return interceptor(ctx, in, info, handler) } -func _Auth_RoleDelete_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) { +func _Auth_RoleList_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(AuthRoleListRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AuthServer).RoleList(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/etcdserverpb.Auth/RoleList", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AuthServer).RoleList(ctx, req.(*AuthRoleListRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Auth_RoleDelete_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(AuthRoleDeleteRequest) if err := dec(in); err != nil { return nil, err } - out, err := srv.(AuthServer).RoleDelete(ctx, in) - if err != nil { - return nil, err + if interceptor == nil { + return srv.(AuthServer).RoleDelete(ctx, in) } - return out, nil + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/etcdserverpb.Auth/RoleDelete", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AuthServer).RoleDelete(ctx, req.(*AuthRoleDeleteRequest)) + } + return interceptor(ctx, in, info, handler) } -func _Auth_RoleGrant_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) { - in := new(AuthRoleGrantRequest) +func _Auth_RoleGrantPermission_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(AuthRoleGrantPermissionRequest) if err := dec(in); err != nil { return nil, err } - out, err := srv.(AuthServer).RoleGrant(ctx, in) - if err != nil { - return nil, err + if interceptor == nil { + return srv.(AuthServer).RoleGrantPermission(ctx, in) } - return out, nil + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/etcdserverpb.Auth/RoleGrantPermission", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AuthServer).RoleGrantPermission(ctx, req.(*AuthRoleGrantPermissionRequest)) + } + return interceptor(ctx, in, info, handler) } -func _Auth_RoleRevoke_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) { - in := new(AuthRoleRevokeRequest) +func _Auth_RoleRevokePermission_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(AuthRoleRevokePermissionRequest) if err := dec(in); err != nil { return nil, err } - out, err := srv.(AuthServer).RoleRevoke(ctx, in) - if err != nil { - return nil, err + if interceptor == nil { + return srv.(AuthServer).RoleRevokePermission(ctx, in) } - return out, nil + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/etcdserverpb.Auth/RoleRevokePermission", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AuthServer).RoleRevokePermission(ctx, req.(*AuthRoleRevokePermissionRequest)) + } + return interceptor(ctx, in, info, handler) } var _Auth_serviceDesc = grpc.ServiceDesc{ @@ -2814,6 +3511,10 @@ var _Auth_serviceDesc = grpc.ServiceDesc{ MethodName: "UserGet", Handler: _Auth_UserGet_Handler, }, + { + MethodName: "UserList", + Handler: _Auth_UserList_Handler, + }, { MethodName: "UserDelete", Handler: _Auth_UserDelete_Handler, @@ -2823,12 +3524,12 @@ var _Auth_serviceDesc = grpc.ServiceDesc{ Handler: _Auth_UserChangePassword_Handler, }, { - MethodName: "UserGrant", - Handler: _Auth_UserGrant_Handler, + MethodName: "UserGrantRole", + Handler: _Auth_UserGrantRole_Handler, }, { - MethodName: "UserRevoke", - Handler: _Auth_UserRevoke_Handler, + MethodName: "UserRevokeRole", + Handler: _Auth_UserRevokeRole_Handler, }, { MethodName: "RoleAdd", @@ -2838,20 +3539,25 @@ var _Auth_serviceDesc = grpc.ServiceDesc{ MethodName: "RoleGet", Handler: _Auth_RoleGet_Handler, }, + { + MethodName: "RoleList", + Handler: _Auth_RoleList_Handler, + }, { MethodName: "RoleDelete", Handler: _Auth_RoleDelete_Handler, }, { - MethodName: "RoleGrant", - Handler: _Auth_RoleGrant_Handler, + MethodName: "RoleGrantPermission", + Handler: _Auth_RoleGrantPermission_Handler, }, { - MethodName: "RoleRevoke", - Handler: _Auth_RoleRevoke_Handler, + MethodName: "RoleRevokePermission", + Handler: _Auth_RoleRevokePermission_Handler, }, }, - Streams: []grpc.StreamDesc{}, + Streams: []grpc.StreamDesc{}, + Metadata: fileDescriptorRpc, } func (m *ResponseHeader) Marshal() (data []byte, err error) { @@ -2907,21 +3613,17 @@ func (m *RangeRequest) MarshalTo(data []byte) (int, error) { _ = i var l int _ = l - if m.Key != nil { - if len(m.Key) > 0 { - data[i] = 0xa - i++ - i = encodeVarintRpc(data, i, uint64(len(m.Key))) - i += copy(data[i:], m.Key) - } + if len(m.Key) > 0 { + data[i] = 0xa + i++ + i = encodeVarintRpc(data, i, uint64(len(m.Key))) + i += copy(data[i:], m.Key) } - if m.RangeEnd != nil { - if len(m.RangeEnd) > 0 { - data[i] = 0x12 - i++ - i = encodeVarintRpc(data, i, uint64(len(m.RangeEnd))) - i += copy(data[i:], m.RangeEnd) - } + if len(m.RangeEnd) > 0 { + data[i] = 0x12 + i++ + i = encodeVarintRpc(data, i, uint64(len(m.RangeEnd))) + i += copy(data[i:], m.RangeEnd) } if m.Limit != 0 { data[i] = 0x18 @@ -2953,6 +3655,26 @@ func (m *RangeRequest) MarshalTo(data []byte) (int, error) { } i++ } + if m.KeysOnly { + data[i] = 0x40 + i++ + if m.KeysOnly { + data[i] = 1 + } else { + data[i] = 0 + } + i++ + } + if m.CountOnly { + data[i] = 0x48 + i++ + if m.CountOnly { + data[i] = 1 + } else { + data[i] = 0 + } + i++ + } return i, nil } @@ -3003,6 +3725,11 @@ func (m *RangeResponse) MarshalTo(data []byte) (int, error) { } i++ } + if m.Count != 0 { + data[i] = 0x20 + i++ + i = encodeVarintRpc(data, i, uint64(m.Count)) + } return i, nil } @@ -3021,21 +3748,17 @@ func (m *PutRequest) MarshalTo(data []byte) (int, error) { _ = i var l int _ = l - if m.Key != nil { - if len(m.Key) > 0 { - data[i] = 0xa - i++ - i = encodeVarintRpc(data, i, uint64(len(m.Key))) - i += copy(data[i:], m.Key) - } + if len(m.Key) > 0 { + data[i] = 0xa + i++ + i = encodeVarintRpc(data, i, uint64(len(m.Key))) + i += copy(data[i:], m.Key) } - if m.Value != nil { - if len(m.Value) > 0 { - data[i] = 0x12 - i++ - i = encodeVarintRpc(data, i, uint64(len(m.Value))) - i += copy(data[i:], m.Value) - } + if len(m.Value) > 0 { + data[i] = 0x12 + i++ + i = encodeVarintRpc(data, i, uint64(len(m.Value))) + i += copy(data[i:], m.Value) } if m.Lease != 0 { data[i] = 0x18 @@ -3088,21 +3811,17 @@ func (m *DeleteRangeRequest) MarshalTo(data []byte) (int, error) { _ = i var l int _ = l - if m.Key != nil { - if len(m.Key) > 0 { - data[i] = 0xa - i++ - i = encodeVarintRpc(data, i, uint64(len(m.Key))) - i += copy(data[i:], m.Key) - } + if len(m.Key) > 0 { + data[i] = 0xa + i++ + i = encodeVarintRpc(data, i, uint64(len(m.Key))) + i += copy(data[i:], m.Key) } - if m.RangeEnd != nil { - if len(m.RangeEnd) > 0 { - data[i] = 0x12 - i++ - i = encodeVarintRpc(data, i, uint64(len(m.RangeEnd))) - i += copy(data[i:], m.RangeEnd) - } + if len(m.RangeEnd) > 0 { + data[i] = 0x12 + i++ + i = encodeVarintRpc(data, i, uint64(len(m.RangeEnd))) + i += copy(data[i:], m.RangeEnd) } return i, nil } @@ -3140,7 +3859,7 @@ func (m *DeleteRangeResponse) MarshalTo(data []byte) (int, error) { return i, nil } -func (m *RequestUnion) 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) @@ -3150,7 +3869,7 @@ func (m *RequestUnion) Marshal() (data []byte, err error) { return data[:n], nil } -func (m *RequestUnion) MarshalTo(data []byte) (int, error) { +func (m *RequestOp) MarshalTo(data []byte) (int, error) { var i int _ = i var l int @@ -3165,7 +3884,7 @@ func (m *RequestUnion) MarshalTo(data []byte) (int, error) { return i, nil } -func (m *RequestUnion_RequestRange) MarshalTo(data []byte) (int, error) { +func (m *RequestOp_RequestRange) MarshalTo(data []byte) (int, error) { i := 0 if m.RequestRange != nil { data[i] = 0xa @@ -3179,7 +3898,7 @@ func (m *RequestUnion_RequestRange) MarshalTo(data []byte) (int, error) { } return i, nil } -func (m *RequestUnion_RequestPut) MarshalTo(data []byte) (int, error) { +func (m *RequestOp_RequestPut) MarshalTo(data []byte) (int, error) { i := 0 if m.RequestPut != nil { data[i] = 0x12 @@ -3193,7 +3912,7 @@ func (m *RequestUnion_RequestPut) MarshalTo(data []byte) (int, error) { } return i, nil } -func (m *RequestUnion_RequestDeleteRange) MarshalTo(data []byte) (int, error) { +func (m *RequestOp_RequestDeleteRange) MarshalTo(data []byte) (int, error) { i := 0 if m.RequestDeleteRange != nil { data[i] = 0x1a @@ -3207,7 +3926,7 @@ func (m *RequestUnion_RequestDeleteRange) MarshalTo(data []byte) (int, error) { } return i, nil } -func (m *ResponseUnion) 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) @@ -3217,7 +3936,7 @@ func (m *ResponseUnion) Marshal() (data []byte, err error) { return data[:n], nil } -func (m *ResponseUnion) MarshalTo(data []byte) (int, error) { +func (m *ResponseOp) MarshalTo(data []byte) (int, error) { var i int _ = i var l int @@ -3232,7 +3951,7 @@ func (m *ResponseUnion) MarshalTo(data []byte) (int, error) { return i, nil } -func (m *ResponseUnion_ResponseRange) MarshalTo(data []byte) (int, error) { +func (m *ResponseOp_ResponseRange) MarshalTo(data []byte) (int, error) { i := 0 if m.ResponseRange != nil { data[i] = 0xa @@ -3246,7 +3965,7 @@ func (m *ResponseUnion_ResponseRange) MarshalTo(data []byte) (int, error) { } return i, nil } -func (m *ResponseUnion_ResponsePut) MarshalTo(data []byte) (int, error) { +func (m *ResponseOp_ResponsePut) MarshalTo(data []byte) (int, error) { i := 0 if m.ResponsePut != nil { data[i] = 0x12 @@ -3260,7 +3979,7 @@ func (m *ResponseUnion_ResponsePut) MarshalTo(data []byte) (int, error) { } return i, nil } -func (m *ResponseUnion_ResponseDeleteRange) MarshalTo(data []byte) (int, error) { +func (m *ResponseOp_ResponseDeleteRange) MarshalTo(data []byte) (int, error) { i := 0 if m.ResponseDeleteRange != nil { data[i] = 0x1a @@ -3299,13 +4018,11 @@ func (m *Compare) MarshalTo(data []byte) (int, error) { i++ i = encodeVarintRpc(data, i, uint64(m.Target)) } - if m.Key != nil { - if len(m.Key) > 0 { - data[i] = 0x1a - i++ - i = encodeVarintRpc(data, i, uint64(len(m.Key))) - i += copy(data[i:], m.Key) - } + if len(m.Key) > 0 { + data[i] = 0x1a + i++ + i = encodeVarintRpc(data, i, uint64(len(m.Key))) + i += copy(data[i:], m.Key) } if m.TargetUnion != nil { nn12, err := m.TargetUnion.MarshalTo(data[i:]) @@ -3564,6 +4281,63 @@ func (m *HashResponse) MarshalTo(data []byte) (int, error) { return i, nil } +func (m *SnapshotRequest) 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 *SnapshotRequest) MarshalTo(data []byte) (int, error) { + var i int + _ = i + var l int + _ = l + return i, nil +} + +func (m *SnapshotResponse) 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 *SnapshotResponse) 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())) + n16, err := m.Header.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += n16 + } + if m.RemainingBytes != 0 { + data[i] = 0x10 + i++ + i = encodeVarintRpc(data, i, uint64(m.RemainingBytes)) + } + if len(m.Blob) > 0 { + data[i] = 0x1a + i++ + 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) { size := m.Size() data = make([]byte, size) @@ -3580,11 +4354,11 @@ func (m *WatchRequest) MarshalTo(data []byte) (int, error) { var l int _ = l if m.RequestUnion != nil { - nn16, err := m.RequestUnion.MarshalTo(data[i:]) + nn17, err := m.RequestUnion.MarshalTo(data[i:]) if err != nil { return 0, err } - i += nn16 + i += nn17 } return i, nil } @@ -3595,11 +4369,11 @@ func (m *WatchRequest_CreateRequest) MarshalTo(data []byte) (int, error) { data[i] = 0xa i++ i = encodeVarintRpc(data, i, uint64(m.CreateRequest.Size())) - n17, err := m.CreateRequest.MarshalTo(data[i:]) + n18, err := m.CreateRequest.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n17 + i += n18 } return i, nil } @@ -3609,11 +4383,11 @@ func (m *WatchRequest_CancelRequest) MarshalTo(data []byte) (int, error) { data[i] = 0x12 i++ i = encodeVarintRpc(data, i, uint64(m.CancelRequest.Size())) - n18, err := m.CancelRequest.MarshalTo(data[i:]) + n19, err := m.CancelRequest.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n18 + i += n19 } return i, nil } @@ -3632,21 +4406,17 @@ func (m *WatchCreateRequest) MarshalTo(data []byte) (int, error) { _ = i var l int _ = l - if m.Key != nil { - if len(m.Key) > 0 { - data[i] = 0xa - i++ - i = encodeVarintRpc(data, i, uint64(len(m.Key))) - i += copy(data[i:], m.Key) - } + if len(m.Key) > 0 { + data[i] = 0xa + i++ + i = encodeVarintRpc(data, i, uint64(len(m.Key))) + i += copy(data[i:], m.Key) } - if m.RangeEnd != nil { - if len(m.RangeEnd) > 0 { - data[i] = 0x12 - i++ - i = encodeVarintRpc(data, i, uint64(len(m.RangeEnd))) - i += copy(data[i:], m.RangeEnd) - } + if len(m.RangeEnd) > 0 { + data[i] = 0x12 + i++ + i = encodeVarintRpc(data, i, uint64(len(m.RangeEnd))) + i += copy(data[i:], m.RangeEnd) } if m.StartRevision != 0 { data[i] = 0x18 @@ -3708,11 +4478,11 @@ func (m *WatchResponse) MarshalTo(data []byte) (int, error) { data[i] = 0xa i++ i = encodeVarintRpc(data, i, uint64(m.Header.Size())) - n19, err := m.Header.MarshalTo(data[i:]) + n20, err := m.Header.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n19 + i += n20 } if m.WatchId != 0 { data[i] = 0x10 @@ -3806,11 +4576,11 @@ func (m *LeaseGrantResponse) MarshalTo(data []byte) (int, error) { data[i] = 0xa i++ i = encodeVarintRpc(data, i, uint64(m.Header.Size())) - n20, err := m.Header.MarshalTo(data[i:]) + n21, err := m.Header.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n20 + i += n21 } if m.ID != 0 { data[i] = 0x10 @@ -3873,11 +4643,11 @@ func (m *LeaseRevokeResponse) MarshalTo(data []byte) (int, error) { data[i] = 0xa i++ i = encodeVarintRpc(data, i, uint64(m.Header.Size())) - n21, err := m.Header.MarshalTo(data[i:]) + n22, err := m.Header.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n21 + i += n22 } return i, nil } @@ -3924,11 +4694,11 @@ func (m *LeaseKeepAliveResponse) MarshalTo(data []byte) (int, error) { data[i] = 0xa i++ i = encodeVarintRpc(data, i, uint64(m.Header.Size())) - n22, err := m.Header.MarshalTo(data[i:]) + n23, err := m.Header.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n22 + i += n23 } if m.ID != 0 { data[i] = 0x10 @@ -3969,19 +4739,9 @@ func (m *Member) MarshalTo(data []byte) (int, error) { i = encodeVarintRpc(data, i, uint64(len(m.Name))) i += copy(data[i:], m.Name) } - if m.IsLeader { - data[i] = 0x18 - i++ - if m.IsLeader { - data[i] = 1 - } else { - data[i] = 0 - } - i++ - } if len(m.PeerURLs) > 0 { for _, s := range m.PeerURLs { - data[i] = 0x22 + data[i] = 0x1a i++ l = len(s) for l >= 1<<7 { @@ -3996,7 +4756,7 @@ func (m *Member) MarshalTo(data []byte) (int, error) { } if len(m.ClientURLs) > 0 { for _, s := range m.ClientURLs { - data[i] = 0x2a + data[i] = 0x22 i++ l = len(s) for l >= 1<<7 { @@ -4064,21 +4824,21 @@ func (m *MemberAddResponse) MarshalTo(data []byte) (int, error) { data[i] = 0xa i++ i = encodeVarintRpc(data, i, uint64(m.Header.Size())) - n23, err := m.Header.MarshalTo(data[i:]) + n24, err := m.Header.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n23 + i += n24 } if m.Member != nil { data[i] = 0x12 i++ i = encodeVarintRpc(data, i, uint64(m.Member.Size())) - n24, err := m.Member.MarshalTo(data[i:]) + n25, err := m.Member.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n24 + i += n25 } return i, nil } @@ -4125,11 +4885,11 @@ func (m *MemberRemoveResponse) MarshalTo(data []byte) (int, error) { data[i] = 0xa i++ i = encodeVarintRpc(data, i, uint64(m.Header.Size())) - n25, err := m.Header.MarshalTo(data[i:]) + n26, err := m.Header.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n25 + i += n26 } return i, nil } @@ -4191,11 +4951,11 @@ func (m *MemberUpdateResponse) MarshalTo(data []byte) (int, error) { data[i] = 0xa i++ i = encodeVarintRpc(data, i, uint64(m.Header.Size())) - n26, err := m.Header.MarshalTo(data[i:]) + n27, err := m.Header.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n26 + i += n27 } return i, nil } @@ -4237,11 +4997,11 @@ func (m *MemberListResponse) MarshalTo(data []byte) (int, error) { data[i] = 0xa i++ i = encodeVarintRpc(data, i, uint64(m.Header.Size())) - n27, err := m.Header.MarshalTo(data[i:]) + n28, err := m.Header.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n27 + i += n28 } if len(m.Members) > 0 { for _, msg := range m.Members { @@ -4295,11 +5055,11 @@ func (m *DefragmentResponse) MarshalTo(data []byte) (int, error) { data[i] = 0xa i++ i = encodeVarintRpc(data, i, uint64(m.Header.Size())) - n28, err := m.Header.MarshalTo(data[i:]) + n29, err := m.Header.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n28 + i += n29 } return i, nil } @@ -4384,11 +5144,11 @@ func (m *AlarmResponse) MarshalTo(data []byte) (int, error) { data[i] = 0xa i++ i = encodeVarintRpc(data, i, uint64(m.Header.Size())) - n29, err := m.Header.MarshalTo(data[i:]) + n30, err := m.Header.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n29 + i += n30 } if len(m.Alarms) > 0 { for _, msg := range m.Alarms { @@ -4442,11 +5202,11 @@ func (m *StatusResponse) MarshalTo(data []byte) (int, error) { data[i] = 0xa i++ i = encodeVarintRpc(data, i, uint64(m.Header.Size())) - n30, err := m.Header.MarshalTo(data[i:]) + n31, err := m.Header.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n30 + i += n31 } if len(m.Version) > 0 { data[i] = 0x12 @@ -4454,6 +5214,26 @@ func (m *StatusResponse) MarshalTo(data []byte) (int, error) { 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 } @@ -4508,6 +5288,18 @@ func (m *AuthenticateRequest) MarshalTo(data []byte) (int, error) { _ = 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 } @@ -4556,6 +5348,12 @@ func (m *AuthUserGetRequest) MarshalTo(data []byte) (int, error) { _ = 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 } @@ -4613,7 +5411,7 @@ func (m *AuthUserChangePasswordRequest) MarshalTo(data []byte) (int, error) { return i, nil } -func (m *AuthUserGrantRequest) Marshal() (data []byte, err error) { +func (m *AuthUserGrantRoleRequest) Marshal() (data []byte, err error) { size := m.Size() data = make([]byte, size) n, err := m.MarshalTo(data) @@ -4623,15 +5421,27 @@ func (m *AuthUserGrantRequest) Marshal() (data []byte, err error) { return data[:n], nil } -func (m *AuthUserGrantRequest) MarshalTo(data []byte) (int, error) { +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 *AuthUserRevokeRequest) Marshal() (data []byte, err error) { +func (m *AuthUserRevokeRoleRequest) Marshal() (data []byte, err error) { size := m.Size() data = make([]byte, size) n, err := m.MarshalTo(data) @@ -4641,11 +5451,23 @@ func (m *AuthUserRevokeRequest) Marshal() (data []byte, err error) { return data[:n], nil } -func (m *AuthUserRevokeRequest) MarshalTo(data []byte) (int, error) { +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 } @@ -4684,6 +5506,48 @@ func (m *AuthRoleGetRequest) Marshal() (data []byte, err error) { } 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 @@ -4706,10 +5570,16 @@ func (m *AuthRoleDeleteRequest) MarshalTo(data []byte) (int, error) { _ = 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 *AuthRoleGrantRequest) Marshal() (data []byte, err error) { +func (m *AuthRoleGrantPermissionRequest) Marshal() (data []byte, err error) { size := m.Size() data = make([]byte, size) n, err := m.MarshalTo(data) @@ -4719,15 +5589,31 @@ func (m *AuthRoleGrantRequest) Marshal() (data []byte, err error) { return data[:n], nil } -func (m *AuthRoleGrantRequest) MarshalTo(data []byte) (int, error) { +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())) + n32, err := m.Perm.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += n32 + } return i, nil } -func (m *AuthRoleRevokeRequest) Marshal() (data []byte, err error) { +func (m *AuthRoleRevokePermissionRequest) Marshal() (data []byte, err error) { size := m.Size() data = make([]byte, size) n, err := m.MarshalTo(data) @@ -4737,11 +5623,29 @@ func (m *AuthRoleRevokeRequest) Marshal() (data []byte, err error) { return data[:n], nil } -func (m *AuthRoleRevokeRequest) MarshalTo(data []byte) (int, error) { +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 } @@ -4764,11 +5668,11 @@ func (m *AuthEnableResponse) MarshalTo(data []byte) (int, error) { data[i] = 0xa i++ i = encodeVarintRpc(data, i, uint64(m.Header.Size())) - n31, err := m.Header.MarshalTo(data[i:]) + n33, err := m.Header.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n31 + i += n33 } return i, nil } @@ -4792,11 +5696,11 @@ func (m *AuthDisableResponse) MarshalTo(data []byte) (int, error) { data[i] = 0xa i++ i = encodeVarintRpc(data, i, uint64(m.Header.Size())) - n32, err := m.Header.MarshalTo(data[i:]) + n34, err := m.Header.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n32 + i += n34 } return i, nil } @@ -4820,11 +5724,17 @@ func (m *AuthenticateResponse) MarshalTo(data []byte) (int, error) { data[i] = 0xa i++ i = encodeVarintRpc(data, i, uint64(m.Header.Size())) - n33, err := m.Header.MarshalTo(data[i:]) + n35, err := m.Header.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n33 + i += n35 + } + 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 } @@ -4848,11 +5758,11 @@ func (m *AuthUserAddResponse) MarshalTo(data []byte) (int, error) { data[i] = 0xa i++ i = encodeVarintRpc(data, i, uint64(m.Header.Size())) - n34, err := m.Header.MarshalTo(data[i:]) + n36, err := m.Header.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n34 + i += n36 } return i, nil } @@ -4876,11 +5786,26 @@ func (m *AuthUserGetResponse) MarshalTo(data []byte) (int, error) { data[i] = 0xa i++ i = encodeVarintRpc(data, i, uint64(m.Header.Size())) - n35, err := m.Header.MarshalTo(data[i:]) + n37, err := m.Header.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n35 + i += n37 + } + 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 } @@ -4904,11 +5829,11 @@ func (m *AuthUserDeleteResponse) MarshalTo(data []byte) (int, error) { data[i] = 0xa i++ i = encodeVarintRpc(data, i, uint64(m.Header.Size())) - n36, err := m.Header.MarshalTo(data[i:]) + n38, err := m.Header.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n36 + i += n38 } return i, nil } @@ -4924,62 +5849,6 @@ func (m *AuthUserChangePasswordResponse) Marshal() (data []byte, err error) { } 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())) - n37, err := m.Header.MarshalTo(data[i:]) - if err != nil { - return 0, err - } - i += n37 - } - return i, nil -} - -func (m *AuthUserGrantResponse) 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 *AuthUserGrantResponse) 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 *AuthUserRevokeResponse) 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 *AuthUserRevokeResponse) MarshalTo(data []byte) (int, error) { var i int _ = i var l int @@ -4997,6 +5866,62 @@ func (m *AuthUserRevokeResponse) MarshalTo(data []byte) (int, error) { 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())) + n40, err := m.Header.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += n40 + } + 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())) + n41, err := m.Header.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += n41 + } + return i, nil +} + func (m *AuthRoleAddResponse) Marshal() (data []byte, err error) { size := m.Size() data = make([]byte, size) @@ -5016,11 +5941,11 @@ func (m *AuthRoleAddResponse) MarshalTo(data []byte) (int, error) { data[i] = 0xa i++ i = encodeVarintRpc(data, i, uint64(m.Header.Size())) - n40, err := m.Header.MarshalTo(data[i:]) + n42, err := m.Header.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n40 + i += n42 } return i, nil } @@ -5044,11 +5969,109 @@ func (m *AuthRoleGetResponse) MarshalTo(data []byte) (int, error) { data[i] = 0xa i++ i = encodeVarintRpc(data, i, uint64(m.Header.Size())) - n41, err := m.Header.MarshalTo(data[i:]) + n43, err := m.Header.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n41 + i += n43 + } + 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 *AuthRoleListResponse) 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 *AuthRoleListResponse) 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.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) { + size := m.Size() + data = make([]byte, size) + n, err := m.MarshalTo(data) + if err != nil { + return nil, err + } + return data[:n], nil +} + +func (m *AuthUserListResponse) 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.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 } @@ -5072,16 +6095,16 @@ func (m *AuthRoleDeleteResponse) MarshalTo(data []byte) (int, error) { data[i] = 0xa i++ i = encodeVarintRpc(data, i, uint64(m.Header.Size())) - n42, err := m.Header.MarshalTo(data[i:]) + n46, err := m.Header.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n42 + i += n46 } return i, nil } -func (m *AuthRoleGrantResponse) Marshal() (data []byte, err error) { +func (m *AuthRoleGrantPermissionResponse) Marshal() (data []byte, err error) { size := m.Size() data = make([]byte, size) n, err := m.MarshalTo(data) @@ -5091,7 +6114,7 @@ func (m *AuthRoleGrantResponse) Marshal() (data []byte, err error) { return data[:n], nil } -func (m *AuthRoleGrantResponse) MarshalTo(data []byte) (int, error) { +func (m *AuthRoleGrantPermissionResponse) MarshalTo(data []byte) (int, error) { var i int _ = i var l int @@ -5100,16 +6123,16 @@ func (m *AuthRoleGrantResponse) MarshalTo(data []byte) (int, error) { data[i] = 0xa i++ i = encodeVarintRpc(data, i, uint64(m.Header.Size())) - n43, err := m.Header.MarshalTo(data[i:]) + n47, err := m.Header.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n43 + i += n47 } return i, nil } -func (m *AuthRoleRevokeResponse) Marshal() (data []byte, err error) { +func (m *AuthRoleRevokePermissionResponse) Marshal() (data []byte, err error) { size := m.Size() data = make([]byte, size) n, err := m.MarshalTo(data) @@ -5119,7 +6142,7 @@ func (m *AuthRoleRevokeResponse) Marshal() (data []byte, err error) { return data[:n], nil } -func (m *AuthRoleRevokeResponse) MarshalTo(data []byte) (int, error) { +func (m *AuthRoleRevokePermissionResponse) MarshalTo(data []byte) (int, error) { var i int _ = i var l int @@ -5128,11 +6151,11 @@ func (m *AuthRoleRevokeResponse) MarshalTo(data []byte) (int, error) { data[i] = 0xa i++ i = encodeVarintRpc(data, i, uint64(m.Header.Size())) - n44, err := m.Header.MarshalTo(data[i:]) + n48, err := m.Header.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n44 + i += n48 } return i, nil } @@ -5185,17 +6208,13 @@ func (m *ResponseHeader) Size() (n int) { func (m *RangeRequest) Size() (n int) { var l int _ = l - if m.Key != nil { - l = len(m.Key) - if l > 0 { - n += 1 + l + sovRpc(uint64(l)) - } + l = len(m.Key) + if l > 0 { + n += 1 + l + sovRpc(uint64(l)) } - if m.RangeEnd != nil { - l = len(m.RangeEnd) - if l > 0 { - n += 1 + l + sovRpc(uint64(l)) - } + l = len(m.RangeEnd) + if l > 0 { + n += 1 + l + sovRpc(uint64(l)) } if m.Limit != 0 { n += 1 + sovRpc(uint64(m.Limit)) @@ -5212,6 +6231,12 @@ func (m *RangeRequest) Size() (n int) { if m.Serializable { n += 2 } + if m.KeysOnly { + n += 2 + } + if m.CountOnly { + n += 2 + } return n } @@ -5231,23 +6256,22 @@ func (m *RangeResponse) Size() (n int) { if m.More { n += 2 } + if m.Count != 0 { + n += 1 + sovRpc(uint64(m.Count)) + } return n } func (m *PutRequest) Size() (n int) { var l int _ = l - if m.Key != nil { - l = len(m.Key) - if l > 0 { - n += 1 + l + sovRpc(uint64(l)) - } + l = len(m.Key) + if l > 0 { + n += 1 + l + sovRpc(uint64(l)) } - if m.Value != nil { - l = len(m.Value) - if l > 0 { - n += 1 + l + sovRpc(uint64(l)) - } + l = len(m.Value) + if l > 0 { + n += 1 + l + sovRpc(uint64(l)) } if m.Lease != 0 { n += 1 + sovRpc(uint64(m.Lease)) @@ -5268,17 +6292,13 @@ func (m *PutResponse) Size() (n int) { func (m *DeleteRangeRequest) Size() (n int) { var l int _ = l - if m.Key != nil { - l = len(m.Key) - if l > 0 { - n += 1 + l + sovRpc(uint64(l)) - } + l = len(m.Key) + if l > 0 { + n += 1 + l + sovRpc(uint64(l)) } - if m.RangeEnd != nil { - l = len(m.RangeEnd) - if l > 0 { - n += 1 + l + sovRpc(uint64(l)) - } + l = len(m.RangeEnd) + if l > 0 { + n += 1 + l + sovRpc(uint64(l)) } return n } @@ -5296,7 +6316,7 @@ func (m *DeleteRangeResponse) Size() (n int) { return n } -func (m *RequestUnion) Size() (n int) { +func (m *RequestOp) Size() (n int) { var l int _ = l if m.Request != nil { @@ -5305,7 +6325,7 @@ func (m *RequestUnion) Size() (n int) { return n } -func (m *RequestUnion_RequestRange) Size() (n int) { +func (m *RequestOp_RequestRange) Size() (n int) { var l int _ = l if m.RequestRange != nil { @@ -5314,7 +6334,7 @@ func (m *RequestUnion_RequestRange) Size() (n int) { } return n } -func (m *RequestUnion_RequestPut) Size() (n int) { +func (m *RequestOp_RequestPut) Size() (n int) { var l int _ = l if m.RequestPut != nil { @@ -5323,7 +6343,7 @@ func (m *RequestUnion_RequestPut) Size() (n int) { } return n } -func (m *RequestUnion_RequestDeleteRange) Size() (n int) { +func (m *RequestOp_RequestDeleteRange) Size() (n int) { var l int _ = l if m.RequestDeleteRange != nil { @@ -5332,7 +6352,7 @@ func (m *RequestUnion_RequestDeleteRange) Size() (n int) { } return n } -func (m *ResponseUnion) Size() (n int) { +func (m *ResponseOp) Size() (n int) { var l int _ = l if m.Response != nil { @@ -5341,7 +6361,7 @@ func (m *ResponseUnion) Size() (n int) { return n } -func (m *ResponseUnion_ResponseRange) Size() (n int) { +func (m *ResponseOp_ResponseRange) Size() (n int) { var l int _ = l if m.ResponseRange != nil { @@ -5350,7 +6370,7 @@ func (m *ResponseUnion_ResponseRange) Size() (n int) { } return n } -func (m *ResponseUnion_ResponsePut) Size() (n int) { +func (m *ResponseOp_ResponsePut) Size() (n int) { var l int _ = l if m.ResponsePut != nil { @@ -5359,7 +6379,7 @@ func (m *ResponseUnion_ResponsePut) Size() (n int) { } return n } -func (m *ResponseUnion_ResponseDeleteRange) Size() (n int) { +func (m *ResponseOp_ResponseDeleteRange) Size() (n int) { var l int _ = l if m.ResponseDeleteRange != nil { @@ -5377,11 +6397,9 @@ func (m *Compare) Size() (n int) { if m.Target != 0 { n += 1 + sovRpc(uint64(m.Target)) } - if m.Key != nil { - l = len(m.Key) - if l > 0 { - n += 1 + l + sovRpc(uint64(l)) - } + l = len(m.Key) + if l > 0 { + n += 1 + l + sovRpc(uint64(l)) } if m.TargetUnion != nil { n += m.TargetUnion.Size() @@ -5500,6 +6518,29 @@ func (m *HashResponse) Size() (n int) { return n } +func (m *SnapshotRequest) Size() (n int) { + var l int + _ = l + return n +} + +func (m *SnapshotResponse) Size() (n int) { + var l int + _ = l + if m.Header != nil { + l = m.Header.Size() + n += 1 + l + sovRpc(uint64(l)) + } + if m.RemainingBytes != 0 { + n += 1 + sovRpc(uint64(m.RemainingBytes)) + } + l = len(m.Blob) + if l > 0 { + n += 1 + l + sovRpc(uint64(l)) + } + return n +} + func (m *WatchRequest) Size() (n int) { var l int _ = l @@ -5530,17 +6571,13 @@ func (m *WatchRequest_CancelRequest) Size() (n int) { func (m *WatchCreateRequest) Size() (n int) { var l int _ = l - if m.Key != nil { - l = len(m.Key) - if l > 0 { - n += 1 + l + sovRpc(uint64(l)) - } + l = len(m.Key) + if l > 0 { + n += 1 + l + sovRpc(uint64(l)) } - if m.RangeEnd != nil { - l = len(m.RangeEnd) - if l > 0 { - n += 1 + l + sovRpc(uint64(l)) - } + l = len(m.RangeEnd) + if l > 0 { + n += 1 + l + sovRpc(uint64(l)) } if m.StartRevision != 0 { n += 1 + sovRpc(uint64(m.StartRevision)) @@ -5674,9 +6711,6 @@ func (m *Member) Size() (n int) { if l > 0 { n += 1 + l + sovRpc(uint64(l)) } - if m.IsLeader { - n += 2 - } if len(m.PeerURLs) > 0 { for _, s := range m.PeerURLs { l = len(s) @@ -5860,6 +6894,18 @@ func (m *StatusResponse) Size() (n int) { if l > 0 { n += 1 + l + sovRpc(uint64(l)) } + if m.DbSize != 0 { + n += 1 + sovRpc(uint64(m.DbSize)) + } + if m.Leader != 0 { + n += 1 + sovRpc(uint64(m.Leader)) + } + if m.RaftIndex != 0 { + n += 1 + sovRpc(uint64(m.RaftIndex)) + } + if m.RaftTerm != 0 { + n += 1 + sovRpc(uint64(m.RaftTerm)) + } return n } @@ -5878,6 +6924,14 @@ func (m *AuthDisableRequest) Size() (n int) { func (m *AuthenticateRequest) Size() (n int) { var l int _ = l + l = len(m.Name) + if l > 0 { + n += 1 + l + sovRpc(uint64(l)) + } + l = len(m.Password) + if l > 0 { + n += 1 + l + sovRpc(uint64(l)) + } return n } @@ -5898,6 +6952,10 @@ func (m *AuthUserAddRequest) Size() (n int) { func (m *AuthUserGetRequest) Size() (n int) { var l int _ = l + l = len(m.Name) + if l > 0 { + n += 1 + l + sovRpc(uint64(l)) + } return n } @@ -5925,15 +6983,31 @@ func (m *AuthUserChangePasswordRequest) Size() (n int) { return n } -func (m *AuthUserGrantRequest) Size() (n int) { +func (m *AuthUserGrantRoleRequest) Size() (n int) { var l int _ = l + l = len(m.User) + if l > 0 { + n += 1 + l + sovRpc(uint64(l)) + } + l = len(m.Role) + if l > 0 { + n += 1 + l + sovRpc(uint64(l)) + } return n } -func (m *AuthUserRevokeRequest) Size() (n int) { +func (m *AuthUserRevokeRoleRequest) Size() (n int) { var l int _ = l + l = len(m.Name) + if l > 0 { + n += 1 + l + sovRpc(uint64(l)) + } + l = len(m.Role) + if l > 0 { + n += 1 + l + sovRpc(uint64(l)) + } return n } @@ -5948,6 +7022,22 @@ func (m *AuthRoleAddRequest) Size() (n int) { } func (m *AuthRoleGetRequest) Size() (n int) { + var l int + _ = l + l = len(m.Role) + if l > 0 { + n += 1 + l + sovRpc(uint64(l)) + } + return n +} + +func (m *AuthUserListRequest) Size() (n int) { + var l int + _ = l + return n +} + +func (m *AuthRoleListRequest) Size() (n int) { var l int _ = l return n @@ -5956,18 +7046,42 @@ func (m *AuthRoleGetRequest) Size() (n int) { func (m *AuthRoleDeleteRequest) Size() (n int) { var l int _ = l + l = len(m.Role) + if l > 0 { + n += 1 + l + sovRpc(uint64(l)) + } return n } -func (m *AuthRoleGrantRequest) Size() (n int) { +func (m *AuthRoleGrantPermissionRequest) Size() (n int) { var l int _ = l + l = len(m.Name) + if l > 0 { + n += 1 + l + sovRpc(uint64(l)) + } + if m.Perm != nil { + l = m.Perm.Size() + n += 1 + l + sovRpc(uint64(l)) + } return n } -func (m *AuthRoleRevokeRequest) Size() (n int) { +func (m *AuthRoleRevokePermissionRequest) Size() (n int) { var l int _ = l + l = len(m.Role) + if l > 0 { + n += 1 + l + sovRpc(uint64(l)) + } + l = len(m.Key) + if l > 0 { + n += 1 + l + sovRpc(uint64(l)) + } + l = len(m.RangeEnd) + if l > 0 { + n += 1 + l + sovRpc(uint64(l)) + } return n } @@ -5998,6 +7112,10 @@ func (m *AuthenticateResponse) Size() (n int) { l = m.Header.Size() n += 1 + l + sovRpc(uint64(l)) } + l = len(m.Token) + if l > 0 { + n += 1 + l + sovRpc(uint64(l)) + } return n } @@ -6018,6 +7136,12 @@ func (m *AuthUserGetResponse) Size() (n int) { l = m.Header.Size() n += 1 + l + sovRpc(uint64(l)) } + if len(m.Roles) > 0 { + for _, s := range m.Roles { + l = len(s) + n += 1 + l + sovRpc(uint64(l)) + } + } return n } @@ -6041,7 +7165,7 @@ func (m *AuthUserChangePasswordResponse) Size() (n int) { return n } -func (m *AuthUserGrantResponse) Size() (n int) { +func (m *AuthUserGrantRoleResponse) Size() (n int) { var l int _ = l if m.Header != nil { @@ -6051,7 +7175,7 @@ func (m *AuthUserGrantResponse) Size() (n int) { return n } -func (m *AuthUserRevokeResponse) Size() (n int) { +func (m *AuthUserRevokeRoleResponse) Size() (n int) { var l int _ = l if m.Header != nil { @@ -6078,6 +7202,44 @@ func (m *AuthRoleGetResponse) Size() (n int) { l = m.Header.Size() n += 1 + l + sovRpc(uint64(l)) } + if len(m.Perm) > 0 { + for _, e := range m.Perm { + l = e.Size() + n += 1 + l + sovRpc(uint64(l)) + } + } + return n +} + +func (m *AuthRoleListResponse) Size() (n int) { + var l int + _ = l + if m.Header != nil { + l = m.Header.Size() + n += 1 + l + sovRpc(uint64(l)) + } + if len(m.Roles) > 0 { + for _, s := range m.Roles { + l = len(s) + n += 1 + l + sovRpc(uint64(l)) + } + } + return n +} + +func (m *AuthUserListResponse) Size() (n int) { + var l int + _ = l + if m.Header != nil { + l = m.Header.Size() + n += 1 + l + sovRpc(uint64(l)) + } + if len(m.Users) > 0 { + for _, s := range m.Users { + l = len(s) + n += 1 + l + sovRpc(uint64(l)) + } + } return n } @@ -6091,7 +7253,7 @@ func (m *AuthRoleDeleteResponse) Size() (n int) { return n } -func (m *AuthRoleGrantResponse) Size() (n int) { +func (m *AuthRoleGrantPermissionResponse) Size() (n int) { var l int _ = l if m.Header != nil { @@ -6101,7 +7263,7 @@ func (m *AuthRoleGrantResponse) Size() (n int) { return n } -func (m *AuthRoleRevokeResponse) Size() (n int) { +func (m *AuthRoleRevokePermissionResponse) Size() (n int) { var l int _ = l if m.Header != nil { @@ -6437,6 +7599,46 @@ func (m *RangeRequest) Unmarshal(data []byte) error { } } m.Serializable = bool(v != 0) + case 8: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field KeysOnly", 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.KeysOnly = bool(v != 0) + case 9: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field CountOnly", 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.CountOnly = bool(v != 0) default: iNdEx = preIndex skippy, err := skipRpc(data[iNdEx:]) @@ -6546,7 +7748,7 @@ func (m *RangeResponse) Unmarshal(data []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Kvs = append(m.Kvs, &storagepb.KeyValue{}) + m.Kvs = append(m.Kvs, &mvccpb.KeyValue{}) if err := m.Kvs[len(m.Kvs)-1].Unmarshal(data[iNdEx:postIndex]); err != nil { return err } @@ -6571,6 +7773,25 @@ func (m *RangeResponse) Unmarshal(data []byte) error { } } m.More = bool(v != 0) + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Count", wireType) + } + m.Count = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + m.Count |= (int64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipRpc(data[iNdEx:]) @@ -7020,7 +8241,7 @@ func (m *DeleteRangeResponse) Unmarshal(data []byte) error { } return nil } -func (m *RequestUnion) Unmarshal(data []byte) error { +func (m *RequestOp) Unmarshal(data []byte) error { l := len(data) iNdEx := 0 for iNdEx < l { @@ -7043,10 +8264,10 @@ func (m *RequestUnion) Unmarshal(data []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: RequestUnion: wiretype end group for non-group") + return fmt.Errorf("proto: RequestOp: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: RequestUnion: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: RequestOp: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -7079,7 +8300,7 @@ func (m *RequestUnion) Unmarshal(data []byte) error { if err := v.Unmarshal(data[iNdEx:postIndex]); err != nil { return err } - m.Request = &RequestUnion_RequestRange{v} + m.Request = &RequestOp_RequestRange{v} iNdEx = postIndex case 2: if wireType != 2 { @@ -7111,7 +8332,7 @@ func (m *RequestUnion) Unmarshal(data []byte) error { if err := v.Unmarshal(data[iNdEx:postIndex]); err != nil { return err } - m.Request = &RequestUnion_RequestPut{v} + m.Request = &RequestOp_RequestPut{v} iNdEx = postIndex case 3: if wireType != 2 { @@ -7143,7 +8364,7 @@ func (m *RequestUnion) Unmarshal(data []byte) error { if err := v.Unmarshal(data[iNdEx:postIndex]); err != nil { return err } - m.Request = &RequestUnion_RequestDeleteRange{v} + m.Request = &RequestOp_RequestDeleteRange{v} iNdEx = postIndex default: iNdEx = preIndex @@ -7166,7 +8387,7 @@ func (m *RequestUnion) Unmarshal(data []byte) error { } return nil } -func (m *ResponseUnion) Unmarshal(data []byte) error { +func (m *ResponseOp) Unmarshal(data []byte) error { l := len(data) iNdEx := 0 for iNdEx < l { @@ -7189,10 +8410,10 @@ func (m *ResponseUnion) Unmarshal(data []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: ResponseUnion: wiretype end group for non-group") + return fmt.Errorf("proto: ResponseOp: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: ResponseUnion: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: ResponseOp: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -7225,7 +8446,7 @@ func (m *ResponseUnion) Unmarshal(data []byte) error { if err := v.Unmarshal(data[iNdEx:postIndex]); err != nil { return err } - m.Response = &ResponseUnion_ResponseRange{v} + m.Response = &ResponseOp_ResponseRange{v} iNdEx = postIndex case 2: if wireType != 2 { @@ -7257,7 +8478,7 @@ func (m *ResponseUnion) Unmarshal(data []byte) error { if err := v.Unmarshal(data[iNdEx:postIndex]); err != nil { return err } - m.Response = &ResponseUnion_ResponsePut{v} + m.Response = &ResponseOp_ResponsePut{v} iNdEx = postIndex case 3: if wireType != 2 { @@ -7289,7 +8510,7 @@ func (m *ResponseUnion) Unmarshal(data []byte) error { if err := v.Unmarshal(data[iNdEx:postIndex]); err != nil { return err } - m.Response = &ResponseUnion_ResponseDeleteRange{v} + m.Response = &ResponseOp_ResponseDeleteRange{v} iNdEx = postIndex default: iNdEx = preIndex @@ -7607,7 +8828,7 @@ func (m *TxnRequest) Unmarshal(data []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Success = append(m.Success, &RequestUnion{}) + m.Success = append(m.Success, &RequestOp{}) if err := m.Success[len(m.Success)-1].Unmarshal(data[iNdEx:postIndex]); err != nil { return err } @@ -7638,7 +8859,7 @@ func (m *TxnRequest) Unmarshal(data []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Failure = append(m.Failure, &RequestUnion{}) + m.Failure = append(m.Failure, &RequestOp{}) if err := m.Failure[len(m.Failure)-1].Unmarshal(data[iNdEx:postIndex]); err != nil { return err } @@ -7772,7 +8993,7 @@ func (m *TxnResponse) Unmarshal(data []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Responses = append(m.Responses, &ResponseUnion{}) + m.Responses = append(m.Responses, &ResponseOp{}) if err := m.Responses[len(m.Responses)-1].Unmarshal(data[iNdEx:postIndex]); err != nil { return err } @@ -8122,6 +9343,189 @@ func (m *HashResponse) Unmarshal(data []byte) error { } return nil } +func (m *SnapshotRequest) 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: SnapshotRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: SnapshotRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + 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 *SnapshotResponse) 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: SnapshotResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: SnapshotResponse: 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 RemainingBytes", wireType) + } + m.RemainingBytes = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + m.RemainingBytes |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Blob", 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.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:]) + 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 *WatchRequest) Unmarshal(data []byte) error { l := len(data) iNdEx := 0 @@ -8622,7 +10026,7 @@ func (m *WatchResponse) Unmarshal(data []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Events = append(m.Events, &storagepb.Event{}) + m.Events = append(m.Events, &mvccpb.Event{}) if err := m.Events[len(m.Events)-1].Unmarshal(data[iNdEx:postIndex]); err != nil { return err } @@ -9306,26 +10710,6 @@ func (m *Member) Unmarshal(data []byte) error { m.Name = string(data[iNdEx:postIndex]) iNdEx = postIndex case 3: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field IsLeader", 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.IsLeader = bool(v != 0) - case 4: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field PeerURLs", wireType) } @@ -9354,7 +10738,7 @@ func (m *Member) Unmarshal(data []byte) error { } m.PeerURLs = append(m.PeerURLs, string(data[iNdEx:postIndex])) iNdEx = postIndex - case 5: + case 4: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field ClientURLs", wireType) } @@ -10679,6 +12063,82 @@ func (m *StatusResponse) Unmarshal(data []byte) error { } m.Version = string(data[iNdEx:postIndex]) iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field DbSize", wireType) + } + m.DbSize = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + m.DbSize |= (int64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Leader", wireType) + } + m.Leader = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + m.Leader |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field RaftIndex", wireType) + } + m.RaftIndex = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + m.RaftIndex |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + case 6: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field RaftTerm", wireType) + } + m.RaftTerm = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + m.RaftTerm |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipRpc(data[iNdEx:]) @@ -10829,6 +12289,64 @@ func (m *AuthenticateRequest) Unmarshal(data []byte) error { return fmt.Errorf("proto: AuthenticateRequest: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthRpc + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(data[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Password", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthRpc + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Password = string(data[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipRpc(data[iNdEx:]) @@ -10987,6 +12505,35 @@ func (m *AuthUserGetRequest) Unmarshal(data []byte) error { return fmt.Errorf("proto: AuthUserGetRequest: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthRpc + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(data[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipRpc(data[iNdEx:]) @@ -11195,7 +12742,7 @@ func (m *AuthUserChangePasswordRequest) Unmarshal(data []byte) error { } return nil } -func (m *AuthUserGrantRequest) Unmarshal(data []byte) error { +func (m *AuthUserGrantRoleRequest) Unmarshal(data []byte) error { l := len(data) iNdEx := 0 for iNdEx < l { @@ -11218,12 +12765,70 @@ func (m *AuthUserGrantRequest) Unmarshal(data []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: AuthUserGrantRequest: wiretype end group for non-group") + return fmt.Errorf("proto: AuthUserGrantRoleRequest: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: AuthUserGrantRequest: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: AuthUserGrantRoleRequest: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field User", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthRpc + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.User = string(data[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Role", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthRpc + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Role = string(data[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipRpc(data[iNdEx:]) @@ -11245,7 +12850,7 @@ func (m *AuthUserGrantRequest) Unmarshal(data []byte) error { } return nil } -func (m *AuthUserRevokeRequest) Unmarshal(data []byte) error { +func (m *AuthUserRevokeRoleRequest) Unmarshal(data []byte) error { l := len(data) iNdEx := 0 for iNdEx < l { @@ -11268,12 +12873,70 @@ func (m *AuthUserRevokeRequest) Unmarshal(data []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: AuthUserRevokeRequest: wiretype end group for non-group") + return fmt.Errorf("proto: AuthUserRevokeRoleRequest: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: AuthUserRevokeRequest: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: AuthUserRevokeRoleRequest: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthRpc + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(data[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Role", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthRpc + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Role = string(data[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipRpc(data[iNdEx:]) @@ -11403,6 +13066,135 @@ func (m *AuthRoleGetRequest) Unmarshal(data []byte) error { return fmt.Errorf("proto: AuthRoleGetRequest: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Role", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthRpc + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Role = string(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 *AuthUserListRequest) 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: AuthUserListRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: AuthUserListRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + 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 *AuthRoleListRequest) 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: AuthRoleListRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: AuthRoleListRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { default: iNdEx = preIndex skippy, err := skipRpc(data[iNdEx:]) @@ -11453,6 +13245,35 @@ func (m *AuthRoleDeleteRequest) Unmarshal(data []byte) error { return fmt.Errorf("proto: AuthRoleDeleteRequest: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Role", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthRpc + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Role = string(data[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipRpc(data[iNdEx:]) @@ -11474,7 +13295,7 @@ func (m *AuthRoleDeleteRequest) Unmarshal(data []byte) error { } return nil } -func (m *AuthRoleGrantRequest) Unmarshal(data []byte) error { +func (m *AuthRoleGrantPermissionRequest) Unmarshal(data []byte) error { l := len(data) iNdEx := 0 for iNdEx < l { @@ -11497,12 +13318,74 @@ func (m *AuthRoleGrantRequest) Unmarshal(data []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: AuthRoleGrantRequest: wiretype end group for non-group") + return fmt.Errorf("proto: AuthRoleGrantPermissionRequest: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: AuthRoleGrantRequest: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: AuthRoleGrantPermissionRequest: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthRpc + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(data[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Perm", 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.Perm == nil { + m.Perm = &authpb.Permission{} + } + if err := m.Perm.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipRpc(data[iNdEx:]) @@ -11524,7 +13407,7 @@ func (m *AuthRoleGrantRequest) Unmarshal(data []byte) error { } return nil } -func (m *AuthRoleRevokeRequest) Unmarshal(data []byte) error { +func (m *AuthRoleRevokePermissionRequest) Unmarshal(data []byte) error { l := len(data) iNdEx := 0 for iNdEx < l { @@ -11547,12 +13430,99 @@ func (m *AuthRoleRevokeRequest) Unmarshal(data []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: AuthRoleRevokeRequest: wiretype end group for non-group") + return fmt.Errorf("proto: AuthRoleRevokePermissionRequest: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: AuthRoleRevokeRequest: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: AuthRoleRevokePermissionRequest: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Role", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthRpc + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Role = string(data[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Key", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthRpc + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Key = string(data[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field RangeEnd", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthRpc + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.RangeEnd = string(data[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipRpc(data[iNdEx:]) @@ -11802,6 +13772,35 @@ func (m *AuthenticateResponse) Unmarshal(data []byte) error { return err } iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Token", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthRpc + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Token = string(data[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipRpc(data[iNdEx:]) @@ -11968,6 +13967,35 @@ func (m *AuthUserGetResponse) Unmarshal(data []byte) error { return err } iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Roles", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthRpc + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Roles = append(m.Roles, string(data[iNdEx:postIndex])) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipRpc(data[iNdEx:]) @@ -12155,7 +14183,7 @@ func (m *AuthUserChangePasswordResponse) Unmarshal(data []byte) error { } return nil } -func (m *AuthUserGrantResponse) Unmarshal(data []byte) error { +func (m *AuthUserGrantRoleResponse) Unmarshal(data []byte) error { l := len(data) iNdEx := 0 for iNdEx < l { @@ -12178,10 +14206,10 @@ func (m *AuthUserGrantResponse) Unmarshal(data []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: AuthUserGrantResponse: wiretype end group for non-group") + return fmt.Errorf("proto: AuthUserGrantRoleResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: AuthUserGrantResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: AuthUserGrantRoleResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -12238,7 +14266,7 @@ func (m *AuthUserGrantResponse) Unmarshal(data []byte) error { } return nil } -func (m *AuthUserRevokeResponse) Unmarshal(data []byte) error { +func (m *AuthUserRevokeRoleResponse) Unmarshal(data []byte) error { l := len(data) iNdEx := 0 for iNdEx < l { @@ -12261,10 +14289,10 @@ func (m *AuthUserRevokeResponse) Unmarshal(data []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: AuthUserRevokeResponse: wiretype end group for non-group") + return fmt.Errorf("proto: AuthUserRevokeRoleResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: AuthUserRevokeResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: AuthUserRevokeRoleResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -12466,6 +14494,261 @@ func (m *AuthRoleGetResponse) Unmarshal(data []byte) error { return err } iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Perm", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthRpc + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Perm = append(m.Perm, &authpb.Permission{}) + 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:]) + 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 *AuthRoleListResponse) 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: AuthRoleListResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: AuthRoleListResponse: 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 != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Roles", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthRpc + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Roles = append(m.Roles, string(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 *AuthUserListResponse) 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: AuthUserListResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: AuthUserListResponse: 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 != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Users", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthRpc + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Users = append(m.Users, string(data[iNdEx:postIndex])) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipRpc(data[iNdEx:]) @@ -12570,7 +14853,7 @@ func (m *AuthRoleDeleteResponse) Unmarshal(data []byte) error { } return nil } -func (m *AuthRoleGrantResponse) Unmarshal(data []byte) error { +func (m *AuthRoleGrantPermissionResponse) Unmarshal(data []byte) error { l := len(data) iNdEx := 0 for iNdEx < l { @@ -12593,10 +14876,10 @@ func (m *AuthRoleGrantResponse) Unmarshal(data []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: AuthRoleGrantResponse: wiretype end group for non-group") + return fmt.Errorf("proto: AuthRoleGrantPermissionResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: AuthRoleGrantResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: AuthRoleGrantPermissionResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -12653,7 +14936,7 @@ func (m *AuthRoleGrantResponse) Unmarshal(data []byte) error { } return nil } -func (m *AuthRoleRevokeResponse) Unmarshal(data []byte) error { +func (m *AuthRoleRevokePermissionResponse) Unmarshal(data []byte) error { l := len(data) iNdEx := 0 for iNdEx < l { @@ -12676,10 +14959,10 @@ func (m *AuthRoleRevokeResponse) Unmarshal(data []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: AuthRoleRevokeResponse: wiretype end group for non-group") + return fmt.Errorf("proto: AuthRoleRevokePermissionResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: AuthRoleRevokeResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: AuthRoleRevokePermissionResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -12840,3 +15123,205 @@ var ( ErrInvalidLengthRpc = fmt.Errorf("proto: negative length found during unmarshaling") ErrIntOverflowRpc = fmt.Errorf("proto: integer overflow") ) + +var fileDescriptorRpc = []byte{ + // 3154 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xb4, 0x5a, 0xcd, 0x72, 0xe3, 0xc6, + 0xf1, 0x17, 0x48, 0x4a, 0x14, 0x9b, 0x14, 0xc5, 0x1d, 0x69, 0xd7, 0x14, 0x56, 0xab, 0xd5, 0xce, + 0x7e, 0xc9, 0x6b, 0x5b, 0xb4, 0x65, 0xff, 0xff, 0x87, 0x4d, 0xca, 0x55, 0x92, 0xc8, 0xac, 0x64, + 0xc9, 0xd2, 0x1a, 0xd2, 0xca, 0x4e, 0x55, 0x2a, 0x2a, 0x88, 0x9c, 0x25, 0x59, 0x22, 0x01, 0x1a, + 0x00, 0xb9, 0x2b, 0x27, 0xa9, 0x4a, 0xb9, 0xe2, 0x43, 0x72, 0xf5, 0x21, 0x5f, 0xc7, 0x3c, 0x43, + 0x6e, 0x79, 0x80, 0x54, 0x2e, 0x71, 0x55, 0x5e, 0x20, 0xb5, 0xc9, 0x21, 0x87, 0xdc, 0x53, 0x39, + 0xa4, 0x92, 0x9a, 0x2f, 0x60, 0x00, 0x02, 0x94, 0x1c, 0xc4, 0x17, 0x09, 0xd3, 0xd3, 0xd3, 0xbf, + 0x9e, 0x9e, 0xe9, 0x46, 0x77, 0x83, 0x50, 0x70, 0x06, 0xcd, 0xf5, 0x81, 0x63, 0x7b, 0x36, 0x2a, + 0x11, 0xaf, 0xd9, 0x72, 0x89, 0x33, 0x22, 0xce, 0xe0, 0x4c, 0x5f, 0x6c, 0xdb, 0x6d, 0x9b, 0x4d, + 0xd4, 0xe8, 0x13, 0xe7, 0xd1, 0x97, 0x28, 0x4f, 0xad, 0x3f, 0x6a, 0x36, 0xd9, 0x9f, 0xc1, 0x59, + 0xed, 0x7c, 0x24, 0xa6, 0x6e, 0xb2, 0x29, 0x73, 0xe8, 0x75, 0xd8, 0x9f, 0xc1, 0x19, 0xfb, 0x27, + 0x26, 0x97, 0xdb, 0xb6, 0xdd, 0xee, 0x91, 0x9a, 0x39, 0xe8, 0xd6, 0x4c, 0xcb, 0xb2, 0x3d, 0xd3, + 0xeb, 0xda, 0x96, 0xcb, 0x67, 0xf1, 0x17, 0x1a, 0x94, 0x0d, 0xe2, 0x0e, 0x6c, 0xcb, 0x25, 0x3b, + 0xc4, 0x6c, 0x11, 0x07, 0xdd, 0x02, 0x68, 0xf6, 0x86, 0xae, 0x47, 0x9c, 0xd3, 0x6e, 0xab, 0xaa, + 0xad, 0x6a, 0x6b, 0x39, 0xa3, 0x20, 0x28, 0xbb, 0x2d, 0x74, 0x13, 0x0a, 0x7d, 0xd2, 0x3f, 0xe3, + 0xb3, 0x19, 0x36, 0x3b, 0xcb, 0x09, 0xbb, 0x2d, 0xa4, 0xc3, 0xac, 0x43, 0x46, 0x5d, 0xb7, 0x6b, + 0x5b, 0xd5, 0xec, 0xaa, 0xb6, 0x96, 0x35, 0xfc, 0x31, 0x5d, 0xe8, 0x98, 0xcf, 0xbd, 0x53, 0x8f, + 0x38, 0xfd, 0x6a, 0x8e, 0x2f, 0xa4, 0x84, 0x63, 0xe2, 0xf4, 0xf1, 0x57, 0x59, 0x28, 0x19, 0xa6, + 0xd5, 0x26, 0x06, 0xf9, 0x74, 0x48, 0x5c, 0x0f, 0x55, 0x20, 0x7b, 0x4e, 0x2e, 0x18, 0x7c, 0xc9, + 0xa0, 0x8f, 0x7c, 0xbd, 0xd5, 0x26, 0xa7, 0xc4, 0xe2, 0xc0, 0x25, 0xba, 0xde, 0x6a, 0x93, 0x86, + 0xd5, 0x42, 0x8b, 0x30, 0xdd, 0xeb, 0xf6, 0xbb, 0x9e, 0x40, 0xe5, 0x83, 0x90, 0x3a, 0xb9, 0x88, + 0x3a, 0xdb, 0x00, 0xae, 0xed, 0x78, 0xa7, 0xb6, 0xd3, 0x22, 0x4e, 0x75, 0x7a, 0x55, 0x5b, 0x2b, + 0x6f, 0xdc, 0x5b, 0x57, 0x0f, 0x62, 0x5d, 0x55, 0x68, 0xfd, 0xc8, 0x76, 0xbc, 0x43, 0xca, 0x6b, + 0x14, 0x5c, 0xf9, 0x88, 0xbe, 0x03, 0x45, 0x26, 0xc4, 0x33, 0x9d, 0x36, 0xf1, 0xaa, 0x33, 0x4c, + 0xca, 0xfd, 0x4b, 0xa4, 0x1c, 0x33, 0x66, 0x83, 0xc1, 0xf3, 0x67, 0x84, 0xa1, 0xe4, 0x12, 0xa7, + 0x6b, 0xf6, 0xba, 0x9f, 0x99, 0x67, 0x3d, 0x52, 0xcd, 0xaf, 0x6a, 0x6b, 0xb3, 0x46, 0x88, 0x46, + 0xf7, 0x7f, 0x4e, 0x2e, 0xdc, 0x53, 0xdb, 0xea, 0x5d, 0x54, 0x67, 0x19, 0xc3, 0x2c, 0x25, 0x1c, + 0x5a, 0xbd, 0x0b, 0x76, 0x68, 0xf6, 0xd0, 0xf2, 0xf8, 0x6c, 0x81, 0xcd, 0x16, 0x18, 0x85, 0x4e, + 0xe3, 0x75, 0x28, 0xf8, 0xfa, 0xa3, 0x59, 0xc8, 0x1d, 0x1c, 0x1e, 0x34, 0x2a, 0x53, 0x08, 0x60, + 0x66, 0xf3, 0x68, 0xbb, 0x71, 0x50, 0xaf, 0x68, 0xa8, 0x08, 0xf9, 0x7a, 0x83, 0x0f, 0x32, 0x78, + 0x0b, 0x20, 0xd0, 0x14, 0xe5, 0x21, 0xbb, 0xd7, 0xf8, 0x6e, 0x65, 0x8a, 0xf2, 0x9c, 0x34, 0x8c, + 0xa3, 0xdd, 0xc3, 0x83, 0x8a, 0x46, 0x17, 0x6f, 0x1b, 0x8d, 0xcd, 0xe3, 0x46, 0x25, 0x43, 0x39, + 0x3e, 0x3c, 0xac, 0x57, 0xb2, 0xa8, 0x00, 0xd3, 0x27, 0x9b, 0xfb, 0xcf, 0x1a, 0x95, 0x1c, 0xfe, + 0x52, 0x83, 0x39, 0xb1, 0x77, 0x7e, 0xbf, 0xd0, 0x7b, 0x30, 0xd3, 0x61, 0x77, 0x8c, 0x1d, 0x6b, + 0x71, 0x63, 0x39, 0x62, 0xa8, 0xd0, 0x3d, 0x34, 0x04, 0x2f, 0xc2, 0x90, 0x3d, 0x1f, 0xb9, 0xd5, + 0xcc, 0x6a, 0x76, 0xad, 0xb8, 0x51, 0x59, 0xe7, 0x97, 0x7f, 0x7d, 0x8f, 0x5c, 0x9c, 0x98, 0xbd, + 0x21, 0x31, 0xe8, 0x24, 0x42, 0x90, 0xeb, 0xdb, 0x0e, 0x61, 0xa7, 0x3f, 0x6b, 0xb0, 0x67, 0x7a, + 0x25, 0x98, 0x01, 0xc4, 0xc9, 0xf3, 0x01, 0xfe, 0x00, 0xe0, 0xe9, 0xd0, 0x4b, 0xbe, 0x65, 0x8b, + 0x30, 0x3d, 0xa2, 0x72, 0xc5, 0x0d, 0xe3, 0x03, 0x76, 0xbd, 0x88, 0xe9, 0x12, 0xff, 0x7a, 0xd1, + 0x01, 0xde, 0x86, 0x22, 0x93, 0x95, 0x66, 0x7b, 0x78, 0x1b, 0x50, 0x9d, 0xf4, 0x88, 0x47, 0x52, + 0x5c, 0x7f, 0x4c, 0x60, 0x21, 0x24, 0x24, 0x95, 0xc1, 0xab, 0x90, 0x6f, 0x31, 0x61, 0x1c, 0x27, + 0x6b, 0xc8, 0x21, 0xfe, 0xbb, 0x06, 0x05, 0xa1, 0xe1, 0xe1, 0x00, 0x6d, 0xc2, 0x9c, 0xc3, 0x07, + 0xa7, 0x4c, 0x11, 0x01, 0xa2, 0x27, 0x5f, 0xff, 0x9d, 0x29, 0xa3, 0x24, 0x96, 0x30, 0x32, 0xfa, + 0x16, 0x14, 0xa5, 0x88, 0xc1, 0xd0, 0x63, 0x70, 0xc5, 0x8d, 0x6a, 0x58, 0x40, 0x70, 0x5c, 0x3b, + 0x53, 0x06, 0x08, 0xf6, 0xa7, 0x43, 0x0f, 0x1d, 0xc3, 0xa2, 0x5c, 0xcc, 0x15, 0x14, 0x6a, 0x64, + 0x99, 0x94, 0xd5, 0xb0, 0x94, 0x71, 0x1b, 0xef, 0x4c, 0x19, 0x48, 0xac, 0x57, 0x26, 0xb7, 0x0a, + 0x90, 0x17, 0x54, 0xfc, 0x0f, 0x0d, 0x40, 0xda, 0xe8, 0x70, 0x80, 0xea, 0x50, 0x76, 0xc4, 0x28, + 0xb4, 0xe1, 0x9b, 0xb1, 0x1b, 0x16, 0xa6, 0x9d, 0x32, 0xe6, 0xe4, 0x22, 0xbe, 0xe5, 0xf7, 0xa1, + 0xe4, 0x4b, 0x09, 0xf6, 0xbc, 0x14, 0xb3, 0x67, 0x5f, 0x42, 0x51, 0x2e, 0xa0, 0xbb, 0xfe, 0x18, + 0xae, 0xfb, 0xeb, 0x63, 0xb6, 0x7d, 0x67, 0xc2, 0xb6, 0x7d, 0x81, 0x0b, 0x52, 0x82, 0xba, 0x71, + 0xa0, 0xc1, 0x92, 0x93, 0xf1, 0xaf, 0xb2, 0x90, 0xdf, 0xb6, 0xfb, 0x03, 0xd3, 0xa1, 0x67, 0x34, + 0xe3, 0x10, 0x77, 0xd8, 0xf3, 0xd8, 0x76, 0xcb, 0x1b, 0x77, 0xc3, 0x08, 0x82, 0x4d, 0xfe, 0x37, + 0x18, 0xab, 0x21, 0x96, 0xd0, 0xc5, 0x22, 0x36, 0x66, 0xae, 0xb0, 0x58, 0x44, 0x46, 0xb1, 0x44, + 0x3a, 0x41, 0x36, 0x70, 0x02, 0x1d, 0xf2, 0x23, 0xe2, 0x04, 0xf1, 0x7c, 0x67, 0xca, 0x90, 0x04, + 0xf4, 0x3a, 0xcc, 0x37, 0x1d, 0x62, 0x52, 0x7b, 0xc8, 0x98, 0x3f, 0x2d, 0x78, 0xca, 0x7c, 0xc2, + 0x90, 0xb1, 0xff, 0x2e, 0x94, 0xfa, 0x76, 0x2b, 0xe0, 0x9b, 0x11, 0x7c, 0xc5, 0xbe, 0xdd, 0xf2, + 0x99, 0x6e, 0xc8, 0x48, 0x40, 0x83, 0x71, 0x69, 0x67, 0x4a, 0xc4, 0x02, 0xfc, 0x0e, 0xcc, 0x85, + 0xf6, 0x4a, 0x63, 0x5e, 0xe3, 0xa3, 0x67, 0x9b, 0xfb, 0x3c, 0x40, 0x3e, 0x61, 0x31, 0xd1, 0xa8, + 0x68, 0x34, 0xce, 0xee, 0x37, 0x8e, 0x8e, 0x2a, 0x19, 0xfc, 0x6d, 0x7f, 0x89, 0x88, 0xa8, 0x4a, + 0x20, 0x9d, 0x52, 0x02, 0xa9, 0x26, 0x03, 0x69, 0x26, 0x08, 0xa4, 0xd9, 0xad, 0x32, 0x94, 0xb8, + 0x41, 0x4e, 0x87, 0x56, 0xd7, 0xb6, 0xf0, 0x6f, 0x34, 0x80, 0xe3, 0x97, 0x96, 0x0c, 0x15, 0x35, + 0xc8, 0x37, 0xb9, 0xf0, 0xaa, 0xc6, 0x62, 0xe4, 0xf5, 0x58, 0x1b, 0x1b, 0x92, 0x0b, 0xbd, 0x03, + 0x79, 0x77, 0xd8, 0x6c, 0x12, 0x57, 0x06, 0xd5, 0xd7, 0xa2, 0x61, 0x41, 0x78, 0xb8, 0x21, 0xf9, + 0xe8, 0x92, 0xe7, 0x66, 0xb7, 0x37, 0x64, 0x21, 0x76, 0xf2, 0x12, 0xc1, 0x87, 0x7f, 0xa9, 0x41, + 0x91, 0x69, 0x99, 0x2a, 0x16, 0x2d, 0x43, 0x81, 0xe9, 0x40, 0x5a, 0x22, 0x1a, 0xcd, 0x1a, 0x01, + 0x01, 0xfd, 0x3f, 0x14, 0xe4, 0x95, 0x75, 0x85, 0x62, 0xd5, 0x78, 0xb1, 0x87, 0x03, 0x23, 0x60, + 0xc5, 0x7b, 0x70, 0x8d, 0x59, 0xa5, 0x49, 0x53, 0x21, 0x69, 0x47, 0x35, 0x59, 0xd0, 0x22, 0xc9, + 0x82, 0x0e, 0xb3, 0x83, 0xce, 0x85, 0xdb, 0x6d, 0x9a, 0x3d, 0xa1, 0x85, 0x3f, 0xc6, 0x1f, 0x00, + 0x52, 0x85, 0xa5, 0x7a, 0x19, 0xcc, 0x41, 0x71, 0xc7, 0x74, 0x3b, 0x42, 0x25, 0xfc, 0x09, 0x94, + 0xf8, 0x30, 0x95, 0x0d, 0x11, 0xe4, 0x3a, 0xa6, 0xdb, 0x61, 0x8a, 0xcf, 0x19, 0xec, 0x19, 0x5f, + 0x83, 0xf9, 0x23, 0xcb, 0x1c, 0xb8, 0x1d, 0x5b, 0x06, 0x57, 0x9a, 0x0a, 0x56, 0x02, 0x5a, 0x2a, + 0xc4, 0x87, 0x30, 0xef, 0x90, 0xbe, 0xd9, 0xb5, 0xba, 0x56, 0xfb, 0xf4, 0xec, 0xc2, 0x23, 0xae, + 0xc8, 0x14, 0xcb, 0x3e, 0x79, 0x8b, 0x52, 0xa9, 0x6a, 0x67, 0x3d, 0xfb, 0x4c, 0xb8, 0x38, 0x7b, + 0xc6, 0xbf, 0xd5, 0xa0, 0xf4, 0xb1, 0xe9, 0x35, 0xa5, 0x15, 0xd0, 0x2e, 0x94, 0x7d, 0xc7, 0x66, + 0x14, 0xa1, 0x4b, 0x24, 0xc2, 0xb3, 0x35, 0xdb, 0xc2, 0xd1, 0x65, 0x84, 0x9f, 0x6b, 0xaa, 0x04, + 0x26, 0xca, 0xb4, 0x9a, 0xa4, 0xe7, 0x8b, 0xca, 0x24, 0x8b, 0x62, 0x8c, 0xaa, 0x28, 0x95, 0xb0, + 0x35, 0x1f, 0xbc, 0xfd, 0xb8, 0x5b, 0x7e, 0xa9, 0x01, 0x1a, 0xd7, 0xe1, 0xeb, 0x26, 0xb2, 0xf7, + 0xa1, 0xec, 0x7a, 0xa6, 0xe3, 0x9d, 0x46, 0xf2, 0xe8, 0x39, 0x46, 0xf5, 0x83, 0xd3, 0x43, 0x98, + 0x1f, 0x38, 0x76, 0xdb, 0x21, 0xae, 0x7b, 0x6a, 0xd9, 0x5e, 0xf7, 0xf9, 0x05, 0x0b, 0x88, 0xb3, + 0x46, 0x59, 0x92, 0x0f, 0x18, 0x15, 0xd7, 0xa4, 0x52, 0xaa, 0xf2, 0x68, 0x09, 0x66, 0x5f, 0x50, + 0xaa, 0xcc, 0xf0, 0xb3, 0x46, 0x9e, 0x8d, 0x77, 0x5b, 0xf8, 0x6f, 0x1a, 0xcc, 0x09, 0xf3, 0xa7, + 0xba, 0x03, 0x2a, 0x44, 0x26, 0x04, 0x41, 0x13, 0x0c, 0x7e, 0x2c, 0x2d, 0x91, 0xb0, 0xc9, 0x21, + 0xf5, 0x33, 0x6e, 0x65, 0xd2, 0x12, 0xfb, 0xf1, 0xc7, 0xe8, 0x75, 0xa8, 0x34, 0xb9, 0x9f, 0x45, + 0x02, 0xbc, 0x31, 0x2f, 0xe8, 0xbe, 0x75, 0xee, 0xc3, 0x0c, 0x19, 0x11, 0xcb, 0x73, 0xab, 0x45, + 0x16, 0x14, 0xe6, 0x64, 0xd6, 0xd8, 0xa0, 0x54, 0x43, 0x4c, 0xe2, 0xff, 0x83, 0x6b, 0xfb, 0x34, + 0x91, 0x7b, 0xe2, 0x98, 0x96, 0x9a, 0x12, 0x1e, 0x1f, 0xef, 0x0b, 0xab, 0x64, 0xbd, 0xe3, 0x7d, + 0x54, 0x86, 0xcc, 0x6e, 0x5d, 0xec, 0x21, 0xd3, 0xad, 0xe3, 0xcf, 0x35, 0x40, 0xea, 0xba, 0x54, + 0x66, 0x8a, 0x08, 0x97, 0xf0, 0xd9, 0x00, 0x7e, 0x11, 0xa6, 0x89, 0xe3, 0xd8, 0x0e, 0x33, 0x48, + 0xc1, 0xe0, 0x03, 0x7c, 0x4f, 0xe8, 0x60, 0x90, 0x91, 0x7d, 0xee, 0x5f, 0x36, 0x2e, 0x4d, 0xf3, + 0x55, 0xdd, 0x83, 0x85, 0x10, 0x57, 0xaa, 0xe0, 0xf4, 0x10, 0xae, 0x33, 0x61, 0x7b, 0x84, 0x0c, + 0x36, 0x7b, 0xdd, 0x51, 0x22, 0xea, 0x00, 0x6e, 0x44, 0x19, 0xbf, 0x59, 0x1b, 0xe1, 0x0e, 0xcc, + 0x7c, 0xc8, 0x6a, 0x50, 0x45, 0x97, 0x1c, 0xe3, 0x45, 0x90, 0xb3, 0xcc, 0x3e, 0x4f, 0xe7, 0x0b, + 0x06, 0x7b, 0x66, 0xd1, 0x9c, 0x10, 0xe7, 0x99, 0xb1, 0xcf, 0xdf, 0x1a, 0x05, 0xc3, 0x1f, 0xa3, + 0x15, 0x5a, 0xfd, 0x76, 0x89, 0xe5, 0xb1, 0xd9, 0x1c, 0x9b, 0x55, 0x28, 0x78, 0x1d, 0x2a, 0x1c, + 0x69, 0xb3, 0xd5, 0x52, 0xde, 0x1c, 0xbe, 0x3c, 0x2d, 0x2c, 0x0f, 0xbf, 0x80, 0x6b, 0x0a, 0x7f, + 0x2a, 0x33, 0xbc, 0x09, 0x33, 0xbc, 0xd0, 0x16, 0x41, 0x6b, 0x31, 0xbc, 0x8a, 0xc3, 0x18, 0x82, + 0x07, 0xdf, 0x87, 0x05, 0x41, 0x21, 0x7d, 0x3b, 0xee, 0xac, 0x98, 0x7d, 0xf0, 0x3e, 0x2c, 0x86, + 0xd9, 0x52, 0x5d, 0x91, 0x4d, 0x09, 0xfa, 0x6c, 0xd0, 0x52, 0x62, 0x60, 0xf4, 0x50, 0x54, 0x83, + 0x65, 0x22, 0x06, 0xf3, 0x15, 0x92, 0x22, 0x52, 0x29, 0xb4, 0x20, 0xcd, 0xbf, 0xdf, 0x75, 0xfd, + 0x37, 0xdd, 0x67, 0x80, 0x54, 0x62, 0xaa, 0x43, 0x59, 0x87, 0x3c, 0x37, 0xb8, 0x4c, 0xa6, 0xe2, + 0x4f, 0x45, 0x32, 0x51, 0x85, 0xea, 0xe4, 0xb9, 0x63, 0xb6, 0xfb, 0xc4, 0x8f, 0x39, 0x34, 0x85, + 0x50, 0x89, 0xa9, 0x76, 0xfc, 0x47, 0x0d, 0x4a, 0x9b, 0x3d, 0xd3, 0xe9, 0x4b, 0xe3, 0xbf, 0x0f, + 0x33, 0x3c, 0x37, 0x11, 0xf9, 0xfb, 0x83, 0xb0, 0x18, 0x95, 0x97, 0x0f, 0x36, 0x79, 0x26, 0x23, + 0x56, 0xd1, 0xc3, 0x12, 0xfd, 0x9d, 0x7a, 0xa4, 0xdf, 0x53, 0x47, 0x6f, 0xc1, 0xb4, 0x49, 0x97, + 0x30, 0x5f, 0x2c, 0x47, 0xb3, 0x42, 0x26, 0xed, 0xf8, 0x62, 0x40, 0x0c, 0xce, 0x85, 0xdf, 0x83, + 0xa2, 0x82, 0x40, 0x93, 0xdd, 0x27, 0x8d, 0xe3, 0xca, 0x14, 0x2a, 0xc1, 0xec, 0xe6, 0xf6, 0xf1, + 0xee, 0x09, 0xcf, 0x81, 0xcb, 0x00, 0xf5, 0x86, 0x3f, 0xce, 0xe0, 0x4f, 0xc4, 0x2a, 0xe1, 0xe1, + 0xaa, 0x3e, 0x5a, 0x92, 0x3e, 0x99, 0x2b, 0xe9, 0xf3, 0x12, 0xe6, 0xc4, 0xf6, 0x53, 0xdd, 0x81, + 0x77, 0x60, 0x86, 0xc9, 0x93, 0x57, 0x60, 0x29, 0x06, 0x56, 0x7a, 0x27, 0x67, 0xc4, 0xf3, 0x30, + 0x77, 0xe4, 0x99, 0xde, 0xd0, 0x95, 0x57, 0xe0, 0x0f, 0x1a, 0x94, 0x25, 0x25, 0x6d, 0xf5, 0x2e, + 0x4b, 0x24, 0x1e, 0xf3, 0xfc, 0x02, 0xe9, 0x06, 0xcc, 0xb4, 0xce, 0x8e, 0xba, 0x9f, 0xc9, 0x2e, + 0x86, 0x18, 0x51, 0x7a, 0x8f, 0xe3, 0xf0, 0xae, 0x9c, 0x18, 0xd1, 0xdc, 0xdb, 0x31, 0x9f, 0x7b, + 0xbb, 0x56, 0x8b, 0xbc, 0x64, 0x6f, 0xda, 0x9c, 0x11, 0x10, 0x58, 0xba, 0x2c, 0xba, 0x77, 0xac, + 0x7e, 0x52, 0xbb, 0x79, 0x0b, 0x70, 0x6d, 0x73, 0xe8, 0x75, 0x1a, 0x96, 0x79, 0xd6, 0x93, 0x41, + 0x00, 0x2f, 0x02, 0xa2, 0xc4, 0x7a, 0xd7, 0x55, 0xa9, 0x0d, 0x58, 0xa0, 0x54, 0x62, 0x79, 0xdd, + 0xa6, 0x12, 0x31, 0x64, 0xd8, 0xd6, 0x22, 0x61, 0xdb, 0x74, 0xdd, 0x17, 0xb6, 0xd3, 0x12, 0x5b, + 0xf3, 0xc7, 0xb8, 0xce, 0x85, 0x3f, 0x73, 0x43, 0x81, 0xf9, 0xeb, 0x4a, 0x59, 0x0b, 0xa4, 0x3c, + 0x21, 0xde, 0x04, 0x29, 0xf8, 0x0d, 0xb8, 0x2e, 0x39, 0x45, 0x0d, 0x3d, 0x81, 0xf9, 0x10, 0x6e, + 0x49, 0xe6, 0xed, 0x0e, 0x4d, 0xf4, 0x9e, 0x0a, 0xc0, 0xff, 0x56, 0xcf, 0x2d, 0xa8, 0xfa, 0x7a, + 0xb2, 0x1c, 0xc4, 0xee, 0xa9, 0x0a, 0x0c, 0x5d, 0x71, 0x67, 0x0a, 0x06, 0x7b, 0xa6, 0x34, 0xc7, + 0xee, 0xf9, 0x2f, 0x41, 0xfa, 0x8c, 0xb7, 0x61, 0x49, 0xca, 0x10, 0xd9, 0x41, 0x58, 0xc8, 0x98, + 0x42, 0x71, 0x42, 0x84, 0xc1, 0xe8, 0xd2, 0xc9, 0x66, 0x57, 0x39, 0xc3, 0xa6, 0x65, 0x32, 0x35, + 0x45, 0xe6, 0x75, 0x7e, 0x23, 0xa8, 0x62, 0x6a, 0xd0, 0x16, 0x64, 0x2a, 0x40, 0x25, 0x8b, 0x83, + 0xa0, 0xe4, 0xb1, 0x83, 0x18, 0x13, 0xfd, 0x3d, 0x58, 0xf1, 0x95, 0xa0, 0x76, 0x7b, 0x4a, 0x9c, + 0x7e, 0xd7, 0x75, 0x95, 0x22, 0x30, 0x6e, 0xe3, 0x0f, 0x20, 0x37, 0x20, 0x22, 0xa6, 0x14, 0x37, + 0xd0, 0x3a, 0xef, 0xb1, 0xaf, 0x2b, 0x8b, 0xd9, 0x3c, 0x6e, 0xc1, 0x6d, 0x29, 0x9d, 0x5b, 0x34, + 0x56, 0x7c, 0x54, 0x29, 0x59, 0x20, 0x70, 0xb3, 0x8e, 0x17, 0x08, 0x59, 0x7e, 0xf6, 0x7e, 0xab, + 0xef, 0x03, 0x6e, 0x48, 0xe9, 0x5b, 0xa9, 0xde, 0x15, 0x7b, 0xdc, 0xa6, 0xbe, 0x4b, 0xa6, 0x12, + 0x76, 0x06, 0x8b, 0x61, 0x4f, 0x4e, 0x15, 0xc6, 0x16, 0x61, 0xda, 0xb3, 0xcf, 0x89, 0x0c, 0x62, + 0x7c, 0x20, 0x15, 0xf6, 0xdd, 0x3c, 0x95, 0xc2, 0x66, 0x20, 0x8c, 0x5d, 0xc9, 0xb4, 0xfa, 0xd2, + 0xd3, 0x94, 0xf9, 0x0c, 0x1f, 0xe0, 0x03, 0xb8, 0x11, 0x0d, 0x13, 0xa9, 0x54, 0x3e, 0xe1, 0x17, + 0x38, 0x2e, 0x92, 0xa4, 0x92, 0xfb, 0x51, 0x10, 0x0c, 0x94, 0x80, 0x92, 0x4a, 0xa4, 0x01, 0x7a, + 0x5c, 0x7c, 0xf9, 0x5f, 0xdc, 0x57, 0x3f, 0xdc, 0xa4, 0x12, 0xe6, 0x06, 0xc2, 0xd2, 0x1f, 0x7f, + 0x10, 0x23, 0xb2, 0x13, 0x63, 0x84, 0x70, 0x92, 0x20, 0x8a, 0x7d, 0x03, 0x97, 0x4e, 0x60, 0x04, + 0x01, 0x34, 0x2d, 0x06, 0x7d, 0x87, 0xf8, 0x18, 0x6c, 0x20, 0x2f, 0xb6, 0x1a, 0x76, 0x53, 0x1d, + 0xc6, 0xc7, 0x41, 0xec, 0x1c, 0x8b, 0xcc, 0xa9, 0x04, 0x7f, 0x02, 0xab, 0xc9, 0x41, 0x39, 0x8d, + 0xe4, 0x47, 0x18, 0x0a, 0x7e, 0x42, 0xa9, 0x7c, 0x53, 0x2b, 0x42, 0xfe, 0xe0, 0xf0, 0xe8, 0xe9, + 0xe6, 0x76, 0xa3, 0xa2, 0x6d, 0xfc, 0x2b, 0x0b, 0x99, 0xbd, 0x13, 0xf4, 0x7d, 0x98, 0xe6, 0xcd, + 0xff, 0x09, 0xdf, 0x46, 0xf4, 0x49, 0x9f, 0x11, 0xf0, 0xf2, 0xe7, 0x7f, 0xfa, 0xeb, 0x97, 0x99, + 0x1b, 0xf8, 0x5a, 0x6d, 0xf4, 0xae, 0xd9, 0x1b, 0x74, 0xcc, 0xda, 0xf9, 0xa8, 0xc6, 0xde, 0x09, + 0x8f, 0xb5, 0x47, 0xe8, 0x04, 0xb2, 0x4f, 0x87, 0x1e, 0x4a, 0xfc, 0x70, 0xa2, 0x27, 0x7f, 0x5e, + 0xc0, 0x3a, 0x93, 0xbc, 0x88, 0xe7, 0x55, 0xc9, 0x83, 0xa1, 0x47, 0xe5, 0x8e, 0xa0, 0xa8, 0x7c, + 0x21, 0x40, 0x97, 0x7e, 0x52, 0xd1, 0x2f, 0xff, 0xfa, 0x80, 0x31, 0xc3, 0x5b, 0xc6, 0xaf, 0xa9, + 0x78, 0xfc, 0x43, 0x86, 0xba, 0x9f, 0xe3, 0x97, 0x56, 0x74, 0x3f, 0x41, 0xcf, 0x3b, 0xba, 0x1f, + 0xa5, 0xcf, 0x1c, 0xbf, 0x1f, 0xef, 0xa5, 0x45, 0xe5, 0xda, 0xe2, 0xab, 0x46, 0xd3, 0x43, 0xb7, + 0x63, 0x9a, 0xe4, 0x6a, 0x3b, 0x58, 0x5f, 0x4d, 0x66, 0x10, 0x48, 0x77, 0x18, 0xd2, 0x4d, 0x7c, + 0x43, 0x45, 0x6a, 0xfa, 0x7c, 0x8f, 0xb5, 0x47, 0x1b, 0x1d, 0x98, 0x66, 0xbd, 0x34, 0x74, 0x2a, + 0x1f, 0xf4, 0x98, 0x4e, 0x63, 0xc2, 0x0d, 0x08, 0x75, 0xe1, 0xf0, 0x12, 0x43, 0x5b, 0xc0, 0x65, + 0x1f, 0x8d, 0xb5, 0xd3, 0x1e, 0x6b, 0x8f, 0xd6, 0xb4, 0xb7, 0xb5, 0x8d, 0x7f, 0x66, 0x60, 0x9a, + 0x35, 0x5d, 0xd0, 0x00, 0x20, 0xe8, 0x4e, 0x45, 0xf7, 0x39, 0xd6, 0xef, 0x8a, 0xee, 0x73, 0xbc, + 0xb1, 0x85, 0x6f, 0x33, 0xe4, 0x25, 0xbc, 0xe8, 0x23, 0xb3, 0xcf, 0x9f, 0xb5, 0x36, 0xe5, 0xa2, + 0x66, 0x7d, 0x01, 0x45, 0xa5, 0xcb, 0x84, 0xe2, 0x24, 0x86, 0xda, 0x54, 0xd1, 0x6b, 0x12, 0xd3, + 0xa2, 0xc2, 0x77, 0x19, 0xe8, 0x2d, 0x5c, 0x55, 0x8d, 0xcb, 0x71, 0x1d, 0xc6, 0x49, 0x81, 0x7f, + 0xa2, 0x41, 0x39, 0xdc, 0x69, 0x42, 0x77, 0x63, 0x44, 0x47, 0x1b, 0x56, 0xfa, 0xbd, 0xc9, 0x4c, + 0x89, 0x2a, 0x70, 0xfc, 0x73, 0x42, 0x06, 0x26, 0xe5, 0x94, 0xb6, 0xff, 0x77, 0x16, 0xf2, 0xdb, + 0xfc, 0x07, 0x12, 0xc8, 0x83, 0x82, 0xdf, 0xef, 0x41, 0x2b, 0x71, 0xbd, 0x80, 0x20, 0x51, 0xd6, + 0x6f, 0x27, 0xce, 0x0b, 0x15, 0x1e, 0x30, 0x15, 0x56, 0xf1, 0x4d, 0x5f, 0x05, 0xf1, 0x43, 0x8c, + 0x1a, 0x2f, 0x79, 0x6b, 0x66, 0xab, 0x45, 0x0d, 0xf1, 0x63, 0x0d, 0x4a, 0x6a, 0x1b, 0x07, 0xdd, + 0x89, 0xed, 0x42, 0xa8, 0x9d, 0x20, 0x1d, 0x4f, 0x62, 0x11, 0xf8, 0xaf, 0x33, 0xfc, 0xbb, 0x78, + 0x25, 0x09, 0xdf, 0x61, 0xfc, 0x61, 0x15, 0x78, 0xe3, 0x26, 0x5e, 0x85, 0x50, 0x5f, 0x28, 0x5e, + 0x85, 0x70, 0xdf, 0xe7, 0x72, 0x15, 0x86, 0x8c, 0x9f, 0xaa, 0xf0, 0x12, 0x20, 0xe8, 0xeb, 0xa0, + 0x58, 0xe3, 0x2a, 0xa5, 0x43, 0xf4, 0xe6, 0x8f, 0xb7, 0x84, 0xf0, 0x43, 0x86, 0x7d, 0x07, 0x2f, + 0x27, 0x61, 0xf7, 0xba, 0x2e, 0xf5, 0x80, 0x8d, 0xdf, 0xe5, 0xa0, 0xf8, 0xa1, 0xd9, 0xb5, 0x3c, + 0x62, 0x99, 0x56, 0x93, 0xa0, 0x36, 0x4c, 0xb3, 0x77, 0x43, 0xd4, 0xdd, 0xd5, 0x66, 0x4b, 0xd4, + 0xdd, 0x43, 0x9d, 0x08, 0x7c, 0x9f, 0x41, 0xdf, 0xc6, 0xba, 0x0f, 0xdd, 0x0f, 0xe4, 0xd7, 0x58, + 0x17, 0x81, 0x6e, 0xf9, 0x1c, 0x66, 0x78, 0xd7, 0x00, 0x45, 0xa4, 0x85, 0xba, 0x0b, 0xfa, 0x72, + 0xfc, 0x64, 0xe2, 0x2d, 0x53, 0xb1, 0x5c, 0xc6, 0x4c, 0xc1, 0x7e, 0x00, 0x10, 0xb4, 0xa9, 0xa2, + 0xf6, 0x1d, 0xeb, 0x6a, 0xe9, 0xab, 0xc9, 0x0c, 0x02, 0xf8, 0x11, 0x03, 0xbe, 0x87, 0x6f, 0xc7, + 0x02, 0xb7, 0xfc, 0x05, 0x14, 0xbc, 0x09, 0xb9, 0x1d, 0xd3, 0xed, 0xa0, 0x48, 0xe8, 0x57, 0x3e, + 0x97, 0xe9, 0x7a, 0xdc, 0x94, 0x80, 0xba, 0xc7, 0xa0, 0x56, 0xf0, 0x52, 0x2c, 0x54, 0xc7, 0x74, + 0x69, 0x24, 0x45, 0x43, 0x98, 0x95, 0x9f, 0xc0, 0xd0, 0xad, 0x88, 0xcd, 0xc2, 0x9f, 0xcb, 0xf4, + 0x95, 0xa4, 0x69, 0x01, 0xb8, 0xc6, 0x00, 0x31, 0xbe, 0x15, 0x6f, 0x54, 0xc1, 0xfe, 0x58, 0x7b, + 0xf4, 0xb6, 0xb6, 0xf1, 0xb3, 0x0a, 0xe4, 0x68, 0x96, 0x42, 0x63, 0x77, 0x50, 0xdc, 0x45, 0x2d, + 0x3c, 0xd6, 0x52, 0x89, 0x5a, 0x78, 0xbc, 0x2e, 0x8c, 0x89, 0xdd, 0xec, 0x67, 0x62, 0x84, 0x71, + 0xd1, 0x1d, 0x7b, 0x50, 0x54, 0x4a, 0x40, 0x14, 0x23, 0x31, 0xdc, 0xb0, 0x89, 0xc6, 0xee, 0x98, + 0xfa, 0x11, 0xaf, 0x32, 0x50, 0x1d, 0x5f, 0x0f, 0x83, 0xb6, 0x38, 0x1b, 0x45, 0xfd, 0x21, 0x94, + 0xd4, 0x5a, 0x11, 0xc5, 0x08, 0x8d, 0x74, 0x84, 0xa2, 0xb1, 0x22, 0xae, 0xd4, 0x8c, 0x71, 0x1a, + 0xff, 0x47, 0x71, 0x92, 0x97, 0xa2, 0x7f, 0x0a, 0x79, 0x51, 0x41, 0xc6, 0xed, 0x37, 0xdc, 0x43, + 0x8a, 0xdb, 0x6f, 0xa4, 0xfc, 0x8c, 0x49, 0x04, 0x18, 0x2c, 0xcd, 0x94, 0x65, 0x80, 0x16, 0x90, + 0x4f, 0x88, 0x97, 0x04, 0x19, 0x74, 0x45, 0x92, 0x20, 0x95, 0x2a, 0x65, 0x22, 0x64, 0x9b, 0x78, + 0xe2, 0x2e, 0xcb, 0x12, 0x00, 0x25, 0x48, 0x54, 0xa3, 0x21, 0x9e, 0xc4, 0x92, 0x98, 0xbb, 0x05, + 0xa8, 0x22, 0x14, 0xa2, 0x1f, 0x01, 0x04, 0xe5, 0x6e, 0xf4, 0x75, 0x1c, 0xdb, 0x33, 0x8b, 0xbe, + 0x8e, 0xe3, 0x2b, 0xe6, 0x18, 0x0f, 0x0e, 0xc0, 0x79, 0xfe, 0x48, 0xe1, 0x7f, 0xae, 0x01, 0x1a, + 0x2f, 0x8f, 0xd1, 0x1b, 0xf1, 0x10, 0xb1, 0xed, 0x38, 0xfd, 0xcd, 0xab, 0x31, 0x27, 0x46, 0xcf, + 0x40, 0xaf, 0x26, 0x5b, 0x32, 0x78, 0x41, 0x35, 0xfb, 0x42, 0x83, 0xb9, 0x50, 0x81, 0x8d, 0x1e, + 0x24, 0x9c, 0x73, 0xa4, 0xa5, 0xa7, 0x3f, 0xbc, 0x94, 0x2f, 0x31, 0x63, 0x51, 0x6e, 0x85, 0xcc, + 0xd6, 0x7e, 0xaa, 0x41, 0x39, 0x5c, 0x95, 0xa3, 0x04, 0x80, 0xb1, 0xbe, 0xa0, 0xbe, 0x76, 0x39, + 0xe3, 0x15, 0x4e, 0x2b, 0x48, 0xe0, 0x3e, 0x85, 0xbc, 0x28, 0xe6, 0xe3, 0xdc, 0x22, 0xdc, 0x56, + 0x8c, 0x73, 0x8b, 0x48, 0x27, 0x20, 0xc9, 0x2d, 0x68, 0x5d, 0xac, 0x78, 0xa2, 0x28, 0xf9, 0x93, + 0x20, 0x27, 0x7b, 0x62, 0xa4, 0x5f, 0x30, 0x11, 0x32, 0xf0, 0x44, 0x59, 0xf0, 0xa3, 0x04, 0x89, + 0x97, 0x78, 0x62, 0xb4, 0x5f, 0x90, 0xe4, 0x89, 0x0c, 0x55, 0xf1, 0xc4, 0xa0, 0x3e, 0x8f, 0xf3, + 0xc4, 0xb1, 0xa6, 0x69, 0x9c, 0x27, 0x8e, 0x97, 0xf8, 0x49, 0x67, 0xcb, 0xc0, 0x43, 0x9e, 0xb8, + 0x10, 0x53, 0xcf, 0xa3, 0x37, 0x13, 0x6c, 0x1a, 0xdb, 0x90, 0xd5, 0xdf, 0xba, 0x22, 0xf7, 0x64, + 0x0f, 0xe0, 0xa7, 0x21, 0x3d, 0xe0, 0xd7, 0x1a, 0x2c, 0xc6, 0x35, 0x04, 0x50, 0x02, 0x58, 0x42, + 0x37, 0x57, 0x5f, 0xbf, 0x2a, 0xfb, 0x15, 0xec, 0xe6, 0xfb, 0xc4, 0x56, 0xe5, 0xf7, 0xaf, 0x56, + 0xb4, 0xaf, 0x5e, 0xad, 0x68, 0x7f, 0x7e, 0xb5, 0xa2, 0xfd, 0xe2, 0x2f, 0x2b, 0x53, 0x67, 0x33, + 0xec, 0xb7, 0xda, 0xef, 0xfe, 0x27, 0x00, 0x00, 0xff, 0xff, 0x45, 0x26, 0x54, 0x69, 0x32, 0x2e, + 0x00, 0x00, +} 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 new file mode 100644 index 00000000000..a2efbcd982e --- /dev/null +++ b/vendor/github.com/coreos/etcd/etcdserver/etcdserverpb/rpc.pb.gw.go @@ -0,0 +1,1866 @@ +// Code generated by protoc-gen-grpc-gateway +// source: etcdserver/etcdserverpb/rpc.proto +// DO NOT EDIT! + +/* +Package etcdserverpb is a reverse proxy. + +It translates gRPC into RESTful JSON APIs. +*/ +package etcdserverpb + +import ( + "io" + "net/http" + + "github.com/golang/protobuf/proto" + "github.com/grpc-ecosystem/grpc-gateway/runtime" + "github.com/grpc-ecosystem/grpc-gateway/utilities" + "golang.org/x/net/context" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/grpclog" +) + +var _ codes.Code +var _ io.Reader +var _ = runtime.String +var _ = utilities.NewDoubleArray + +func request_KV_Range_0(ctx context.Context, marshaler runtime.Marshaler, client KVClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq RangeRequest + 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.Range(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func request_KV_Put_0(ctx context.Context, marshaler runtime.Marshaler, client KVClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq PutRequest + 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.Put(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func request_KV_DeleteRange_0(ctx context.Context, marshaler runtime.Marshaler, client KVClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq DeleteRangeRequest + 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.DeleteRange(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func request_KV_Txn_0(ctx context.Context, marshaler runtime.Marshaler, client KVClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq TxnRequest + 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.Txn(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func request_KV_Compact_0(ctx context.Context, marshaler runtime.Marshaler, client KVClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq CompactionRequest + 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.Compact(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func request_Watch_Watch_0(ctx context.Context, marshaler runtime.Marshaler, client WatchClient, req *http.Request, pathParams map[string]string) (Watch_WatchClient, runtime.ServerMetadata, error) { + var metadata runtime.ServerMetadata + stream, err := client.Watch(ctx) + if err != nil { + grpclog.Printf("Failed to start streaming: %v", err) + return nil, metadata, err + } + dec := marshaler.NewDecoder(req.Body) + handleSend := func() error { + var protoReq WatchRequest + err = dec.Decode(&protoReq) + if err == io.EOF { + return err + } + if err != nil { + grpclog.Printf("Failed to decode request: %v", err) + return err + } + if err = stream.Send(&protoReq); err != nil { + grpclog.Printf("Failed to send request: %v", err) + return err + } + return nil + } + if err := handleSend(); err != nil { + if cerr := stream.CloseSend(); cerr != nil { + grpclog.Printf("Failed to terminate client stream: %v", cerr) + } + if err == io.EOF { + return stream, metadata, nil + } + return nil, metadata, err + } + go func() { + for { + if err := handleSend(); err != nil { + break + } + } + if err := stream.CloseSend(); err != nil { + grpclog.Printf("Failed to terminate client stream: %v", err) + } + }() + header, err := stream.Header() + if err != nil { + grpclog.Printf("Failed to get header from client: %v", err) + return nil, metadata, err + } + metadata.HeaderMD = header + return stream, metadata, nil +} + +func request_Lease_LeaseGrant_0(ctx context.Context, marshaler runtime.Marshaler, client LeaseClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq LeaseGrantRequest + 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.LeaseGrant(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func request_Lease_LeaseRevoke_0(ctx context.Context, marshaler runtime.Marshaler, client LeaseClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq LeaseRevokeRequest + 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.LeaseRevoke(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func request_Lease_LeaseKeepAlive_0(ctx context.Context, marshaler runtime.Marshaler, client LeaseClient, req *http.Request, pathParams map[string]string) (Lease_LeaseKeepAliveClient, runtime.ServerMetadata, error) { + var metadata runtime.ServerMetadata + stream, err := client.LeaseKeepAlive(ctx) + if err != nil { + grpclog.Printf("Failed to start streaming: %v", err) + return nil, metadata, err + } + dec := marshaler.NewDecoder(req.Body) + handleSend := func() error { + var protoReq LeaseKeepAliveRequest + err = dec.Decode(&protoReq) + if err == io.EOF { + return err + } + if err != nil { + grpclog.Printf("Failed to decode request: %v", err) + return err + } + if err = stream.Send(&protoReq); err != nil { + grpclog.Printf("Failed to send request: %v", err) + return err + } + return nil + } + if err := handleSend(); err != nil { + if cerr := stream.CloseSend(); cerr != nil { + grpclog.Printf("Failed to terminate client stream: %v", cerr) + } + if err == io.EOF { + return stream, metadata, nil + } + return nil, metadata, err + } + go func() { + for { + if err := handleSend(); err != nil { + break + } + } + if err := stream.CloseSend(); err != nil { + grpclog.Printf("Failed to terminate client stream: %v", err) + } + }() + header, err := stream.Header() + if err != nil { + grpclog.Printf("Failed to get header from client: %v", err) + return nil, metadata, err + } + metadata.HeaderMD = header + return stream, metadata, nil +} + +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 + + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { + return nil, metadata, grpc.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.MemberAdd(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func request_Cluster_MemberRemove_0(ctx context.Context, marshaler runtime.Marshaler, client ClusterClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq MemberRemoveRequest + 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.MemberRemove(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func request_Cluster_MemberUpdate_0(ctx context.Context, marshaler runtime.Marshaler, client ClusterClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq MemberUpdateRequest + 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.MemberUpdate(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func request_Cluster_MemberList_0(ctx context.Context, marshaler runtime.Marshaler, client ClusterClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq MemberListRequest + 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.MemberList(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func request_Maintenance_Alarm_0(ctx context.Context, marshaler runtime.Marshaler, client MaintenanceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq AlarmRequest + 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.Alarm(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func request_Maintenance_Status_0(ctx context.Context, marshaler runtime.Marshaler, client MaintenanceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq StatusRequest + 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.Status(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func request_Maintenance_Defragment_0(ctx context.Context, marshaler runtime.Marshaler, client MaintenanceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq DefragmentRequest + 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.Defragment(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func request_Maintenance_Hash_0(ctx context.Context, marshaler runtime.Marshaler, client MaintenanceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq HashRequest + 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.Hash(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func request_Maintenance_Snapshot_0(ctx context.Context, marshaler runtime.Marshaler, client MaintenanceClient, req *http.Request, pathParams map[string]string) (Maintenance_SnapshotClient, runtime.ServerMetadata, error) { + var protoReq SnapshotRequest + var metadata runtime.ServerMetadata + + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { + return nil, metadata, grpc.Errorf(codes.InvalidArgument, "%v", err) + } + + stream, err := client.Snapshot(ctx, &protoReq) + if err != nil { + return nil, metadata, err + } + header, err := stream.Header() + if err != nil { + return nil, metadata, err + } + metadata.HeaderMD = header + return stream, metadata, nil + +} + +func request_Auth_AuthEnable_0(ctx context.Context, marshaler runtime.Marshaler, client AuthClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq AuthEnableRequest + 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.AuthEnable(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func request_Auth_AuthDisable_0(ctx context.Context, marshaler runtime.Marshaler, client AuthClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq AuthDisableRequest + 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.AuthDisable(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func request_Auth_Authenticate_0(ctx context.Context, marshaler runtime.Marshaler, client AuthClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq AuthenticateRequest + 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.Authenticate(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func request_Auth_UserAdd_0(ctx context.Context, marshaler runtime.Marshaler, client AuthClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq AuthUserAddRequest + 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.UserAdd(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func request_Auth_UserGet_0(ctx context.Context, marshaler runtime.Marshaler, client AuthClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq AuthUserGetRequest + 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.UserGet(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func request_Auth_UserList_0(ctx context.Context, marshaler runtime.Marshaler, client AuthClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq AuthUserListRequest + 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.UserList(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func request_Auth_UserDelete_0(ctx context.Context, marshaler runtime.Marshaler, client AuthClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq AuthUserDeleteRequest + 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.UserDelete(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func request_Auth_UserChangePassword_0(ctx context.Context, marshaler runtime.Marshaler, client AuthClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq AuthUserChangePasswordRequest + 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.UserChangePassword(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func request_Auth_UserGrantRole_0(ctx context.Context, marshaler runtime.Marshaler, client AuthClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq AuthUserGrantRoleRequest + 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.UserGrantRole(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func request_Auth_UserRevokeRole_0(ctx context.Context, marshaler runtime.Marshaler, client AuthClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq AuthUserRevokeRoleRequest + 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.UserRevokeRole(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func request_Auth_RoleAdd_0(ctx context.Context, marshaler runtime.Marshaler, client AuthClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq AuthRoleAddRequest + 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.RoleAdd(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func request_Auth_RoleGet_0(ctx context.Context, marshaler runtime.Marshaler, client AuthClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq AuthRoleGetRequest + 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.RoleGet(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func request_Auth_RoleList_0(ctx context.Context, marshaler runtime.Marshaler, client AuthClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq AuthRoleListRequest + 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.RoleList(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func request_Auth_RoleDelete_0(ctx context.Context, marshaler runtime.Marshaler, client AuthClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq AuthRoleDeleteRequest + 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.RoleDelete(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func request_Auth_RoleGrantPermission_0(ctx context.Context, marshaler runtime.Marshaler, client AuthClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq AuthRoleGrantPermissionRequest + 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.RoleGrantPermission(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func request_Auth_RoleRevokePermission_0(ctx context.Context, marshaler runtime.Marshaler, client AuthClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq AuthRoleRevokePermissionRequest + 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.RoleRevokePermission(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +// RegisterKVHandlerFromEndpoint is same as RegisterKVHandler but +// automatically dials to "endpoint" and closes the connection when "ctx" gets done. +func RegisterKVHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) { + conn, err := grpc.Dial(endpoint, opts...) + if err != nil { + return err + } + defer func() { + if err != nil { + if cerr := conn.Close(); cerr != nil { + grpclog.Printf("Failed to close conn to %s: %v", endpoint, cerr) + } + return + } + go func() { + <-ctx.Done() + if cerr := conn.Close(); cerr != nil { + grpclog.Printf("Failed to close conn to %s: %v", endpoint, cerr) + } + }() + }() + + return RegisterKVHandler(ctx, mux, conn) +} + +// RegisterKVHandler registers the http handlers for service KV to "mux". +// The handlers forward requests to the grpc endpoint over "conn". +func RegisterKVHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error { + client := NewKVClient(conn) + + mux.Handle("POST", pattern_KV_Range_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_KV_Range_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, outboundMarshaler, w, req, err) + return + } + + forward_KV_Range_0(ctx, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_KV_Put_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_KV_Put_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, outboundMarshaler, w, req, err) + return + } + + forward_KV_Put_0(ctx, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_KV_DeleteRange_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_KV_DeleteRange_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, outboundMarshaler, w, req, err) + return + } + + forward_KV_DeleteRange_0(ctx, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_KV_Txn_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_KV_Txn_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, outboundMarshaler, w, req, err) + return + } + + forward_KV_Txn_0(ctx, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_KV_Compact_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_KV_Compact_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, outboundMarshaler, w, req, err) + return + } + + forward_KV_Compact_0(ctx, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +var ( + pattern_KV_Range_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v3alpha", "kv", "range"}, "")) + + pattern_KV_Put_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v3alpha", "kv", "put"}, "")) + + pattern_KV_DeleteRange_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v3alpha", "kv", "deleterange"}, "")) + + pattern_KV_Txn_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v3alpha", "kv", "txn"}, "")) + + pattern_KV_Compact_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v3alpha", "kv", "compaction"}, "")) +) + +var ( + forward_KV_Range_0 = runtime.ForwardResponseMessage + + forward_KV_Put_0 = runtime.ForwardResponseMessage + + forward_KV_DeleteRange_0 = runtime.ForwardResponseMessage + + forward_KV_Txn_0 = runtime.ForwardResponseMessage + + forward_KV_Compact_0 = runtime.ForwardResponseMessage +) + +// RegisterWatchHandlerFromEndpoint is same as RegisterWatchHandler but +// automatically dials to "endpoint" and closes the connection when "ctx" gets done. +func RegisterWatchHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) { + conn, err := grpc.Dial(endpoint, opts...) + if err != nil { + return err + } + defer func() { + if err != nil { + if cerr := conn.Close(); cerr != nil { + grpclog.Printf("Failed to close conn to %s: %v", endpoint, cerr) + } + return + } + go func() { + <-ctx.Done() + if cerr := conn.Close(); cerr != nil { + grpclog.Printf("Failed to close conn to %s: %v", endpoint, cerr) + } + }() + }() + + return RegisterWatchHandler(ctx, mux, conn) +} + +// RegisterWatchHandler registers the http handlers for service Watch to "mux". +// The handlers forward requests to the grpc endpoint over "conn". +func RegisterWatchHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error { + client := NewWatchClient(conn) + + mux.Handle("POST", pattern_Watch_Watch_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_Watch_Watch_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, outboundMarshaler, w, req, err) + return + } + + forward_Watch_Watch_0(ctx, outboundMarshaler, w, req, func() (proto.Message, error) { return resp.Recv() }, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +var ( + pattern_Watch_Watch_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v3alpha", "watch"}, "")) +) + +var ( + forward_Watch_Watch_0 = runtime.ForwardResponseStream +) + +// RegisterLeaseHandlerFromEndpoint is same as RegisterLeaseHandler but +// automatically dials to "endpoint" and closes the connection when "ctx" gets done. +func RegisterLeaseHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) { + conn, err := grpc.Dial(endpoint, opts...) + if err != nil { + return err + } + defer func() { + if err != nil { + if cerr := conn.Close(); cerr != nil { + grpclog.Printf("Failed to close conn to %s: %v", endpoint, cerr) + } + return + } + go func() { + <-ctx.Done() + if cerr := conn.Close(); cerr != nil { + grpclog.Printf("Failed to close conn to %s: %v", endpoint, cerr) + } + }() + }() + + return RegisterLeaseHandler(ctx, mux, conn) +} + +// RegisterLeaseHandler registers the http handlers for service Lease to "mux". +// The handlers forward requests to the grpc endpoint over "conn". +func RegisterLeaseHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error { + client := NewLeaseClient(conn) + + mux.Handle("POST", pattern_Lease_LeaseGrant_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_LeaseGrant_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, outboundMarshaler, w, req, err) + return + } + + forward_Lease_LeaseGrant_0(ctx, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_Lease_LeaseRevoke_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_LeaseRevoke_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, outboundMarshaler, w, req, err) + return + } + + forward_Lease_LeaseRevoke_0(ctx, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_Lease_LeaseKeepAlive_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_LeaseKeepAlive_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, outboundMarshaler, w, req, err) + return + } + + forward_Lease_LeaseKeepAlive_0(ctx, outboundMarshaler, w, req, func() (proto.Message, error) { return resp.Recv() }, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +var ( + pattern_Lease_LeaseGrant_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v3alpha", "lease", "grant"}, "")) + + 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"}, "")) +) + +var ( + forward_Lease_LeaseGrant_0 = runtime.ForwardResponseMessage + + forward_Lease_LeaseRevoke_0 = runtime.ForwardResponseMessage + + forward_Lease_LeaseKeepAlive_0 = runtime.ForwardResponseStream +) + +// RegisterClusterHandlerFromEndpoint is same as RegisterClusterHandler but +// automatically dials to "endpoint" and closes the connection when "ctx" gets done. +func RegisterClusterHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) { + conn, err := grpc.Dial(endpoint, opts...) + if err != nil { + return err + } + defer func() { + if err != nil { + if cerr := conn.Close(); cerr != nil { + grpclog.Printf("Failed to close conn to %s: %v", endpoint, cerr) + } + return + } + go func() { + <-ctx.Done() + if cerr := conn.Close(); cerr != nil { + grpclog.Printf("Failed to close conn to %s: %v", endpoint, cerr) + } + }() + }() + + return RegisterClusterHandler(ctx, mux, conn) +} + +// RegisterClusterHandler registers the http handlers for service Cluster to "mux". +// The handlers forward requests to the grpc endpoint over "conn". +func RegisterClusterHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error { + client := NewClusterClient(conn) + + mux.Handle("POST", pattern_Cluster_MemberAdd_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_Cluster_MemberAdd_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, outboundMarshaler, w, req, err) + return + } + + forward_Cluster_MemberAdd_0(ctx, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_Cluster_MemberRemove_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_Cluster_MemberRemove_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, outboundMarshaler, w, req, err) + return + } + + forward_Cluster_MemberRemove_0(ctx, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_Cluster_MemberUpdate_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_Cluster_MemberUpdate_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, outboundMarshaler, w, req, err) + return + } + + forward_Cluster_MemberUpdate_0(ctx, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_Cluster_MemberList_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_Cluster_MemberList_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, outboundMarshaler, w, req, err) + return + } + + forward_Cluster_MemberList_0(ctx, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +var ( + pattern_Cluster_MemberAdd_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"v3alpha", "cluster", "member", "add"}, "")) + + pattern_Cluster_MemberRemove_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"v3alpha", "cluster", "member", "remove"}, "")) + + pattern_Cluster_MemberUpdate_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"v3alpha", "cluster", "member", "update"}, "")) + + pattern_Cluster_MemberList_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"v3alpha", "cluster", "member", "list"}, "")) +) + +var ( + forward_Cluster_MemberAdd_0 = runtime.ForwardResponseMessage + + forward_Cluster_MemberRemove_0 = runtime.ForwardResponseMessage + + forward_Cluster_MemberUpdate_0 = runtime.ForwardResponseMessage + + forward_Cluster_MemberList_0 = runtime.ForwardResponseMessage +) + +// RegisterMaintenanceHandlerFromEndpoint is same as RegisterMaintenanceHandler but +// automatically dials to "endpoint" and closes the connection when "ctx" gets done. +func RegisterMaintenanceHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) { + conn, err := grpc.Dial(endpoint, opts...) + if err != nil { + return err + } + defer func() { + if err != nil { + if cerr := conn.Close(); cerr != nil { + grpclog.Printf("Failed to close conn to %s: %v", endpoint, cerr) + } + return + } + go func() { + <-ctx.Done() + if cerr := conn.Close(); cerr != nil { + grpclog.Printf("Failed to close conn to %s: %v", endpoint, cerr) + } + }() + }() + + return RegisterMaintenanceHandler(ctx, mux, conn) +} + +// RegisterMaintenanceHandler registers the http handlers for service Maintenance to "mux". +// The handlers forward requests to the grpc endpoint over "conn". +func RegisterMaintenanceHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error { + client := NewMaintenanceClient(conn) + + mux.Handle("POST", pattern_Maintenance_Alarm_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_Maintenance_Alarm_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, outboundMarshaler, w, req, err) + return + } + + forward_Maintenance_Alarm_0(ctx, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_Maintenance_Status_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_Maintenance_Status_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, outboundMarshaler, w, req, err) + return + } + + forward_Maintenance_Status_0(ctx, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_Maintenance_Defragment_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_Maintenance_Defragment_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, outboundMarshaler, w, req, err) + return + } + + forward_Maintenance_Defragment_0(ctx, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_Maintenance_Hash_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_Maintenance_Hash_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, outboundMarshaler, w, req, err) + return + } + + forward_Maintenance_Hash_0(ctx, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_Maintenance_Snapshot_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_Maintenance_Snapshot_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, outboundMarshaler, w, req, err) + return + } + + forward_Maintenance_Snapshot_0(ctx, outboundMarshaler, w, req, func() (proto.Message, error) { return resp.Recv() }, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +var ( + pattern_Maintenance_Alarm_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v3alpha", "maintenance", "alarm"}, "")) + + pattern_Maintenance_Status_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v3alpha", "maintenance", "status"}, "")) + + pattern_Maintenance_Defragment_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v3alpha", "maintenance", "defragment"}, "")) + + pattern_Maintenance_Hash_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v3alpha", "maintenance", "hash"}, "")) + + pattern_Maintenance_Snapshot_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v3alpha", "maintenance", "snapshot"}, "")) +) + +var ( + forward_Maintenance_Alarm_0 = runtime.ForwardResponseMessage + + forward_Maintenance_Status_0 = runtime.ForwardResponseMessage + + forward_Maintenance_Defragment_0 = runtime.ForwardResponseMessage + + forward_Maintenance_Hash_0 = runtime.ForwardResponseMessage + + forward_Maintenance_Snapshot_0 = runtime.ForwardResponseStream +) + +// RegisterAuthHandlerFromEndpoint is same as RegisterAuthHandler but +// automatically dials to "endpoint" and closes the connection when "ctx" gets done. +func RegisterAuthHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) { + conn, err := grpc.Dial(endpoint, opts...) + if err != nil { + return err + } + defer func() { + if err != nil { + if cerr := conn.Close(); cerr != nil { + grpclog.Printf("Failed to close conn to %s: %v", endpoint, cerr) + } + return + } + go func() { + <-ctx.Done() + if cerr := conn.Close(); cerr != nil { + grpclog.Printf("Failed to close conn to %s: %v", endpoint, cerr) + } + }() + }() + + return RegisterAuthHandler(ctx, mux, conn) +} + +// RegisterAuthHandler registers the http handlers for service Auth to "mux". +// The handlers forward requests to the grpc endpoint over "conn". +func RegisterAuthHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error { + client := NewAuthClient(conn) + + mux.Handle("POST", pattern_Auth_AuthEnable_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_Auth_AuthEnable_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, outboundMarshaler, w, req, err) + return + } + + forward_Auth_AuthEnable_0(ctx, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_Auth_AuthDisable_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_Auth_AuthDisable_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, outboundMarshaler, w, req, err) + return + } + + forward_Auth_AuthDisable_0(ctx, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_Auth_Authenticate_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_Auth_Authenticate_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, outboundMarshaler, w, req, err) + return + } + + forward_Auth_Authenticate_0(ctx, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_Auth_UserAdd_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_Auth_UserAdd_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, outboundMarshaler, w, req, err) + return + } + + forward_Auth_UserAdd_0(ctx, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_Auth_UserGet_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_Auth_UserGet_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, outboundMarshaler, w, req, err) + return + } + + forward_Auth_UserGet_0(ctx, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_Auth_UserList_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_Auth_UserList_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, outboundMarshaler, w, req, err) + return + } + + forward_Auth_UserList_0(ctx, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_Auth_UserDelete_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_Auth_UserDelete_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, outboundMarshaler, w, req, err) + return + } + + forward_Auth_UserDelete_0(ctx, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_Auth_UserChangePassword_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_Auth_UserChangePassword_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, outboundMarshaler, w, req, err) + return + } + + forward_Auth_UserChangePassword_0(ctx, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_Auth_UserGrantRole_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_Auth_UserGrantRole_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, outboundMarshaler, w, req, err) + return + } + + forward_Auth_UserGrantRole_0(ctx, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_Auth_UserRevokeRole_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_Auth_UserRevokeRole_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, outboundMarshaler, w, req, err) + return + } + + forward_Auth_UserRevokeRole_0(ctx, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_Auth_RoleAdd_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_Auth_RoleAdd_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, outboundMarshaler, w, req, err) + return + } + + forward_Auth_RoleAdd_0(ctx, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_Auth_RoleGet_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_Auth_RoleGet_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, outboundMarshaler, w, req, err) + return + } + + forward_Auth_RoleGet_0(ctx, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_Auth_RoleList_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_Auth_RoleList_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, outboundMarshaler, w, req, err) + return + } + + forward_Auth_RoleList_0(ctx, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_Auth_RoleDelete_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_Auth_RoleDelete_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, outboundMarshaler, w, req, err) + return + } + + forward_Auth_RoleDelete_0(ctx, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_Auth_RoleGrantPermission_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_Auth_RoleGrantPermission_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, outboundMarshaler, w, req, err) + return + } + + forward_Auth_RoleGrantPermission_0(ctx, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_Auth_RoleRevokePermission_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_Auth_RoleRevokePermission_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, outboundMarshaler, w, req, err) + return + } + + forward_Auth_RoleRevokePermission_0(ctx, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +var ( + pattern_Auth_AuthEnable_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v3alpha", "auth", "enable"}, "")) + + pattern_Auth_AuthDisable_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v3alpha", "auth", "disable"}, "")) + + pattern_Auth_Authenticate_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v3alpha", "auth", "authenticate"}, "")) + + pattern_Auth_UserAdd_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"v3alpha", "auth", "user", "add"}, "")) + + pattern_Auth_UserGet_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"v3alpha", "auth", "user", "get"}, "")) + + pattern_Auth_UserList_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"v3alpha", "auth", "user", "list"}, "")) + + pattern_Auth_UserDelete_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"v3alpha", "auth", "user", "delete"}, "")) + + pattern_Auth_UserChangePassword_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"v3alpha", "auth", "user", "changepw"}, "")) + + pattern_Auth_UserGrantRole_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"v3alpha", "auth", "user", "grant"}, "")) + + pattern_Auth_UserRevokeRole_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"v3alpha", "auth", "user", "revoke"}, "")) + + pattern_Auth_RoleAdd_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"v3alpha", "auth", "role", "add"}, "")) + + pattern_Auth_RoleGet_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"v3alpha", "auth", "role", "get"}, "")) + + pattern_Auth_RoleList_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"v3alpha", "auth", "role", "list"}, "")) + + pattern_Auth_RoleDelete_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"v3alpha", "auth", "role", "delete"}, "")) + + pattern_Auth_RoleGrantPermission_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"v3alpha", "auth", "role", "grant"}, "")) + + pattern_Auth_RoleRevokePermission_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"v3alpha", "auth", "role", "revoke"}, "")) +) + +var ( + forward_Auth_AuthEnable_0 = runtime.ForwardResponseMessage + + forward_Auth_AuthDisable_0 = runtime.ForwardResponseMessage + + forward_Auth_Authenticate_0 = runtime.ForwardResponseMessage + + forward_Auth_UserAdd_0 = runtime.ForwardResponseMessage + + forward_Auth_UserGet_0 = runtime.ForwardResponseMessage + + forward_Auth_UserList_0 = runtime.ForwardResponseMessage + + forward_Auth_UserDelete_0 = runtime.ForwardResponseMessage + + forward_Auth_UserChangePassword_0 = runtime.ForwardResponseMessage + + forward_Auth_UserGrantRole_0 = runtime.ForwardResponseMessage + + forward_Auth_UserRevokeRole_0 = runtime.ForwardResponseMessage + + forward_Auth_RoleAdd_0 = runtime.ForwardResponseMessage + + forward_Auth_RoleGet_0 = runtime.ForwardResponseMessage + + forward_Auth_RoleList_0 = runtime.ForwardResponseMessage + + forward_Auth_RoleDelete_0 = runtime.ForwardResponseMessage + + forward_Auth_RoleGrantPermission_0 = runtime.ForwardResponseMessage + + forward_Auth_RoleRevokePermission_0 = runtime.ForwardResponseMessage +) diff --git a/vendor/github.com/coreos/etcd/etcdserver/etcdserverpb/rpc.proto b/vendor/github.com/coreos/etcd/etcdserver/etcdserverpb/rpc.proto index b1a501bf29e..04f08cb564f 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/etcdserverpb/rpc.proto +++ b/vendor/github.com/coreos/etcd/etcdserver/etcdserverpb/rpc.proto @@ -2,56 +2,107 @@ syntax = "proto3"; package etcdserverpb; import "gogoproto/gogo.proto"; -import "etcd/storage/storagepb/kv.proto"; +import "etcd/mvcc/mvccpb/kv.proto"; +import "etcd/auth/authpb/auth.proto"; + +// for grpc-gateway +import "google/api/annotations.proto"; option (gogoproto.marshaler_all) = true; option (gogoproto.unmarshaler_all) = true; service KV { - // Range gets the keys in the range from the store. - rpc Range(RangeRequest) returns (RangeResponse) {} + // Range gets the keys in the range from the key-value store. + rpc Range(RangeRequest) returns (RangeResponse) { + option (google.api.http) = { + post: "/v3alpha/kv/range" + body: "*" + }; + } - // Put puts the given key into the store. - // A put request increases the revision of the store, + // Put puts the given key into the key-value store. + // A put request increments the revision of the key-value store // and generates one event in the event history. - rpc Put(PutRequest) returns (PutResponse) {} + rpc Put(PutRequest) returns (PutResponse) { + option (google.api.http) = { + post: "/v3alpha/kv/put" + body: "*" + }; + } - // Delete deletes the given range from the store. - // A delete request increase the revision of the store, - // and generates one event in the event history. - rpc DeleteRange(DeleteRangeRequest) returns (DeleteRangeResponse) {} + // DeleteRange deletes the given range from the key-value store. + // A delete request increments the revision of the key-value store + // and generates a delete event in the event history for every deleted key. + rpc DeleteRange(DeleteRangeRequest) returns (DeleteRangeResponse) { + option (google.api.http) = { + post: "/v3alpha/kv/deleterange" + body: "*" + }; + } - // Txn processes all the requests in one transaction. - // A txn request increases the revision of the store, - // and generates events with the same revision in the event history. + // Txn processes multiple requests in a single transaction. + // A txn request increments the revision of the key-value store + // and generates events with the same revision for every completed request. // It is not allowed to modify the same key several times within one txn. - rpc Txn(TxnRequest) returns (TxnResponse) {} + rpc Txn(TxnRequest) returns (TxnResponse) { + option (google.api.http) = { + post: "/v3alpha/kv/txn" + body: "*" + }; + } - // Compact compacts the event history in etcd. User should compact the - // event history periodically, or it will grow infinitely. - rpc Compact(CompactionRequest) returns (CompactionResponse) {} + // Compact compacts the event history in the etcd key-value store. The key-value + // store should be periodically compacted or the event history will continue to grow + // indefinitely. + rpc Compact(CompactionRequest) returns (CompactionResponse) { + option (google.api.http) = { + post: "/v3alpha/kv/compaction" + body: "*" + }; + } } service Watch { - // Watch watches the events happening or happened. Both input and output - // are stream. One watch rpc can watch for multiple keys or prefixs and - // get a stream of events. The whole events history can be watched unless - // compacted. - rpc Watch(stream WatchRequest) returns (stream WatchResponse) {} + // Watch watches for events happening or that have happened. Both input and output + // are streams; the input stream is for creating and canceling watchers and the output + // stream sends events. One watch RPC can watch on multiple key ranges, streaming events + // for several watches at once. The entire event history can be watched starting from the + // last compaction revision. + rpc Watch(stream WatchRequest) returns (stream WatchResponse) { + option (google.api.http) = { + post: "/v3alpha/watch" + body: "*" + }; + } } service Lease { - // LeaseGrant creates a lease. A lease has a TTL. The lease will expire if the - // server does not receive a keepAlive within TTL from the lease holder. - // All keys attached to the lease will be expired and deleted if the lease expires. - // The key expiration generates an event in event history. - rpc LeaseGrant(LeaseGrantRequest) returns (LeaseGrantResponse) {} + // LeaseGrant creates a lease which expires if the server does not receive a keepAlive + // within a given time to live period. All keys attached to the lease will be expired and + // deleted if the lease expires. Each expired key generates a delete event in the event history. + rpc LeaseGrant(LeaseGrantRequest) returns (LeaseGrantResponse) { + option (google.api.http) = { + post: "/v3alpha/lease/grant" + body: "*" + }; + } - // LeaseRevoke revokes a lease. All the key attached to the lease will be expired and deleted. - rpc LeaseRevoke(LeaseRevokeRequest) returns (LeaseRevokeResponse) {} + // LeaseRevoke revokes a lease. All keys attached to the lease will expire and be deleted. + rpc LeaseRevoke(LeaseRevokeRequest) returns (LeaseRevokeResponse) { + option (google.api.http) = { + post: "/v3alpha/kv/lease/revoke" + body: "*" + }; + } - // KeepAlive keeps the lease alive. - rpc LeaseKeepAlive(stream LeaseKeepAliveRequest) returns (stream LeaseKeepAliveResponse) {} + // 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. + rpc LeaseKeepAlive(stream LeaseKeepAliveRequest) returns (stream LeaseKeepAliveResponse) { + option (google.api.http) = { + post: "/v3alpha/lease/keepalive" + body: "*" + }; + } // TODO(xiangli) List all existing Leases? // TODO(xiangli) Get details information (expirations, leased keys, etc.) of a lease? @@ -59,83 +110,220 @@ service Lease { service Cluster { // MemberAdd adds a member into the cluster. - rpc MemberAdd(MemberAddRequest) returns (MemberAddResponse) {} + rpc MemberAdd(MemberAddRequest) returns (MemberAddResponse) { + option (google.api.http) = { + post: "/v3alpha/cluster/member/add" + body: "*" + }; + } // MemberRemove removes an existing member from the cluster. - rpc MemberRemove(MemberRemoveRequest) returns (MemberRemoveResponse) {} + rpc MemberRemove(MemberRemoveRequest) returns (MemberRemoveResponse) { + option (google.api.http) = { + post: "/v3alpha/cluster/member/remove" + body: "*" + }; + } // MemberUpdate updates the member configuration. - rpc MemberUpdate(MemberUpdateRequest) returns (MemberUpdateResponse) {} + rpc MemberUpdate(MemberUpdateRequest) returns (MemberUpdateResponse) { + option (google.api.http) = { + post: "/v3alpha/cluster/member/update" + body: "*" + }; + } // MemberList lists all the members in the cluster. - rpc MemberList(MemberListRequest) returns (MemberListResponse) {} + rpc MemberList(MemberListRequest) returns (MemberListResponse) { + option (google.api.http) = { + post: "/v3alpha/cluster/member/list" + body: "*" + }; + } } service Maintenance { // Alarm activates, deactivates, and queries alarms regarding cluster health. - rpc Alarm(AlarmRequest) returns (AlarmResponse) {} + rpc Alarm(AlarmRequest) returns (AlarmResponse) { + option (google.api.http) = { + post: "/v3alpha/maintenance/alarm" + body: "*" + }; + } // Status gets the status of the member. - rpc Status(StatusRequest) returns (StatusResponse) {} + rpc Status(StatusRequest) returns (StatusResponse) { + option (google.api.http) = { + post: "/v3alpha/maintenance/status" + body: "*" + }; + } - rpc Defragment(DefragmentRequest) returns (DefragmentResponse) {} + // Defragment defragments a member's backend database to recover storage space. + rpc Defragment(DefragmentRequest) returns (DefragmentResponse) { + option (google.api.http) = { + post: "/v3alpha/maintenance/defragment" + body: "*" + }; + } // Hash returns the hash of the local KV state for consistency checking purpose. // This is designed for testing; do not use this in production when there // are ongoing transactions. - rpc Hash(HashRequest) returns (HashResponse) {} + rpc Hash(HashRequest) returns (HashResponse) { + option (google.api.http) = { + post: "/v3alpha/maintenance/hash" + body: "*" + }; + } + + // Snapshot sends a snapshot of the entire backend from a member over a stream to a client. + rpc Snapshot(SnapshotRequest) returns (stream SnapshotResponse) { + option (google.api.http) = { + post: "/v3alpha/maintenance/snapshot" + body: "*" + }; + } } service Auth { // AuthEnable enables authentication. - rpc AuthEnable(AuthEnableRequest) returns (AuthEnableResponse) {} + rpc AuthEnable(AuthEnableRequest) returns (AuthEnableResponse) { + option (google.api.http) = { + post: "/v3alpha/auth/enable" + body: "*" + }; + } // AuthDisable disables authentication. - rpc AuthDisable(AuthDisableRequest) returns (AuthDisableResponse) {} + rpc AuthDisable(AuthDisableRequest) returns (AuthDisableResponse) { + option (google.api.http) = { + post: "/v3alpha/auth/disable" + body: "*" + }; + } - // Authenticate processes authenticate request. - rpc Authenticate(AuthenticateRequest) returns (AuthenticateResponse) {} + // Authenticate processes an authenticate request. + rpc Authenticate(AuthenticateRequest) returns (AuthenticateResponse) { + option (google.api.http) = { + post: "/v3alpha/auth/authenticate" + body: "*" + }; + } // UserAdd adds a new user. - rpc UserAdd(AuthUserAddRequest) returns (AuthUserAddResponse) {} + rpc UserAdd(AuthUserAddRequest) returns (AuthUserAddResponse) { + option (google.api.http) = { + post: "/v3alpha/auth/user/add" + body: "*" + }; + } - // UserGet gets a detailed information of a user or lists entire users. - rpc UserGet(AuthUserGetRequest) returns (AuthUserGetResponse) {} + // UserGet gets detailed user information. + rpc UserGet(AuthUserGetRequest) returns (AuthUserGetResponse) { + option (google.api.http) = { + post: "/v3alpha/auth/user/get" + body: "*" + }; + } + + // UserList gets a list of all users. + rpc UserList(AuthUserListRequest) returns (AuthUserListResponse) { + option (google.api.http) = { + post: "/v3alpha/auth/user/list" + body: "*" + }; + } // UserDelete deletes a specified user. - rpc UserDelete(AuthUserDeleteRequest) returns (AuthUserDeleteResponse) {} + rpc UserDelete(AuthUserDeleteRequest) returns (AuthUserDeleteResponse) { + option (google.api.http) = { + post: "/v3alpha/auth/user/delete" + body: "*" + }; + } - // UserChangePassword changes password of a specified user. - rpc UserChangePassword(AuthUserChangePasswordRequest) returns (AuthUserChangePasswordResponse) {} + // UserChangePassword changes the password of a specified user. + rpc UserChangePassword(AuthUserChangePasswordRequest) returns (AuthUserChangePasswordResponse) { + option (google.api.http) = { + post: "/v3alpha/auth/user/changepw" + body: "*" + }; + } // UserGrant grants a role to a specified user. - rpc UserGrant(AuthUserGrantRequest) returns (AuthUserGrantResponse) {} + rpc UserGrantRole(AuthUserGrantRoleRequest) returns (AuthUserGrantRoleResponse) { + option (google.api.http) = { + post: "/v3alpha/auth/user/grant" + body: "*" + }; + } - // UserRevoke revokes a role of specified user. - rpc UserRevoke(AuthUserRevokeRequest) returns (AuthUserRevokeResponse) {} + // UserRevokeRole revokes a role of specified user. + rpc UserRevokeRole(AuthUserRevokeRoleRequest) returns (AuthUserRevokeRoleResponse) { + option (google.api.http) = { + post: "/v3alpha/auth/user/revoke" + body: "*" + }; + } // RoleAdd adds a new role. - rpc RoleAdd(AuthRoleAddRequest) returns (AuthRoleAddResponse) {} + rpc RoleAdd(AuthRoleAddRequest) returns (AuthRoleAddResponse) { + option (google.api.http) = { + post: "/v3alpha/auth/role/add" + body: "*" + }; + } - // RoleGet gets a detailed information of a role or lists entire roles. - rpc RoleGet(AuthRoleGetRequest) returns (AuthRoleGetResponse) {} + // RoleGet gets detailed role information. + rpc RoleGet(AuthRoleGetRequest) returns (AuthRoleGetResponse) { + option (google.api.http) = { + post: "/v3alpha/auth/role/get" + body: "*" + }; + } + + // RoleList gets lists of all roles. + rpc RoleList(AuthRoleListRequest) returns (AuthRoleListResponse) { + option (google.api.http) = { + post: "/v3alpha/auth/role/list" + body: "*" + }; + } // RoleDelete deletes a specified role. - rpc RoleDelete(AuthRoleDeleteRequest) returns (AuthRoleDeleteResponse) {} + rpc RoleDelete(AuthRoleDeleteRequest) returns (AuthRoleDeleteResponse) { + option (google.api.http) = { + post: "/v3alpha/auth/role/delete" + body: "*" + }; + } - // RoleGrant grants a permission of a specified key or range to a specified role. - rpc RoleGrant(AuthRoleGrantRequest) returns (AuthRoleGrantResponse) {} + // RoleGrantPermission grants a permission of a specified key or range to a specified role. + rpc RoleGrantPermission(AuthRoleGrantPermissionRequest) returns (AuthRoleGrantPermissionResponse) { + option (google.api.http) = { + post: "/v3alpha/auth/role/grant" + body: "*" + }; + } - // RoleRevoke revokes a key or range permission of a specified role. - rpc RoleRevoke(AuthRoleRevokeRequest) returns (AuthRoleRevokeResponse) {} + // RoleRevokePermission revokes a key or range permission of a specified role. + rpc RoleRevokePermission(AuthRoleRevokePermissionRequest) returns (AuthRoleRevokePermissionResponse) { + option (google.api.http) = { + post: "/v3alpha/auth/role/revoke" + body: "*" + }; + } } message ResponseHeader { + // cluster_id is the ID of the cluster which sent the response. uint64 cluster_id = 1; + // member_id is the ID of the member which sent the response. uint64 member_id = 2; - // revision of the store when the request was applied. + // revision is the key-value store revision when the request was applied. int64 revision = 3; - // term of raft when the request was applied. + // raft_term is the raft term when the request was applied. uint64 raft_term = 4; } @@ -153,43 +341,60 @@ message RangeRequest { VALUE = 4; } - // if the range_end is not given, the request returns the key. + // key is the first key for the range. If range_end is not given, the request only looks up key. bytes key = 1; - // if the range_end is given, it gets the keys in range [key, range_end) - // if range_end is nonempty, otherwise it returns all keys >= key. + // range_end is the upper bound on the requested range [key, range_end). + // If range_end is '\0', the range is all keys >= key. + // If the range_end is one bit larger than the given key, + // then the range requests get the all keys with the prefix (the given key). + // If both key and range_end are '\0', then range requests returns all keys. bytes range_end = 2; - // limit the number of keys returned. + // limit is a limit on the number of keys returned for the request. int64 limit = 3; - // range over the store at the given revision. - // if revision is less or equal to zero, range over the newest store. - // if the revision has been compacted, ErrCompaction will be returned in - // response. + // revision is the point-in-time of the key-value store to use for the range. + // If revision is less or equal to zero, the range is over the newest key-value store. + // If the revision has been compacted, ErrCompacted is returned as a response. int64 revision = 4; - // sort_order is the requested order for returned the results + // sort_order is the order for returned sorted results. SortOrder sort_order = 5; - // sort_target is the kv field to use for sorting + // sort_target is the key-value field to use for sorting. SortTarget sort_target = 6; - // range request is linearizable by default. Linearizable requests has a higher - // latency and lower throughput than serializable request. - // To reduce latency, serializable can be set. If serializable is set, range request - // will be serializable, but not linearizable with other requests. - // Serializable range can be served locally without waiting for other nodes in the cluster. + // serializable sets the range request to use serializable member-local reads. + // Range requests are linearizable by default; linearizable requests have higher + // latency and lower throughput than serializable requests but reflect the current + // consensus of the cluster. For better performance, in exchange for possible stale reads, + // a serializable range request is served locally without needing to reach consensus + // with other nodes in the cluster. bool serializable = 7; + + // keys_only when set returns only the keys and not the values. + bool keys_only = 8; + + // count_only when set returns only the count of the keys in the range. + bool count_only = 9; } message RangeResponse { ResponseHeader header = 1; - repeated storagepb.KeyValue kvs = 2; + // kvs is the list of key-value pairs matched by the range request. + // kvs is empty when count is requested. + repeated mvccpb.KeyValue kvs = 2; // more indicates if there are more keys to return in the requested range. bool more = 3; + // count is set to the number of keys within the range when requested. + int64 count = 4; } message PutRequest { + // key is the key, in bytes, to put into the key-value store. bytes key = 1; + // value is the value, in bytes, to associate with the key in the key-value store. bytes value = 2; + // lease is the lease ID to associate with the key in the key-value store. A lease + // value of 0 indicates no lease. int64 lease = 3; } @@ -198,19 +403,22 @@ message PutResponse { } message DeleteRangeRequest { - // if the range_end is not given, the request deletes the key. + // key is the first key to delete in the range. bytes key = 1; - // if the range_end is given, it deletes the keys in range [key, range_end). + // 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 '\0', the range is all keys greater than or equal to the key argument. bytes range_end = 2; } message DeleteRangeResponse { ResponseHeader header = 1; - // Deleted is the number of keys that got deleted. + // deleted is the number of keys deleted by the delete range request. int64 deleted = 2; } -message RequestUnion { +message RequestOp { + // request is a union of request types accepted by a transaction. oneof request { RangeRequest request_range = 1; PutRequest request_put = 2; @@ -218,7 +426,8 @@ message RequestUnion { } } -message ResponseUnion { +message ResponseOp { + // response is a union of response types returned by a transaction. oneof response { RangeResponse response_range = 1; PutResponse response_put = 2; @@ -238,27 +447,24 @@ message Compare { MOD = 2; VALUE= 3; } + // result is logical comparison operation for this comparison. CompareResult result = 1; + // target is the key-value field to inspect for the comparison. CompareTarget target = 2; - // key path + // key is the subject key for the comparison operation. bytes key = 3; oneof target_union { - // version of the given key + // version is the version of the given key int64 version = 4; - // create revision of the given key + // create_revision is the creation revision of the given key int64 create_revision = 5; - // last modified revision of the given key + // mod_revision is the last modified revision of the given key. int64 mod_revision = 6; - // value of the given key + // value is the value of the given key, in bytes. bytes value = 7; } } -// If the comparisons succeed, then the success requests will be processed in order, -// and the response will contain their respective responses in order. -// If the comparisons fail, then the failure requests will be processed in order, -// and the response will contain their respective responses in order. - // From google paxosdb paper: // Our implementation hinges around a powerful primitive which we call MultiOp. All other database // operations except for iteration are implemented as a single call to MultiOp. A MultiOp is applied atomically @@ -275,26 +481,35 @@ message Compare { // true. // 3. A list of database operations called f op. Like t op, but executed if guard evaluates to false. message TxnRequest { + // compare is a list of predicates representing a conjunction of terms. + // If the comparisons succeed, then the success requests will be processed in order, + // and the response will contain their respective responses in order. + // If the comparisons fail, then the failure requests will be processed in order, + // and the response will contain their respective responses in order. repeated Compare compare = 1; - repeated RequestUnion success = 2; - repeated RequestUnion failure = 3; + // success is a list of requests which will be applied when compare evaluates to true. + repeated RequestOp success = 2; + // failure is a list of requests which will be applied when compare evaluates to false. + repeated RequestOp failure = 3; } message TxnResponse { ResponseHeader header = 1; + // succeeded is set to true if the compare evaluated to true or false otherwise. bool succeeded = 2; - repeated ResponseUnion responses = 3; + // responses is a list of responses corresponding to the results from applying + // success if succeeded is true or failure if succeeded is false. + repeated ResponseOp responses = 3; } -// Compaction compacts the kv store upto the given revision (including). -// It removes the old versions of a key. It keeps the newest version of -// the key even if its latest modification revision is smaller than the given -// revision. +// CompactionRequest compacts the key-value store up to a given revision. All superseded keys +// with a revision less than the compaction revision will be removed. message CompactionRequest { + // revision is the key-value store revision for the compaction operation. int64 revision = 1; // physical is set so the RPC will wait until the compaction is physically // applied to the local database such that compacted entries are totally - // removed from the backing store. + // removed from the backend database. bool physical = 2; } @@ -307,10 +522,27 @@ message HashRequest { message HashResponse { ResponseHeader header = 1; + // hash is the hash value computed from the responding member's key-value store. uint32 hash = 2; } +message SnapshotRequest { +} + +message SnapshotResponse { + // header has the current key-value store information. The first header in the snapshot + // stream indicates the point in time of the snapshot. + ResponseHeader header = 1; + + // remaining_bytes is the number of blob bytes to be sent after this message + uint64 remaining_bytes = 2; + + // blob contains the next chunk of the snapshot in the snapshot stream. + bytes blob = 3; +} + message WatchRequest { + // request_union is a request to either create a new watcher or cancel an existing watcher. oneof request_union { WatchCreateRequest create_request = 1; WatchCancelRequest cancel_request = 2; @@ -318,65 +550,69 @@ message WatchRequest { } message WatchCreateRequest { - // the key to be watched + // key is the key to register for watching. bytes key = 1; - // if the range_end is given, keys in [key, range_end) are watched - // NOTE: only range_end == prefixEnd(key) is accepted now + // 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. bytes range_end = 2; - // start_revision is an optional revision (including) to watch from. No start_revision is "now". + // start_revision is an optional revision to watch from (inclusive). No start_revision is "now". int64 start_revision = 3; - // if progress_notify is set, etcd server sends WatchResponse with empty events to the - // created watcher when there are no recent events. It is useful when clients want always to be - // able to recover a disconnected watcher from a recent known revision. - // etcdsever can decide how long it should send a notification based on current load. + // progress_notify is set so that the etcd server will periodically send a WatchResponse with + // no events to the new watcher if there are no recent events. It is useful when clients + // 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; } message WatchCancelRequest { + // watch_id is the watcher id to cancel so that no more events are transmitted. int64 watch_id = 1; } message WatchResponse { ResponseHeader header = 1; - // watch_id is the ID of the watching the response sent to. + // watch_id is the ID of the watcher that corresponds to the response. int64 watch_id = 2; - // If the response is for a create watch request, created is set to true. - // Client should record the watch_id and prepare for receiving events for - // that watching from the same stream. - // All events sent to the created watching will attach with the same watch_id. + // created is set to true if the response is for a create watch request. + // The client should record the watch_id and expect to receive events for + // the created watcher from the same stream. + // All events sent to the created watcher will attach with the same watch_id. bool created = 3; - // If the response is for a cancel watch request, cancel is set to true. - // No further events will be sent to the canceled watching. + // canceled is set to true if the response is for a cancel watch request. + // No further events will be sent to the canceled watcher. bool canceled = 4; - // CompactRevision is set to the minimum index if a watching tries to watch + // compact_revision is set to the minimum index if a watcher tries to watch // at a compacted index. // - // This happens when creating a watching at a compacted revision or the watching cannot - // catch up with the progress of the KV. + // This happens when creating a watcher at a compacted revision or the watcher cannot + // catch up with the progress of the key-value store. // - // Client should treat the watching as canceled and should not try to create any - // watching with same start_revision again. + // The client should treat the watcher as canceled and should not try to create any + // watcher with the same start_revision again. int64 compact_revision = 5; - repeated storagepb.Event events = 11; + repeated mvccpb.Event events = 11; } message LeaseGrantRequest { - // advisory ttl in seconds + // TTL is the advisory time-to-live in seconds. int64 TTL = 1; - // requested ID to create; 0 lets lessor choose + // ID is the requested ID for the lease. If ID is set to 0, the lessor chooses an ID. int64 ID = 2; } message LeaseGrantResponse { ResponseHeader header = 1; + // ID is the lease ID for the granted lease. int64 ID = 2; - // server decided ttl in second + // TTL is the server chosen lease time-to-live in seconds. int64 TTL = 3; string error = 4; } message LeaseRevokeRequest { + // ID is the lease ID to revoke. When the ID is revoked, all associated keys will be deleted. int64 ID = 1; } @@ -385,36 +621,42 @@ message LeaseRevokeResponse { } message LeaseKeepAliveRequest { + // ID is the lease ID for the lease to keep alive. int64 ID = 1; } message LeaseKeepAliveResponse { ResponseHeader header = 1; + // ID is the lease ID from the keep alive request. int64 ID = 2; + // TTL is the new time-to-live for the lease. int64 TTL = 3; } message Member { + // ID is the member ID for this member. uint64 ID = 1; - // If the member is not started, name will be an empty string. + // name is the human-readable name of the member. If the member is not started, the name will be an empty string. string name = 2; - bool IsLeader = 3; - repeated string peerURLs = 4; - // If the member is not started, client_URLs will be an zero length - // string array. - repeated string clientURLs = 5; + // peerURLs is the list of URLs the member exposes to the cluster for communication. + repeated string peerURLs = 3; + // clientURLs is the list of URLs the member exposes to clients for communication. If the member is not started, clientURLs will be empty. + repeated string clientURLs = 4; } message MemberAddRequest { + // peerURLs is the list of URLs the added member will use to communicate with the cluster. repeated string peerURLs = 1; } message MemberAddResponse { ResponseHeader header = 1; + // member is the member information for the added member. Member member = 2; } message MemberRemoveRequest { + // ID is the member ID of the member to remove. uint64 ID = 1; } @@ -423,7 +665,9 @@ message MemberRemoveResponse { } message MemberUpdateRequest { + // ID is the member ID of the member to update. uint64 ID = 1; + // peerURLs is the new list of URLs the member will use to communicate with the cluster. repeated string peerURLs = 2; } @@ -436,11 +680,11 @@ message MemberListRequest { message MemberListResponse { ResponseHeader header = 1; + // members is a list of all members associated with the cluster. repeated Member members = 2; } message DefragmentRequest { - } message DefragmentResponse { @@ -449,7 +693,7 @@ message DefragmentResponse { enum AlarmType { NONE = 0; // default, used to query if any alarm is active - NOSPACE = 1; + NOSPACE = 1; // space quota is exhausted } message AlarmRequest { @@ -458,19 +702,27 @@ message AlarmRequest { ACTIVATE = 1; DEACTIVATE = 2; } + // action is the kind of alarm request to issue. The action + // may GET alarm statuses, ACTIVATE an alarm, or DEACTIVATE a + // raised alarm. AlarmAction action = 1; - // MemberID is the member raising the alarm request + // memberID is the ID of the member associated with the alarm. If memberID is 0, the + // alarm request covers all members. uint64 memberID = 2; + // alarm is the type of alarm to consider for this request. AlarmType alarm = 3; } message AlarmMember { - uint64 memberID = 1; - AlarmType alarm = 2; + // memberID is the ID of the member associated with the raised alarm. + uint64 memberID = 1; + // alarm is the type of alarm which has been raised. + AlarmType alarm = 2; } message AlarmResponse { ResponseHeader header = 1; + // alarms is a list of alarms associated with the alarm request. repeated AlarmMember alarms = 2; } @@ -479,7 +731,16 @@ message StatusRequest { message StatusResponse { ResponseHeader header = 1; + // version is the cluster protocol version used by the responding member. string version = 2; + // dbSize is the size of the backend database, in bytes, of the responding member. + int64 dbSize = 3; + // leader is the member ID which the responding member believes is the current leader. + uint64 leader = 4; + // raftIndex is the current raft index of the responding member. + uint64 raftIndex = 5; + // raftTerm is the current raft term of the responding member. + uint64 raftTerm = 6; } message AuthEnableRequest { @@ -489,6 +750,8 @@ message AuthDisableRequest { } message AuthenticateRequest { + string name = 1; + string password = 2; } message AuthUserAddRequest { @@ -497,37 +760,63 @@ message AuthUserAddRequest { } message AuthUserGetRequest { + string name = 1; } message AuthUserDeleteRequest { + // name is the name of the user to delete. string name = 1; } message AuthUserChangePasswordRequest { + // name is the name of the user whose password is being changed. string name = 1; + // password is the new password for the user. string password = 2; } -message AuthUserGrantRequest { +message AuthUserGrantRoleRequest { + // user is the name of the user which should be granted a given role. + string user = 1; + // role is the name of the role to grant to the user. + string role = 2; } -message AuthUserRevokeRequest { +message AuthUserRevokeRoleRequest { + string name = 1; + string role = 2; } message AuthRoleAddRequest { + // name is the name of the role to add to the authentication system. string name = 1; } message AuthRoleGetRequest { + string role = 1; +} + +message AuthUserListRequest { +} + +message AuthRoleListRequest { } message AuthRoleDeleteRequest { + string role = 1; } -message AuthRoleGrantRequest { +message AuthRoleGrantPermissionRequest { + // name is the name of the role which will be granted the permission. + string name = 1; + // perm is the permission to grant to the role. + authpb.Permission perm = 2; } -message AuthRoleRevokeRequest { +message AuthRoleRevokePermissionRequest { + string role = 1; + string key = 2; + string range_end = 3; } message AuthEnableResponse { @@ -540,6 +829,8 @@ message AuthDisableResponse { message AuthenticateResponse { ResponseHeader header = 1; + // token is an authorized token that can be used in succeeding RPCs + string token = 2; } message AuthUserAddResponse { @@ -548,6 +839,8 @@ message AuthUserAddResponse { message AuthUserGetResponse { ResponseHeader header = 1; + + repeated string roles = 2; } message AuthUserDeleteResponse { @@ -558,11 +851,11 @@ message AuthUserChangePasswordResponse { ResponseHeader header = 1; } -message AuthUserGrantResponse { +message AuthUserGrantRoleResponse { ResponseHeader header = 1; } -message AuthUserRevokeResponse { +message AuthUserRevokeRoleResponse { ResponseHeader header = 1; } @@ -572,16 +865,30 @@ message AuthRoleAddResponse { message AuthRoleGetResponse { ResponseHeader header = 1; + + repeated authpb.Permission perm = 2; +} + +message AuthRoleListResponse { + ResponseHeader header = 1; + + repeated string roles = 2; +} + +message AuthUserListResponse { + ResponseHeader header = 1; + + repeated string users = 2; } message AuthRoleDeleteResponse { ResponseHeader header = 1; } -message AuthRoleGrantResponse { +message AuthRoleGrantPermissionResponse { ResponseHeader header = 1; } -message AuthRoleRevokeResponse { +message AuthRoleRevokePermissionResponse { ResponseHeader header = 1; } diff --git a/vendor/github.com/coreos/etcd/etcdserver/membership/cluster.go b/vendor/github.com/coreos/etcd/etcdserver/membership/cluster.go index 0771e874f73..4e757725dc3 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/membership/cluster.go +++ b/vendor/github.com/coreos/etcd/etcdserver/membership/cluster.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. @@ -25,11 +25,11 @@ import ( "strings" "sync" + "github.com/coreos/etcd/mvcc/backend" "github.com/coreos/etcd/pkg/netutil" "github.com/coreos/etcd/pkg/types" "github.com/coreos/etcd/raft" "github.com/coreos/etcd/raft/raftpb" - "github.com/coreos/etcd/storage/backend" "github.com/coreos/etcd/store" "github.com/coreos/etcd/version" "github.com/coreos/go-semver/semver" @@ -144,9 +144,7 @@ func (c *RaftCluster) PeerURLs() []string { defer c.Unlock() urls := make([]string, 0) for _, p := range c.members { - for _, addr := range p.PeerURLs { - urls = append(urls, addr) - } + urls = append(urls, p.PeerURLs...) } sort.Strings(urls) return urls @@ -159,9 +157,7 @@ func (c *RaftCluster) ClientURLs() []string { defer c.Unlock() urls := make([]string, 0) for _, p := range c.members { - for _, url := range p.ClientURLs { - urls = append(urls, url) - } + urls = append(urls, p.ClientURLs...) } sort.Strings(urls) return urls @@ -199,13 +195,19 @@ func (c *RaftCluster) SetID(id types.ID) { c.id = id } func (c *RaftCluster) SetStore(st store.Store) { c.store = st } -func (c *RaftCluster) Recover() { +func (c *RaftCluster) SetBackend(be backend.Backend) { + c.be = be + mustCreateBackendBuckets(c.be) +} + +func (c *RaftCluster) Recover(onSet func(*semver.Version)) { c.Lock() defer c.Unlock() c.members, c.removed = membersFromStore(c.store) c.version = clusterVersionFromStore(c.store) mustDetectDowngrade(c.version) + onSet(c.version) for _, m := range c.members { plog.Infof("added member %s %v to cluster %s from store", m.ID, m.PeerURLs, c.id) @@ -289,6 +291,8 @@ func (c *RaftCluster) AddMember(m *Member) { } c.members[m.ID] = m + + plog.Infof("added member %s %v to cluster %s", m.ID, m.PeerURLs, c.id) } // RemoveMember removes a member from the store. @@ -305,23 +309,28 @@ func (c *RaftCluster) RemoveMember(id types.ID) { delete(c.members, id) c.removed[id] = true + + plog.Infof("removed member %s from cluster %s", id, c.id) } -func (c *RaftCluster) UpdateAttributes(id types.ID, attr Attributes) bool { +func (c *RaftCluster) UpdateAttributes(id types.ID, attr Attributes) { c.Lock() defer c.Unlock() if m, ok := c.members[id]; ok { m.Attributes = attr - return true + if c.store != nil { + mustUpdateMemberAttrInStore(c.store, m) + } + if c.be != nil { + mustSaveMemberToBackend(c.be, m) + } + return } _, ok := c.removed[id] - if ok { - plog.Warningf("skipped updating attributes of removed member %s", id) - } else { + if !ok { plog.Panicf("error updating attributes of unknown member %s", id) } - // TODO: update store in this function - return false + plog.Warningf("skipped updating attributes of removed member %s", id) } func (c *RaftCluster) UpdateRaftAttributes(id types.ID, raftAttr RaftAttributes) { @@ -335,6 +344,8 @@ func (c *RaftCluster) UpdateRaftAttributes(id types.ID, raftAttr RaftAttributes) if c.be != nil { mustSaveMemberToBackend(c.be, c.members[id]) } + + plog.Noticef("updated member %s %v in cluster %s", id, raftAttr.PeerURLs, c.id) } func (c *RaftCluster) Version() *semver.Version { @@ -346,7 +357,7 @@ func (c *RaftCluster) Version() *semver.Version { return semver.Must(semver.NewVersion(c.version.String())) } -func (c *RaftCluster) SetVersion(ver *semver.Version) { +func (c *RaftCluster) SetVersion(ver *semver.Version, onSet func(*semver.Version)) { c.Lock() defer c.Unlock() if c.version != nil { @@ -356,6 +367,13 @@ func (c *RaftCluster) SetVersion(ver *semver.Version) { } c.version = ver mustDetectDowngrade(c.version) + if c.store != nil { + mustSaveClusterVersionToStore(c.store, ver) + } + if c.be != nil { + mustSaveClusterVersionToBackend(c.be, ver) + } + onSet(ver) } func (c *RaftCluster) IsReadyToAddNewMember() bool { @@ -371,7 +389,7 @@ func (c *RaftCluster) IsReadyToAddNewMember() bool { if nstarted == 1 && nmembers == 2 { // a case of adding a new node to 1-member cluster for restoring cluster data - // https://github.com/coreos/etcd/blob/master/Documentation/admin_guide.md#restoring-the-cluster + // https://github.com/coreos/etcd/blob/master/Documentation/v2/admin_guide.md#restoring-the-cluster plog.Debugf("The number of started member is 1. This cluster can accept add member request.") return true diff --git a/vendor/github.com/coreos/etcd/etcdserver/membership/errors.go b/vendor/github.com/coreos/etcd/etcdserver/membership/errors.go index a8605e3ebf2..e4d36af2547 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/membership/errors.go +++ b/vendor/github.com/coreos/etcd/etcdserver/membership/errors.go @@ -1,4 +1,4 @@ -// Copyright 2016 CoreOS, Inc. +// 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. diff --git a/vendor/github.com/coreos/etcd/etcdserver/membership/member.go b/vendor/github.com/coreos/etcd/etcdserver/membership/member.go index fbf2c0702da..35ce3a973bb 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/membership/member.go +++ b/vendor/github.com/coreos/etcd/etcdserver/membership/member.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. diff --git a/vendor/github.com/coreos/etcd/etcdserver/membership/store.go b/vendor/github.com/coreos/etcd/etcdserver/membership/store.go index cdd16371fc6..f2ea0120d74 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/membership/store.go +++ b/vendor/github.com/coreos/etcd/etcdserver/membership/store.go @@ -1,4 +1,4 @@ -// Copyright 2016 CoreOS, Inc. +// 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. @@ -19,15 +19,15 @@ import ( "fmt" "path" + "github.com/coreos/etcd/mvcc/backend" "github.com/coreos/etcd/pkg/types" - "github.com/coreos/etcd/storage/backend" "github.com/coreos/etcd/store" + + "github.com/coreos/go-semver/semver" ) const ( - // TODO: make this private after moving all membership storage logic - // from etcdserver pkg - AttributesSuffix = "attributes" + attributesSuffix = "attributes" raftAttributesSuffix = "raftAttributes" // the prefix for stroing membership related information in store provided by store pkg. @@ -37,6 +37,7 @@ const ( var ( membersBucketName = []byte("members") membersRemovedBuckedName = []byte("members_removed") + clusterBucketName = []byte("cluster") StoreMembersPrefix = path.Join(storePrefix, "members") storeRemovedMembersPrefix = path.Join(storePrefix, "removed_members") @@ -44,7 +45,7 @@ var ( func mustSaveMemberToBackend(be backend.Backend, m *Member) { mkey := backendMemberKey(m.ID) - mvalue, err := json.Marshal(m.RaftAttributes) + mvalue, err := json.Marshal(m) if err != nil { plog.Panicf("marshal raftAttributes should never fail: %v", err) } @@ -65,6 +66,15 @@ func mustDeleteMemberFromBackend(be backend.Backend, id types.ID) { tx.Unlock() } +func mustSaveClusterVersionToBackend(be backend.Backend, ver *semver.Version) { + ckey := backendClusterVersionKey() + + tx := be.BatchTx() + tx.Lock() + defer tx.Unlock() + tx.UnsafePut(clusterBucketName, ckey, []byte(ver.String())) +} + func mustSaveMemberToStore(s store.Store, m *Member) { b, err := json.Marshal(m.RaftAttributes) if err != nil { @@ -96,13 +106,30 @@ func mustUpdateMemberInStore(s store.Store, m *Member) { } } +func mustUpdateMemberAttrInStore(s store.Store, m *Member) { + b, err := json.Marshal(m.Attributes) + if err != nil { + plog.Panicf("marshal raftAttributes should never fail: %v", err) + } + p := path.Join(MemberStoreKey(m.ID), attributesSuffix) + if _, err := s.Set(p, false, string(b), store.TTLOptionSet{ExpireTime: store.Permanent}); err != nil { + plog.Panicf("update raftAttributes should never fail: %v", err) + } +} + +func mustSaveClusterVersionToStore(s store.Store, ver *semver.Version) { + if _, err := s.Set(StoreClusterVersionKey(), false, ver.String(), store.TTLOptionSet{ExpireTime: store.Permanent}); err != nil { + plog.Panicf("save cluster version should never fail: %v", err) + } +} + // nodeToMember builds member from a key value node. // the child nodes of the given node MUST be sorted by key. func nodeToMember(n *store.NodeExtern) (*Member, error) { m := &Member{ID: MustParseMemberIDFromKey(n.Key)} attrs := make(map[string][]byte) raftAttrKey := path.Join(n.Key, raftAttributesSuffix) - attrKey := path.Join(n.Key, AttributesSuffix) + attrKey := path.Join(n.Key, attributesSuffix) for _, nn := range n.Nodes { if nn.Key != raftAttrKey && nn.Key != attrKey { return nil, fmt.Errorf("unknown key %q", nn.Key) @@ -125,15 +152,32 @@ func nodeToMember(n *store.NodeExtern) (*Member, error) { } func backendMemberKey(id types.ID) []byte { - return []byte(path.Join(id.String(), raftAttributesSuffix)) + return []byte(id.String()) +} + +func backendClusterVersionKey() []byte { + return []byte("clusterVersion") +} + +func mustCreateBackendBuckets(be backend.Backend) { + tx := be.BatchTx() + tx.Lock() + defer tx.Unlock() + tx.UnsafeCreateBucket(membersBucketName) + tx.UnsafeCreateBucket(membersRemovedBuckedName) + tx.UnsafeCreateBucket(clusterBucketName) } func MemberStoreKey(id types.ID) string { return path.Join(StoreMembersPrefix, id.String()) } +func StoreClusterVersionKey() string { + return path.Join(storePrefix, "version") +} + func MemberAttributesStorePath(id types.ID) string { - return path.Join(MemberStoreKey(id), AttributesSuffix) + return path.Join(MemberStoreKey(id), attributesSuffix) } func MustParseMemberIDFromKey(key string) types.ID { diff --git a/vendor/github.com/coreos/etcd/etcdserver/metrics.go b/vendor/github.com/coreos/etcd/etcdserver/metrics.go index 0eee58dcaa0..c701a917520 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/metrics.go +++ b/vendor/github.com/coreos/etcd/etcdserver/metrics.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. @@ -22,42 +22,51 @@ import ( ) var ( - // TODO: with label in v3? - proposeDurations = prometheus.NewHistogram(prometheus.HistogramOpts{ + hasLeader = prometheus.NewGauge(prometheus.GaugeOpts{ Namespace: "etcd", Subsystem: "server", - Name: "proposal_durations_seconds", - Help: "The latency distributions of committing proposal.", - Buckets: prometheus.ExponentialBuckets(0.001, 2, 14), + Name: "has_leader", + Help: "Whether or not a leader exists. 1 is existence, 0 is not.", }) - proposePending = prometheus.NewGauge(prometheus.GaugeOpts{ + leaderChanges = prometheus.NewCounter(prometheus.CounterOpts{ Namespace: "etcd", Subsystem: "server", - Name: "pending_proposal_total", - Help: "The total number of pending proposals.", + Name: "leader_changes_seen_total", + Help: "The number of leader changes seen.", }) - // This is number of proposal failed in client's view. - // The proposal might be later got committed in raft. - proposeFailed = prometheus.NewCounter(prometheus.CounterOpts{ + proposalsCommitted = prometheus.NewGauge(prometheus.GaugeOpts{ Namespace: "etcd", Subsystem: "server", - Name: "proposal_failed_total", - Help: "The total number of failed proposals.", + Name: "proposals_committed_total", + Help: "The total number of consensus proposals committed.", }) - - fileDescriptorUsed = prometheus.NewGauge(prometheus.GaugeOpts{ + proposalsApplied = prometheus.NewGauge(prometheus.GaugeOpts{ Namespace: "etcd", Subsystem: "server", - Name: "file_descriptors_used_total", - Help: "The total number of file descriptors used.", + Name: "proposals_applied_total", + Help: "The total number of consensus proposals applied.", + }) + proposalsPending = prometheus.NewGauge(prometheus.GaugeOpts{ + Namespace: "etcd", + Subsystem: "server", + Name: "proposals_pending", + Help: "The current number of pending proposals to commit.", + }) + proposalsFailed = prometheus.NewGauge(prometheus.GaugeOpts{ + Namespace: "etcd", + Subsystem: "server", + Name: "proposals_failed_total", + Help: "The total number of failed proposals seen.", }) ) func init() { - prometheus.MustRegister(proposeDurations) - prometheus.MustRegister(proposePending) - prometheus.MustRegister(proposeFailed) - prometheus.MustRegister(fileDescriptorUsed) + prometheus.MustRegister(hasLeader) + prometheus.MustRegister(leaderChanges) + prometheus.MustRegister(proposalsCommitted) + prometheus.MustRegister(proposalsApplied) + prometheus.MustRegister(proposalsPending) + prometheus.MustRegister(proposalsFailed) } func monitorFileDescriptor(done <-chan struct{}) { @@ -69,7 +78,6 @@ func monitorFileDescriptor(done <-chan struct{}) { plog.Errorf("cannot monitor file descriptor usage (%v)", err) return } - fileDescriptorUsed.Set(float64(used)) limit, err := runtime.FDLimit() if err != nil { plog.Errorf("cannot monitor file descriptor usage (%v)", err) diff --git a/vendor/github.com/coreos/etcd/etcdserver/quota.go b/vendor/github.com/coreos/etcd/etcdserver/quota.go index 87c97f4acfa..088a4696253 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/quota.go +++ b/vendor/github.com/coreos/etcd/etcdserver/quota.go @@ -1,4 +1,4 @@ -// Copyright 2016 CoreOS, Inc. +// 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. @@ -16,7 +16,7 @@ package etcdserver import ( pb "github.com/coreos/etcd/etcdserver/etcdserverpb" - "github.com/coreos/etcd/storage/backend" + "github.com/coreos/etcd/mvcc/backend" ) // Quota represents an arbitrary quota against arbitrary requests. Each request @@ -50,20 +50,20 @@ const ( ) func NewBackendQuota(s *EtcdServer) Quota { - if s.cfg.QuotaBackendBytes < 0 { + if s.Cfg.QuotaBackendBytes < 0 { // disable quotas if negative plog.Warningf("disabling backend quota") return &passthroughQuota{} } - if s.cfg.QuotaBackendBytes == 0 { + if s.Cfg.QuotaBackendBytes == 0 { // use default size if no quota size given return &backendQuota{s, backend.DefaultQuotaBytes} } - if s.cfg.QuotaBackendBytes > backend.MaxQuotaBytes { - plog.Warningf("backend quota %v exceeds maximum quota %v; using maximum", s.cfg.QuotaBackendBytes, backend.MaxQuotaBytes) + if s.Cfg.QuotaBackendBytes > backend.MaxQuotaBytes { + plog.Warningf("backend quota %v exceeds maximum quota %v; using maximum", s.Cfg.QuotaBackendBytes, backend.MaxQuotaBytes) return &backendQuota{s, backend.MaxQuotaBytes} } - return &backendQuota{s, s.cfg.QuotaBackendBytes} + return &backendQuota{s, s.Cfg.QuotaBackendBytes} } func (b *backendQuota) Available(v interface{}) bool { @@ -86,7 +86,7 @@ func (b *backendQuota) Cost(v interface{}) int { func costPut(r *pb.PutRequest) int { return kvOverhead + len(r.Key) + len(r.Value) } -func costTxnReq(u *pb.RequestUnion) int { +func costTxnReq(u *pb.RequestOp) int { r := u.GetRequestPut() if r == nil { return 0 diff --git a/vendor/github.com/coreos/etcd/etcdserver/raft.go b/vendor/github.com/coreos/etcd/etcdserver/raft.go index a936afee751..95e95fd22a4 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/raft.go +++ b/vendor/github.com/coreos/etcd/etcdserver/raft.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. @@ -17,7 +17,6 @@ package etcdserver import ( "encoding/json" "expvar" - "os" "sort" "sync" "sync/atomic" @@ -135,8 +134,8 @@ func (r *raftNode) start(s *EtcdServer) { r.done = make(chan struct{}) heartbeat := 200 * time.Millisecond - if s.cfg != nil { - heartbeat = time.Duration(s.cfg.TickMs) * 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. @@ -158,7 +157,15 @@ func (r *raftNode) start(s *EtcdServer) { r.mu.Lock() r.lt = time.Now() r.mu.Unlock() + leaderChanges.Inc() } + + if rd.SoftState.Lead == raft.None { + hasLeader.Set(0) + } else { + hasLeader.Set(1) + } + atomic.StoreUint64(&r.lead, rd.SoftState.Lead) if rd.RaftState == raft.StateLeader { islead = true @@ -166,7 +173,7 @@ func (r *raftNode) start(s *EtcdServer) { // 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()) + r.s.lessor.Promote(r.s.Cfg.electionTimeout()) } // TODO: remove the nil checking // current test utility does not provide the stats @@ -206,28 +213,40 @@ func (r *raftNode) start(s *EtcdServer) { // writing to their disks. // For more details, check raft thesis 10.2.1 if islead { + // gofail: var raftBeforeLeaderSend struct{} r.s.send(rd.Messages) } - if !raft.IsEmptySnap(rd.Snapshot) { - if err := r.storage.SaveSnap(rd.Snapshot); err != nil { - plog.Fatalf("raft save snapshot error: %v", err) - } - r.raftStorage.ApplySnapshot(rd.Snapshot) - plog.Infof("raft applied incoming snapshot at index %d", rd.Snapshot.Metadata.Index) - } + // gofail: var raftBeforeSave struct{} if err := r.storage.Save(rd.HardState, rd.Entries); err != nil { plog.Fatalf("raft save state and entries error: %v", err) } + if !raft.IsEmptyHardState(rd.HardState) { + proposalsCommitted.Set(float64(rd.HardState.Commit)) + } + // gofail: var raftAfterSave struct{} + + if !raft.IsEmptySnap(rd.Snapshot) { + // gofail: var raftBeforeSaveSnap struct{} + if err := r.storage.SaveSnap(rd.Snapshot); err != nil { + plog.Fatalf("raft save snapshot error: %v", err) + } + // gofail: var raftAfterSaveSnap struct{} + r.raftStorage.ApplySnapshot(rd.Snapshot) + plog.Infof("raft applied incoming snapshot at index %d", rd.Snapshot.Metadata.Index) + // gofail: var raftAfterApplySnap struct{} + } + r.raftStorage.Append(rd.Entries) if !islead { + // gofail: var raftBeforeFollowerSend struct{} r.s.send(rd.Messages) } raftDone <- struct{}{} r.Advance() case <-syncC: - r.s.sync(r.s.cfg.ReqTimeout()) + r.s.sync(r.s.Cfg.ReqTimeout()) case <-r.stopped: return } @@ -289,9 +308,6 @@ func startNode(cfg *ServerConfig, cl *membership.RaftCluster, ids []types.ID) (i ClusterID: uint64(cl.ID()), }, ) - if err = os.MkdirAll(cfg.SnapDir(), privateDirMode); err != nil { - plog.Fatalf("create snapshot directory error: %v", err) - } if w, err = wal.Create(cfg.WALDir(), metadata); err != nil { plog.Fatalf("create wal error: %v", err) } @@ -438,7 +454,7 @@ func getIDs(snap *raftpb.Snapshot, ents []raftpb.Entry) []uint64 { plog.Panicf("ConfChange Type should be either ConfChangeAddNode or ConfChangeRemoveNode!") } } - sids := make(types.Uint64Slice, 0) + sids := make(types.Uint64Slice, 0, len(ids)) for id := range ids { sids = append(sids, id) } @@ -476,7 +492,7 @@ func createConfigChangeEnts(ids []uint64, self uint64, term, index uint64) []raf if !found { m := membership.Member{ ID: types.ID(self), - RaftAttributes: membership.RaftAttributes{PeerURLs: []string{"http://localhost:7001", "http://localhost:2380"}}, + RaftAttributes: membership.RaftAttributes{PeerURLs: []string{"http://localhost:2380"}}, } ctx, err := json.Marshal(m) if err != nil { diff --git a/vendor/github.com/coreos/etcd/etcdserver/server.go b/vendor/github.com/coreos/etcd/etcdserver/server.go index 2a0d9c99896..e4943aeecf4 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/server.go +++ b/vendor/github.com/coreos/etcd/etcdserver/server.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. @@ -31,11 +31,14 @@ import ( "github.com/coreos/etcd/auth" "github.com/coreos/etcd/compactor" "github.com/coreos/etcd/discovery" + "github.com/coreos/etcd/etcdserver/api" "github.com/coreos/etcd/etcdserver/api/v2http/httptypes" pb "github.com/coreos/etcd/etcdserver/etcdserverpb" "github.com/coreos/etcd/etcdserver/membership" "github.com/coreos/etcd/etcdserver/stats" "github.com/coreos/etcd/lease" + "github.com/coreos/etcd/mvcc" + "github.com/coreos/etcd/mvcc/backend" "github.com/coreos/etcd/pkg/fileutil" "github.com/coreos/etcd/pkg/idutil" "github.com/coreos/etcd/pkg/pbutil" @@ -47,8 +50,6 @@ import ( "github.com/coreos/etcd/raft/raftpb" "github.com/coreos/etcd/rafthttp" "github.com/coreos/etcd/snap" - dstorage "github.com/coreos/etcd/storage" - "github.com/coreos/etcd/storage/backend" "github.com/coreos/etcd/store" "github.com/coreos/etcd/version" "github.com/coreos/etcd/wal" @@ -58,9 +59,6 @@ import ( ) const ( - // owner can make/remove files inside the directory - privateDirMode = 0700 - DefaultSnapCount = 10000 StoreClusterPrefix = "/0" @@ -156,11 +154,17 @@ type Server interface { // EtcdServer is the production implementation of the Server interface type EtcdServer struct { - // r must be the first element to keep 64-bit alignment for atomic + // r and inflightSnapshots must be the first elements to keep 64-bit alignment for atomic // access to fields - r raftNode - cfg *ServerConfig + // count the number of inflight snapshots. + // MUST use atomic operation to access this field. + inflightSnapshots int64 + Cfg *ServerConfig + + readych chan struct{} + r raftNode + snapCount uint64 w wait.Wait @@ -174,8 +178,10 @@ type EtcdServer struct { store store.Store + applyV2 ApplierV2 + applyV3 applierV3 - kv dstorage.ConsistentWatchableKV + kv mvcc.ConsistentWatchableKV lessor lease.Lessor bemu sync.Mutex be backend.Backend @@ -203,15 +209,18 @@ type EtcdServer struct { msgSnapC chan raftpb.Message - // count the number of inflight snapshots. - // MUST use atomic operation to access this field. - inflightSnapshots int64 + // wg is used to wait for the go routines that depends on the server state + // to exit when stopping the server. + wg sync.WaitGroup + + appliedIndex uint64 } // NewServer creates a new EtcdServer from the supplied configuration. The // configuration is considered static for the lifetime of the EtcdServer. -func NewServer(cfg *ServerConfig) (*EtcdServer, error) { +func NewServer(cfg *ServerConfig) (srv *EtcdServer, err error) { st := store.New(StoreClusterPrefix, StoreKeysPrefix) + var ( w *wal.WAL n raft.Node @@ -229,45 +238,63 @@ func NewServer(cfg *ServerConfig) (*EtcdServer, error) { if err != nil { return nil, err } - if err := upgradeDataDir(cfg.DataDir, cfg.Name, dataVer); err != nil { + 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 { + plog.Fatalf("create snapshot directory error: %v", err) + } ss := snap.New(cfg.SnapDir()) + bepath := path.Join(cfg.SnapDir(), databaseFilename) + beExist := fileutil.Exist(bepath) + be := backend.NewDefaultBackend(bepath) + defer func() { + if err != nil { + be.Close() + } + }() + prt, err := rafthttp.NewRoundTripper(cfg.PeerTLSInfo, cfg.peerDialTimeout()) if err != nil { return nil, err } - var remotes []*membership.Member + var ( + remotes []*membership.Member + snapshot *raftpb.Snapshot + ) + switch { case !haveWAL && !cfg.NewCluster: - if err := cfg.VerifyJoinExisting(); err != nil { + if err = cfg.VerifyJoinExisting(); err != nil { return nil, err } cl, err = membership.NewClusterFromURLsMap(cfg.InitialClusterToken, cfg.InitialPeerURLsMap) if err != nil { return nil, err } - existingCluster, err := GetClusterFromRemotePeers(getRemotePeerURLs(cl, cfg.Name), prt) - if err != nil { - return nil, fmt.Errorf("cannot fetch cluster info from peer urls: %v", err) + existingCluster, gerr := GetClusterFromRemotePeers(getRemotePeerURLs(cl, cfg.Name), prt) + if gerr != nil { + return nil, fmt.Errorf("cannot fetch cluster info from peer urls: %v", gerr) } - if err := membership.ValidateClusterAndAssignIDs(cl, existingCluster); err != nil { + if err = membership.ValidateClusterAndAssignIDs(cl, existingCluster); err != nil { return nil, fmt.Errorf("error validating peerURLs %s: %v", existingCluster, err) } if !isCompatibleWithCluster(cl, cl.MemberByName(cfg.Name).ID, prt) { - return nil, fmt.Errorf("incomptible with current running cluster") + return nil, fmt.Errorf("incompatible with current running cluster") } remotes = existingCluster.Members() cl.SetID(existingCluster.ID()) cl.SetStore(st) + cl.SetBackend(be) cfg.Print() id, n, s, w = startNode(cfg, cl, nil) case !haveWAL && cfg.NewCluster: - if err := cfg.VerifyBootstrap(); err != nil { + if err = cfg.VerifyBootstrap(); err != nil { return nil, err } cl, err = membership.NewClusterFromURLsMap(cfg.InitialClusterToken, cfg.InitialPeerURLsMap) @@ -280,12 +307,12 @@ func NewServer(cfg *ServerConfig) (*EtcdServer, error) { } if cfg.ShouldDiscover() { var str string - var err error str, err = discovery.JoinCluster(cfg.DiscoveryURL, cfg.DiscoveryProxy, m.ID, cfg.InitialPeerURLsMap.String()) if err != nil { return nil, &DiscoveryError{Op: "join", Err: err} } - urlsmap, err := types.NewURLsMap(str) + var urlsmap types.URLsMap + urlsmap, err = types.NewURLsMap(str) if err != nil { return nil, err } @@ -297,28 +324,27 @@ func NewServer(cfg *ServerConfig) (*EtcdServer, error) { } } cl.SetStore(st) + cl.SetBackend(be) cfg.PrintWithInitial() id, n, s, w = startNode(cfg, cl, cl.MemberIDs()) case haveWAL: - if err := fileutil.IsDirWriteable(cfg.MemberDir()); err != nil { + if err = fileutil.IsDirWriteable(cfg.MemberDir()); err != nil { return nil, fmt.Errorf("cannot write to member directory: %v", err) } - if err := fileutil.IsDirWriteable(cfg.WALDir()); err != nil { + if err = fileutil.IsDirWriteable(cfg.WALDir()); err != nil { return nil, fmt.Errorf("cannot write to WAL directory: %v", err) } if cfg.ShouldDiscover() { plog.Warningf("discovery token ignored since a cluster has already been initialized. Valid log found at %q", cfg.WALDir()) } - var snapshot *raftpb.Snapshot - var err error snapshot, err = ss.Load() if err != nil && err != snap.ErrNoSnapshot { return nil, err } if snapshot != nil { - if err := st.Recovery(snapshot.Data); err != nil { + if err = st.Recovery(snapshot.Data); err != nil { plog.Panicf("recovered store from snapshot error: %v", err) } plog.Infof("recovered store from snapshot at index %d", snapshot.Metadata.Index) @@ -330,7 +356,12 @@ func NewServer(cfg *ServerConfig) (*EtcdServer, error) { id, cl, n, s, w = restartAsStandaloneNode(cfg, snapshot) } cl.SetStore(st) - cl.Recover() + cl.SetBackend(be) + cl.Recover(api.UpdateCapability) + if cl.Version() != nil && !cl.Version().LessThan(semver.Version{Major: 3}) && !beExist { + os.RemoveAll(bepath) + return nil, fmt.Errorf("database file (%v) of the backend is missing", bepath) + } default: return nil, fmt.Errorf("unsupported bootstrap config") } @@ -346,8 +377,9 @@ func NewServer(cfg *ServerConfig) (*EtcdServer, error) { sstats.Initialize() lstats := stats.NewLeaderStats(id.String()) - srv := &EtcdServer{ - cfg: cfg, + srv = &EtcdServer{ + readych: make(chan struct{}), + Cfg: cfg, snapCount: cfg.SnapCount, errorc: make(chan error, 1), store: st, @@ -369,9 +401,17 @@ func NewServer(cfg *ServerConfig) (*EtcdServer, error) { msgSnapC: make(chan raftpb.Message, maxInFlightMsgSnap), } - srv.be = backend.NewDefaultBackend(path.Join(cfg.SnapDir(), databaseFilename)) + srv.applyV2 = &applierV2store{store: srv.store, cluster: srv.cluster} + + srv.be = be srv.lessor = lease.NewLessor(srv.be) - srv.kv = dstorage.New(srv.be, srv.lessor, &srv.consistIndex) + srv.kv = mvcc.New(srv.be, srv.lessor, &srv.consistIndex) + if beExist { + kvindex := srv.kv.ConsistentIndex() + if snapshot != nil && kvindex < snapshot.Metadata.Index { + return nil, fmt.Errorf("database file (%v index %d) does not match with snapshot (index %d).", bepath, kvindex, snapshot.Metadata.Index) + } + } srv.consistIndex.setConsistentIndex(srv.kv.ConsistentIndex()) srv.authStore = auth.NewAuthStore(srv.be) if h := cfg.AutoCompactionRetention; h != 0 { @@ -379,7 +419,7 @@ func NewServer(cfg *ServerConfig) (*EtcdServer, error) { srv.compactor.Run() } - if err := srv.restoreAlarms(); err != nil { + if err = srv.restoreAlarms(); err != nil { return nil, err } @@ -396,7 +436,7 @@ func NewServer(cfg *ServerConfig) (*EtcdServer, error) { LeaderStats: lstats, ErrorC: srv.errorc, } - if err := tr.Start(); err != nil { + if err = tr.Start(); err != nil { return nil, err } // add all remotes into transport @@ -420,7 +460,7 @@ func NewServer(cfg *ServerConfig) (*EtcdServer, 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.publish(s.Cfg.ReqTimeout()) go s.purgeFile() go monitorFileDescriptor(s.done) go s.monitorVersions() @@ -449,11 +489,11 @@ func (s *EtcdServer) start() { func (s *EtcdServer) purgeFile() { var serrc, werrc <-chan error - if s.cfg.MaxSnapFiles > 0 { - serrc = fileutil.PurgeFile(s.cfg.SnapDir(), "snap", s.cfg.MaxSnapFiles, purgeFileInterval, s.done) + if s.Cfg.MaxSnapFiles > 0 { + serrc = fileutil.PurgeFile(s.Cfg.SnapDir(), "snap", s.Cfg.MaxSnapFiles, purgeFileInterval, s.done) } - if s.cfg.MaxWALFiles > 0 { - werrc = fileutil.PurgeFile(s.cfg.WALDir(), "wal", s.cfg.MaxWALFiles, purgeFileInterval, s.done) + if s.Cfg.MaxWALFiles > 0 { + werrc = fileutil.PurgeFile(s.Cfg.WALDir(), "wal", s.Cfg.MaxWALFiles, purgeFileInterval, s.done) } select { case e := <-werrc: @@ -516,9 +556,15 @@ func (s *EtcdServer) run() { } defer func() { - s.r.stop() sched.Stop() + // wait for snapshots before closing raft so wal stays open + s.wg.Wait() + + // must stop raft after scheduler-- etcdserver can leak rafthttp pipelines + // by adding a peer after raft stops the transport + s.r.stop() + // kv, lessor and backend can be nil if running without v3 enabled // or running unit tests. if s.lessor != nil { @@ -564,7 +610,15 @@ func (s *EtcdServer) run() { func (s *EtcdServer) applyAll(ep *etcdProgress, apply *apply) { s.applySnapshot(ep, apply) + st := time.Now() s.applyEntries(ep, apply) + d := time.Since(st) + entriesNum := len(apply.entries) + if entriesNum != 0 && d > time.Duration(entriesNum)*warnApplyDuration { + plog.Warningf("apply entries took too long [%v for %d entries]", d, len(apply.entries)) + plog.Warningf("avoid queries with large range/delete range!") + } + proposalsApplied.Set(float64(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. @@ -584,6 +638,9 @@ func (s *EtcdServer) applySnapshot(ep *etcdProgress, apply *apply) { return } + plog.Infof("applying snapshot at index %d...", ep.snapi) + defer plog.Infof("finished applying incoming snapshot at index %d", ep.snapi) + if apply.snapshot.Metadata.Index <= ep.appliedi { plog.Panicf("snapshot index [%d] should > appliedi[%d] + 1", apply.snapshot.Metadata.Index, ep.appliedi) @@ -594,23 +651,31 @@ 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 := path.Join(s.Cfg.SnapDir(), databaseFilename) if err := os.Rename(snapfn, fn); err != nil { plog.Panicf("rename snapshot file error: %v", err) } newbe := backend.NewDefaultBackend(fn) + + plog.Info("restoring mvcc store...") + if err := s.kv.Restore(newbe); err != nil { plog.Panicf("restore KV error: %v", err) } s.consistIndex.setConsistentIndex(s.kv.ConsistentIndex()) + plog.Info("finished restoring mvcc store") + // Closing old backend might block until all the txns // on the backend are finished. // We do not want to wait on closing the old backend. s.bemu.Lock() oldbe := s.be go func() { + plog.Info("closing old backend...") + defer plog.Info("finished closing old backend") + if err := oldbe.Close(); err != nil { plog.Panicf("close backend error: %v", err) } @@ -620,35 +685,51 @@ func (s *EtcdServer) applySnapshot(ep *etcdProgress, apply *apply) { s.bemu.Unlock() if s.lessor != nil { + plog.Info("recovering lessor...") s.lessor.Recover(newbe, s.kv) + plog.Info("finished recovering lessor") } + plog.Info("recovering alarms...") if err := s.restoreAlarms(); err != nil { plog.Panicf("restore alarms error: %v", err) } + plog.Info("finished recovering alarms") if s.authStore != nil { + plog.Info("recovering auth store...") s.authStore.Recover(newbe) + plog.Info("finished recovering auth store") } + plog.Info("recovering store v2...") if err := s.store.Recovery(apply.snapshot.Data); err != nil { plog.Panicf("recovery store error: %v", err) } - s.cluster.Recover() + plog.Info("finished recovering store v2") + s.cluster.SetBackend(s.be) + plog.Info("recovering cluster configuration...") + s.cluster.Recover(api.UpdateCapability) + plog.Info("finished recovering cluster configuration") + + plog.Info("removing old peers from network...") // recover raft transport s.r.transport.RemoveAllPeers() + plog.Info("finished removing old peers from network") + + plog.Info("adding peers from new cluster configuration into network...") for _, m := range s.cluster.Members() { if m.ID == s.ID() { continue } s.r.transport.AddPeer(m.ID, m.PeerURLs) } + plog.Info("finished adding peers from new cluster configuration into network...") ep.appliedi = apply.snapshot.Metadata.Index ep.snapi = ep.appliedi ep.confState = apply.snapshot.Metadata.ConfState - plog.Infof("recovered from incoming snapshot at index %d", ep.snapi) } func (s *EtcdServer) applyEntries(ep *etcdProgress, apply *apply) { @@ -677,15 +758,6 @@ func (s *EtcdServer) triggerSnapshot(ep *etcdProgress) { return } - // When sending a snapshot, etcd will pause compaction. - // After receives a snapshot, the slow follower needs to get all the entries right after - // the snapshot sent to catch up. If we do not pause compaction, the log entries right after - // the snapshot sent might already be compacted. It happens when the snapshot takes long time - // to send and save. Pausing compaction avoids triggering a snapshot sending cycle. - if atomic.LoadInt64(&s.inflightSnapshots) != 0 { - return - } - plog.Infof("start to snapshot (applied: %d, lastsnap: %d)", ep.appliedi, ep.snapi) s.snapshot(ep.appliedi, ep.confState) ep.snapi = ep.appliedi @@ -702,6 +774,10 @@ func (s *EtcdServer) Stop() { <-s.done } +// 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 } + func (s *EtcdServer) stopWithDelay(d time.Duration, err error) { select { case <-time.After(d): @@ -717,70 +793,6 @@ func (s *EtcdServer) stopWithDelay(d time.Duration, err error) { // when the server is stopped. func (s *EtcdServer) StopNotify() <-chan struct{} { return s.done } -// Do interprets r and performs an operation on s.store according to r.Method -// and other fields. If r.Method is "POST", "PUT", "DELETE", or a "GET" with -// Quorum == true, r will be sent through consensus before performing its -// respective operation. Do will block until an action is performed or there is -// an error. -func (s *EtcdServer) Do(ctx context.Context, r pb.Request) (Response, error) { - r.ID = s.reqIDGen.Next() - if r.Method == "GET" && r.Quorum { - r.Method = "QGET" - } - switch r.Method { - case "POST", "PUT", "DELETE", "QGET": - data, err := r.Marshal() - if err != nil { - return Response{}, err - } - ch := s.w.Register(r.ID) - - // TODO: benchmark the cost of time.Now() - // might be sampling? - start := time.Now() - s.r.Propose(ctx, data) - - proposePending.Inc() - defer proposePending.Dec() - - select { - case x := <-ch: - proposeDurations.Observe(float64(time.Since(start)) / float64(time.Second)) - resp := x.(Response) - return resp, resp.err - case <-ctx.Done(): - proposeFailed.Inc() - s.w.Trigger(r.ID, nil) // GC wait - return Response{}, s.parseProposeCtxErr(ctx.Err(), start) - case <-s.done: - return Response{}, ErrStopped - } - case "GET": - switch { - case r.Wait: - wc, err := s.store.Watch(r.Path, r.Recursive, r.Stream, r.Since) - if err != nil { - return Response{}, err - } - return Response{Watcher: wc}, nil - default: - ev, err := s.store.Get(r.Path, r.Recursive, r.Sorted) - if err != nil { - return Response{}, err - } - return Response{Event: ev}, nil - } - case "HEAD": - ev, err := s.store.Get(r.Path, r.Recursive, r.Sorted) - if err != nil { - return Response{}, err - } - return Response{Event: ev}, nil - default: - return Response{}, ErrUnknownMethod - } -} - func (s *EtcdServer) SelfStats() []byte { return s.stats.JSON() } func (s *EtcdServer) LeaderStats() []byte { @@ -794,7 +806,7 @@ func (s *EtcdServer) LeaderStats() []byte { func (s *EtcdServer) StoreStats() []byte { return s.store.JsonStats() } func (s *EtcdServer) AddMember(ctx context.Context, memb membership.Member) error { - if s.cfg.StrictReconfigCheck && !s.cluster.IsReadyToAddNewMember() { + 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 @@ -814,7 +826,7 @@ 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 && !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 @@ -853,7 +865,7 @@ 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 } +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 @@ -925,6 +937,7 @@ func (s *EtcdServer) publish(timeout time.Duration) { cancel() switch err { case nil: + close(s.readych) plog.Infof("published %+v to cluster %s", s.attributes, s.cluster.ID()) return case ErrStopped: @@ -938,11 +951,20 @@ func (s *EtcdServer) publish(timeout time.Duration) { // TODO: move this function into raft.go func (s *EtcdServer) send(ms []raftpb.Message) { - for i := range ms { + 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. @@ -959,7 +981,7 @@ func (s *EtcdServer) send(ms []raftpb.Message) { ok, exceed := s.r.td.Observe(ms[i].To) if !ok { // TODO: limit request rate. - plog.Warningf("failed to send out heartbeat on time (deadline exceeded for %v)", exceed) + 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") } } @@ -1002,48 +1024,7 @@ func (s *EtcdServer) apply(es []raftpb.Entry, confState *raftpb.ConfState) (uint e := es[i] switch e.Type { case raftpb.EntryNormal: - // raft state machine may generate noop entry when leader confirmation. - // skip it in advance to avoid some potential bug in the future - if len(e.Data) == 0 { - select { - case s.forceVersionC <- struct{}{}: - default: - } - break - } - - var raftReq pb.InternalRaftRequest - if !pbutil.MaybeUnmarshal(&raftReq, e.Data) { // backward compatible - var r pb.Request - pbutil.MustUnmarshal(&r, e.Data) - s.w.Trigger(r.ID, s.applyRequest(r)) - } else if raftReq.V2 != nil { - req := raftReq.V2 - s.w.Trigger(req.ID, s.applyRequest(*req)) - } else { - // do not re-apply applied entries. - if e.Index <= s.consistIndex.ConsistentIndex() { - break - } - // set the consistent index of current executing entry - s.consistIndex.setConsistentIndex(e.Index) - ar := s.applyV3Request(&raftReq) - if ar.err != ErrNoSpace || len(s.alarmStore.Get(pb.AlarmType_NOSPACE)) > 0 { - s.w.Trigger(raftReq.ID, ar) - break - } - plog.Errorf("applying raft message exceeded backend quota") - go func() { - a := &pb.AlarmRequest{ - MemberID: uint64(s.ID()), - Action: pb.AlarmRequest_ACTIVATE, - Alarm: pb.AlarmType_NOSPACE, - } - r := pb.InternalRaftRequest{Alarm: a} - s.processInternalRaftRequest(context.TODO(), r) - s.w.Trigger(raftReq.ID, ar) - }() - } + s.applyEntryNormal(&e) case raftpb.EntryConfChange: var cc raftpb.ConfChange pbutil.MustUnmarshal(&cc, e.Data) @@ -1060,71 +1041,66 @@ func (s *EtcdServer) apply(es []raftpb.Entry, confState *raftpb.ConfState) (uint return applied, shouldstop } -// applyRequest interprets r as a call to store.X and returns a Response interpreted -// from store.Event -func (s *EtcdServer) applyRequest(r pb.Request) Response { - f := func(ev *store.Event, err error) Response { - return Response{Event: ev, err: err} +// applyEntryNormal apples an EntryNormal type raftpb request to the EtcdServer +func (s *EtcdServer) applyEntryNormal(e *raftpb.Entry) { + shouldApplyV3 := false + if e.Index > s.consistIndex.ConsistentIndex() { + // set the consistent index of current executing entry + s.consistIndex.setConsistentIndex(e.Index) + shouldApplyV3 = true } - refresh, _ := pbutil.GetBool(r.Refresh) - ttlOptions := store.TTLOptionSet{Refresh: refresh} - if r.Expiration != 0 { - ttlOptions.ExpireTime = time.Unix(0, r.Expiration) + // raft state machine may generate noop entry when leader confirmation. + // skip it in advance to avoid some potential bug in the future + if len(e.Data) == 0 { + select { + case s.forceVersionC <- struct{}{}: + default: + } + return } - switch r.Method { - case "POST": - return f(s.store.Create(r.Path, r.Dir, r.Val, true, ttlOptions)) - case "PUT": - exists, existsSet := pbutil.GetBool(r.PrevExist) - switch { - case existsSet: - if exists { - if r.PrevIndex == 0 && r.PrevValue == "" { - return f(s.store.Update(r.Path, r.Val, ttlOptions)) - } else { - return f(s.store.CompareAndSwap(r.Path, r.PrevValue, r.PrevIndex, r.Val, ttlOptions)) - } - } - return f(s.store.Create(r.Path, r.Dir, r.Val, false, ttlOptions)) - case r.PrevIndex > 0 || r.PrevValue != "": - return f(s.store.CompareAndSwap(r.Path, r.PrevValue, r.PrevIndex, r.Val, ttlOptions)) - default: - // TODO (yicheng): cluster should be the owner of cluster prefix store - // we should not modify cluster store here. - if storeMemberAttributeRegexp.MatchString(r.Path) { - id := membership.MustParseMemberIDFromKey(path.Dir(r.Path)) - var attr membership.Attributes - if err := json.Unmarshal([]byte(r.Val), &attr); err != nil { - plog.Panicf("unmarshal %s should never fail: %v", r.Val, err) - } - ok := s.cluster.UpdateAttributes(id, attr) - if !ok { - return Response{} - } - } - if r.Path == path.Join(StoreClusterPrefix, "version") { - s.cluster.SetVersion(semver.Must(semver.NewVersion(r.Val))) - } - return f(s.store.Set(r.Path, r.Dir, r.Val, ttlOptions)) - } - case "DELETE": - switch { - case r.PrevIndex > 0 || r.PrevValue != "": - return f(s.store.CompareAndDelete(r.Path, r.PrevValue, r.PrevIndex)) - default: - return f(s.store.Delete(r.Path, r.Dir, r.Recursive)) - } - case "QGET": - return f(s.store.Get(r.Path, r.Recursive, r.Sorted)) - case "SYNC": - s.store.DeleteExpiredKeys(time.Unix(0, r.Time)) - return Response{} - default: - // This should never be reached, but just in case: - return Response{err: ErrUnknownMethod} + var raftReq pb.InternalRaftRequest + if !pbutil.MaybeUnmarshal(&raftReq, e.Data) { // backward compatible + var r pb.Request + pbutil.MustUnmarshal(&r, e.Data) + s.w.Trigger(r.ID, s.applyV2Request(&r)) + return } + if raftReq.V2 != nil { + req := raftReq.V2 + s.w.Trigger(req.ID, s.applyV2Request(req)) + return + } + + // do not re-apply applied entries. + if !shouldApplyV3 { + return + } + + id := raftReq.ID + if id == 0 { + id = raftReq.Header.ID + } + + ar := s.applyV3.Apply(&raftReq) + s.setAppliedIndex(e.Index) + 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() { + a := &pb.AlarmRequest{ + MemberID: uint64(s.ID()), + Action: pb.AlarmRequest_ACTIVATE, + Alarm: pb.AlarmType_NOSPACE, + } + 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 @@ -1146,21 +1122,16 @@ func (s *EtcdServer) applyConfChange(cc raftpb.ConfChange, confState *raftpb.Con plog.Panicf("nodeID should always be equal to member ID") } s.cluster.AddMember(m) - if m.ID == s.id { - plog.Noticef("added local member %s %v to cluster %s", m.ID, m.PeerURLs, s.cluster.ID()) - } else { + if m.ID != s.id { s.r.transport.AddPeer(m.ID, m.PeerURLs) - plog.Noticef("added member %s %v to cluster %s", m.ID, m.PeerURLs, s.cluster.ID()) } case raftpb.ConfChangeRemoveNode: id := types.ID(cc.NodeID) s.cluster.RemoveMember(id) if id == s.id { return true, nil - } else { - s.r.transport.RemovePeer(id) - plog.Noticef("removed member %s from cluster %s", id, s.cluster.ID()) } + s.r.transport.RemovePeer(id) case raftpb.ConfChangeUpdateNode: m := new(membership.Member) if err := json.Unmarshal(cc.Context, m); err != nil { @@ -1170,11 +1141,8 @@ func (s *EtcdServer) applyConfChange(cc raftpb.ConfChange, confState *raftpb.Con plog.Panicf("nodeID should always be equal to member ID") } s.cluster.UpdateRaftAttributes(m.ID, m.RaftAttributes) - if m.ID == s.id { - plog.Noticef("update local member %s %v in cluster %s", m.ID, m.PeerURLs, s.cluster.ID()) - } else { + if m.ID != s.id { s.r.transport.UpdatePeer(m.ID, m.PeerURLs) - plog.Noticef("update member %s %v in cluster %s", m.ID, m.PeerURLs, s.cluster.ID()) } } return false, nil @@ -1184,7 +1152,10 @@ func (s *EtcdServer) applyConfChange(cc raftpb.ConfChange, confState *raftpb.Con func (s *EtcdServer) snapshot(snapi uint64, confState raftpb.ConfState) { clone := s.store.Clone() + s.wg.Add(1) go func() { + defer s.wg.Done() + d, err := clone.SaveNoCopy() // TODO: current store will never fail to do a snapshot // what should we do if the store might fail? @@ -1200,8 +1171,7 @@ func (s *EtcdServer) snapshot(snapi uint64, confState raftpb.ConfState) { } plog.Panicf("unexpected create snapshot error %v", err) } - // commit v3 storage because WAL file before snapshot index - // could be removed after SaveSnap. + // 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. @@ -1210,6 +1180,16 @@ func (s *EtcdServer) snapshot(snapi uint64, confState raftpb.ConfState) { } plog.Infof("saved snapshot at index %d", snap.Metadata.Index) + // When sending a snapshot, etcd will pause compaction. + // After receives a snapshot, the slow follower needs to get all the entries right after + // the snapshot sent to catch up. If we do not pause compaction, the log entries right after + // the snapshot sent might already be compacted. It happens when the snapshot takes long time + // to send and save. Pausing compaction avoids triggering a snapshot sending cycle. + if atomic.LoadInt64(&s.inflightSnapshots) != 0 { + plog.Infof("skip compaction since there is an inflight snapshot") + return + } + // keep some in memory log entries for slow followers. compacti := uint64(1) if snapi > numberOfCatchUpEntries { @@ -1293,10 +1273,10 @@ func (s *EtcdServer) updateClusterVersion(ver string) { } req := pb.Request{ Method: "PUT", - Path: path.Join(StoreClusterPrefix, "version"), + Path: membership.StoreClusterVersionKey(), Val: ver, } - ctx, cancel := context.WithTimeout(context.Background(), s.cfg.ReqTimeout()) + ctx, cancel := context.WithTimeout(context.Background(), s.Cfg.ReqTimeout()) _, err := s.Do(ctx, req) cancel() switch err { @@ -1316,7 +1296,7 @@ func (s *EtcdServer) parseProposeCtxErr(err error, start time.Time) error { return ErrCanceled case context.DeadlineExceeded: curLeadElected := s.r.leadElectedTime() - prevLeadLost := curLeadElected.Add(-2 * time.Duration(s.cfg.ElectionTicks) * time.Duration(s.cfg.TickMs) * time.Millisecond) + prevLeadLost := curLeadElected.Add(-2 * time.Duration(s.Cfg.ElectionTicks) * time.Duration(s.Cfg.TickMs) * time.Millisecond) if start.After(prevLeadLost) && start.Before(curLeadElected) { return ErrTimeoutDueToLeaderFail } @@ -1341,7 +1321,7 @@ func (s *EtcdServer) parseProposeCtxErr(err error, start time.Time) error { } } -func (s *EtcdServer) KV() dstorage.ConsistentWatchableKV { return s.kv } +func (s *EtcdServer) KV() mvcc.ConsistentWatchableKV { return s.kv } func (s *EtcdServer) Backend() backend.Backend { s.bemu.Lock() defer s.bemu.Unlock() @@ -1351,8 +1331,7 @@ func (s *EtcdServer) Backend() backend.Backend { func (s *EtcdServer) AuthStore() auth.AuthStore { return s.authStore } func (s *EtcdServer) restoreAlarms() error { - s.applyV3 = newQuotaApplierV3(s, &applierV3backend{s}) - + s.applyV3 = s.newApplierV3() as, err := alarm.NewAlarmStore(s) if err != nil { return err @@ -1363,3 +1342,11 @@ func (s *EtcdServer) restoreAlarms() error { } return nil } + +func (s *EtcdServer) getAppliedIndex() uint64 { + return atomic.LoadUint64(&s.appliedIndex) +} + +func (s *EtcdServer) setAppliedIndex(v uint64) { + atomic.StoreUint64(&s.appliedIndex, v) +} diff --git a/vendor/github.com/coreos/etcd/etcdserver/snapshot_merge.go b/vendor/github.com/coreos/etcd/etcdserver/snapshot_merge.go index 51599bcf506..1de996c507f 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/snapshot_merge.go +++ b/vendor/github.com/coreos/etcd/etcdserver/snapshot_merge.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. @@ -18,9 +18,9 @@ import ( "io" "log" + "github.com/coreos/etcd/mvcc/backend" "github.com/coreos/etcd/raft/raftpb" "github.com/coreos/etcd/snap" - "github.com/coreos/etcd/storage/backend" ) // createMergedSnapshotMessage creates a snapshot message that contains: raft status (term, conf), @@ -39,8 +39,11 @@ func (s *EtcdServer) createMergedSnapshotMessage(m raftpb.Message, snapi uint64, plog.Panicf("store save should never fail: %v", err) } + // commit kv to write metadata(for example: consistent index). + s.KV().Commit() + dbsnap := s.be.Snapshot() // get a snapshot of v3 KV as readCloser - rc := newSnapshotReaderCloser(s.be.Snapshot()) + rc := newSnapshotReaderCloser(dbsnap) // put the []byte snapshot of store into raft snapshot and return the merged snapshot with // KV readCloser snapshot. @@ -54,7 +57,7 @@ func (s *EtcdServer) createMergedSnapshotMessage(m raftpb.Message, snapi uint64, } m.Snapshot = snapshot - return *snap.NewMessage(m, rc) + return *snap.NewMessage(m, rc, dbsnap.Size()) } func newSnapshotReaderCloser(snapshot backend.Snapshot) io.ReadCloser { diff --git a/vendor/github.com/coreos/etcd/etcdserver/stats/leader.go b/vendor/github.com/coreos/etcd/etcdserver/stats/leader.go index 0dbea6ba35e..1bed85474e3 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/stats/leader.go +++ b/vendor/github.com/coreos/etcd/etcdserver/stats/leader.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. diff --git a/vendor/github.com/coreos/etcd/etcdserver/stats/queue.go b/vendor/github.com/coreos/etcd/etcdserver/stats/queue.go index aa8d36e54ec..635074c4898 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/stats/queue.go +++ b/vendor/github.com/coreos/etcd/etcdserver/stats/queue.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. @@ -85,7 +85,7 @@ func (q *statsQueue) Rate() (float64, float64) { return 0, 0 } - if time.Now().Sub(back.SendingTime) > time.Second { + if time.Since(back.SendingTime) > time.Second { q.Clear() return 0, 0 } diff --git a/vendor/github.com/coreos/etcd/etcdserver/stats/server.go b/vendor/github.com/coreos/etcd/etcdserver/stats/server.go index 84065985d1b..10849813cb4 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/stats/server.go +++ b/vendor/github.com/coreos/etcd/etcdserver/stats/server.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. @@ -57,7 +57,7 @@ func (ss *ServerStats) JSON() []byte { ss.Lock() stats := *ss ss.Unlock() - stats.LeaderInfo.Uptime = time.Now().Sub(stats.LeaderInfo.StartTime).String() + stats.LeaderInfo.Uptime = time.Since(stats.LeaderInfo.StartTime).String() stats.SendingPkgRate, stats.SendingBandwidthRate = stats.SendRates() stats.RecvingPkgRate, stats.RecvingBandwidthRate = stats.RecvRates() b, err := json.Marshal(stats) @@ -142,6 +142,9 @@ func (ss *ServerStats) SendAppendReq(reqSize int) { } func (ss *ServerStats) BecomeLeader() { + ss.Lock() + defer ss.Unlock() + 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 658662b2f59..e793398947d 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/stats/stats.go +++ b/vendor/github.com/coreos/etcd/etcdserver/stats/stats.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. diff --git a/vendor/github.com/coreos/etcd/etcdserver/storage.go b/vendor/github.com/coreos/etcd/etcdserver/storage.go index 26aa69d89b5..6453a179471 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/storage.go +++ b/vendor/github.com/coreos/etcd/etcdserver/storage.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. @@ -20,6 +20,7 @@ import ( "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" @@ -66,11 +67,7 @@ func (st *storage) SaveSnap(snap raftpb.Snapshot) error { if err != nil { return err } - err = st.WAL.ReleaseLockTo(snap.Metadata.Index) - if err != nil { - return err - } - return nil + return st.WAL.ReleaseLockTo(snap.Metadata.Index) } func readWAL(waldir string, snap walpb.Snapshot) (w *wal.WAL, id, cid types.ID, st raftpb.HardState, ents []raftpb.Entry) { @@ -133,7 +130,7 @@ func makeMemberDir(dir string) error { case !os.IsNotExist(err): return err } - if err := os.MkdirAll(membdir, 0700); err != nil { + if err := fileutil.CreateDirAll(membdir); err != nil { return err } names := []string{"snap", "wal"} diff --git a/vendor/github.com/coreos/etcd/etcdserver/util.go b/vendor/github.com/coreos/etcd/etcdserver/util.go index 0f4c3772b94..32c16174303 100644 --- a/vendor/github.com/coreos/etcd/etcdserver/util.go +++ b/vendor/github.com/coreos/etcd/etcdserver/util.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. diff --git a/vendor/github.com/coreos/etcd/etcdserver/v2_server.go b/vendor/github.com/coreos/etcd/etcdserver/v2_server.go new file mode 100644 index 00000000000..a7285688e17 --- /dev/null +++ b/vendor/github.com/coreos/etcd/etcdserver/v2_server.go @@ -0,0 +1,125 @@ +// 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 etcdserver + +import ( + "time" + + pb "github.com/coreos/etcd/etcdserver/etcdserverpb" + "golang.org/x/net/context" +) + +type v2API interface { + Post(ctx context.Context, r *pb.Request) (Response, error) + Put(ctx context.Context, r *pb.Request) (Response, error) + Delete(ctx context.Context, r *pb.Request) (Response, error) + QGet(ctx context.Context, r *pb.Request) (Response, error) + Get(ctx context.Context, r *pb.Request) (Response, error) + Head(ctx context.Context, r *pb.Request) (Response, error) +} + +type v2apiStore struct{ s *EtcdServer } + +func (a *v2apiStore) Post(ctx context.Context, r *pb.Request) (Response, error) { + return a.processRaftRequest(ctx, r) +} + +func (a *v2apiStore) Put(ctx context.Context, r *pb.Request) (Response, error) { + return a.processRaftRequest(ctx, r) +} + +func (a *v2apiStore) Delete(ctx context.Context, r *pb.Request) (Response, error) { + return a.processRaftRequest(ctx, r) +} + +func (a *v2apiStore) QGet(ctx context.Context, r *pb.Request) (Response, error) { + return a.processRaftRequest(ctx, r) +} + +func (a *v2apiStore) processRaftRequest(ctx context.Context, r *pb.Request) (Response, error) { + data, err := r.Marshal() + if err != nil { + return Response{}, err + } + ch := a.s.w.Register(r.ID) + + start := time.Now() + a.s.r.Propose(ctx, data) + proposalsPending.Inc() + defer proposalsPending.Dec() + + select { + case x := <-ch: + resp := x.(Response) + return resp, resp.err + case <-ctx.Done(): + proposalsFailed.Inc() + a.s.w.Trigger(r.ID, nil) // GC wait + return Response{}, a.s.parseProposeCtxErr(ctx.Err(), start) + case <-a.s.done: + } + return Response{}, ErrStopped +} + +func (a *v2apiStore) Get(ctx context.Context, r *pb.Request) (Response, error) { + if r.Wait { + wc, err := a.s.store.Watch(r.Path, r.Recursive, r.Stream, r.Since) + if err != nil { + return Response{}, err + } + return Response{Watcher: wc}, nil + } + ev, err := a.s.store.Get(r.Path, r.Recursive, r.Sorted) + if err != nil { + return Response{}, err + } + return Response{Event: ev}, nil +} + +func (a *v2apiStore) Head(ctx context.Context, r *pb.Request) (Response, error) { + ev, err := a.s.store.Get(r.Path, r.Recursive, r.Sorted) + if err != nil { + return Response{}, err + } + return Response{Event: ev}, nil +} + +// Do interprets r and performs an operation on s.store according to r.Method +// and other fields. If r.Method is "POST", "PUT", "DELETE", or a "GET" with +// Quorum == true, r will be sent through consensus before performing its +// respective operation. Do will block until an action is performed or there is +// an error. +func (s *EtcdServer) Do(ctx context.Context, r pb.Request) (Response, error) { + r.ID = s.reqIDGen.Next() + if r.Method == "GET" && r.Quorum { + r.Method = "QGET" + } + v2api := (v2API)(&v2apiStore{s}) + switch r.Method { + case "POST": + return v2api.Post(ctx, &r) + case "PUT": + return v2api.Put(ctx, &r) + case "DELETE": + return v2api.Delete(ctx, &r) + case "QGET": + return v2api.QGet(ctx, &r) + case "GET": + return v2api.Get(ctx, &r) + case "HEAD": + return v2api.Head(ctx, &r) + } + return Response{}, ErrUnknownMethod +} diff --git a/vendor/github.com/coreos/etcd/etcdserver/v3_server.go b/vendor/github.com/coreos/etcd/etcdserver/v3_server.go new file mode 100644 index 00000000000..12e7eda7033 --- /dev/null +++ b/vendor/github.com/coreos/etcd/etcdserver/v3_server.go @@ -0,0 +1,554 @@ +// Copyright 2015 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 etcdserver + +import ( + "strconv" + "strings" + "time" + + pb "github.com/coreos/etcd/etcdserver/etcdserverpb" + "github.com/coreos/etcd/lease" + "github.com/coreos/etcd/lease/leasehttp" + "github.com/coreos/etcd/mvcc" + "golang.org/x/net/context" + "google.golang.org/grpc/metadata" +) + +const ( + // the max request size that raft accepts. + // TODO: make this a flag? But we probably do not want to + // accept large request which might block raft stream. User + // 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 +) + +type RaftKV interface { + Range(ctx context.Context, r *pb.RangeRequest) (*pb.RangeResponse, error) + Put(ctx context.Context, r *pb.PutRequest) (*pb.PutResponse, error) + DeleteRange(ctx context.Context, r *pb.DeleteRangeRequest) (*pb.DeleteRangeResponse, error) + Txn(ctx context.Context, r *pb.TxnRequest) (*pb.TxnResponse, error) + Compact(ctx context.Context, r *pb.CompactionRequest) (*pb.CompactionResponse, error) +} + +type Lessor interface { + // LeaseGrant sends LeaseGrant request to raft and apply it after committed. + LeaseGrant(ctx context.Context, r *pb.LeaseGrantRequest) (*pb.LeaseGrantResponse, error) + // LeaseRevoke sends LeaseRevoke request to raft and apply it after committed. + LeaseRevoke(ctx context.Context, r *pb.LeaseRevokeRequest) (*pb.LeaseRevokeResponse, error) + + // LeaseRenew renews the lease with given ID. The renewed TTL is returned. Or an error + // is returned. + LeaseRenew(id lease.LeaseID) (int64, error) +} + +type Authenticator interface { + AuthEnable(ctx context.Context, r *pb.AuthEnableRequest) (*pb.AuthEnableResponse, error) + AuthDisable(ctx context.Context, r *pb.AuthDisableRequest) (*pb.AuthDisableResponse, error) + Authenticate(ctx context.Context, r *pb.AuthenticateRequest) (*pb.AuthenticateResponse, error) + UserAdd(ctx context.Context, r *pb.AuthUserAddRequest) (*pb.AuthUserAddResponse, error) + UserDelete(ctx context.Context, r *pb.AuthUserDeleteRequest) (*pb.AuthUserDeleteResponse, error) + UserChangePassword(ctx context.Context, r *pb.AuthUserChangePasswordRequest) (*pb.AuthUserChangePasswordResponse, error) + UserGrantRole(ctx context.Context, r *pb.AuthUserGrantRoleRequest) (*pb.AuthUserGrantRoleResponse, error) + UserGet(ctx context.Context, r *pb.AuthUserGetRequest) (*pb.AuthUserGetResponse, error) + UserRevokeRole(ctx context.Context, r *pb.AuthUserRevokeRoleRequest) (*pb.AuthUserRevokeRoleResponse, error) + RoleAdd(ctx context.Context, r *pb.AuthRoleAddRequest) (*pb.AuthRoleAddResponse, error) + RoleGrantPermission(ctx context.Context, r *pb.AuthRoleGrantPermissionRequest) (*pb.AuthRoleGrantPermissionResponse, error) + RoleGet(ctx context.Context, r *pb.AuthRoleGetRequest) (*pb.AuthRoleGetResponse, error) + RoleRevokePermission(ctx context.Context, r *pb.AuthRoleRevokePermissionRequest) (*pb.AuthRoleRevokePermissionResponse, error) + RoleDelete(ctx context.Context, r *pb.AuthRoleDeleteRequest) (*pb.AuthRoleDeleteResponse, error) + UserList(ctx context.Context, r *pb.AuthUserListRequest) (*pb.AuthUserListResponse, error) + RoleList(ctx context.Context, r *pb.AuthRoleListRequest) (*pb.AuthRoleListResponse, error) +} + +func (s *EtcdServer) Range(ctx context.Context, r *pb.RangeRequest) (*pb.RangeResponse, error) { + var result *applyResult + var err error + + if r.Serializable { + var user string + user, err = s.usernameFromCtx(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}) + } + if err != nil { + return nil, err + } + if result.err != nil { + return nil, result.err + } + return result.resp.(*pb.RangeResponse), nil +} + +func (s *EtcdServer) Put(ctx context.Context, r *pb.PutRequest) (*pb.PutResponse, error) { + result, err := s.processInternalRaftRequest(ctx, pb.InternalRaftRequest{Put: r}) + if err != nil { + return nil, err + } + if result.err != nil { + return nil, result.err + } + return result.resp.(*pb.PutResponse), nil +} + +func (s *EtcdServer) DeleteRange(ctx context.Context, r *pb.DeleteRangeRequest) (*pb.DeleteRangeResponse, error) { + result, err := s.processInternalRaftRequest(ctx, pb.InternalRaftRequest{DeleteRange: r}) + if err != nil { + return nil, err + } + if result.err != nil { + return nil, result.err + } + return result.resp.(*pb.DeleteRangeResponse), nil +} + +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}) + } + if err != nil { + return nil, err + } + if result.err != nil { + return nil, result.err + } + return result.resp.(*pb.TxnResponse), nil +} + +func isTxnSerializable(r *pb.TxnRequest) bool { + for _, u := range r.Success { + if r := u.GetRequestRange(); r == nil || !r.Serializable { + return false + } + } + for _, u := range r.Failure { + if r := u.GetRequestRange(); r == nil || !r.Serializable { + 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}) + if r.Physical && result != nil && result.physc != nil { + <-result.physc + // The compaction is done deleting keys; the hash is now settled + // but the data is not necessarily committed. If there's a crash, + // the hash may revert to a hash prior to compaction completing + // if the compaction resumes. Force the finished compaction to + // commit so it won't resume following a crash. + s.be.ForceCommit() + } + if err != nil { + return nil, err + } + if result.err != nil { + return nil, result.err + } + resp := result.resp.(*pb.CompactionResponse) + if resp == nil { + resp = &pb.CompactionResponse{} + } + if resp.Header == nil { + resp.Header = &pb.ResponseHeader{} + } + resp.Header.Revision = s.kv.Rev() + return resp, nil +} + +func (s *EtcdServer) LeaseGrant(ctx context.Context, r *pb.LeaseGrantRequest) (*pb.LeaseGrantResponse, error) { + // no id given? choose one + for r.ID == int64(lease.NoLease) { + // only use positive int64 id's + r.ID = int64(s.reqIDGen.Next() & ((1 << 63) - 1)) + } + result, err := s.processInternalRaftRequest(ctx, pb.InternalRaftRequest{LeaseGrant: r}) + if err != nil { + return nil, err + } + if result.err != nil { + return nil, result.err + } + return result.resp.(*pb.LeaseGrantResponse), nil +} + +func (s *EtcdServer) LeaseRevoke(ctx context.Context, r *pb.LeaseRevokeRequest) (*pb.LeaseRevokeResponse, error) { + result, err := s.processInternalRaftRequest(ctx, pb.InternalRaftRequest{LeaseRevoke: r}) + if err != nil { + return nil, err + } + if result.err != nil { + return nil, result.err + } + return result.resp.(*pb.LeaseRevokeResponse), nil +} + +func (s *EtcdServer) LeaseRenew(id lease.LeaseID) (int64, error) { + ttl, err := s.lessor.Renew(id) + if err == nil { + return ttl, nil + } + if err != lease.ErrNotPrimary { + return -1, err + } + + // renewals don't go through raft; forward to leader manually + leader := s.cluster.Member(s.Leader()) + for i := 0; i < 5 && leader == nil; i++ { + // wait an election + dur := time.Duration(s.Cfg.ElectionTicks) * time.Duration(s.Cfg.TickMs) * time.Millisecond + select { + case <-time.After(dur): + leader = s.cluster.Member(s.Leader()) + case <-s.done: + return -1, ErrStopped + } + } + if leader == nil || len(leader.PeerURLs) == 0 { + return -1, ErrNoLeader + } + + for _, url := range leader.PeerURLs { + lurl := url + "/leases" + ttl, err = leasehttp.RenewHTTP(id, lurl, s.peerRt, s.Cfg.peerDialTimeout()) + if err == nil { + break + } + } + return ttl, err +} + +func (s *EtcdServer) Alarm(ctx context.Context, r *pb.AlarmRequest) (*pb.AlarmResponse, error) { + result, err := s.processInternalRaftRequest(ctx, pb.InternalRaftRequest{Alarm: r}) + if err != nil { + return nil, err + } + if result.err != nil { + return nil, result.err + } + return result.resp.(*pb.AlarmResponse), nil +} + +func (s *EtcdServer) AuthEnable(ctx context.Context, r *pb.AuthEnableRequest) (*pb.AuthEnableResponse, error) { + result, err := s.processInternalRaftRequest(ctx, pb.InternalRaftRequest{AuthEnable: r}) + if err != nil { + return nil, err + } + if result.err != nil { + return nil, result.err + } + return result.resp.(*pb.AuthEnableResponse), nil +} + +func (s *EtcdServer) AuthDisable(ctx context.Context, r *pb.AuthDisableRequest) (*pb.AuthDisableResponse, error) { + result, err := s.processInternalRaftRequest(ctx, pb.InternalRaftRequest{AuthDisable: r}) + if err != nil { + return nil, err + } + if result.err != nil { + return nil, result.err + } + return result.resp.(*pb.AuthDisableResponse), nil +} + +func (s *EtcdServer) Authenticate(ctx context.Context, r *pb.AuthenticateRequest) (*pb.AuthenticateResponse, error) { + 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.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 +} + +func (s *EtcdServer) UserAdd(ctx context.Context, r *pb.AuthUserAddRequest) (*pb.AuthUserAddResponse, error) { + result, err := s.processInternalRaftRequest(ctx, pb.InternalRaftRequest{AuthUserAdd: r}) + if err != nil { + return nil, err + } + if result.err != nil { + return nil, result.err + } + return result.resp.(*pb.AuthUserAddResponse), nil +} + +func (s *EtcdServer) UserDelete(ctx context.Context, r *pb.AuthUserDeleteRequest) (*pb.AuthUserDeleteResponse, error) { + result, err := s.processInternalRaftRequest(ctx, pb.InternalRaftRequest{AuthUserDelete: r}) + if err != nil { + return nil, err + } + if result.err != nil { + return nil, result.err + } + return result.resp.(*pb.AuthUserDeleteResponse), nil +} + +func (s *EtcdServer) UserChangePassword(ctx context.Context, r *pb.AuthUserChangePasswordRequest) (*pb.AuthUserChangePasswordResponse, error) { + result, err := s.processInternalRaftRequest(ctx, pb.InternalRaftRequest{AuthUserChangePassword: r}) + if err != nil { + return nil, err + } + if result.err != nil { + return nil, result.err + } + return result.resp.(*pb.AuthUserChangePasswordResponse), nil +} + +func (s *EtcdServer) UserGrantRole(ctx context.Context, r *pb.AuthUserGrantRoleRequest) (*pb.AuthUserGrantRoleResponse, error) { + result, err := s.processInternalRaftRequest(ctx, pb.InternalRaftRequest{AuthUserGrantRole: r}) + if err != nil { + return nil, err + } + if result.err != nil { + return nil, result.err + } + return result.resp.(*pb.AuthUserGrantRoleResponse), nil +} + +func (s *EtcdServer) UserGet(ctx context.Context, r *pb.AuthUserGetRequest) (*pb.AuthUserGetResponse, error) { + result, err := s.processInternalRaftRequest(ctx, pb.InternalRaftRequest{AuthUserGet: r}) + if err != nil { + return nil, err + } + if result.err != nil { + return nil, result.err + } + return result.resp.(*pb.AuthUserGetResponse), nil +} + +func (s *EtcdServer) UserList(ctx context.Context, r *pb.AuthUserListRequest) (*pb.AuthUserListResponse, error) { + result, err := s.processInternalRaftRequest(ctx, pb.InternalRaftRequest{AuthUserList: r}) + if err != nil { + return nil, err + } + if result.err != nil { + return nil, result.err + } + return result.resp.(*pb.AuthUserListResponse), nil +} + +func (s *EtcdServer) UserRevokeRole(ctx context.Context, r *pb.AuthUserRevokeRoleRequest) (*pb.AuthUserRevokeRoleResponse, error) { + result, err := s.processInternalRaftRequest(ctx, pb.InternalRaftRequest{AuthUserRevokeRole: r}) + if err != nil { + return nil, err + } + if result.err != nil { + return nil, result.err + } + return result.resp.(*pb.AuthUserRevokeRoleResponse), nil +} + +func (s *EtcdServer) RoleAdd(ctx context.Context, r *pb.AuthRoleAddRequest) (*pb.AuthRoleAddResponse, error) { + result, err := s.processInternalRaftRequest(ctx, pb.InternalRaftRequest{AuthRoleAdd: r}) + if err != nil { + return nil, err + } + if result.err != nil { + return nil, result.err + } + return result.resp.(*pb.AuthRoleAddResponse), nil +} + +func (s *EtcdServer) RoleGrantPermission(ctx context.Context, r *pb.AuthRoleGrantPermissionRequest) (*pb.AuthRoleGrantPermissionResponse, error) { + result, err := s.processInternalRaftRequest(ctx, pb.InternalRaftRequest{AuthRoleGrantPermission: r}) + if err != nil { + return nil, err + } + if result.err != nil { + return nil, result.err + } + return result.resp.(*pb.AuthRoleGrantPermissionResponse), nil +} + +func (s *EtcdServer) RoleGet(ctx context.Context, r *pb.AuthRoleGetRequest) (*pb.AuthRoleGetResponse, error) { + result, err := s.processInternalRaftRequest(ctx, pb.InternalRaftRequest{AuthRoleGet: r}) + if err != nil { + return nil, err + } + if result.err != nil { + return nil, result.err + } + return result.resp.(*pb.AuthRoleGetResponse), nil +} + +func (s *EtcdServer) RoleList(ctx context.Context, r *pb.AuthRoleListRequest) (*pb.AuthRoleListResponse, error) { + result, err := s.processInternalRaftRequest(ctx, pb.InternalRaftRequest{AuthRoleList: r}) + if err != nil { + return nil, err + } + if result.err != nil { + return nil, result.err + } + return result.resp.(*pb.AuthRoleListResponse), nil +} + +func (s *EtcdServer) RoleRevokePermission(ctx context.Context, r *pb.AuthRoleRevokePermissionRequest) (*pb.AuthRoleRevokePermissionResponse, error) { + result, err := s.processInternalRaftRequest(ctx, pb.InternalRaftRequest{AuthRoleRevokePermission: r}) + if err != nil { + return nil, err + } + if result.err != nil { + return nil, result.err + } + return result.resp.(*pb.AuthRoleRevokePermissionResponse), nil +} + +func (s *EtcdServer) RoleDelete(ctx context.Context, r *pb.AuthRoleDeleteRequest) (*pb.AuthRoleDeleteResponse, error) { + result, err := s.processInternalRaftRequest(ctx, pb.InternalRaftRequest{AuthRoleDelete: r}) + if err != nil { + return nil, err + } + if result.err != nil { + return nil, result.err + } + 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 + } + + time.Sleep(100 * time.Millisecond) + } + + 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 + } + + 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) + if err != nil { + return nil, err + } + r.Header.Username = username + + data, err := r.Marshal() + if err != nil { + return nil, err + } + + if len(data) > maxRequestBytes { + return nil, ErrRequestTooLarge + } + + id := r.ID + if id == 0 { + id = r.Header.ID + } + ch := s.w.Register(id) + + cctx, cancel := context.WithTimeout(ctx, maxV3RequestTimeout) + defer cancel() + + start := time.Now() + s.r.Propose(cctx, data) + proposalsPending.Inc() + defer proposalsPending.Dec() + + select { + case x := <-ch: + return x.(*applyResult), nil + case <-cctx.Done(): + proposalsFailed.Inc() + s.w.Trigger(id, nil) // GC wait + return nil, s.parseProposeCtxErr(cctx.Err(), start) + case <-s.done: + return nil, ErrStopped + } +} + +// Watchable returns a watchable interface attached to the etcdserver. +func (s *EtcdServer) Watchable() mvcc.Watchable { return s.KV() } diff --git a/vendor/github.com/coreos/etcd/etcdserver/v3demo_server.go b/vendor/github.com/coreos/etcd/etcdserver/v3demo_server.go deleted file mode 100644 index eb81e2b8941..00000000000 --- a/vendor/github.com/coreos/etcd/etcdserver/v3demo_server.go +++ /dev/null @@ -1,273 +0,0 @@ -// Copyright 2015 CoreOS, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// 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 etcdserver - -import ( - "time" - - pb "github.com/coreos/etcd/etcdserver/etcdserverpb" - "github.com/coreos/etcd/lease" - "github.com/coreos/etcd/lease/leasehttp" - dstorage "github.com/coreos/etcd/storage" - "golang.org/x/net/context" -) - -const ( - // the max request size that raft accepts. - // TODO: make this a flag? But we probably do not want to - // accept large request which might block raft stream. User - // specify a large value might end up with shooting in the foot. - maxRequestBytes = 1.5 * 1024 * 1024 -) - -type RaftKV interface { - Range(ctx context.Context, r *pb.RangeRequest) (*pb.RangeResponse, error) - Put(ctx context.Context, r *pb.PutRequest) (*pb.PutResponse, error) - DeleteRange(ctx context.Context, r *pb.DeleteRangeRequest) (*pb.DeleteRangeResponse, error) - Txn(ctx context.Context, r *pb.TxnRequest) (*pb.TxnResponse, error) - Compact(ctx context.Context, r *pb.CompactionRequest) (*pb.CompactionResponse, error) -} - -type Lessor interface { - // LeaseGrant sends LeaseGrant request to raft and apply it after committed. - LeaseGrant(ctx context.Context, r *pb.LeaseGrantRequest) (*pb.LeaseGrantResponse, error) - // LeaseRevoke sends LeaseRevoke request to raft and apply it after committed. - LeaseRevoke(ctx context.Context, r *pb.LeaseRevokeRequest) (*pb.LeaseRevokeResponse, error) - - // LeaseRenew renews the lease with given ID. The renewed TTL is returned. Or an error - // is returned. - LeaseRenew(id lease.LeaseID) (int64, error) -} - -type Authenticator interface { - AuthEnable(ctx context.Context, r *pb.AuthEnableRequest) (*pb.AuthEnableResponse, error) - UserAdd(ctx context.Context, r *pb.AuthUserAddRequest) (*pb.AuthUserAddResponse, error) - UserDelete(ctx context.Context, r *pb.AuthUserDeleteRequest) (*pb.AuthUserDeleteResponse, error) - UserChangePassword(ctx context.Context, r *pb.AuthUserChangePasswordRequest) (*pb.AuthUserChangePasswordResponse, error) - RoleAdd(ctx context.Context, r *pb.AuthRoleAddRequest) (*pb.AuthRoleAddResponse, error) -} - -func (s *EtcdServer) Range(ctx context.Context, r *pb.RangeRequest) (*pb.RangeResponse, error) { - if r.Serializable { - return s.applyV3.Range(noTxn, r) - } - - result, err := s.processInternalRaftRequest(ctx, pb.InternalRaftRequest{Range: r}) - if err != nil { - return nil, err - } - return result.resp.(*pb.RangeResponse), result.err -} - -func (s *EtcdServer) Put(ctx context.Context, r *pb.PutRequest) (*pb.PutResponse, error) { - result, err := s.processInternalRaftRequest(ctx, pb.InternalRaftRequest{Put: r}) - if err != nil { - return nil, err - } - return result.resp.(*pb.PutResponse), result.err -} - -func (s *EtcdServer) DeleteRange(ctx context.Context, r *pb.DeleteRangeRequest) (*pb.DeleteRangeResponse, error) { - result, err := s.processInternalRaftRequest(ctx, pb.InternalRaftRequest{DeleteRange: r}) - if err != nil { - return nil, err - } - return result.resp.(*pb.DeleteRangeResponse), result.err -} - -func (s *EtcdServer) Txn(ctx context.Context, r *pb.TxnRequest) (*pb.TxnResponse, error) { - if isTxnSerializable(r) { - return s.applyV3.Txn(r) - } - - result, err := s.processInternalRaftRequest(ctx, pb.InternalRaftRequest{Txn: r}) - if err != nil { - return nil, err - } - return result.resp.(*pb.TxnResponse), result.err -} - -func isTxnSerializable(r *pb.TxnRequest) bool { - for _, u := range r.Success { - if r := u.GetRequestRange(); r == nil || !r.Serializable { - return false - } - } - for _, u := range r.Failure { - if r := u.GetRequestRange(); r == nil || !r.Serializable { - 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}) - if r.Physical && result.physc != nil { - <-result.physc - // The compaction is done deleting keys; the hash is now settled - // but the data is not necessarily committed. If there's a crash, - // the hash may revert to a hash prior to compaction completing - // if the compaction resumes. Force the finished compaction to - // commit so it won't resume following a crash. - s.be.ForceCommit() - } - if err != nil { - return nil, err - } - resp := result.resp.(*pb.CompactionResponse) - if resp == nil { - resp = &pb.CompactionResponse{} - } - if resp.Header == nil { - resp.Header = &pb.ResponseHeader{} - } - resp.Header.Revision = s.kv.Rev() - return resp, result.err -} - -func (s *EtcdServer) LeaseGrant(ctx context.Context, r *pb.LeaseGrantRequest) (*pb.LeaseGrantResponse, error) { - // no id given? choose one - for r.ID == int64(lease.NoLease) { - // only use positive int64 id's - r.ID = int64(s.reqIDGen.Next() & ((1 << 63) - 1)) - } - result, err := s.processInternalRaftRequest(ctx, pb.InternalRaftRequest{LeaseGrant: r}) - if err != nil { - return nil, err - } - return result.resp.(*pb.LeaseGrantResponse), result.err -} - -func (s *EtcdServer) LeaseRevoke(ctx context.Context, r *pb.LeaseRevokeRequest) (*pb.LeaseRevokeResponse, error) { - result, err := s.processInternalRaftRequest(ctx, pb.InternalRaftRequest{LeaseRevoke: r}) - if err != nil { - return nil, err - } - return result.resp.(*pb.LeaseRevokeResponse), result.err -} - -func (s *EtcdServer) LeaseRenew(id lease.LeaseID) (int64, error) { - ttl, err := s.lessor.Renew(id) - if err == nil { - return ttl, nil - } - if err != lease.ErrNotPrimary { - return -1, err - } - - // renewals don't go through raft; forward to leader manually - leader := s.cluster.Member(s.Leader()) - for i := 0; i < 5 && leader == nil; i++ { - // wait an election - dur := time.Duration(s.cfg.ElectionTicks) * time.Duration(s.cfg.TickMs) * time.Millisecond - select { - case <-time.After(dur): - leader = s.cluster.Member(s.Leader()) - case <-s.done: - return -1, ErrStopped - } - } - if leader == nil || len(leader.PeerURLs) == 0 { - return -1, ErrNoLeader - } - - for _, url := range leader.PeerURLs { - lurl := url + "/leases" - ttl, err = leasehttp.RenewHTTP(id, lurl, s.peerRt, s.cfg.peerDialTimeout()) - if err == nil { - break - } - } - return ttl, err -} - -func (s *EtcdServer) Alarm(ctx context.Context, r *pb.AlarmRequest) (*pb.AlarmResponse, error) { - result, err := s.processInternalRaftRequest(ctx, pb.InternalRaftRequest{Alarm: r}) - if err != nil { - return nil, err - } - return result.resp.(*pb.AlarmResponse), result.err -} - -func (s *EtcdServer) AuthEnable(ctx context.Context, r *pb.AuthEnableRequest) (*pb.AuthEnableResponse, error) { - result, err := s.processInternalRaftRequest(ctx, pb.InternalRaftRequest{AuthEnable: r}) - if err != nil { - return nil, err - } - return result.resp.(*pb.AuthEnableResponse), result.err -} - -func (s *EtcdServer) UserAdd(ctx context.Context, r *pb.AuthUserAddRequest) (*pb.AuthUserAddResponse, error) { - result, err := s.processInternalRaftRequest(ctx, pb.InternalRaftRequest{AuthUserAdd: r}) - if err != nil { - return nil, err - } - return result.resp.(*pb.AuthUserAddResponse), result.err -} - -func (s *EtcdServer) UserDelete(ctx context.Context, r *pb.AuthUserDeleteRequest) (*pb.AuthUserDeleteResponse, error) { - result, err := s.processInternalRaftRequest(ctx, pb.InternalRaftRequest{AuthUserDelete: r}) - if err != nil { - return nil, err - } - return result.resp.(*pb.AuthUserDeleteResponse), result.err -} - -func (s *EtcdServer) UserChangePassword(ctx context.Context, r *pb.AuthUserChangePasswordRequest) (*pb.AuthUserChangePasswordResponse, error) { - result, err := s.processInternalRaftRequest(ctx, pb.InternalRaftRequest{AuthUserChangePassword: r}) - if err != nil { - return nil, err - } - return result.resp.(*pb.AuthUserChangePasswordResponse), result.err -} - -func (s *EtcdServer) RoleAdd(ctx context.Context, r *pb.AuthRoleAddRequest) (*pb.AuthRoleAddResponse, error) { - result, err := s.processInternalRaftRequest(ctx, pb.InternalRaftRequest{AuthRoleAdd: r}) - if err != nil { - return nil, err - } - return result.resp.(*pb.AuthRoleAddResponse), result.err -} - -func (s *EtcdServer) processInternalRaftRequest(ctx context.Context, r pb.InternalRaftRequest) (*applyResult, error) { - r.ID = s.reqIDGen.Next() - - data, err := r.Marshal() - if err != nil { - return nil, err - } - - if len(data) > maxRequestBytes { - return nil, ErrRequestTooLarge - } - - ch := s.w.Register(r.ID) - - s.r.Propose(ctx, data) - - select { - case x := <-ch: - return x.(*applyResult), nil - case <-ctx.Done(): - s.w.Trigger(r.ID, nil) // GC wait - return nil, ctx.Err() - case <-s.done: - return nil, ErrStopped - } -} - -// Watchable returns a watchable interface attached to the etcdserver. -func (s *EtcdServer) Watchable() dstorage.Watchable { return s.KV() } diff --git a/vendor/github.com/coreos/etcd/integration/bridge.go b/vendor/github.com/coreos/etcd/integration/bridge.go new file mode 100644 index 00000000000..e46397ca895 --- /dev/null +++ b/vendor/github.com/coreos/etcd/integration/bridge.go @@ -0,0 +1,138 @@ +// 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 integration + +import ( + "fmt" + "io" + "net" + "sync" + + "github.com/coreos/etcd/pkg/transport" +) + +// bridge creates a unix socket bridge to another unix socket, making it possible +// to disconnect grpc network connections without closing the logical grpc connection. +type bridge struct { + inaddr string + outaddr string + l net.Listener + conns map[*bridgeConn]struct{} + + stopc chan struct{} + wg sync.WaitGroup + + mu sync.Mutex +} + +func newBridge(addr string) (*bridge, error) { + b := &bridge{ + inaddr: addr + ".bridge", + outaddr: addr, + conns: make(map[*bridgeConn]struct{}), + stopc: make(chan struct{}, 1), + } + l, err := transport.NewUnixListener(b.inaddr) + if err != nil { + return nil, fmt.Errorf("listen failed on socket %s (%v)", addr, err) + } + b.l = l + b.wg.Add(1) + go b.serveListen() + return b, nil +} + +func (b *bridge) URL() string { return "unix://" + b.inaddr } + +func (b *bridge) Close() { + b.l.Close() + select { + case b.stopc <- struct{}{}: + default: + } + b.wg.Wait() +} + +func (b *bridge) Reset() { + b.mu.Lock() + defer b.mu.Unlock() + for bc := range b.conns { + bc.Close() + } + b.conns = make(map[*bridgeConn]struct{}) +} + +func (b *bridge) serveListen() { + defer func() { + b.l.Close() + b.mu.Lock() + for bc := range b.conns { + bc.Close() + } + b.mu.Unlock() + b.wg.Done() + }() + + for { + inc, ierr := b.l.Accept() + if ierr != nil { + return + } + outc, oerr := net.Dial("unix", b.outaddr) + if oerr != nil { + inc.Close() + return + } + + bc := &bridgeConn{inc, outc} + b.wg.Add(1) + b.mu.Lock() + b.conns[bc] = struct{}{} + go b.serveConn(bc) + b.mu.Unlock() + } +} + +func (b *bridge) serveConn(bc *bridgeConn) { + defer func() { + bc.Close() + b.mu.Lock() + delete(b.conns, bc) + b.mu.Unlock() + b.wg.Done() + }() + + var wg sync.WaitGroup + wg.Add(2) + go func() { + io.Copy(bc.out, bc.in) + wg.Done() + }() + go func() { + io.Copy(bc.in, bc.out) + wg.Done() + }() + wg.Wait() +} + +type bridgeConn struct { + in net.Conn + out net.Conn +} + +func (bc *bridgeConn) Close() { + bc.in.Close() + bc.out.Close() +} diff --git a/vendor/github.com/coreos/etcd/integration/cluster.go b/vendor/github.com/coreos/etcd/integration/cluster.go index 4798aeb707e..4b34bf494f5 100644 --- a/vendor/github.com/coreos/etcd/integration/cluster.go +++ b/vendor/github.com/coreos/etcd/integration/cluster.go @@ -1,4 +1,4 @@ -// Copyright 2016 CoreOS, Inc. +// 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. @@ -25,8 +25,8 @@ import ( "os" "reflect" "sort" - "strconv" "strings" + "sync" "sync/atomic" "testing" "time" @@ -37,6 +37,7 @@ import ( "github.com/coreos/etcd/client" "github.com/coreos/etcd/clientv3" "github.com/coreos/etcd/etcdserver" + "github.com/coreos/etcd/etcdserver/api" "github.com/coreos/etcd/etcdserver/api/v2http" "github.com/coreos/etcd/etcdserver/api/v3rpc" pb "github.com/coreos/etcd/etcdserver/etcdserverpb" @@ -44,20 +45,25 @@ import ( "github.com/coreos/etcd/pkg/transport" "github.com/coreos/etcd/pkg/types" "github.com/coreos/etcd/rafthttp" + "github.com/coreos/pkg/capnslog" ) const ( tickDuration = 10 * time.Millisecond clusterName = "etcd" requestTimeout = 20 * time.Second + + basePort = 21000 + UrlScheme = "unix" + UrlSchemeTLS = "unixs" ) var ( electionTicks = 10 - // integration test uses well-known ports to listen for each running member, - // which ensures restarted member could listen on specific port again. - nextListenPort int64 = 20000 + // integration test uses unique ports, counting up, to listen for each + // member, ensuring restarted members can listen on the same port again. + localListenCount int64 = 0 testTLSInfo = transport.TLSInfo{ KeyFile: "./fixtures/server.key.insecure", @@ -65,14 +71,17 @@ var ( TrustedCAFile: "./fixtures/ca.crt", ClientCertAuth: true, } + + plog = capnslog.NewPackageLogger("github.com/coreos/etcd", "integration") ) type ClusterConfig struct { - Size int - PeerTLS *transport.TLSInfo - ClientTLS *transport.TLSInfo - DiscoveryURL string - UseGRPC bool + Size int + PeerTLS *transport.TLSInfo + ClientTLS *transport.TLSInfo + DiscoveryURL string + UseGRPC bool + QuotaBackendBytes int64 } type cluster struct { @@ -80,6 +89,18 @@ type cluster struct { Members []*member } +func init() { + // manually enable v3 capability since we know the cluster members all support v3. + api.EnableCapability(api.V3rpcCapability) +} + +func schemeFromTLSInfo(tls *transport.TLSInfo) string { + if tls == nil { + return UrlScheme + } + return UrlSchemeTLS +} + func (c *cluster) fillClusterForMembers() error { if c.cfg.DiscoveryURL != "" { // cluster will be discovered @@ -88,10 +109,7 @@ func (c *cluster) fillClusterForMembers() error { addrs := make([]string, 0) for _, m := range c.Members { - scheme := "http" - if m.PeerTLSInfo != nil { - scheme = "https" - } + scheme := schemeFromTLSInfo(m.PeerTLSInfo) for _, l := range m.PeerListeners { addrs = append(addrs, fmt.Sprintf("%s=%s://%s", m.Name, scheme, l.Addr().String())) } @@ -175,13 +193,8 @@ func (c *cluster) URLs() []string { func (c *cluster) HTTPMembers() []client.Member { ms := []client.Member{} for _, m := range c.Members { - pScheme, cScheme := "http", "http" - if m.PeerTLSInfo != nil { - pScheme = "https" - } - if m.ClientTLSInfo != nil { - cScheme = "https" - } + pScheme := schemeFromTLSInfo(m.PeerTLSInfo) + cScheme := schemeFromTLSInfo(m.ClientTLSInfo) cm := client.Member{Name: m.Name} for _, ln := range m.PeerListeners { cm.PeerURLs = append(cm.PeerURLs, pScheme+"://"+ln.Addr().String()) @@ -195,8 +208,13 @@ func (c *cluster) HTTPMembers() []client.Member { } func (c *cluster) mustNewMember(t *testing.T) *member { - name := c.name(rand.Int()) - m := mustNewMember(t, name, c.cfg.PeerTLS, c.cfg.ClientTLS) + m := mustNewMember(t, + memberConfig{ + name: c.name(rand.Int()), + peerTLS: c.cfg.PeerTLS, + clientTLS: c.cfg.ClientTLS, + quotaBackendBytes: c.cfg.QuotaBackendBytes, + }) m.DiscoveryURL = c.cfg.DiscoveryURL if c.cfg.UseGRPC { if err := m.listenGRPC(); err != nil { @@ -209,10 +227,7 @@ func (c *cluster) mustNewMember(t *testing.T) *member { func (c *cluster) addMember(t *testing.T) { m := c.mustNewMember(t) - scheme := "http" - if c.cfg.PeerTLS != nil { - scheme = "https" - } + scheme := schemeFromTLSInfo(c.cfg.PeerTLS) // send add request to the cluster var err error @@ -242,7 +257,7 @@ func (c *cluster) addMember(t *testing.T) { } func (c *cluster) addMemberByURL(t *testing.T, clientURL, peerURL string) error { - cc := mustNewHTTPClient(t, []string{clientURL}, c.cfg.ClientTLS) + cc := MustNewHTTPClient(t, []string{clientURL}, c.cfg.ClientTLS) ma := client.NewMembersAPI(cc) ctx, cancel := context.WithTimeout(context.Background(), requestTimeout) if _, err := ma.Add(ctx, peerURL); err != nil { @@ -262,7 +277,7 @@ func (c *cluster) AddMember(t *testing.T) { func (c *cluster) RemoveMember(t *testing.T, id uint64) { // send remove request to the cluster - cc := mustNewHTTPClient(t, c.URLs(), c.cfg.ClientTLS) + 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 { @@ -297,7 +312,7 @@ func (c *cluster) Terminate(t *testing.T) { func (c *cluster) waitMembersMatch(t *testing.T, membs []client.Member) { for _, u := range c.URLs() { - cc := mustNewHTTPClient(t, []string{u}, c.cfg.ClientTLS) + cc := MustNewHTTPClient(t, []string{u}, c.cfg.ClientTLS) ma := client.NewMembersAPI(cc) for { ctx, cancel := context.WithTimeout(context.Background(), requestTimeout) @@ -312,6 +327,8 @@ func (c *cluster) waitMembersMatch(t *testing.T, membs []client.Member) { return } +func (c *cluster) WaitLeader(t *testing.T) int { return c.waitLeader(t, c.Members) } + func (c *cluster) waitLeader(t *testing.T, membs []*member) int { possibleLead := make(map[uint64]bool) var lead uint64 @@ -329,11 +346,11 @@ func (c *cluster) waitLeader(t *testing.T, membs []*member) int { } if lead != 0 && lead != m.s.Lead() { lead = 0 + time.Sleep(10 * tickDuration) break } lead = m.s.Lead() } - time.Sleep(10 * tickDuration) } for i, m := range membs { @@ -372,26 +389,13 @@ func isMembersEqual(membs []client.Member, wmembs []client.Member) bool { } func newLocalListener(t *testing.T) net.Listener { - port := atomic.AddInt64(&nextListenPort, 1) - l, err := net.Listen("tcp", "127.0.0.1:"+strconv.FormatInt(port, 10)) - if err != nil { - t.Fatal(err) - } - return l + c := atomic.AddInt64(&localListenCount, 1) + addr := fmt.Sprintf("127.0.0.1:%d.%d.sock", c+basePort, os.Getpid()) + return NewListenerWithAddr(t, addr) } -func newListenerWithAddr(t *testing.T, addr string) net.Listener { - var err error - var l net.Listener - // TODO: we want to reuse a previous closed port immediately. - // a better way is to set SO_REUSExx instead of doing retry. - for i := 0; i < 5; i++ { - l, err = net.Listen("tcp", addr) - if err == nil { - break - } - time.Sleep(500 * time.Millisecond) - } +func NewListenerWithAddr(t *testing.T, addr string) net.Listener { + l, err := transport.NewUnixListener(addr) if err != nil { t.Fatal(err) } @@ -413,21 +417,26 @@ type member struct { grpcServer *grpc.Server grpcAddr string + grpcBridge *bridge +} + +func (m *member) GRPCAddr() string { return m.grpcAddr } + +type memberConfig struct { + name string + peerTLS *transport.TLSInfo + clientTLS *transport.TLSInfo + quotaBackendBytes int64 } // mustNewMember return an inited member with the given name. If peerTLS is // set, it will use https scheme to communicate between peers. -func mustNewMember(t *testing.T, name string, peerTLS *transport.TLSInfo, clientTLS *transport.TLSInfo) *member { +func mustNewMember(t *testing.T, mcfg memberConfig) *member { var err error m := &member{} - peerScheme, clientScheme := "http", "http" - if peerTLS != nil { - peerScheme = "https" - } - if clientTLS != nil { - clientScheme = "https" - } + peerScheme := schemeFromTLSInfo(mcfg.peerTLS) + clientScheme := schemeFromTLSInfo(mcfg.clientTLS) pln := newLocalListener(t) m.PeerListeners = []net.Listener{pln} @@ -435,7 +444,7 @@ func mustNewMember(t *testing.T, name string, peerTLS *transport.TLSInfo, client if err != nil { t.Fatal(err) } - m.PeerTLSInfo = peerTLS + m.PeerTLSInfo = mcfg.peerTLS cln := newLocalListener(t) m.ClientListeners = []net.Listener{cln} @@ -443,15 +452,15 @@ func mustNewMember(t *testing.T, name string, peerTLS *transport.TLSInfo, client if err != nil { t.Fatal(err) } - m.ClientTLSInfo = clientTLS + m.ClientTLSInfo = mcfg.clientTLS - m.Name = name + m.Name = mcfg.name m.DataDir, err = ioutil.TempDir(os.TempDir(), "etcd") if err != nil { t.Fatal(err) } - clusterStr := fmt.Sprintf("%s=%s://%s", name, peerScheme, pln.Addr().String()) + clusterStr := fmt.Sprintf("%s=%s://%s", mcfg.name, peerScheme, pln.Addr().String()) m.InitialPeerURLsMap, err = types.NewURLsMap(clusterStr) if err != nil { t.Fatal(err) @@ -464,6 +473,7 @@ func mustNewMember(t *testing.T, name string, peerTLS *transport.TLSInfo, client } m.ElectionTicks = electionTicks m.TickMs = uint(tickDuration / time.Millisecond) + m.QuotaBackendBytes = mcfg.quotaBackendBytes return m } @@ -471,18 +481,22 @@ func mustNewMember(t *testing.T, name string, peerTLS *transport.TLSInfo, client func (m *member) listenGRPC() error { // prefix with localhost so cert has right domain m.grpcAddr = "localhost:" + m.Name + ".sock" - if err := os.RemoveAll(m.grpcAddr); err != nil { - return err - } - l, err := net.Listen("unix", m.grpcAddr) + l, err := transport.NewUnixListener(m.grpcAddr) if err != nil { return fmt.Errorf("listen failed on grpc socket %s (%v)", m.grpcAddr, err) } - m.grpcAddr = "unix://" + m.grpcAddr + m.grpcBridge, err = newBridge(m.grpcAddr) + if err != nil { + l.Close() + return err + } + m.grpcAddr = m.grpcBridge.URL() m.grpcListener = l return nil } +func (m *member) DropConnections() { m.grpcBridge.Reset() } + // NewClientV3 creates a new grpc client connection to the member func NewClientV3(m *member) (*clientv3.Client, error) { if m.grpcAddr == "" { @@ -539,6 +553,7 @@ func (m *member) Clone(t *testing.T) *member { // Launch starts a member based on ServerConfig, PeerListeners // and ClientListeners. func (m *member) Launch() error { + plog.Printf("launching %s (%s)", m.Name, m.grpcAddr) var err error if m.s, err = etcdserver.NewServer(&m.ServerConfig); err != nil { return fmt.Errorf("failed to initialize the etcd server: %v", err) @@ -593,11 +608,13 @@ func (m *member) Launch() error { m.grpcServer = v3rpc.Server(m.s, tlscfg) go m.grpcServer.Serve(m.grpcListener) } + + plog.Printf("launched %s (%s)", m.Name, m.grpcAddr) return nil } func (m *member) WaitOK(t *testing.T) { - cc := mustNewHTTPClient(t, []string{m.URL()}, m.ClientTLSInfo) + cc := MustNewHTTPClient(t, []string{m.URL()}, m.ClientTLSInfo) kapi := client.NewKeysAPI(cc) for { ctx, cancel := context.WithTimeout(context.Background(), requestTimeout) @@ -628,6 +645,10 @@ func (m *member) Resume() { // Close stops the member's etcdserver and closes its connections func (m *member) Close() { + if m.grpcBridge != nil { + m.grpcBridge.Close() + m.grpcBridge = nil + } if m.grpcServer != nil { m.grpcServer.Stop() m.grpcServer = nil @@ -641,8 +662,10 @@ func (m *member) Close() { // Stop stops the member, but the data dir of the member is preserved. func (m *member) Stop(t *testing.T) { + plog.Printf("stopping %s (%s)", m.Name, m.grpcAddr) m.Close() m.hss = nil + plog.Printf("stopped %s (%s)", m.Name, m.grpcAddr) } // StopNotify unblocks when a member stop completes @@ -652,14 +675,15 @@ func (m *member) StopNotify() <-chan struct{} { // Restart starts the member using the preserved data dir. func (m *member) Restart(t *testing.T) error { + plog.Printf("restarting %s (%s)", m.Name, m.grpcAddr) newPeerListeners := make([]net.Listener, 0) for _, ln := range m.PeerListeners { - newPeerListeners = append(newPeerListeners, newListenerWithAddr(t, ln.Addr().String())) + newPeerListeners = append(newPeerListeners, NewListenerWithAddr(t, ln.Addr().String())) } m.PeerListeners = newPeerListeners newClientListeners := make([]net.Listener, 0) for _, ln := range m.ClientListeners { - newClientListeners = append(newClientListeners, newListenerWithAddr(t, ln.Addr().String())) + newClientListeners = append(newClientListeners, NewListenerWithAddr(t, ln.Addr().String())) } m.ClientListeners = newClientListeners @@ -669,18 +693,22 @@ func (m *member) Restart(t *testing.T) error { } } - return m.Launch() + err := m.Launch() + plog.Printf("restarted %s (%s)", m.Name, m.grpcAddr) + return err } // Terminate stops the member and removes the data dir. 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) } + plog.Printf("terminated %s (%s)", m.Name, m.grpcAddr) } -func mustNewHTTPClient(t *testing.T, eps []string, tls *transport.TLSInfo) client.Client { +func MustNewHTTPClient(t *testing.T, eps []string, tls *transport.TLSInfo) client.Client { cfgtls := transport.TLSInfo{} if tls != nil { cfgtls = *tls @@ -712,6 +740,8 @@ func (p SortableMemberSliceByPeerURLs) Swap(i, j int) { p[i], p[j] = p[j], p[i] type ClusterV3 struct { *cluster + + mu sync.Mutex clients []*clientv3.Client } @@ -719,24 +749,38 @@ type ClusterV3 struct { // for each cluster member. func NewClusterV3(t *testing.T, cfg *ClusterConfig) *ClusterV3 { cfg.UseGRPC = true - clus := &ClusterV3{cluster: NewClusterByConfig(t, cfg)} + clus := &ClusterV3{ + cluster: NewClusterByConfig(t, cfg), + } for _, m := range clus.Members { client, err := NewClientV3(m) if err != nil { - t.Fatal(err) + t.Fatalf("cannot create client: %v", err) } clus.clients = append(clus.clients, client) } clus.Launch(t) + return clus } +func (c *ClusterV3) TakeClient(idx int) { + c.mu.Lock() + c.clients[idx] = nil + c.mu.Unlock() +} + func (c *ClusterV3) Terminate(t *testing.T) { + c.mu.Lock() for _, client := range c.clients { + if client == nil { + continue + } if err := client.Close(); err != nil { t.Error(err) } } + c.mu.Unlock() c.cluster.Terminate(t) } diff --git a/vendor/github.com/coreos/etcd/integration/doc.go b/vendor/github.com/coreos/etcd/integration/doc.go index 5d006637e41..fbf19d54368 100644 --- a/vendor/github.com/coreos/etcd/integration/doc.go +++ b/vendor/github.com/coreos/etcd/integration/doc.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. diff --git a/vendor/github.com/coreos/etcd/lease/doc.go b/vendor/github.com/coreos/etcd/lease/doc.go new file mode 100644 index 00000000000..73e7d0ec51a --- /dev/null +++ b/vendor/github.com/coreos/etcd/lease/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 lease provides an interface and implemetation for time-limited leases over arbitrary resources. +package lease diff --git a/vendor/github.com/coreos/etcd/lease/leasehttp/doc.go b/vendor/github.com/coreos/etcd/lease/leasehttp/doc.go new file mode 100644 index 00000000000..8177a37b663 --- /dev/null +++ b/vendor/github.com/coreos/etcd/lease/leasehttp/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 leasehttp serves lease renewals made through HTTP requests. +package leasehttp diff --git a/vendor/github.com/coreos/etcd/lease/leasehttp/http.go b/vendor/github.com/coreos/etcd/lease/leasehttp/http.go index 4cc1d183276..cf95595b6f0 100644 --- a/vendor/github.com/coreos/etcd/lease/leasehttp/http.go +++ b/vendor/github.com/coreos/etcd/lease/leasehttp/http.go @@ -1,4 +1,4 @@ -// Copyright 2016 CoreOS, Inc. +// 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. @@ -89,6 +89,7 @@ func RenewHTTP(id lease.LeaseID, url string, rt http.RoundTripper, timeout time. return -1, err } b, err := ioutil.ReadAll(resp.Body) + resp.Body.Close() if err != nil { return -1, err } 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 9c0d77124c2..62115a3c995 100644 --- a/vendor/github.com/coreos/etcd/lease/leasepb/lease.pb.go +++ b/vendor/github.com/coreos/etcd/lease/leasepb/lease.pb.go @@ -16,7 +16,7 @@ package leasepb import ( "fmt" - proto "github.com/gogo/protobuf/proto" + proto "github.com/golang/protobuf/proto" math "math" ) @@ -28,14 +28,19 @@ var _ = proto.Marshal var _ = fmt.Errorf 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 + type Lease struct { - ID int64 `protobuf:"varint,1,opt,name=ID,proto3" json:"ID,omitempty"` - TTL int64 `protobuf:"varint,2,opt,name=TTL,proto3" json:"TTL,omitempty"` + 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"` } -func (m *Lease) Reset() { *m = Lease{} } -func (m *Lease) String() string { return proto.CompactTextString(m) } -func (*Lease) ProtoMessage() {} +func (m *Lease) Reset() { *m = Lease{} } +func (m *Lease) String() string { return proto.CompactTextString(m) } +func (*Lease) ProtoMessage() {} +func (*Lease) Descriptor() ([]byte, []int) { return fileDescriptorLease, []int{0} } func init() { proto.RegisterType((*Lease)(nil), "leasepb.Lease") @@ -312,3 +317,15 @@ var ( ErrInvalidLengthLease = fmt.Errorf("proto: negative length found during unmarshaling") ErrIntOverflowLease = fmt.Errorf("proto: integer overflow") ) + +var fileDescriptorLease = []byte{ + // 126 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, +} diff --git a/vendor/github.com/coreos/etcd/lease/lessor.go b/vendor/github.com/coreos/etcd/lease/lessor.go index 268eb8b497c..13c3f1b128e 100644 --- a/vendor/github.com/coreos/etcd/lease/lessor.go +++ b/vendor/github.com/coreos/etcd/lease/lessor.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. @@ -22,7 +22,7 @@ import ( "time" "github.com/coreos/etcd/lease/leasepb" - "github.com/coreos/etcd/storage/backend" + "github.com/coreos/etcd/mvcc/backend" ) const ( @@ -47,14 +47,14 @@ type LeaseID int64 // RangeDeleter defines an interface with DeleteRange method. // We define this interface only for lessor to limit the number -// of methods of storage.KV to what lessor actually needs. +// of methods of mvcc.KV to what lessor actually needs. // // Having a minimum interface makes testing easy. type RangeDeleter interface { DeleteRange(key, end []byte) (int64, int64) } -// A Lessor is the owner of leases. It can grant, revoke, renew and modify leases for lessee. +// Lessor owns leases. It can grant, revoke, renew and modify leases for lessee. type Lessor interface { // SetRangeDeleter sets the RangeDeleter to the Lessor. // Lessor deletes the items in the revoked or expired lease from the @@ -172,13 +172,13 @@ func (le *lessor) SetRangeDeleter(rd RangeDeleter) { le.rd = rd } -// TODO: when lessor is under high load, it should give out lease -// with longer TTL to reduce renew load. func (le *lessor) Grant(id LeaseID, ttl int64) (*Lease, error) { if id == NoLease { return nil, ErrLeaseNotFound } + // 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{})} le.mu.Lock() diff --git a/vendor/github.com/coreos/etcd/storage/backend/backend.go b/vendor/github.com/coreos/etcd/mvcc/backend/backend.go similarity index 85% rename from vendor/github.com/coreos/etcd/storage/backend/backend.go rename to vendor/github.com/coreos/etcd/mvcc/backend/backend.go index 05c22162b68..51b89021d8b 100644 --- a/vendor/github.com/coreos/etcd/storage/backend/backend.go +++ b/vendor/github.com/coreos/etcd/mvcc/backend/backend.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. @@ -19,7 +19,6 @@ import ( "hash/crc32" "io" "io/ioutil" - "log" "os" "path" "sync" @@ -27,6 +26,7 @@ import ( "time" "github.com/boltdb/bolt" + "github.com/coreos/pkg/capnslog" ) var ( @@ -39,6 +39,8 @@ var ( // the potential max db size can prevent writer from blocking reader. // This only works for linux. InitialMmapSize = int64(10 * 1024 * 1024 * 1024) + + plog = capnslog.NewPackageLogger("github.com/coreos/etcd/mvcc", "backend") ) const ( @@ -53,7 +55,7 @@ const ( type Backend interface { BatchTx() BatchTx Snapshot() Snapshot - Hash() (uint32, error) + Hash(ignores map[IgnoreKey]struct{}) (uint32, error) // Size returns the current size of the backend. Size() int64 Defrag() error @@ -101,7 +103,7 @@ func NewDefaultBackend(path string) Backend { func newBackend(path string, d time.Duration, limit int) *backend { db, err := bolt.Open(path, 0600, boltOpenOptions) if err != nil { - log.Panicf("backend: cannot open database at %s (%v)", path, err) + plog.Panicf("cannot open database at %s (%v)", path, err) } b := &backend{ @@ -137,12 +139,17 @@ func (b *backend) Snapshot() Snapshot { defer b.mu.RUnlock() tx, err := b.db.Begin(false) if err != nil { - log.Fatalf("backend: cannot begin tx (%s)", err) + plog.Fatalf("cannot begin tx (%s)", err) } return &snapshot{tx} } -func (b *backend) Hash() (uint32, error) { +type IgnoreKey struct { + Bucket string + Key string +} + +func (b *backend) Hash(ignores map[IgnoreKey]struct{}) (uint32, error) { h := crc32.New(crc32.MakeTable(crc32.Castagnoli)) b.mu.RLock() @@ -156,8 +163,11 @@ func (b *backend) Hash() (uint32, error) { } h.Write(next) b.ForEach(func(k, v []byte) error { - h.Write(k) - h.Write(v) + bk := IgnoreKey{Bucket: string(next), Key: string(k)} + if _, ok := ignores[bk]; !ok { + h.Write(k) + h.Write(v) + } return nil }) } @@ -177,15 +187,17 @@ func (b *backend) Size() int64 { func (b *backend) run() { defer close(b.donec) - + t := time.NewTimer(b.batchInterval) + defer t.Stop() for { select { - case <-time.After(b.batchInterval): + case <-t.C: case <-b.stopc: b.batchTx.CommitAndStop() return } b.batchTx.Commit() + t.Reset(b.batchInterval) } } @@ -201,6 +213,18 @@ func (b *backend) Commits() int64 { } func (b *backend) Defrag() error { + err := b.defrag() + if err != nil { + return err + } + + // commit to update metadata like db.size + b.batchTx.Commit() + + return nil +} + +func (b *backend) defrag() error { // TODO: make this non-blocking? // lock batchTx to ensure nobody is using previous tx, and then // close previous ongoing tx. @@ -232,24 +256,24 @@ func (b *backend) Defrag() error { err = b.db.Close() if err != nil { - log.Fatalf("backend: cannot close database (%s)", err) + plog.Fatalf("cannot close database (%s)", err) } err = tmpdb.Close() if err != nil { - log.Fatalf("backend: cannot close database (%s)", err) + plog.Fatalf("cannot close database (%s)", err) } err = os.Rename(tdbp, dbp) if err != nil { - log.Fatalf("backend: cannot rename database (%s)", err) + plog.Fatalf("cannot rename database (%s)", err) } b.db, err = bolt.Open(dbp, 0600, boltOpenOptions) if err != nil { - log.Panicf("backend: cannot open database at %s (%v)", dbp, err) + plog.Panicf("cannot open database at %s (%v)", dbp, err) } b.batchTx.tx, err = b.db.Begin(true) if err != nil { - log.Fatalf("backend: cannot begin tx (%s)", err) + plog.Fatalf("cannot begin tx (%s)", err) } return nil @@ -297,11 +321,7 @@ func defragdb(odb, tmpdb *bolt.DB, limit int) error { tmpb = tmptx.Bucket(next) count = 0 } - err = tmpb.Put(k, v) - if err != nil { - return err - } - return nil + return tmpb.Put(k, v) }) } @@ -312,7 +332,7 @@ func defragdb(odb, tmpdb *bolt.DB, limit int) error { func NewTmpBackend(batchInterval time.Duration, batchLimit int) (*backend, string) { dir, err := ioutil.TempDir(os.TempDir(), "etcd_backend_test") if err != nil { - log.Fatal(err) + plog.Fatal(err) } tmpPath := path.Join(dir, "database") return newBackend(tmpPath, batchInterval, batchLimit), tmpPath diff --git a/vendor/github.com/coreos/etcd/storage/backend/batch_tx.go b/vendor/github.com/coreos/etcd/mvcc/backend/batch_tx.go similarity index 84% rename from vendor/github.com/coreos/etcd/storage/backend/batch_tx.go rename to vendor/github.com/coreos/etcd/mvcc/backend/batch_tx.go index d59833cd19e..e1cdcc65a92 100644 --- a/vendor/github.com/coreos/etcd/storage/backend/batch_tx.go +++ b/vendor/github.com/coreos/etcd/mvcc/backend/batch_tx.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. @@ -16,9 +16,9 @@ package backend import ( "bytes" - "log" "sync" "sync/atomic" + "time" "github.com/boltdb/bolt" ) @@ -52,7 +52,7 @@ func newBatchTx(backend *backend) *batchTx { func (t *batchTx) UnsafeCreateBucket(name []byte) { _, err := t.tx.CreateBucket(name) if err != nil && err != bolt.ErrBucketExists { - log.Fatalf("storage: cannot create bucket %s (%v)", string(name), err) + plog.Fatalf("cannot create bucket %s (%v)", name, err) } t.pending++ } @@ -70,7 +70,7 @@ func (t *batchTx) UnsafeSeqPut(bucketName []byte, key []byte, value []byte) { func (t *batchTx) unsafePut(bucketName []byte, key []byte, value []byte, seq bool) { bucket := t.tx.Bucket(bucketName) if bucket == nil { - log.Fatalf("storage: bucket %s does not exist", string(bucketName)) + plog.Fatalf("bucket %s does not exist", bucketName) } if seq { // it is useful to increase fill percent when the workloads are mostly append-only. @@ -78,7 +78,7 @@ func (t *batchTx) unsafePut(bucketName []byte, key []byte, value []byte, seq boo bucket.FillPercent = 0.9 } if err := bucket.Put(key, value); err != nil { - log.Fatalf("storage: cannot put key into bucket (%v)", err) + plog.Fatalf("cannot put key into bucket (%v)", err) } t.pending++ } @@ -87,7 +87,7 @@ func (t *batchTx) unsafePut(bucketName []byte, key []byte, value []byte, seq boo func (t *batchTx) UnsafeRange(bucketName []byte, key, endKey []byte, limit int64) (keys [][]byte, vs [][]byte) { bucket := t.tx.Bucket(bucketName) if bucket == nil { - log.Fatalf("storage: bucket %s does not exist", string(bucketName)) + plog.Fatalf("bucket %s does not exist", bucketName) } if len(endKey) == 0 { @@ -114,18 +114,23 @@ func (t *batchTx) UnsafeRange(bucketName []byte, key, endKey []byte, limit int64 func (t *batchTx) UnsafeDelete(bucketName []byte, key []byte) { bucket := t.tx.Bucket(bucketName) if bucket == nil { - log.Fatalf("storage: bucket %s does not exist", string(bucketName)) + plog.Fatalf("bucket %s does not exist", bucketName) } err := bucket.Delete(key) if err != nil { - log.Fatalf("storage: cannot delete key from bucket (%v)", err) + plog.Fatalf("cannot delete key from bucket (%v)", err) } t.pending++ } // UnsafeForEach must be called holding the lock on the tx. func (t *batchTx) UnsafeForEach(bucketName []byte, visitor func(k, v []byte) error) error { - return t.tx.Bucket(bucketName).ForEach(visitor) + b := t.tx.Bucket(bucketName) + if b == nil { + // bucket does not exist + return nil + } + return b.ForEach(visitor) } // Commit commits a previous tx and begins a new writable one. @@ -155,14 +160,19 @@ func (t *batchTx) commit(stop bool) { // commit the last tx if t.tx != nil { if t.pending == 0 && !stop { + t.backend.mu.RLock() + defer t.backend.mu.RUnlock() + atomic.StoreInt64(&t.backend.size, t.tx.Size()) return } + start := time.Now() err = t.tx.Commit() + commitDurations.Observe(time.Since(start).Seconds()) atomic.AddInt64(&t.backend.commits, 1) t.pending = 0 if err != nil { - log.Fatalf("storage: cannot commit tx (%s)", err) + plog.Fatalf("cannot commit tx (%s)", err) } } @@ -175,7 +185,7 @@ func (t *batchTx) commit(stop bool) { // begin a new tx t.tx, err = t.backend.db.Begin(true) if err != nil { - log.Fatalf("storage: cannot begin tx (%s)", err) + plog.Fatalf("cannot begin tx (%s)", err) } atomic.StoreInt64(&t.backend.size, t.tx.Size()) } diff --git a/vendor/github.com/coreos/etcd/storage/backend/boltoption_darwin.go b/vendor/github.com/coreos/etcd/mvcc/backend/boltoption_default.go similarity index 92% rename from vendor/github.com/coreos/etcd/storage/backend/boltoption_darwin.go rename to vendor/github.com/coreos/etcd/mvcc/backend/boltoption_default.go index 67269f0b55b..92019c18415 100644 --- a/vendor/github.com/coreos/etcd/storage/backend/boltoption_darwin.go +++ b/vendor/github.com/coreos/etcd/mvcc/backend/boltoption_default.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// 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. @@ -12,6 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +// +build !linux + package backend import "github.com/boltdb/bolt" diff --git a/vendor/github.com/coreos/etcd/storage/backend/boltoption_unix.go b/vendor/github.com/coreos/etcd/mvcc/backend/boltoption_linux.go similarity index 95% rename from vendor/github.com/coreos/etcd/storage/backend/boltoption_unix.go rename to vendor/github.com/coreos/etcd/mvcc/backend/boltoption_linux.go index 017f6032a48..4ee9b05a77c 100644 --- a/vendor/github.com/coreos/etcd/storage/backend/boltoption_unix.go +++ b/vendor/github.com/coreos/etcd/mvcc/backend/boltoption_linux.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. @@ -12,8 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -// +build linux - package backend import ( diff --git a/vendor/github.com/coreos/etcd/storage/backend/doc.go b/vendor/github.com/coreos/etcd/mvcc/backend/doc.go similarity index 92% rename from vendor/github.com/coreos/etcd/storage/backend/doc.go rename to vendor/github.com/coreos/etcd/mvcc/backend/doc.go index 50cd8d5cfdd..9cc42fa793c 100644 --- a/vendor/github.com/coreos/etcd/storage/backend/doc.go +++ b/vendor/github.com/coreos/etcd/mvcc/backend/doc.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. @@ -12,5 +12,5 @@ // See the License for the specific language governing permissions and // limitations under the License. -// Package backend defines a standard interface for etcd's backend storage. +// Package backend defines a standard interface for etcd's backend MVCC storage. package backend diff --git a/vendor/github.com/coreos/etcd/storage/backend/boltoption_windows.go b/vendor/github.com/coreos/etcd/mvcc/backend/metrics.go similarity index 56% rename from vendor/github.com/coreos/etcd/storage/backend/boltoption_windows.go rename to vendor/github.com/coreos/etcd/mvcc/backend/metrics.go index 1a790d10f71..34a56a91956 100644 --- a/vendor/github.com/coreos/etcd/storage/backend/boltoption_windows.go +++ b/vendor/github.com/coreos/etcd/mvcc/backend/metrics.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// 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. @@ -14,8 +14,18 @@ package backend -import "github.com/boltdb/bolt" +import "github.com/prometheus/client_golang/prometheus" -// TODO: support syscall.MAP_POPULATE in windows. -// Need upstream patch from boltdb/bolt. -var boltOpenOptions *bolt.Options = nil +var ( + commitDurations = prometheus.NewHistogram(prometheus.HistogramOpts{ + Namespace: "etcd", + Subsystem: "disk", + Name: "backend_commit_duration_seconds", + Help: "The latency distributions of commit called by backend.", + Buckets: prometheus.ExponentialBuckets(0.001, 2, 14), + }) +) + +func init() { + prometheus.MustRegister(commitDurations) +} diff --git a/vendor/github.com/coreos/etcd/storage/doc.go b/vendor/github.com/coreos/etcd/mvcc/doc.go similarity index 84% rename from vendor/github.com/coreos/etcd/storage/doc.go rename to vendor/github.com/coreos/etcd/mvcc/doc.go index 7de6851c5a9..ad5be03086f 100644 --- a/vendor/github.com/coreos/etcd/storage/doc.go +++ b/vendor/github.com/coreos/etcd/mvcc/doc.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. @@ -12,5 +12,5 @@ // See the License for the specific language governing permissions and // limitations under the License. -// Package storage defines etcd's stable storage. -package storage +// Package mvcc defines etcd's stable MVCC storage. +package mvcc diff --git a/vendor/github.com/coreos/etcd/storage/index.go b/vendor/github.com/coreos/etcd/mvcc/index.go similarity index 95% rename from vendor/github.com/coreos/etcd/storage/index.go rename to vendor/github.com/coreos/etcd/mvcc/index.go index 3b52f97b3b0..e8e489b4d68 100644 --- a/vendor/github.com/coreos/etcd/storage/index.go +++ b/vendor/github.com/coreos/etcd/mvcc/index.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. @@ -12,10 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -package storage +package mvcc import ( - "log" "sort" "sync" @@ -168,8 +167,8 @@ func (ti *treeIndex) RangeSince(key, end []byte, rev int64) []revision { func (ti *treeIndex) Compact(rev int64) map[revision]struct{} { available := make(map[revision]struct{}) - emptyki := make([]*keyIndex, 0) - log.Printf("store.index: compact %d", rev) + var emptyki []*keyIndex + plog.Printf("store.index: compact %d", rev) // TODO: do not hold the lock for long time? // This is probably OK. Compacting 10M keys takes O(10ms). ti.Lock() @@ -178,7 +177,7 @@ func (ti *treeIndex) Compact(rev int64) map[revision]struct{} { for _, ki := range emptyki { item := ti.tree.Delete(ki) if item == nil { - log.Panic("store.index: unexpected delete failure during compaction") + plog.Panic("store.index: unexpected delete failure during compaction") } } return available diff --git a/vendor/github.com/coreos/etcd/storage/key_index.go b/vendor/github.com/coreos/etcd/mvcc/key_index.go similarity index 92% rename from vendor/github.com/coreos/etcd/storage/key_index.go rename to vendor/github.com/coreos/etcd/mvcc/key_index.go index e8a344ec21e..983c64e2f6b 100644 --- a/vendor/github.com/coreos/etcd/storage/key_index.go +++ b/vendor/github.com/coreos/etcd/mvcc/key_index.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. @@ -12,19 +12,18 @@ // See the License for the specific language governing permissions and // limitations under the License. -package storage +package mvcc import ( "bytes" "errors" "fmt" - "log" "github.com/google/btree" ) var ( - ErrRevisionNotFound = errors.New("stroage: revision not found") + ErrRevisionNotFound = errors.New("mvcc: revision not found") ) // keyIndex stores the revisions of a key in the backend. @@ -78,7 +77,7 @@ func (ki *keyIndex) put(main int64, sub int64) { rev := revision{main: main, sub: sub} if !rev.GreaterThan(ki.modified) { - log.Panicf("store.keyindex: put with unexpected smaller revision [%v / %v]", rev, ki.modified) + plog.Panicf("store.keyindex: put with unexpected smaller revision [%v / %v]", rev, ki.modified) } if len(ki.generations) == 0 { ki.generations = append(ki.generations, generation{}) @@ -95,7 +94,7 @@ func (ki *keyIndex) put(main int64, sub int64) { func (ki *keyIndex) restore(created, modified revision, ver int64) { if len(ki.generations) != 0 { - log.Panicf("store.keyindex: cannot restore non-empty keyIndex") + plog.Panicf("store.keyindex: cannot restore non-empty keyIndex") } ki.modified = modified @@ -109,7 +108,7 @@ func (ki *keyIndex) restore(created, modified revision, ver int64) { // It returns ErrRevisionNotFound when tombstone on an empty generation. func (ki *keyIndex) tombstone(main int64, sub int64) error { if ki.isEmpty() { - log.Panicf("store.keyindex: unexpected tombstone on empty keyIndex %s", string(ki.key)) + plog.Panicf("store.keyindex: unexpected tombstone on empty keyIndex %s", string(ki.key)) } if ki.generations[len(ki.generations)-1].isEmpty() { return ErrRevisionNotFound @@ -124,7 +123,7 @@ func (ki *keyIndex) tombstone(main int64, sub int64) error { // Rev must be higher than or equal to the given atRev. func (ki *keyIndex) get(atRev int64) (modified, created revision, ver int64, err error) { if ki.isEmpty() { - log.Panicf("store.keyindex: unexpected get on empty keyIndex %s", string(ki.key)) + plog.Panicf("store.keyindex: unexpected get on empty keyIndex %s", string(ki.key)) } g := ki.findGeneration(atRev) if g.isEmpty() { @@ -144,7 +143,7 @@ func (ki *keyIndex) get(atRev int64) (modified, created revision, ver int64, err // main revision. func (ki *keyIndex) since(rev int64) []revision { if ki.isEmpty() { - log.Panicf("store.keyindex: unexpected get on empty keyIndex %s", string(ki.key)) + plog.Panicf("store.keyindex: unexpected get on empty keyIndex %s", string(ki.key)) } since := revision{rev, 0} var gi int @@ -185,7 +184,7 @@ func (ki *keyIndex) since(rev int64) []revision { // If a generation becomes empty during compaction, it will be removed. func (ki *keyIndex) compact(atRev int64, available map[revision]struct{}) { if ki.isEmpty() { - log.Panicf("store.keyindex: unexpected compact on empty keyIndex %s", string(ki.key)) + plog.Panicf("store.keyindex: unexpected compact on empty keyIndex %s", string(ki.key)) } // walk until reaching the first revision that has an revision smaller or equal to diff --git a/vendor/github.com/coreos/etcd/storage/kv.go b/vendor/github.com/coreos/etcd/mvcc/kv.go similarity index 87% rename from vendor/github.com/coreos/etcd/storage/kv.go rename to vendor/github.com/coreos/etcd/mvcc/kv.go index 33d26e29e52..c851c8725e8 100644 --- a/vendor/github.com/coreos/etcd/storage/kv.go +++ b/vendor/github.com/coreos/etcd/mvcc/kv.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. @@ -12,14 +12,26 @@ // See the License for the specific language governing permissions and // limitations under the License. -package storage +package mvcc import ( "github.com/coreos/etcd/lease" - "github.com/coreos/etcd/storage/backend" - "github.com/coreos/etcd/storage/storagepb" + "github.com/coreos/etcd/mvcc/backend" + "github.com/coreos/etcd/mvcc/mvccpb" ) +type RangeOptions struct { + Limit int64 + Rev int64 + Count bool +} + +type RangeResult struct { + KVs []mvccpb.KeyValue + Rev int64 + Count int +} + type KV interface { // Rev returns the current revision of the KV. Rev() int64 @@ -37,7 +49,7 @@ type KV interface { // If `end` is not nil and empty, it gets the keys greater than or equal to key. // Limit limits the number of keys returned. // If the required rev is compacted, ErrCompacted will be returned. - Range(key, end []byte, limit, rangeRev int64) (kvs []storagepb.KeyValue, rev int64, err error) + Range(key, end []byte, ro RangeOptions) (r *RangeResult, err error) // Put puts the given key, value into the store. Put also takes additional argument lease to // attach a lease to a key-value pair as meta-data. KV implementation does not validate the lease @@ -63,15 +75,16 @@ type KV interface { // TxnEnd ends the on-going txn with txn ID. If the on-going txn ID is not matched, error is returned. TxnEnd(txnID int64) error // TxnRange returns the current revision of the KV when the operation is executed. - TxnRange(txnID int64, key, end []byte, limit, rangeRev int64) (kvs []storagepb.KeyValue, rev int64, err error) + TxnRange(txnID int64, key, end []byte, ro RangeOptions) (r *RangeResult, err error) TxnPut(txnID int64, key, value []byte, lease lease.LeaseID) (rev int64, err error) TxnDeleteRange(txnID int64, key, end []byte) (n, rev int64, err error) + // Compact frees all superseded keys with revisions less than rev. Compact(rev int64) (<-chan struct{}, error) - // Hash retrieves the hash of KV state. + // Hash retrieves the hash of KV state and revision. // This method is designed for consistency checking purpose. - Hash() (uint32, error) + Hash() (hash uint32, revision int64, err error) // Commit commits txns into the underlying backend. Commit() diff --git a/vendor/github.com/coreos/etcd/storage/kvstore.go b/vendor/github.com/coreos/etcd/mvcc/kvstore.go similarity index 79% rename from vendor/github.com/coreos/etcd/storage/kvstore.go rename to vendor/github.com/coreos/etcd/mvcc/kvstore.go index e9fceb7da56..d1c71fd7c1a 100644 --- a/vendor/github.com/coreos/etcd/storage/kvstore.go +++ b/vendor/github.com/coreos/etcd/mvcc/kvstore.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. @@ -12,21 +12,21 @@ // See the License for the specific language governing permissions and // limitations under the License. -package storage +package mvcc import ( "encoding/binary" "errors" - "log" "math" "math/rand" "sync" "time" "github.com/coreos/etcd/lease" + "github.com/coreos/etcd/mvcc/backend" + "github.com/coreos/etcd/mvcc/mvccpb" "github.com/coreos/etcd/pkg/schedule" - "github.com/coreos/etcd/storage/backend" - "github.com/coreos/etcd/storage/storagepb" + "github.com/coreos/pkg/capnslog" "golang.org/x/net/context" ) @@ -45,10 +45,12 @@ var ( scheduledCompactKeyName = []byte("scheduledCompactRev") finishedCompactKeyName = []byte("finishedCompactRev") - ErrTxnIDMismatch = errors.New("storage: txn id mismatch") - ErrCompacted = errors.New("storage: required revision has been compacted") - ErrFutureRev = errors.New("storage: required revision is a future revision") - ErrCanceled = errors.New("storage: watcher is canceled") + ErrTxnIDMismatch = errors.New("mvcc: txn id mismatch") + ErrCompacted = errors.New("mvcc: required revision has been compacted") + ErrFutureRev = errors.New("mvcc: required revision is a future revision") + ErrCanceled = errors.New("mvcc: watcher is canceled") + + plog = capnslog.NewPackageLogger("github.com/coreos/etcd", "mvcc") ) // ConsistentIndexGetter is an interface that wraps the Get method. @@ -75,14 +77,18 @@ type store struct { tx backend.BatchTx txnID int64 // tracks the current txnID to verify txn operations - changes []storagepb.KeyValue + // bytesBuf8 is a byte slice of length 8 + // to avoid a repetitive allocation in saveIndex. + bytesBuf8 []byte + + changes []mvccpb.KeyValue fifoSched schedule.Scheduler stopc chan struct{} } // NewStore returns a new store. It is useful to create a store inside -// storage pkg. It should only be used for testing externally. +// mvcc pkg. It should only be used for testing externally. func NewStore(b backend.Backend, le lease.Lessor, ig ConsistentIndexGetter) *store { s := &store{ b: b, @@ -94,6 +100,7 @@ func NewStore(b backend.Backend, le lease.Lessor, ig ConsistentIndexGetter) *sto currentRev: revision{main: 1}, compactMainRev: -1, + bytesBuf8: make([]byte, 8, 8), fifoSched: schedule.NewFIFOScheduler(), stopc: make(chan struct{}), @@ -142,14 +149,20 @@ func (s *store) Put(key, value []byte, lease lease.LeaseID) int64 { return int64(s.currentRev.main) } -func (s *store) Range(key, end []byte, limit, rangeRev int64) (kvs []storagepb.KeyValue, rev int64, err error) { +func (s *store) Range(key, end []byte, ro RangeOptions) (r *RangeResult, err error) { id := s.TxnBegin() - kvs, rev, err = s.rangeKeys(key, end, limit, rangeRev) + kvs, count, rev, err := s.rangeKeys(key, end, ro.Limit, ro.Rev, ro.Count) s.txnEnd(id) rangeCounter.Inc() - return kvs, rev, err + r = &RangeResult{ + KVs: kvs, + Count: count, + Rev: rev, + } + + return r, err } func (s *store) DeleteRange(key, end []byte) (n, rev int64) { @@ -201,11 +214,19 @@ func (s *store) txnEnd(txnID int64) error { return nil } -func (s *store) TxnRange(txnID int64, key, end []byte, limit, rangeRev int64) (kvs []storagepb.KeyValue, rev int64, err error) { +func (s *store) TxnRange(txnID int64, key, end []byte, ro RangeOptions) (r *RangeResult, err error) { if txnID != s.txnID { - return nil, 0, ErrTxnIDMismatch + return nil, ErrTxnIDMismatch } - return s.rangeKeys(key, end, limit, rangeRev) + + kvs, count, rev, err := s.rangeKeys(key, end, ro.Limit, ro.Rev, ro.Count) + + r = &RangeResult{ + KVs: kvs, + Count: count, + Rev: rev, + } + return r, err } func (s *store) TxnPut(txnID int64, key, value []byte, lease lease.LeaseID) (rev int64, err error) { @@ -289,16 +310,38 @@ func (s *store) Compact(rev int64) (<-chan struct{}, error) { s.fifoSched.Schedule(j) - indexCompactionPauseDurations.Observe(float64(time.Now().Sub(start) / time.Millisecond)) + indexCompactionPauseDurations.Observe(float64(time.Since(start) / time.Millisecond)) return ch, nil } -func (s *store) Hash() (uint32, error) { +func (s *store) Hash() (uint32, int64, error) { s.b.ForceCommit() - return s.b.Hash() + + s.mu.Lock() + defer s.mu.Unlock() + + // 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) + rev := s.currentRev.main + return h, rev, err } -func (s *store) Commit() { s.b.ForceCommit() } +func (s *store) Commit() { + s.mu.Lock() + defer s.mu.Unlock() + + s.tx = s.b.BatchTx() + s.tx.Lock() + s.saveIndex() + s.tx.Unlock() + s.b.ForceCommit() +} func (s *store) Restore(b backend.Backend) error { s.mu.Lock() @@ -330,15 +373,15 @@ func (s *store) restore() error { _, finishedCompactBytes := tx.UnsafeRange(metaBucketName, finishedCompactKeyName, nil, 0) if len(finishedCompactBytes) != 0 { s.compactMainRev = bytesToRev(finishedCompactBytes[0]).main - log.Printf("storage: restore compact to %d", s.compactMainRev) + plog.Printf("restore compact to %d", s.compactMainRev) } // TODO: limit N to reduce max memory usage keys, vals := tx.UnsafeRange(keyBucketName, min, max, 0) for i, key := range keys { - var kv storagepb.KeyValue + var kv mvccpb.KeyValue if err := kv.Unmarshal(vals[i]); err != nil { - log.Fatalf("storage: cannot unmarshal event: %v", err) + plog.Fatalf("cannot unmarshal event: %v", err) } rev := bytesToRev(key[:revBytesLen]) @@ -350,7 +393,7 @@ func (s *store) restore() error { if lease.LeaseID(kv.Lease) != lease.NoLease { err := s.le.Detach(lease.LeaseID(kv.Lease), []lease.LeaseItem{{Key: string(kv.Key)}}) if err != nil && err != lease.ErrLeaseNotFound { - log.Fatalf("storage: unexpected Detach error %v", err) + plog.Fatalf("unexpected Detach error %v", err) } } default: @@ -387,7 +430,7 @@ func (s *store) restore() error { if scheduledCompact != 0 { s.Compact(scheduledCompact) - log.Printf("storage: resume scheduled compaction at %d", scheduledCompact) + plog.Printf("resume scheduled compaction at %d", scheduledCompact) } return nil @@ -410,14 +453,14 @@ func (a *store) Equal(b *store) bool { } // range is a keyword in Go, add Keys suffix. -func (s *store) rangeKeys(key, end []byte, limit, rangeRev int64) (kvs []storagepb.KeyValue, curRev int64, err error) { +func (s *store) rangeKeys(key, end []byte, limit, rangeRev int64, countOnly bool) (kvs []mvccpb.KeyValue, count int, curRev int64, err error) { curRev = int64(s.currentRev.main) if s.currentRev.sub > 0 { curRev += 1 } if rangeRev > curRev { - return nil, s.currentRev.main, ErrFutureRev + return nil, -1, s.currentRev.main, ErrFutureRev } var rev int64 if rangeRev <= 0 { @@ -425,13 +468,16 @@ func (s *store) rangeKeys(key, end []byte, limit, rangeRev int64) (kvs []storage } else { rev = rangeRev } - if rev <= s.compactMainRev { - return nil, 0, ErrCompacted + if rev < s.compactMainRev { + return nil, -1, 0, ErrCompacted } _, revpairs := s.kvindex.Range(key, end, int64(rev)) if len(revpairs) == 0 { - return nil, curRev, nil + return nil, 0, curRev, nil + } + if countOnly { + return nil, len(revpairs), curRev, nil } for _, revpair := range revpairs { @@ -439,19 +485,19 @@ func (s *store) rangeKeys(key, end []byte, limit, rangeRev int64) (kvs []storage _, vs := s.tx.UnsafeRange(keyBucketName, start, end, 0) if len(vs) != 1 { - log.Fatalf("storage: range cannot find rev (%d,%d)", revpair.main, revpair.sub) + plog.Fatalf("range cannot find rev (%d,%d)", revpair.main, revpair.sub) } - var kv storagepb.KeyValue + var kv mvccpb.KeyValue if err := kv.Unmarshal(vs[0]); err != nil { - log.Fatalf("storage: cannot unmarshal event: %v", err) + plog.Fatalf("cannot unmarshal event: %v", err) } kvs = append(kvs, kv) if limit > 0 && len(kvs) >= int(limit) { break } } - return kvs, curRev, nil + return kvs, len(kvs), curRev, nil } func (s *store) put(key, value []byte, leaseID lease.LeaseID) { @@ -467,9 +513,9 @@ func (s *store) put(key, value []byte, leaseID lease.LeaseID) { ibytes := newRevBytes() revToBytes(grev, ibytes) _, vs := s.tx.UnsafeRange(keyBucketName, ibytes, nil, 0) - var kv storagepb.KeyValue + var kv mvccpb.KeyValue if err = kv.Unmarshal(vs[0]); err != nil { - log.Fatalf("storage: cannot unmarshal value: %v", err) + plog.Fatalf("cannot unmarshal value: %v", err) } oldLease = lease.LeaseID(kv.Lease) } @@ -478,7 +524,7 @@ func (s *store) put(key, value []byte, leaseID lease.LeaseID) { revToBytes(revision{main: rev, sub: s.currentRev.sub}, ibytes) ver = ver + 1 - kv := storagepb.KeyValue{ + kv := mvccpb.KeyValue{ Key: key, Value: value, CreateRevision: c, @@ -489,7 +535,7 @@ func (s *store) put(key, value []byte, leaseID lease.LeaseID) { d, err := kv.Marshal() if err != nil { - log.Fatalf("storage: cannot marshal event: %v", err) + plog.Fatalf("cannot marshal event: %v", err) } s.tx.UnsafeSeqPut(keyBucketName, ibytes, d) @@ -544,19 +590,19 @@ func (s *store) delete(key []byte, rev revision) { revToBytes(revision{main: mainrev, sub: s.currentRev.sub}, ibytes) ibytes = appendMarkTombstone(ibytes) - kv := storagepb.KeyValue{ + kv := mvccpb.KeyValue{ Key: key, } d, err := kv.Marshal() if err != nil { - log.Fatalf("storage: cannot marshal event: %v", err) + plog.Fatalf("cannot marshal event: %v", err) } s.tx.UnsafeSeqPut(keyBucketName, ibytes, d) err = s.kvindex.Tombstone(key, revision{main: mainrev, sub: s.currentRev.sub}) if err != nil { - log.Fatalf("storage: cannot tombstone an existing key (%s): %v", string(key), err) + plog.Fatalf("cannot tombstone an existing key (%s): %v", string(key), err) } s.changes = append(s.changes, kv) s.currentRev.sub += 1 @@ -567,20 +613,20 @@ func (s *store) delete(key []byte, rev revision) { kv.Reset() if err = kv.Unmarshal(vs[0]); err != nil { - log.Fatalf("storage: cannot unmarshal value: %v", err) + 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 err != nil { - log.Fatalf("storage: cannot detach %v", err) + plog.Fatalf("cannot detach %v", err) } } } -func (s *store) getChanges() []storagepb.KeyValue { +func (s *store) getChanges() []mvccpb.KeyValue { changes := s.changes - s.changes = make([]storagepb.KeyValue, 0, 128) + s.changes = make([]mvccpb.KeyValue, 0, 4) return changes } @@ -589,8 +635,7 @@ func (s *store) saveIndex() { return } tx := s.tx - // TODO: avoid this unnecessary allocation - bs := make([]byte, 8) + bs := s.bytesBuf8 binary.BigEndian.PutUint64(bs, s.ig.ConsistentIndex()) // put the index into the underlying backend // tx has been locked in TxnBegin, so there is no need to lock it again @@ -612,7 +657,7 @@ func (s *store) ConsistentIndex() uint64 { // appendMarkTombstone appends tombstone mark to normal revision bytes. func appendMarkTombstone(b []byte) []byte { if len(b) != revBytesLen { - log.Panicf("cannot append mark to non normal revision bytes") + plog.Panicf("cannot append mark to non normal revision bytes") } return append(b, markTombstone) } diff --git a/vendor/github.com/coreos/etcd/storage/kvstore_compaction.go b/vendor/github.com/coreos/etcd/mvcc/kvstore_compaction.go similarity index 82% rename from vendor/github.com/coreos/etcd/storage/kvstore_compaction.go rename to vendor/github.com/coreos/etcd/mvcc/kvstore_compaction.go index a7b9cc8ad5a..bbd38f547f3 100644 --- a/vendor/github.com/coreos/etcd/storage/kvstore_compaction.go +++ b/vendor/github.com/coreos/etcd/mvcc/kvstore_compaction.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package storage +package mvcc import ( "encoding/binary" @@ -21,7 +21,7 @@ import ( func (s *store) scheduleCompaction(compactMainRev int64, keep map[revision]struct{}) bool { totalStart := time.Now() - defer dbCompactionTotalDurations.Observe(float64(time.Now().Sub(totalStart) / time.Millisecond)) + defer dbCompactionTotalDurations.Observe(float64(time.Since(totalStart) / time.Millisecond)) end := make([]byte, 8) binary.BigEndian.PutUint64(end, uint64(compactMainRev+1)) @@ -48,13 +48,14 @@ func (s *store) scheduleCompaction(compactMainRev int64, keep map[revision]struc revToBytes(revision{main: compactMainRev}, rbytes) tx.UnsafePut(metaBucketName, finishedCompactKeyName, rbytes) tx.Unlock() + plog.Printf("finished scheduled compaction at %d (took %v)", compactMainRev, time.Since(totalStart)) return true } // update last revToBytes(revision{main: rev.main, sub: rev.sub + 1}, last) tx.Unlock() - dbCompactionPauseDurations.Observe(float64(time.Now().Sub(start) / time.Millisecond)) + dbCompactionPauseDurations.Observe(float64(time.Since(start) / time.Millisecond)) select { case <-time.After(100 * time.Millisecond): diff --git a/vendor/github.com/coreos/etcd/storage/metrics.go b/vendor/github.com/coreos/etcd/mvcc/metrics.go similarity index 81% rename from vendor/github.com/coreos/etcd/storage/metrics.go rename to vendor/github.com/coreos/etcd/mvcc/metrics.go index 24b45a7ecdc..aa8af6aa552 100644 --- a/vendor/github.com/coreos/etcd/storage/metrics.go +++ b/vendor/github.com/coreos/etcd/mvcc/metrics.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package storage +package mvcc import ( "github.com/prometheus/client_golang/prometheus" @@ -21,88 +21,88 @@ import ( var ( rangeCounter = prometheus.NewCounter( prometheus.CounterOpts{ - Namespace: "etcd", - Subsystem: "storage", + Namespace: "etcd_debugging", + Subsystem: "mvcc", Name: "range_total", Help: "Total number of ranges seen by this member.", }) putCounter = prometheus.NewCounter( prometheus.CounterOpts{ - Namespace: "etcd", - Subsystem: "storage", + Namespace: "etcd_debugging", + Subsystem: "mvcc", Name: "put_total", Help: "Total number of puts seen by this member.", }) deleteCounter = prometheus.NewCounter( prometheus.CounterOpts{ - Namespace: "etcd", - Subsystem: "storage", + Namespace: "etcd_debugging", + Subsystem: "mvcc", Name: "delete_total", Help: "Total number of deletes seen by this member.", }) txnCounter = prometheus.NewCounter( prometheus.CounterOpts{ - Namespace: "etcd", - Subsystem: "storage", + Namespace: "etcd_debugging", + Subsystem: "mvcc", Name: "txn_total", Help: "Total number of txns seen by this member.", }) keysGauge = prometheus.NewGauge( prometheus.GaugeOpts{ - Namespace: "etcd", - Subsystem: "storage", + Namespace: "etcd_debugging", + Subsystem: "mvcc", Name: "keys_total", Help: "Total number of keys.", }) watchStreamGauge = prometheus.NewGauge( prometheus.GaugeOpts{ - Namespace: "etcd", - Subsystem: "storage", + Namespace: "etcd_debugging", + Subsystem: "mvcc", Name: "watch_stream_total", Help: "Total number of watch streams.", }) watcherGauge = prometheus.NewGauge( prometheus.GaugeOpts{ - Namespace: "etcd", - Subsystem: "storage", + Namespace: "etcd_debugging", + Subsystem: "mvcc", Name: "watcher_total", Help: "Total number of watchers.", }) slowWatcherGauge = prometheus.NewGauge( prometheus.GaugeOpts{ - Namespace: "etcd", - Subsystem: "storage", + Namespace: "etcd_debugging", + Subsystem: "mvcc", Name: "slow_watcher_total", Help: "Total number of unsynced slow watchers.", }) totalEventsCounter = prometheus.NewCounter( prometheus.CounterOpts{ - Namespace: "etcd", - Subsystem: "storage", + Namespace: "etcd_debugging", + Subsystem: "mvcc", Name: "events_total", Help: "Total number of events sent by this member.", }) pendingEventsGauge = prometheus.NewGauge( prometheus.GaugeOpts{ - Namespace: "etcd", - Subsystem: "storage", + Namespace: "etcd_debugging", + Subsystem: "mvcc", Name: "pending_events_total", Help: "Total number of pending events to be sent.", }) indexCompactionPauseDurations = prometheus.NewHistogram( prometheus.HistogramOpts{ - Namespace: "etcd", - Subsystem: "storage", + Namespace: "etcd_debugging", + Subsystem: "mvcc", Name: "index_compaction_pause_duration_milliseconds", Help: "Bucketed histogram of index compaction pause duration.", // 0.5ms -> 1second @@ -111,8 +111,8 @@ var ( dbCompactionPauseDurations = prometheus.NewHistogram( prometheus.HistogramOpts{ - Namespace: "etcd", - Subsystem: "storage", + Namespace: "etcd_debugging", + Subsystem: "mvcc", Name: "db_compaction_pause_duration_milliseconds", Help: "Bucketed histogram of db compaction pause duration.", // 1ms -> 4second @@ -121,8 +121,8 @@ var ( dbCompactionTotalDurations = prometheus.NewHistogram( prometheus.HistogramOpts{ - Namespace: "etcd", - Subsystem: "storage", + Namespace: "etcd_debugging", + Subsystem: "mvcc", Name: "db_compaction_total_duration_milliseconds", Help: "Bucketed histogram of db compaction total duration.", // 100ms -> 800second @@ -130,8 +130,8 @@ var ( }) dbTotalSize = prometheus.NewGauge(prometheus.GaugeOpts{ - Namespace: "etcd", - Subsystem: "storage", + Namespace: "etcd_debugging", + Subsystem: "mvcc", Name: "db_total_size_in_bytes", Help: "Total size of the underlying database in bytes.", }) @@ -156,8 +156,8 @@ func init() { // ReportEventReceived reports that an event is received. // This function should be called when the external systems received an -// event from storage.Watcher. -func ReportEventReceived() { - pendingEventsGauge.Dec() - totalEventsCounter.Inc() +// event from mvcc.Watcher. +func ReportEventReceived(n int) { + pendingEventsGauge.Sub(float64(n)) + totalEventsCounter.Add(float64(n)) } diff --git a/vendor/github.com/coreos/etcd/storage/storagepb/kv.pb.go b/vendor/github.com/coreos/etcd/mvcc/mvccpb/kv.pb.go similarity index 75% rename from vendor/github.com/coreos/etcd/storage/storagepb/kv.pb.go rename to vendor/github.com/coreos/etcd/mvcc/mvccpb/kv.pb.go index 2987b9be6cb..2ab97270cf0 100644 --- a/vendor/github.com/coreos/etcd/storage/storagepb/kv.pb.go +++ b/vendor/github.com/coreos/etcd/mvcc/mvccpb/kv.pb.go @@ -3,7 +3,7 @@ // DO NOT EDIT! /* - Package storagepb is a generated protocol buffer package. + Package mvccpb is a generated protocol buffer package. It is generated from these files: kv.proto @@ -12,12 +12,12 @@ KeyValue Event */ -package storagepb +package mvccpb import ( "fmt" - proto "github.com/gogo/protobuf/proto" + proto "github.com/golang/protobuf/proto" math "math" ) @@ -29,51 +29,61 @@ var _ = proto.Marshal var _ = fmt.Errorf 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 + type Event_EventType int32 const ( PUT Event_EventType = 0 DELETE Event_EventType = 1 - EXPIRE Event_EventType = 2 ) var Event_EventType_name = map[int32]string{ 0: "PUT", 1: "DELETE", - 2: "EXPIRE", } var Event_EventType_value = map[string]int32{ "PUT": 0, "DELETE": 1, - "EXPIRE": 2, } func (x Event_EventType) String() string { return proto.EnumName(Event_EventType_name, int32(x)) } +func (Event_EventType) EnumDescriptor() ([]byte, []int) { return fileDescriptorKv, []int{1, 0} } type KeyValue struct { + // key is the key in bytes. An empty key is not allowed. Key []byte `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` // create_revision is the revision of last creation on this key. - CreateRevision int64 `protobuf:"varint,2,opt,name=create_revision,proto3" json:"create_revision,omitempty"` + CreateRevision int64 `protobuf:"varint,2,opt,name=create_revision,json=createRevision,proto3" json:"create_revision,omitempty"` // mod_revision is the revision of last modification on this key. - ModRevision int64 `protobuf:"varint,3,opt,name=mod_revision,proto3" json:"mod_revision,omitempty"` + ModRevision int64 `protobuf:"varint,3,opt,name=mod_revision,json=modRevision,proto3" json:"mod_revision,omitempty"` // version is the version of the key. A deletion resets // the version to zero and any modification of the key // increases its version. - Version int64 `protobuf:"varint,4,opt,name=version,proto3" json:"version,omitempty"` - Value []byte `protobuf:"bytes,5,opt,name=value,proto3" json:"value,omitempty"` + Version int64 `protobuf:"varint,4,opt,name=version,proto3" json:"version,omitempty"` + // value is the value held by the key, in bytes. + Value []byte `protobuf:"bytes,5,opt,name=value,proto3" json:"value,omitempty"` // lease is the ID of the lease that attached to key. // When the attached lease expires, the key will be deleted. + // If lease is 0, then no lease is attached to the key. Lease int64 `protobuf:"varint,6,opt,name=lease,proto3" json:"lease,omitempty"` } -func (m *KeyValue) Reset() { *m = KeyValue{} } -func (m *KeyValue) String() string { return proto.CompactTextString(m) } -func (*KeyValue) ProtoMessage() {} +func (m *KeyValue) Reset() { *m = KeyValue{} } +func (m *KeyValue) String() string { return proto.CompactTextString(m) } +func (*KeyValue) ProtoMessage() {} +func (*KeyValue) Descriptor() ([]byte, []int) { return fileDescriptorKv, []int{0} } type Event struct { - Type Event_EventType `protobuf:"varint,1,opt,name=type,proto3,enum=storagepb.Event_EventType" json:"type,omitempty"` + // type is the kind of event. If type is a PUT, it indicates + // new data has been stored to the key. If type is a DELETE, + // it indicates the key was deleted. + Type Event_EventType `protobuf:"varint,1,opt,name=type,proto3,enum=mvccpb.Event_EventType" json:"type,omitempty"` + // kv holds the KeyValue for the event. // A PUT event contains current kv pair. // A PUT event with kv.Version=1 indicates the creation of a key. // A DELETE/EXPIRE event contains the deleted key with @@ -81,14 +91,15 @@ type Event struct { Kv *KeyValue `protobuf:"bytes,2,opt,name=kv" json:"kv,omitempty"` } -func (m *Event) Reset() { *m = Event{} } -func (m *Event) String() string { return proto.CompactTextString(m) } -func (*Event) ProtoMessage() {} +func (m *Event) Reset() { *m = Event{} } +func (m *Event) String() string { return proto.CompactTextString(m) } +func (*Event) ProtoMessage() {} +func (*Event) Descriptor() ([]byte, []int) { return fileDescriptorKv, []int{1} } func init() { - proto.RegisterType((*KeyValue)(nil), "storagepb.KeyValue") - proto.RegisterType((*Event)(nil), "storagepb.Event") - proto.RegisterEnum("storagepb.Event_EventType", Event_EventType_name, Event_EventType_value) + proto.RegisterType((*KeyValue)(nil), "mvccpb.KeyValue") + 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) { size := m.Size() @@ -105,13 +116,11 @@ func (m *KeyValue) MarshalTo(data []byte) (int, error) { _ = i var l int _ = l - if m.Key != nil { - if len(m.Key) > 0 { - data[i] = 0xa - i++ - i = encodeVarintKv(data, i, uint64(len(m.Key))) - i += copy(data[i:], m.Key) - } + if len(m.Key) > 0 { + data[i] = 0xa + i++ + i = encodeVarintKv(data, i, uint64(len(m.Key))) + i += copy(data[i:], m.Key) } if m.CreateRevision != 0 { data[i] = 0x10 @@ -128,13 +137,11 @@ func (m *KeyValue) MarshalTo(data []byte) (int, error) { i++ i = encodeVarintKv(data, i, uint64(m.Version)) } - if m.Value != nil { - if len(m.Value) > 0 { - data[i] = 0x2a - i++ - i = encodeVarintKv(data, i, uint64(len(m.Value))) - i += copy(data[i:], m.Value) - } + if len(m.Value) > 0 { + data[i] = 0x2a + i++ + i = encodeVarintKv(data, i, uint64(len(m.Value))) + i += copy(data[i:], m.Value) } if m.Lease != 0 { data[i] = 0x30 @@ -207,11 +214,9 @@ func encodeVarintKv(data []byte, offset int, v uint64) int { func (m *KeyValue) Size() (n int) { var l int _ = l - if m.Key != nil { - l = len(m.Key) - if l > 0 { - n += 1 + l + sovKv(uint64(l)) - } + l = len(m.Key) + if l > 0 { + n += 1 + l + sovKv(uint64(l)) } if m.CreateRevision != 0 { n += 1 + sovKv(uint64(m.CreateRevision)) @@ -222,11 +227,9 @@ func (m *KeyValue) Size() (n int) { if m.Version != 0 { n += 1 + sovKv(uint64(m.Version)) } - if m.Value != nil { - l = len(m.Value) - if l > 0 { - n += 1 + l + sovKv(uint64(l)) - } + l = len(m.Value) + if l > 0 { + n += 1 + l + sovKv(uint64(l)) } if m.Lease != 0 { n += 1 + sovKv(uint64(m.Lease)) @@ -654,3 +657,25 @@ var ( ErrInvalidLengthKv = fmt.Errorf("proto: negative length found during unmarshaling") ErrIntOverflowKv = fmt.Errorf("proto: integer overflow") ) + +var fileDescriptorKv = []byte{ + // 285 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x44, 0x90, 0x41, 0x4a, 0xc3, 0x40, + 0x14, 0x86, 0x33, 0x4d, 0x9b, 0xd6, 0xd7, 0x52, 0xc3, 0x50, 0x70, 0x70, 0x31, 0xc4, 0x6e, 0x2c, + 0x08, 0x11, 0xea, 0x0d, 0xc4, 0xac, 0x74, 0x21, 0x21, 0xba, 0x95, 0x34, 0x7d, 0x94, 0x92, 0xa6, + 0x13, 0xd2, 0x38, 0x98, 0x9b, 0x78, 0x0a, 0xcf, 0xd1, 0x65, 0x8f, 0x60, 0xe3, 0x45, 0x24, 0x6f, + 0x4c, 0xdd, 0x0c, 0xef, 0xff, 0xff, 0x6f, 0x98, 0xff, 0x0d, 0x0c, 0x52, 0xed, 0xe7, 0x85, 0x2a, + 0x15, 0x77, 0x32, 0x9d, 0x24, 0xf9, 0xe2, 0x72, 0xb2, 0x52, 0x2b, 0x45, 0xd6, 0x6d, 0x33, 0x99, + 0x74, 0xfa, 0xc5, 0x60, 0xf0, 0x88, 0xd5, 0x6b, 0xbc, 0x79, 0x47, 0xee, 0x82, 0x9d, 0x62, 0x25, + 0x98, 0xc7, 0x66, 0xa3, 0xb0, 0x19, 0xf9, 0x35, 0x9c, 0x27, 0x05, 0xc6, 0x25, 0xbe, 0x15, 0xa8, + 0xd7, 0xbb, 0xb5, 0xda, 0x8a, 0x8e, 0xc7, 0x66, 0x76, 0x38, 0x36, 0x76, 0xf8, 0xe7, 0xf2, 0x2b, + 0x18, 0x65, 0x6a, 0xf9, 0x4f, 0xd9, 0x44, 0x0d, 0x33, 0xb5, 0x3c, 0x21, 0x02, 0xfa, 0x1a, 0x0b, + 0x4a, 0xbb, 0x94, 0xb6, 0x92, 0x4f, 0xa0, 0xa7, 0x9b, 0x02, 0xa2, 0x47, 0x2f, 0x1b, 0xd1, 0xb8, + 0x1b, 0x8c, 0x77, 0x28, 0x1c, 0xa2, 0x8d, 0x98, 0x7e, 0x40, 0x2f, 0xd0, 0xb8, 0x2d, 0xf9, 0x0d, + 0x74, 0xcb, 0x2a, 0x47, 0x6a, 0x3b, 0x9e, 0x5f, 0xf8, 0x66, 0x4d, 0x9f, 0x42, 0x73, 0x46, 0x55, + 0x8e, 0x21, 0x41, 0xdc, 0x83, 0x4e, 0xaa, 0xa9, 0xfa, 0x70, 0xee, 0xb6, 0x68, 0xbb, 0x77, 0xd8, + 0x49, 0xf5, 0xd4, 0x83, 0xb3, 0xd3, 0x25, 0xde, 0x07, 0xfb, 0xf9, 0x25, 0x72, 0x2d, 0x0e, 0xe0, + 0x3c, 0x04, 0x4f, 0x41, 0x14, 0xb8, 0xec, 0x5e, 0xec, 0x8f, 0xd2, 0x3a, 0x1c, 0xa5, 0xb5, 0xaf, + 0x25, 0x3b, 0xd4, 0x92, 0x7d, 0xd7, 0x92, 0x7d, 0xfe, 0x48, 0x6b, 0xe1, 0xd0, 0x5f, 0xde, 0xfd, + 0x06, 0x00, 0x00, 0xff, 0xff, 0xd6, 0x21, 0x8f, 0x2c, 0x75, 0x01, 0x00, 0x00, +} diff --git a/vendor/github.com/coreos/etcd/storage/storagepb/kv.proto b/vendor/github.com/coreos/etcd/mvcc/mvccpb/kv.proto similarity index 74% rename from vendor/github.com/coreos/etcd/storage/storagepb/kv.proto rename to vendor/github.com/coreos/etcd/mvcc/mvccpb/kv.proto index bfd48553cef..f0c82b57cd4 100644 --- a/vendor/github.com/coreos/etcd/storage/storagepb/kv.proto +++ b/vendor/github.com/coreos/etcd/mvcc/mvccpb/kv.proto @@ -1,5 +1,5 @@ syntax = "proto3"; -package storagepb; +package mvccpb; import "gogoproto/gogo.proto"; @@ -10,6 +10,7 @@ option (gogoproto.goproto_getters_all) = false; option (gogoproto.goproto_enum_prefix_all) = false; message KeyValue { + // key is the key in bytes. An empty key is not allowed. bytes key = 1; // create_revision is the revision of last creation on this key. int64 create_revision = 2; @@ -19,9 +20,11 @@ message KeyValue { // the version to zero and any modification of the key // increases its version. int64 version = 4; + // value is the value held by the key, in bytes. bytes value = 5; // lease is the ID of the lease that attached to key. // When the attached lease expires, the key will be deleted. + // If lease is 0, then no lease is attached to the key. int64 lease = 6; } @@ -29,9 +32,12 @@ message Event { enum EventType { PUT = 0; DELETE = 1; - EXPIRE = 2; } + // type is the kind of event. If type is a PUT, it indicates + // new data has been stored to the key. If type is a DELETE, + // it indicates the key was deleted. EventType type = 1; + // kv holds the KeyValue for the event. // A PUT event contains current kv pair. // A PUT event with kv.Version=1 indicates the creation of a key. // A DELETE/EXPIRE event contains the deleted key with diff --git a/vendor/github.com/coreos/etcd/storage/revision.go b/vendor/github.com/coreos/etcd/mvcc/revision.go similarity index 97% rename from vendor/github.com/coreos/etcd/storage/revision.go rename to vendor/github.com/coreos/etcd/mvcc/revision.go index d31bcbbf285..5fa35a1c2a2 100644 --- a/vendor/github.com/coreos/etcd/storage/revision.go +++ b/vendor/github.com/coreos/etcd/mvcc/revision.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package storage +package mvcc import "encoding/binary" diff --git a/vendor/github.com/coreos/etcd/mvcc/util.go b/vendor/github.com/coreos/etcd/mvcc/util.go new file mode 100644 index 00000000000..8a0df0bfcc3 --- /dev/null +++ b/vendor/github.com/coreos/etcd/mvcc/util.go @@ -0,0 +1,56 @@ +// 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 mvcc + +import ( + "encoding/binary" + + "github.com/coreos/etcd/mvcc/backend" + "github.com/coreos/etcd/mvcc/mvccpb" +) + +func UpdateConsistentIndex(be backend.Backend, index uint64) { + tx := be.BatchTx() + tx.Lock() + defer tx.Unlock() + + var oldi uint64 + _, vs := tx.UnsafeRange(metaBucketName, consistentIndexKeyName, nil, 0) + if len(vs) != 0 { + oldi = binary.BigEndian.Uint64(vs[0]) + } + + if index <= oldi { + return + } + + bs := make([]byte, 8) + binary.BigEndian.PutUint64(bs, index) + tx.UnsafePut(metaBucketName, consistentIndexKeyName, bs) +} + +func WriteKV(be backend.Backend, kv mvccpb.KeyValue) { + ibytes := newRevBytes() + revToBytes(revision{main: kv.ModRevision}, ibytes) + + d, err := kv.Marshal() + if err != nil { + plog.Fatalf("cannot marshal event: %v", err) + } + + be.BatchTx().Lock() + be.BatchTx().UnsafePut(keyBucketName, ibytes, d) + be.BatchTx().Unlock() +} diff --git a/vendor/github.com/coreos/etcd/storage/watchable_store.go b/vendor/github.com/coreos/etcd/mvcc/watchable_store.go similarity index 52% rename from vendor/github.com/coreos/etcd/storage/watchable_store.go rename to vendor/github.com/coreos/etcd/mvcc/watchable_store.go index 818fcafcbb4..8339500ec84 100644 --- a/vendor/github.com/coreos/etcd/storage/watchable_store.go +++ b/vendor/github.com/coreos/etcd/mvcc/watchable_store.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. @@ -12,16 +12,15 @@ // See the License for the specific language governing permissions and // limitations under the License. -package storage +package mvcc import ( - "log" "sync" "time" "github.com/coreos/etcd/lease" - "github.com/coreos/etcd/storage/backend" - "github.com/coreos/etcd/storage/storagepb" + "github.com/coreos/etcd/mvcc/backend" + "github.com/coreos/etcd/mvcc/mvccpb" ) const ( @@ -30,6 +29,9 @@ const ( // TODO: find a good buf value. 1024 is just a random one that // seems to be reasonable. chanBufLen = 1024 + + // maxWatchersPerSync is the number of watchers to sync in a single batch + maxWatchersPerSync = 512 ) type watchable interface { @@ -43,6 +45,10 @@ type watchableStore struct { *store + // victims are watcher batches that were blocked on the watch channel + victims []watcherBatch + victimc chan struct{} + // contains all unsynced watchers that needs to sync with events that have happened unsynced watcherGroup @@ -65,6 +71,7 @@ func New(b backend.Backend, le lease.Lessor, ig ConsistentIndexGetter) Consisten func newWatchableStore(b backend.Backend, le lease.Lessor, ig ConsistentIndexGetter) *watchableStore { s := &watchableStore{ store: NewStore(b, le, ig), + victimc: make(chan struct{}, 1), unsynced: newWatcherGroup(), synced: newWatcherGroup(), stopc: make(chan struct{}), @@ -73,8 +80,9 @@ func newWatchableStore(b backend.Backend, le lease.Lessor, ig ConsistentIndexGet // use this store as the deleter so revokes trigger watch events s.le.SetRangeDeleter(s) } - s.wg.Add(1) + s.wg.Add(2) go s.syncWatchersLoop() + go s.syncVictimsLoop() return s } @@ -85,14 +93,14 @@ func (s *watchableStore) Put(key, value []byte, lease lease.LeaseID) (rev int64) rev = s.store.Put(key, value, lease) changes := s.store.getChanges() if len(changes) != 1 { - log.Panicf("unexpected len(changes) != 1 after put") + plog.Panicf("unexpected len(changes) != 1 after put") } - ev := storagepb.Event{ - Type: storagepb.PUT, + ev := mvccpb.Event{ + Type: mvccpb.PUT, Kv: &changes[0], } - s.notify(rev, []storagepb.Event{ev}) + s.notify(rev, []mvccpb.Event{ev}) return rev } @@ -104,18 +112,18 @@ func (s *watchableStore) DeleteRange(key, end []byte) (n, rev int64) { changes := s.store.getChanges() if len(changes) != int(n) { - log.Panicf("unexpected len(changes) != n after deleteRange") + plog.Panicf("unexpected len(changes) != n after deleteRange") } if n == 0 { return n, rev } - evs := make([]storagepb.Event, n) - for i, change := range changes { - evs[i] = storagepb.Event{ - Type: storagepb.DELETE, - Kv: &change} + evs := make([]mvccpb.Event, n) + for i := range changes { + evs[i] = mvccpb.Event{ + Type: mvccpb.DELETE, + Kv: &changes[i]} evs[i].Kv.ModRevision = rev } s.notify(rev, evs) @@ -140,17 +148,17 @@ func (s *watchableStore) TxnEnd(txnID int64) error { } rev := s.store.Rev() - evs := make([]storagepb.Event, len(changes)) + evs := make([]mvccpb.Event, len(changes)) for i, change := range changes { switch change.CreateRevision { case 0: - evs[i] = storagepb.Event{ - Type: storagepb.DELETE, + evs[i] = mvccpb.Event{ + Type: mvccpb.DELETE, Kv: &changes[i]} evs[i].Kv.ModRevision = rev default: - evs[i] = storagepb.Event{ - Type: storagepb.PUT, + evs[i] = mvccpb.Event{ + Type: mvccpb.PUT, Kv: &changes[i]} } } @@ -182,19 +190,19 @@ func (s *watchableStore) watch(key, end []byte, startRev int64, id WatchID, ch c defer s.mu.Unlock() wa := &watcher{ - key: key, - end: end, - cur: startRev, - id: id, - ch: ch, + key: key, + end: end, + minRev: startRev, + id: id, + ch: ch, } s.store.mu.Lock() synced := startRev > s.store.currentRev.main || startRev == 0 if synced { - wa.cur = s.store.currentRev.main + 1 - if startRev > wa.cur { - wa.cur = startRev + wa.minRev = s.store.currentRev.main + 1 + if startRev > wa.minRev { + wa.minRev = startRev } } s.store.mu.Unlock() @@ -206,23 +214,47 @@ func (s *watchableStore) watch(key, end []byte, startRev int64, id WatchID, ch c } watcherGauge.Inc() - cancel := cancelFunc(func() { + return wa, func() { s.cancelWatcher(wa) } +} + +// cancelWatcher removes references of the watcher from the watchableStore +func (s *watchableStore) cancelWatcher(wa *watcher) { + for { s.mu.Lock() - defer s.mu.Unlock() - // remove references of the watcher + if s.unsynced.delete(wa) { slowWatcherGauge.Dec() - watcherGauge.Dec() - return + break + } else if s.synced.delete(wa) { + break + } else if wa.compacted { + break } - if s.synced.delete(wa) { - watcherGauge.Dec() + if !wa.victim { + panic("watcher not victim but not in watch groups") } - // If we cannot find it, it should have finished watch. - }) - return wa, cancel + var victimBatch watcherBatch + for _, wb := range s.victims { + if wb[wa] != nil { + victimBatch = wb + break + } + } + if victimBatch != nil { + slowWatcherGauge.Dec() + delete(victimBatch, wa) + break + } + + // victim being processed so not accessible; retry + s.mu.Unlock() + time.Sleep(time.Millisecond) + } + + watcherGauge.Dec() + s.mu.Unlock() } // syncWatchersLoop syncs the watcher in the unsynced map every 100ms. @@ -231,36 +263,133 @@ func (s *watchableStore) syncWatchersLoop() { for { s.mu.Lock() + st := time.Now() + lastUnsyncedWatchers := s.unsynced.size() s.syncWatchers() + unsyncedWatchers := s.unsynced.size() s.mu.Unlock() + syncDuration := time.Since(st) + + waitDuration := 100 * time.Millisecond + // more work pending? + if unsyncedWatchers != 0 && lastUnsyncedWatchers > unsyncedWatchers { + // be fair to other store operations by yielding time taken + waitDuration = syncDuration + } select { - case <-time.After(100 * time.Millisecond): + case <-time.After(waitDuration): case <-s.stopc: return } } } -// syncWatchers periodically syncs unsynced watchers by: Iterate all unsynced -// watchers to get the minimum revision within its range, skipping the -// watcher if its current revision is behind the compact revision of the -// store. And use this minimum revision to get all key-value pairs. Then send -// those events to watchers. -func (s *watchableStore) syncWatchers() { - s.store.mu.Lock() - defer s.store.mu.Unlock() +// syncVictimsLoop tries to write precomputed watcher responses to +// watchers that had a blocked watcher channel +func (s *watchableStore) syncVictimsLoop() { + defer s.wg.Done() + for { + for s.moveVictims() != 0 { + // try to update all victim watchers + } + s.mu.Lock() + isEmpty := len(s.victims) == 0 + s.mu.Unlock() + + var tickc <-chan time.Time + if !isEmpty { + tickc = time.After(10 * time.Millisecond) + } + + select { + case <-tickc: + case <-s.victimc: + case <-s.stopc: + return + } + } +} + +// moveVictims tries to update watches with already pending event data +func (s *watchableStore) moveVictims() (moved int) { + s.mu.Lock() + victims := s.victims + s.victims = nil + s.mu.Unlock() + + var newVictim watcherBatch + for _, wb := range victims { + // try to send responses again + 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}: + pendingEventsGauge.Add(float64(len(eb.evs))) + default: + if newVictim == nil { + newVictim = make(watcherBatch) + } + newVictim[w] = eb + continue + } + moved++ + } + + // assign completed victim watchers to unsync/sync + s.mu.Lock() + s.store.mu.Lock() + curRev := s.store.currentRev.main + for w, eb := range wb { + if newVictim != nil && newVictim[w] != nil { + // couldn't send watch response; stays victim + continue + } + w.victim = false + if eb.moreRev != 0 { + w.minRev = eb.moreRev + } + if w.minRev <= curRev { + s.unsynced.add(w) + } else { + slowWatcherGauge.Dec() + s.synced.add(w) + } + } + s.store.mu.Unlock() + s.mu.Unlock() + } + + if len(newVictim) > 0 { + s.mu.Lock() + s.victims = append(s.victims, newVictim) + s.mu.Unlock() + } + + return moved +} + +// syncWatchers syncs unsynced watchers by: +// 1. choose a set of watchers from the unsynced watcher group +// 2. iterate over the set to get the minimum revision and remove compacted watchers +// 3. use minimum revision to get all key-value pairs and send those events to watchers +// 4. remove synced watchers in set from unsynced group and move to synced group +func (s *watchableStore) syncWatchers() { if s.unsynced.size() == 0 { return } + s.store.mu.Lock() + defer s.store.mu.Unlock() + // in order to find key-value pairs from unsynced watchers, we need to // find min revision index, and these revisions can be used to // query the backend store of key-value pairs curRev := s.store.currentRev.main compactionRev := s.store.compactMainRev - minRev := s.unsynced.scanMinRev(curRev, compactionRev) + wg, minRev := s.unsynced.choose(maxWatchersPerSync, curRev, compactionRev) minBytes, maxBytes := newRevBytes(), newRevBytes() revToBytes(revision{main: minRev}, minBytes) revToBytes(revision{main: curRev + 1}, maxBytes) @@ -270,84 +399,114 @@ func (s *watchableStore) syncWatchers() { tx := s.store.b.BatchTx() tx.Lock() revs, vs := tx.UnsafeRange(keyBucketName, minBytes, maxBytes, 0) - evs := kvsToEvents(&s.unsynced, revs, vs) + evs := kvsToEvents(wg, revs, vs) tx.Unlock() - wb := newWatcherBatch(&s.unsynced, evs) + var victims watcherBatch + wb := newWatcherBatch(wg, evs) + for w := range wg.watchers { + w.minRev = curRev + 1 - for w, eb := range wb { - select { - // s.store.Rev also uses Lock, so just return directly - case w.ch <- WatchResponse{WatchID: w.id, Events: eb.evs, Revision: s.store.currentRev.main}: - pendingEventsGauge.Add(float64(len(eb.evs))) - default: - // TODO: handle the full unsynced watchers. - // continue to process other watchers for now, the full ones - // will be processed next time and hopefully it will not be full. - continue - } - if eb.moreRev != 0 { - w.cur = eb.moreRev - continue - } - w.cur = curRev - s.synced.add(w) - s.unsynced.delete(w) - } - - // bring all un-notified watchers to synced. - for w := range s.unsynced.watchers { - if !wb.contains(w) { - w.cur = curRev + eb, ok := wb[w] + if !ok { + // bring un-notified watcher to synced s.synced.add(w) s.unsynced.delete(w) + continue } - } - slowWatcherGauge.Set(float64(s.unsynced.size())) + if eb.moreRev != 0 { + w.minRev = eb.moreRev + } + + select { + case w.ch <- WatchResponse{WatchID: w.id, Events: eb.evs, Revision: curRev}: + pendingEventsGauge.Add(float64(len(eb.evs))) + default: + if victims == nil { + victims = make(watcherBatch) + } + w.victim = true + } + + if w.victim { + victims[w] = eb + } else { + if eb.moreRev != 0 { + // stay unsynced; more to read + continue + } + s.synced.add(w) + } + s.unsynced.delete(w) + } + s.addVictim(victims) + + vsz := 0 + for _, v := range s.victims { + vsz += len(v) + } + slowWatcherGauge.Set(float64(s.unsynced.size() + vsz)) } // kvsToEvents gets all events for the watchers from all key-value pairs -func kvsToEvents(wg *watcherGroup, revs, vals [][]byte) (evs []storagepb.Event) { +func kvsToEvents(wg *watcherGroup, revs, vals [][]byte) (evs []mvccpb.Event) { for i, v := range vals { - var kv storagepb.KeyValue + var kv mvccpb.KeyValue if err := kv.Unmarshal(v); err != nil { - log.Panicf("storage: cannot unmarshal event: %v", err) + plog.Panicf("cannot unmarshal event: %v", err) } if !wg.contains(string(kv.Key)) { continue } - ty := storagepb.PUT + ty := mvccpb.PUT if isTombstone(revs[i]) { - ty = storagepb.DELETE + ty = mvccpb.DELETE // patch in mod revision so watchers won't skip kv.ModRevision = bytesToRev(revs[i]).main } - evs = append(evs, storagepb.Event{Kv: &kv, Type: ty}) + evs = append(evs, mvccpb.Event{Kv: &kv, Type: ty}) } return evs } // notify notifies the fact that given event at the given rev just happened to // watchers that watch on the key of the event. -func (s *watchableStore) notify(rev int64, evs []storagepb.Event) { +func (s *watchableStore) notify(rev int64, evs []mvccpb.Event) { + var victim watcherBatch for w, eb := range newWatcherBatch(&s.synced, evs) { if eb.revs != 1 { - panic("unexpected multiple revisions in notification") + plog.Panicf("unexpected multiple revisions in notification") } select { - case w.ch <- WatchResponse{WatchID: w.id, Events: eb.evs, Revision: s.Rev()}: + case w.ch <- WatchResponse{WatchID: w.id, Events: eb.evs, Revision: rev}: pendingEventsGauge.Add(float64(len(eb.evs))) default: - // move slow watcher to unsynced - w.cur = rev - s.unsynced.add(w) + // move slow watcher to victims + w.minRev = rev + 1 + if victim == nil { + victim = make(watcherBatch) + } + w.victim = true + victim[w] = eb s.synced.delete(w) slowWatcherGauge.Inc() } } + s.addVictim(victim) +} + +func (s *watchableStore) addVictim(victim watcherBatch) { + if victim == nil { + return + } + s.victims = append(s.victims, victim) + select { + case s.victimc <- struct{}{}: + default: + } } func (s *watchableStore) rev() int64 { return s.store.Rev() } @@ -373,12 +532,15 @@ type watcher struct { // If end is set, the watcher is on a range. end []byte - // cur is the current watcher revision of a unsynced watcher. - // cur will be updated for unsynced watcher while it is catching up. - // cur is startRev of a synced watcher. - // cur will not be updated for synced watcher. - cur int64 - id WatchID + // victim is set when ch is blocked and undergoing victim processing + victim bool + + // compacted is set when the watcher is removed because of compaction + compacted bool + + // minRev is the minimum revision update the watcher will accept + minRev int64 + id WatchID // a chan to send out the watch response. // The chan might be shared with other watchers. diff --git a/vendor/github.com/coreos/etcd/storage/watcher.go b/vendor/github.com/coreos/etcd/mvcc/watcher.go similarity index 93% rename from vendor/github.com/coreos/etcd/storage/watcher.go rename to vendor/github.com/coreos/etcd/mvcc/watcher.go index 6449c453ae7..9353f835683 100644 --- a/vendor/github.com/coreos/etcd/storage/watcher.go +++ b/vendor/github.com/coreos/etcd/mvcc/watcher.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. @@ -12,17 +12,17 @@ // See the License for the specific language governing permissions and // limitations under the License. -package storage +package mvcc import ( "errors" "sync" - "github.com/coreos/etcd/storage/storagepb" + "github.com/coreos/etcd/mvcc/mvccpb" ) var ( - ErrWatcherNotExist = errors.New("storage: watcher does not exist") + ErrWatcherNotExist = errors.New("mvcc: watcher does not exist") ) type WatchID int64 @@ -66,7 +66,7 @@ type WatchResponse struct { WatchID WatchID // Events contains all the events that needs to send. - Events []storagepb.Event + Events []mvccpb.Event // Revision is the revision of the KV when the watchResponse is created. // For a normal response, the revision should be the same as the last @@ -117,13 +117,18 @@ func (ws *watchStream) Chan() <-chan WatchResponse { } func (ws *watchStream) Cancel(id WatchID) error { + ws.mu.Lock() cancel, ok := ws.cancels[id] + ok = ok && !ws.closed + if ok { + delete(ws.cancels, id) + delete(ws.watchers, id) + } + ws.mu.Unlock() if !ok { return ErrWatcherNotExist } cancel() - delete(ws.cancels, id) - delete(ws.watchers, id) return nil } diff --git a/vendor/github.com/coreos/etcd/storage/watcher_group.go b/vendor/github.com/coreos/etcd/mvcc/watcher_group.go similarity index 84% rename from vendor/github.com/coreos/etcd/storage/watcher_group.go rename to vendor/github.com/coreos/etcd/mvcc/watcher_group.go index 3f8f8cf3b1d..7a4d7daa80e 100644 --- a/vendor/github.com/coreos/etcd/storage/watcher_group.go +++ b/vendor/github.com/coreos/etcd/mvcc/watcher_group.go @@ -1,4 +1,4 @@ -// Copyright 2016 CoreOS, Inc. +// 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. @@ -12,13 +12,13 @@ // See the License for the specific language governing permissions and // limitations under the License. -package storage +package mvcc import ( "math" + "github.com/coreos/etcd/mvcc/mvccpb" "github.com/coreos/etcd/pkg/adt" - "github.com/coreos/etcd/storage/storagepb" ) var ( @@ -30,14 +30,14 @@ var ( type eventBatch struct { // evs is a batch of revision-ordered events - evs []storagepb.Event + evs []mvccpb.Event // revs is the minimum unique revisions observed for this batch revs int // moreRev is first revision with more events following this batch moreRev int64 } -func (eb *eventBatch) add(ev storagepb.Event) { +func (eb *eventBatch) add(ev mvccpb.Event) { if eb.revs > watchBatchMaxRevs { // maxed out batch size return @@ -66,7 +66,7 @@ func (eb *eventBatch) add(ev storagepb.Event) { type watcherBatch map[*watcher]*eventBatch -func (wb watcherBatch) add(w *watcher, ev storagepb.Event) { +func (wb watcherBatch) add(w *watcher, ev mvccpb.Event) { eb := wb[w] if eb == nil { eb = &eventBatch{} @@ -75,18 +75,13 @@ func (wb watcherBatch) add(w *watcher, ev storagepb.Event) { eb.add(ev) } -func (wb watcherBatch) contains(w *watcher) bool { - _, ok := wb[w] - return ok -} - // newWatcherBatch maps watchers to their matched events. It enables quick // events look up by watcher. -func newWatcherBatch(wg *watcherGroup, evs []storagepb.Event) watcherBatch { +func newWatcherBatch(wg *watcherGroup, evs []mvccpb.Event) watcherBatch { wb := make(watcherBatch) for _, ev := range evs { for w := range wg.watcherSetByKey(string(ev.Kv.Key)) { - if ev.Kv.ModRevision >= w.cur { + if ev.Kv.ModRevision >= w.minRev { // don't double notify wb.add(w, ev) } @@ -219,29 +214,46 @@ func (wg *watcherGroup) delete(wa *watcher) bool { return true } -func (wg *watcherGroup) scanMinRev(curRev int64, compactRev int64) int64 { +// choose selects watchers from the watcher group to update +func (wg *watcherGroup) choose(maxWatchers int, curRev, compactRev int64) (*watcherGroup, int64) { + if len(wg.watchers) < maxWatchers { + return wg, wg.chooseAll(curRev, compactRev) + } + ret := newWatcherGroup() + for w := range wg.watchers { + if maxWatchers <= 0 { + break + } + maxWatchers-- + ret.add(w) + } + return &ret, ret.chooseAll(curRev, compactRev) +} + +func (wg *watcherGroup) chooseAll(curRev, compactRev int64) int64 { minRev := int64(math.MaxInt64) for w := range wg.watchers { - if w.cur > curRev { + if w.minRev > curRev { panic("watcher current revision should not exceed current revision") } - if w.cur < compactRev { + if w.minRev < compactRev { select { case w.ch <- WatchResponse{WatchID: w.id, CompactRevision: compactRev}: + w.compacted = true wg.delete(w) default: // retry next time } continue } - if minRev > w.cur { - minRev = w.cur + if minRev > w.minRev { + minRev = w.minRev } } return minRev } -// watcherSetByKey gets the set of watchers that recieve events on the given key. +// watcherSetByKey gets the set of watchers that receive events on the given key. func (wg *watcherGroup) watcherSetByKey(key string) watcherSet { wkeys := wg.keyWatchers[key] wranges := wg.ranges.Stab(adt.NewStringAffinePoint(key)) diff --git a/vendor/github.com/coreos/etcd/storage/backend/boltoption_freebsd.go b/vendor/github.com/coreos/etcd/pkg/adt/doc.go similarity index 82% rename from vendor/github.com/coreos/etcd/storage/backend/boltoption_freebsd.go rename to vendor/github.com/coreos/etcd/pkg/adt/doc.go index 67269f0b55b..1a9559145b3 100644 --- a/vendor/github.com/coreos/etcd/storage/backend/boltoption_freebsd.go +++ b/vendor/github.com/coreos/etcd/pkg/adt/doc.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// 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. @@ -12,8 +12,5 @@ // See the License for the specific language governing permissions and // limitations under the License. -package backend - -import "github.com/boltdb/bolt" - -var boltOpenOptions *bolt.Options = nil +// Package adt implements useful abstract data types. +package adt 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 a3ec803f64f..ab311c6d677 100644 --- a/vendor/github.com/coreos/etcd/pkg/adt/interval_tree.go +++ b/vendor/github.com/coreos/etcd/pkg/adt/interval_tree.go @@ -1,4 +1,4 @@ -// Copyright 2016 CoreOS, Inc. +// 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. diff --git a/vendor/github.com/coreos/etcd/pkg/contention/contention.go b/vendor/github.com/coreos/etcd/pkg/contention/contention.go index 9a96a8d77ab..26ce9a2f347 100644 --- a/vendor/github.com/coreos/etcd/pkg/contention/contention.go +++ b/vendor/github.com/coreos/etcd/pkg/contention/contention.go @@ -1,4 +1,4 @@ -// Copyright 2016 CoreOS, Inc. +// 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. diff --git a/vendor/github.com/coreos/etcd/pkg/contention/doc.go b/vendor/github.com/coreos/etcd/pkg/contention/doc.go new file mode 100644 index 00000000000..daf452219e0 --- /dev/null +++ b/vendor/github.com/coreos/etcd/pkg/contention/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 contention provides facilities for detecting system contention. +package contention diff --git a/vendor/github.com/coreos/etcd/pkg/fileutil/fileutil.go b/vendor/github.com/coreos/etcd/pkg/fileutil/fileutil.go index 145886a1a03..c963a79032e 100644 --- a/vendor/github.com/coreos/etcd/pkg/fileutil/fileutil.go +++ b/vendor/github.com/coreos/etcd/pkg/fileutil/fileutil.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. @@ -16,6 +16,7 @@ package fileutil import ( + "fmt" "io/ioutil" "os" "path" @@ -25,9 +26,10 @@ import ( ) const ( - privateFileMode = 0600 - // owner can make/remove files inside the directory - privateDirMode = 0700 + // PrivateFileMode grants owner to read/write a file. + PrivateFileMode = 0600 + // PrivateDirMode grants owner to make/remove files inside the directory. + PrivateDirMode = 0700 ) var ( @@ -38,7 +40,7 @@ var ( // to dir. It returns nil if dir is writable. func IsDirWriteable(dir string) error { f := path.Join(dir, ".touch") - if err := ioutil.WriteFile(f, []byte(""), privateFileMode); err != nil { + if err := ioutil.WriteFile(f, []byte(""), PrivateFileMode); err != nil { return err } return os.Remove(f) @@ -62,13 +64,34 @@ func ReadDir(dirpath string) ([]string, error) { // TouchDirAll is similar to os.MkdirAll. It creates directories with 0700 permission if any directory // does not exists. TouchDirAll also ensures the given directory is writable. func TouchDirAll(dir string) error { - err := os.MkdirAll(dir, privateDirMode) - if err != nil && err != os.ErrExist { + // If path is already a directory, MkdirAll does nothing + // and returns nil. + err := os.MkdirAll(dir, PrivateDirMode) + if err != nil { + // if mkdirAll("a/text") and "text" is not + // a directory, this will return syscall.ENOTDIR return err } return IsDirWriteable(dir) } +// CreateDirAll is similar to TouchDirAll but returns error +// if the deepest directory was not empty. +func CreateDirAll(dir string) error { + err := TouchDirAll(dir) + if err == nil { + var ns []string + ns, err = ReadDir(dir) + if err != nil { + return err + } + if len(ns) != 0 { + err = fmt.Errorf("expected %q to be empty, got %q", dir, ns) + } + } + return err +} + func Exist(name string) bool { _, err := os.Stat(name) return err == nil diff --git a/vendor/github.com/coreos/etcd/pkg/fileutil/lock.go b/vendor/github.com/coreos/etcd/pkg/fileutil/lock.go index da2b92c7314..338627f43c8 100644 --- a/vendor/github.com/coreos/etcd/pkg/fileutil/lock.go +++ b/vendor/github.com/coreos/etcd/pkg/fileutil/lock.go @@ -1,4 +1,4 @@ -// Copyright 2016 CoreOS, Inc. +// 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. diff --git a/vendor/github.com/coreos/etcd/pkg/fileutil/lock_flock.go b/vendor/github.com/coreos/etcd/pkg/fileutil/lock_flock.go new file mode 100644 index 00000000000..542550bc8a9 --- /dev/null +++ b/vendor/github.com/coreos/etcd/pkg/fileutil/lock_flock.go @@ -0,0 +1,49 @@ +// 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 !windows,!plan9,!solaris + +package fileutil + +import ( + "os" + "syscall" +) + +func flockTryLockFile(path string, flag int, perm os.FileMode) (*LockedFile, error) { + f, err := os.OpenFile(path, flag, perm) + if err != nil { + return nil, err + } + if err = syscall.Flock(int(f.Fd()), syscall.LOCK_EX|syscall.LOCK_NB); err != nil { + f.Close() + if err == syscall.EWOULDBLOCK { + err = ErrLocked + } + return nil, err + } + return &LockedFile{f}, nil +} + +func flockLockFile(path string, flag int, perm os.FileMode) (*LockedFile, error) { + f, err := os.OpenFile(path, flag, perm) + if err != nil { + return nil, err + } + if err = syscall.Flock(int(f.Fd()), syscall.LOCK_EX); err != nil { + f.Close() + return nil, err + } + return &LockedFile{f}, err +} diff --git a/vendor/github.com/coreos/etcd/pkg/fileutil/lock_linux.go b/vendor/github.com/coreos/etcd/pkg/fileutil/lock_linux.go new file mode 100644 index 00000000000..dec25a1af44 --- /dev/null +++ b/vendor/github.com/coreos/etcd/pkg/fileutil/lock_linux.go @@ -0,0 +1,96 @@ +// 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 fileutil + +import ( + "os" + "syscall" +) + +// This used to call syscall.Flock() but that call fails with EBADF on NFS. +// An alternative is lockf() which works on NFS but that call lets a process lock +// the same file twice. Instead, use Linux's non-standard open file descriptor +// locks which will block if the process already holds the file lock. +// +// constants from /usr/include/bits/fcntl-linux.h +const ( + F_OFD_GETLK = 37 + F_OFD_SETLK = 37 + F_OFD_SETLKW = 38 +) + +var ( + wrlck = syscall.Flock_t{ + Type: syscall.F_WRLCK, + Whence: int16(os.SEEK_SET), + Start: 0, + Len: 0, + } + + linuxTryLockFile = flockTryLockFile + linuxLockFile = flockLockFile +) + +func init() { + // use open file descriptor locks if the system supports it + getlk := syscall.Flock_t{Type: syscall.F_RDLCK} + if err := syscall.FcntlFlock(0, F_OFD_GETLK, &getlk); err == nil { + linuxTryLockFile = ofdTryLockFile + linuxLockFile = ofdLockFile + } +} + +func TryLockFile(path string, flag int, perm os.FileMode) (*LockedFile, error) { + return linuxTryLockFile(path, flag, perm) +} + +func ofdTryLockFile(path string, flag int, perm os.FileMode) (*LockedFile, error) { + f, err := os.OpenFile(path, flag, perm) + if err != nil { + return nil, err + } + + flock := wrlck + if err = syscall.FcntlFlock(f.Fd(), F_OFD_SETLK, &flock); err != nil { + f.Close() + if err == syscall.EWOULDBLOCK { + err = ErrLocked + } + return nil, err + } + return &LockedFile{f}, nil +} + +func LockFile(path string, flag int, perm os.FileMode) (*LockedFile, error) { + return linuxLockFile(path, flag, perm) +} + +func ofdLockFile(path string, flag int, perm os.FileMode) (*LockedFile, error) { + f, err := os.OpenFile(path, flag, perm) + if err != nil { + return nil, err + } + + flock := wrlck + err = syscall.FcntlFlock(f.Fd(), F_OFD_SETLKW, &flock) + + if err != nil { + f.Close() + return nil, err + } + return &LockedFile{f}, err +} diff --git a/vendor/github.com/coreos/etcd/pkg/fileutil/lock_plan9.go b/vendor/github.com/coreos/etcd/pkg/fileutil/lock_plan9.go index 1c924a7e5f6..fee6a7c8f46 100644 --- a/vendor/github.com/coreos/etcd/pkg/fileutil/lock_plan9.go +++ b/vendor/github.com/coreos/etcd/pkg/fileutil/lock_plan9.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. @@ -21,7 +21,7 @@ import ( ) func TryLockFile(path string, flag int, perm os.FileMode) (*LockedFile, error) { - if err := os.Chmod(path, syscall.DMEXCL|0600); err != nil { + if err := os.Chmod(path, syscall.DMEXCL|PrivateFileMode); err != nil { return nil, err } f, err := os.Open(path, flag, perm) @@ -32,7 +32,7 @@ func TryLockFile(path string, flag int, perm os.FileMode) (*LockedFile, error) { } func LockFile(path string, flag int, perm os.FileMode) (*LockedFile, error) { - if err := os.Chmod(path, syscall.DMEXCL|0600); err != nil { + if err := os.Chmod(path, syscall.DMEXCL|PrivateFileMode); err != nil { return nil, err } for { diff --git a/vendor/github.com/coreos/etcd/pkg/fileutil/lock_solaris.go b/vendor/github.com/coreos/etcd/pkg/fileutil/lock_solaris.go index 0d5375aee74..352ca5590d1 100644 --- a/vendor/github.com/coreos/etcd/pkg/fileutil/lock_solaris.go +++ b/vendor/github.com/coreos/etcd/pkg/fileutil/lock_solaris.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. diff --git a/vendor/github.com/coreos/etcd/pkg/fileutil/lock_unix.go b/vendor/github.com/coreos/etcd/pkg/fileutil/lock_unix.go index aa5127ef550..ed01164de6e 100644 --- a/vendor/github.com/coreos/etcd/pkg/fileutil/lock_unix.go +++ b/vendor/github.com/coreos/etcd/pkg/fileutil/lock_unix.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. @@ -12,38 +12,18 @@ // See the License for the specific language governing permissions and // limitations under the License. -// +build !windows,!plan9,!solaris +// +build !windows,!plan9,!solaris,!linux package fileutil import ( "os" - "syscall" ) func TryLockFile(path string, flag int, perm os.FileMode) (*LockedFile, error) { - f, err := os.OpenFile(path, flag, perm) - if err != nil { - return nil, err - } - if err = syscall.Flock(int(f.Fd()), syscall.LOCK_EX|syscall.LOCK_NB); err != nil { - f.Close() - if err == syscall.EWOULDBLOCK { - err = ErrLocked - } - return nil, err - } - return &LockedFile{f}, nil + return flockTryLockFile(path, flag, perm) } func LockFile(path string, flag int, perm os.FileMode) (*LockedFile, error) { - f, err := os.OpenFile(path, flag, perm) - if err != nil { - return nil, err - } - if err = syscall.Flock(int(f.Fd()), syscall.LOCK_EX); err != nil { - f.Close() - return nil, err - } - return &LockedFile{f}, err + return flockLockFile(path, flag, perm) } diff --git a/vendor/github.com/coreos/etcd/pkg/fileutil/lock_windows.go b/vendor/github.com/coreos/etcd/pkg/fileutil/lock_windows.go index 67a425a9124..8698f4a8d11 100644 --- a/vendor/github.com/coreos/etcd/pkg/fileutil/lock_windows.go +++ b/vendor/github.com/coreos/etcd/pkg/fileutil/lock_windows.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. diff --git a/vendor/github.com/coreos/etcd/pkg/fileutil/preallocate.go b/vendor/github.com/coreos/etcd/pkg/fileutil/preallocate.go index 8cd03f015e4..bb7f0281239 100644 --- a/vendor/github.com/coreos/etcd/pkg/fileutil/preallocate.go +++ b/vendor/github.com/coreos/etcd/pkg/fileutil/preallocate.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. @@ -23,7 +23,7 @@ import "os" // Otherwise, the error encountered will be returned. func Preallocate(f *os.File, sizeInBytes int64, extendFile bool) error { if extendFile { - preallocExtend(f, sizeInBytes) + return preallocExtend(f, sizeInBytes) } return preallocFixed(f, sizeInBytes) } diff --git a/vendor/github.com/coreos/etcd/pkg/fileutil/preallocate_darwin.go b/vendor/github.com/coreos/etcd/pkg/fileutil/preallocate_darwin.go index 5ac19508a7c..1ed09c560f2 100644 --- a/vendor/github.com/coreos/etcd/pkg/fileutil/preallocate_darwin.go +++ b/vendor/github.com/coreos/etcd/pkg/fileutil/preallocate_darwin.go @@ -1,4 +1,4 @@ -// Copyright 2016 CoreOS, Inc. +// 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. diff --git a/vendor/github.com/coreos/etcd/pkg/fileutil/preallocate_unix.go b/vendor/github.com/coreos/etcd/pkg/fileutil/preallocate_unix.go index b71113e7259..50bd84f02ad 100644 --- a/vendor/github.com/coreos/etcd/pkg/fileutil/preallocate_unix.go +++ b/vendor/github.com/coreos/etcd/pkg/fileutil/preallocate_unix.go @@ -1,4 +1,4 @@ -// Copyright 2016 CoreOS, Inc. +// 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. @@ -26,8 +26,9 @@ func preallocExtend(f *os.File, sizeInBytes int64) error { err := syscall.Fallocate(int(f.Fd()), 0, 0, sizeInBytes) if err != nil { errno, ok := err.(syscall.Errno) - // treat not support as nil error - if ok && errno == syscall.ENOTSUP { + // not supported; fallback + // fallocate EINTRs frequently in some environments; fallback + if ok && (errno == syscall.ENOTSUP || errno == syscall.EINTR) { return preallocExtendTrunc(f, sizeInBytes) } } diff --git a/vendor/github.com/coreos/etcd/pkg/fileutil/preallocate_unsupported.go b/vendor/github.com/coreos/etcd/pkg/fileutil/preallocate_unsupported.go index 7f94a3653ef..162fbc5f782 100644 --- a/vendor/github.com/coreos/etcd/pkg/fileutil/preallocate_unsupported.go +++ b/vendor/github.com/coreos/etcd/pkg/fileutil/preallocate_unsupported.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. diff --git a/vendor/github.com/coreos/etcd/pkg/fileutil/purge.go b/vendor/github.com/coreos/etcd/pkg/fileutil/purge.go index 0d1bd99c0d6..53bda0c0120 100644 --- a/vendor/github.com/coreos/etcd/pkg/fileutil/purge.go +++ b/vendor/github.com/coreos/etcd/pkg/fileutil/purge.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. @@ -23,6 +23,11 @@ import ( ) func PurgeFile(dirname string, suffix string, max uint, interval time.Duration, stop <-chan struct{}) <-chan error { + return purgeFile(dirname, suffix, max, interval, stop, nil) +} + +// purgeFile is the internal implementation for PurgeFile which can post purged files to purgec if non-nil. +func purgeFile(dirname string, suffix string, max uint, interval time.Duration, stop <-chan struct{}, purgec chan<- string) <-chan error { errC := make(chan error, 1) go func() { for { @@ -38,9 +43,10 @@ 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]) - l, err := TryLockFile(f, os.O_WRONLY, 0600) + l, err := TryLockFile(f, os.O_WRONLY, PrivateFileMode) if err != nil { break } @@ -56,6 +62,11 @@ func PurgeFile(dirname string, suffix string, max uint, interval time.Duration, plog.Infof("purged file %s successfully", f) newfnames = newfnames[1:] } + if purgec != nil { + for i := 0; i < len(fnames)-len(newfnames); i++ { + purgec <- fnames[i] + } + } select { case <-time.After(interval): case <-stop: diff --git a/vendor/github.com/coreos/etcd/pkg/fileutil/sync.go b/vendor/github.com/coreos/etcd/pkg/fileutil/sync.go index cd7fff08f64..54dd41f4f35 100644 --- a/vendor/github.com/coreos/etcd/pkg/fileutil/sync.go +++ b/vendor/github.com/coreos/etcd/pkg/fileutil/sync.go @@ -1,4 +1,4 @@ -// Copyright 2016 CoreOS, Inc. +// 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. @@ -12,15 +12,18 @@ // See the License for the specific language governing permissions and // limitations under the License. -// +build !linux +// +build !linux,!darwin package fileutil import "os" -// Fdatasync is similar to fsync(), but does not flush modified metadata -// unless that metadata is needed in order to allow a subsequent data retrieval -// to be correctly handled. +// Fsync is a wrapper around file.Sync(). Special handling is needed on darwin platform. +func Fsync(f *os.File) error { + return f.Sync() +} + +// Fdatasync is a wrapper around file.Sync(). Special handling is needed on linux platform. func Fdatasync(f *os.File) error { return f.Sync() } diff --git a/vendor/github.com/coreos/etcd/pkg/fileutil/sync_darwin.go b/vendor/github.com/coreos/etcd/pkg/fileutil/sync_darwin.go new file mode 100644 index 00000000000..c2f39bf204d --- /dev/null +++ b/vendor/github.com/coreos/etcd/pkg/fileutil/sync_darwin.go @@ -0,0 +1,40 @@ +// 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 darwin + +package fileutil + +import ( + "os" + "syscall" +) + +// Fsync on HFS/OSX flushes the data on to the physical drive but the drive +// may not write it to the persistent media for quite sometime and it may be +// written in out-of-order sequence. Using F_FULLFSYNC ensures that the +// physical drive's buffer will also get flushed to the media. +func Fsync(f *os.File) error { + _, _, errno := syscall.Syscall(syscall.SYS_FCNTL, f.Fd(), uintptr(syscall.F_FULLFSYNC), uintptr(0)) + if errno == 0 { + return nil + } + return errno +} + +// Fdatasync on darwin platform invokes fcntl(F_FULLFSYNC) for actual persistence +// on physical drive media. +func Fdatasync(f *os.File) error { + return Fsync(f) +} diff --git a/vendor/github.com/coreos/etcd/pkg/fileutil/sync_linux.go b/vendor/github.com/coreos/etcd/pkg/fileutil/sync_linux.go index 14c4b4808e3..1bbced915e9 100644 --- a/vendor/github.com/coreos/etcd/pkg/fileutil/sync_linux.go +++ b/vendor/github.com/coreos/etcd/pkg/fileutil/sync_linux.go @@ -1,4 +1,4 @@ -// Copyright 2016 CoreOS, Inc. +// 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. @@ -21,6 +21,11 @@ import ( "syscall" ) +// Fsync is a wrapper around file.Sync(). Special handling is needed on darwin platform. +func Fsync(f *os.File) error { + return f.Sync() +} + // Fdatasync is similar to fsync(), but does not flush modified metadata // unless that metadata is needed in order to allow a subsequent data retrieval // to be correctly handled. diff --git a/vendor/github.com/coreos/etcd/pkg/idutil/id.go b/vendor/github.com/coreos/etcd/pkg/idutil/id.go index 6f1d379112a..931beb2d058 100644 --- a/vendor/github.com/coreos/etcd/pkg/idutil/id.go +++ b/vendor/github.com/coreos/etcd/pkg/idutil/id.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. diff --git a/vendor/github.com/coreos/etcd/pkg/ioutil/readcloser.go b/vendor/github.com/coreos/etcd/pkg/ioutil/readcloser.go index 7c1fda1c289..d3efcfe3d5a 100644 --- a/vendor/github.com/coreos/etcd/pkg/ioutil/readcloser.go +++ b/vendor/github.com/coreos/etcd/pkg/ioutil/readcloser.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. @@ -14,7 +14,10 @@ package ioutil -import "io" +import ( + "fmt" + "io" +) // ReaderAndCloser implements io.ReadCloser interface by combining // reader and closer together. @@ -22,3 +25,42 @@ type ReaderAndCloser struct { io.Reader io.Closer } + +var ( + ErrShortRead = fmt.Errorf("ioutil: short read") + ErrExpectEOF = fmt.Errorf("ioutil: expect EOF") +) + +// NewExactReadCloser returns a ReadCloser that returns errors if the underlying +// reader does not read back exactly the requested number of bytes. +func NewExactReadCloser(rc io.ReadCloser, totalBytes int64) io.ReadCloser { + return &exactReadCloser{rc: rc, totalBytes: totalBytes} +} + +type exactReadCloser struct { + rc io.ReadCloser + br int64 + totalBytes int64 +} + +func (e *exactReadCloser) Read(p []byte) (int, error) { + n, err := e.rc.Read(p) + e.br += int64(n) + if e.br > e.totalBytes { + return 0, ErrExpectEOF + } + if e.br < e.totalBytes && n == 0 { + return 0, ErrShortRead + } + return n, err +} + +func (e *exactReadCloser) Close() error { + if err := e.rc.Close(); err != nil { + return err + } + if e.br < e.totalBytes { + return ErrShortRead + } + return nil +} diff --git a/vendor/github.com/coreos/etcd/pkg/ioutil/reader.go b/vendor/github.com/coreos/etcd/pkg/ioutil/reader.go index 8ef9a933070..0703ed476d8 100644 --- a/vendor/github.com/coreos/etcd/pkg/ioutil/reader.go +++ b/vendor/github.com/coreos/etcd/pkg/ioutil/reader.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. diff --git a/vendor/github.com/coreos/etcd/pkg/ioutil/util.go b/vendor/github.com/coreos/etcd/pkg/ioutil/util.go index 9acc7983018..192ad888c24 100644 --- a/vendor/github.com/coreos/etcd/pkg/ioutil/util.go +++ b/vendor/github.com/coreos/etcd/pkg/ioutil/util.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. @@ -17,6 +17,8 @@ package ioutil import ( "io" "os" + + "github.com/coreos/etcd/pkg/fileutil" ) // WriteAndSyncFile behaves just like ioutil.WriteFile in the standard library, @@ -32,7 +34,7 @@ func WriteAndSyncFile(filename string, data []byte, perm os.FileMode) error { err = io.ErrShortWrite } if err == nil { - err = f.Sync() + err = fileutil.Fsync(f) } if err1 := f.Close(); err == nil { err = err1 diff --git a/vendor/github.com/coreos/etcd/pkg/logutil/merge_logger.go b/vendor/github.com/coreos/etcd/pkg/logutil/merge_logger.go index 8e82c520af4..cc750f4d3d6 100644 --- a/vendor/github.com/coreos/etcd/pkg/logutil/merge_logger.go +++ b/vendor/github.com/coreos/etcd/pkg/logutil/merge_logger.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. 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 c61f16c58a3..c866cea8ee1 100644 --- a/vendor/github.com/coreos/etcd/pkg/netutil/isolate_linux.go +++ b/vendor/github.com/coreos/etcd/pkg/netutil/isolate_linux.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. diff --git a/vendor/github.com/coreos/etcd/pkg/netutil/isolate_stub.go b/vendor/github.com/coreos/etcd/pkg/netutil/isolate_stub.go index d517fd688e0..7f4c3e67c2a 100644 --- a/vendor/github.com/coreos/etcd/pkg/netutil/isolate_stub.go +++ b/vendor/github.com/coreos/etcd/pkg/netutil/isolate_stub.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. diff --git a/vendor/github.com/coreos/etcd/pkg/netutil/netutil.go b/vendor/github.com/coreos/etcd/pkg/netutil/netutil.go index 4292cd06f63..b13ebcc9381 100644 --- a/vendor/github.com/coreos/etcd/pkg/netutil/netutil.go +++ b/vendor/github.com/coreos/etcd/pkg/netutil/netutil.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. diff --git a/vendor/github.com/coreos/etcd/pkg/pbutil/pbutil.go b/vendor/github.com/coreos/etcd/pkg/pbutil/pbutil.go index 9d640a8af6f..8f96b4d5490 100644 --- a/vendor/github.com/coreos/etcd/pkg/pbutil/pbutil.go +++ b/vendor/github.com/coreos/etcd/pkg/pbutil/pbutil.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. diff --git a/vendor/github.com/coreos/etcd/pkg/runtime/fds_linux.go b/vendor/github.com/coreos/etcd/pkg/runtime/fds_linux.go index d8111440559..8e9359db28c 100644 --- a/vendor/github.com/coreos/etcd/pkg/runtime/fds_linux.go +++ b/vendor/github.com/coreos/etcd/pkg/runtime/fds_linux.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. diff --git a/vendor/github.com/coreos/etcd/pkg/runtime/fds_other.go b/vendor/github.com/coreos/etcd/pkg/runtime/fds_other.go index 0ed152f0f35..0cbdb88c7a6 100644 --- a/vendor/github.com/coreos/etcd/pkg/runtime/fds_other.go +++ b/vendor/github.com/coreos/etcd/pkg/runtime/fds_other.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. diff --git a/vendor/github.com/coreos/etcd/pkg/schedule/doc.go b/vendor/github.com/coreos/etcd/pkg/schedule/doc.go new file mode 100644 index 00000000000..cca2c75fb6a --- /dev/null +++ b/vendor/github.com/coreos/etcd/pkg/schedule/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 schedule provides mechanisms and policies for scheduling units of work. +package schedule diff --git a/vendor/github.com/coreos/etcd/pkg/schedule/schedule.go b/vendor/github.com/coreos/etcd/pkg/schedule/schedule.go index d566364b164..79c59b01288 100644 --- a/vendor/github.com/coreos/etcd/pkg/schedule/schedule.go +++ b/vendor/github.com/coreos/etcd/pkg/schedule/schedule.go @@ -1,4 +1,4 @@ -// Copyright 2016 CoreOS, Inc. +// 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. diff --git a/vendor/github.com/coreos/etcd/pkg/testutil/leak.go b/vendor/github.com/coreos/etcd/pkg/testutil/leak.go index 79b8b2db4d6..0f2ee559fb9 100644 --- a/vendor/github.com/coreos/etcd/pkg/testutil/leak.go +++ b/vendor/github.com/coreos/etcd/pkg/testutil/leak.go @@ -48,7 +48,7 @@ func CheckLeakedGoroutine() bool { } stackCount := make(map[string]int) - re := regexp.MustCompile("\\(0[0-9a-fx, ]*\\)") + re := regexp.MustCompile(`\(0[0-9a-fx, ]*\)`) for _, g := range gs { // strip out pointer arguments in first function of stack dump normalized := string(re.ReplaceAll([]byte(g), []byte("(...)"))) diff --git a/vendor/github.com/coreos/etcd/pkg/testutil/pauseable_handler.go b/vendor/github.com/coreos/etcd/pkg/testutil/pauseable_handler.go index 99582810253..e0d6aca26df 100644 --- a/vendor/github.com/coreos/etcd/pkg/testutil/pauseable_handler.go +++ b/vendor/github.com/coreos/etcd/pkg/testutil/pauseable_handler.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. diff --git a/vendor/github.com/coreos/etcd/pkg/testutil/recorder.go b/vendor/github.com/coreos/etcd/pkg/testutil/recorder.go index 326edaf3744..bdbbd8cc5d5 100644 --- a/vendor/github.com/coreos/etcd/pkg/testutil/recorder.go +++ b/vendor/github.com/coreos/etcd/pkg/testutil/recorder.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. diff --git a/vendor/github.com/coreos/etcd/pkg/testutil/testutil.go b/vendor/github.com/coreos/etcd/pkg/testutil/testutil.go index a789667b5c0..a67eded1e2d 100644 --- a/vendor/github.com/coreos/etcd/pkg/testutil/testutil.go +++ b/vendor/github.com/coreos/etcd/pkg/testutil/testutil.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. diff --git a/vendor/github.com/coreos/etcd/storage/backend/boltoption_solaris.go b/vendor/github.com/coreos/etcd/pkg/tlsutil/doc.go similarity index 82% rename from vendor/github.com/coreos/etcd/storage/backend/boltoption_solaris.go rename to vendor/github.com/coreos/etcd/pkg/tlsutil/doc.go index f12bf58a2ea..3b6aa670baf 100644 --- a/vendor/github.com/coreos/etcd/storage/backend/boltoption_solaris.go +++ b/vendor/github.com/coreos/etcd/pkg/tlsutil/doc.go @@ -1,4 +1,4 @@ -// Copyright 2016 CoreOS, Inc. +// 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. @@ -12,8 +12,5 @@ // See the License for the specific language governing permissions and // limitations under the License. -package backend - -import "github.com/boltdb/bolt" - -var boltOpenOptions *bolt.Options = nil +// Package tlsutil provides utility functions for handling TLS. +package tlsutil diff --git a/vendor/github.com/coreos/etcd/pkg/tlsutil/tlsutil.go b/vendor/github.com/coreos/etcd/pkg/tlsutil/tlsutil.go index 340dd2c09d0..79b1f632ed5 100644 --- a/vendor/github.com/coreos/etcd/pkg/tlsutil/tlsutil.go +++ b/vendor/github.com/coreos/etcd/pkg/tlsutil/tlsutil.go @@ -1,4 +1,4 @@ -// Copyright 2016 CoreOS, Inc. +// 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. diff --git a/vendor/github.com/coreos/etcd/pkg/transport/doc.go b/vendor/github.com/coreos/etcd/pkg/transport/doc.go index 4411e448751..37658ce591a 100644 --- a/vendor/github.com/coreos/etcd/pkg/transport/doc.go +++ b/vendor/github.com/coreos/etcd/pkg/transport/doc.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. diff --git a/vendor/github.com/coreos/etcd/pkg/transport/keepalive_listener.go b/vendor/github.com/coreos/etcd/pkg/transport/keepalive_listener.go index ee9a3a13e5b..6ccae4ee4a1 100644 --- a/vendor/github.com/coreos/etcd/pkg/transport/keepalive_listener.go +++ b/vendor/github.com/coreos/etcd/pkg/transport/keepalive_listener.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. diff --git a/vendor/github.com/coreos/etcd/pkg/transport/limit_listen.go b/vendor/github.com/coreos/etcd/pkg/transport/limit_listen.go index ad2bc417c21..930c542066f 100644 --- a/vendor/github.com/coreos/etcd/pkg/transport/limit_listen.go +++ b/vendor/github.com/coreos/etcd/pkg/transport/limit_listen.go @@ -1,6 +1,16 @@ -// Copyright 2013 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. +// Copyright 2013 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 transport provides network utility functions, complementing the more // common ones in the net package. diff --git a/vendor/github.com/coreos/etcd/pkg/transport/listener.go b/vendor/github.com/coreos/etcd/pkg/transport/listener.go index 931652d3f13..d94757b2c52 100644 --- a/vendor/github.com/coreos/etcd/pkg/transport/listener.go +++ b/vendor/github.com/coreos/etcd/pkg/transport/listener.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. @@ -25,28 +25,28 @@ import ( "fmt" "math/big" "net" - "net/http" "os" "path" "strings" "time" + "github.com/coreos/etcd/pkg/fileutil" "github.com/coreos/etcd/pkg/tlsutil" ) -func NewListener(addr string, scheme string, tlscfg *tls.Config) (net.Listener, error) { - nettype := "tcp" - if scheme == "unix" { +func NewListener(addr string, scheme string, tlscfg *tls.Config) (l net.Listener, err error) { + if scheme == "unix" || scheme == "unixs" { // unix sockets via unix://laddr - nettype = scheme + l, err = NewUnixListener(addr) + } else { + l, err = net.Listen("tcp", addr) } - l, err := net.Listen(nettype, addr) if err != nil { return nil, err } - if scheme == "https" { + 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) } @@ -57,27 +57,6 @@ func NewListener(addr string, scheme string, tlscfg *tls.Config) (net.Listener, return l, nil } -func NewTransport(info TLSInfo, dialtimeoutd time.Duration) (*http.Transport, error) { - cfg, err := info.ClientConfig() - if err != nil { - return nil, err - } - - t := &http.Transport{ - Proxy: http.ProxyFromEnvironment, - Dial: (&net.Dialer{ - Timeout: dialtimeoutd, - // value taken from http.DefaultTransport - KeepAlive: 30 * time.Second, - }).Dial, - // value taken from http.DefaultTransport - TLSHandshakeTimeout: 10 * time.Second, - TLSClientConfig: cfg, - } - - return t, nil -} - type TLSInfo struct { CertFile string KeyFile string @@ -101,7 +80,7 @@ func (info TLSInfo) Empty() bool { } func SelfCert(dirpath string, hosts []string) (info TLSInfo, err error) { - if err = os.MkdirAll(dirpath, 0700); err != nil { + if err = fileutil.TouchDirAll(dirpath); err != nil { return } @@ -184,7 +163,7 @@ func (info TLSInfo) baseConfig() (*tls.Config, error) { cfg := &tls.Config{ Certificates: []tls.Certificate{*tlsCert}, - MinVersion: tls.VersionTLS10, + MinVersion: tls.VersionTLS12, } return cfg, nil } @@ -252,3 +231,32 @@ func (info TLSInfo) ClientConfig() (*tls.Config, error) { } return cfg, nil } + +// ShallowCopyTLSConfig copies *tls.Config. This is only +// work-around for go-vet tests, which complains +// +// assignment copies lock value to p: crypto/tls.Config contains sync.Once contains sync.Mutex +// +// Keep up-to-date with 'go/src/crypto/tls/common.go' +func ShallowCopyTLSConfig(cfg *tls.Config) *tls.Config { + ncfg := tls.Config{ + Time: cfg.Time, + Certificates: cfg.Certificates, + NameToCertificate: cfg.NameToCertificate, + GetCertificate: cfg.GetCertificate, + RootCAs: cfg.RootCAs, + NextProtos: cfg.NextProtos, + ServerName: cfg.ServerName, + ClientAuth: cfg.ClientAuth, + ClientCAs: cfg.ClientCAs, + InsecureSkipVerify: cfg.InsecureSkipVerify, + CipherSuites: cfg.CipherSuites, + PreferServerCipherSuites: cfg.PreferServerCipherSuites, + SessionTicketKey: cfg.SessionTicketKey, + ClientSessionCache: cfg.ClientSessionCache, + MinVersion: cfg.MinVersion, + MaxVersion: cfg.MaxVersion, + CurvePreferences: cfg.CurvePreferences, + } + return &ncfg +} diff --git a/vendor/github.com/coreos/etcd/pkg/transport/timeout_conn.go b/vendor/github.com/coreos/etcd/pkg/transport/timeout_conn.go index daca554e932..7e8c02030fe 100644 --- a/vendor/github.com/coreos/etcd/pkg/transport/timeout_conn.go +++ b/vendor/github.com/coreos/etcd/pkg/transport/timeout_conn.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. diff --git a/vendor/github.com/coreos/etcd/pkg/transport/timeout_dialer.go b/vendor/github.com/coreos/etcd/pkg/transport/timeout_dialer.go index 9bd61298043..6ae39ecfc9b 100644 --- a/vendor/github.com/coreos/etcd/pkg/transport/timeout_dialer.go +++ b/vendor/github.com/coreos/etcd/pkg/transport/timeout_dialer.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. 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 bf12ba6ed1d..f176c43b95d 100644 --- a/vendor/github.com/coreos/etcd/pkg/transport/timeout_listener.go +++ b/vendor/github.com/coreos/etcd/pkg/transport/timeout_listener.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. 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 e894c6e4f34..742cc5cbf18 100644 --- a/vendor/github.com/coreos/etcd/pkg/transport/timeout_transport.go +++ b/vendor/github.com/coreos/etcd/pkg/transport/timeout_transport.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. @@ -34,6 +34,9 @@ func NewTimeoutTransport(info TLSInfo, dialtimeoutd, rdtimeoutd, wtimeoutd time. // the timed out connection will timeout soon after it is idle. // 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. + tr.MaxIdleConnsPerHost = 1024 } tr.Dial = (&rwTimeoutDialer{ diff --git a/vendor/github.com/coreos/etcd/pkg/transport/transport.go b/vendor/github.com/coreos/etcd/pkg/transport/transport.go new file mode 100644 index 00000000000..ca9ccfd8025 --- /dev/null +++ b/vendor/github.com/coreos/etcd/pkg/transport/transport.go @@ -0,0 +1,70 @@ +// 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 transport + +import ( + "net" + "net/http" + "strings" + "time" +) + +type unixTransport struct{ *http.Transport } + +func NewTransport(info TLSInfo, dialtimeoutd time.Duration) (*http.Transport, error) { + cfg, err := info.ClientConfig() + if err != nil { + return nil, err + } + + t := &http.Transport{ + Proxy: http.ProxyFromEnvironment, + Dial: (&net.Dialer{ + Timeout: dialtimeoutd, + // value taken from http.DefaultTransport + KeepAlive: 30 * time.Second, + }).Dial, + // value taken from http.DefaultTransport + TLSHandshakeTimeout: 10 * time.Second, + TLSClientConfig: cfg, + } + + dialer := (&net.Dialer{ + Timeout: dialtimeoutd, + KeepAlive: 30 * time.Second, + }) + dial := func(net, addr string) (net.Conn, error) { + return dialer.Dial("unix", addr) + } + + tu := &http.Transport{ + Proxy: http.ProxyFromEnvironment, + Dial: dial, + TLSHandshakeTimeout: 10 * time.Second, + TLSClientConfig: cfg, + } + ut := &unixTransport{tu} + + t.RegisterProtocol("unix", ut) + t.RegisterProtocol("unixs", ut) + + return t, nil +} + +func (urt *unixTransport) RoundTrip(req *http.Request) (*http.Response, error) { + req2 := *req + req2.URL.Scheme = strings.Replace(req.URL.Scheme, "unix", "http", 1) + return urt.Transport.RoundTrip(req) +} diff --git a/vendor/github.com/coreos/etcd/pkg/transport/unix_listener.go b/vendor/github.com/coreos/etcd/pkg/transport/unix_listener.go new file mode 100644 index 00000000000..c126b6f7fa0 --- /dev/null +++ b/vendor/github.com/coreos/etcd/pkg/transport/unix_listener.go @@ -0,0 +1,40 @@ +// 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 transport + +import ( + "net" + "os" +) + +type unixListener struct{ net.Listener } + +func NewUnixListener(addr string) (net.Listener, error) { + if err := os.RemoveAll(addr); err != nil { + return nil, err + } + l, err := net.Listen("unix", addr) + if err != nil { + return nil, err + } + return &unixListener{l}, nil +} + +func (ul *unixListener) Close() error { + if err := os.RemoveAll(ul.Addr().String()); err != nil { + return err + } + return ul.Listener.Close() +} diff --git a/vendor/github.com/coreos/etcd/pkg/types/doc.go b/vendor/github.com/coreos/etcd/pkg/types/doc.go index 04b4c38d1ca..de8ef0bd712 100644 --- a/vendor/github.com/coreos/etcd/pkg/types/doc.go +++ b/vendor/github.com/coreos/etcd/pkg/types/doc.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. diff --git a/vendor/github.com/coreos/etcd/pkg/types/id.go b/vendor/github.com/coreos/etcd/pkg/types/id.go index 88cb9e63494..1b042d9ce65 100644 --- a/vendor/github.com/coreos/etcd/pkg/types/id.go +++ b/vendor/github.com/coreos/etcd/pkg/types/id.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. diff --git a/vendor/github.com/coreos/etcd/pkg/types/set.go b/vendor/github.com/coreos/etcd/pkg/types/set.go index bb997174c77..73ef431bef1 100644 --- a/vendor/github.com/coreos/etcd/pkg/types/set.go +++ b/vendor/github.com/coreos/etcd/pkg/types/set.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. diff --git a/vendor/github.com/coreos/etcd/pkg/types/slice.go b/vendor/github.com/coreos/etcd/pkg/types/slice.go index 0327950f706..0dd9ca798ae 100644 --- a/vendor/github.com/coreos/etcd/pkg/types/slice.go +++ b/vendor/github.com/coreos/etcd/pkg/types/slice.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. diff --git a/vendor/github.com/coreos/etcd/pkg/types/urls.go b/vendor/github.com/coreos/etcd/pkg/types/urls.go index 8d5ff624811..9e5d03ff645 100644 --- a/vendor/github.com/coreos/etcd/pkg/types/urls.go +++ b/vendor/github.com/coreos/etcd/pkg/types/urls.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. @@ -36,8 +36,8 @@ func NewURLs(strs []string) (URLs, error) { if err != nil { return nil, err } - if u.Scheme != "http" && u.Scheme != "https" { - return nil, fmt.Errorf("URL scheme must be http or https: %s", in) + if u.Scheme != "http" && u.Scheme != "https" && u.Scheme != "unix" && u.Scheme != "unixs" { + return nil, fmt.Errorf("URL scheme must be http, https, unix, or unixs: %s", in) } if _, _, err := net.SplitHostPort(u.Host); err != nil { return nil, fmt.Errorf(`URL address does not have the form "host:port": %s`, in) diff --git a/vendor/github.com/coreos/etcd/pkg/types/urlsmap.go b/vendor/github.com/coreos/etcd/pkg/types/urlsmap.go index 4fe9218c745..47690cc381a 100644 --- a/vendor/github.com/coreos/etcd/pkg/types/urlsmap.go +++ b/vendor/github.com/coreos/etcd/pkg/types/urlsmap.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. @@ -40,6 +40,20 @@ func NewURLsMap(s string) (URLsMap, error) { return cl, nil } +// NewURLsMapFromStringMap takes a map of strings and returns a URLsMap. The +// string values in the map can be multiple values separated by the sep string. +func NewURLsMapFromStringMap(m map[string]string, sep string) (URLsMap, error) { + var err error + um := URLsMap{} + for k, v := range m { + um[k], err = NewURLs(strings.Split(v, sep)) + if err != nil { + return nil, err + } + } + return um, nil +} + // String turns URLsMap into discovery-formatted name-to-URLs sorted by name. func (c URLsMap) String() string { var pairs []string diff --git a/vendor/github.com/coreos/etcd/pkg/wait/wait.go b/vendor/github.com/coreos/etcd/pkg/wait/wait.go index 07f9944ffbf..a341c02708d 100644 --- a/vendor/github.com/coreos/etcd/pkg/wait/wait.go +++ b/vendor/github.com/coreos/etcd/pkg/wait/wait.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. 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 7911e404fdb..0357d81f361 100644 --- a/vendor/github.com/coreos/etcd/pkg/wait/wait_time.go +++ b/vendor/github.com/coreos/etcd/pkg/wait/wait_time.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. diff --git a/vendor/github.com/coreos/etcd/raft/README.md b/vendor/github.com/coreos/etcd/raft/README.md new file mode 100644 index 00000000000..c828081aaa7 --- /dev/null +++ b/vendor/github.com/coreos/etcd/raft/README.md @@ -0,0 +1,198 @@ +# Raft library + +Raft is a protocol with which a cluster of nodes can maintain a replicated state machine. +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. + +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 + +## Notable Users + +- [cockroachdb](https://github.com/cockroachdb/cockroach) A Scalable, Survivable, Strongly-Consistent SQL 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 +- [swarmkit](https://github.com/docker/swarmkit) A toolkit for orchestrating distributed systems at any scale. + +## Usage + +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: + +```go + storage := raft.NewMemoryStorage() + c := &Config{ + ID: 0x01, + ElectionTick: 10, + HeartbeatTick: 1, + Storage: storage, + MaxSizePerMsg: 4096, + MaxInflightMsgs: 256, + } + n := raft.StartNode(c, []raft.Peer{{ID: 0x02}, {ID: 0x03}}) +``` + +To restart a node from previous state: + +```go + storage := raft.NewMemoryStorage() + + // recover the in-memory storage from persistent + // snapshot, state and entries. + storage.ApplySnapshot(snapshot) + storage.SetHardState(state) + storage.Append(entries) + + c := &Config{ + ID: 0x01, + ElectionTick: 10, + HeartbeatTick: 1, + Storage: storage, + MaxSizePerMsg: 4096, + MaxInflightMsgs: 256, + } + + // restart raft without peer information. + // peer information is already included in the storage. + n := raft.RestartNode(c) +``` + +Now that you are holding onto a Node you have a few responsibilities: + +First, you must read from the Node.Ready() channel and process the updates +it contains. These steps may be performed in parallel, except as noted in step +2. + +1. Write HardState, Entries, and Snapshot to persistent storage if they are +not empty. Note that when writing an Entry with Index i, any +previously-persisted entries with Index >= i must be discarded. + +2. Send all Messages to the nodes named in the To field. It is important that +no messages be sent until the latest HardState has been persisted to disk, +and all Entries written by any previous Ready batch (Messages may be sent while +entries from the same batch are being persisted). To reduce the I/O latency, an +optimization can be applied to make leader write to disk in parallel with its +followers (as explained at section 10.2.1 in Raft thesis). If any Message has type +MsgSnap, call Node.ReportSnapshot() after it has been sent (these messages may be +large). Note: Marshalling messages is not thread-safe; it is important that you +make sure that no new entries are persisted while marshalling. +The easiest way to achieve this is to serialise the messages directly inside +your main raft loop. + +3. Apply Snapshot (if any) and CommittedEntries to the state machine. +If any committed Entry has Type EntryConfChange, call Node.ApplyConfChange() +to apply it to the node. The configuration change may be cancelled at this point +by setting the NodeID field to zero before calling ApplyConfChange +(but ApplyConfChange must be called one way or the other, and the decision to cancel +must be based solely on the state machine and not external information such as +the observed health of the node). + +4. Call Node.Advance() to signal readiness for the next batch of updates. +This may be done at any time after step 1, although all updates must be processed +in the order they were returned by Ready. + +Second, all persisted log entries must be made available via an +implementation of the Storage interface. The provided MemoryStorage +type can be used for this (if you repopulate its state upon a +restart), or you can supply your own disk-backed implementation. + +Third, when you receive a message from another node, pass it to Node.Step: + +```go + func recvRaftRPC(ctx context.Context, m raftpb.Message) { + n.Step(ctx, m) + } +``` + +Finally, you need to call `Node.Tick()` at regular intervals (probably +via a `time.Ticker`). Raft has two important timeouts: heartbeat and the +election timeout. However, internally to the raft package time is +represented by an abstract "tick". + +The total state machine handling loop will look something like this: + +```go + for { + select { + case <-s.Ticker: + n.Tick() + case rd := <-s.Node.Ready(): + saveToStorage(rd.State, rd.Entries, rd.Snapshot) + send(rd.Messages) + if !raft.IsEmptySnap(rd.Snapshot) { + processSnapshot(rd.Snapshot) + } + for _, entry := range rd.CommittedEntries { + process(entry) + if entry.Type == raftpb.EntryConfChange { + var cc raftpb.ConfChange + cc.Unmarshal(entry.Data) + s.Node.ApplyConfChange(cc) + } + } + s.Node.Advance() + case <-s.done: + return + } + } +``` + +To propose changes to the state machine from your node take your application +data, serialize it into a byte slice and call: + +```go + n.Propose(ctx, data) +``` + +If the proposal is committed, data will appear in committed entries with type +raftpb.EntryNormal. There is no guarantee that a proposed command will be +committed; you may have to re-propose after a timeout. + +To add or remove node in a cluster, build ConfChange struct 'cc' and call: + +```go + n.ProposeConfChange(ctx, cc) +``` + +After config change is committed, some committed entry with type +raftpb.EntryConfChange will be returned. You must apply it to node through: + +```go + var cc raftpb.ConfChange + cc.Unmarshal(data) + n.ApplyConfChange(cc) +``` + +Note: An ID represents a unique node in a cluster for all time. A +given ID MUST be used only once even if the old node has been removed. +This means that for example IP addresses make poor node IDs since they +may be reused. Node IDs must be non-zero. + +## Implementation notes + +This implementation is up to date with the final Raft thesis +(https://ramcloud.stanford.edu/~ongaro/thesis.pdf), although our +implementation of the membership change protocol differs somewhat from +that described in chapter 4. The key invariant that membership changes +happen one node at a time is preserved, but in our implementation the +membership change takes effect when its entry is applied, not when it +is added to the log (so the entry is committed under the old +membership instead of the new). This is equivalent in terms of safety, +since the old and new configurations are guaranteed to overlap. + +To ensure that we do not attempt to commit two membership changes at +once by matching log positions (which would be unsafe since they +should have different quorum requirements), we simply disallow any +proposed membership change while any uncommitted change appears in +the leader's log. + +This approach introduces a problem when you try to remove a member +from a two-member cluster: If one of the members dies before the +other one receives the commit of the confchange entry, then the member +cannot be removed any more since the cluster cannot make progress. +For this reason it is highly recommended to use three or more nodes in +every cluster. diff --git a/vendor/github.com/coreos/etcd/raft/doc.go b/vendor/github.com/coreos/etcd/raft/doc.go index 6ed0bcfadb4..a071932ae94 100644 --- a/vendor/github.com/coreos/etcd/raft/doc.go +++ b/vendor/github.com/coreos/etcd/raft/doc.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. @@ -77,7 +77,7 @@ not empty. Note that when writing an Entry with Index i, any previously-persisted entries with Index >= i must be discarded. 2. Send all Messages to the nodes named in the To field. It is important that -no messages be sent until after the latest HardState has been persisted to disk, +no messages be sent until the latest HardState has been persisted to disk, and all Entries written by any previous Ready batch (Messages may be sent while entries from the same batch are being persisted). To reduce the I/O latency, an optimization can be applied to make leader write to disk in parallel with its @@ -137,6 +137,7 @@ The total state machine handling loop will look something like this: cc.Unmarshal(entry.Data) s.Node.ApplyConfChange(cc) } + } s.Node.Advance() case <-s.done: return @@ -209,10 +210,10 @@ stale log entries: passes 'MsgHup' to its Step method and becomes (or remains) a candidate to start a new election. - 'MsgBeat' is an internal type that signals leaders to send a heartbeat of + 'MsgBeat' is an internal type that signals the leader to send a heartbeat of the 'MsgHeartbeat' type. If a node is a leader, the 'tick' function in - the 'raft' struct is set as 'tickHeartbeat', and sends periodic heartbeat - messages of the 'MsgBeat' type to its followers. + the 'raft' struct is set as 'tickHeartbeat', and triggers the leader to + send periodic 'MsgHeartbeat' messages to its followers. 'MsgProp' proposes to append data to its log entries. This is a special type to redirect proposals to leader. Therefore, send method overwrites diff --git a/vendor/github.com/coreos/etcd/raft/log.go b/vendor/github.com/coreos/etcd/raft/log.go index 7a2709afbb1..263f4225533 100644 --- a/vendor/github.com/coreos/etcd/raft/log.go +++ b/vendor/github.com/coreos/etcd/raft/log.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. diff --git a/vendor/github.com/coreos/etcd/raft/log_unstable.go b/vendor/github.com/coreos/etcd/raft/log_unstable.go index df90178f9af..bfd4daa6748 100644 --- a/vendor/github.com/coreos/etcd/raft/log_unstable.go +++ b/vendor/github.com/coreos/etcd/raft/log_unstable.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. diff --git a/vendor/github.com/coreos/etcd/raft/logger.go b/vendor/github.com/coreos/etcd/raft/logger.go index 31c194a06bb..92e55b373e1 100644 --- a/vendor/github.com/coreos/etcd/raft/logger.go +++ b/vendor/github.com/coreos/etcd/raft/logger.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. diff --git a/vendor/github.com/coreos/etcd/raft/node.go b/vendor/github.com/coreos/etcd/raft/node.go index 5811af23a36..59d61284d89 100644 --- a/vendor/github.com/coreos/etcd/raft/node.go +++ b/vendor/github.com/coreos/etcd/raft/node.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. @@ -200,6 +200,7 @@ func StartNode(c *Config, peers []Peer) Node { } n := newNode() + n.logger = c.Logger go n.run(r) return &n } @@ -212,6 +213,7 @@ func RestartNode(c *Config) Node { r := newRaft(c) n := newNode() + n.logger = c.Logger go n.run(r) return &n } @@ -228,6 +230,8 @@ type node struct { done chan struct{} stop chan struct{} status chan chan Status + + logger Logger } func newNode() node { @@ -238,10 +242,13 @@ func newNode() node { confstatec: make(chan pb.ConfState), readyc: make(chan Ready), advancec: make(chan struct{}), - tickc: make(chan struct{}), - done: make(chan struct{}), - stop: make(chan struct{}), - status: make(chan chan Status), + // make tickc a buffered chan, so raft node can buffer some ticks when the node + // is busy processing raft messages. Raft node will resume process buffered + // ticks when it becomes idle. + tickc: make(chan struct{}, 128), + done: make(chan struct{}), + stop: make(chan struct{}), + status: make(chan chan Status), } } @@ -306,7 +313,7 @@ func (n *node) run(r *raft) { r.Step(m) case m := <-n.recvc: // filter out response message from unknown From. - if _, ok := r.prs[m.From]; ok || !IsResponseMsg(m) { + if _, ok := r.prs[m.From]; ok || !IsResponseMsg(m.Type) { r.Step(m) // raft never returns an error } case cc := <-n.confc: @@ -325,7 +332,7 @@ func (n *node) run(r *raft) { // block incoming proposal when local node is // removed if cc.NodeID == r.id { - n.propc = nil + propc = nil } r.removeNode(cc.NodeID) case pb.ConfChangeUpdateNode: @@ -381,6 +388,8 @@ func (n *node) Tick() { select { case n.tickc <- struct{}{}: case <-n.done: + default: + n.logger.Warningf("A tick missed to fire. Node blocks too long!") } } @@ -392,7 +401,7 @@ func (n *node) Propose(ctx context.Context, data []byte) error { func (n *node) Step(ctx context.Context, m pb.Message) error { // ignore unexpected local messages receiving over network - if IsLocalMsg(m) { + if IsLocalMsg(m.Type) { // TODO: return an error? return nil } diff --git a/vendor/github.com/coreos/etcd/raft/progress.go b/vendor/github.com/coreos/etcd/raft/progress.go index 11f53409d4c..39547053470 100644 --- a/vendor/github.com/coreos/etcd/raft/progress.go +++ b/vendor/github.com/coreos/etcd/raft/progress.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. @@ -75,7 +75,6 @@ type Progress struct { func (pr *Progress) resetState(state ProgressStateType) { pr.Paused = false - pr.RecentActive = false pr.PendingSnapshot = 0 pr.State = state pr.ins.reset() @@ -167,9 +166,9 @@ func (pr *Progress) isPaused() bool { func (pr *Progress) snapshotFailure() { pr.PendingSnapshot = 0 } -// maybeSnapshotAbort unsets pendingSnapshot if Match is equal or higher than -// the pendingSnapshot -func (pr *Progress) maybeSnapshotAbort() bool { +// needSnapshotAbort returns true if snapshot progress's Match +// is equal or higher than the pendingSnapshot. +func (pr *Progress) needSnapshotAbort() bool { return pr.State == ProgressStateSnapshot && pr.Match >= pr.PendingSnapshot } diff --git a/vendor/github.com/coreos/etcd/raft/raft.go b/vendor/github.com/coreos/etcd/raft/raft.go index e7da600b762..86b393d6ac5 100644 --- a/vendor/github.com/coreos/etcd/raft/raft.go +++ b/vendor/github.com/coreos/etcd/raft/raft.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. @@ -29,8 +29,6 @@ import ( const None uint64 = 0 const noLimit = math.MaxUint64 -var ErrSnapshotTemporarilyUnavailable = errors.New("snapshot is temporarily unavailable") - // Possible values for StateType. const ( StateFollower StateType = iota @@ -156,7 +154,9 @@ type raft struct { // the leader id lead uint64 - + // leadTransferee is id of the leader transfer target when its value is not zero. + // Follow the procedure defined in raft thesis 3.10. + leadTransferee uint64 // New configuration is ignored if there exists unapplied configuration. pendingConf bool @@ -229,7 +229,7 @@ func newRaft(c *Config) *raft { } r.becomeFollower(r.Term, None) - nodesStrs := make([]string, 0) + var nodesStrs []string for _, n := range r.nodes() { nodesStrs = append(nodesStrs, fmt.Sprintf("%x", n)) } @@ -397,6 +397,8 @@ func (r *raft) reset(term uint64) { r.heartbeatElapsed = 0 r.resetRandomizedElectionTimeout() + r.abortLeaderTransfer() + r.votes = make(map[uint64]bool) for id := range r.prs { r.prs[id] = &Progress{Next: r.raftLog.lastIndex() + 1, ins: newInflights(r.maxInflight)} @@ -421,12 +423,9 @@ func (r *raft) appendEntry(es ...pb.Entry) { // tickElection is run by followers and candidates after r.electionTimeout. func (r *raft) tickElection() { - if !r.promotable() { - r.electionElapsed = 0 - return - } r.electionElapsed++ - if r.pastElectionTimeout() { + + if r.promotable() && r.pastElectionTimeout() { r.electionElapsed = 0 r.Step(pb.Message{From: r.id, Type: pb.MsgHup}) } @@ -442,6 +441,10 @@ func (r *raft) tickHeartbeat() { if r.checkQuorum { r.Step(pb.Message{From: r.id, Type: pb.MsgCheckQuorum}) } + // If current leader cannot transfer leadership in electionTimeout, it becomes leader again. + if r.state == StateLeader && r.leadTransferee != None { + r.abortLeaderTransfer() + } } if r.state != StateLeader { @@ -547,6 +550,11 @@ func (r *raft) Step(m pb.Message) error { } 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) + } + } switch { case m.Term == 0: @@ -554,15 +562,35 @@ func (r *raft) Step(m pb.Message) error { case m.Term > r.Term: lead := m.From if m.Type == pb.MsgVote { + if r.checkQuorum && r.state != StateCandidate && r.electionElapsed < r.electionTimeout { + // 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) + 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) case m.Term < r.Term: - // ignore - r.logger.Infof("%x [term: %d] ignored a %s message with lower term from %x [term: %d]", - r.id, r.Term, m.Type, m.From, m.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 + r.send(pb.Message{To: m.From, Type: pb.MsgAppResp}) + } else { + // ignore other cases + r.logger.Infof("%x [term: %d] ignored a %s message with lower term from %x [term: %d]", + r.id, r.Term, m.Type, m.From, m.Term) + } return nil } r.step(r, m) @@ -572,7 +600,6 @@ func (r *raft) Step(m pb.Message) error { type stepFunc func(r *raft, m pb.Message) func stepLeader(r *raft, m pb.Message) { - // These message types do not require any progress for m.From. switch m.Type { case pb.MsgBeat: @@ -594,6 +621,11 @@ func stepLeader(r *raft, m pb.Message) { // drop any new proposals. return } + if r.leadTransferee != None { + r.logger.Debugf("%x [term %d] transfer leadership to %x is in progress; dropping proposal", r.id, r.Term, r.leadTransferee) + return + } + for i, e := range m.Entries { if e.Type == pb.EntryConfChange { if r.pendingConf { @@ -615,7 +647,7 @@ func stepLeader(r *raft, m pb.Message) { // All other message types require a progress for m.From (pr). pr, prOk := r.prs[m.From] if !prOk { - r.logger.Debugf("no progress available for %x", m.From) + r.logger.Debugf("%x no progress available for %x", r.id, m.From) return } switch m.Type { @@ -638,7 +670,7 @@ func stepLeader(r *raft, m pb.Message) { switch { case pr.State == ProgressStateProbe: pr.becomeReplicate() - case pr.State == ProgressStateSnapshot && pr.maybeSnapshotAbort(): + case pr.State == ProgressStateSnapshot && pr.needSnapshotAbort(): r.logger.Debugf("%x snapshot aborted, resumed sending replication messages to %x [%s]", r.id, m.From, pr) pr.becomeProbe() case pr.State == ProgressStateReplicate: @@ -652,6 +684,11 @@ func stepLeader(r *raft, m pb.Message) { // an update before, send it now. r.sendAppend(m.From) } + // Transfer leadership is in progress. + if m.From == r.leadTransferee && pr.Match == r.raftLog.lastIndex() { + r.logger.Infof("%x sent MsgTimeoutNow to %x after received MsgAppResp", r.id, m.From) + r.sendTimeoutNow(m.From) + } } } case pb.MsgHeartbeatResp: @@ -687,6 +724,33 @@ func stepLeader(r *raft, m pb.Message) { pr.becomeProbe() } r.logger.Debugf("%x failed to send message to %x because it is unreachable [%s]", r.id, m.From, pr) + case pb.MsgTransferLeader: + leadTransferee := m.From + lastLeadTransferee := r.leadTransferee + if lastLeadTransferee != None { + if lastLeadTransferee == leadTransferee { + r.logger.Infof("%x [term %d] transfer leadership to %x is in progress, ignores request to same node %x", + r.id, r.Term, leadTransferee, leadTransferee) + return + } + r.abortLeaderTransfer() + r.logger.Infof("%x [term %d] abort previous transferring leadership to %x", r.id, r.Term, lastLeadTransferee) + } + if leadTransferee == r.id { + r.logger.Debugf("%x is already leader. Ignored transferring leadership to self", r.id) + return + } + // Transfer leadership to third party. + r.logger.Infof("%x [term %d] starts to transfer leadership to %x", r.id, r.Term, leadTransferee) + // Transfer leadership should be finished in one electionTimeout, so reset r.electionElapsed. + r.electionElapsed = 0 + r.leadTransferee = leadTransferee + if pr.Match == r.raftLog.lastIndex() { + r.sendTimeoutNow(leadTransferee) + r.logger.Infof("%x sends MsgTimeoutNow to %x immediately as %x already has up-to-date log", r.id, leadTransferee, leadTransferee) + } else { + r.sendAppend(leadTransferee) + } } } @@ -718,6 +782,8 @@ func stepCandidate(r *raft, m pb.Message) { case len(r.votes) - gr: r.becomeFollower(r.Term, None) } + case pb.MsgTimeoutNow: + r.logger.Debugf("%x [term %d state %v] ignored MsgTimeoutNow from %x", r.id, r.Term, r.state, m.From) } } @@ -753,6 +819,9 @@ func stepFollower(r *raft, m pb.Message) { 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.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() } } @@ -841,11 +910,21 @@ func (r *raft) addNode(id uint64) { func (r *raft) removeNode(id uint64) { r.delProgress(id) r.pendingConf = false + + // do not try to commit or abort transferring if there is no nodes in the cluster. + if len(r.prs) == 0 { + return + } + // The quorum size is now smaller, so see if any pending entries can // be committed. if r.maybeCommit() { r.bcastAppend() } + // If the removed node is the leadTransferee, then abort the leadership transferring. + if r.state == StateLeader && r.leadTransferee == id { + r.abortLeaderTransfer() + } } func (r *raft) resetPendingConf() { r.pendingConf = false } @@ -900,3 +979,11 @@ func (r *raft) checkQuorumActive() bool { return act >= r.quorum() } + +func (r *raft) sendTimeoutNow(to uint64) { + r.send(pb.Message{To: to, Type: pb.MsgTimeoutNow}) +} + +func (r *raft) abortLeaderTransfer() { + r.leadTransferee = None +} 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 41e619d655d..6199ee81659 100644 --- a/vendor/github.com/coreos/etcd/raft/raftpb/raft.pb.go +++ b/vendor/github.com/coreos/etcd/raft/raftpb/raft.pb.go @@ -22,7 +22,7 @@ package raftpb import ( "fmt" - proto "github.com/gogo/protobuf/proto" + proto "github.com/golang/protobuf/proto" math "math" ) @@ -34,6 +34,10 @@ var _ = proto.Marshal var _ = fmt.Errorf 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 + type EntryType int32 const ( @@ -66,23 +70,26 @@ func (x *EntryType) UnmarshalJSON(data []byte) error { *x = EntryType(value) return nil } +func (EntryType) EnumDescriptor() ([]byte, []int) { return fileDescriptorRaft, []int{0} } type MessageType int32 const ( - MsgHup MessageType = 0 - MsgBeat MessageType = 1 - MsgProp MessageType = 2 - MsgApp MessageType = 3 - MsgAppResp MessageType = 4 - MsgVote MessageType = 5 - MsgVoteResp MessageType = 6 - MsgSnap MessageType = 7 - MsgHeartbeat MessageType = 8 - MsgHeartbeatResp MessageType = 9 - MsgUnreachable MessageType = 10 - MsgSnapStatus MessageType = 11 - MsgCheckQuorum MessageType = 12 + MsgHup MessageType = 0 + MsgBeat MessageType = 1 + MsgProp MessageType = 2 + MsgApp MessageType = 3 + MsgAppResp MessageType = 4 + MsgVote MessageType = 5 + MsgVoteResp MessageType = 6 + MsgSnap MessageType = 7 + MsgHeartbeat MessageType = 8 + MsgHeartbeatResp MessageType = 9 + MsgUnreachable MessageType = 10 + MsgSnapStatus MessageType = 11 + MsgCheckQuorum MessageType = 12 + MsgTransferLeader MessageType = 13 + MsgTimeoutNow MessageType = 14 ) var MessageType_name = map[int32]string{ @@ -99,21 +106,25 @@ var MessageType_name = map[int32]string{ 10: "MsgUnreachable", 11: "MsgSnapStatus", 12: "MsgCheckQuorum", + 13: "MsgTransferLeader", + 14: "MsgTimeoutNow", } var MessageType_value = map[string]int32{ - "MsgHup": 0, - "MsgBeat": 1, - "MsgProp": 2, - "MsgApp": 3, - "MsgAppResp": 4, - "MsgVote": 5, - "MsgVoteResp": 6, - "MsgSnap": 7, - "MsgHeartbeat": 8, - "MsgHeartbeatResp": 9, - "MsgUnreachable": 10, - "MsgSnapStatus": 11, - "MsgCheckQuorum": 12, + "MsgHup": 0, + "MsgBeat": 1, + "MsgProp": 2, + "MsgApp": 3, + "MsgAppResp": 4, + "MsgVote": 5, + "MsgVoteResp": 6, + "MsgSnap": 7, + "MsgHeartbeat": 8, + "MsgHeartbeatResp": 9, + "MsgUnreachable": 10, + "MsgSnapStatus": 11, + "MsgCheckQuorum": 12, + "MsgTransferLeader": 13, + "MsgTimeoutNow": 14, } func (x MessageType) Enum() *MessageType { @@ -132,6 +143,7 @@ func (x *MessageType) UnmarshalJSON(data []byte) error { *x = MessageType(value) return nil } +func (MessageType) EnumDescriptor() ([]byte, []int) { return fileDescriptorRaft, []int{1} } type ConfChangeType int32 @@ -168,29 +180,32 @@ func (x *ConfChangeType) UnmarshalJSON(data []byte) error { *x = ConfChangeType(value) return nil } +func (ConfChangeType) EnumDescriptor() ([]byte, []int) { return fileDescriptorRaft, []int{2} } type Entry struct { - Type EntryType `protobuf:"varint,1,opt,name=Type,enum=raftpb.EntryType" json:"Type"` - Term uint64 `protobuf:"varint,2,opt,name=Term" json:"Term"` - Index uint64 `protobuf:"varint,3,opt,name=Index" json:"Index"` - Data []byte `protobuf:"bytes,4,opt,name=Data" json:"Data,omitempty"` + Type EntryType `protobuf:"varint,1,opt,name=Type,json=type,enum=raftpb.EntryType" json:"Type"` + Term uint64 `protobuf:"varint,2,opt,name=Term,json=term" json:"Term"` + Index uint64 `protobuf:"varint,3,opt,name=Index,json=index" json:"Index"` + Data []byte `protobuf:"bytes,4,opt,name=Data,json=data" json:"Data,omitempty"` XXX_unrecognized []byte `json:"-"` } -func (m *Entry) Reset() { *m = Entry{} } -func (m *Entry) String() string { return proto.CompactTextString(m) } -func (*Entry) ProtoMessage() {} +func (m *Entry) Reset() { *m = Entry{} } +func (m *Entry) String() string { return proto.CompactTextString(m) } +func (*Entry) ProtoMessage() {} +func (*Entry) Descriptor() ([]byte, []int) { return fileDescriptorRaft, []int{0} } type SnapshotMetadata struct { - ConfState ConfState `protobuf:"bytes,1,opt,name=conf_state" json:"conf_state"` + ConfState ConfState `protobuf:"bytes,1,opt,name=conf_state,json=confState" json:"conf_state"` Index uint64 `protobuf:"varint,2,opt,name=index" json:"index"` Term uint64 `protobuf:"varint,3,opt,name=term" json:"term"` XXX_unrecognized []byte `json:"-"` } -func (m *SnapshotMetadata) Reset() { *m = SnapshotMetadata{} } -func (m *SnapshotMetadata) String() string { return proto.CompactTextString(m) } -func (*SnapshotMetadata) ProtoMessage() {} +func (m *SnapshotMetadata) Reset() { *m = SnapshotMetadata{} } +func (m *SnapshotMetadata) String() string { return proto.CompactTextString(m) } +func (*SnapshotMetadata) ProtoMessage() {} +func (*SnapshotMetadata) Descriptor() ([]byte, []int) { return fileDescriptorRaft, []int{1} } type Snapshot struct { Data []byte `protobuf:"bytes,1,opt,name=data" json:"data,omitempty"` @@ -198,9 +213,10 @@ type Snapshot struct { XXX_unrecognized []byte `json:"-"` } -func (m *Snapshot) Reset() { *m = Snapshot{} } -func (m *Snapshot) String() string { return proto.CompactTextString(m) } -func (*Snapshot) ProtoMessage() {} +func (m *Snapshot) Reset() { *m = Snapshot{} } +func (m *Snapshot) String() string { return proto.CompactTextString(m) } +func (*Snapshot) ProtoMessage() {} +func (*Snapshot) Descriptor() ([]byte, []int) { return fileDescriptorRaft, []int{2} } type Message struct { Type MessageType `protobuf:"varint,1,opt,name=type,enum=raftpb.MessageType" json:"type"` @@ -217,9 +233,10 @@ type Message struct { XXX_unrecognized []byte `json:"-"` } -func (m *Message) Reset() { *m = Message{} } -func (m *Message) String() string { return proto.CompactTextString(m) } -func (*Message) ProtoMessage() {} +func (m *Message) Reset() { *m = Message{} } +func (m *Message) String() string { return proto.CompactTextString(m) } +func (*Message) ProtoMessage() {} +func (*Message) Descriptor() ([]byte, []int) { return fileDescriptorRaft, []int{3} } type HardState struct { Term uint64 `protobuf:"varint,1,opt,name=term" json:"term"` @@ -228,30 +245,33 @@ type HardState struct { XXX_unrecognized []byte `json:"-"` } -func (m *HardState) Reset() { *m = HardState{} } -func (m *HardState) String() string { return proto.CompactTextString(m) } -func (*HardState) ProtoMessage() {} +func (m *HardState) Reset() { *m = HardState{} } +func (m *HardState) String() string { return proto.CompactTextString(m) } +func (*HardState) ProtoMessage() {} +func (*HardState) Descriptor() ([]byte, []int) { return fileDescriptorRaft, []int{4} } type ConfState struct { Nodes []uint64 `protobuf:"varint,1,rep,name=nodes" json:"nodes,omitempty"` XXX_unrecognized []byte `json:"-"` } -func (m *ConfState) Reset() { *m = ConfState{} } -func (m *ConfState) String() string { return proto.CompactTextString(m) } -func (*ConfState) ProtoMessage() {} +func (m *ConfState) Reset() { *m = ConfState{} } +func (m *ConfState) String() string { return proto.CompactTextString(m) } +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"` - 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"` + 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"` XXX_unrecognized []byte `json:"-"` } -func (m *ConfChange) Reset() { *m = ConfChange{} } -func (m *ConfChange) String() string { return proto.CompactTextString(m) } -func (*ConfChange) ProtoMessage() {} +func (m *ConfChange) Reset() { *m = ConfChange{} } +func (m *ConfChange) String() string { return proto.CompactTextString(m) } +func (*ConfChange) ProtoMessage() {} +func (*ConfChange) Descriptor() ([]byte, []int) { return fileDescriptorRaft, []int{6} } func init() { proto.RegisterType((*Entry)(nil), "raftpb.Entry") @@ -1766,3 +1786,55 @@ var ( ErrInvalidLengthRaft = fmt.Errorf("proto: negative length found during unmarshaling") ErrIntOverflowRaft = fmt.Errorf("proto: integer overflow") ) + +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, +} diff --git a/vendor/github.com/coreos/etcd/raft/raftpb/raft.proto b/vendor/github.com/coreos/etcd/raft/raftpb/raft.proto index 0a98b8cfa5f..42f10d269f0 100644 --- a/vendor/github.com/coreos/etcd/raft/raftpb/raft.proto +++ b/vendor/github.com/coreos/etcd/raft/raftpb/raft.proto @@ -46,6 +46,8 @@ enum MessageType { MsgUnreachable = 10; MsgSnapStatus = 11; MsgCheckQuorum = 12; + MsgTransferLeader = 13; + MsgTimeoutNow = 14; } message Message { diff --git a/vendor/github.com/coreos/etcd/raft/rawnode.go b/vendor/github.com/coreos/etcd/raft/rawnode.go index 8cf08589176..4cea62f64fa 100644 --- a/vendor/github.com/coreos/etcd/raft/rawnode.go +++ b/vendor/github.com/coreos/etcd/raft/rawnode.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. @@ -168,10 +168,10 @@ func (rn *RawNode) ApplyConfChange(cc pb.ConfChange) *pb.ConfState { // Step advances the state machine using the given message. func (rn *RawNode) Step(m pb.Message) error { // ignore unexpected local messages receiving over network - if IsLocalMsg(m) { + if IsLocalMsg(m.Type) { return ErrStepLocalMsg } - if _, ok := rn.raft.prs[m.From]; ok || !IsResponseMsg(m) { + if _, ok := rn.raft.prs[m.From]; ok || !IsResponseMsg(m.Type) { return rn.raft.Step(m) } return ErrStepPeerNotFound @@ -226,3 +226,8 @@ func (rn *RawNode) ReportSnapshot(id uint64, status SnapshotStatus) { _ = rn.raft.Step(pb.Message{Type: pb.MsgSnapStatus, From: id, Reject: rej}) } + +// TransferLeader tries to transfer leadership to the given transferee. +func (rn *RawNode) TransferLeader(transferee uint64) { + _ = rn.raft.Step(pb.Message{Type: pb.MsgTransferLeader, From: transferee}) +} diff --git a/vendor/github.com/coreos/etcd/raft/status.go b/vendor/github.com/coreos/etcd/raft/status.go index d18a489541c..b690fa56b95 100644 --- a/vendor/github.com/coreos/etcd/raft/status.go +++ b/vendor/github.com/coreos/etcd/raft/status.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. diff --git a/vendor/github.com/coreos/etcd/raft/storage.go b/vendor/github.com/coreos/etcd/raft/storage.go index f3724162cee..37f6b378e21 100644 --- a/vendor/github.com/coreos/etcd/raft/storage.go +++ b/vendor/github.com/coreos/etcd/raft/storage.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. @@ -29,8 +29,14 @@ var ErrCompacted = errors.New("requested index is unavailable due to compaction" // index is older than the existing snapshot. var ErrSnapOutOfDate = errors.New("requested index is older than the existing snapshot") +// ErrUnavailable is returned by Storage interface when the requested log entries +// are unavailable. var ErrUnavailable = errors.New("requested entry at index is unavailable") +// ErrSnapshotTemporarilyUnavailable is returned by the Storage interface when the required +// snapshot is temporarily unavailable. +var ErrSnapshotTemporarilyUnavailable = errors.New("snapshot is temporarily unavailable") + // Storage is an interface that may be implemented by the application // to retrieve log entries from storage. // @@ -220,12 +226,14 @@ func (ms *MemoryStorage) Compact(compactIndex uint64) error { // TODO (xiangli): ensure the entries are continuous and // entries[0].Index > ms.entries[0].Index func (ms *MemoryStorage) Append(entries []pb.Entry) error { - ms.Lock() - defer ms.Unlock() if len(entries) == 0 { return nil } - first := ms.ents[0].Index + 1 + + ms.Lock() + defer ms.Unlock() + + first := ms.firstIndex() last := entries[0].Index + uint64(len(entries)) - 1 // shortcut if there is no new entry. diff --git a/vendor/github.com/coreos/etcd/raft/util.go b/vendor/github.com/coreos/etcd/raft/util.go index 8d4c4190012..c57855a1740 100644 --- a/vendor/github.com/coreos/etcd/raft/util.go +++ b/vendor/github.com/coreos/etcd/raft/util.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. @@ -46,12 +46,13 @@ func max(a, b uint64) uint64 { return b } -func IsLocalMsg(m pb.Message) bool { - return m.Type == pb.MsgHup || m.Type == pb.MsgBeat || m.Type == pb.MsgUnreachable || m.Type == pb.MsgSnapStatus || m.Type == pb.MsgCheckQuorum +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 } -func IsResponseMsg(m pb.Message) bool { - return m.Type == pb.MsgAppResp || m.Type == pb.MsgVoteResp || m.Type == pb.MsgHeartbeatResp || m.Type == pb.MsgUnreachable +func IsResponseMsg(msgt pb.MessageType) bool { + return msgt == pb.MsgAppResp || msgt == pb.MsgVoteResp || msgt == pb.MsgHeartbeatResp || msgt == pb.MsgUnreachable } // 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 de6ac6cc0d6..2d2d24c9bcb 100644 --- a/vendor/github.com/coreos/etcd/rafthttp/coder.go +++ b/vendor/github.com/coreos/etcd/rafthttp/coder.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. diff --git a/vendor/github.com/coreos/etcd/rafthttp/doc.go b/vendor/github.com/coreos/etcd/rafthttp/doc.go index 320f842b86f..a9486a8bb66 100644 --- a/vendor/github.com/coreos/etcd/rafthttp/doc.go +++ b/vendor/github.com/coreos/etcd/rafthttp/doc.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. diff --git a/vendor/github.com/coreos/etcd/rafthttp/http.go b/vendor/github.com/coreos/etcd/rafthttp/http.go index 662b856b98c..76b74bd8a91 100644 --- a/vendor/github.com/coreos/etcd/rafthttp/http.go +++ b/vendor/github.com/coreos/etcd/rafthttp/http.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. @@ -106,12 +106,16 @@ func (h *pipelineHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { http.Error(w, "error reading raft message", http.StatusBadRequest) return } + var m raftpb.Message 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) return } + + receivedBytes.WithLabelValues(types.ID(m.From).String()).Add(float64(len(b))) + if err := h.r.Process(context.TODO(), m); err != nil { switch v := err.(type) { case writerToResponse: @@ -181,6 +185,9 @@ func (h *snapshotHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { http.Error(w, msg, http.StatusBadRequest) return } + + receivedBytes.WithLabelValues(types.ID(m.From).String()).Add(float64(m.Size())) + if m.Type != raftpb.MsgSnap { plog.Errorf("unexpected raft message type %s on snapshot path", m.Type) http.Error(w, "wrong raft message type", http.StatusBadRequest) @@ -189,12 +196,14 @@ func (h *snapshotHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { plog.Infof("receiving database snapshot [index:%d, from %s] ...", m.Snapshot.Metadata.Index, types.ID(m.From)) // save incoming database snapshot. - if err := h.snapshotter.SaveDBFrom(r.Body, m.Snapshot.Metadata.Index); err != nil { + n, err := h.snapshotter.SaveDBFrom(r.Body, m.Snapshot.Metadata.Index) + if err != nil { msg := fmt.Sprintf("failed to save KV snapshot (%v)", err) plog.Error(msg) http.Error(w, msg, http.StatusInternalServerError) return } + receivedBytes.WithLabelValues(types.ID(m.From).String()).Add(float64(n)) plog.Infof("received and saved database snapshot [index: %d, from: %s] successfully", m.Snapshot.Metadata.Index, types.ID(m.From)) if err := h.r.Process(context.TODO(), m); err != nil { diff --git a/vendor/github.com/coreos/etcd/rafthttp/metrics.go b/vendor/github.com/coreos/etcd/rafthttp/metrics.go index d3a3c5dbe9b..e9550c3bb78 100644 --- a/vendor/github.com/coreos/etcd/rafthttp/metrics.go +++ b/vendor/github.com/coreos/etcd/rafthttp/metrics.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. @@ -14,57 +14,41 @@ package rafthttp -import ( - "time" - - "github.com/coreos/etcd/pkg/types" - "github.com/coreos/etcd/raft/raftpb" - "github.com/prometheus/client_golang/prometheus" -) +import "github.com/prometheus/client_golang/prometheus" +// TODO: record write/recv failures. var ( - // TODO: create a separate histogram for recording - // snapshot sending metric. snapshot can be large and - // take a long time to send. So it needs a different - // time range than other type of messages. - msgSentDuration = prometheus.NewHistogramVec( - prometheus.HistogramOpts{ - Namespace: "etcd", - Subsystem: "rafthttp", - Name: "message_sent_latency_seconds", - Help: "message sent latency distributions.", - Buckets: prometheus.ExponentialBuckets(0.0005, 2, 13), - }, - []string{"sendingType", "remoteID", "msgType"}, + sentBytes = prometheus.NewCounterVec(prometheus.CounterOpts{ + Namespace: "etcd", + Subsystem: "network", + Name: "peer_sent_bytes_total", + Help: "The total number of bytes sent to peers.", + }, + []string{"To"}, ) - msgSentFailed = prometheus.NewCounterVec(prometheus.CounterOpts{ + receivedBytes = prometheus.NewCounterVec(prometheus.CounterOpts{ Namespace: "etcd", - Subsystem: "rafthttp", - Name: "message_sent_failed_total", - Help: "The total number of failed messages sent.", + Subsystem: "network", + Name: "peer_received_bytes_total", + Help: "The total number of bytes received from peers.", }, - []string{"sendingType", "remoteID", "msgType"}, + []string{"From"}, + ) + + rtts = prometheus.NewHistogramVec(prometheus.HistogramOpts{ + Namespace: "etcd", + Subsystem: "network", + Name: "peer_round_trip_time_seconds", + Help: "Round-Trip-Time histogram between peers.", + Buckets: prometheus.ExponentialBuckets(0.0001, 2, 14), + }, + []string{"To"}, ) ) func init() { - prometheus.MustRegister(msgSentDuration) - prometheus.MustRegister(msgSentFailed) -} - -func reportSentDuration(sendingType string, m raftpb.Message, duration time.Duration) { - typ := m.Type.String() - if isLinkHeartbeatMessage(m) { - typ = "MsgLinkHeartbeat" - } - msgSentDuration.WithLabelValues(sendingType, types.ID(m.To).String(), typ).Observe(float64(duration) / float64(time.Second)) -} - -func reportSentFailure(sendingType string, m raftpb.Message) { - typ := m.Type.String() - if isLinkHeartbeatMessage(m) { - typ = "MsgLinkHeartbeat" - } - msgSentFailed.WithLabelValues(sendingType, types.ID(m.To).String(), typ).Inc() + prometheus.MustRegister(sentBytes) + prometheus.MustRegister(receivedBytes) + 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 6616872e06b..b6c97e36268 100644 --- a/vendor/github.com/coreos/etcd/rafthttp/msg_codec.go +++ b/vendor/github.com/coreos/etcd/rafthttp/msg_codec.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. diff --git a/vendor/github.com/coreos/etcd/rafthttp/msgappv2_codec.go b/vendor/github.com/coreos/etcd/rafthttp/msgappv2_codec.go index e9292fab0d7..e61bd98c245 100644 --- a/vendor/github.com/coreos/etcd/rafthttp/msgappv2_codec.go +++ b/vendor/github.com/coreos/etcd/rafthttp/msgappv2_codec.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. @@ -58,7 +58,7 @@ const ( // Data format of MsgApp: // | offset | bytes | description | // +--------+-------+-------------+ -// | 0 | 1 | \x01 | +// | 0 | 1 | \x02 | // | 1 | 8 | length of encoded message | // | 9 | n | encoded message | type msgAppV2Encoder struct { diff --git a/vendor/github.com/coreos/etcd/rafthttp/peer.go b/vendor/github.com/coreos/etcd/rafthttp/peer.go index 30b9c4cdca9..3bc8b5190da 100644 --- a/vendor/github.com/coreos/etcd/rafthttp/peer.go +++ b/vendor/github.com/coreos/etcd/rafthttp/peer.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. @@ -117,18 +117,34 @@ type peer struct { stopc chan struct{} } -func startPeer(transport *Transport, urls types.URLs, local, to, cid types.ID, r Raft, fs *stats.FollowerStats, errorc chan error) *peer { - status := newPeerStatus(to) +func startPeer(transport *Transport, urls types.URLs, peerID types.ID, fs *stats.FollowerStats) *peer { + plog.Infof("starting peer %s...", peerID) + defer plog.Infof("started peer %s", peerID) + + status := newPeerStatus(peerID) picker := newURLPicker(urls) + errorc := transport.ErrorC + r := transport.Raft + pipeline := &pipeline{ + peerID: peerID, + tr: transport, + picker: picker, + status: status, + followerStats: fs, + raft: r, + errorc: errorc, + } + pipeline.start() + p := &peer{ - id: to, + id: peerID, r: r, status: status, picker: picker, - msgAppV2Writer: startStreamWriter(to, status, fs, r), - writer: startStreamWriter(to, status, fs, r), - pipeline: newPipeline(transport, picker, local, to, cid, status, fs, r, errorc), - snapSender: newSnapshotSender(transport, picker, local, to, cid, status, r, errorc), + msgAppV2Writer: startStreamWriter(peerID, status, fs, r), + 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), @@ -166,8 +182,26 @@ func startPeer(transport *Transport, urls types.URLs, local, to, cid types.ID, r } }() - p.msgAppV2Reader = startStreamReader(transport, picker, streamTypeMsgAppV2, local, to, cid, status, p.recvc, p.propc, errorc) - p.msgAppReader = startStreamReader(transport, picker, streamTypeMessage, local, to, cid, status, p.recvc, p.propc, errorc) + p.msgAppV2Reader = &streamReader{ + peerID: peerID, + typ: streamTypeMsgAppV2, + tr: transport, + picker: picker, + status: status, + recvc: p.recvc, + propc: p.propc, + } + p.msgAppReader = &streamReader{ + peerID: peerID, + typ: streamTypeMessage, + tr: transport, + picker: picker, + status: status, + recvc: p.recvc, + propc: p.propc, + } + p.msgAppV2Reader.start() + p.msgAppReader.start() return p } @@ -219,7 +253,7 @@ func (p *peer) attachOutgoingConn(conn *outgoingConn) { } } -func (p *peer) activeSince() time.Time { return p.status.activeSince } +func (p *peer) activeSince() time.Time { return p.status.activeSince() } // Pause pauses the peer. The peer will simply drops all incoming // messages without returning an error. @@ -241,6 +275,9 @@ func (p *peer) Resume() { } func (p *peer) stop() { + plog.Infof("stopping peer %s...", p.id) + defer plog.Infof("stopped peer %s", p.id) + close(p.stopc) p.cancel() p.msgAppV2Writer.stop() diff --git a/vendor/github.com/coreos/etcd/rafthttp/peer_status.go b/vendor/github.com/coreos/etcd/rafthttp/peer_status.go index d838b7ab3e5..706144f6466 100644 --- a/vendor/github.com/coreos/etcd/rafthttp/peer_status.go +++ b/vendor/github.com/coreos/etcd/rafthttp/peer_status.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. @@ -28,10 +28,10 @@ type failureType struct { } type peerStatus struct { - id types.ID - mu sync.Mutex // protect variables below - active bool - activeSince time.Time + id types.ID + mu sync.Mutex // protect variables below + active bool + since time.Time } func newPeerStatus(id types.ID) *peerStatus { @@ -44,9 +44,9 @@ func (s *peerStatus) activate() { s.mu.Lock() defer s.mu.Unlock() if !s.active { - plog.Infof("the connection with %s became active", s.id) + plog.Infof("peer %s became active", s.id) s.active = true - s.activeSince = time.Now() + s.since = time.Now() } } @@ -56,9 +56,9 @@ func (s *peerStatus) deactivate(failure failureType, reason string) { msg := fmt.Sprintf("failed to %s %s on %s (%s)", failure.action, s.id, failure.source, reason) if s.active { plog.Errorf(msg) - plog.Infof("the connection with %s became inactive", s.id) + plog.Infof("peer %s became inactive", s.id) s.active = false - s.activeSince = time.Time{} + s.since = time.Time{} return } plog.Debugf(msg) @@ -69,3 +69,9 @@ func (s *peerStatus) isActive() bool { defer s.mu.Unlock() return s.active } + +func (s *peerStatus) activeSince() time.Time { + s.mu.Lock() + defer s.mu.Unlock() + return s.since +} diff --git a/vendor/github.com/coreos/etcd/rafthttp/pipeline.go b/vendor/github.com/coreos/etcd/rafthttp/pipeline.go index b47dd5614e7..4774c91b813 100644 --- a/vendor/github.com/coreos/etcd/rafthttp/pipeline.go +++ b/vendor/github.com/coreos/etcd/rafthttp/pipeline.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. @@ -41,15 +41,15 @@ const ( var errStopped = errors.New("stopped") type pipeline struct { - from, to types.ID - cid types.ID + peerID types.ID tr *Transport picker *urlPicker status *peerStatus - fs *stats.FollowerStats - r Raft + raft Raft errorc chan error + // deprecate when we depercate v2 API + followerStats *stats.FollowerStats msgc chan raftpb.Message // wait for the handling routines @@ -57,30 +57,20 @@ type pipeline struct { stopc chan struct{} } -func newPipeline(tr *Transport, picker *urlPicker, from, to, cid types.ID, status *peerStatus, fs *stats.FollowerStats, r Raft, errorc chan error) *pipeline { - p := &pipeline{ - from: from, - to: to, - cid: cid, - tr: tr, - picker: picker, - status: status, - fs: fs, - r: r, - errorc: errorc, - stopc: make(chan struct{}), - msgc: make(chan raftpb.Message, pipelineBufSize), - } +func (p *pipeline) start() { + p.stopc = make(chan struct{}) + p.msgc = make(chan raftpb.Message, pipelineBufSize) p.wg.Add(connPerPipeline) for i := 0; i < connPerPipeline; i++ { go p.handle() } - return p + plog.Infof("started HTTP pipelining with peer %s", p.peerID) } func (p *pipeline) stop() { close(p.stopc) p.wg.Wait() + plog.Infof("stopped HTTP pipelining with peer %s", p.peerID) } func (p *pipeline) handle() { @@ -96,25 +86,24 @@ func (p *pipeline) handle() { if err != nil { p.status.deactivate(failureType{source: pipelineMsg, action: "write"}, err.Error()) - reportSentFailure(pipelineMsg, m) - if m.Type == raftpb.MsgApp && p.fs != nil { - p.fs.Fail() + if m.Type == raftpb.MsgApp && p.followerStats != nil { + p.followerStats.Fail() } - p.r.ReportUnreachable(m.To) + p.raft.ReportUnreachable(m.To) if isMsgSnap(m) { - p.r.ReportSnapshot(m.To, raft.SnapshotFailure) + p.raft.ReportSnapshot(m.To, raft.SnapshotFailure) } continue } p.status.activate() - if m.Type == raftpb.MsgApp && p.fs != nil { - p.fs.Succ(end.Sub(start)) + if m.Type == raftpb.MsgApp && p.followerStats != nil { + p.followerStats.Succ(end.Sub(start)) } if isMsgSnap(m) { - p.r.ReportSnapshot(m.To, raft.SnapshotFinish) + p.raft.ReportSnapshot(m.To, raft.SnapshotFinish) } - reportSentDuration(pipelineMsg, m, time.Since(start)) + sentBytes.WithLabelValues(types.ID(m.To).String()).Add(float64(m.Size())) case <-p.stopc: return } @@ -125,7 +114,7 @@ func (p *pipeline) handle() { // error on any failure. func (p *pipeline) post(data []byte) (err error) { u := p.picker.pick() - req := createPostRequest(u, RaftPrefix, bytes.NewBuffer(data), "application/protobuf", p.tr.URLs, p.from, p.cid) + 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) @@ -151,7 +140,7 @@ func (p *pipeline) post(data []byte) (err error) { } resp.Body.Close() - err = checkPostResponse(resp, b, req, p.to) + err = checkPostResponse(resp, b, req, p.peerID) if err != nil { p.picker.unreachable(u) // errMemberRemoved is a critical error since a removed member should diff --git a/vendor/github.com/coreos/etcd/rafthttp/probing_status.go b/vendor/github.com/coreos/etcd/rafthttp/probing_status.go index b3027a96fb8..a0859a4cb6d 100644 --- a/vendor/github.com/coreos/etcd/rafthttp/probing_status.go +++ b/vendor/github.com/coreos/etcd/rafthttp/probing_status.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. @@ -48,11 +48,12 @@ func monitorProbingStatus(s probing.Status, id string) { select { case <-time.After(statusMonitoringInterval): if !s.Health() { - plog.Warningf("the connection to peer %s is unhealthy", id) + plog.Warningf("health check for peer %s failed", id) } if s.ClockDiff() > time.Second { plog.Warningf("the clock difference against peer %s is too high [%v > %v]", id, s.ClockDiff(), time.Second) } + rtts.WithLabelValues(id).Observe(s.SRTT().Seconds()) case <-s.StopNotify(): return } diff --git a/vendor/github.com/coreos/etcd/rafthttp/remote.go b/vendor/github.com/coreos/etcd/rafthttp/remote.go index a41bf2ac397..f83f4ab82dc 100644 --- a/vendor/github.com/coreos/etcd/rafthttp/remote.go +++ b/vendor/github.com/coreos/etcd/rafthttp/remote.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. @@ -25,13 +25,23 @@ type remote struct { pipeline *pipeline } -func startRemote(tr *Transport, urls types.URLs, local, to, cid types.ID, r Raft, errorc chan error) *remote { +func startRemote(tr *Transport, urls types.URLs, id types.ID) *remote { picker := newURLPicker(urls) - status := newPeerStatus(to) + status := newPeerStatus(id) + pipeline := &pipeline{ + peerID: id, + tr: tr, + picker: picker, + status: status, + raft: tr.Raft, + errorc: tr.ErrorC, + } + pipeline.start() + return &remote{ - id: to, + id: id, status: status, - pipeline: newPipeline(tr, picker, local, to, cid, status, nil, r, errorc), + pipeline: pipeline, } } diff --git a/vendor/github.com/coreos/etcd/rafthttp/snapshot_sender.go b/vendor/github.com/coreos/etcd/rafthttp/snapshot_sender.go index a871b886abf..615e408e37b 100644 --- a/vendor/github.com/coreos/etcd/rafthttp/snapshot_sender.go +++ b/vendor/github.com/coreos/etcd/rafthttp/snapshot_sender.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. @@ -46,16 +46,16 @@ type snapshotSender struct { stopc chan struct{} } -func newSnapshotSender(tr *Transport, picker *urlPicker, from, to, cid types.ID, status *peerStatus, r Raft, errorc chan error) *snapshotSender { +func newSnapshotSender(tr *Transport, picker *urlPicker, to types.ID, status *peerStatus) *snapshotSender { return &snapshotSender{ - from: from, + from: tr.ID, to: to, - cid: cid, + cid: tr.ClusterID, tr: tr, picker: picker, status: status, - r: r, - errorc: errorc, + r: tr.Raft, + errorc: tr.ErrorC, stopc: make(chan struct{}), } } @@ -65,8 +65,6 @@ func (s *snapshotSender) stop() { close(s.stopc) } func (s *snapshotSender) send(merged snap.Message) { m := merged.Message - start := time.Now() - body := createSnapBody(merged) defer body.Close() @@ -87,7 +85,6 @@ func (s *snapshotSender) send(merged snap.Message) { } s.picker.unreachable(u) - reportSentFailure(sendSnap, m) s.status.deactivate(failureType{source: sendSnap, action: "post"}, err.Error()) s.r.ReportUnreachable(m.To) // report SnapshotFailure to raft state machine. After raft state @@ -96,10 +93,11 @@ func (s *snapshotSender) send(merged snap.Message) { s.r.ReportSnapshot(m.To, raft.SnapshotFailure) return } - reportSentDuration(sendSnap, m, time.Since(start)) s.status.activate() s.r.ReportSnapshot(m.To, raft.SnapshotFinish) plog.Infof("database snapshot [index: %d, to: %s] sent out successfully", m.Snapshot.Metadata.Index, types.ID(m.To)) + + sentBytes.WithLabelValues(types.ID(m.To).String()).Add(float64(merged.TotalSize)) } // post posts the given request. diff --git a/vendor/github.com/coreos/etcd/rafthttp/stream.go b/vendor/github.com/coreos/etcd/rafthttp/stream.go index 1a76b89cc2f..07bc1c20474 100644 --- a/vendor/github.com/coreos/etcd/rafthttp/stream.go +++ b/vendor/github.com/coreos/etcd/rafthttp/stream.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. @@ -97,7 +97,7 @@ type outgoingConn struct { // streamWriter writes messages to the attached outgoingConn. type streamWriter struct { - id types.ID + peerID types.ID status *peerStatus fs *stats.FollowerStats r Raft @@ -116,7 +116,7 @@ type streamWriter struct { // messages and writes to the attached outgoing connection. func startStreamWriter(id types.ID, status *peerStatus, fs *stats.FollowerStats, r Raft) *streamWriter { w := &streamWriter{ - id: id, + peerID: id, status: status, fs: fs, r: r, @@ -139,47 +139,56 @@ func (cw *streamWriter) run() { batched int ) tickc := time.Tick(ConnReadTimeout / 3) + unflushed := 0 + + plog.Infof("started streaming with peer %s (writer)", cw.peerID) for { select { case <-heartbeatc: - start := time.Now() err := enc.encode(linkHeartbeatMessage) + unflushed += linkHeartbeatMessage.Size() if err == nil { flusher.Flush() batched = 0 - reportSentDuration(string(t), linkHeartbeatMessage, time.Since(start)) + sentBytes.WithLabelValues(cw.peerID.String()).Add(float64(unflushed)) + unflushed = 0 continue } - reportSentFailure(string(t), linkHeartbeatMessage) cw.status.deactivate(failureType{source: t.String(), action: "heartbeat"}, err.Error()) + cw.close() + plog.Warningf("lost the TCP streaming connection with peer %s (%s writer)", cw.peerID, t) heartbeatc, msgc = nil, nil case m := <-msgc: - start := time.Now() err := enc.encode(m) if err == nil { + unflushed += m.Size() + if len(msgc) == 0 || batched > streamBufSize/2 { flusher.Flush() + sentBytes.WithLabelValues(cw.peerID.String()).Add(float64(unflushed)) + unflushed = 0 batched = 0 } else { batched++ } - reportSentDuration(string(t), m, time.Since(start)) continue } - reportSentFailure(string(t), m) cw.status.deactivate(failureType{source: t.String(), action: "write"}, err.Error()) cw.close() + plog.Warningf("lost the TCP streaming connection with peer %s (%s writer)", cw.peerID, t) heartbeatc, msgc = nil, nil cw.r.ReportUnreachable(m.To) case conn := <-cw.connc: - cw.close() + if cw.close() { + plog.Warningf("closed an existing TCP streaming connection with peer %s (%s writer)", cw.peerID, t) + } t = conn.t switch conn.t { case streamTypeMsgAppV2: @@ -190,15 +199,20 @@ func (cw *streamWriter) run() { plog.Panicf("unhandled stream type %s", conn.t) } flusher = conn.Flusher + unflushed = 0 cw.mu.Lock() cw.status.activate() cw.closer = conn.Closer cw.working = true cw.mu.Unlock() + plog.Infof("established a TCP streaming connection with peer %s (%s writer)", cw.peerID, t) heartbeatc, msgc = tickc, cw.msgc case <-cw.stopc: - cw.close() + 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) return } } @@ -210,18 +224,19 @@ func (cw *streamWriter) writec() (chan<- raftpb.Message, bool) { return cw.msgc, cw.working } -func (cw *streamWriter) close() { +func (cw *streamWriter) close() bool { cw.mu.Lock() defer cw.mu.Unlock() if !cw.working { - return + return false } cw.closer.Close() if len(cw.msgc) > 0 { - cw.r.ReportUnreachable(uint64(cw.id)) + cw.r.ReportUnreachable(uint64(cw.peerID)) } cw.msgc = make(chan raftpb.Message, streamBufSize) cw.working = false + return true } func (cw *streamWriter) attach(conn *outgoingConn) bool { @@ -241,46 +256,40 @@ func (cw *streamWriter) stop() { // streamReader is a long-running go-routine that dials to the remote stream // endpoint and reads messages from the response body returned. type streamReader struct { - tr *Transport - picker *urlPicker - t streamType - local, remote types.ID - cid types.ID - status *peerStatus - recvc chan<- raftpb.Message - propc chan<- raftpb.Message - errorc chan<- error + peerID types.ID + typ streamType + + tr *Transport + picker *urlPicker + status *peerStatus + recvc chan<- raftpb.Message + propc chan<- raftpb.Message + + errorc chan<- error mu sync.Mutex paused bool cancel func() closer io.Closer - stopc chan struct{} - done chan struct{} + + stopc chan struct{} + done chan struct{} } -func startStreamReader(tr *Transport, picker *urlPicker, t streamType, local, remote, cid types.ID, status *peerStatus, recvc chan<- raftpb.Message, propc chan<- raftpb.Message, errorc chan<- error) *streamReader { - r := &streamReader{ - tr: tr, - picker: picker, - t: t, - local: local, - remote: remote, - cid: cid, - status: status, - recvc: recvc, - propc: propc, - errorc: errorc, - stopc: make(chan struct{}), - done: make(chan struct{}), +func (r *streamReader) start() { + r.stopc = make(chan struct{}) + r.done = make(chan struct{}) + if r.errorc == nil { + r.errorc = r.tr.ErrorC } + go r.run() - return r } func (cr *streamReader) run() { + t := cr.typ + plog.Infof("started streaming with peer %s (%s reader)", cr.peerID, t) for { - t := cr.t rc, err := cr.dial(t) if err != nil { if err != errUnsupportedStreamType { @@ -288,7 +297,9 @@ func (cr *streamReader) run() { } } else { cr.status.activate() + plog.Infof("established a TCP streaming connection with peer %s (%s reader)", cr.peerID, cr.typ) err := cr.decodeLoop(rc, t) + plog.Warningf("lost the TCP streaming connection with peer %s (%s reader)", cr.peerID, cr.typ) switch { // all data is read out case err == io.EOF: @@ -304,6 +315,7 @@ func (cr *streamReader) run() { case <-time.After(100 * time.Millisecond): case <-cr.stopc: close(cr.done) + plog.Infof("stopped streaming with peer %s (%s reader)", cr.peerID, t) return } } @@ -314,7 +326,7 @@ func (cr *streamReader) decodeLoop(rc io.ReadCloser, t streamType) error { cr.mu.Lock() switch t { case streamTypeMsgAppV2: - dec = newMsgAppV2Decoder(rc, cr.local, cr.remote) + dec = newMsgAppV2Decoder(rc, cr.tr.ID, cr.peerID) case streamTypeMessage: dec = &messageDecoder{r: rc} default: @@ -332,6 +344,8 @@ func (cr *streamReader) decodeLoop(rc io.ReadCloser, t streamType) error { return err } + receivedBytes.WithLabelValues(types.ID(m.From).String()).Add(float64(m.Size())) + cr.mu.Lock() paused := cr.paused cr.mu.Unlock() @@ -377,18 +391,18 @@ func (cr *streamReader) stop() { func (cr *streamReader) dial(t streamType) (io.ReadCloser, error) { u := cr.picker.pick() uu := u - uu.Path = path.Join(t.endpoint(), cr.local.String()) + uu.Path = path.Join(t.endpoint(), cr.tr.ID.String()) req, err := http.NewRequest("GET", uu.String(), nil) if err != nil { cr.picker.unreachable(u) - return nil, fmt.Errorf("failed to make http request to %s (%v)", u, err) + return nil, fmt.Errorf("failed to make http request to %v (%v)", u, err) } - req.Header.Set("X-Server-From", cr.local.String()) + req.Header.Set("X-Server-From", cr.tr.ID.String()) req.Header.Set("X-Server-Version", version.Version) req.Header.Set("X-Min-Cluster-Version", version.MinClusterVersion) - req.Header.Set("X-Etcd-Cluster-ID", cr.cid.String()) - req.Header.Set("X-Raft-To", cr.remote.String()) + req.Header.Set("X-Etcd-Cluster-ID", cr.tr.ClusterID.String()) + req.Header.Set("X-Raft-To", cr.peerID.String()) setPeerURLsHeader(req, cr.tr.URLs) @@ -431,7 +445,7 @@ func (cr *streamReader) dial(t streamType) (io.ReadCloser, error) { case http.StatusNotFound: httputil.GracefulClose(resp) cr.picker.unreachable(u) - return nil, fmt.Errorf("remote member %s could not recognize local member", cr.remote) + return nil, fmt.Errorf("peer %s faild to fine local node %s", cr.peerID, cr.tr.ID) case http.StatusPreconditionFailed: b, err := ioutil.ReadAll(resp.Body) if err != nil { @@ -443,11 +457,11 @@ func (cr *streamReader) dial(t streamType) (io.ReadCloser, error) { switch strings.TrimSuffix(string(b), "\n") { case errIncompatibleVersion.Error(): - plog.Errorf("request sent was ignored by peer %s (server version incompatible)", cr.remote) + plog.Errorf("request sent was ignored by peer %s (server version incompatible)", cr.peerID) return nil, errIncompatibleVersion case errClusterIDMismatch.Error(): - plog.Errorf("request sent was ignored (cluster ID mismatch: remote[%s]=%s, local=%s)", - cr.remote, resp.Header.Get("X-Etcd-Cluster-ID"), cr.cid) + plog.Errorf("request sent was ignored (cluster ID mismatch: peer[%s]=%s, local=%s)", + cr.peerID, resp.Header.Get("X-Etcd-Cluster-ID"), cr.tr.ClusterID) return nil, errClusterIDMismatch default: return nil, fmt.Errorf("unhandled error %q when precondition failed", string(b)) diff --git a/vendor/github.com/coreos/etcd/rafthttp/transport.go b/vendor/github.com/coreos/etcd/rafthttp/transport.go index 3c4ce3c194c..a7692d3b9d9 100644 --- a/vendor/github.com/coreos/etcd/rafthttp/transport.go +++ b/vendor/github.com/coreos/etcd/rafthttp/transport.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. @@ -202,11 +202,19 @@ func (t *Transport) Stop() { if tr, ok := t.pipelineRt.(*http.Transport); ok { tr.CloseIdleConnections() } + t.peers = nil + t.remotes = nil } func (t *Transport) AddRemote(id types.ID, us []string) { t.mu.Lock() defer t.mu.Unlock() + if t.remotes == nil { + // there's no clean way to shutdown the golang http server + // (see: https://github.com/golang/go/issues/4674) before + // stopping the transport; ignore any new connections. + return + } if _, ok := t.peers[id]; ok { return } @@ -217,12 +225,16 @@ func (t *Transport) AddRemote(id types.ID, us []string) { if err != nil { plog.Panicf("newURLs %+v should never fail: %+v", us, err) } - t.remotes[id] = startRemote(t, urls, t.ID, id, t.ClusterID, t.Raft, t.ErrorC) + t.remotes[id] = startRemote(t, urls, id) } func (t *Transport) AddPeer(id types.ID, us []string) { t.mu.Lock() defer t.mu.Unlock() + + if t.peers == nil { + panic("transport stopped") + } if _, ok := t.peers[id]; ok { return } @@ -231,8 +243,10 @@ func (t *Transport) AddPeer(id types.ID, us []string) { plog.Panicf("newURLs %+v should never fail: %+v", us, err) } fs := t.LeaderStats.Follower(id.String()) - t.peers[id] = startPeer(t, urls, t.ID, id, t.ClusterID, t.Raft, fs, t.ErrorC) + t.peers[id] = startPeer(t, urls, id, fs) addPeerToProber(t.prober, id.String(), us) + + plog.Infof("added peer %s", id) } func (t *Transport) RemovePeer(id types.ID) { @@ -259,6 +273,7 @@ func (t *Transport) removePeer(id types.ID) { delete(t.peers, id) delete(t.LeaderStats.Followers, id.String()) t.prober.Remove(id.String()) + plog.Infof("removed peer %s", id) } func (t *Transport) UpdatePeer(id types.ID, us []string) { @@ -276,6 +291,7 @@ func (t *Transport) UpdatePeer(id types.ID, us []string) { t.prober.Remove(id.String()) addPeerToProber(t.prober, id.String(), us) + plog.Infof("updated peer %s", id) } func (t *Transport) ActiveSince(id types.ID) time.Time { diff --git a/vendor/github.com/coreos/etcd/rafthttp/urlpick.go b/vendor/github.com/coreos/etcd/rafthttp/urlpick.go index 584f1c0ad3e..61839deeb70 100644 --- a/vendor/github.com/coreos/etcd/rafthttp/urlpick.go +++ b/vendor/github.com/coreos/etcd/rafthttp/urlpick.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. diff --git a/vendor/github.com/coreos/etcd/rafthttp/util.go b/vendor/github.com/coreos/etcd/rafthttp/util.go index 93c87f8f493..61855c52a60 100644 --- a/vendor/github.com/coreos/etcd/rafthttp/util.go +++ b/vendor/github.com/coreos/etcd/rafthttp/util.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. @@ -197,9 +197,9 @@ func setPeerURLsHeader(req *http.Request, urls types.URLs) { // often not set in unit tests return } - var peerURLs []string - for _, url := range urls { - peerURLs = append(peerURLs, url.String()) + peerURLs := make([]string, urls.Len()) + for i := range urls { + peerURLs[i] = urls[i].String() } req.Header.Set("X-PeerURLs", strings.Join(peerURLs, ",")) } diff --git a/vendor/github.com/coreos/etcd/snap/db.go b/vendor/github.com/coreos/etcd/snap/db.go index ca68837cb1b..743deac1e2a 100644 --- a/vendor/github.com/coreos/etcd/snap/db.go +++ b/vendor/github.com/coreos/etcd/snap/db.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. @@ -26,35 +26,35 @@ import ( // SaveDBFrom saves snapshot of the database from the given reader. It // guarantees the save operation is atomic. -func (s *Snapshotter) SaveDBFrom(r io.Reader, id uint64) error { +func (s *Snapshotter) SaveDBFrom(r io.Reader, id uint64) (int64, error) { f, err := ioutil.TempFile(s.dir, "tmp") if err != nil { - return err + return 0, err } var n int64 n, err = io.Copy(f, r) if err == nil { - err = f.Sync() + err = fileutil.Fsync(f) } f.Close() if err != nil { os.Remove(f.Name()) - return err + return n, err } fn := path.Join(s.dir, fmt.Sprintf("%016x.snap.db", id)) if fileutil.Exist(fn) { os.Remove(f.Name()) - return nil + return n, nil } err = os.Rename(f.Name(), fn) if err != nil { os.Remove(f.Name()) - return err + return n, err } plog.Infof("saved database snapshot to disk [total bytes: %d]", n) - return nil + return n, nil } // DBFilePath returns the file path for the snapshot of the database with diff --git a/vendor/github.com/coreos/etcd/snap/message.go b/vendor/github.com/coreos/etcd/snap/message.go index 2d2b2110619..d73713ff169 100644 --- a/vendor/github.com/coreos/etcd/snap/message.go +++ b/vendor/github.com/coreos/etcd/snap/message.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. @@ -17,6 +17,7 @@ package snap import ( "io" + "github.com/coreos/etcd/pkg/ioutil" "github.com/coreos/etcd/raft/raftpb" ) @@ -31,13 +32,15 @@ import ( type Message struct { raftpb.Message ReadCloser io.ReadCloser + TotalSize int64 closeC chan bool } -func NewMessage(rs raftpb.Message, rc io.ReadCloser) *Message { +func NewMessage(rs raftpb.Message, rc io.ReadCloser, rcSize int64) *Message { return &Message{ Message: rs, - ReadCloser: rc, + ReadCloser: ioutil.NewExactReadCloser(rc, rcSize), + TotalSize: int64(rs.Size()) + rcSize, closeC: make(chan bool, 1), } } @@ -50,7 +53,9 @@ func (m Message) CloseNotify() <-chan bool { } func (m Message) CloseWithError(err error) { - m.ReadCloser.Close() + if cerr := m.ReadCloser.Close(); cerr != nil { + err = cerr + } if err == nil { m.closeC <- true } else { diff --git a/vendor/github.com/coreos/etcd/snap/metrics.go b/vendor/github.com/coreos/etcd/snap/metrics.go index 88aad5dc9c7..433ef09d4ba 100644 --- a/vendor/github.com/coreos/etcd/snap/metrics.go +++ b/vendor/github.com/coreos/etcd/snap/metrics.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. @@ -19,17 +19,17 @@ import "github.com/prometheus/client_golang/prometheus" var ( // TODO: save_fsync latency? saveDurations = prometheus.NewHistogram(prometheus.HistogramOpts{ - Namespace: "etcd", - Subsystem: "snapshot", - Name: "save_total_durations_seconds", + Namespace: "etcd_debugging", + Subsystem: "snap", + Name: "save_total_duration_seconds", Help: "The total latency distributions of save called by snapshot.", Buckets: prometheus.ExponentialBuckets(0.001, 2, 14), }) marshallingDurations = prometheus.NewHistogram(prometheus.HistogramOpts{ - Namespace: "etcd", - Subsystem: "snapshot", - Name: "save_marshalling_durations_seconds", + Namespace: "etcd_debugging", + Subsystem: "snap", + Name: "save_marshalling_duration_seconds", Help: "The marshalling cost distributions of save called by snapshot.", Buckets: prometheus.ExponentialBuckets(0.001, 2, 14), }) 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 f83fd411a28..11c86dfeaed 100644 --- a/vendor/github.com/coreos/etcd/snap/snappb/snap.pb.go +++ b/vendor/github.com/coreos/etcd/snap/snappb/snap.pb.go @@ -16,7 +16,7 @@ package snappb import ( "fmt" - proto "github.com/gogo/protobuf/proto" + proto "github.com/golang/protobuf/proto" math "math" ) @@ -28,15 +28,20 @@ var _ = proto.Marshal var _ = fmt.Errorf 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 + type Snapshot struct { Crc uint32 `protobuf:"varint,1,opt,name=crc" json:"crc"` Data []byte `protobuf:"bytes,2,opt,name=data" json:"data,omitempty"` XXX_unrecognized []byte `json:"-"` } -func (m *Snapshot) Reset() { *m = Snapshot{} } -func (m *Snapshot) String() string { return proto.CompactTextString(m) } -func (*Snapshot) ProtoMessage() {} +func (m *Snapshot) Reset() { *m = Snapshot{} } +func (m *Snapshot) String() string { return proto.CompactTextString(m) } +func (*Snapshot) ProtoMessage() {} +func (*Snapshot) Descriptor() ([]byte, []int) { return fileDescriptorSnap, []int{0} } func init() { proto.RegisterType((*Snapshot)(nil), "snappb.snapshot") @@ -330,3 +335,15 @@ var ( ErrInvalidLengthSnap = fmt.Errorf("proto: negative length found during unmarshaling") ErrIntOverflowSnap = fmt.Errorf("proto: integer overflow") ) + +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, + 0xd0, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0x03, 0xb1, 0x0b, 0x92, 0xa4, 0x44, 0xd2, 0xf3, + 0xd3, 0xf3, 0xc1, 0x42, 0xfa, 0x20, 0x16, 0x44, 0x56, 0xc9, 0x8c, 0x8b, 0x03, 0x24, 0x5f, 0x9c, + 0x91, 0x5f, 0x22, 0x24, 0xc6, 0xc5, 0x9c, 0x5c, 0x94, 0x2c, 0xc1, 0xa8, 0xc0, 0xa8, 0xc1, 0xeb, + 0xc4, 0x72, 0xe2, 0x9e, 0x3c, 0x43, 0x10, 0x48, 0x40, 0x48, 0x88, 0x8b, 0x25, 0x25, 0xb1, 0x24, + 0x51, 0x82, 0x49, 0x81, 0x51, 0x83, 0x27, 0x08, 0xcc, 0x76, 0x12, 0x39, 0xf1, 0x50, 0x8e, 0xe1, + 0xc4, 0x23, 0x39, 0xc6, 0x0b, 0x8f, 0xe4, 0x18, 0x1f, 0x3c, 0x92, 0x63, 0x9c, 0xf1, 0x58, 0x8e, + 0x01, 0x10, 0x00, 0x00, 0xff, 0xff, 0xd8, 0x0f, 0x32, 0xb2, 0x78, 0x00, 0x00, 0x00, +} diff --git a/vendor/github.com/coreos/etcd/snap/snapshotter.go b/vendor/github.com/coreos/etcd/snap/snapshotter.go index ab56d32dbc9..50d09dda14c 100644 --- a/vendor/github.com/coreos/etcd/snap/snapshotter.go +++ b/vendor/github.com/coreos/etcd/snap/snapshotter.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. @@ -26,6 +26,7 @@ import ( "strings" "time" + pioutil "github.com/coreos/etcd/pkg/ioutil" "github.com/coreos/etcd/pkg/pbutil" "github.com/coreos/etcd/raft" "github.com/coreos/etcd/raft/raftpb" @@ -83,9 +84,14 @@ func (s *Snapshotter) save(snapshot *raftpb.Snapshot) error { marshallingDurations.Observe(float64(time.Since(start)) / float64(time.Second)) } - err = ioutil.WriteFile(path.Join(s.dir, fname), d, 0666) + err = pioutil.WriteAndSyncFile(path.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)) + if err1 != nil { + plog.Errorf("failed to remove broken snapshot file %s", path.Join(s.dir, fname)) + } } return err } diff --git a/vendor/github.com/coreos/etcd/store/doc.go b/vendor/github.com/coreos/etcd/store/doc.go index 08cb924ab94..612df927976 100644 --- a/vendor/github.com/coreos/etcd/store/doc.go +++ b/vendor/github.com/coreos/etcd/store/doc.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. diff --git a/vendor/github.com/coreos/etcd/store/event.go b/vendor/github.com/coreos/etcd/store/event.go index 8b1cfc02a06..efcddb0e053 100644 --- a/vendor/github.com/coreos/etcd/store/event.go +++ b/vendor/github.com/coreos/etcd/store/event.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. @@ -30,6 +30,7 @@ type Event struct { Node *NodeExtern `json:"node,omitempty"` PrevNode *NodeExtern `json:"prevNode,omitempty"` EtcdIndex uint64 `json:"-"` + Refresh bool `json:"refresh,omitempty"` } func newEvent(action string, key string, modifiedIndex, createdIndex uint64) *Event { @@ -64,3 +65,7 @@ func (e *Event) Clone() *Event { PrevNode: e.PrevNode.Clone(), } } + +func (e *Event) SetRefresh() { + e.Refresh = true +} diff --git a/vendor/github.com/coreos/etcd/store/event_history.go b/vendor/github.com/coreos/etcd/store/event_history.go index 5bd967eadc3..4977ee93aa3 100644 --- a/vendor/github.com/coreos/etcd/store/event_history.go +++ b/vendor/github.com/coreos/etcd/store/event_history.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. @@ -78,24 +78,26 @@ func (eh *EventHistory) scan(key string, recursive bool, index uint64) (*Event, for { e := eh.Queue.Events[i] - ok := (e.Node.Key == key) + if !e.Refresh { + ok := (e.Node.Key == key) - if recursive { - // add tailing slash - key = path.Clean(key) - if key[len(key)-1] != '/' { - key = key + "/" + if recursive { + // add tailing slash + key = path.Clean(key) + if key[len(key)-1] != '/' { + key = key + "/" + } + + ok = ok || strings.HasPrefix(e.Node.Key, key) } - ok = ok || strings.HasPrefix(e.Node.Key, key) - } + if (e.Action == Delete || e.Action == Expire) && e.PrevNode != nil && e.PrevNode.Dir { + ok = ok || strings.HasPrefix(key, e.PrevNode.Key) + } - if (e.Action == Delete || e.Action == Expire) && e.PrevNode != nil && e.PrevNode.Dir { - ok = ok || strings.HasPrefix(key, e.PrevNode.Key) - } - - if ok { - return e, nil + if ok { + return e, nil + } } i = (i + 1) % eh.Queue.Capacity @@ -117,10 +119,7 @@ func (eh *EventHistory) clone() *EventHistory { Back: eh.Queue.Back, } - for i, e := range eh.Queue.Events { - clonedQueue.Events[i] = e - } - + copy(clonedQueue.Events, eh.Queue.Events) return &EventHistory{ StartIndex: eh.StartIndex, Queue: clonedQueue, diff --git a/vendor/github.com/coreos/etcd/store/event_queue.go b/vendor/github.com/coreos/etcd/store/event_queue.go index cd35d43526b..767b835913e 100644 --- a/vendor/github.com/coreos/etcd/store/event_queue.go +++ b/vendor/github.com/coreos/etcd/store/event_queue.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. diff --git a/vendor/github.com/coreos/etcd/store/metrics.go b/vendor/github.com/coreos/etcd/store/metrics.go index 12bf545dab2..26404ba72e3 100644 --- a/vendor/github.com/coreos/etcd/store/metrics.go +++ b/vendor/github.com/coreos/etcd/store/metrics.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. @@ -26,7 +26,7 @@ import ( var ( readCounter = prometheus.NewCounterVec( prometheus.CounterOpts{ - Namespace: "etcd", + Namespace: "etcd_debugging", Subsystem: "store", Name: "reads_total", Help: "Total number of reads action by (get/getRecursive), local to this member.", @@ -34,7 +34,7 @@ var ( writeCounter = prometheus.NewCounterVec( prometheus.CounterOpts{ - Namespace: "etcd", + Namespace: "etcd_debugging", Subsystem: "store", Name: "writes_total", Help: "Total number of writes (e.g. set/compareAndDelete) seen by this member.", @@ -42,7 +42,7 @@ var ( readFailedCounter = prometheus.NewCounterVec( prometheus.CounterOpts{ - Namespace: "etcd", + Namespace: "etcd_debugging", Subsystem: "store", Name: "reads_failed_total", Help: "Failed read actions by (get/getRecursive), local to this member.", @@ -50,7 +50,7 @@ var ( writeFailedCounter = prometheus.NewCounterVec( prometheus.CounterOpts{ - Namespace: "etcd", + Namespace: "etcd_debugging", Subsystem: "store", Name: "writes_failed_total", Help: "Failed write actions (e.g. set/compareAndDelete), seen by this member.", @@ -58,7 +58,7 @@ var ( expireCounter = prometheus.NewCounter( prometheus.CounterOpts{ - Namespace: "etcd", + Namespace: "etcd_debugging", Subsystem: "store", Name: "expires_total", Help: "Total number of expired keys.", @@ -66,7 +66,7 @@ var ( watchRequests = prometheus.NewCounter( prometheus.CounterOpts{ - Namespace: "etcd", + Namespace: "etcd_debugging", Subsystem: "store", Name: "watch_requests_total", Help: "Total number of incoming watch requests (new or reestablished).", @@ -74,7 +74,7 @@ var ( watcherCount = prometheus.NewGauge( prometheus.GaugeOpts{ - Namespace: "etcd", + Namespace: "etcd_debugging", Subsystem: "store", Name: "watchers", Help: "Count of currently active watchers.", diff --git a/vendor/github.com/coreos/etcd/store/node.go b/vendor/github.com/coreos/etcd/store/node.go index f9ba458a97e..731327b08ba 100644 --- a/vendor/github.com/coreos/etcd/store/node.go +++ b/vendor/github.com/coreos/etcd/store/node.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. diff --git a/vendor/github.com/coreos/etcd/store/node_extern.go b/vendor/github.com/coreos/etcd/store/node_extern.go index 891a602c166..7ba870cbe7b 100644 --- a/vendor/github.com/coreos/etcd/store/node_extern.go +++ b/vendor/github.com/coreos/etcd/store/node_extern.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. diff --git a/vendor/github.com/coreos/etcd/store/stats.go b/vendor/github.com/coreos/etcd/store/stats.go index a3c76796df0..59b45f2b8b3 100644 --- a/vendor/github.com/coreos/etcd/store/stats.go +++ b/vendor/github.com/coreos/etcd/store/stats.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. diff --git a/vendor/github.com/coreos/etcd/store/store.go b/vendor/github.com/coreos/etcd/store/store.go index 3a4ec0df494..f0a1fe5385b 100644 --- a/vendor/github.com/coreos/etcd/store/store.go +++ b/vendor/github.com/coreos/etcd/store/store.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. @@ -119,8 +119,8 @@ func (s *store) Index() uint64 { func (s *store) Get(nodePath string, recursive, sorted bool) (*Event, error) { var err *etcdErr.Error - s.worldLock.Lock() - defer s.worldLock.Unlock() + s.worldLock.RLock() + defer s.worldLock.RUnlock() defer func() { if err == nil { @@ -236,6 +236,9 @@ func (s *store) Set(nodePath string, dir bool, value string, expireOpts TTLOptio if !expireOpts.Refresh { s.WatcherHub.notify(e) + } else { + e.SetRefresh() + s.WatcherHub.add(e) } return e, nil @@ -295,6 +298,10 @@ func (s *store) CompareAndSwap(nodePath string, prevValue string, prevIndex uint return nil, err } + if expireOpts.Refresh { + value = n.Value + } + // update etcd index s.CurrentIndex++ @@ -314,6 +321,9 @@ func (s *store) CompareAndSwap(nodePath string, prevValue string, prevIndex uint if !expireOpts.Refresh { s.WatcherHub.notify(e) + } else { + e.SetRefresh() + s.WatcherHub.add(e) } return e, nil @@ -345,7 +355,7 @@ func (s *store) Delete(nodePath string, dir, recursive bool) (*Event, error) { } // recursive implies dir - if recursive == true { + if recursive { dir = true } @@ -539,6 +549,9 @@ func (s *store) Update(nodePath string, newValue string, expireOpts TTLOptionSet if !expireOpts.Refresh { s.WatcherHub.notify(e) + } else { + e.SetRefresh() + s.WatcherHub.add(e) } s.CurrentIndex = nextIndex diff --git a/vendor/github.com/coreos/etcd/store/ttl_key_heap.go b/vendor/github.com/coreos/etcd/store/ttl_key_heap.go index d2dffeccb90..21ae9b7c699 100644 --- a/vendor/github.com/coreos/etcd/store/ttl_key_heap.go +++ b/vendor/github.com/coreos/etcd/store/ttl_key_heap.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. diff --git a/vendor/github.com/coreos/etcd/store/watcher.go b/vendor/github.com/coreos/etcd/store/watcher.go index 252cdb1c603..a236ec77703 100644 --- a/vendor/github.com/coreos/etcd/store/watcher.go +++ b/vendor/github.com/coreos/etcd/store/watcher.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. diff --git a/vendor/github.com/coreos/etcd/store/watcher_hub.go b/vendor/github.com/coreos/etcd/store/watcher_hub.go index 112e10ca6ee..6dd63f3c541 100644 --- a/vendor/github.com/coreos/etcd/store/watcher_hub.go +++ b/vendor/github.com/coreos/etcd/store/watcher_hub.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. @@ -115,6 +115,10 @@ func (wh *watcherHub) watch(key string, recursive, stream bool, index, storeInde return w, nil } +func (wh *watcherHub) add(e *Event) { + e = wh.EventHistory.addEvent(e) +} + // notify function accepts an event and notify to the watchers. func (wh *watcherHub) notify(e *Event) { e = wh.EventHistory.addEvent(e) // add event into the eventHistory diff --git a/vendor/github.com/coreos/etcd/version/version.go b/vendor/github.com/coreos/etcd/version/version.go index 7b9daf0ba20..01bdd6933c1 100644 --- a/vendor/github.com/coreos/etcd/version/version.go +++ b/vendor/github.com/coreos/etcd/version/version.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. @@ -28,8 +28,8 @@ import ( var ( // MinClusterVersion is the min cluster version this etcd binary is compatible with. - MinClusterVersion = "2.2.0" - Version = "2.3.0+git" + MinClusterVersion = "2.3.0" + Version = "3.0.4" // Git SHA Value will be set during build GitSHA = "Not provided (use ./build instead of go build)" diff --git a/vendor/github.com/coreos/etcd/wal/decoder.go b/vendor/github.com/coreos/etcd/wal/decoder.go index 0678ab74f69..0d9b4428c94 100644 --- a/vendor/github.com/coreos/etcd/wal/decoder.go +++ b/vendor/github.com/coreos/etcd/wal/decoder.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. @@ -27,6 +27,8 @@ import ( "github.com/coreos/etcd/wal/walpb" ) +const minSectorSize = 512 + type decoder struct { mu sync.Mutex brs []*bufio.Reader @@ -73,7 +75,9 @@ func (d *decoder) decodeRecord(rec *walpb.Record) error { return err } - data := make([]byte, l) + recBytes, padBytes := decodeFrameSize(l) + + data := make([]byte, recBytes+padBytes) if _, err = io.ReadFull(d.brs[0], data); err != nil { // ReadFull returns io.EOF only if no bytes were read // the decoder should treat this as an ErrUnexpectedEOF instead. @@ -82,7 +86,10 @@ func (d *decoder) decodeRecord(rec *walpb.Record) error { } return err } - if err := rec.Unmarshal(data); err != nil { + if err := rec.Unmarshal(data[:recBytes]); err != nil { + if d.isTornEntry(data) { + return io.ErrUnexpectedEOF + } return err } @@ -90,14 +97,65 @@ func (d *decoder) decodeRecord(rec *walpb.Record) error { if rec.Type != crcType { d.crc.Write(rec.Data) if err := rec.Validate(d.crc.Sum32()); err != nil { + if d.isTornEntry(data) { + return io.ErrUnexpectedEOF + } return err } } // record decoded as valid; point last valid offset to end of record - d.lastValidOff += l + 8 + d.lastValidOff += recBytes + padBytes + 8 return nil } +func decodeFrameSize(lenField int64) (recBytes int64, padBytes int64) { + // the record size is stored in the lower 56 bits of the 64-bit length + recBytes = int64(uint64(lenField) & ^(uint64(0xff) << 56)) + // non-zero padding is indicated by set MSb / a negative length + if lenField < 0 { + // padding is stored in lower 3 bits of length MSB + padBytes = int64((uint64(lenField) >> 56) & 0x7) + } + return +} + +// isTornEntry determines whether the last entry of the WAL was partially written +// and corrupted because of a torn write. +func (d *decoder) isTornEntry(data []byte) bool { + if len(d.brs) != 1 { + return false + } + + fileOff := d.lastValidOff + 8 + curOff := 0 + chunks := [][]byte{} + // split data on sector boundaries + for curOff < len(data) { + chunkLen := int(minSectorSize - (fileOff % minSectorSize)) + if chunkLen > len(data)-curOff { + chunkLen = len(data) - curOff + } + chunks = append(chunks, data[curOff:curOff+chunkLen]) + fileOff += int64(chunkLen) + curOff += chunkLen + } + + // if any data for a sector chunk is all 0, it's a torn write + for _, sect := range chunks { + isZero := true + for _, v := range sect { + if v != 0 { + isZero = false + break + } + } + if isZero { + return true + } + } + return false +} + func (d *decoder) updateCRC(prevCrc uint32) { d.crc = crc.New(prevCrc, crcTable) } diff --git a/vendor/github.com/coreos/etcd/wal/doc.go b/vendor/github.com/coreos/etcd/wal/doc.go index 769b522f040..031a043a3d5 100644 --- a/vendor/github.com/coreos/etcd/wal/doc.go +++ b/vendor/github.com/coreos/etcd/wal/doc.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. @@ -34,6 +34,13 @@ When a user has finished using a WAL it must be closed: w.Close() +Each WAL file is a stream of WAL records. A WAL record is a length field and a wal record +protobuf. The record protobuf contains a CRC, a type, and a data payload. The length field is a +64-bit packed structure holding the length of the remaining logical record data in its lower +56 bits and its physical padding in the first three bits of the most significant byte. Each +record is 8-byte aligned so that the length field is never torn. The CRC contains the CRC32 +value of all record protobufs preceding the current record. + WAL files are placed inside of the directory in the following format: $seq-$index.wal @@ -41,7 +48,7 @@ The first WAL file to be created will be 0000000000000000-0000000000000000.wal indicating an initial sequence of 0 and an initial raft index of 0. The first entry written to WAL MUST have raft index 0. -WAL will cuts its current wal files if its size exceeds 8MB. This will increment an internal +WAL will cut its current tail wal file if its size exceeds 64MB. This will increment an internal sequence number and cause a new file to be created. If the last raft index saved was 0x20 and this is the first time cut has been called on this WAL then the sequence will increment from 0x0 to 0x1. The new file will be: 0000000000000001-0000000000000021.wal. diff --git a/vendor/github.com/coreos/etcd/wal/encoder.go b/vendor/github.com/coreos/etcd/wal/encoder.go index f5b73fe12b4..fdeceaf8006 100644 --- a/vendor/github.com/coreos/etcd/wal/encoder.go +++ b/vendor/github.com/coreos/etcd/wal/encoder.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. @@ -68,22 +68,38 @@ func (e *encoder) encode(rec *walpb.Record) error { } data = e.buf[:n] } - if err = writeInt64(e.bw, int64(len(data)), e.uint64buf); err != nil { + + lenField, padBytes := encodeFrameSize(len(data)) + if err = writeUint64(e.bw, lenField, e.uint64buf); err != nil { return err } + + if padBytes != 0 { + data = append(data, make([]byte, padBytes)...) + } _, err = e.bw.Write(data) return err } +func encodeFrameSize(dataBytes int) (lenField uint64, padBytes int) { + lenField = uint64(dataBytes) + // force 8 byte alignment so length never gets a torn write + padBytes = (8 - (dataBytes % 8)) % 8 + if padBytes != 0 { + lenField |= uint64(0x80|padBytes) << 56 + } + return +} + func (e *encoder) flush() error { e.mu.Lock() defer e.mu.Unlock() return e.bw.Flush() } -func writeInt64(w io.Writer, n int64, buf []byte) error { +func writeUint64(w io.Writer, n uint64, buf []byte) error { // http://golang.org/src/encoding/binary/binary.go - binary.LittleEndian.PutUint64(buf, uint64(n)) + binary.LittleEndian.PutUint64(buf, n) _, err := w.Write(buf) return err } diff --git a/vendor/github.com/coreos/etcd/wal/file_pipeline.go b/vendor/github.com/coreos/etcd/wal/file_pipeline.go index 6db9f66d74c..3412210a35b 100644 --- a/vendor/github.com/coreos/etcd/wal/file_pipeline.go +++ b/vendor/github.com/coreos/etcd/wal/file_pipeline.go @@ -1,4 +1,4 @@ -// Copyright 2016 CoreOS, Inc. +// 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. @@ -48,7 +48,8 @@ func newFilePipeline(dir string, fileSize int64) *filePipeline { return fp } -// Open returns a fresh file for writing +// Open returns a fresh file for writing. Rename the file before calling +// Open again or there will be file collisions. func (fp *filePipeline) Open() (f *fileutil.LockedFile, err error) { select { case f = <-fp.filec: @@ -63,8 +64,9 @@ func (fp *filePipeline) Close() error { } func (fp *filePipeline) alloc() (f *fileutil.LockedFile, err error) { - fpath := path.Join(fp.dir, fmt.Sprintf("%d.tmp", fp.count)) - if f, err = fileutil.LockFile(fpath, os.O_CREATE|os.O_WRONLY, 0600); err != nil { + // 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)) + if f, err = fileutil.LockFile(fpath, os.O_CREATE|os.O_WRONLY, fileutil.PrivateFileMode); err != nil { return nil, err } if err = fileutil.Preallocate(f.File, fp.size, true); err != nil { diff --git a/vendor/github.com/coreos/etcd/wal/metrics.go b/vendor/github.com/coreos/etcd/wal/metrics.go index ed270fac634..9e089d380f9 100644 --- a/vendor/github.com/coreos/etcd/wal/metrics.go +++ b/vendor/github.com/coreos/etcd/wal/metrics.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. @@ -19,20 +19,13 @@ import "github.com/prometheus/client_golang/prometheus" var ( syncDurations = prometheus.NewHistogram(prometheus.HistogramOpts{ Namespace: "etcd", - Subsystem: "wal", - Name: "fsync_durations_seconds", + Subsystem: "disk", + Name: "wal_fsync_duration_seconds", Help: "The latency distributions of fsync called by wal.", Buckets: prometheus.ExponentialBuckets(0.001, 2, 14), }) - lastIndexSaved = prometheus.NewGauge(prometheus.GaugeOpts{ - Namespace: "etcd", - Subsystem: "wal", - Name: "last_index_saved", - Help: "The index of the last entry saved by wal.", - }) ) func init() { prometheus.MustRegister(syncDurations) - prometheus.MustRegister(lastIndexSaved) } diff --git a/vendor/github.com/coreos/etcd/wal/repair.go b/vendor/github.com/coreos/etcd/wal/repair.go index eceebff3cea..0a920e2d8bb 100644 --- a/vendor/github.com/coreos/etcd/wal/repair.go +++ b/vendor/github.com/coreos/etcd/wal/repair.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. @@ -32,15 +32,13 @@ func Repair(dirpath string) bool { } defer f.Close() - n := 0 rec := &walpb.Record{} - decoder := newDecoder(f) for { + lastOffset := decoder.lastOffset() err := decoder.decode(rec) switch err { case nil: - n += 8 + rec.Size() // update crc of the decoder when necessary switch rec.Type { case crcType: @@ -74,11 +72,11 @@ func Repair(dirpath string) bool { return false } - if err = f.Truncate(int64(n)); err != nil { + if err = f.Truncate(int64(lastOffset)); err != nil { plog.Errorf("could not repair %v, failed to truncate file", f.Name()) return false } - if err = f.Sync(); err != nil { + if err = fileutil.Fsync(f.File); err != nil { plog.Errorf("could not repair %v, failed to sync file", f.Name()) return false } @@ -91,15 +89,11 @@ func Repair(dirpath string) bool { } // openLast opens the last wal file for read and write. -func openLast(dirpath string) (*os.File, error) { - names, err := fileutil.ReadDir(dirpath) +func openLast(dirpath string) (*fileutil.LockedFile, error) { + names, err := readWalNames(dirpath) if err != nil { return nil, err } - names = checkWalNames(names) - if len(names) == 0 { - return nil, ErrFileNotFound - } last := path.Join(dirpath, names[len(names)-1]) - return os.OpenFile(last, os.O_RDWR, 0) + return fileutil.LockFile(last, os.O_RDWR, fileutil.PrivateFileMode) } diff --git a/vendor/github.com/coreos/etcd/wal/util.go b/vendor/github.com/coreos/etcd/wal/util.go index 9588b6ec084..5c56e228872 100644 --- a/vendor/github.com/coreos/etcd/wal/util.go +++ b/vendor/github.com/coreos/etcd/wal/util.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. @@ -67,12 +67,26 @@ func isValidSeq(names []string) bool { } return true } +func readWalNames(dirpath string) ([]string, error) { + names, err := fileutil.ReadDir(dirpath) + if err != nil { + return nil, err + } + wnames := checkWalNames(names) + if len(wnames) == 0 { + return nil, ErrFileNotFound + } + return wnames, nil +} func checkWalNames(names []string) []string { wnames := make([]string, 0) for _, name := range names { if _, _, err := parseWalName(name); err != nil { - plog.Warningf("ignored file %v in wal", name) + // don't complain about left over tmp files + if !strings.HasSuffix(name, ".tmp") { + plog.Warningf("ignored file %v in wal", name) + } continue } wnames = append(wnames, name) diff --git a/vendor/github.com/coreos/etcd/wal/wal.go b/vendor/github.com/coreos/etcd/wal/wal.go index 3e5db72323e..e9ca81e2a2d 100644 --- a/vendor/github.com/coreos/etcd/wal/wal.go +++ b/vendor/github.com/coreos/etcd/wal/wal.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. @@ -15,13 +15,13 @@ package wal import ( + "bytes" "errors" "fmt" "hash/crc32" "io" "os" "path" - "reflect" "sync" "time" @@ -41,12 +41,13 @@ const ( crcType snapshotType - // the owner can make/remove files inside the directory - privateDirMode = 0700 - // 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 ( @@ -89,12 +90,19 @@ func Create(dirpath string, metadata []byte) (*WAL, error) { return nil, os.ErrExist } - if err := os.MkdirAll(dirpath, privateDirMode); err != nil { + // keep temporary wal directory so WAL initialization appears atomic + tmpdirpath := path.Clean(dirpath) + ".tmp" + if fileutil.Exist(tmpdirpath) { + if err := os.RemoveAll(tmpdirpath); err != nil { + return nil, err + } + } + if err := fileutil.CreateDirAll(tmpdirpath); err != nil { return nil, err } - p := path.Join(dirpath, walName(0, 0)) - f, err := fileutil.LockFile(p, os.O_WRONLY|os.O_CREATE, 0600) + p := path.Join(tmpdirpath, walName(0, 0)) + f, err := fileutil.LockFile(p, os.O_WRONLY|os.O_CREATE, fileutil.PrivateFileMode) if err != nil { return nil, err } @@ -109,7 +117,6 @@ func Create(dirpath string, metadata []byte) (*WAL, error) { dir: dirpath, metadata: metadata, encoder: newEncoder(f, 0), - fp: newFilePipeline(dirpath, segmentSizeBytes), } w.locks = append(w.locks, f) if err := w.saveCrc(0); err != nil { @@ -121,7 +128,23 @@ func Create(dirpath string, metadata []byte) (*WAL, error) { if err := w.SaveSnapshot(walpb.Snapshot{}); err != nil { return nil, err } - return w, nil + + // rename of directory with locked files doesn't work on windows; close + // the WAL to release the locks so the directory can be renamed + w.Close() + if err := os.Rename(tmpdirpath, dirpath); err != nil { + return nil, err + } + // reopen and relock + newWAL, oerr := Open(dirpath, walpb.Snapshot{}) + if oerr != nil { + return nil, oerr + } + if _, _, _, err := newWAL.ReadAll(); err != nil { + newWAL.Close() + return nil, err + } + return newWAL, nil } // Open opens the WAL at the given snap. @@ -141,14 +164,10 @@ func OpenForRead(dirpath string, snap walpb.Snapshot) (*WAL, error) { } func openAtIndex(dirpath string, snap walpb.Snapshot, write bool) (*WAL, error) { - names, err := fileutil.ReadDir(dirpath) + names, err := readWalNames(dirpath) if err != nil { return nil, err } - names = checkWalNames(names) - if len(names) == 0 { - return nil, ErrFileNotFound - } nameIndex, ok := searchIndex(names, snap.Index) if !ok || !isValidSeq(names[nameIndex:]) { @@ -162,7 +181,7 @@ func openAtIndex(dirpath string, snap walpb.Snapshot, write bool) (*WAL, error) for _, name := range names[nameIndex:] { p := path.Join(dirpath, name) if write { - l, err := fileutil.TryLockFile(p, os.O_RDWR, 0600) + l, err := fileutil.TryLockFile(p, os.O_RDWR, fileutil.PrivateFileMode) if err != nil { closeAll(rcs...) return nil, err @@ -170,7 +189,7 @@ func openAtIndex(dirpath string, snap walpb.Snapshot, write bool) (*WAL, error) ls = append(ls, l) rcs = append(rcs, l) } else { - rf, err := os.OpenFile(p, os.O_RDONLY, 0600) + rf, err := os.OpenFile(p, os.O_RDONLY, fileutil.PrivateFileMode) if err != nil { closeAll(rcs...) return nil, err @@ -196,17 +215,10 @@ 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 { closer() return nil, err } - // don't resize file for preallocation in case tail is corrupted - if err := fileutil.Preallocate(w.tail().File, segmentSizeBytes, false); err != nil { - closer() - plog.Errorf("failed to allocate space when creating new wal file (%v)", err) - return nil, err - } w.fp = newFilePipeline(w.dir, segmentSizeBytes) } @@ -242,7 +254,7 @@ func (w *WAL) ReadAll() (metadata []byte, state raftpb.HardState, ents []raftpb. case stateType: state = mustUnmarshalState(rec.Data) case metadataType: - if metadata != nil && !reflect.DeepEqual(metadata, rec.Data) { + if metadata != nil && !bytes.Equal(metadata, rec.Data) { state.Reset() return nil, state, nil, ErrMetadataConflict } @@ -307,7 +319,6 @@ func (w *WAL) ReadAll() (metadata []byte, state raftpb.HardState, ents []raftpb. // create encoder (chain crc with the decoder), enable appending _, err = w.tail().Seek(w.decoder.lastOffset(), os.SEEK_SET) w.encoder = newEncoder(w.tail(), w.decoder.lastCRC()) - lastIndexSaved.Set(float64(w.enti)) } w.decoder = nil @@ -366,7 +377,7 @@ func (w *WAL) cut() error { } newTail.Close() - if newTail, err = fileutil.LockFile(fpath, os.O_WRONLY, 0600); err != nil { + if newTail, err = fileutil.LockFile(fpath, os.O_WRONLY, fileutil.PrivateFileMode); err != nil { return err } if _, err = newTail.Seek(off, os.SEEK_SET); err != nil { @@ -390,7 +401,13 @@ func (w *WAL) sync() error { } start := time.Now() err := fileutil.Fdatasync(w.tail().File) - syncDurations.Observe(float64(time.Since(start)) / float64(time.Second)) + + duration := time.Since(start) + if duration > warnSyncDuration { + plog.Warningf("sync duration of %v, expected less than %v", duration, warnSyncDuration) + } + syncDurations.Observe(duration.Seconds()) + return err } @@ -471,7 +488,6 @@ func (w *WAL) saveEntry(e *raftpb.Entry) error { return err } w.enti = e.Index - lastIndexSaved.Set(float64(w.enti)) return nil } @@ -534,7 +550,6 @@ func (w *WAL) SaveSnapshot(e walpb.Snapshot) error { if w.enti < e.Index { w.enti = e.Index } - lastIndexSaved.Set(float64(w.enti)) return w.sync() } @@ -567,10 +582,7 @@ func mustSync(st, prevst raftpb.HardState, entsnum int) bool { // currentTerm // votedFor // log entries[] - if entsnum != 0 || st.Vote != prevst.Vote || st.Term != prevst.Term { - return true - } - return false + return entsnum != 0 || st.Vote != prevst.Vote || st.Term != prevst.Term } func closeAll(rcs ...io.ReadCloser) error { diff --git a/vendor/github.com/coreos/etcd/wal/walpb/record.go b/vendor/github.com/coreos/etcd/wal/walpb/record.go index bb536856976..30a05e0c139 100644 --- a/vendor/github.com/coreos/etcd/wal/walpb/record.go +++ b/vendor/github.com/coreos/etcd/wal/walpb/record.go @@ -1,4 +1,4 @@ -// Copyright 2015 CoreOS, Inc. +// Copyright 2015 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. 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 7ae042a51c7..bc715a818e5 100644 --- a/vendor/github.com/coreos/etcd/wal/walpb/record.pb.go +++ b/vendor/github.com/coreos/etcd/wal/walpb/record.pb.go @@ -17,7 +17,7 @@ package walpb import ( "fmt" - proto "github.com/gogo/protobuf/proto" + proto "github.com/golang/protobuf/proto" math "math" ) @@ -29,6 +29,10 @@ var _ = proto.Marshal var _ = fmt.Errorf 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 + type Record struct { Type int64 `protobuf:"varint,1,opt,name=type" json:"type"` Crc uint32 `protobuf:"varint,2,opt,name=crc" json:"crc"` @@ -36,9 +40,10 @@ type Record struct { XXX_unrecognized []byte `json:"-"` } -func (m *Record) Reset() { *m = Record{} } -func (m *Record) String() string { return proto.CompactTextString(m) } -func (*Record) ProtoMessage() {} +func (m *Record) Reset() { *m = Record{} } +func (m *Record) String() string { return proto.CompactTextString(m) } +func (*Record) ProtoMessage() {} +func (*Record) Descriptor() ([]byte, []int) { return fileDescriptorRecord, []int{0} } type Snapshot struct { Index uint64 `protobuf:"varint,1,opt,name=index" json:"index"` @@ -46,9 +51,10 @@ type Snapshot struct { XXX_unrecognized []byte `json:"-"` } -func (m *Snapshot) Reset() { *m = Snapshot{} } -func (m *Snapshot) String() string { return proto.CompactTextString(m) } -func (*Snapshot) ProtoMessage() {} +func (m *Snapshot) Reset() { *m = Snapshot{} } +func (m *Snapshot) String() string { return proto.CompactTextString(m) } +func (*Snapshot) ProtoMessage() {} +func (*Snapshot) Descriptor() ([]byte, []int) { return fileDescriptorRecord, []int{1} } func init() { proto.RegisterType((*Record)(nil), "walpb.Record") @@ -493,3 +499,19 @@ var ( ErrInvalidLengthRecord = fmt.Errorf("proto: negative length found during unmarshaling") ErrIntOverflowRecord = fmt.Errorf("proto: integer overflow") ) + +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, + 0x2f, 0x4a, 0xd1, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0x2d, 0x4f, 0xcc, 0x29, 0x48, 0x92, + 0x12, 0x49, 0xcf, 0x4f, 0xcf, 0x07, 0x8b, 0xe8, 0x83, 0x58, 0x10, 0x49, 0x25, 0x3f, 0x2e, 0xb6, + 0x20, 0xb0, 0x62, 0x21, 0x09, 0x2e, 0x96, 0x92, 0xca, 0x82, 0x54, 0x09, 0x46, 0x05, 0x46, 0x0d, + 0x66, 0x27, 0x96, 0x13, 0xf7, 0xe4, 0x19, 0x82, 0xc0, 0x22, 0x42, 0x62, 0x5c, 0xcc, 0xc9, 0x45, + 0xc9, 0x12, 0x4c, 0x0a, 0x8c, 0x1a, 0xbc, 0x50, 0x09, 0x90, 0x80, 0x90, 0x10, 0x17, 0x4b, 0x4a, + 0x62, 0x49, 0xa2, 0x04, 0xb3, 0x02, 0xa3, 0x06, 0x4f, 0x10, 0x98, 0xad, 0xe4, 0xc0, 0xc5, 0x11, + 0x9c, 0x97, 0x58, 0x50, 0x9c, 0x91, 0x5f, 0x22, 0x24, 0xc5, 0xc5, 0x9a, 0x99, 0x97, 0x92, 0x5a, + 0x01, 0x36, 0x92, 0x05, 0xaa, 0x13, 0x22, 0x04, 0xb6, 0x2d, 0xb5, 0x28, 0x17, 0x6c, 0x28, 0x0b, + 0xdc, 0xb6, 0xd4, 0xa2, 0x5c, 0x27, 0x91, 0x13, 0x0f, 0xe5, 0x18, 0x4e, 0x3c, 0x92, 0x63, 0xbc, + 0xf0, 0x48, 0x8e, 0xf1, 0xc1, 0x23, 0x39, 0xc6, 0x19, 0x8f, 0xe5, 0x18, 0x00, 0x01, 0x00, 0x00, + 0xff, 0xff, 0x7f, 0x5e, 0x5c, 0x46, 0xd3, 0x00, 0x00, 0x00, +} diff --git a/vendor/github.com/coreos/go-semver/semver/semver.go b/vendor/github.com/coreos/go-semver/semver/semver.go index db0b988dcf7..f1f8ab79739 100644 --- a/vendor/github.com/coreos/go-semver/semver/semver.go +++ b/vendor/github.com/coreos/go-semver/semver/semver.go @@ -1,18 +1,3 @@ -// Copyright 2013-2015 CoreOS, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// 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. - -// Semantic Versions http://semver.org package semver import ( @@ -47,15 +32,15 @@ func splitOff(input *string, delim string) (val string) { func NewVersion(version string) (*Version, error) { v := Version{} - v.Metadata = splitOff(&version, "+") - v.PreRelease = PreRelease(splitOff(&version, "-")) - dotParts := strings.SplitN(version, ".", 3) if len(dotParts) != 3 { return nil, errors.New(fmt.Sprintf("%s is not in dotted-tri format", version)) } + v.Metadata = splitOff(&dotParts[2], "+") + v.PreRelease = PreRelease(splitOff(&dotParts[2], "-")) + parsed := make([]int64, 3, 3) for i, v := range dotParts[:3] { @@ -83,39 +68,20 @@ func Must(v *Version, err error) *Version { func (v *Version) String() string { var buffer bytes.Buffer - fmt.Fprintf(&buffer, "%d.%d.%d", v.Major, v.Minor, v.Patch) + base := fmt.Sprintf("%d.%d.%d", v.Major, v.Minor, v.Patch) + buffer.WriteString(base) if v.PreRelease != "" { - fmt.Fprintf(&buffer, "-%s", v.PreRelease) + buffer.WriteString(fmt.Sprintf("-%s", v.PreRelease)) } if v.Metadata != "" { - fmt.Fprintf(&buffer, "+%s", v.Metadata) + buffer.WriteString(fmt.Sprintf("+%s", v.Metadata)) } return buffer.String() } -func (v *Version) MarshalJSON() ([]byte, error) { - return []byte(`"` + v.String() + `"`), nil -} - -func (v *Version) UnmarshalJSON(data []byte) error { - l := len(data) - if l == 0 || string(data) == `""` { - return nil - } - if l < 2 || data[0] != '"' || data[l-1] != '"' { - return errors.New("invalid semver string") - } - vv, err := NewVersion(string(data[1 : l-1])) - if err != nil { - return err - } - *v = *vv - return nil -} - func (v *Version) LessThan(versionB Version) bool { versionA := *v cmp := recursiveCompare(versionA.Slice(), versionB.Slice()) @@ -187,8 +153,7 @@ func recursivePreReleaseCompare(versionA []string, versionB []string) int { a := versionA[0] b := versionB[0] - aInt := false - bInt := false + aInt := false; bInt := false aI, err := strconv.Atoi(versionA[0]) if err == nil { diff --git a/vendor/github.com/coreos/go-semver/semver/sort.go b/vendor/github.com/coreos/go-semver/semver/sort.go index e256b41a5dd..86203007ae9 100644 --- a/vendor/github.com/coreos/go-semver/semver/sort.go +++ b/vendor/github.com/coreos/go-semver/semver/sort.go @@ -1,17 +1,3 @@ -// Copyright 2013-2015 CoreOS, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// 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 semver import ( diff --git a/vendor/github.com/coreos/pkg/capnslog/pkg_logger.go b/vendor/github.com/coreos/pkg/capnslog/pkg_logger.go index e2c4668823a..612d55c66c8 100644 --- a/vendor/github.com/coreos/pkg/capnslog/pkg_logger.go +++ b/vendor/github.com/coreos/pkg/capnslog/pkg_logger.go @@ -92,6 +92,12 @@ func (p *PackageLogger) Fatal(args ...interface{}) { os.Exit(1) } +func (p *PackageLogger) Fatalln(args ...interface{}) { + s := fmt.Sprintln(args...) + p.internalLog(calldepth, CRITICAL, s) + os.Exit(1) +} + // Error Functions func (p *PackageLogger) Errorf(format string, args ...interface{}) { diff --git a/vendor/github.com/coreos/rkt/api/v1alpha/api.pb.go b/vendor/github.com/coreos/rkt/api/v1alpha/api.pb.go index 5c4bbf0883c..1b03b90ecbd 100644 --- a/vendor/github.com/coreos/rkt/api/v1alpha/api.pb.go +++ b/vendor/github.com/coreos/rkt/api/v1alpha/api.pb.go @@ -54,7 +54,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 // ImageType defines the supported image type. type ImageType int32 @@ -224,7 +226,7 @@ type Image struct { // Base format of the image, required. This indicates the original format // for the image as nowadays all the image formats will be transformed to // ACI. - BaseFormat *ImageFormat `protobuf:"bytes,1,opt,name=base_format" json:"base_format,omitempty"` + BaseFormat *ImageFormat `protobuf:"bytes,1,opt,name=base_format,json=baseFormat" json:"base_format,omitempty"` // ID of the image, a string that can be used to uniquely identify the image, // e.g. sha512 hash of the ACIs, required. Id string `protobuf:"bytes,2,opt,name=id" json:"id,omitempty"` @@ -233,13 +235,15 @@ type Image struct { // Version of the image, e.g. 'latest', '2.0.10', optional. Version string `protobuf:"bytes,4,opt,name=version" json:"version,omitempty"` // Timestamp of when the image is imported, it is the seconds since epoch, optional. - ImportTimestamp int64 `protobuf:"varint,5,opt,name=import_timestamp" json:"import_timestamp,omitempty"` + ImportTimestamp int64 `protobuf:"varint,5,opt,name=import_timestamp,json=importTimestamp" json:"import_timestamp,omitempty"` // JSON-encoded byte array that represents the image manifest, optional. Manifest []byte `protobuf:"bytes,6,opt,name=manifest,proto3" json:"manifest,omitempty"` // Size is the size in bytes of this image in the store. Size int64 `protobuf:"varint,7,opt,name=size" json:"size,omitempty"` // Annotations on this image. Annotations []*KeyValue `protobuf:"bytes,8,rep,name=annotations" json:"annotations,omitempty"` + // Labels of this image. + Labels []*KeyValue `protobuf:"bytes,9,rep,name=labels" json:"labels,omitempty"` } func (m *Image) Reset() { *m = Image{} } @@ -261,6 +265,13 @@ func (m *Image) GetAnnotations() []*KeyValue { return nil } +func (m *Image) GetLabels() []*KeyValue { + if m != nil { + return m.Labels + } + return nil +} + // Network describes the network information of a pod. type Network struct { // Name of the network that a pod belongs to, required. @@ -287,7 +298,7 @@ type App struct { State AppState `protobuf:"varint,3,opt,name=state,enum=v1alpha.AppState" json:"state,omitempty"` // Exit code of the app. optional, only valid if it's returned by InspectPod() and // the app has already exited. - ExitCode int32 `protobuf:"zigzag32,4,opt,name=exit_code" json:"exit_code,omitempty"` + ExitCode int32 `protobuf:"zigzag32,4,opt,name=exit_code,json=exitCode" json:"exit_code,omitempty"` // Annotations for this app. Annotations []*KeyValue `protobuf:"bytes,5,rep,name=annotations" json:"annotations,omitempty"` } @@ -342,14 +353,14 @@ type Pod struct { Cgroup string `protobuf:"bytes,8,opt,name=cgroup" json:"cgroup,omitempty"` // Timestamp of when the pod is created, nanoseconds since epoch. // Zero if the pod is not created. - CreatedAt int64 `protobuf:"varint,9,opt,name=created_at" json:"created_at,omitempty"` + CreatedAt int64 `protobuf:"varint,9,opt,name=created_at,json=createdAt" json:"created_at,omitempty"` // Timestamp of when the pod is started, nanoseconds since epoch. // Zero if the pod is not started. - StartedAt int64 `protobuf:"varint,10,opt,name=started_at" json:"started_at,omitempty"` + StartedAt int64 `protobuf:"varint,10,opt,name=started_at,json=startedAt" json:"started_at,omitempty"` // Timestamp of when the pod is moved to exited-garbage/garbage, // in nanoseconds since epoch. // Zero if the pod is not moved to exited-garbage/garbage yet. - GcMarkedAt int64 `protobuf:"varint,11,opt,name=gc_marked_at" json:"gc_marked_at,omitempty"` + GcMarkedAt int64 `protobuf:"varint,11,opt,name=gc_marked_at,json=gcMarkedAt" json:"gc_marked_at,omitempty"` } func (m *Pod) Reset() { *m = Pod{} } @@ -380,7 +391,7 @@ func (m *Pod) GetAnnotations() []*KeyValue { type KeyValue struct { // Key part of the key-value pair. - Key string `protobuf:"bytes,1,opt,name=Key" json:"Key,omitempty"` + Key string `protobuf:"bytes,1,opt,name=Key,json=key" json:"Key,omitempty"` // Value part of the key-value pair. Value string `protobuf:"bytes,2,opt,name=value" json:"value,omitempty"` } @@ -396,20 +407,20 @@ type PodFilter struct { // If not empty, the pods that have any of the ids will be returned. Ids []string `protobuf:"bytes,1,rep,name=ids" json:"ids,omitempty"` // If not empty, the pods that have any of the states will be returned. - States []PodState `protobuf:"varint,2,rep,name=states,enum=v1alpha.PodState" json:"states,omitempty"` + States []PodState `protobuf:"varint,2,rep,packed,name=states,enum=v1alpha.PodState" json:"states,omitempty"` // If not empty, the pods that all of the apps will be returned. - AppNames []string `protobuf:"bytes,3,rep,name=app_names" json:"app_names,omitempty"` + AppNames []string `protobuf:"bytes,3,rep,name=app_names,json=appNames" json:"app_names,omitempty"` // If not empty, the pods that have all of the images(in the apps) will be returned - ImageIds []string `protobuf:"bytes,4,rep,name=image_ids" json:"image_ids,omitempty"` + ImageIds []string `protobuf:"bytes,4,rep,name=image_ids,json=imageIds" json:"image_ids,omitempty"` // If not empty, the pods that are in all of the networks will be returned. - NetworkNames []string `protobuf:"bytes,5,rep,name=network_names" json:"network_names,omitempty"` + NetworkNames []string `protobuf:"bytes,5,rep,name=network_names,json=networkNames" json:"network_names,omitempty"` // If not empty, the pods that have all of the annotations will be returned. Annotations []*KeyValue `protobuf:"bytes,6,rep,name=annotations" json:"annotations,omitempty"` // If not empty, the pods whose cgroup are listed will be returned. Cgroups []string `protobuf:"bytes,7,rep,name=cgroups" json:"cgroups,omitempty"` // If not empty, the pods whose these cgroup belong to will be returned. // i.e. the pod's cgroup is a prefix of the specified cgroup - PodSubCgroups []string `protobuf:"bytes,8,rep,name=pod_sub_cgroups" json:"pod_sub_cgroups,omitempty"` + PodSubCgroups []string `protobuf:"bytes,8,rep,name=pod_sub_cgroups,json=podSubCgroups" json:"pod_sub_cgroups,omitempty"` } func (m *PodFilter) Reset() { *m = PodFilter{} } @@ -434,20 +445,20 @@ type ImageFilter struct { // If not empty, the images that have any of the base names will be returned. // For example, both 'coreos.com/etcd' and 'k8s.io/etcd' will be returned if 'etcd' is included, // however 'k8s.io/etcd-backup' will not be returned. - BaseNames []string `protobuf:"bytes,3,rep,name=base_names" json:"base_names,omitempty"` + BaseNames []string `protobuf:"bytes,3,rep,name=base_names,json=baseNames" json:"base_names,omitempty"` // If not empty, the images that have any of the keywords in the name will be returned. // For example, both 'kubernetes-etcd', 'etcd:latest' will be returned if 'etcd' is included, Keywords []string `protobuf:"bytes,4,rep,name=keywords" json:"keywords,omitempty"` // If not empty, the images that have all of the labels will be returned. Labels []*KeyValue `protobuf:"bytes,5,rep,name=labels" json:"labels,omitempty"` // If set, the images that are imported after this timestamp will be returned. - ImportedAfter int64 `protobuf:"varint,6,opt,name=imported_after" json:"imported_after,omitempty"` + ImportedAfter int64 `protobuf:"varint,6,opt,name=imported_after,json=importedAfter" json:"imported_after,omitempty"` // If set, the images that are imported before this timestamp will be returned. - ImportedBefore int64 `protobuf:"varint,7,opt,name=imported_before" json:"imported_before,omitempty"` + ImportedBefore int64 `protobuf:"varint,7,opt,name=imported_before,json=importedBefore" json:"imported_before,omitempty"` // If not empty, the images that have all of the annotations will be returned. Annotations []*KeyValue `protobuf:"bytes,8,rep,name=annotations" json:"annotations,omitempty"` // If not empty, the images that have any of the exact full names will be returned. - FullNames []string `protobuf:"bytes,9,rep,name=full_names" json:"full_names,omitempty"` + FullNames []string `protobuf:"bytes,9,rep,name=full_names,json=fullNames" json:"full_names,omitempty"` } func (m *ImageFilter) Reset() { *m = ImageFilter{} } @@ -474,15 +485,15 @@ type GlobalFlags struct { // Data directory. Dir string `protobuf:"bytes,1,opt,name=dir" json:"dir,omitempty"` // System configuration directory. - SystemConfigDir string `protobuf:"bytes,2,opt,name=system_config_dir" json:"system_config_dir,omitempty"` + SystemConfigDir string `protobuf:"bytes,2,opt,name=system_config_dir,json=systemConfigDir" json:"system_config_dir,omitempty"` // Local configuration directory. - LocalConfigDir string `protobuf:"bytes,3,opt,name=local_config_dir" json:"local_config_dir,omitempty"` + LocalConfigDir string `protobuf:"bytes,3,opt,name=local_config_dir,json=localConfigDir" json:"local_config_dir,omitempty"` // User configuration directory. - UserConfigDir string `protobuf:"bytes,4,opt,name=user_config_dir" json:"user_config_dir,omitempty"` + UserConfigDir string `protobuf:"bytes,4,opt,name=user_config_dir,json=userConfigDir" json:"user_config_dir,omitempty"` // Insecure flags configurates what security features to disable. - InsecureFlags string `protobuf:"bytes,5,opt,name=insecure_flags" json:"insecure_flags,omitempty"` + InsecureFlags string `protobuf:"bytes,5,opt,name=insecure_flags,json=insecureFlags" json:"insecure_flags,omitempty"` // Whether to automatically trust gpg keys fetched from https - TrustKeysFromHttps bool `protobuf:"varint,6,opt,name=trust_keys_from_https" json:"trust_keys_from_https,omitempty"` + TrustKeysFromHttps bool `protobuf:"varint,6,opt,name=trust_keys_from_https,json=trustKeysFromHttps" json:"trust_keys_from_https,omitempty"` } func (m *GlobalFlags) Reset() { *m = GlobalFlags{} } @@ -493,13 +504,13 @@ func (*GlobalFlags) Descriptor() ([]byte, []int) { return fileDescriptor0, []int // Info describes the information of rkt on the machine. type Info struct { // Version of rkt, required, in the form of Semantic Versioning 2.0.0 (http://semver.org/). - RktVersion string `protobuf:"bytes,1,opt,name=rkt_version" json:"rkt_version,omitempty"` + RktVersion string `protobuf:"bytes,1,opt,name=rkt_version,json=rktVersion" json:"rkt_version,omitempty"` // Version of appc, required, in the form of Semantic Versioning 2.0.0 (http://semver.org/). - AppcVersion string `protobuf:"bytes,2,opt,name=appc_version" json:"appc_version,omitempty"` + AppcVersion string `protobuf:"bytes,2,opt,name=appc_version,json=appcVersion" json:"appc_version,omitempty"` // Latest version of the api that's supported by the service, required, in the form of Semantic Versioning 2.0.0 (http://semver.org/). - ApiVersion string `protobuf:"bytes,3,opt,name=api_version" json:"api_version,omitempty"` + ApiVersion string `protobuf:"bytes,3,opt,name=api_version,json=apiVersion" json:"api_version,omitempty"` // The global flags that passed to the rkt api service when it's launched. - GlobalFlags *GlobalFlags `protobuf:"bytes,4,opt,name=global_flags" json:"global_flags,omitempty"` + GlobalFlags *GlobalFlags `protobuf:"bytes,4,opt,name=global_flags,json=globalFlags" json:"global_flags,omitempty"` } func (m *Info) Reset() { *m = Info{} } @@ -549,7 +560,7 @@ func (m *Event) GetData() []*KeyValue { // The condition are combined by 'AND'. type EventFilter struct { // If not empty, then only returns the events that have the listed types. - Types []EventType `protobuf:"varint,1,rep,name=types,enum=v1alpha.EventType" json:"types,omitempty"` + Types []EventType `protobuf:"varint,1,rep,packed,name=types,enum=v1alpha.EventType" json:"types,omitempty"` // If not empty, then only returns the events whose 'id' is included in the listed ids. Ids []string `protobuf:"bytes,2,rep,name=ids" json:"ids,omitempty"` // If not empty, then only returns the events whose 'from' is included in the listed names. @@ -557,10 +568,10 @@ type EventFilter struct { // If set, then only returns the events after this timestamp. // If the server starts after since_time, then only the events happened after the start of the server will be returned. // If since_time is a future timestamp, then no events will be returned until that time. - SinceTime int64 `protobuf:"varint,4,opt,name=since_time" json:"since_time,omitempty"` + SinceTime int64 `protobuf:"varint,4,opt,name=since_time,json=sinceTime" json:"since_time,omitempty"` // If set, then only returns the events before this timestamp. // If it is a future timestamp, then the event stream will be closed at that moment. - UntilTime int64 `protobuf:"varint,5,opt,name=until_time" json:"until_time,omitempty"` + UntilTime int64 `protobuf:"varint,5,opt,name=until_time,json=untilTime" json:"until_time,omitempty"` } func (m *EventFilter) Reset() { *m = EventFilter{} } @@ -757,11 +768,11 @@ func (m *ListenEventsResponse) GetEvents() []*Event { // Request for GetLogs(). type GetLogsRequest struct { // ID of the pod which we will get logs from, required. - PodId string `protobuf:"bytes,1,opt,name=pod_id" json:"pod_id,omitempty"` + PodId string `protobuf:"bytes,1,opt,name=pod_id,json=podId" json:"pod_id,omitempty"` // Name of the app within the pod which we will get logs // from, optional. If not set, then the logs of all the // apps within the pod will be returned. - AppName string `protobuf:"bytes,2,opt,name=app_name" json:"app_name,omitempty"` + AppName string `protobuf:"bytes,2,opt,name=app_name,json=appName" json:"app_name,omitempty"` // Number of most recent lines to return, optional. Lines int32 `protobuf:"varint,3,opt,name=lines" json:"lines,omitempty"` // If true, then a response stream will not be closed, @@ -769,10 +780,10 @@ type GetLogsRequest struct { Follow bool `protobuf:"varint,4,opt,name=follow" json:"follow,omitempty"` // If set, then only the logs after the timestamp will // be returned, optional. - SinceTime int64 `protobuf:"varint,5,opt,name=since_time" json:"since_time,omitempty"` + SinceTime int64 `protobuf:"varint,5,opt,name=since_time,json=sinceTime" json:"since_time,omitempty"` // If set, then only the logs before the timestamp will // be returned, optional. - UntilTime int64 `protobuf:"varint,6,opt,name=until_time" json:"until_time,omitempty"` + UntilTime int64 `protobuf:"varint,6,opt,name=until_time,json=untilTime" json:"until_time,omitempty"` } func (m *GetLogsRequest) Reset() { *m = GetLogsRequest{} } @@ -828,6 +839,10 @@ func init() { var _ context.Context 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 + // Client API for PublicAPI service type PublicAPIClient interface { @@ -999,64 +1014,94 @@ func RegisterPublicAPIServer(s *grpc.Server, srv PublicAPIServer) { s.RegisterService(&_PublicAPI_serviceDesc, srv) } -func _PublicAPI_GetInfo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) { +func _PublicAPI_GetInfo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(GetInfoRequest) if err := dec(in); err != nil { return nil, err } - out, err := srv.(PublicAPIServer).GetInfo(ctx, in) - if err != nil { - return nil, err + if interceptor == nil { + return srv.(PublicAPIServer).GetInfo(ctx, in) } - return out, nil + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/v1alpha.PublicAPI/GetInfo", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(PublicAPIServer).GetInfo(ctx, req.(*GetInfoRequest)) + } + return interceptor(ctx, in, info, handler) } -func _PublicAPI_ListPods_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) { +func _PublicAPI_ListPods_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(ListPodsRequest) if err := dec(in); err != nil { return nil, err } - out, err := srv.(PublicAPIServer).ListPods(ctx, in) - if err != nil { - return nil, err + if interceptor == nil { + return srv.(PublicAPIServer).ListPods(ctx, in) } - return out, nil + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/v1alpha.PublicAPI/ListPods", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(PublicAPIServer).ListPods(ctx, req.(*ListPodsRequest)) + } + return interceptor(ctx, in, info, handler) } -func _PublicAPI_InspectPod_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) { +func _PublicAPI_InspectPod_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(InspectPodRequest) if err := dec(in); err != nil { return nil, err } - out, err := srv.(PublicAPIServer).InspectPod(ctx, in) - if err != nil { - return nil, err + if interceptor == nil { + return srv.(PublicAPIServer).InspectPod(ctx, in) } - return out, nil + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/v1alpha.PublicAPI/InspectPod", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(PublicAPIServer).InspectPod(ctx, req.(*InspectPodRequest)) + } + return interceptor(ctx, in, info, handler) } -func _PublicAPI_ListImages_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) { +func _PublicAPI_ListImages_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(ListImagesRequest) if err := dec(in); err != nil { return nil, err } - out, err := srv.(PublicAPIServer).ListImages(ctx, in) - if err != nil { - return nil, err + if interceptor == nil { + return srv.(PublicAPIServer).ListImages(ctx, in) } - return out, nil + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/v1alpha.PublicAPI/ListImages", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(PublicAPIServer).ListImages(ctx, req.(*ListImagesRequest)) + } + return interceptor(ctx, in, info, handler) } -func _PublicAPI_InspectImage_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) { +func _PublicAPI_InspectImage_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(InspectImageRequest) if err := dec(in); err != nil { return nil, err } - out, err := srv.(PublicAPIServer).InspectImage(ctx, in) - if err != nil { - return nil, err + if interceptor == nil { + return srv.(PublicAPIServer).InspectImage(ctx, in) } - return out, nil + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/v1alpha.PublicAPI/InspectImage", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(PublicAPIServer).InspectImage(ctx, req.(*InspectImageRequest)) + } + return interceptor(ctx, in, info, handler) } func _PublicAPI_ListenEvents_Handler(srv interface{}, stream grpc.ServerStream) error { @@ -1138,102 +1183,122 @@ var _PublicAPI_serviceDesc = grpc.ServiceDesc{ ServerStreams: true, }, }, + Metadata: fileDescriptor0, } +func init() { proto.RegisterFile("api.proto", fileDescriptor0) } + var fileDescriptor0 = []byte{ - // 1492 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x94, 0x57, 0xcf, 0x6e, 0xdb, 0xc6, - 0x13, 0x8e, 0xfe, 0x4b, 0x23, 0x45, 0x96, 0xd6, 0x4e, 0x2c, 0x2b, 0xff, 0x1c, 0xfe, 0x7e, 0x0d, - 0x52, 0x1f, 0xdc, 0xd6, 0x49, 0x73, 0x29, 0x50, 0x44, 0xb1, 0x69, 0x43, 0x8d, 0x2d, 0x09, 0x8a, - 0x62, 0x34, 0x27, 0x82, 0x92, 0x56, 0x0e, 0x61, 0x8a, 0x64, 0x49, 0xca, 0x89, 0x7b, 0xec, 0xa9, - 0xb7, 0x3e, 0x42, 0x1f, 0xa3, 0xc7, 0xde, 0xfb, 0x18, 0x05, 0xfa, 0x1e, 0x9d, 0x5d, 0x2e, 0xc9, - 0x25, 0x45, 0x1d, 0x7a, 0xb3, 0x66, 0x66, 0xbf, 0xf9, 0x66, 0x76, 0xe6, 0x5b, 0x1a, 0x6a, 0xba, - 0x63, 0x1c, 0x3a, 0xae, 0xed, 0xdb, 0xa4, 0x72, 0xf3, 0x8d, 0x6e, 0x3a, 0x1f, 0x75, 0xe5, 0x35, - 0xd4, 0xfb, 0x4b, 0xfd, 0x8a, 0x9e, 0xda, 0xee, 0x52, 0xf7, 0xc9, 0x3e, 0x14, 0xfd, 0x5b, 0x87, - 0x76, 0x72, 0xfb, 0xb9, 0xe7, 0xcd, 0x23, 0x72, 0x28, 0xc2, 0x0e, 0x79, 0xcc, 0x04, 0x3d, 0x64, - 0x0b, 0x2a, 0x37, 0xd4, 0xf5, 0x0c, 0xdb, 0xea, 0xe4, 0x31, 0xa8, 0xa6, 0xfc, 0x99, 0x83, 0x12, - 0x77, 0x93, 0x2f, 0xa1, 0x3e, 0xd5, 0x3d, 0xaa, 0x2d, 0x38, 0x16, 0xc7, 0xa8, 0x1f, 0xed, 0x24, - 0x31, 0x44, 0x1e, 0x80, 0xbc, 0x31, 0x0f, 0x00, 0x48, 0x03, 0x8a, 0x96, 0xbe, 0xa4, 0x9d, 0x02, - 0xff, 0x25, 0xe1, 0x17, 0xb9, 0xa1, 0x03, 0x2d, 0x63, 0xe9, 0xd8, 0xae, 0xaf, 0xf9, 0xc6, 0x92, - 0x7a, 0xbe, 0xbe, 0x74, 0x3a, 0x25, 0xf4, 0x14, 0x48, 0x0b, 0xaa, 0x4b, 0xdd, 0x32, 0x16, 0x68, - 0xec, 0x94, 0xd1, 0xd2, 0x60, 0x50, 0x9e, 0xf1, 0x33, 0xed, 0x54, 0xb8, 0xff, 0x19, 0xd4, 0x75, - 0xcb, 0xb2, 0x7d, 0xdd, 0x47, 0x34, 0xaf, 0x53, 0xdd, 0x2f, 0x20, 0x9f, 0x76, 0xc4, 0xe7, 0x2d, - 0xbd, 0xbd, 0xd4, 0xcd, 0x15, 0x55, 0x5e, 0x40, 0x65, 0x40, 0xfd, 0x4f, 0xb6, 0x7b, 0x1d, 0x71, - 0xc9, 0x85, 0xcc, 0x0c, 0xe7, 0xe6, 0x65, 0xcc, 0x13, 0x7f, 0xbd, 0x0a, 0x78, 0x2a, 0xbf, 0xe5, - 0xa0, 0xd0, 0x73, 0x9c, 0xd4, 0x89, 0x47, 0x50, 0x32, 0x58, 0x99, 0xfc, 0x48, 0xfd, 0xa8, 0x99, - 0x2c, 0x1e, 0xdb, 0x5b, 0xc2, 0x02, 0xfc, 0xa0, 0xd6, 0xa6, 0xc4, 0x05, 0x91, 0xde, 0x31, 0x07, - 0x69, 0x43, 0x8d, 0x7e, 0x36, 0x7c, 0x6d, 0x66, 0xcf, 0x29, 0x6f, 0x40, 0x3b, 0x5d, 0x46, 0x69, - 0x53, 0x19, 0xbf, 0xe6, 0xa1, 0x30, 0xb2, 0xe7, 0xa2, 0xb7, 0x01, 0x9f, 0x3a, 0x14, 0x1c, 0xd1, - 0xe8, 0xf6, 0xe6, 0xec, 0x78, 0x2a, 0xc8, 0xde, 0x85, 0xa2, 0xee, 0x38, 0x1e, 0x26, 0x66, 0x39, - 0x1a, 0x32, 0x3d, 0xa2, 0x40, 0xd5, 0x0a, 0xba, 0x14, 0x72, 0x68, 0x45, 0xfe, 0xb0, 0x7d, 0xeb, - 0x37, 0x92, 0x22, 0x5f, 0xd9, 0x40, 0x9e, 0x34, 0xa1, 0x3c, 0xbb, 0x72, 0xed, 0x95, 0x83, 0xd7, - 0xc4, 0x88, 0x63, 0x15, 0x33, 0x97, 0x22, 0xa7, 0xb9, 0x86, 0xa3, 0x54, 0xe3, 0xf7, 0x89, 0x36, - 0xe4, 0xef, 0x0a, 0x1b, 0x70, 0xdb, 0x0e, 0x34, 0xae, 0x66, 0xda, 0x52, 0x77, 0xaf, 0x03, 0x6b, - 0x9d, 0x59, 0x95, 0x67, 0x50, 0x8d, 0x90, 0xb1, 0x05, 0xf8, 0xb7, 0xe8, 0xc7, 0x5d, 0x28, 0xdd, - 0x30, 0xab, 0x98, 0xdd, 0xbf, 0x72, 0x50, 0xc3, 0xe2, 0x4f, 0x0d, 0xd3, 0xa7, 0x2e, 0x8b, 0x34, - 0xe6, 0x1e, 0x46, 0x16, 0x30, 0xf2, 0x29, 0x94, 0x79, 0xb3, 0x3c, 0x0c, 0x2d, 0x64, 0x77, 0xab, - 0xcd, 0x36, 0xca, 0xd1, 0xd8, 0xf5, 0x7b, 0xd8, 0x53, 0x76, 0x0a, 0x4d, 0xfc, 0xfe, 0x35, 0x06, - 0x54, 0xe4, 0xa6, 0x7b, 0x70, 0x57, 0xf4, 0x4d, 0x44, 0x96, 0xb8, 0x39, 0xd5, 0x98, 0xf2, 0xa6, - 0xc6, 0xe0, 0x3e, 0x04, 0x8d, 0x09, 0x9a, 0x57, 0x23, 0xbb, 0xb0, 0xe5, 0xd8, 0x73, 0xcd, 0x5b, - 0x4d, 0xb5, 0xd0, 0xc1, 0x26, 0xbb, 0xa6, 0xfc, 0x9d, 0x0b, 0x77, 0x39, 0xa3, 0x1c, 0xbc, 0x19, - 0xc7, 0xa5, 0x0b, 0xe3, 0xb3, 0x28, 0x88, 0x77, 0x98, 0x6f, 0xab, 0x4c, 0x1f, 0xa3, 0xae, 0xe9, - 0x2d, 0x72, 0x8d, 0xd8, 0x63, 0x1b, 0x4c, 0x7d, 0x4a, 0xcd, 0xcd, 0x73, 0x47, 0xee, 0x43, 0x33, - 0x58, 0x50, 0x76, 0x03, 0x0b, 0xcc, 0xcc, 0xaf, 0xbe, 0xc0, 0x88, 0x46, 0xf6, 0x29, 0x45, 0x51, - 0xf8, 0x8f, 0x7b, 0xc9, 0x18, 0x2e, 0x56, 0xa6, 0x29, 0x18, 0xd6, 0x78, 0x91, 0xbf, 0x63, 0x91, - 0x67, 0xa6, 0x3d, 0xd5, 0xcd, 0x53, 0x53, 0xbf, 0xf2, 0x58, 0x91, 0x73, 0xc3, 0x15, 0xb7, 0xbb, - 0x07, 0x6d, 0xef, 0xd6, 0xf3, 0xe9, 0x12, 0xd7, 0xc7, 0x5a, 0x18, 0x57, 0x1a, 0x73, 0xe5, 0x43, - 0x15, 0x31, 0xed, 0x99, 0x6e, 0xca, 0x9e, 0x40, 0x70, 0x90, 0xe6, 0xca, 0xa3, 0xae, 0xec, 0x08, - 0x84, 0x87, 0xd5, 0x65, 0x79, 0x74, 0xb6, 0x72, 0x51, 0xd2, 0x58, 0x32, 0x2e, 0x3b, 0x6c, 0xc7, - 0xef, 0xf9, 0xee, 0xca, 0xf3, 0x35, 0x6c, 0x95, 0xa7, 0x2d, 0x5c, 0x7b, 0xa9, 0x7d, 0xf4, 0x7d, - 0xc7, 0xe3, 0x65, 0x57, 0x15, 0x17, 0x8a, 0x7d, 0x6b, 0x61, 0x93, 0x6d, 0xa8, 0xbb, 0xd7, 0xbe, - 0x16, 0x8a, 0x59, 0xc0, 0x10, 0xc7, 0x15, 0x47, 0x66, 0xa6, 0x25, 0x24, 0x94, 0x85, 0xa2, 0x34, - 0x47, 0xc6, 0x80, 0xd7, 0x01, 0x4e, 0x36, 0x2f, 0x54, 0x24, 0x2f, 0xa6, 0xe4, 0x54, 0xea, 0x02, - 0xe6, 0x2c, 0xa9, 0x37, 0xd4, 0xda, 0xac, 0xdf, 0xdc, 0xcb, 0xf5, 0x3b, 0xa5, 0xbc, 0x8c, 0xbe, - 0x48, 0x88, 0xbf, 0x98, 0xc2, 0xf2, 0x44, 0x05, 0xf2, 0x04, 0x8a, 0x73, 0xdd, 0xd7, 0x37, 0xcb, - 0x8d, 0x0f, 0x75, 0x8e, 0x2a, 0xa6, 0xed, 0x29, 0x94, 0x58, 0xe6, 0x60, 0xde, 0xb2, 0x53, 0x8b, - 0x81, 0x0c, 0xc6, 0x0f, 0x37, 0x51, 0x9e, 0x3c, 0xb6, 0xdb, 0x86, 0x35, 0xa3, 0x9a, 0x44, 0x01, - 0x6d, 0x2b, 0xcb, 0x37, 0xcc, 0xc0, 0xc6, 0x35, 0x5f, 0x69, 0x41, 0xf3, 0x8c, 0xfa, 0xac, 0xc1, - 0x63, 0xfa, 0xd3, 0x0a, 0x75, 0x46, 0x39, 0x84, 0xad, 0xc8, 0xe2, 0x39, 0x38, 0x50, 0x94, 0x3c, - 0x40, 0xa5, 0xc6, 0xdf, 0xe2, 0x05, 0xba, 0x1b, 0x8b, 0x30, 0x1a, 0x95, 0x53, 0xd8, 0x3a, 0x37, - 0x3c, 0x1f, 0xb7, 0xd8, 0x13, 0x10, 0xe4, 0x7f, 0x50, 0x59, 0xf0, 0x2a, 0x02, 0xf6, 0x75, 0x89, - 0x7d, 0xac, 0x0e, 0xa8, 0x50, 0x73, 0xea, 0xeb, 0x86, 0xc9, 0x9b, 0x57, 0xc5, 0xbc, 0xad, 0x18, - 0x47, 0x24, 0x46, 0xfd, 0xc4, 0xdd, 0x0c, 0x51, 0x1a, 0x32, 0x8a, 0xf2, 0x04, 0xda, 0x7d, 0xcb, - 0x73, 0xe8, 0x8c, 0x1d, 0x09, 0x33, 0x4b, 0x5a, 0xad, 0x7c, 0x05, 0x44, 0x0e, 0x10, 0x90, 0x7b, - 0xa8, 0xe0, 0xf6, 0x5c, 0x94, 0x92, 0x44, 0xfc, 0x01, 0xda, 0x8c, 0x01, 0xdf, 0xf9, 0xa8, 0x96, - 0x2f, 0xd2, 0xb5, 0xa4, 0x1f, 0xe0, 0xec, 0x6a, 0x5e, 0x02, 0x91, 0xb1, 0x44, 0xf2, 0xc7, 0x50, - 0xe6, 0x72, 0x16, 0x62, 0xa5, 0xde, 0x33, 0xe5, 0x29, 0x6c, 0x0b, 0xca, 0xfc, 0x77, 0x56, 0x55, - 0xdf, 0xc2, 0x4e, 0x32, 0x44, 0x40, 0x47, 0x2f, 0x65, 0x2e, 0xeb, 0xa5, 0x54, 0xbe, 0x83, 0x6d, - 0xc6, 0x87, 0x5a, 0x7c, 0x7c, 0xa2, 0xea, 0xfe, 0x0f, 0xe5, 0xa0, 0xba, 0xb5, 0xaf, 0x0b, 0x69, - 0x16, 0x95, 0x57, 0xb0, 0x93, 0x3c, 0x1c, 0x97, 0x43, 0xb9, 0x65, 0xad, 0x1c, 0x1e, 0xa8, 0xdc, - 0xf2, 0xe1, 0x3a, 0xb7, 0xaf, 0xa2, 0x7c, 0xd8, 0x26, 0x26, 0xb6, 0xd1, 0x7b, 0x8a, 0x02, 0x19, - 0x4a, 0xbe, 0xd8, 0x21, 0x9c, 0x63, 0xd3, 0xb0, 0xf8, 0x1c, 0xe7, 0x9e, 0x97, 0xd8, 0x81, 0x85, - 0x6d, 0x9a, 0xf6, 0x27, 0x3e, 0xc3, 0xd5, 0xd4, 0x5c, 0x97, 0x32, 0xe6, 0x9a, 0x8b, 0xa5, 0xb2, - 0xcf, 0xa7, 0x38, 0x48, 0x2d, 0xd8, 0x46, 0xc8, 0x5c, 0xc1, 0x0f, 0x28, 0xd4, 0xe2, 0xaf, 0xb0, - 0x0e, 0x76, 0xf5, 0xa2, 0x77, 0xa6, 0x6a, 0x93, 0x0f, 0x23, 0x55, 0x7b, 0x3f, 0x38, 0x51, 0x4f, - 0xfb, 0x03, 0xf5, 0xa4, 0x75, 0x07, 0xb5, 0x64, 0x4b, 0xf2, 0xf4, 0x46, 0xa3, 0xe3, 0x56, 0x0e, - 0xdf, 0xa0, 0xb6, 0x64, 0x3c, 0x19, 0x1e, 0xbf, 0x55, 0xc7, 0xad, 0x3c, 0x12, 0x69, 0x4a, 0xe6, - 0xe1, 0x71, 0xbf, 0x55, 0x38, 0x18, 0x41, 0x35, 0xfa, 0x18, 0xd9, 0x85, 0x6d, 0x04, 0xd0, 0xde, - 0x4d, 0x7a, 0x93, 0x64, 0x12, 0xc4, 0x8b, 0x1d, 0xe3, 0xf7, 0x83, 0x41, 0x7f, 0x70, 0x86, 0x69, - 0x76, 0xa0, 0x15, 0x9b, 0xd5, 0x1f, 0xfb, 0x13, 0x0c, 0xce, 0x1f, 0xfc, 0x93, 0x83, 0x6a, 0xf4, - 0x66, 0x22, 0xe4, 0x68, 0x78, 0x92, 0x01, 0x89, 0x67, 0x63, 0x87, 0x7a, 0xf1, 0x66, 0xfc, 0x61, - 0x88, 0x88, 0x89, 0xf0, 0xd1, 0x58, 0x1d, 0xf5, 0xc6, 0x2c, 0x55, 0x1e, 0xc5, 0x99, 0xa4, 0x1d, - 0x08, 0x53, 0x60, 0xcc, 0x62, 0x7b, 0xc8, 0xac, 0x88, 0xd3, 0xb6, 0x17, 0x9b, 0x7b, 0x6f, 0x86, - 0x63, 0xa4, 0x16, 0x1e, 0x6b, 0x95, 0x52, 0xc9, 0x03, 0xe2, 0xe5, 0x64, 0x8e, 0x13, 0xf5, 0x5c, - 0x9d, 0x30, 0xb0, 0x4a, 0x32, 0xc7, 0x59, 0x6f, 0xfc, 0x06, 0x5b, 0xd8, 0xaa, 0x1e, 0xfc, 0x91, - 0x87, 0x5a, 0x2c, 0x76, 0x78, 0x43, 0xea, 0xa5, 0x3a, 0x98, 0xac, 0xdf, 0xd0, 0x03, 0xd8, 0x95, - 0x3c, 0x0c, 0x29, 0xe2, 0x9f, 0xc3, 0xaf, 0xac, 0xc7, 0xd9, 0xce, 0x90, 0x35, 0xd6, 0xde, 0x85, - 0xfb, 0xa9, 0x18, 0xa4, 0xc2, 0x7d, 0x05, 0x94, 0x8b, 0x7b, 0x29, 0x9f, 0x28, 0xa7, 0x88, 0xbb, - 0xb3, 0x9f, 0x72, 0x09, 0xee, 0xda, 0xf1, 0xf0, 0xfc, 0x5c, 0x3d, 0x66, 0x51, 0xa5, 0x14, 0xb8, - 0xb8, 0xce, 0x71, 0xd0, 0x90, 0x24, 0x38, 0xf3, 0x09, 0xf0, 0x0a, 0x6b, 0xb0, 0xe4, 0x0a, 0xa6, - 0xaa, 0x7f, 0x31, 0x0a, 0x28, 0x57, 0xc9, 0x43, 0xe8, 0xac, 0xb9, 0xc7, 0xea, 0xc5, 0xf0, 0x12, - 0xbd, 0xb5, 0xa3, 0x5f, 0x8a, 0xf8, 0x19, 0xb6, 0x9a, 0x9a, 0xc6, 0xac, 0x37, 0xea, 0x93, 0xef, - 0xa1, 0x22, 0x04, 0x9d, 0xec, 0xc6, 0xaf, 0x5d, 0x42, 0xf4, 0xbb, 0x9d, 0x75, 0x47, 0xb0, 0x35, - 0xca, 0x1d, 0xd2, 0x83, 0x6a, 0x28, 0xcc, 0x24, 0x8e, 0x4b, 0x69, 0x7e, 0x77, 0x2f, 0xc3, 0x13, - 0x41, 0x9c, 0x01, 0xc4, 0x52, 0x4c, 0xba, 0xd2, 0x03, 0x92, 0x12, 0xf0, 0xee, 0x83, 0x4c, 0x9f, - 0x0c, 0x14, 0xcb, 0xaa, 0x04, 0xb4, 0xa6, 0xdb, 0x12, 0xd0, 0xba, 0x0e, 0x23, 0xd0, 0x05, 0x34, - 0x64, 0x19, 0x25, 0x0f, 0xd3, 0x79, 0x65, 0x01, 0xee, 0x3e, 0xda, 0xe0, 0x8d, 0xe0, 0x86, 0xd0, - 0x90, 0x15, 0x52, 0x82, 0xcb, 0x50, 0x5d, 0x09, 0x2e, 0x4b, 0x56, 0x95, 0x3b, 0x5f, 0xe7, 0xc8, - 0x6b, 0x7e, 0x69, 0x4c, 0xbf, 0x92, 0x97, 0x26, 0x89, 0x69, 0xf2, 0xd2, 0x64, 0xa9, 0x63, 0x08, - 0xd3, 0x32, 0xff, 0xcf, 0xf4, 0xc5, 0xbf, 0x01, 0x00, 0x00, 0xff, 0xff, 0x4a, 0x23, 0xef, 0x15, - 0xa6, 0x0e, 0x00, 0x00, + // 1767 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x9c, 0x58, 0xcd, 0x6e, 0xdb, 0xc6, + 0x16, 0x8e, 0xfe, 0xa5, 0x23, 0x59, 0x96, 0xc7, 0x4e, 0xa2, 0x38, 0x3f, 0xd7, 0x97, 0xb9, 0x49, + 0x7c, 0x8d, 0x0b, 0xe3, 0xc6, 0x49, 0xdb, 0x4d, 0x10, 0x54, 0x96, 0x69, 0x57, 0x88, 0x2d, 0x09, + 0x8c, 0xe2, 0x36, 0xe8, 0x82, 0xa0, 0x24, 0x4a, 0x21, 0x4c, 0x89, 0x2c, 0x49, 0x39, 0x71, 0x97, + 0x7d, 0x80, 0xbe, 0x41, 0xbb, 0xea, 0xba, 0xdb, 0x02, 0xdd, 0xf7, 0x51, 0xba, 0xe8, 0x13, 0x74, + 0xdb, 0x33, 0x3f, 0x24, 0x87, 0xb4, 0x9c, 0x1a, 0xdd, 0x71, 0xce, 0x77, 0xe6, 0x9b, 0xf3, 0x37, + 0xe7, 0x8c, 0x04, 0x15, 0xc3, 0xb5, 0x76, 0x5d, 0xcf, 0x09, 0x1c, 0x52, 0x3a, 0x7f, 0x6a, 0xd8, + 0xee, 0x3b, 0x43, 0xe9, 0x41, 0xb5, 0x33, 0x33, 0xa6, 0xe6, 0xa1, 0xe3, 0xcd, 0x8c, 0x80, 0x3c, + 0x86, 0x7c, 0x70, 0xe1, 0x9a, 0xcd, 0xcc, 0x56, 0x66, 0xbb, 0xbe, 0x47, 0x76, 0x85, 0xda, 0x2e, + 0xd3, 0x19, 0x20, 0xa2, 0x31, 0x9c, 0x34, 0xa1, 0x74, 0x6e, 0x7a, 0xbe, 0xe5, 0xcc, 0x9b, 0x59, + 0x54, 0xad, 0x68, 0xe1, 0x52, 0xf9, 0x25, 0x0b, 0x05, 0xa6, 0x4d, 0x3e, 0x81, 0xea, 0xd0, 0xf0, + 0x4d, 0x7d, 0xc2, 0xa8, 0x19, 0x65, 0x75, 0x6f, 0x23, 0x49, 0xc9, 0x8f, 0xd5, 0x80, 0x2a, 0x0a, + 0x13, 0xea, 0x90, 0xb5, 0xc6, 0x82, 0x15, 0xbf, 0x08, 0x81, 0xfc, 0xdc, 0x98, 0x99, 0xcd, 0x1c, + 0x93, 0xb0, 0x6f, 0xf9, 0xf8, 0x7c, 0xe2, 0x78, 0xf2, 0x5f, 0x68, 0x58, 0x33, 0xd7, 0xf1, 0x02, + 0x3d, 0xb0, 0x66, 0xa6, 0x1f, 0x18, 0x33, 0xb7, 0x59, 0x40, 0x95, 0x9c, 0xb6, 0xca, 0xe5, 0x83, + 0x50, 0x4c, 0x36, 0xa1, 0x3c, 0x33, 0xe6, 0xd6, 0x04, 0x97, 0xcd, 0x22, 0xaa, 0xd4, 0xb4, 0x68, + 0x4d, 0x0f, 0xf5, 0xad, 0x6f, 0xcd, 0x66, 0x89, 0x6d, 0x65, 0xdf, 0xe4, 0x19, 0x54, 0x8d, 0xf9, + 0xdc, 0x09, 0x8c, 0x00, 0x0f, 0xf2, 0x9b, 0xe5, 0xad, 0x1c, 0xfa, 0xb3, 0x16, 0xf9, 0xf3, 0xca, + 0xbc, 0x38, 0x35, 0xec, 0x85, 0xa9, 0xc9, 0x5a, 0x68, 0x4f, 0xd1, 0x36, 0x86, 0xa6, 0xed, 0x37, + 0x2b, 0x57, 0xe9, 0x0b, 0x05, 0x45, 0x85, 0x52, 0xd7, 0x0c, 0xde, 0x3b, 0xde, 0x59, 0xe4, 0x73, + 0x46, 0xf2, 0x19, 0x65, 0x96, 0x7b, 0xfe, 0x5c, 0x44, 0x86, 0x7d, 0x0b, 0xd9, 0xa7, 0x61, 0x6c, + 0xe8, 0xb7, 0xf2, 0x6b, 0x06, 0x72, 0x2d, 0xd7, 0x5d, 0xca, 0xf1, 0x1f, 0x28, 0x58, 0x34, 0xec, + 0x8c, 0xa4, 0xba, 0x57, 0x4f, 0x26, 0x43, 0xe3, 0x20, 0x79, 0x02, 0x05, 0x8c, 0x50, 0xc0, 0x43, + 0x5e, 0x97, 0x4c, 0x46, 0xda, 0xd7, 0x14, 0xd0, 0x38, 0x4e, 0xee, 0x42, 0xc5, 0xfc, 0x60, 0x05, + 0xfa, 0xc8, 0x19, 0x9b, 0x2c, 0x11, 0x6b, 0x5a, 0x99, 0x0a, 0xda, 0xb8, 0x4e, 0x87, 0xab, 0x70, + 0x9d, 0x70, 0x29, 0x7f, 0x64, 0x21, 0xd7, 0x77, 0xc6, 0xa2, 0x08, 0x32, 0x51, 0x11, 0x34, 0x20, + 0xe7, 0x8a, 0xaa, 0x58, 0xd3, 0xe8, 0xe7, 0xd5, 0x46, 0xe2, 0xf6, 0x84, 0x91, 0x5b, 0x90, 0x37, + 0x5c, 0xd7, 0x47, 0xfb, 0xa8, 0x01, 0x35, 0xd9, 0x19, 0x8d, 0x21, 0xe4, 0x7f, 0x50, 0x9e, 0xf3, + 0xc0, 0x87, 0x66, 0x36, 0x22, 0x2d, 0x91, 0x11, 0x2d, 0xd2, 0xf8, 0x68, 0xd9, 0xa4, 0x7c, 0x2e, + 0x5d, 0xab, 0x44, 0x6e, 0x41, 0x71, 0x34, 0xf5, 0x9c, 0x85, 0x8b, 0x25, 0x45, 0xfd, 0x15, 0x2b, + 0x72, 0x1f, 0x60, 0xe4, 0x99, 0xe8, 0xc2, 0x58, 0xc7, 0xeb, 0x53, 0x61, 0x95, 0x58, 0x11, 0x92, + 0x56, 0x40, 0x61, 0x74, 0xd0, 0x13, 0x30, 0x70, 0x58, 0x48, 0x10, 0xde, 0x82, 0xda, 0x74, 0xa4, + 0xcf, 0x0c, 0xef, 0x8c, 0x2b, 0x54, 0x99, 0x02, 0x4c, 0x47, 0x27, 0x4c, 0xd4, 0x0a, 0x94, 0x3d, + 0x28, 0x87, 0x06, 0xd1, 0xf8, 0xe2, 0xb7, 0x08, 0x78, 0xee, 0xcc, 0xbc, 0x20, 0x1b, 0x50, 0x38, + 0xa7, 0x90, 0xa8, 0x37, 0xbe, 0x50, 0x7e, 0xcc, 0x42, 0x05, 0x03, 0x7c, 0x68, 0xd9, 0x81, 0xe9, + 0xd1, 0x5d, 0xd6, 0xd8, 0xc7, 0x5d, 0x39, 0xba, 0x0b, 0x3f, 0x69, 0xb9, 0xb3, 0xa8, 0xfb, 0xb8, + 0x2d, 0xb7, 0x3c, 0x2d, 0x42, 0x81, 0x16, 0x0f, 0x46, 0x5f, 0xa7, 0x75, 0xe9, 0x63, 0x12, 0x29, + 0x45, 0x19, 0x05, 0x5d, 0xba, 0xa6, 0x20, 0xab, 0x45, 0x9d, 0xf2, 0xe7, 0x39, 0xc8, 0x04, 0x1d, + 0x3c, 0xe4, 0x21, 0xac, 0x88, 0x6c, 0x88, 0xdd, 0x05, 0xa6, 0x50, 0x13, 0x42, 0xce, 0x90, 0x4a, + 0x45, 0xf1, 0x5a, 0xa9, 0xc0, 0xbe, 0xc2, 0x83, 0xcf, 0x73, 0x87, 0x7d, 0x45, 0x2c, 0xb1, 0x31, + 0xae, 0xba, 0xce, 0x58, 0xf7, 0x17, 0x43, 0x3d, 0xd4, 0x28, 0x33, 0x8d, 0x15, 0x14, 0xbf, 0x5e, + 0x0c, 0xdb, 0x5c, 0xa8, 0xfc, 0x96, 0x0d, 0x1b, 0xea, 0x55, 0x21, 0xc2, 0xfa, 0x71, 0x3d, 0x73, + 0x62, 0x7d, 0x10, 0x41, 0x42, 0xcf, 0xc2, 0x35, 0xcd, 0x29, 0x6b, 0x99, 0x72, 0x50, 0x2a, 0x54, + 0xc2, 0x7d, 0xc2, 0xad, 0x98, 0x1a, 0xf4, 0x31, 0x0e, 0x4a, 0xb8, 0x96, 0x1a, 0x4d, 0xe1, 0x6f, + 0x1a, 0x0d, 0x79, 0x04, 0x75, 0xde, 0x0b, 0x69, 0x65, 0x4c, 0xd0, 0x4a, 0x56, 0xc7, 0x39, 0x6d, + 0x25, 0x94, 0xb6, 0xa8, 0x10, 0x6f, 0xd8, 0x6a, 0xa4, 0x36, 0x34, 0xb1, 0x8b, 0x87, 0xed, 0x30, + 0xda, 0xbd, 0xcf, 0xa4, 0xff, 0xac, 0x31, 0xa2, 0xab, 0x93, 0x85, 0x6d, 0x0b, 0x57, 0x2b, 0xdc, + 0x55, 0x2a, 0x61, 0xae, 0x2a, 0x7f, 0x66, 0xa0, 0x7a, 0x64, 0x3b, 0x43, 0xc3, 0x3e, 0xb4, 0x8d, + 0xa9, 0x4f, 0xe3, 0x38, 0xb6, 0xbc, 0xb0, 0x40, 0xf1, 0x93, 0xec, 0xc0, 0x9a, 0x7f, 0xe1, 0x07, + 0xe6, 0x0c, 0xdb, 0xcf, 0x7c, 0x62, 0x4d, 0x75, 0x8a, 0xf3, 0x62, 0x5d, 0xe5, 0x40, 0x9b, 0xc9, + 0x0f, 0x50, 0x77, 0x1b, 0x1a, 0xb6, 0x33, 0x32, 0x6c, 0x59, 0x95, 0xf7, 0xcc, 0x3a, 0x93, 0xc7, + 0x9a, 0x98, 0xe7, 0x85, 0x6f, 0x7a, 0xb2, 0x22, 0x9f, 0x30, 0x2b, 0x54, 0x1c, 0xeb, 0xd1, 0x18, + 0xce, 0x7d, 0x73, 0xb4, 0xf0, 0x70, 0xc0, 0x51, 0x0b, 0xd9, 0x94, 0x41, 0xb5, 0x50, 0xca, 0xcd, + 0x7e, 0x0a, 0x37, 0x03, 0x6f, 0xe1, 0x07, 0x3a, 0xe6, 0xc9, 0xd7, 0x27, 0x9e, 0x33, 0xd3, 0xdf, + 0x05, 0x81, 0xeb, 0xb3, 0x88, 0x97, 0x35, 0xc2, 0x40, 0x0c, 0x90, 0x7f, 0x88, 0xd0, 0x17, 0x14, + 0x51, 0x7e, 0xca, 0x40, 0xbe, 0x33, 0x9f, 0x38, 0xe4, 0x5f, 0x50, 0xf5, 0xce, 0x02, 0x3d, 0x1c, + 0x74, 0xdc, 0x75, 0x40, 0xd1, 0xa9, 0x98, 0x75, 0xff, 0x86, 0x1a, 0x5e, 0x98, 0x91, 0x9e, 0x9c, + 0xc4, 0x55, 0x2a, 0x0b, 0x55, 0x90, 0x03, 0x87, 0x7e, 0xa4, 0xc1, 0x7d, 0x06, 0x14, 0x85, 0x0a, + 0x9f, 0x61, 0x9b, 0x60, 0x61, 0x16, 0x5e, 0xe4, 0x53, 0x53, 0x5a, 0xca, 0x81, 0x56, 0x9d, 0xc6, + 0x0b, 0xe5, 0xfb, 0x0c, 0x14, 0xd4, 0x73, 0x73, 0x7e, 0xf5, 0x9b, 0x81, 0xa1, 0xd2, 0x9b, 0x61, + 0xc9, 0x60, 0xa7, 0x01, 0x09, 0x87, 0x17, 0xfd, 0xa6, 0x32, 0x3a, 0xb7, 0x99, 0x19, 0x38, 0x77, + 0xe9, 0x37, 0x86, 0x3a, 0x3f, 0x36, 0x02, 0xe3, 0xea, 0xba, 0x66, 0xb0, 0xf2, 0x03, 0x56, 0x0c, + 0x3b, 0x52, 0xdc, 0xbc, 0x6d, 0x28, 0xd0, 0x63, 0xf9, 0xdd, 0x5b, 0x6e, 0x17, 0x57, 0x08, 0xef, + 0x68, 0x36, 0xbe, 0xa3, 0xd8, 0xfc, 0xe4, 0x2b, 0xc8, 0x17, 0xac, 0xe3, 0x5a, 0xf3, 0x91, 0xa9, + 0x4b, 0x26, 0x56, 0x98, 0x84, 0x3e, 0x2a, 0x28, 0xbc, 0x98, 0x07, 0x96, 0xcd, 0x61, 0xfe, 0xe8, + 0xa8, 0x30, 0x09, 0x85, 0x95, 0x06, 0xd4, 0x8f, 0xcc, 0x80, 0x66, 0x56, 0x33, 0xbf, 0x59, 0xe0, + 0xb4, 0x50, 0x9e, 0xc3, 0x6a, 0x24, 0xf1, 0x5d, 0xbc, 0x14, 0x26, 0xa6, 0x34, 0x6f, 0xe1, 0x5a, + 0x3c, 0x96, 0x56, 0xe2, 0xf9, 0x4c, 0x95, 0x18, 0xa4, 0x7c, 0x09, 0xab, 0xc7, 0x96, 0x1f, 0x60, + 0x3f, 0xf5, 0x05, 0x11, 0x0e, 0xb0, 0xd2, 0x84, 0x39, 0xcd, 0x9d, 0xad, 0x4a, 0xce, 0x46, 0xcd, + 0x5a, 0x0b, 0x55, 0xe8, 0xbc, 0x19, 0x9b, 0x81, 0x61, 0xd9, 0x2c, 0x17, 0x65, 0x4d, 0xac, 0xd0, + 0x9c, 0x46, 0x4c, 0x2c, 0xec, 0xc1, 0xe1, 0x89, 0xfd, 0x2d, 0xa4, 0xad, 0xc9, 0xb4, 0x1a, 0x43, + 0x94, 0x87, 0xb0, 0xd6, 0x99, 0xfb, 0xae, 0x39, 0xa2, 0x1b, 0x43, 0x83, 0x52, 0xe3, 0x1b, 0xa9, + 0x89, 0xac, 0x24, 0xc8, 0x1f, 0xe0, 0x50, 0x77, 0xc6, 0xc2, 0xd7, 0x24, 0x37, 0x05, 0x94, 0xaf, + 0x61, 0x8d, 0x1a, 0xc4, 0xda, 0x69, 0xe4, 0xeb, 0x6e, 0xda, 0xd7, 0xf4, 0x8b, 0xf2, 0x9a, 0xde, + 0xbe, 0x00, 0x22, 0x93, 0x0b, 0x93, 0x1e, 0x43, 0x91, 0x8d, 0x99, 0x90, 0x3c, 0xfd, 0x42, 0x12, + 0xa8, 0xf2, 0x08, 0xd6, 0x85, 0x43, 0x5c, 0x7e, 0x85, 0xdf, 0x2f, 0x60, 0x23, 0xa9, 0x26, 0x8e, + 0x89, 0xde, 0x61, 0x99, 0x8f, 0xbc, 0xc3, 0x94, 0x36, 0xac, 0x53, 0x13, 0xcd, 0x39, 0xab, 0x58, + 0x29, 0xdb, 0x45, 0xee, 0xdc, 0xa5, 0x27, 0xb5, 0x54, 0xfe, 0x9a, 0xd0, 0x51, 0x5e, 0xc2, 0x46, + 0x92, 0x24, 0xf6, 0xd4, 0x64, 0x92, 0x4b, 0x9e, 0x32, 0x45, 0x4d, 0xa0, 0xca, 0xcf, 0x19, 0x56, + 0xb7, 0xc7, 0xce, 0x34, 0x32, 0xe0, 0x26, 0x14, 0xe9, 0x2c, 0x8c, 0x3c, 0x2d, 0xe0, 0xaa, 0x33, + 0x26, 0x77, 0xa0, 0x1c, 0x0e, 0xf4, 0xf0, 0x47, 0x81, 0x98, 0xe7, 0xf4, 0x3e, 0xd9, 0xd6, 0x9c, + 0xdd, 0xa7, 0xcc, 0x76, 0x41, 0xe3, 0x0b, 0x9a, 0x9a, 0x89, 0x63, 0xdb, 0xce, 0x7b, 0x76, 0x97, + 0x30, 0x35, 0x7c, 0x95, 0xba, 0x67, 0x85, 0x8f, 0xdf, 0xb3, 0x62, 0xfa, 0x9e, 0x3d, 0x61, 0xb7, + 0x8a, 0xdb, 0x2b, 0x7c, 0x8d, 0x8e, 0xe7, 0x63, 0x98, 0x2f, 0x76, 0x4c, 0xa8, 0x44, 0x3f, 0x6b, + 0x70, 0xf2, 0x6f, 0x74, 0x4e, 0x5a, 0x47, 0xaa, 0x3e, 0x78, 0xdb, 0x57, 0xf5, 0x37, 0xdd, 0x03, + 0xf5, 0xb0, 0xd3, 0x55, 0x0f, 0x1a, 0x37, 0xc8, 0x3a, 0xac, 0x4a, 0x48, 0xab, 0xdf, 0x6f, 0x37, + 0x32, 0x18, 0x82, 0x35, 0x49, 0x78, 0xd0, 0x6b, 0xbf, 0x52, 0xb5, 0x46, 0x16, 0xdb, 0x57, 0x5d, + 0x12, 0xf7, 0xda, 0x9d, 0x46, 0x6e, 0xa7, 0x0f, 0xe5, 0xf0, 0xdd, 0x4c, 0x6e, 0xc3, 0x3a, 0x12, + 0xe8, 0xaf, 0x07, 0xad, 0x41, 0xf2, 0x10, 0xe4, 0x8b, 0x01, 0xed, 0x4d, 0xb7, 0xdb, 0xe9, 0x1e, + 0xe1, 0x31, 0x1b, 0xd0, 0x88, 0xc5, 0xea, 0x57, 0x9d, 0x01, 0x2a, 0x67, 0x77, 0x7e, 0xcf, 0x40, + 0x39, 0x7c, 0x4e, 0x51, 0xca, 0x7e, 0xef, 0x60, 0x09, 0x25, 0xee, 0x8d, 0x01, 0xf5, 0x64, 0x5f, + 0x7b, 0xdb, 0x43, 0xc6, 0x84, 0x7a, 0x5f, 0x53, 0xfb, 0x2d, 0x8d, 0x1e, 0x95, 0xc5, 0x64, 0x90, + 0x34, 0x80, 0x34, 0x39, 0x6a, 0x59, 0x2c, 0x0f, 0x2d, 0xcb, 0x63, 0x12, 0xee, 0xc4, 0xe2, 0xd6, + 0x7e, 0x4f, 0x43, 0xd3, 0xc2, 0x6d, 0x8d, 0x42, 0xea, 0x70, 0x6e, 0x78, 0x31, 0x79, 0xc6, 0x81, + 0x7a, 0xac, 0x0e, 0x28, 0x59, 0x29, 0x79, 0xc6, 0x51, 0x4b, 0xdb, 0xc7, 0x10, 0x36, 0xca, 0x3b, + 0xf8, 0x53, 0xb2, 0x12, 0x35, 0x6b, 0x9a, 0x21, 0xf5, 0x54, 0xed, 0x0e, 0x2e, 0x67, 0xe8, 0x2e, + 0xdc, 0x96, 0x10, 0xca, 0x14, 0xd9, 0x9f, 0x21, 0x0a, 0x3c, 0x58, 0x0e, 0x86, 0x56, 0xa3, 0xef, + 0x9b, 0x70, 0x2b, 0xa5, 0x83, 0xa6, 0x30, 0x2c, 0x87, 0x55, 0x7d, 0x33, 0x85, 0x09, 0x77, 0xf2, + 0x78, 0x8b, 0xb7, 0x52, 0x90, 0xb0, 0x5d, 0x6f, 0xf7, 0x8e, 0x8f, 0xd5, 0x36, 0xd5, 0x2a, 0xa4, + 0xc8, 0x45, 0x3a, 0x35, 0x1e, 0x90, 0x24, 0x39, 0xc5, 0x04, 0x79, 0x89, 0x06, 0x58, 0x82, 0x78, + 0x55, 0x75, 0x4e, 0xfa, 0xdc, 0xe4, 0x32, 0xb9, 0x07, 0xcd, 0x4b, 0xb0, 0xa6, 0x9e, 0xf4, 0x4e, + 0x11, 0xad, 0xec, 0x7d, 0x97, 0xc7, 0x67, 0xfa, 0x62, 0x68, 0x5b, 0xa3, 0x56, 0xbf, 0x43, 0x5e, + 0x42, 0x49, 0xcc, 0x19, 0x72, 0x3b, 0x1e, 0xec, 0x89, 0x59, 0xb4, 0xd9, 0xbc, 0x0c, 0xf0, 0xcb, + 0xa3, 0xdc, 0x20, 0x2d, 0x28, 0x87, 0x83, 0x81, 0xc4, 0x7a, 0xa9, 0x21, 0xb4, 0x79, 0x67, 0x09, + 0x12, 0x51, 0x1c, 0x01, 0xc4, 0x03, 0x80, 0x6c, 0x4a, 0x73, 0x2d, 0x35, 0x3a, 0x36, 0xef, 0x2e, + 0xc5, 0x64, 0xa2, 0xb8, 0x6d, 0x4b, 0x44, 0x97, 0x06, 0x85, 0x44, 0x74, 0xb9, 0xcf, 0x23, 0xd1, + 0x09, 0xd4, 0xe4, 0xd6, 0x4c, 0xee, 0xa5, 0xcf, 0x95, 0x1b, 0xfb, 0xe6, 0xfd, 0x2b, 0xd0, 0x88, + 0xae, 0x07, 0x35, 0xb9, 0xcd, 0x4a, 0x74, 0x4b, 0x5a, 0xb8, 0x44, 0xb7, 0xac, 0x37, 0x2b, 0x37, + 0xfe, 0x9f, 0x21, 0x9f, 0xb3, 0xa4, 0xd1, 0x36, 0x96, 0x4c, 0x9a, 0xd4, 0x88, 0x93, 0x49, 0x93, + 0x3b, 0x1e, 0x65, 0x18, 0x16, 0xd9, 0x5f, 0x3d, 0xcf, 0xfe, 0x0a, 0x00, 0x00, 0xff, 0xff, 0x45, + 0x22, 0xcb, 0xca, 0xf7, 0x11, 0x00, 0x00, } diff --git a/vendor/github.com/coreos/rkt/api/v1alpha/api.proto b/vendor/github.com/coreos/rkt/api/v1alpha/api.proto index 80b870a3f38..8bddb5c4f77 100644 --- a/vendor/github.com/coreos/rkt/api/v1alpha/api.proto +++ b/vendor/github.com/coreos/rkt/api/v1alpha/api.proto @@ -74,6 +74,9 @@ message Image { // Annotations on this image. repeated KeyValue annotations = 8; + + // Labels of this image. + repeated KeyValue labels = 9; } // Network describes the network information of a pod. diff --git a/vendor/github.com/coreos/rkt/api/v1alpha/client_example.go b/vendor/github.com/coreos/rkt/api/v1alpha/client_example.go index ec807d9ee31..81d3d15c7de 100644 --- a/vendor/github.com/coreos/rkt/api/v1alpha/client_example.go +++ b/vendor/github.com/coreos/rkt/api/v1alpha/client_example.go @@ -17,15 +17,89 @@ package main import ( + "flag" "fmt" + "io" "os" + "time" "github.com/coreos/rkt/api/v1alpha" "golang.org/x/net/context" "google.golang.org/grpc" ) +func getLogsWithoutFollow(c v1alpha.PublicAPIClient, p *v1alpha.Pod) { + if len(p.Apps) == 0 { + fmt.Printf("Pod %q has no apps\n", p.Id) + return + } + + logsResp, err := c.GetLogs(context.Background(), &v1alpha.GetLogsRequest{ + PodId: p.Id, + Follow: false, + AppName: p.Apps[0].Name, + SinceTime: time.Now().Add(-time.Second * 5).Unix(), + Lines: 10, + }) + + if err != nil { + fmt.Println(err) + os.Exit(1) + } + + logsRecvResp, err := logsResp.Recv() + + if err == io.EOF { + return + } + + if err != nil { + fmt.Println(err) + return + } + + for _, l := range logsRecvResp.Lines { + fmt.Println(l) + } +} + +func getLogsWithFollow(c v1alpha.PublicAPIClient, p *v1alpha.Pod) { + if len(p.Apps) == 0 { + fmt.Printf("Pod %q has no apps\n", p.Id) + return + } + + logsResp, err := c.GetLogs(context.Background(), &v1alpha.GetLogsRequest{ + PodId: p.Id, + Follow: true, + AppName: p.Apps[0].Name, + }) + if err != nil { + fmt.Println(err) + os.Exit(1) + } + + for { + logsRecvResp, err := logsResp.Recv() + if err == io.EOF { + return + } + + if err != nil { + fmt.Println(err) + return + } + + for _, l := range logsRecvResp.Lines { + fmt.Println(l) + } + } +} + func main() { + followFlag := flag.Bool("follow", false, "enable 'follow' option on GetLogs") + flag.Parse() + conn, err := grpc.Dial("localhost:15441", grpc.WithInsecure()) if err != nil { fmt.Println(err) @@ -46,11 +120,17 @@ func main() { }) if err != nil { fmt.Println(err) - os.Exit(2) + os.Exit(1) } for _, p := range podResp.Pods { - fmt.Printf("Pod %q is running\n", p.Id) + if *followFlag { + fmt.Printf("Pod %q is running. Following logs:\n", p.Id) + getLogsWithFollow(c, p) + } else { + fmt.Printf("Pod %q is running.\n", p.Id) + getLogsWithoutFollow(c, p) + } } // List images. @@ -65,7 +145,7 @@ func main() { }) if err != nil { fmt.Println(err) - os.Exit(3) + os.Exit(1) } for _, im := range imgResp.Images { diff --git a/vendor/github.com/gogo/protobuf/gogoproto/gogo.pb.go b/vendor/github.com/gogo/protobuf/gogoproto/gogo.pb.go index 760e4e61d86..f97c2338e72 100644 --- a/vendor/github.com/gogo/protobuf/gogoproto/gogo.pb.go +++ b/vendor/github.com/gogo/protobuf/gogoproto/gogo.pb.go @@ -22,12 +22,16 @@ var _ = proto.Marshal var _ = fmt.Errorf 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.GoGoProtoPackageIsVersion1 + var E_GoprotoEnumPrefix = &proto.ExtensionDesc{ ExtendedType: (*google_protobuf.EnumOptions)(nil), ExtensionType: (*bool)(nil), Field: 62001, Name: "gogoproto.goproto_enum_prefix", - Tag: "varint,62001,opt,name=goproto_enum_prefix", + Tag: "varint,62001,opt,name=goproto_enum_prefix,json=goprotoEnumPrefix", } var E_GoprotoEnumStringer = &proto.ExtensionDesc{ @@ -35,7 +39,7 @@ var E_GoprotoEnumStringer = &proto.ExtensionDesc{ ExtensionType: (*bool)(nil), Field: 62021, Name: "gogoproto.goproto_enum_stringer", - Tag: "varint,62021,opt,name=goproto_enum_stringer", + Tag: "varint,62021,opt,name=goproto_enum_stringer,json=goprotoEnumStringer", } var E_EnumStringer = &proto.ExtensionDesc{ @@ -43,7 +47,23 @@ var E_EnumStringer = &proto.ExtensionDesc{ ExtensionType: (*bool)(nil), Field: 62022, Name: "gogoproto.enum_stringer", - Tag: "varint,62022,opt,name=enum_stringer", + Tag: "varint,62022,opt,name=enum_stringer,json=enumStringer", +} + +var E_EnumCustomname = &proto.ExtensionDesc{ + ExtendedType: (*google_protobuf.EnumOptions)(nil), + ExtensionType: (*string)(nil), + Field: 62023, + Name: "gogoproto.enum_customname", + Tag: "bytes,62023,opt,name=enum_customname,json=enumCustomname", +} + +var E_EnumvalueCustomname = &proto.ExtensionDesc{ + ExtendedType: (*google_protobuf.EnumValueOptions)(nil), + ExtensionType: (*string)(nil), + Field: 66001, + Name: "gogoproto.enumvalue_customname", + Tag: "bytes,66001,opt,name=enumvalue_customname,json=enumvalueCustomname", } var E_GoprotoGettersAll = &proto.ExtensionDesc{ @@ -51,7 +71,7 @@ var E_GoprotoGettersAll = &proto.ExtensionDesc{ ExtensionType: (*bool)(nil), Field: 63001, Name: "gogoproto.goproto_getters_all", - Tag: "varint,63001,opt,name=goproto_getters_all", + Tag: "varint,63001,opt,name=goproto_getters_all,json=goprotoGettersAll", } var E_GoprotoEnumPrefixAll = &proto.ExtensionDesc{ @@ -59,7 +79,7 @@ var E_GoprotoEnumPrefixAll = &proto.ExtensionDesc{ ExtensionType: (*bool)(nil), Field: 63002, Name: "gogoproto.goproto_enum_prefix_all", - Tag: "varint,63002,opt,name=goproto_enum_prefix_all", + Tag: "varint,63002,opt,name=goproto_enum_prefix_all,json=goprotoEnumPrefixAll", } var E_GoprotoStringerAll = &proto.ExtensionDesc{ @@ -67,7 +87,7 @@ var E_GoprotoStringerAll = &proto.ExtensionDesc{ ExtensionType: (*bool)(nil), Field: 63003, Name: "gogoproto.goproto_stringer_all", - Tag: "varint,63003,opt,name=goproto_stringer_all", + Tag: "varint,63003,opt,name=goproto_stringer_all,json=goprotoStringerAll", } var E_VerboseEqualAll = &proto.ExtensionDesc{ @@ -75,7 +95,7 @@ var E_VerboseEqualAll = &proto.ExtensionDesc{ ExtensionType: (*bool)(nil), Field: 63004, Name: "gogoproto.verbose_equal_all", - Tag: "varint,63004,opt,name=verbose_equal_all", + Tag: "varint,63004,opt,name=verbose_equal_all,json=verboseEqualAll", } var E_FaceAll = &proto.ExtensionDesc{ @@ -83,7 +103,7 @@ var E_FaceAll = &proto.ExtensionDesc{ ExtensionType: (*bool)(nil), Field: 63005, Name: "gogoproto.face_all", - Tag: "varint,63005,opt,name=face_all", + Tag: "varint,63005,opt,name=face_all,json=faceAll", } var E_GostringAll = &proto.ExtensionDesc{ @@ -91,7 +111,7 @@ var E_GostringAll = &proto.ExtensionDesc{ ExtensionType: (*bool)(nil), Field: 63006, Name: "gogoproto.gostring_all", - Tag: "varint,63006,opt,name=gostring_all", + Tag: "varint,63006,opt,name=gostring_all,json=gostringAll", } var E_PopulateAll = &proto.ExtensionDesc{ @@ -99,7 +119,7 @@ var E_PopulateAll = &proto.ExtensionDesc{ ExtensionType: (*bool)(nil), Field: 63007, Name: "gogoproto.populate_all", - Tag: "varint,63007,opt,name=populate_all", + Tag: "varint,63007,opt,name=populate_all,json=populateAll", } var E_StringerAll = &proto.ExtensionDesc{ @@ -107,7 +127,7 @@ var E_StringerAll = &proto.ExtensionDesc{ ExtensionType: (*bool)(nil), Field: 63008, Name: "gogoproto.stringer_all", - Tag: "varint,63008,opt,name=stringer_all", + Tag: "varint,63008,opt,name=stringer_all,json=stringerAll", } var E_OnlyoneAll = &proto.ExtensionDesc{ @@ -115,7 +135,7 @@ var E_OnlyoneAll = &proto.ExtensionDesc{ ExtensionType: (*bool)(nil), Field: 63009, Name: "gogoproto.onlyone_all", - Tag: "varint,63009,opt,name=onlyone_all", + Tag: "varint,63009,opt,name=onlyone_all,json=onlyoneAll", } var E_EqualAll = &proto.ExtensionDesc{ @@ -123,7 +143,7 @@ var E_EqualAll = &proto.ExtensionDesc{ ExtensionType: (*bool)(nil), Field: 63013, Name: "gogoproto.equal_all", - Tag: "varint,63013,opt,name=equal_all", + Tag: "varint,63013,opt,name=equal_all,json=equalAll", } var E_DescriptionAll = &proto.ExtensionDesc{ @@ -131,7 +151,7 @@ var E_DescriptionAll = &proto.ExtensionDesc{ ExtensionType: (*bool)(nil), Field: 63014, Name: "gogoproto.description_all", - Tag: "varint,63014,opt,name=description_all", + Tag: "varint,63014,opt,name=description_all,json=descriptionAll", } var E_TestgenAll = &proto.ExtensionDesc{ @@ -139,7 +159,7 @@ var E_TestgenAll = &proto.ExtensionDesc{ ExtensionType: (*bool)(nil), Field: 63015, Name: "gogoproto.testgen_all", - Tag: "varint,63015,opt,name=testgen_all", + Tag: "varint,63015,opt,name=testgen_all,json=testgenAll", } var E_BenchgenAll = &proto.ExtensionDesc{ @@ -147,7 +167,7 @@ var E_BenchgenAll = &proto.ExtensionDesc{ ExtensionType: (*bool)(nil), Field: 63016, Name: "gogoproto.benchgen_all", - Tag: "varint,63016,opt,name=benchgen_all", + Tag: "varint,63016,opt,name=benchgen_all,json=benchgenAll", } var E_MarshalerAll = &proto.ExtensionDesc{ @@ -155,7 +175,7 @@ var E_MarshalerAll = &proto.ExtensionDesc{ ExtensionType: (*bool)(nil), Field: 63017, Name: "gogoproto.marshaler_all", - Tag: "varint,63017,opt,name=marshaler_all", + Tag: "varint,63017,opt,name=marshaler_all,json=marshalerAll", } var E_UnmarshalerAll = &proto.ExtensionDesc{ @@ -163,7 +183,15 @@ var E_UnmarshalerAll = &proto.ExtensionDesc{ ExtensionType: (*bool)(nil), Field: 63018, Name: "gogoproto.unmarshaler_all", - Tag: "varint,63018,opt,name=unmarshaler_all", + Tag: "varint,63018,opt,name=unmarshaler_all,json=unmarshalerAll", +} + +var E_StableMarshalerAll = &proto.ExtensionDesc{ + ExtendedType: (*google_protobuf.FileOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 63019, + Name: "gogoproto.stable_marshaler_all", + Tag: "varint,63019,opt,name=stable_marshaler_all,json=stableMarshalerAll", } var E_SizerAll = &proto.ExtensionDesc{ @@ -171,7 +199,7 @@ var E_SizerAll = &proto.ExtensionDesc{ ExtensionType: (*bool)(nil), Field: 63020, Name: "gogoproto.sizer_all", - Tag: "varint,63020,opt,name=sizer_all", + Tag: "varint,63020,opt,name=sizer_all,json=sizerAll", } var E_GoprotoEnumStringerAll = &proto.ExtensionDesc{ @@ -179,7 +207,7 @@ var E_GoprotoEnumStringerAll = &proto.ExtensionDesc{ ExtensionType: (*bool)(nil), Field: 63021, Name: "gogoproto.goproto_enum_stringer_all", - Tag: "varint,63021,opt,name=goproto_enum_stringer_all", + Tag: "varint,63021,opt,name=goproto_enum_stringer_all,json=goprotoEnumStringerAll", } var E_EnumStringerAll = &proto.ExtensionDesc{ @@ -187,7 +215,7 @@ var E_EnumStringerAll = &proto.ExtensionDesc{ ExtensionType: (*bool)(nil), Field: 63022, Name: "gogoproto.enum_stringer_all", - Tag: "varint,63022,opt,name=enum_stringer_all", + Tag: "varint,63022,opt,name=enum_stringer_all,json=enumStringerAll", } var E_UnsafeMarshalerAll = &proto.ExtensionDesc{ @@ -195,7 +223,7 @@ var E_UnsafeMarshalerAll = &proto.ExtensionDesc{ ExtensionType: (*bool)(nil), Field: 63023, Name: "gogoproto.unsafe_marshaler_all", - Tag: "varint,63023,opt,name=unsafe_marshaler_all", + Tag: "varint,63023,opt,name=unsafe_marshaler_all,json=unsafeMarshalerAll", } var E_UnsafeUnmarshalerAll = &proto.ExtensionDesc{ @@ -203,7 +231,7 @@ var E_UnsafeUnmarshalerAll = &proto.ExtensionDesc{ ExtensionType: (*bool)(nil), Field: 63024, Name: "gogoproto.unsafe_unmarshaler_all", - Tag: "varint,63024,opt,name=unsafe_unmarshaler_all", + Tag: "varint,63024,opt,name=unsafe_unmarshaler_all,json=unsafeUnmarshalerAll", } var E_GoprotoExtensionsMapAll = &proto.ExtensionDesc{ @@ -211,7 +239,7 @@ var E_GoprotoExtensionsMapAll = &proto.ExtensionDesc{ ExtensionType: (*bool)(nil), Field: 63025, Name: "gogoproto.goproto_extensions_map_all", - Tag: "varint,63025,opt,name=goproto_extensions_map_all", + Tag: "varint,63025,opt,name=goproto_extensions_map_all,json=goprotoExtensionsMapAll", } var E_GoprotoUnrecognizedAll = &proto.ExtensionDesc{ @@ -219,7 +247,7 @@ var E_GoprotoUnrecognizedAll = &proto.ExtensionDesc{ ExtensionType: (*bool)(nil), Field: 63026, Name: "gogoproto.goproto_unrecognized_all", - Tag: "varint,63026,opt,name=goproto_unrecognized_all", + Tag: "varint,63026,opt,name=goproto_unrecognized_all,json=goprotoUnrecognizedAll", } var E_GogoprotoImport = &proto.ExtensionDesc{ @@ -227,7 +255,7 @@ var E_GogoprotoImport = &proto.ExtensionDesc{ ExtensionType: (*bool)(nil), Field: 63027, Name: "gogoproto.gogoproto_import", - Tag: "varint,63027,opt,name=gogoproto_import", + Tag: "varint,63027,opt,name=gogoproto_import,json=gogoprotoImport", } var E_ProtosizerAll = &proto.ExtensionDesc{ @@ -235,7 +263,15 @@ var E_ProtosizerAll = &proto.ExtensionDesc{ ExtensionType: (*bool)(nil), Field: 63028, Name: "gogoproto.protosizer_all", - Tag: "varint,63028,opt,name=protosizer_all", + Tag: "varint,63028,opt,name=protosizer_all,json=protosizerAll", +} + +var E_CompareAll = &proto.ExtensionDesc{ + ExtendedType: (*google_protobuf.FileOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 63029, + Name: "gogoproto.compare_all", + Tag: "varint,63029,opt,name=compare_all,json=compareAll", } var E_GoprotoGetters = &proto.ExtensionDesc{ @@ -243,7 +279,7 @@ var E_GoprotoGetters = &proto.ExtensionDesc{ ExtensionType: (*bool)(nil), Field: 64001, Name: "gogoproto.goproto_getters", - Tag: "varint,64001,opt,name=goproto_getters", + Tag: "varint,64001,opt,name=goproto_getters,json=goprotoGetters", } var E_GoprotoStringer = &proto.ExtensionDesc{ @@ -251,7 +287,7 @@ var E_GoprotoStringer = &proto.ExtensionDesc{ ExtensionType: (*bool)(nil), Field: 64003, Name: "gogoproto.goproto_stringer", - Tag: "varint,64003,opt,name=goproto_stringer", + Tag: "varint,64003,opt,name=goproto_stringer,json=goprotoStringer", } var E_VerboseEqual = &proto.ExtensionDesc{ @@ -259,7 +295,7 @@ var E_VerboseEqual = &proto.ExtensionDesc{ ExtensionType: (*bool)(nil), Field: 64004, Name: "gogoproto.verbose_equal", - Tag: "varint,64004,opt,name=verbose_equal", + Tag: "varint,64004,opt,name=verbose_equal,json=verboseEqual", } var E_Face = &proto.ExtensionDesc{ @@ -350,6 +386,14 @@ var E_Unmarshaler = &proto.ExtensionDesc{ Tag: "varint,64018,opt,name=unmarshaler", } +var E_StableMarshaler = &proto.ExtensionDesc{ + ExtendedType: (*google_protobuf.MessageOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 64019, + Name: "gogoproto.stable_marshaler", + Tag: "varint,64019,opt,name=stable_marshaler,json=stableMarshaler", +} + var E_Sizer = &proto.ExtensionDesc{ ExtendedType: (*google_protobuf.MessageOptions)(nil), ExtensionType: (*bool)(nil), @@ -363,7 +407,7 @@ var E_UnsafeMarshaler = &proto.ExtensionDesc{ ExtensionType: (*bool)(nil), Field: 64023, Name: "gogoproto.unsafe_marshaler", - Tag: "varint,64023,opt,name=unsafe_marshaler", + Tag: "varint,64023,opt,name=unsafe_marshaler,json=unsafeMarshaler", } var E_UnsafeUnmarshaler = &proto.ExtensionDesc{ @@ -371,7 +415,7 @@ var E_UnsafeUnmarshaler = &proto.ExtensionDesc{ ExtensionType: (*bool)(nil), Field: 64024, Name: "gogoproto.unsafe_unmarshaler", - Tag: "varint,64024,opt,name=unsafe_unmarshaler", + Tag: "varint,64024,opt,name=unsafe_unmarshaler,json=unsafeUnmarshaler", } var E_GoprotoExtensionsMap = &proto.ExtensionDesc{ @@ -379,7 +423,7 @@ var E_GoprotoExtensionsMap = &proto.ExtensionDesc{ ExtensionType: (*bool)(nil), Field: 64025, Name: "gogoproto.goproto_extensions_map", - Tag: "varint,64025,opt,name=goproto_extensions_map", + Tag: "varint,64025,opt,name=goproto_extensions_map,json=goprotoExtensionsMap", } var E_GoprotoUnrecognized = &proto.ExtensionDesc{ @@ -387,7 +431,7 @@ var E_GoprotoUnrecognized = &proto.ExtensionDesc{ ExtensionType: (*bool)(nil), Field: 64026, Name: "gogoproto.goproto_unrecognized", - Tag: "varint,64026,opt,name=goproto_unrecognized", + Tag: "varint,64026,opt,name=goproto_unrecognized,json=goprotoUnrecognized", } var E_Protosizer = &proto.ExtensionDesc{ @@ -398,6 +442,14 @@ var E_Protosizer = &proto.ExtensionDesc{ Tag: "varint,64028,opt,name=protosizer", } +var E_Compare = &proto.ExtensionDesc{ + ExtendedType: (*google_protobuf.MessageOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 64029, + Name: "gogoproto.compare", + Tag: "varint,64029,opt,name=compare", +} + var E_Nullable = &proto.ExtensionDesc{ ExtendedType: (*google_protobuf.FieldOptions)(nil), ExtensionType: (*bool)(nil), @@ -474,6 +526,8 @@ func init() { proto.RegisterExtension(E_GoprotoEnumPrefix) proto.RegisterExtension(E_GoprotoEnumStringer) proto.RegisterExtension(E_EnumStringer) + proto.RegisterExtension(E_EnumCustomname) + proto.RegisterExtension(E_EnumvalueCustomname) proto.RegisterExtension(E_GoprotoGettersAll) proto.RegisterExtension(E_GoprotoEnumPrefixAll) proto.RegisterExtension(E_GoprotoStringerAll) @@ -489,6 +543,7 @@ func init() { proto.RegisterExtension(E_BenchgenAll) proto.RegisterExtension(E_MarshalerAll) proto.RegisterExtension(E_UnmarshalerAll) + proto.RegisterExtension(E_StableMarshalerAll) proto.RegisterExtension(E_SizerAll) proto.RegisterExtension(E_GoprotoEnumStringerAll) proto.RegisterExtension(E_EnumStringerAll) @@ -498,6 +553,7 @@ func init() { proto.RegisterExtension(E_GoprotoUnrecognizedAll) proto.RegisterExtension(E_GogoprotoImport) proto.RegisterExtension(E_ProtosizerAll) + proto.RegisterExtension(E_CompareAll) proto.RegisterExtension(E_GoprotoGetters) proto.RegisterExtension(E_GoprotoStringer) proto.RegisterExtension(E_VerboseEqual) @@ -512,12 +568,14 @@ func init() { proto.RegisterExtension(E_Benchgen) proto.RegisterExtension(E_Marshaler) proto.RegisterExtension(E_Unmarshaler) + proto.RegisterExtension(E_StableMarshaler) proto.RegisterExtension(E_Sizer) proto.RegisterExtension(E_UnsafeMarshaler) proto.RegisterExtension(E_UnsafeUnmarshaler) proto.RegisterExtension(E_GoprotoExtensionsMap) proto.RegisterExtension(E_GoprotoUnrecognized) proto.RegisterExtension(E_Protosizer) + proto.RegisterExtension(E_Compare) proto.RegisterExtension(E_Nullable) proto.RegisterExtension(E_Embed) proto.RegisterExtension(E_Customtype) @@ -528,3 +586,76 @@ func init() { proto.RegisterExtension(E_Castkey) proto.RegisterExtension(E_Castvalue) } + +var fileDescriptorGogo = []byte{ + // 1096 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x94, 0x97, 0xcb, 0x6f, 0xdc, 0x54, + 0x14, 0x87, 0x85, 0x48, 0x95, 0x99, 0x93, 0x17, 0x99, 0x84, 0x50, 0x2a, 0x10, 0xed, 0x8e, 0x55, + 0xba, 0x42, 0xa8, 0xae, 0x10, 0x6a, 0xab, 0x34, 0x2a, 0x22, 0x10, 0x05, 0x52, 0x40, 0x2c, 0x46, + 0x9e, 0xc9, 0x8d, 0x3b, 0xe0, 0xf1, 0x35, 0xbe, 0x76, 0xd5, 0xb0, 0x43, 0xe5, 0x21, 0x84, 0x78, + 0x23, 0x41, 0x4b, 0xcb, 0x63, 0xc1, 0xfb, 0x59, 0x1e, 0x7b, 0x36, 0xc0, 0x9a, 0xff, 0x81, 0x0d, + 0x10, 0x5e, 0x52, 0x76, 0xd9, 0xf4, 0x1e, 0xfb, 0x1c, 0xcf, 0xb5, 0x67, 0xa4, 0x7b, 0x67, 0xe7, + 0x64, 0xee, 0xf7, 0xcd, 0xf5, 0x39, 0xbe, 0xe7, 0x37, 0x06, 0x08, 0x64, 0x20, 0x97, 0xe3, 0x44, + 0xa6, 0xb2, 0xd5, 0xc4, 0xeb, 0xfc, 0xf2, 0xd0, 0xe1, 0x40, 0xca, 0x20, 0x14, 0x47, 0xf3, 0xbf, + 0x3a, 0xd9, 0xf6, 0xd1, 0x2d, 0xa1, 0xba, 0x49, 0x2f, 0x4e, 0x65, 0x52, 0x2c, 0xf6, 0x1e, 0x80, + 0x05, 0x5a, 0xdc, 0x16, 0x51, 0xd6, 0x6f, 0xc7, 0x89, 0xd8, 0xee, 0x5d, 0x68, 0xdd, 0xb6, 0x5c, + 0x90, 0xcb, 0x4c, 0x2e, 0xaf, 0xe8, 0x4f, 0x1f, 0x8c, 0xd3, 0x9e, 0x8c, 0xd4, 0xc1, 0x6b, 0xbf, + 0xdf, 0x78, 0xf8, 0x86, 0x3b, 0x1b, 0x1b, 0xf3, 0x84, 0xe2, 0x67, 0xeb, 0x39, 0xe8, 0x6d, 0xc0, + 0xcd, 0x15, 0x9f, 0x4a, 0x93, 0x5e, 0x14, 0x88, 0xc4, 0x62, 0xfc, 0x99, 0x8c, 0x0b, 0x86, 0xf1, + 0x21, 0x42, 0xbd, 0x53, 0x30, 0x33, 0x8e, 0xeb, 0x17, 0x72, 0x4d, 0x0b, 0x53, 0xb2, 0x0a, 0x73, + 0xb9, 0xa4, 0x9b, 0xa9, 0x54, 0xf6, 0x23, 0xbf, 0x2f, 0x2c, 0x9a, 0x5f, 0x73, 0x4d, 0x73, 0x63, + 0x16, 0xb1, 0x53, 0x25, 0xe5, 0x9d, 0x85, 0x45, 0xfc, 0xcf, 0x79, 0x3f, 0xcc, 0x84, 0x69, 0x3b, + 0x32, 0xd2, 0x76, 0x16, 0x97, 0xb1, 0xf2, 0xb7, 0x8b, 0x13, 0xb9, 0x72, 0xa1, 0x14, 0x18, 0x5e, + 0xa3, 0x13, 0x81, 0x48, 0x53, 0x91, 0xa8, 0xb6, 0x1f, 0x86, 0x23, 0x36, 0x79, 0xba, 0x17, 0x96, + 0xc6, 0x4b, 0xbb, 0xd5, 0x4e, 0xac, 0x16, 0xe4, 0x89, 0x30, 0xf4, 0x36, 0xe1, 0x96, 0x11, 0x9d, + 0x75, 0x70, 0x5e, 0x26, 0xe7, 0xe2, 0x50, 0x77, 0x51, 0xbb, 0x0e, 0xfc, 0xff, 0xb2, 0x1f, 0x0e, + 0xce, 0x77, 0xc9, 0xd9, 0x22, 0x96, 0xdb, 0x82, 0xc6, 0xfb, 0x60, 0xfe, 0xbc, 0x48, 0x3a, 0x52, + 0x89, 0xb6, 0x78, 0x2a, 0xf3, 0x43, 0x07, 0xdd, 0x15, 0xd2, 0xcd, 0x11, 0xb8, 0x82, 0x1c, 0xba, + 0x8e, 0x41, 0x63, 0xdb, 0xef, 0x0a, 0x07, 0xc5, 0x55, 0x52, 0x4c, 0xe2, 0x7a, 0x44, 0x4f, 0xc0, + 0x74, 0x20, 0x8b, 0x5b, 0x72, 0xc0, 0xdf, 0x23, 0x7c, 0x8a, 0x19, 0x52, 0xc4, 0x32, 0xce, 0x42, + 0x3f, 0x75, 0xd9, 0xc1, 0xfb, 0xac, 0x60, 0x86, 0x14, 0x63, 0x94, 0xf5, 0x03, 0x56, 0x28, 0xa3, + 0x9e, 0xf7, 0xc2, 0x94, 0x8c, 0xc2, 0x1d, 0x19, 0xb9, 0x6c, 0xe2, 0x43, 0x32, 0x00, 0x21, 0x28, + 0x38, 0x0e, 0x4d, 0xd7, 0x46, 0x7c, 0x44, 0x78, 0x43, 0x70, 0x07, 0xf4, 0x39, 0xe3, 0x21, 0xa3, + 0x57, 0x38, 0x28, 0x3e, 0x26, 0xc5, 0xac, 0x81, 0xd1, 0x6d, 0xa4, 0x42, 0xa5, 0x81, 0x70, 0x91, + 0x7c, 0xc2, 0xb7, 0x41, 0x08, 0x95, 0xb2, 0x23, 0xa2, 0xee, 0x39, 0x37, 0xc3, 0xa7, 0x5c, 0x4a, + 0x66, 0x50, 0xa1, 0x27, 0x4f, 0xdf, 0x4f, 0xd4, 0x39, 0x3f, 0x74, 0x6a, 0xc7, 0x67, 0xe4, 0x98, + 0x2e, 0x21, 0xaa, 0x48, 0x16, 0x8d, 0xa3, 0xf9, 0x9c, 0x2b, 0x62, 0x60, 0x74, 0xf4, 0x54, 0xea, + 0x77, 0x42, 0xd1, 0x1e, 0xc7, 0xf6, 0x05, 0x1f, 0xbd, 0x82, 0x5d, 0x33, 0x8d, 0xba, 0xd3, 0xaa, + 0xf7, 0xb4, 0x93, 0xe6, 0x4b, 0xee, 0x74, 0x0e, 0x20, 0xfc, 0x18, 0xdc, 0x3a, 0x72, 0xd4, 0x3b, + 0xc8, 0xbe, 0x22, 0xd9, 0xd2, 0x88, 0x71, 0x4f, 0x23, 0x61, 0x5c, 0xe5, 0xd7, 0x3c, 0x12, 0x44, + 0xcd, 0xa5, 0xab, 0x96, 0x45, 0xca, 0xdf, 0x1e, 0xaf, 0x6a, 0xdf, 0x70, 0xd5, 0x0a, 0xb6, 0x52, + 0xb5, 0x87, 0x61, 0x89, 0x8c, 0xe3, 0xf5, 0xf5, 0x5b, 0x1e, 0xac, 0x05, 0xbd, 0x59, 0xed, 0xee, + 0xe3, 0x70, 0xa8, 0x2c, 0xe7, 0x85, 0x54, 0x44, 0x0a, 0x19, 0xbd, 0xe7, 0xd8, 0xc1, 0x7c, 0x8d, + 0xcc, 0x3c, 0xf1, 0x57, 0x4a, 0xc1, 0x9a, 0x1f, 0xa3, 0xfc, 0x51, 0x38, 0xc8, 0xf2, 0x2c, 0x4a, + 0x44, 0x57, 0x06, 0x91, 0x6e, 0xe3, 0x96, 0x83, 0xfa, 0xbb, 0x5a, 0xab, 0x36, 0x0d, 0x1c, 0xcd, + 0x67, 0xe0, 0xa6, 0xf2, 0xf7, 0x46, 0xbb, 0xd7, 0x8f, 0x65, 0x92, 0x5a, 0x8c, 0xdf, 0x73, 0xa7, + 0x4a, 0xee, 0x4c, 0x8e, 0x79, 0x2b, 0x30, 0x9b, 0xff, 0xe9, 0xfa, 0x48, 0xfe, 0x40, 0xa2, 0x99, + 0x01, 0x45, 0x83, 0xa3, 0x2b, 0xfb, 0xb1, 0x9f, 0xb8, 0xcc, 0xbf, 0x1f, 0x79, 0x70, 0x10, 0x52, + 0x3c, 0x7d, 0x73, 0xb5, 0x24, 0x6e, 0xdd, 0x31, 0x24, 0x59, 0x13, 0x4a, 0xf9, 0x41, 0xe9, 0x79, + 0x66, 0x8f, 0xce, 0x6c, 0x35, 0x88, 0xbd, 0xfb, 0xb1, 0x3c, 0xd5, 0xb8, 0xb4, 0xcb, 0x2e, 0xee, + 0x95, 0x15, 0xaa, 0xa4, 0xa5, 0x77, 0x1a, 0x66, 0x2a, 0x51, 0x69, 0x57, 0x3d, 0x4b, 0xaa, 0x69, + 0x33, 0x29, 0xbd, 0xbb, 0x60, 0x02, 0x63, 0xcf, 0x8e, 0x3f, 0x47, 0x78, 0xbe, 0xdc, 0xbb, 0x07, + 0x1a, 0x1c, 0x77, 0x76, 0xf4, 0x79, 0x42, 0x4b, 0x04, 0x71, 0x8e, 0x3a, 0x3b, 0xfe, 0x02, 0xe3, + 0x8c, 0x20, 0xee, 0x5e, 0xc2, 0x9f, 0x5e, 0x9a, 0xa0, 0x71, 0xc5, 0xb5, 0x3b, 0x0e, 0x93, 0x94, + 0x71, 0x76, 0xfa, 0x45, 0xfa, 0x72, 0x26, 0xbc, 0xbb, 0xe1, 0x80, 0x63, 0xc1, 0x5f, 0x26, 0xb4, + 0x58, 0xaf, 0x13, 0x64, 0xca, 0xc8, 0x35, 0x3b, 0xfe, 0x0a, 0xe1, 0x26, 0x85, 0x5b, 0xa7, 0x5c, + 0xb3, 0x0b, 0x5e, 0xe5, 0xad, 0x13, 0x81, 0x65, 0xe3, 0x48, 0xb3, 0xd3, 0xaf, 0x71, 0xd5, 0x19, + 0xd1, 0xa7, 0xa9, 0x59, 0x8e, 0x29, 0x3b, 0xff, 0x3a, 0xf1, 0x03, 0x06, 0x2b, 0x60, 0x8c, 0x49, + 0xbb, 0xe2, 0x0d, 0xae, 0x80, 0x41, 0xe1, 0x31, 0xaa, 0x47, 0x9f, 0xdd, 0xf4, 0x26, 0x1f, 0xa3, + 0x5a, 0xf2, 0x61, 0x37, 0xf3, 0x69, 0x61, 0x57, 0xbc, 0xc5, 0xdd, 0xcc, 0xd7, 0xe3, 0x36, 0xea, + 0x59, 0x62, 0x77, 0xbc, 0xcd, 0xdb, 0xa8, 0x45, 0x89, 0x4e, 0xa6, 0xd6, 0x70, 0x8e, 0xd8, 0x7d, + 0xef, 0x90, 0x6f, 0x7e, 0x28, 0x46, 0xbc, 0x47, 0x60, 0x69, 0x74, 0x86, 0xd8, 0xad, 0x97, 0xf6, + 0x6a, 0xbf, 0xfa, 0xcd, 0x08, 0xd1, 0x91, 0xb7, 0x38, 0x2a, 0x3f, 0xec, 0xda, 0xcb, 0x7b, 0xd5, + 0x17, 0x3b, 0x33, 0x3e, 0xf4, 0x2f, 0x34, 0x18, 0x8c, 0x6e, 0xbb, 0xeb, 0x0a, 0xb9, 0x0c, 0x08, + 0x8f, 0x06, 0x4d, 0x6e, 0x3b, 0x7f, 0x95, 0x8f, 0x06, 0x11, 0x1a, 0x6e, 0x44, 0x59, 0x18, 0xe2, + 0xc3, 0xd1, 0xba, 0x7d, 0x44, 0x4c, 0x88, 0x70, 0x8b, 0xd9, 0x3f, 0xf6, 0xe9, 0x60, 0x30, 0xa0, + 0x67, 0xe8, 0x01, 0xd1, 0xef, 0xe8, 0x1a, 0x58, 0xc8, 0x3f, 0xf7, 0x79, 0x20, 0xe0, 0x6a, 0x7d, + 0x9e, 0xa0, 0x78, 0x69, 0x4c, 0x77, 0x62, 0xeb, 0xb7, 0xfe, 0xb5, 0x5f, 0xbc, 0x83, 0x1a, 0xc8, + 0x40, 0x90, 0xbf, 0x75, 0x5a, 0x04, 0xbb, 0x55, 0x41, 0xfe, 0xa2, 0x79, 0x0c, 0x26, 0x9f, 0x50, + 0x32, 0x4a, 0xfd, 0xc0, 0x46, 0xff, 0x4d, 0x34, 0xaf, 0xc7, 0x82, 0xf5, 0x65, 0x22, 0xf4, 0xa5, + 0xb2, 0xb1, 0xff, 0x10, 0x5b, 0x02, 0x08, 0x77, 0x7d, 0x95, 0xba, 0xdc, 0xf7, 0xbf, 0x0c, 0x33, + 0x80, 0x9b, 0xc6, 0xeb, 0x27, 0xc5, 0x8e, 0x8d, 0xfd, 0x8f, 0x37, 0x4d, 0xeb, 0xf5, 0x00, 0x6c, + 0xe2, 0x65, 0xfe, 0xbe, 0x6d, 0x83, 0xff, 0x27, 0x78, 0x40, 0x9c, 0x3c, 0x02, 0x0b, 0xfa, 0x79, + 0xa9, 0x63, 0x27, 0x61, 0x55, 0xae, 0xca, 0xf5, 0xfc, 0x41, 0xbc, 0x1e, 0x00, 0x00, 0xff, 0xff, + 0x87, 0x5c, 0xee, 0x2b, 0x7e, 0x11, 0x00, 0x00, +} diff --git a/vendor/github.com/gogo/protobuf/gogoproto/gogo.proto b/vendor/github.com/gogo/protobuf/gogoproto/gogo.proto index 3373faf3197..e8e3edb61f5 100644 --- a/vendor/github.com/gogo/protobuf/gogoproto/gogo.proto +++ b/vendor/github.com/gogo/protobuf/gogoproto/gogo.proto @@ -36,6 +36,11 @@ extend google.protobuf.EnumOptions { optional bool goproto_enum_prefix = 62001; optional bool goproto_enum_stringer = 62021; optional bool enum_stringer = 62022; + optional string enum_customname = 62023; +} + +extend google.protobuf.EnumValueOptions { + optional string enumvalue_customname = 66001; } extend google.protobuf.FileOptions { @@ -55,6 +60,7 @@ extend google.protobuf.FileOptions { optional bool benchgen_all = 63016; optional bool marshaler_all = 63017; optional bool unmarshaler_all = 63018; + optional bool stable_marshaler_all = 63019; optional bool sizer_all = 63020; @@ -67,8 +73,8 @@ extend google.protobuf.FileOptions { optional bool goproto_extensions_map_all = 63025; optional bool goproto_unrecognized_all = 63026; optional bool gogoproto_import = 63027; - optional bool protosizer_all = 63028; + optional bool compare_all = 63029; } extend google.protobuf.MessageOptions { @@ -78,7 +84,7 @@ extend google.protobuf.MessageOptions { optional bool face = 64005; optional bool gostring = 64006; optional bool populate = 64007; - optional bool stringer = 67008; + optional bool stringer = 67008; optional bool onlyone = 64009; optional bool equal = 64013; @@ -87,6 +93,7 @@ extend google.protobuf.MessageOptions { optional bool benchgen = 64016; optional bool marshaler = 64017; optional bool unmarshaler = 64018; + optional bool stable_marshaler = 64019; optional bool sizer = 64020; @@ -97,17 +104,17 @@ extend google.protobuf.MessageOptions { optional bool goproto_unrecognized = 64026; optional bool protosizer = 64028; + optional bool compare = 64029; } extend google.protobuf.FieldOptions { - optional bool nullable = 65001; - optional bool embed = 65002; - optional string customtype = 65003; - optional string customname = 65004; - optional string jsontag = 65005; - optional string moretags = 65006; - optional string casttype = 65007; - optional string castkey = 65008; - optional string castvalue = 65009; + optional bool nullable = 65001; + optional bool embed = 65002; + optional string customtype = 65003; + optional string customname = 65004; + optional string jsontag = 65005; + optional string moretags = 65006; + optional string casttype = 65007; + optional string castkey = 65008; + optional string castvalue = 65009; } - diff --git a/vendor/github.com/gogo/protobuf/gogoproto/helper.go b/vendor/github.com/gogo/protobuf/gogoproto/helper.go index b5a18538447..8c29dbc0e12 100644 --- a/vendor/github.com/gogo/protobuf/gogoproto/helper.go +++ b/vendor/github.com/gogo/protobuf/gogoproto/helper.go @@ -37,6 +37,17 @@ func IsNullable(field *google_protobuf.FieldDescriptorProto) bool { return proto.GetBoolExtension(field.Options, E_Nullable, true) } +func NeedsNilCheck(proto3 bool, field *google_protobuf.FieldDescriptorProto) bool { + nullable := IsNullable(field) + if field.IsMessage() || IsCustomType(field) { + return nullable + } + if proto3 { + return false + } + return nullable || *field.Type == google_protobuf.FieldDescriptorProto_TYPE_BYTES +} + func IsCustomType(field *google_protobuf.FieldDescriptorProto) bool { typ := GetCustomType(field) if len(typ) > 0 { @@ -117,6 +128,22 @@ func IsCustomName(field *google_protobuf.FieldDescriptorProto) bool { return false } +func IsEnumCustomName(field *google_protobuf.EnumDescriptorProto) bool { + name := GetEnumCustomName(field) + if len(name) > 0 { + return true + } + return false +} + +func IsEnumValueCustomName(field *google_protobuf.EnumValueDescriptorProto) bool { + name := GetEnumValueCustomName(field) + if len(name) > 0 { + return true + } + return false +} + func GetCustomName(field *google_protobuf.FieldDescriptorProto) string { if field.Options != nil { v, err := proto.GetExtension(field.Options, E_Customname) @@ -127,6 +154,26 @@ func GetCustomName(field *google_protobuf.FieldDescriptorProto) string { return "" } +func GetEnumCustomName(field *google_protobuf.EnumDescriptorProto) string { + if field.Options != nil { + v, err := proto.GetExtension(field.Options, E_EnumCustomname) + if err == nil && v.(*string) != nil { + return *(v.(*string)) + } + } + return "" +} + +func GetEnumValueCustomName(field *google_protobuf.EnumValueDescriptorProto) string { + if field.Options != nil { + v, err := proto.GetExtension(field.Options, E_EnumvalueCustomname) + if err == nil && v.(*string) != nil { + return *(v.(*string)) + } + } + return "" +} + func GetJsonTag(field *google_protobuf.FieldDescriptorProto) *string { if field.Options != nil { v, err := proto.GetExtension(field.Options, E_Jsontag) @@ -209,6 +256,10 @@ func IsUnmarshaler(file *google_protobuf.FileDescriptorProto, message *google_pr return proto.GetBoolExtension(message.Options, E_Unmarshaler, proto.GetBoolExtension(file.Options, E_UnmarshalerAll, false)) } +func IsStableMarshaler(file *google_protobuf.FileDescriptorProto, message *google_protobuf.DescriptorProto) bool { + return proto.GetBoolExtension(message.Options, E_StableMarshaler, proto.GetBoolExtension(file.Options, E_StableMarshalerAll, false)) +} + func IsSizer(file *google_protobuf.FileDescriptorProto, message *google_protobuf.DescriptorProto) bool { return proto.GetBoolExtension(message.Options, E_Sizer, proto.GetBoolExtension(file.Options, E_SizerAll, false)) } @@ -251,3 +302,7 @@ func IsProto3(file *google_protobuf.FileDescriptorProto) bool { func ImportsGoGoProto(file *google_protobuf.FileDescriptorProto) bool { return proto.GetBoolExtension(file.Options, E_GogoprotoImport, true) } + +func HasCompare(file *google_protobuf.FileDescriptorProto, message *google_protobuf.DescriptorProto) bool { + return proto.GetBoolExtension(message.Options, E_Compare, proto.GetBoolExtension(file.Options, E_CompareAll, false)) +} diff --git a/vendor/github.com/gogo/protobuf/plugin/compare/compare.go b/vendor/github.com/gogo/protobuf/plugin/compare/compare.go new file mode 100644 index 00000000000..9f54d194486 --- /dev/null +++ b/vendor/github.com/gogo/protobuf/plugin/compare/compare.go @@ -0,0 +1,520 @@ +// Copyright (c) 2013, Vastech SA (PTY) LTD. 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 compare + +import ( + "github.com/gogo/protobuf/gogoproto" + "github.com/gogo/protobuf/proto" + descriptor "github.com/gogo/protobuf/protoc-gen-gogo/descriptor" + "github.com/gogo/protobuf/protoc-gen-gogo/generator" + "github.com/gogo/protobuf/vanity" +) + +type plugin struct { + *generator.Generator + generator.PluginImports + fmtPkg generator.Single + bytesPkg generator.Single + sortkeysPkg generator.Single +} + +func NewPlugin() *plugin { + return &plugin{} +} + +func (p *plugin) Name() string { + return "compare" +} + +func (p *plugin) Init(g *generator.Generator) { + p.Generator = g +} + +func (p *plugin) Generate(file *generator.FileDescriptor) { + p.PluginImports = generator.NewPluginImports(p.Generator) + p.fmtPkg = p.NewImport("fmt") + p.bytesPkg = p.NewImport("bytes") + p.sortkeysPkg = p.NewImport("github.com/gogo/protobuf/sortkeys") + + for _, msg := range file.Messages() { + if msg.DescriptorProto.GetOptions().GetMapEntry() { + continue + } + if gogoproto.HasCompare(file.FileDescriptorProto, msg.DescriptorProto) { + p.generateMessage(file, msg) + } + } +} + +func (p *plugin) generateNullableField(fieldname string) { + p.P(`if this.`, fieldname, ` != nil && that1.`, fieldname, ` != nil {`) + p.In() + p.P(`if *this.`, fieldname, ` != *that1.`, fieldname, `{`) + p.In() + p.P(`if *this.`, fieldname, ` < *that1.`, fieldname, `{`) + p.In() + p.P(`return -1`) + p.Out() + p.P(`}`) + p.P(`return 1`) + p.Out() + p.P(`}`) + p.Out() + p.P(`} else if this.`, fieldname, ` != nil {`) + p.In() + p.P(`return 1`) + p.Out() + p.P(`} else if that1.`, fieldname, ` != nil {`) + p.In() + p.P(`return -1`) + p.Out() + p.P(`}`) +} + +func (p *plugin) generateMsgNullAndTypeCheck(ccTypeName string) { + p.P(`if that == nil {`) + p.In() + p.P(`if this == nil {`) + p.In() + p.P(`return 0`) + p.Out() + p.P(`}`) + p.P(`return 1`) + p.Out() + p.P(`}`) + p.P(``) + p.P(`that1, ok := that.(*`, ccTypeName, `)`) + p.P(`if !ok {`) + p.In() + p.P(`that2, ok := that.(`, ccTypeName, `)`) + p.P(`if ok {`) + p.In() + p.P(`that1 = &that2`) + p.Out() + p.P(`} else {`) + p.In() + p.P(`return 1`) + p.Out() + p.P(`}`) + p.Out() + p.P(`}`) + p.P(`if that1 == nil {`) + p.In() + p.P(`if this == nil {`) + p.In() + p.P(`return 0`) + p.Out() + p.P(`}`) + p.P(`return 1`) + p.Out() + p.P(`} else if this == nil {`) + p.In() + p.P(`return -1`) + p.Out() + p.P(`}`) +} + +func (p *plugin) generateField(file *generator.FileDescriptor, message *generator.Descriptor, field *descriptor.FieldDescriptorProto) { + proto3 := gogoproto.IsProto3(file.FileDescriptorProto) + fieldname := p.GetOneOfFieldName(message, field) + repeated := field.IsRepeated() + ctype := gogoproto.IsCustomType(field) + nullable := gogoproto.IsNullable(field) + // oneof := field.OneofIndex != nil + if !repeated { + if ctype { + if nullable { + p.P(`if that1.`, fieldname, ` == nil {`) + p.In() + p.P(`if this.`, fieldname, ` != nil {`) + p.In() + p.P(`return 1`) + p.Out() + p.P(`}`) + p.Out() + p.P(`} else if this.`, fieldname, ` == nil {`) + p.In() + p.P(`return -1`) + p.Out() + p.P(`} else if c := this.`, fieldname, `.Compare(*that1.`, fieldname, `); c != 0 {`) + } else { + p.P(`if c := this.`, fieldname, `.Compare(that1.`, fieldname, `); c != 0 {`) + } + p.In() + p.P(`return c`) + p.Out() + p.P(`}`) + } else { + if field.IsMessage() || p.IsGroup(field) { + if nullable { + p.P(`if c := this.`, fieldname, `.Compare(that1.`, fieldname, `); c != 0 {`) + } else { + p.P(`if c := this.`, fieldname, `.Compare(&that1.`, fieldname, `); c != 0 {`) + } + p.In() + p.P(`return c`) + p.Out() + p.P(`}`) + } else if field.IsBytes() { + p.P(`if c := `, p.bytesPkg.Use(), `.Compare(this.`, fieldname, `, that1.`, fieldname, `); c != 0 {`) + p.In() + p.P(`return c`) + p.Out() + p.P(`}`) + } else if field.IsString() { + if nullable && !proto3 { + p.generateNullableField(fieldname) + } else { + p.P(`if this.`, fieldname, ` != that1.`, fieldname, `{`) + p.In() + p.P(`if this.`, fieldname, ` < that1.`, fieldname, `{`) + p.In() + p.P(`return -1`) + p.Out() + p.P(`}`) + p.P(`return 1`) + p.Out() + p.P(`}`) + } + } else if field.IsBool() { + if nullable && !proto3 { + p.P(`if this.`, fieldname, ` != nil && that1.`, fieldname, ` != nil {`) + p.In() + p.P(`if *this.`, fieldname, ` != *that1.`, fieldname, `{`) + p.In() + p.P(`if !*this.`, fieldname, ` {`) + p.In() + p.P(`return -1`) + p.Out() + p.P(`}`) + p.P(`return 1`) + p.Out() + p.P(`}`) + p.Out() + p.P(`} else if this.`, fieldname, ` != nil {`) + p.In() + p.P(`return 1`) + p.Out() + p.P(`} else if that1.`, fieldname, ` != nil {`) + p.In() + p.P(`return -1`) + p.Out() + p.P(`}`) + } else { + p.P(`if this.`, fieldname, ` != that1.`, fieldname, `{`) + p.In() + p.P(`if !this.`, fieldname, ` {`) + p.In() + p.P(`return -1`) + p.Out() + p.P(`}`) + p.P(`return 1`) + p.Out() + p.P(`}`) + } + } else { + if nullable && !proto3 { + p.generateNullableField(fieldname) + } else { + p.P(`if this.`, fieldname, ` != that1.`, fieldname, `{`) + p.In() + p.P(`if this.`, fieldname, ` < that1.`, fieldname, `{`) + p.In() + p.P(`return -1`) + p.Out() + p.P(`}`) + p.P(`return 1`) + p.Out() + p.P(`}`) + } + } + } + } else { + p.P(`if len(this.`, fieldname, `) != len(that1.`, fieldname, `) {`) + p.In() + p.P(`if len(this.`, fieldname, `) < len(that1.`, fieldname, `) {`) + p.In() + p.P(`return -1`) + p.Out() + p.P(`}`) + p.P(`return 1`) + p.Out() + p.P(`}`) + p.P(`for i := range this.`, fieldname, ` {`) + p.In() + if ctype { + p.P(`if c := this.`, fieldname, `[i].Compare(that1.`, fieldname, `[i]); c != 0 {`) + p.In() + p.P(`return c`) + p.Out() + p.P(`}`) + } else { + if p.IsMap(field) { + m := p.GoMapType(nil, field) + valuegoTyp, _ := p.GoType(nil, m.ValueField) + valuegoAliasTyp, _ := p.GoType(nil, m.ValueAliasField) + nullable, valuegoTyp, valuegoAliasTyp = generator.GoMapValueTypes(field, m.ValueField, valuegoTyp, valuegoAliasTyp) + + mapValue := m.ValueAliasField + if mapValue.IsMessage() || p.IsGroup(mapValue) { + if nullable && valuegoTyp == valuegoAliasTyp { + p.P(`if c := this.`, fieldname, `[i].Compare(that1.`, fieldname, `[i]); c != 0 {`) + } else { + // Compare() has a pointer receiver, but map value is a value type + a := `this.` + fieldname + `[i]` + b := `that1.` + fieldname + `[i]` + if valuegoTyp != valuegoAliasTyp { + // cast back to the type that has the generated methods on it + a = `(` + valuegoTyp + `)(` + a + `)` + b = `(` + valuegoTyp + `)(` + b + `)` + } + p.P(`a := `, a) + p.P(`b := `, b) + if nullable { + p.P(`if c := a.Compare(b); c != 0 {`) + } else { + p.P(`if c := (&a).Compare(&b); c != 0 {`) + } + } + p.In() + p.P(`return c`) + p.Out() + p.P(`}`) + } else if mapValue.IsBytes() { + p.P(`if c := `, p.bytesPkg.Use(), `.Compare(this.`, fieldname, `[i], that1.`, fieldname, `[i]); c != 0 {`) + p.In() + p.P(`return c`) + p.Out() + p.P(`}`) + } else if mapValue.IsString() { + p.P(`if this.`, fieldname, `[i] != that1.`, fieldname, `[i] {`) + p.In() + p.P(`if this.`, fieldname, `[i] < that1.`, fieldname, `[i] {`) + p.In() + p.P(`return -1`) + p.Out() + p.P(`}`) + p.P(`return 1`) + p.Out() + p.P(`}`) + } else { + p.P(`if this.`, fieldname, `[i] != that1.`, fieldname, `[i] {`) + p.In() + p.P(`if this.`, fieldname, `[i] < that1.`, fieldname, `[i] {`) + p.In() + p.P(`return -1`) + p.Out() + p.P(`}`) + p.P(`return 1`) + p.Out() + p.P(`}`) + } + } else if field.IsMessage() || p.IsGroup(field) { + if nullable { + p.P(`if c := this.`, fieldname, `[i].Compare(that1.`, fieldname, `[i]); c != 0 {`) + p.In() + p.P(`return c`) + p.Out() + p.P(`}`) + } else { + p.P(`if c := this.`, fieldname, `[i].Compare(&that1.`, fieldname, `[i]); c != 0 {`) + p.In() + p.P(`return c`) + p.Out() + p.P(`}`) + } + } else if field.IsBytes() { + p.P(`if c := `, p.bytesPkg.Use(), `.Compare(this.`, fieldname, `[i], that1.`, fieldname, `[i]); c != 0 {`) + p.In() + p.P(`return c`) + p.Out() + p.P(`}`) + } else if field.IsString() { + p.P(`if this.`, fieldname, `[i] != that1.`, fieldname, `[i] {`) + p.In() + p.P(`if this.`, fieldname, `[i] < that1.`, fieldname, `[i] {`) + p.In() + p.P(`return -1`) + p.Out() + p.P(`}`) + p.P(`return 1`) + p.Out() + p.P(`}`) + } else if field.IsBool() { + p.P(`if this.`, fieldname, `[i] != that1.`, fieldname, `[i] {`) + p.In() + p.P(`if !this.`, fieldname, `[i] {`) + p.In() + p.P(`return -1`) + p.Out() + p.P(`}`) + p.P(`return 1`) + p.Out() + p.P(`}`) + } else { + p.P(`if this.`, fieldname, `[i] != that1.`, fieldname, `[i] {`) + p.In() + p.P(`if this.`, fieldname, `[i] < that1.`, fieldname, `[i] {`) + p.In() + p.P(`return -1`) + p.Out() + p.P(`}`) + p.P(`return 1`) + p.Out() + p.P(`}`) + } + } + p.Out() + p.P(`}`) + } +} + +func (p *plugin) generateMessage(file *generator.FileDescriptor, message *generator.Descriptor) { + ccTypeName := generator.CamelCaseSlice(message.TypeName()) + p.P(`func (this *`, ccTypeName, `) Compare(that interface{}) int {`) + p.In() + p.generateMsgNullAndTypeCheck(ccTypeName) + oneofs := make(map[string]struct{}) + + for _, field := range message.Field { + oneof := field.OneofIndex != nil + if oneof { + fieldname := p.GetFieldName(message, field) + if _, ok := oneofs[fieldname]; ok { + continue + } else { + oneofs[fieldname] = struct{}{} + } + p.P(`if that1.`, fieldname, ` == nil {`) + p.In() + p.P(`if this.`, fieldname, ` != nil {`) + p.In() + p.P(`return 1`) + p.Out() + p.P(`}`) + p.Out() + p.P(`} else if this.`, fieldname, ` == nil {`) + p.In() + p.P(`return -1`) + p.Out() + p.P(`} else if c := this.`, fieldname, `.Compare(that1.`, fieldname, `); c != 0 {`) + p.In() + p.P(`return c`) + p.Out() + p.P(`}`) + } else { + p.generateField(file, message, field) + } + } + if message.DescriptorProto.HasExtension() { + fieldname := "XXX_extensions" + if gogoproto.HasExtensionsMap(file.FileDescriptorProto, message.DescriptorProto) { + p.P(`extkeys := make([]int32, 0, len(this.`, fieldname, `)+len(that1.`, fieldname, `))`) + p.P(`for k, _ := range this.`, fieldname, ` {`) + p.In() + p.P(`extkeys = append(extkeys, k)`) + p.Out() + p.P(`}`) + p.P(`for k, _ := range that1.`, fieldname, ` {`) + p.In() + p.P(`if _, ok := this.`, fieldname, `[k]; !ok {`) + p.In() + p.P(`extkeys = append(extkeys, k)`) + p.Out() + p.P(`}`) + p.Out() + p.P(`}`) + p.P(p.sortkeysPkg.Use(), `.Int32s(extkeys)`) + p.P(`for _, k := range extkeys {`) + p.In() + p.P(`if v, ok := this.`, fieldname, `[k]; ok {`) + p.In() + p.P(`if v2, ok := that1.`, fieldname, `[k]; ok {`) + p.In() + p.P(`if c := v.Compare(&v2); c != 0 {`) + p.In() + p.P(`return c`) + p.Out() + p.P(`}`) + p.Out() + p.P(`} else {`) + p.In() + p.P(`return 1`) + p.Out() + p.P(`}`) + p.Out() + p.P(`} else {`) + p.In() + p.P(`return -1`) + p.Out() + p.P(`}`) + p.Out() + p.P(`}`) + } else { + p.P(`if c := `, p.bytesPkg.Use(), `.Compare(this.`, fieldname, `, that1.`, fieldname, `); c != 0 {`) + p.In() + p.P(`return c`) + p.Out() + p.P(`}`) + } + } + if gogoproto.HasUnrecognized(file.FileDescriptorProto, message.DescriptorProto) { + fieldname := "XXX_unrecognized" + p.P(`if c := `, p.bytesPkg.Use(), `.Compare(this.`, fieldname, `, that1.`, fieldname, `); c != 0 {`) + p.In() + p.P(`return c`) + p.Out() + p.P(`}`) + } + p.P(`return 0`) + p.Out() + p.P(`}`) + + //Generate Compare methods for oneof fields + m := proto.Clone(message.DescriptorProto).(*descriptor.DescriptorProto) + for _, field := range m.Field { + oneof := field.OneofIndex != nil + if !oneof { + continue + } + ccTypeName := p.OneOfTypeName(message, field) + p.P(`func (this *`, ccTypeName, `) Compare(that interface{}) int {`) + p.In() + + p.generateMsgNullAndTypeCheck(ccTypeName) + vanity.TurnOffNullableForNativeTypesWithoutDefaultsOnly(field) + p.generateField(file, message, field) + + p.P(`return 0`) + p.Out() + p.P(`}`) + } +} + +func init() { + generator.RegisterPlugin(NewPlugin()) +} diff --git a/vendor/github.com/gogo/protobuf/plugin/compare/comparetest.go b/vendor/github.com/gogo/protobuf/plugin/compare/comparetest.go new file mode 100644 index 00000000000..db71571791b --- /dev/null +++ b/vendor/github.com/gogo/protobuf/plugin/compare/comparetest.go @@ -0,0 +1,105 @@ +// Copyright (c) 2013, Vastech SA (PTY) LTD. 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 compare + +import ( + "github.com/gogo/protobuf/gogoproto" + "github.com/gogo/protobuf/plugin/testgen" + "github.com/gogo/protobuf/protoc-gen-gogo/generator" +) + +type test struct { + *generator.Generator +} + +func NewTest(g *generator.Generator) testgen.TestPlugin { + return &test{g} +} + +func (p *test) Generate(imports generator.PluginImports, file *generator.FileDescriptor) bool { + used := false + randPkg := imports.NewImport("math/rand") + timePkg := imports.NewImport("time") + testingPkg := imports.NewImport("testing") + protoPkg := imports.NewImport("github.com/gogo/protobuf/proto") + if !gogoproto.ImportsGoGoProto(file.FileDescriptorProto) { + protoPkg = imports.NewImport("github.com/golang/protobuf/proto") + } + for _, message := range file.Messages() { + ccTypeName := generator.CamelCaseSlice(message.TypeName()) + if !gogoproto.HasCompare(file.FileDescriptorProto, message.DescriptorProto) { + continue + } + if message.DescriptorProto.GetOptions().GetMapEntry() { + continue + } + + if gogoproto.HasTestGen(file.FileDescriptorProto, message.DescriptorProto) { + used = true + p.P(`func Test`, ccTypeName, `Compare(t *`, testingPkg.Use(), `.T) {`) + p.In() + p.P(`popr := `, randPkg.Use(), `.New(`, randPkg.Use(), `.NewSource(`, timePkg.Use(), `.Now().UnixNano()))`) + p.P(`p := NewPopulated`, ccTypeName, `(popr, false)`) + p.P(`data, err := `, protoPkg.Use(), `.Marshal(p)`) + p.P(`if err != nil {`) + p.In() + p.P(`panic(err)`) + p.Out() + p.P(`}`) + p.P(`msg := &`, ccTypeName, `{}`) + p.P(`if err := `, protoPkg.Use(), `.Unmarshal(data, msg); err != nil {`) + p.In() + p.P(`panic(err)`) + p.Out() + p.P(`}`) + p.P(`if c := p.Compare(msg); c != 0 {`) + p.In() + p.P(`t.Fatalf("%#v !Compare %#v, since %d", msg, p, c)`) + p.Out() + p.P(`}`) + p.P(`p2 := NewPopulated`, ccTypeName, `(popr, false)`) + p.P(`c := p.Compare(p2)`) + p.P(`c2 := p2.Compare(p)`) + p.P(`if c != (-1 * c2) {`) + p.In() + p.P(`t.Errorf("p.Compare(p2) = %d", c)`) + p.P(`t.Errorf("p2.Compare(p) = %d", c2)`) + p.P(`t.Errorf("p = %#v", p)`) + p.P(`t.Errorf("p2 = %#v", p2)`) + p.Out() + p.P(`}`) + p.Out() + p.P(`}`) + } + + } + return used +} + +func init() { + testgen.RegisterTestPlugin(NewTest) +} diff --git a/vendor/github.com/gogo/protobuf/plugin/description/description.go b/vendor/github.com/gogo/protobuf/plugin/description/description.go index 002e2ebc5cf..a2f08aa075e 100644 --- a/vendor/github.com/gogo/protobuf/plugin/description/description.go +++ b/vendor/github.com/gogo/protobuf/plugin/description/description.go @@ -74,15 +74,18 @@ This package is subject to change, since a use has not been figured out yet. package description import ( + "bytes" + "compress/gzip" "fmt" "github.com/gogo/protobuf/gogoproto" + "github.com/gogo/protobuf/proto" descriptor "github.com/gogo/protobuf/protoc-gen-gogo/descriptor" "github.com/gogo/protobuf/protoc-gen-gogo/generator" ) type plugin struct { *generator.Generator - used bool + generator.PluginImports } func NewPlugin() *plugin { @@ -98,8 +101,16 @@ func (p *plugin) Init(g *generator.Generator) { } func (p *plugin) Generate(file *generator.FileDescriptor) { - p.used = false + used := false localName := generator.FileName(file) + + p.PluginImports = generator.NewPluginImports(p.Generator) + descriptorPkg := p.NewImport("github.com/gogo/protobuf/protoc-gen-gogo/descriptor") + protoPkg := p.NewImport("github.com/gogo/protobuf/proto") + gzipPkg := p.NewImport("compress/gzip") + bytesPkg := p.NewImport("bytes") + ioutilPkg := p.NewImport("io/ioutil") + for _, message := range file.Messages() { if !gogoproto.HasDescription(file.FileDescriptorProto, message.DescriptorProto) { continue @@ -107,18 +118,18 @@ func (p *plugin) Generate(file *generator.FileDescriptor) { if message.DescriptorProto.GetOptions().GetMapEntry() { continue } - p.used = true + used = true ccTypeName := generator.CamelCaseSlice(message.TypeName()) - p.P(`func (this *`, ccTypeName, `) Description() (desc *descriptor.FileDescriptorSet) {`) + p.P(`func (this *`, ccTypeName, `) Description() (desc *`, descriptorPkg.Use(), `.FileDescriptorSet) {`) p.In() p.P(`return `, localName, `Description()`) p.Out() p.P(`}`) } - if p.used { + if used { - p.P(`func `, localName, `Description() (desc *descriptor.FileDescriptorSet) {`) + p.P(`func `, localName, `Description() (desc *`, descriptorPkg.Use(), `.FileDescriptorSet) {`) p.In() //Don't generate SourceCodeInfo, since it will create too much code. @@ -127,19 +138,59 @@ func (p *plugin) Generate(file *generator.FileDescriptor) { ss = append(ss, f.SourceCodeInfo) f.SourceCodeInfo = nil } - s := fmt.Sprintf("%#v", p.Generator.AllFiles()) + b, err := proto.Marshal(p.Generator.AllFiles()) + if err != nil { + panic(err) + } for i, f := range p.Generator.AllFiles().GetFile() { f.SourceCodeInfo = ss[i] } - p.P(`return `, s) + p.P(`d := &`, descriptorPkg.Use(), `.FileDescriptorSet{}`) + var buf bytes.Buffer + w, _ := gzip.NewWriterLevel(&buf, gzip.BestCompression) + w.Write(b) + w.Close() + b = buf.Bytes() + p.P("var gzipped = []byte{") + p.In() + p.P("// ", len(b), " bytes of a gzipped FileDescriptorSet") + for len(b) > 0 { + n := 16 + if n > len(b) { + n = len(b) + } + + s := "" + for _, c := range b[:n] { + s += fmt.Sprintf("0x%02x,", c) + } + p.P(s) + + b = b[n:] + } + p.Out() + p.P("}") + p.P(`r := `, bytesPkg.Use(), `.NewReader(gzipped)`) + p.P(`gzipr, err := `, gzipPkg.Use(), `.NewReader(r)`) + p.P(`if err != nil {`) + p.In() + p.P(`panic(err)`) + p.Out() + p.P(`}`) + p.P(`ungzipped, err := `, ioutilPkg.Use(), `.ReadAll(gzipr)`) + p.P(`if err != nil {`) + p.In() + p.P(`panic(err)`) + p.Out() + p.P(`}`) + p.P(`if err := `, protoPkg.Use(), `.Unmarshal(ungzipped, d); err != nil {`) + p.In() + p.P(`panic(err)`) + p.Out() + p.P(`}`) + p.P(`return d`) p.Out() p.P(`}`) - } -} - -func (this *plugin) GenerateImports(file *generator.FileDescriptor) { - if this.used { - this.P(`import "github.com/gogo/protobuf/protoc-gen-gogo/descriptor"`) } } diff --git a/vendor/github.com/gogo/protobuf/plugin/face/face.go b/vendor/github.com/gogo/protobuf/plugin/face/face.go index 06529a30f11..3c0c25b3ecb 100644 --- a/vendor/github.com/gogo/protobuf/plugin/face/face.go +++ b/vendor/github.com/gogo/protobuf/plugin/face/face.go @@ -200,7 +200,7 @@ func (p *plugin) Generate(file *generator.FileDescriptor) { for _, field := range message.Field { fieldname := p.GetFieldName(message, field) goTyp, _ := p.GoType(message, field) - if generator.IsMap(file.FileDescriptorProto, field) { + if p.IsMap(field) { m := p.GoMapType(nil, field) goTyp = m.GoType } diff --git a/vendor/github.com/gogo/protobuf/plugin/gostring/gostring.go b/vendor/github.com/gogo/protobuf/plugin/gostring/gostring.go index e13870ee7d1..0b355fb1eaf 100644 --- a/vendor/github.com/gogo/protobuf/plugin/gostring/gostring.go +++ b/vendor/github.com/gogo/protobuf/plugin/gostring/gostring.go @@ -177,7 +177,7 @@ func (p *gostring) Generate(file *generator.FileDescriptor) { p.P(`s = append(s, "`, fieldname, `: " + `, fmtPkg.Use(), `.Sprintf("%#v", this.`, fieldname, `) + ",\n")`) p.Out() p.P(`}`) - } else if generator.IsMap(file.FileDescriptorProto, field) { + } else if p.IsMap(field) { m := p.GoMapType(nil, field) mapgoTyp, keyField, keyAliasField := m.GoType, m.KeyField, m.KeyAliasField keysName := `keysFor` + fieldname diff --git a/vendor/github.com/gogo/protobuf/plugin/marshalto/marshalto.go b/vendor/github.com/gogo/protobuf/plugin/marshalto/marshalto.go index 52d36098fe0..27a4dfb6432 100644 --- a/vendor/github.com/gogo/protobuf/plugin/marshalto/marshalto.go +++ b/vendor/github.com/gogo/protobuf/plugin/marshalto/marshalto.go @@ -124,6 +124,10 @@ The user can also using the generated Size method to check that his reusable buf The generated tests and benchmarks will keep you safe and show that this is really a significant speed improvement. +An additional message-level option `stable_marshaler` (and the file-level +option `stable_marshaler_all`) exists which causes the generated marshalling +code to behave deterministically. Today, this only changes the serialization of +maps; they are serialized in sort order. */ package marshalto @@ -377,6 +381,7 @@ func (p *marshalto) generateField(proto3 bool, numGen NumGen, file *generator.Fi required := field.IsRequired() protoSizer := gogoproto.IsProtoSizer(file.FileDescriptorProto, message.DescriptorProto) + doNilCheck := gogoproto.NeedsNilCheck(proto3, field) if required && nullable { p.P(`if m.`, fieldname, `== nil {`) p.In() @@ -390,8 +395,7 @@ func (p *marshalto) generateField(proto3 bool, numGen NumGen, file *generator.Fi } else if repeated { p.P(`if len(m.`, fieldname, `) > 0 {`) p.In() - } else if ((!proto3 || field.IsMessage()) && nullable) || - (*field.Type == descriptor.FieldDescriptorProto_TYPE_BYTES && !gogoproto.IsCustomType(field)) { + } else if doNilCheck { p.P(`if m.`, fieldname, ` != nil {`) p.In() } @@ -822,15 +826,32 @@ func (p *marshalto) generateField(proto3 bool, numGen NumGen, file *generator.Fi case descriptor.FieldDescriptorProto_TYPE_GROUP: panic(fmt.Errorf("marshaler does not support group %v", fieldname)) case descriptor.FieldDescriptorProto_TYPE_MESSAGE: - if generator.IsMap(file.FileDescriptorProto, field) { + if p.IsMap(field) { m := p.GoMapType(nil, field) - _, keywire := p.GoType(nil, m.KeyField) + keygoTyp, keywire := p.GoType(nil, m.KeyField) + keygoAliasTyp, _ := p.GoType(nil, m.KeyAliasField) + // keys may not be pointers + keygoTyp = strings.Replace(keygoTyp, "*", "", 1) + keygoAliasTyp = strings.Replace(keygoAliasTyp, "*", "", 1) + keyCapTyp := generator.CamelCase(keygoTyp) valuegoTyp, valuewire := p.GoType(nil, m.ValueField) valuegoAliasTyp, _ := p.GoType(nil, m.ValueAliasField) nullable, valuegoTyp, valuegoAliasTyp = generator.GoMapValueTypes(field, m.ValueField, valuegoTyp, valuegoAliasTyp) keyKeySize := keySize(1, wireToType(keywire)) valueKeySize := keySize(2, wireToType(valuewire)) - p.P(`for k, _ := range m.`, fieldname, ` {`) + if gogoproto.IsStableMarshaler(file.FileDescriptorProto, message.DescriptorProto) { + keysName := `keysFor` + fieldname + p.P(keysName, ` := make([]`, keygoTyp, `, 0, len(m.`, fieldname, `))`) + p.P(`for k, _ := range m.`, fieldname, ` {`) + p.In() + p.P(keysName, ` = append(`, keysName, `, `, keygoTyp, `(k))`) + p.Out() + p.P(`}`) + p.P(p.sortKeysPkg.Use(), `.`, keyCapTyp, `s(`, keysName, `)`) + p.P(`for _, k := range `, keysName, ` {`) + } else { + p.P(`for k, _ := range m.`, fieldname, ` {`) + } p.In() p.encodeKey(fieldNumber, wireType) sum := []string{strconv.Itoa(keyKeySize)} @@ -858,7 +879,11 @@ func (p *marshalto) generateField(proto3 bool, numGen NumGen, file *generator.Fi descriptor.FieldDescriptorProto_TYPE_SINT64: sum = append(sum, `soz`+p.localName+`(uint64(k))`) } - p.P(`v := m.`, fieldname, `[k]`) + if gogoproto.IsStableMarshaler(file.FileDescriptorProto, message.DescriptorProto) { + p.P(`v := m.`, fieldname, `[`, keygoAliasTyp, `(k)]`) + } else { + p.P(`v := m.`, fieldname, `[k]`) + } accessor := `v` sum = append(sum, strconv.Itoa(valueKeySize)) switch m.ValueField.GetType() { @@ -1103,10 +1128,7 @@ func (p *marshalto) generateField(proto3 bool, numGen NumGen, file *generator.Fi default: panic("not implemented") } - if (required && nullable) || - ((!proto3 || field.IsMessage()) && nullable) || - repeated || - (*field.Type == descriptor.FieldDescriptorProto_TYPE_BYTES && !gogoproto.IsCustomType(field)) { + if (required && nullable) || repeated || doNilCheck { p.Out() p.P(`}`) } diff --git a/vendor/github.com/gogo/protobuf/plugin/populate/populate.go b/vendor/github.com/gogo/protobuf/plugin/populate/populate.go index 6594096f7f7..c95d9f28e87 100644 --- a/vendor/github.com/gogo/protobuf/plugin/populate/populate.go +++ b/vendor/github.com/gogo/protobuf/plugin/populate/populate.go @@ -248,7 +248,7 @@ func (p *plugin) GenerateField(file *generator.FileDescriptor, message *generato } if m.ValueField.IsMessage() || p.IsGroup(field) { s := `this.` + fieldname + `[` + keyval + `] = ` - goTypName := generator.GoTypeToName(valuegoTyp) + goTypName = generator.GoTypeToName(valuegoTyp) funcCall := getFuncCall(goTypName) if !nullable { funcCall = `*` + funcCall diff --git a/vendor/github.com/gogo/protobuf/plugin/size/size.go b/vendor/github.com/gogo/protobuf/plugin/size/size.go index 49b1f962cd3..7e507c31ab2 100644 --- a/vendor/github.com/gogo/protobuf/plugin/size/size.go +++ b/vendor/github.com/gogo/protobuf/plugin/size/size.go @@ -119,13 +119,14 @@ package size import ( "fmt" + "strconv" + "strings" + "github.com/gogo/protobuf/gogoproto" "github.com/gogo/protobuf/proto" descriptor "github.com/gogo/protobuf/protoc-gen-gogo/descriptor" "github.com/gogo/protobuf/protoc-gen-gogo/generator" "github.com/gogo/protobuf/vanity" - "strconv" - "strings" ) type size struct { @@ -201,10 +202,11 @@ func (p *size) generateField(proto3 bool, file *generator.FileDescriptor, messag fieldname := p.GetOneOfFieldName(message, field) nullable := gogoproto.IsNullable(field) repeated := field.IsRepeated() + doNilCheck := gogoproto.NeedsNilCheck(proto3, field) if repeated { p.P(`if len(m.`, fieldname, `) > 0 {`) p.In() - } else if ((!proto3 || field.IsMessage()) && nullable) || (!gogoproto.IsCustomType(field) && *field.Type == descriptor.FieldDescriptorProto_TYPE_BYTES) { + } else if doNilCheck { p.P(`if m.`, fieldname, ` != nil {`) p.In() } @@ -324,7 +326,7 @@ func (p *size) generateField(proto3 bool, file *generator.FileDescriptor, messag case descriptor.FieldDescriptorProto_TYPE_GROUP: panic(fmt.Errorf("size does not support group %v", fieldname)) case descriptor.FieldDescriptorProto_TYPE_MESSAGE: - if generator.IsMap(file.FileDescriptorProto, field) { + if p.IsMap(field) { m := p.GoMapType(nil, field) _, keywire := p.GoType(nil, m.KeyAliasField) valuegoTyp, _ := p.GoType(nil, m.ValueField) @@ -488,7 +490,7 @@ func (p *size) generateField(proto3 bool, file *generator.FileDescriptor, messag default: panic("not implemented") } - if ((!proto3 || field.IsMessage()) && nullable) || repeated || (!gogoproto.IsCustomType(field) && *field.Type == descriptor.FieldDescriptorProto_TYPE_BYTES) { + if repeated || doNilCheck { p.Out() p.P(`}`) } diff --git a/vendor/github.com/gogo/protobuf/plugin/stringer/stringer.go b/vendor/github.com/gogo/protobuf/plugin/stringer/stringer.go index b6360485caf..1bd17bbc331 100644 --- a/vendor/github.com/gogo/protobuf/plugin/stringer/stringer.go +++ b/vendor/github.com/gogo/protobuf/plugin/stringer/stringer.go @@ -146,7 +146,7 @@ func (p *stringer) Generate(file *generator.FileDescriptor) { p.Out() p.P(`}`) for _, field := range message.Field { - if !generator.IsMap(file.FileDescriptorProto, field) { + if !p.IsMap(field) { continue } fieldname := p.GetFieldName(message, field) @@ -197,7 +197,7 @@ func (p *stringer) Generate(file *generator.FileDescriptor) { oneofs[fieldname] = struct{}{} } p.P("`", fieldname, ":`", ` + `, fmtPkg.Use(), `.Sprintf("%v", this.`, fieldname, ") + `,", "`,") - } else if generator.IsMap(file.FileDescriptorProto, field) { + } else if p.IsMap(field) { mapName := `mapStringFor` + fieldname p.P("`", fieldname, ":`", ` + `, mapName, " + `,", "`,") } else if field.IsMessage() || p.IsGroup(field) { diff --git a/vendor/github.com/gogo/protobuf/plugin/unmarshal/unmarshal.go b/vendor/github.com/gogo/protobuf/plugin/unmarshal/unmarshal.go index 13285960988..e87f4726a40 100644 --- a/vendor/github.com/gogo/protobuf/plugin/unmarshal/unmarshal.go +++ b/vendor/github.com/gogo/protobuf/plugin/unmarshal/unmarshal.go @@ -676,7 +676,7 @@ func (p *unmarshal) field(file *generator.FileDescriptor, msg *generator.Descrip p.Out() p.P(`}`) p.P(`m.`, fieldname, ` = &`, p.OneOfTypeName(msg, field), `{v}`) - } else if generator.IsMap(file.FileDescriptorProto, field) { + } else if p.IsMap(field) { m := p.GoMapType(nil, field) keygoTyp, _ := p.GoType(nil, m.KeyField) @@ -1135,16 +1135,7 @@ func (p *unmarshal) Generate(file *generator.FileDescriptor) { p.P(`return `, p.ioPkg.Use(), `.ErrUnexpectedEOF`) p.Out() p.P(`}`) - if gogoproto.HasExtensionsMap(file.FileDescriptorProto, message.DescriptorProto) { - p.P(`if m.XXX_extensions == nil {`) - p.In() - p.P(`m.XXX_extensions = make(map[int32]`, protoPkg.Use(), `.Extension)`) - p.Out() - p.P(`}`) - p.P(`m.XXX_extensions[int32(fieldNum)] = `, protoPkg.Use(), `.NewExtension(data[iNdEx:iNdEx+skippy])`) - } else { - p.P(`m.XXX_extensions = append(m.XXX_extensions, data[iNdEx:iNdEx+skippy]...)`) - } + p.P(protoPkg.Use(), `.AppendExtension(m, int32(fieldNum), data[iNdEx:iNdEx+skippy])`) p.P(`iNdEx += skippy`) p.Out() p.P(`} else {`) diff --git a/vendor/github.com/gogo/protobuf/proto/decode.go b/vendor/github.com/gogo/protobuf/proto/decode.go index cb5b213f9b9..7b06266d14f 100644 --- a/vendor/github.com/gogo/protobuf/proto/decode.go +++ b/vendor/github.com/gogo/protobuf/proto/decode.go @@ -773,10 +773,11 @@ func (o *Buffer) dec_new_map(p *Properties, base structPointer) error { } } keyelem, valelem := keyptr.Elem(), valptr.Elem() - if !keyelem.IsValid() || !valelem.IsValid() { - // We did not decode the key or the value in the map entry. - // Either way, it's an invalid map entry. - return fmt.Errorf("proto: bad map data: missing key/val") + if !keyelem.IsValid() { + keyelem = reflect.Zero(p.mtype.Key()) + } + if !valelem.IsValid() { + valelem = reflect.Zero(p.mtype.Elem()) } v.SetMapIndex(keyelem, valelem) diff --git a/vendor/github.com/gogo/protobuf/proto/decode_gogo.go b/vendor/github.com/gogo/protobuf/proto/decode_gogo.go index 6a77aad7661..603dabec3f7 100644 --- a/vendor/github.com/gogo/protobuf/proto/decode_gogo.go +++ b/vendor/github.com/gogo/protobuf/proto/decode_gogo.go @@ -115,14 +115,8 @@ func setCustomType(base structPointer, f field, value interface{}) { oldHeader.Len = v.Len() oldHeader.Cap = v.Cap() default: - l := 1 size := reflect.TypeOf(value).Elem().Size() - if kind == reflect.Array { - l = reflect.TypeOf(value).Elem().Len() - size = reflect.TypeOf(value).Size() - } - total := int(size) * l - structPointer_Copy(toStructPointer(reflect.ValueOf(value)), structPointer_Add(base, f), total) + structPointer_Copy(toStructPointer(reflect.ValueOf(value)), structPointer_Add(base, f), int(size)) } } diff --git a/vendor/github.com/gogo/protobuf/proto/encode.go b/vendor/github.com/gogo/protobuf/proto/encode.go index 7321e1aae12..eb7e0474ef6 100644 --- a/vendor/github.com/gogo/protobuf/proto/encode.go +++ b/vendor/github.com/gogo/protobuf/proto/encode.go @@ -64,6 +64,10 @@ var ( // a struct with a repeated field containing a nil element. errRepeatedHasNil = errors.New("proto: repeated field has nil element") + // errOneofHasNil is the error returned if Marshal is called with + // a struct with a oneof field containing a nil element. + errOneofHasNil = errors.New("proto: oneof field has nil value") + // ErrNil is the error returned if Marshal is called with nil. ErrNil = errors.New("proto: Marshal called with nil") ) @@ -105,6 +109,11 @@ func (p *Buffer) EncodeVarint(x uint64) error { return nil } +// SizeVarint returns the varint encoding size of an integer. +func SizeVarint(x uint64) int { + return sizeVarint(x) +} + func sizeVarint(x uint64) (n int) { for { n++ @@ -1217,7 +1226,9 @@ func (o *Buffer) enc_struct(prop *StructProperties, base structPointer) error { // Do oneof fields. if prop.oneofMarshaler != nil { m := structPointer_Interface(base, prop.stype).(Message) - if err := prop.oneofMarshaler(m, o); err != nil { + if err := prop.oneofMarshaler(m, o); err == ErrNil { + return errOneofHasNil + } else if err != nil { return err } } @@ -1248,24 +1259,9 @@ func size_struct(prop *StructProperties, base structPointer) (n int) { } // Factor in any oneof fields. - // TODO: This could be faster and use less reflection. - if prop.oneofMarshaler != nil { - sv := reflect.ValueOf(structPointer_Interface(base, prop.stype)).Elem() - for i := 0; i < prop.stype.NumField(); i++ { - fv := sv.Field(i) - if fv.Kind() != reflect.Interface || fv.IsNil() { - continue - } - if prop.stype.Field(i).Tag.Get("protobuf_oneof") == "" { - continue - } - spv := fv.Elem() // interface -> *T - sv := spv.Elem() // *T -> T - sf := sv.Type().Field(0) // StructField inside T - var prop Properties - prop.Init(sf.Type, "whatever", sf.Tag.Get("protobuf"), &sf) - n += prop.size(&prop, toStructPointer(spv)) - } + if prop.oneofSizer != nil { + m := structPointer_Interface(base, prop.stype).(Message) + n += prop.oneofSizer(m) } return diff --git a/vendor/github.com/gogo/protobuf/proto/equal.go b/vendor/github.com/gogo/protobuf/proto/equal.go index cc3f2c95a7a..f5db1def3c2 100644 --- a/vendor/github.com/gogo/protobuf/proto/equal.go +++ b/vendor/github.com/gogo/protobuf/proto/equal.go @@ -50,7 +50,9 @@ Equality is defined in this way: are equal, and extensions sets are equal. - Two set scalar fields are equal iff their values are equal. If the fields are of a floating-point type, remember that - NaN != x for all x, including NaN. + NaN != x for all x, including NaN. If the message is defined + 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) @@ -88,6 +90,7 @@ func Equal(a, b Message) bool { // v1 and v2 are known to have the same type. func equalStruct(v1, v2 reflect.Value) bool { + sprop := GetProperties(v1.Type()) for i := 0; i < v1.NumField(); i++ { f := v1.Type().Field(i) if strings.HasPrefix(f.Name, "XXX_") { @@ -113,7 +116,7 @@ func equalStruct(v1, v2 reflect.Value) bool { } f1, f2 = f1.Elem(), f2.Elem() } - if !equalAny(f1, f2) { + if !equalAny(f1, f2, sprop.Prop[i]) { return false } } @@ -140,7 +143,8 @@ func equalStruct(v1, v2 reflect.Value) bool { } // v1 and v2 are known to have the same type. -func equalAny(v1, v2 reflect.Value) bool { +// prop may be nil. +func equalAny(v1, v2 reflect.Value, prop *Properties) bool { if v1.Type() == protoMessageType { m1, _ := v1.Interface().(Message) m2, _ := v2.Interface().(Message) @@ -163,7 +167,7 @@ func equalAny(v1, v2 reflect.Value) bool { if e1.Type() != e2.Type() { return false } - return equalAny(e1, e2) + return equalAny(e1, e2, nil) case reflect.Map: if v1.Len() != v2.Len() { return false @@ -174,16 +178,22 @@ func equalAny(v1, v2 reflect.Value) bool { // This key was not found in the second map. return false } - if !equalAny(v1.MapIndex(key), val2) { + if !equalAny(v1.MapIndex(key), val2, nil) { return false } } return true case reflect.Ptr: - return equalAny(v1.Elem(), v2.Elem()) + return equalAny(v1.Elem(), v2.Elem(), prop) case reflect.Slice: if v1.Type().Elem().Kind() == reflect.Uint8 { // short circuit: []byte + + // Edge case: if this is in a proto3 message, a zero length + // bytes field is considered the zero value. + if prop != nil && prop.proto3 && v1.Len() == 0 && v2.Len() == 0 { + return true + } if v1.IsNil() != v2.IsNil() { return false } @@ -194,7 +204,7 @@ func equalAny(v1, v2 reflect.Value) bool { return false } for i := 0; i < v1.Len(); i++ { - if !equalAny(v1.Index(i), v2.Index(i)) { + if !equalAny(v1.Index(i), v2.Index(i), prop) { return false } } @@ -229,7 +239,7 @@ func equalExtensions(base reflect.Type, em1, em2 map[int32]Extension) bool { if m1 != nil && m2 != nil { // Both are unencoded. - if !equalAny(reflect.ValueOf(m1), reflect.ValueOf(m2)) { + if !equalAny(reflect.ValueOf(m1), reflect.ValueOf(m2), nil) { return false } continue @@ -257,7 +267,7 @@ func equalExtensions(base reflect.Type, em1, em2 map[int32]Extension) bool { log.Printf("proto: badly encoded extension %d of %v: %v", extNum, base, err) return false } - if !equalAny(reflect.ValueOf(m1), reflect.ValueOf(m2)) { + if !equalAny(reflect.ValueOf(m1), reflect.ValueOf(m2), nil) { return false } } diff --git a/vendor/github.com/gogo/protobuf/proto/extensions.go b/vendor/github.com/gogo/protobuf/proto/extensions.go index 9a6374fdbde..6180347e393 100644 --- a/vendor/github.com/gogo/protobuf/proto/extensions.go +++ b/vendor/github.com/gogo/protobuf/proto/extensions.go @@ -403,7 +403,6 @@ func decodeExtension(b []byte, extension *ExtensionDesc) (interface{}, error) { o := NewBuffer(b) t := reflect.TypeOf(extension.ExtensionType) - rep := extension.repeated() props := extensionProperties(extension) @@ -425,7 +424,7 @@ func decodeExtension(b []byte, extension *ExtensionDesc) (interface{}, error) { return nil, err } - if !rep || o.index >= len(o.buf) { + if o.index >= len(o.buf) { break } } diff --git a/vendor/github.com/gogo/protobuf/proto/extensions_gogo.go b/vendor/github.com/gogo/protobuf/proto/extensions_gogo.go index bd55fb68b61..86b1fa2344f 100644 --- a/vendor/github.com/gogo/protobuf/proto/extensions_gogo.go +++ b/vendor/github.com/gogo/protobuf/proto/extensions_gogo.go @@ -56,6 +56,10 @@ func (this *Extension) Equal(that *Extension) bool { return bytes.Equal(this.enc, that.enc) } +func (this *Extension) Compare(that *Extension) int { + return bytes.Compare(this.enc, that.enc) +} + func SizeOfExtensionMap(m map[int32]Extension) (n int) { return sizeExtensionMap(m) } @@ -185,6 +189,17 @@ 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 { + ext := ee.GetExtensions() + *ext = append(*ext, buf...) + } +} + func (this Extension) GoString() string { if this.enc == nil { if err := encodeExtension(&this); err != nil { diff --git a/vendor/github.com/gogo/protobuf/proto/lib.go b/vendor/github.com/gogo/protobuf/proto/lib.go index 8ffa91a3e90..2e35ae2d2ac 100644 --- a/vendor/github.com/gogo/protobuf/proto/lib.go +++ b/vendor/github.com/gogo/protobuf/proto/lib.go @@ -70,6 +70,12 @@ for a protocol buffer variable v: with distinguished wrapper types for each possible field value. - Marshal and Unmarshal are functions to encode and decode the wire format. +When the .proto file specifies `syntax="proto3"`, there are some differences: + + - Non-repeated fields of non-message type are values instead of pointers. + - Getters are only generated for message and oneof fields. + - Enum types do not get an Enum method. + The simplest way to describe this is to see an example. Given file test.proto, containing @@ -229,6 +235,7 @@ To create and play with a Test object: test := &pb.Test{ Label: proto.String("hello"), Type: proto.Int32(17), + Reps: []int64{1, 2, 3}, Optionalgroup: &pb.Test_OptionalGroup{ RequiredField: proto.String("good bye"), }, @@ -441,7 +448,7 @@ func (p *Buffer) DebugPrint(s string, b []byte) { var u uint64 obuf := p.buf - index := p.index + sindex := p.index p.buf = b p.index = 0 depth := 0 @@ -536,7 +543,7 @@ out: fmt.Printf("\n") p.buf = obuf - p.index = index + p.index = sindex } // SetDefaults sets unset protocol buffer fields to their default values. @@ -881,3 +888,7 @@ func isProto3Zero(v reflect.Value) bool { } return false } + +// 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/properties.go b/vendor/github.com/gogo/protobuf/proto/properties.go index 4711057e2be..5e6a0b3ba71 100644 --- a/vendor/github.com/gogo/protobuf/proto/properties.go +++ b/vendor/github.com/gogo/protobuf/proto/properties.go @@ -96,6 +96,9 @@ type oneofMarshaler func(Message, *Buffer) error // A oneofUnmarshaler does the unmarshaling for a oneof field in a message. type oneofUnmarshaler func(Message, int, int, *Buffer) (bool, error) +// A oneofSizer does the sizing for all oneof fields in a message. +type oneofSizer func(Message) int + // tagMap is an optimization over map[int]int for typical protocol buffer // use-cases. Encoded protocol buffers are often in tag order with small tag // numbers. @@ -147,6 +150,7 @@ type StructProperties struct { oneofMarshaler oneofMarshaler oneofUnmarshaler oneofUnmarshaler + oneofSizer oneofSizer stype reflect.Type // OneofTypes contains information about the oneof fields in this message. @@ -174,6 +178,7 @@ func (sp *StructProperties) Swap(i, j int) { sp.order[i], sp.order[j] = sp.order type Properties struct { Name string // name of the field, for error messages OrigName string // original name before protocol compiler (always set) + JSONName string // name to use for JSON; determined by protoc Wire string WireType int Tag int @@ -233,8 +238,9 @@ func (p *Properties) String() string { if p.Packed { s += ",packed" } - if p.OrigName != p.Name { - s += ",name=" + p.OrigName + s += ",name=" + p.OrigName + if p.JSONName != p.OrigName { + s += ",json=" + p.JSONName } if p.proto3 { s += ",proto3" @@ -314,6 +320,8 @@ func (p *Properties) Parse(s string) { p.Packed = true case strings.HasPrefix(f, "name="): p.OrigName = f[5:] + case strings.HasPrefix(f, "json="): + p.JSONName = f[5:] case strings.HasPrefix(f, "enum="): p.Enum = f[5:] case f == "proto3": @@ -784,11 +792,11 @@ func getPropertiesLocked(t reflect.Type) *StructProperties { sort.Sort(prop) type oneofMessage interface { - XXX_OneofFuncs() (func(Message, *Buffer) error, func(Message, int, int, *Buffer) (bool, error), []interface{}) + XXX_OneofFuncs() (func(Message, *Buffer) error, func(Message, int, int, *Buffer) (bool, error), func(Message) int, []interface{}) } if om, ok := reflect.Zero(reflect.PtrTo(t)).Interface().(oneofMessage); isOneofMessage && ok { var oots []interface{} - prop.oneofMarshaler, prop.oneofUnmarshaler, oots = om.XXX_OneofFuncs() + prop.oneofMarshaler, prop.oneofUnmarshaler, prop.oneofSizer, oots = om.XXX_OneofFuncs() prop.stype = t // Interpret oneof metadata. diff --git a/vendor/github.com/gogo/protobuf/proto/text.go b/vendor/github.com/gogo/protobuf/proto/text.go index 7c9ae90f95d..b60be28ab08 100644 --- a/vendor/github.com/gogo/protobuf/proto/text.go +++ b/vendor/github.com/gogo/protobuf/proto/text.go @@ -335,7 +335,8 @@ func writeStruct(w *textWriter, sv reflect.Value) error { } inner := fv.Elem().Elem() // interface -> *T -> T tag := inner.Type().Field(0).Tag.Get("protobuf") - props.Parse(tag) // Overwrite the outer props. + props = new(Properties) // Overwrite the outer props var, but not its pointee. + props.Parse(tag) // Write the value in the oneof, not the oneof itself. fv = inner.Field(0) @@ -573,12 +574,12 @@ func writeUnknownStruct(w *textWriter, data []byte) (err error) { return ferr } if wire != WireStartGroup { - if err := w.WriteByte(':'); err != nil { + if err = w.WriteByte(':'); err != nil { return err } } if !w.compact || wire == WireStartGroup { - if err := w.WriteByte(' '); err != nil { + if err = w.WriteByte(' '); err != nil { return err } } @@ -727,7 +728,14 @@ func (w *textWriter) writeIndent() { w.complete = false } -func marshalText(w io.Writer, pb Message, compact bool) error { +// TextMarshaler is a configurable text format marshaler. +type TextMarshaler struct { + Compact bool // use compact text format (one line). +} + +// 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 { val := reflect.ValueOf(pb) if pb == nil || val.IsNil() { w.Write([]byte("")) @@ -742,7 +750,7 @@ func marshalText(w io.Writer, pb Message, compact bool) error { aw := &textWriter{ w: ww, complete: true, - compact: compact, + compact: m.Compact, } if tm, ok := pb.(encoding.TextMarshaler); ok { @@ -769,25 +777,29 @@ func marshalText(w io.Writer, pb Message, compact bool) error { return nil } +// Text is the same as Marshal, but returns the string directly. +func (m *TextMarshaler) Text(pb Message) string { + var buf bytes.Buffer + m.Marshal(&buf, pb) + return buf.String() +} + +var ( + defaultTextMarshaler = TextMarshaler{} + compactTextMarshaler = TextMarshaler{Compact: true} +) + +// TODO: consider removing some of the Marshal functions below. + // MarshalText writes a given protocol buffer in text format. // The only errors returned are from w. -func MarshalText(w io.Writer, pb Message) error { - return marshalText(w, pb, false) -} +func MarshalText(w io.Writer, pb Message) error { return defaultTextMarshaler.Marshal(w, pb) } // MarshalTextString is the same as MarshalText, but returns the string directly. -func MarshalTextString(pb Message) string { - var buf bytes.Buffer - marshalText(&buf, pb, false) - return buf.String() -} +func MarshalTextString(pb Message) string { return defaultTextMarshaler.Text(pb) } // CompactText writes a given protocol buffer in compact text format (one line). -func CompactText(w io.Writer, pb Message) error { return marshalText(w, pb, true) } +func CompactText(w io.Writer, pb Message) error { return compactTextMarshaler.Marshal(w, pb) } // CompactTextString is the same as CompactText, but returns the string directly. -func CompactTextString(pb Message) string { - var buf bytes.Buffer - marshalText(&buf, pb, true) - return buf.String() -} +func CompactTextString(pb Message) string { return compactTextMarshaler.Text(pb) } diff --git a/vendor/github.com/gogo/protobuf/proto/text_parser.go b/vendor/github.com/gogo/protobuf/proto/text_parser.go index f3909695ede..61b4bc8cc8f 100644 --- a/vendor/github.com/gogo/protobuf/proto/text_parser.go +++ b/vendor/github.com/gogo/protobuf/proto/text_parser.go @@ -124,6 +124,14 @@ func isWhitespace(c byte) bool { return false } +func isQuote(c byte) bool { + switch c { + case '"', '\'': + return true + } + return false +} + func (p *textParser) skipWhitespace() { i := 0 for i < len(p.s) && (isWhitespace(p.s[i]) || p.s[i] == '#') { @@ -338,13 +346,13 @@ func (p *textParser) next() *token { p.advance() if p.done { p.cur.value = "" - } else if len(p.cur.value) > 0 && p.cur.value[0] == '"' { + } else if len(p.cur.value) > 0 && isQuote(p.cur.value[0]) { // Look for multiple quoted strings separated by whitespace, // and concatenate them. cat := p.cur for { p.skipWhitespace() - if p.done || p.s[0] != '"' { + if p.done || !isQuote(p.s[0]) { break } p.advance() @@ -724,15 +732,15 @@ func (p *textParser) readAny(v reflect.Value, props *Properties) error { if err != nil { return err } - tok := p.next() - if tok.err != nil { - return tok.err + ntok := p.next() + if ntok.err != nil { + return ntok.err } - if tok.value == "]" { + if ntok.value == "]" { break } - if tok.value != "," { - return p.errorf("Expected ']' or ',' found %q", tok.value) + if ntok.value != "," { + return p.errorf("Expected ']' or ',' found %q", ntok.value) } } return nil diff --git a/vendor/github.com/gogo/protobuf/protoc-gen-gogo/descriptor/descriptor.pb.go b/vendor/github.com/gogo/protobuf/protoc-gen-gogo/descriptor/descriptor.pb.go index 0eeadb3f7e6..342d65a4256 100644 --- a/vendor/github.com/gogo/protobuf/protoc-gen-gogo/descriptor/descriptor.pb.go +++ b/vendor/github.com/gogo/protobuf/protoc-gen-gogo/descriptor/descriptor.pb.go @@ -39,6 +39,10 @@ var _ = proto.Marshal var _ = fmt.Errorf 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.GoGoProtoPackageIsVersion1 + type FieldDescriptorProto_Type int32 const ( @@ -126,6 +130,9 @@ func (x *FieldDescriptorProto_Type) UnmarshalJSON(data []byte) error { *x = FieldDescriptorProto_Type(value) return nil } +func (FieldDescriptorProto_Type) EnumDescriptor() ([]byte, []int) { + return fileDescriptorDescriptor, []int{3, 0} +} type FieldDescriptorProto_Label int32 @@ -163,6 +170,9 @@ func (x *FieldDescriptorProto_Label) UnmarshalJSON(data []byte) error { *x = FieldDescriptorProto_Label(value) return nil } +func (FieldDescriptorProto_Label) EnumDescriptor() ([]byte, []int) { + return fileDescriptorDescriptor, []int{3, 1} +} // Generated classes can be optimized for speed or code size. type FileOptions_OptimizeMode int32 @@ -201,6 +211,9 @@ func (x *FileOptions_OptimizeMode) UnmarshalJSON(data []byte) error { *x = FileOptions_OptimizeMode(value) return nil } +func (FileOptions_OptimizeMode) EnumDescriptor() ([]byte, []int) { + return fileDescriptorDescriptor, []int{9, 0} +} type FieldOptions_CType int32 @@ -238,6 +251,9 @@ func (x *FieldOptions_CType) UnmarshalJSON(data []byte) error { *x = FieldOptions_CType(value) return nil } +func (FieldOptions_CType) EnumDescriptor() ([]byte, []int) { + return fileDescriptorDescriptor, []int{11, 0} +} type FieldOptions_JSType int32 @@ -277,6 +293,9 @@ func (x *FieldOptions_JSType) UnmarshalJSON(data []byte) error { *x = FieldOptions_JSType(value) return nil } +func (FieldOptions_JSType) EnumDescriptor() ([]byte, []int) { + return fileDescriptorDescriptor, []int{11, 1} +} // The protocol compiler can output a FileDescriptorSet containing the .proto // files it parses. @@ -285,9 +304,10 @@ type FileDescriptorSet struct { XXX_unrecognized []byte `json:"-"` } -func (m *FileDescriptorSet) Reset() { *m = FileDescriptorSet{} } -func (m *FileDescriptorSet) String() string { return proto.CompactTextString(m) } -func (*FileDescriptorSet) ProtoMessage() {} +func (m *FileDescriptorSet) Reset() { *m = FileDescriptorSet{} } +func (m *FileDescriptorSet) String() string { return proto.CompactTextString(m) } +func (*FileDescriptorSet) ProtoMessage() {} +func (*FileDescriptorSet) Descriptor() ([]byte, []int) { return fileDescriptorDescriptor, []int{0} } func (m *FileDescriptorSet) GetFile() []*FileDescriptorProto { if m != nil { @@ -303,13 +323,13 @@ type FileDescriptorProto struct { // Names of files imported by this file. Dependency []string `protobuf:"bytes,3,rep,name=dependency" json:"dependency,omitempty"` // Indexes of the public imported files in the dependency list above. - PublicDependency []int32 `protobuf:"varint,10,rep,name=public_dependency" json:"public_dependency,omitempty"` + PublicDependency []int32 `protobuf:"varint,10,rep,name=public_dependency,json=publicDependency" json:"public_dependency,omitempty"` // Indexes of the weak imported files in the dependency list. // For Google-internal migration only. Do not use. - WeakDependency []int32 `protobuf:"varint,11,rep,name=weak_dependency" json:"weak_dependency,omitempty"` + WeakDependency []int32 `protobuf:"varint,11,rep,name=weak_dependency,json=weakDependency" json:"weak_dependency,omitempty"` // All top-level definitions in this file. - MessageType []*DescriptorProto `protobuf:"bytes,4,rep,name=message_type" json:"message_type,omitempty"` - EnumType []*EnumDescriptorProto `protobuf:"bytes,5,rep,name=enum_type" json:"enum_type,omitempty"` + MessageType []*DescriptorProto `protobuf:"bytes,4,rep,name=message_type,json=messageType" json:"message_type,omitempty"` + EnumType []*EnumDescriptorProto `protobuf:"bytes,5,rep,name=enum_type,json=enumType" json:"enum_type,omitempty"` Service []*ServiceDescriptorProto `protobuf:"bytes,6,rep,name=service" json:"service,omitempty"` Extension []*FieldDescriptorProto `protobuf:"bytes,7,rep,name=extension" json:"extension,omitempty"` Options *FileOptions `protobuf:"bytes,8,opt,name=options" json:"options,omitempty"` @@ -317,16 +337,17 @@ type FileDescriptorProto struct { // You may safely remove this entire field without harming runtime // functionality of the descriptors -- the information is needed only by // development tools. - SourceCodeInfo *SourceCodeInfo `protobuf:"bytes,9,opt,name=source_code_info" json:"source_code_info,omitempty"` + SourceCodeInfo *SourceCodeInfo `protobuf:"bytes,9,opt,name=source_code_info,json=sourceCodeInfo" json:"source_code_info,omitempty"` // The syntax of the proto file. // The supported values are "proto2" and "proto3". Syntax *string `protobuf:"bytes,12,opt,name=syntax" json:"syntax,omitempty"` XXX_unrecognized []byte `json:"-"` } -func (m *FileDescriptorProto) Reset() { *m = FileDescriptorProto{} } -func (m *FileDescriptorProto) String() string { return proto.CompactTextString(m) } -func (*FileDescriptorProto) ProtoMessage() {} +func (m *FileDescriptorProto) Reset() { *m = FileDescriptorProto{} } +func (m *FileDescriptorProto) String() string { return proto.CompactTextString(m) } +func (*FileDescriptorProto) ProtoMessage() {} +func (*FileDescriptorProto) Descriptor() ([]byte, []int) { return fileDescriptorDescriptor, []int{1} } func (m *FileDescriptorProto) GetName() string { if m != nil && m.Name != nil { @@ -417,21 +438,22 @@ type DescriptorProto struct { Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` Field []*FieldDescriptorProto `protobuf:"bytes,2,rep,name=field" json:"field,omitempty"` Extension []*FieldDescriptorProto `protobuf:"bytes,6,rep,name=extension" json:"extension,omitempty"` - NestedType []*DescriptorProto `protobuf:"bytes,3,rep,name=nested_type" json:"nested_type,omitempty"` - EnumType []*EnumDescriptorProto `protobuf:"bytes,4,rep,name=enum_type" json:"enum_type,omitempty"` - ExtensionRange []*DescriptorProto_ExtensionRange `protobuf:"bytes,5,rep,name=extension_range" json:"extension_range,omitempty"` - OneofDecl []*OneofDescriptorProto `protobuf:"bytes,8,rep,name=oneof_decl" json:"oneof_decl,omitempty"` + NestedType []*DescriptorProto `protobuf:"bytes,3,rep,name=nested_type,json=nestedType" json:"nested_type,omitempty"` + EnumType []*EnumDescriptorProto `protobuf:"bytes,4,rep,name=enum_type,json=enumType" json:"enum_type,omitempty"` + ExtensionRange []*DescriptorProto_ExtensionRange `protobuf:"bytes,5,rep,name=extension_range,json=extensionRange" json:"extension_range,omitempty"` + OneofDecl []*OneofDescriptorProto `protobuf:"bytes,8,rep,name=oneof_decl,json=oneofDecl" json:"oneof_decl,omitempty"` Options *MessageOptions `protobuf:"bytes,7,opt,name=options" json:"options,omitempty"` - ReservedRange []*DescriptorProto_ReservedRange `protobuf:"bytes,9,rep,name=reserved_range" json:"reserved_range,omitempty"` + ReservedRange []*DescriptorProto_ReservedRange `protobuf:"bytes,9,rep,name=reserved_range,json=reservedRange" json:"reserved_range,omitempty"` // Reserved field names, which may not be used by fields in the same message. // A given name may only be reserved once. - ReservedName []string `protobuf:"bytes,10,rep,name=reserved_name" json:"reserved_name,omitempty"` + ReservedName []string `protobuf:"bytes,10,rep,name=reserved_name,json=reservedName" json:"reserved_name,omitempty"` XXX_unrecognized []byte `json:"-"` } -func (m *DescriptorProto) Reset() { *m = DescriptorProto{} } -func (m *DescriptorProto) String() string { return proto.CompactTextString(m) } -func (*DescriptorProto) ProtoMessage() {} +func (m *DescriptorProto) Reset() { *m = DescriptorProto{} } +func (m *DescriptorProto) String() string { return proto.CompactTextString(m) } +func (*DescriptorProto) ProtoMessage() {} +func (*DescriptorProto) Descriptor() ([]byte, []int) { return fileDescriptorDescriptor, []int{2} } func (m *DescriptorProto) GetName() string { if m != nil && m.Name != nil { @@ -512,6 +534,9 @@ type DescriptorProto_ExtensionRange struct { func (m *DescriptorProto_ExtensionRange) Reset() { *m = DescriptorProto_ExtensionRange{} } func (m *DescriptorProto_ExtensionRange) String() string { return proto.CompactTextString(m) } func (*DescriptorProto_ExtensionRange) ProtoMessage() {} +func (*DescriptorProto_ExtensionRange) Descriptor() ([]byte, []int) { + return fileDescriptorDescriptor, []int{2, 0} +} func (m *DescriptorProto_ExtensionRange) GetStart() int32 { if m != nil && m.Start != nil { @@ -539,6 +564,9 @@ type DescriptorProto_ReservedRange struct { func (m *DescriptorProto_ReservedRange) Reset() { *m = DescriptorProto_ReservedRange{} } func (m *DescriptorProto_ReservedRange) String() string { return proto.CompactTextString(m) } func (*DescriptorProto_ReservedRange) ProtoMessage() {} +func (*DescriptorProto_ReservedRange) Descriptor() ([]byte, []int) { + return fileDescriptorDescriptor, []int{2, 1} +} func (m *DescriptorProto_ReservedRange) GetStart() int32 { if m != nil && m.Start != nil { @@ -567,7 +595,7 @@ type FieldDescriptorProto struct { // rules are used to find the type (i.e. first the nested types within this // message are searched, then within the parent, on up to the root // namespace). - TypeName *string `protobuf:"bytes,6,opt,name=type_name" json:"type_name,omitempty"` + TypeName *string `protobuf:"bytes,6,opt,name=type_name,json=typeName" json:"type_name,omitempty"` // For extensions, this is the name of the type being extended. It is // resolved in the same manner as type_name. Extendee *string `protobuf:"bytes,2,opt,name=extendee" json:"extendee,omitempty"` @@ -576,22 +604,23 @@ type FieldDescriptorProto struct { // For strings, contains the default text contents (not escaped in any way). // For bytes, contains the C escaped value. All bytes >= 128 are escaped. // TODO(kenton): Base-64 encode? - DefaultValue *string `protobuf:"bytes,7,opt,name=default_value" json:"default_value,omitempty"` + DefaultValue *string `protobuf:"bytes,7,opt,name=default_value,json=defaultValue" json:"default_value,omitempty"` // If set, gives the index of a oneof in the containing type's oneof_decl // list. This field is a member of that oneof. - OneofIndex *int32 `protobuf:"varint,9,opt,name=oneof_index" json:"oneof_index,omitempty"` + OneofIndex *int32 `protobuf:"varint,9,opt,name=oneof_index,json=oneofIndex" json:"oneof_index,omitempty"` // JSON name of this field. The value is set by protocol compiler. If the // user has set a "json_name" option on this field, that option's value // will be used. Otherwise, it's deduced from the field's name by converting // it to camelCase. - JsonName *string `protobuf:"bytes,10,opt,name=json_name" json:"json_name,omitempty"` + JsonName *string `protobuf:"bytes,10,opt,name=json_name,json=jsonName" json:"json_name,omitempty"` Options *FieldOptions `protobuf:"bytes,8,opt,name=options" json:"options,omitempty"` XXX_unrecognized []byte `json:"-"` } -func (m *FieldDescriptorProto) Reset() { *m = FieldDescriptorProto{} } -func (m *FieldDescriptorProto) String() string { return proto.CompactTextString(m) } -func (*FieldDescriptorProto) ProtoMessage() {} +func (m *FieldDescriptorProto) Reset() { *m = FieldDescriptorProto{} } +func (m *FieldDescriptorProto) String() string { return proto.CompactTextString(m) } +func (*FieldDescriptorProto) ProtoMessage() {} +func (*FieldDescriptorProto) Descriptor() ([]byte, []int) { return fileDescriptorDescriptor, []int{3} } func (m *FieldDescriptorProto) GetName() string { if m != nil && m.Name != nil { @@ -669,9 +698,10 @@ type OneofDescriptorProto struct { XXX_unrecognized []byte `json:"-"` } -func (m *OneofDescriptorProto) Reset() { *m = OneofDescriptorProto{} } -func (m *OneofDescriptorProto) String() string { return proto.CompactTextString(m) } -func (*OneofDescriptorProto) ProtoMessage() {} +func (m *OneofDescriptorProto) Reset() { *m = OneofDescriptorProto{} } +func (m *OneofDescriptorProto) String() string { return proto.CompactTextString(m) } +func (*OneofDescriptorProto) ProtoMessage() {} +func (*OneofDescriptorProto) Descriptor() ([]byte, []int) { return fileDescriptorDescriptor, []int{4} } func (m *OneofDescriptorProto) GetName() string { if m != nil && m.Name != nil { @@ -688,9 +718,10 @@ type EnumDescriptorProto struct { XXX_unrecognized []byte `json:"-"` } -func (m *EnumDescriptorProto) Reset() { *m = EnumDescriptorProto{} } -func (m *EnumDescriptorProto) String() string { return proto.CompactTextString(m) } -func (*EnumDescriptorProto) ProtoMessage() {} +func (m *EnumDescriptorProto) Reset() { *m = EnumDescriptorProto{} } +func (m *EnumDescriptorProto) String() string { return proto.CompactTextString(m) } +func (*EnumDescriptorProto) ProtoMessage() {} +func (*EnumDescriptorProto) Descriptor() ([]byte, []int) { return fileDescriptorDescriptor, []int{5} } func (m *EnumDescriptorProto) GetName() string { if m != nil && m.Name != nil { @@ -724,6 +755,9 @@ type EnumValueDescriptorProto struct { func (m *EnumValueDescriptorProto) Reset() { *m = EnumValueDescriptorProto{} } func (m *EnumValueDescriptorProto) String() string { return proto.CompactTextString(m) } func (*EnumValueDescriptorProto) ProtoMessage() {} +func (*EnumValueDescriptorProto) Descriptor() ([]byte, []int) { + return fileDescriptorDescriptor, []int{6} +} func (m *EnumValueDescriptorProto) GetName() string { if m != nil && m.Name != nil { @@ -754,9 +788,10 @@ type ServiceDescriptorProto struct { XXX_unrecognized []byte `json:"-"` } -func (m *ServiceDescriptorProto) Reset() { *m = ServiceDescriptorProto{} } -func (m *ServiceDescriptorProto) String() string { return proto.CompactTextString(m) } -func (*ServiceDescriptorProto) ProtoMessage() {} +func (m *ServiceDescriptorProto) Reset() { *m = ServiceDescriptorProto{} } +func (m *ServiceDescriptorProto) String() string { return proto.CompactTextString(m) } +func (*ServiceDescriptorProto) ProtoMessage() {} +func (*ServiceDescriptorProto) Descriptor() ([]byte, []int) { return fileDescriptorDescriptor, []int{7} } func (m *ServiceDescriptorProto) GetName() string { if m != nil && m.Name != nil { @@ -784,19 +819,20 @@ type MethodDescriptorProto struct { Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` // Input and output type names. These are resolved in the same way as // FieldDescriptorProto.type_name, but must refer to a message type. - InputType *string `protobuf:"bytes,2,opt,name=input_type" json:"input_type,omitempty"` - OutputType *string `protobuf:"bytes,3,opt,name=output_type" json:"output_type,omitempty"` + InputType *string `protobuf:"bytes,2,opt,name=input_type,json=inputType" json:"input_type,omitempty"` + OutputType *string `protobuf:"bytes,3,opt,name=output_type,json=outputType" json:"output_type,omitempty"` Options *MethodOptions `protobuf:"bytes,4,opt,name=options" json:"options,omitempty"` // Identifies if client streams multiple client messages - ClientStreaming *bool `protobuf:"varint,5,opt,name=client_streaming,def=0" json:"client_streaming,omitempty"` + ClientStreaming *bool `protobuf:"varint,5,opt,name=client_streaming,json=clientStreaming,def=0" json:"client_streaming,omitempty"` // Identifies if server streams multiple server messages - ServerStreaming *bool `protobuf:"varint,6,opt,name=server_streaming,def=0" json:"server_streaming,omitempty"` + ServerStreaming *bool `protobuf:"varint,6,opt,name=server_streaming,json=serverStreaming,def=0" json:"server_streaming,omitempty"` XXX_unrecognized []byte `json:"-"` } -func (m *MethodDescriptorProto) Reset() { *m = MethodDescriptorProto{} } -func (m *MethodDescriptorProto) String() string { return proto.CompactTextString(m) } -func (*MethodDescriptorProto) ProtoMessage() {} +func (m *MethodDescriptorProto) Reset() { *m = MethodDescriptorProto{} } +func (m *MethodDescriptorProto) String() string { return proto.CompactTextString(m) } +func (*MethodDescriptorProto) ProtoMessage() {} +func (*MethodDescriptorProto) Descriptor() ([]byte, []int) { return fileDescriptorDescriptor, []int{8} } const Default_MethodDescriptorProto_ClientStreaming bool = false const Default_MethodDescriptorProto_ServerStreaming bool = false @@ -848,20 +884,20 @@ type FileOptions struct { // placed. By default, the proto package is used, but this is often // inappropriate because proto packages do not normally start with backwards // domain names. - JavaPackage *string `protobuf:"bytes,1,opt,name=java_package" json:"java_package,omitempty"` + JavaPackage *string `protobuf:"bytes,1,opt,name=java_package,json=javaPackage" json:"java_package,omitempty"` // If set, all the classes from the .proto file are wrapped in a single // outer class with the given name. This applies to both Proto1 // (equivalent to the old "--one_java_file" option) and Proto2 (where // a .proto always translates to a single class, but you may want to // explicitly choose the class name). - JavaOuterClassname *string `protobuf:"bytes,8,opt,name=java_outer_classname" json:"java_outer_classname,omitempty"` + JavaOuterClassname *string `protobuf:"bytes,8,opt,name=java_outer_classname,json=javaOuterClassname" json:"java_outer_classname,omitempty"` // If set true, then the Java code generator will generate a separate .java // file for each top-level message, enum, and service defined in the .proto // file. Thus, these types will *not* be nested inside the outer class // named by java_outer_classname. However, the outer class will still be // generated to contain the file's getDescriptor() method as well as any // top-level extensions defined in the file. - JavaMultipleFiles *bool `protobuf:"varint,10,opt,name=java_multiple_files,def=0" json:"java_multiple_files,omitempty"` + JavaMultipleFiles *bool `protobuf:"varint,10,opt,name=java_multiple_files,json=javaMultipleFiles,def=0" json:"java_multiple_files,omitempty"` // If set true, then the Java code generator will generate equals() and // hashCode() methods for all messages defined in the .proto file. // This increases generated code size, potentially substantially for large @@ -874,21 +910,21 @@ type FileOptions struct { // the generated methods compute their results based on field values rather // than object identity. (Implementations should not assume that hashcodes // will be consistent across runtimes or versions of the protocol compiler.) - JavaGenerateEqualsAndHash *bool `protobuf:"varint,20,opt,name=java_generate_equals_and_hash,def=0" json:"java_generate_equals_and_hash,omitempty"` + JavaGenerateEqualsAndHash *bool `protobuf:"varint,20,opt,name=java_generate_equals_and_hash,json=javaGenerateEqualsAndHash,def=0" json:"java_generate_equals_and_hash,omitempty"` // If set true, then the Java2 code generator will generate code that // throws an exception whenever an attempt is made to assign a non-UTF-8 // byte sequence to a string field. // Message reflection will do the same. // However, an extension field still accepts non-UTF-8 byte sequences. // This option has no effect on when used with the lite runtime. - JavaStringCheckUtf8 *bool `protobuf:"varint,27,opt,name=java_string_check_utf8,def=0" json:"java_string_check_utf8,omitempty"` - OptimizeFor *FileOptions_OptimizeMode `protobuf:"varint,9,opt,name=optimize_for,enum=google.protobuf.FileOptions_OptimizeMode,def=1" json:"optimize_for,omitempty"` + JavaStringCheckUtf8 *bool `protobuf:"varint,27,opt,name=java_string_check_utf8,json=javaStringCheckUtf8,def=0" json:"java_string_check_utf8,omitempty"` + OptimizeFor *FileOptions_OptimizeMode `protobuf:"varint,9,opt,name=optimize_for,json=optimizeFor,enum=google.protobuf.FileOptions_OptimizeMode,def=1" json:"optimize_for,omitempty"` // Sets the Go package where structs generated from this .proto will be // placed. If omitted, the Go package will be derived from the following: // - The basename of the package import path, if provided. // - Otherwise, the package statement in the .proto file, if present. // - Otherwise, the basename of the .proto file, without extension. - GoPackage *string `protobuf:"bytes,11,opt,name=go_package" json:"go_package,omitempty"` + GoPackage *string `protobuf:"bytes,11,opt,name=go_package,json=goPackage" json:"go_package,omitempty"` // Should generic services be generated in each language? "Generic" services // are not specific to any particular RPC system. They are generated by the // main code generators in each language (without additional plugins). @@ -899,9 +935,9 @@ type FileOptions struct { // that generate code specific to your particular RPC system. Therefore, // these default to false. Old code which depends on generic services should // explicitly set them to true. - CcGenericServices *bool `protobuf:"varint,16,opt,name=cc_generic_services,def=0" json:"cc_generic_services,omitempty"` - JavaGenericServices *bool `protobuf:"varint,17,opt,name=java_generic_services,def=0" json:"java_generic_services,omitempty"` - PyGenericServices *bool `protobuf:"varint,18,opt,name=py_generic_services,def=0" json:"py_generic_services,omitempty"` + CcGenericServices *bool `protobuf:"varint,16,opt,name=cc_generic_services,json=ccGenericServices,def=0" json:"cc_generic_services,omitempty"` + JavaGenericServices *bool `protobuf:"varint,17,opt,name=java_generic_services,json=javaGenericServices,def=0" json:"java_generic_services,omitempty"` + PyGenericServices *bool `protobuf:"varint,18,opt,name=py_generic_services,json=pyGenericServices,def=0" json:"py_generic_services,omitempty"` // Is this file deprecated? // Depending on the target platform, this can emit Deprecated annotations // for everything in the file, or it will be completely ignored; in the very @@ -909,24 +945,25 @@ type FileOptions struct { Deprecated *bool `protobuf:"varint,23,opt,name=deprecated,def=0" json:"deprecated,omitempty"` // Enables the use of arenas for the proto messages in this file. This applies // only to generated classes for C++. - CcEnableArenas *bool `protobuf:"varint,31,opt,name=cc_enable_arenas,def=0" json:"cc_enable_arenas,omitempty"` + CcEnableArenas *bool `protobuf:"varint,31,opt,name=cc_enable_arenas,json=ccEnableArenas,def=0" json:"cc_enable_arenas,omitempty"` // Sets the objective c class prefix which is prepended to all objective c // generated classes from this .proto. There is no default. - ObjcClassPrefix *string `protobuf:"bytes,36,opt,name=objc_class_prefix" json:"objc_class_prefix,omitempty"` + ObjcClassPrefix *string `protobuf:"bytes,36,opt,name=objc_class_prefix,json=objcClassPrefix" json:"objc_class_prefix,omitempty"` // Namespace for generated classes; defaults to the package. - CsharpNamespace *string `protobuf:"bytes,37,opt,name=csharp_namespace" json:"csharp_namespace,omitempty"` + CsharpNamespace *string `protobuf:"bytes,37,opt,name=csharp_namespace,json=csharpNamespace" json:"csharp_namespace,omitempty"` // Whether the nano proto compiler should generate in the deprecated non-nano // suffixed package. - JavananoUseDeprecatedPackage *bool `protobuf:"varint,38,opt,name=javanano_use_deprecated_package" json:"javanano_use_deprecated_package,omitempty"` + JavananoUseDeprecatedPackage *bool `protobuf:"varint,38,opt,name=javanano_use_deprecated_package,json=javananoUseDeprecatedPackage" json:"javanano_use_deprecated_package,omitempty"` // The parser stores options it doesn't recognize here. See above. - UninterpretedOption []*UninterpretedOption `protobuf:"bytes,999,rep,name=uninterpreted_option" json:"uninterpreted_option,omitempty"` + UninterpretedOption []*UninterpretedOption `protobuf:"bytes,999,rep,name=uninterpreted_option,json=uninterpretedOption" json:"uninterpreted_option,omitempty"` XXX_extensions map[int32]proto.Extension `json:"-"` XXX_unrecognized []byte `json:"-"` } -func (m *FileOptions) Reset() { *m = FileOptions{} } -func (m *FileOptions) String() string { return proto.CompactTextString(m) } -func (*FileOptions) ProtoMessage() {} +func (m *FileOptions) Reset() { *m = FileOptions{} } +func (m *FileOptions) String() string { return proto.CompactTextString(m) } +func (*FileOptions) ProtoMessage() {} +func (*FileOptions) Descriptor() ([]byte, []int) { return fileDescriptorDescriptor, []int{9} } var extRange_FileOptions = []proto.ExtensionRange{ {1000, 536870911}, @@ -1083,11 +1120,11 @@ type MessageOptions struct { // // Because this is an option, the above two restrictions are not enforced by // the protocol compiler. - MessageSetWireFormat *bool `protobuf:"varint,1,opt,name=message_set_wire_format,def=0" json:"message_set_wire_format,omitempty"` + MessageSetWireFormat *bool `protobuf:"varint,1,opt,name=message_set_wire_format,json=messageSetWireFormat,def=0" json:"message_set_wire_format,omitempty"` // Disables the generation of the standard "descriptor()" accessor, which can // conflict with a field of the same name. This is meant to make migration // from proto1 easier; new code should avoid fields named "descriptor". - NoStandardDescriptorAccessor *bool `protobuf:"varint,2,opt,name=no_standard_descriptor_accessor,def=0" json:"no_standard_descriptor_accessor,omitempty"` + NoStandardDescriptorAccessor *bool `protobuf:"varint,2,opt,name=no_standard_descriptor_accessor,json=noStandardDescriptorAccessor,def=0" json:"no_standard_descriptor_accessor,omitempty"` // Is this message deprecated? // Depending on the target platform, this can emit Deprecated annotations // for the message, or it will be completely ignored; in the very least, @@ -1114,16 +1151,17 @@ type MessageOptions struct { // NOTE: Do not set the option in .proto files. Always use the maps syntax // instead. The option should only be implicitly set by the proto compiler // parser. - MapEntry *bool `protobuf:"varint,7,opt,name=map_entry" json:"map_entry,omitempty"` + MapEntry *bool `protobuf:"varint,7,opt,name=map_entry,json=mapEntry" json:"map_entry,omitempty"` // The parser stores options it doesn't recognize here. See above. - UninterpretedOption []*UninterpretedOption `protobuf:"bytes,999,rep,name=uninterpreted_option" json:"uninterpreted_option,omitempty"` + UninterpretedOption []*UninterpretedOption `protobuf:"bytes,999,rep,name=uninterpreted_option,json=uninterpretedOption" json:"uninterpreted_option,omitempty"` XXX_extensions map[int32]proto.Extension `json:"-"` XXX_unrecognized []byte `json:"-"` } -func (m *MessageOptions) Reset() { *m = MessageOptions{} } -func (m *MessageOptions) String() string { return proto.CompactTextString(m) } -func (*MessageOptions) ProtoMessage() {} +func (m *MessageOptions) Reset() { *m = MessageOptions{} } +func (m *MessageOptions) String() string { return proto.CompactTextString(m) } +func (*MessageOptions) ProtoMessage() {} +func (*MessageOptions) Descriptor() ([]byte, []int) { return fileDescriptorDescriptor, []int{10} } var extRange_MessageOptions = []proto.ExtensionRange{ {1000, 536870911}, @@ -1237,14 +1275,15 @@ type FieldOptions struct { // For Google-internal migration only. Do not use. Weak *bool `protobuf:"varint,10,opt,name=weak,def=0" json:"weak,omitempty"` // The parser stores options it doesn't recognize here. See above. - UninterpretedOption []*UninterpretedOption `protobuf:"bytes,999,rep,name=uninterpreted_option" json:"uninterpreted_option,omitempty"` + UninterpretedOption []*UninterpretedOption `protobuf:"bytes,999,rep,name=uninterpreted_option,json=uninterpretedOption" json:"uninterpreted_option,omitempty"` XXX_extensions map[int32]proto.Extension `json:"-"` XXX_unrecognized []byte `json:"-"` } -func (m *FieldOptions) Reset() { *m = FieldOptions{} } -func (m *FieldOptions) String() string { return proto.CompactTextString(m) } -func (*FieldOptions) ProtoMessage() {} +func (m *FieldOptions) Reset() { *m = FieldOptions{} } +func (m *FieldOptions) String() string { return proto.CompactTextString(m) } +func (*FieldOptions) ProtoMessage() {} +func (*FieldOptions) Descriptor() ([]byte, []int) { return fileDescriptorDescriptor, []int{11} } var extRange_FieldOptions = []proto.ExtensionRange{ {1000, 536870911}, @@ -1318,21 +1357,22 @@ func (m *FieldOptions) GetUninterpretedOption() []*UninterpretedOption { type EnumOptions struct { // Set this option to true to allow mapping different tag names to the same // value. - AllowAlias *bool `protobuf:"varint,2,opt,name=allow_alias" json:"allow_alias,omitempty"` + AllowAlias *bool `protobuf:"varint,2,opt,name=allow_alias,json=allowAlias" json:"allow_alias,omitempty"` // Is this enum deprecated? // Depending on the target platform, this can emit Deprecated annotations // for the enum, or it will be completely ignored; in the very least, this // is a formalization for deprecating enums. Deprecated *bool `protobuf:"varint,3,opt,name=deprecated,def=0" json:"deprecated,omitempty"` // The parser stores options it doesn't recognize here. See above. - UninterpretedOption []*UninterpretedOption `protobuf:"bytes,999,rep,name=uninterpreted_option" json:"uninterpreted_option,omitempty"` + UninterpretedOption []*UninterpretedOption `protobuf:"bytes,999,rep,name=uninterpreted_option,json=uninterpretedOption" json:"uninterpreted_option,omitempty"` XXX_extensions map[int32]proto.Extension `json:"-"` XXX_unrecognized []byte `json:"-"` } -func (m *EnumOptions) Reset() { *m = EnumOptions{} } -func (m *EnumOptions) String() string { return proto.CompactTextString(m) } -func (*EnumOptions) ProtoMessage() {} +func (m *EnumOptions) Reset() { *m = EnumOptions{} } +func (m *EnumOptions) String() string { return proto.CompactTextString(m) } +func (*EnumOptions) ProtoMessage() {} +func (*EnumOptions) Descriptor() ([]byte, []int) { return fileDescriptorDescriptor, []int{12} } var extRange_EnumOptions = []proto.ExtensionRange{ {1000, 536870911}, @@ -1378,14 +1418,15 @@ type EnumValueOptions struct { // this is a formalization for deprecating enum values. Deprecated *bool `protobuf:"varint,1,opt,name=deprecated,def=0" json:"deprecated,omitempty"` // The parser stores options it doesn't recognize here. See above. - UninterpretedOption []*UninterpretedOption `protobuf:"bytes,999,rep,name=uninterpreted_option" json:"uninterpreted_option,omitempty"` + UninterpretedOption []*UninterpretedOption `protobuf:"bytes,999,rep,name=uninterpreted_option,json=uninterpretedOption" json:"uninterpreted_option,omitempty"` XXX_extensions map[int32]proto.Extension `json:"-"` XXX_unrecognized []byte `json:"-"` } -func (m *EnumValueOptions) Reset() { *m = EnumValueOptions{} } -func (m *EnumValueOptions) String() string { return proto.CompactTextString(m) } -func (*EnumValueOptions) ProtoMessage() {} +func (m *EnumValueOptions) Reset() { *m = EnumValueOptions{} } +func (m *EnumValueOptions) String() string { return proto.CompactTextString(m) } +func (*EnumValueOptions) ProtoMessage() {} +func (*EnumValueOptions) Descriptor() ([]byte, []int) { return fileDescriptorDescriptor, []int{13} } var extRange_EnumValueOptions = []proto.ExtensionRange{ {1000, 536870911}, @@ -1424,14 +1465,15 @@ type ServiceOptions struct { // this is a formalization for deprecating services. Deprecated *bool `protobuf:"varint,33,opt,name=deprecated,def=0" json:"deprecated,omitempty"` // The parser stores options it doesn't recognize here. See above. - UninterpretedOption []*UninterpretedOption `protobuf:"bytes,999,rep,name=uninterpreted_option" json:"uninterpreted_option,omitempty"` + UninterpretedOption []*UninterpretedOption `protobuf:"bytes,999,rep,name=uninterpreted_option,json=uninterpretedOption" json:"uninterpreted_option,omitempty"` XXX_extensions map[int32]proto.Extension `json:"-"` XXX_unrecognized []byte `json:"-"` } -func (m *ServiceOptions) Reset() { *m = ServiceOptions{} } -func (m *ServiceOptions) String() string { return proto.CompactTextString(m) } -func (*ServiceOptions) ProtoMessage() {} +func (m *ServiceOptions) Reset() { *m = ServiceOptions{} } +func (m *ServiceOptions) String() string { return proto.CompactTextString(m) } +func (*ServiceOptions) ProtoMessage() {} +func (*ServiceOptions) Descriptor() ([]byte, []int) { return fileDescriptorDescriptor, []int{14} } var extRange_ServiceOptions = []proto.ExtensionRange{ {1000, 536870911}, @@ -1470,14 +1512,15 @@ type MethodOptions struct { // this is a formalization for deprecating methods. Deprecated *bool `protobuf:"varint,33,opt,name=deprecated,def=0" json:"deprecated,omitempty"` // The parser stores options it doesn't recognize here. See above. - UninterpretedOption []*UninterpretedOption `protobuf:"bytes,999,rep,name=uninterpreted_option" json:"uninterpreted_option,omitempty"` + UninterpretedOption []*UninterpretedOption `protobuf:"bytes,999,rep,name=uninterpreted_option,json=uninterpretedOption" json:"uninterpreted_option,omitempty"` XXX_extensions map[int32]proto.Extension `json:"-"` XXX_unrecognized []byte `json:"-"` } -func (m *MethodOptions) Reset() { *m = MethodOptions{} } -func (m *MethodOptions) String() string { return proto.CompactTextString(m) } -func (*MethodOptions) ProtoMessage() {} +func (m *MethodOptions) Reset() { *m = MethodOptions{} } +func (m *MethodOptions) String() string { return proto.CompactTextString(m) } +func (*MethodOptions) ProtoMessage() {} +func (*MethodOptions) Descriptor() ([]byte, []int) { return fileDescriptorDescriptor, []int{15} } var extRange_MethodOptions = []proto.ExtensionRange{ {1000, 536870911}, @@ -1519,18 +1562,19 @@ type UninterpretedOption struct { Name []*UninterpretedOption_NamePart `protobuf:"bytes,2,rep,name=name" json:"name,omitempty"` // The value of the uninterpreted option, in whatever type the tokenizer // identified it as during parsing. Exactly one of these should be set. - IdentifierValue *string `protobuf:"bytes,3,opt,name=identifier_value" json:"identifier_value,omitempty"` - PositiveIntValue *uint64 `protobuf:"varint,4,opt,name=positive_int_value" json:"positive_int_value,omitempty"` - NegativeIntValue *int64 `protobuf:"varint,5,opt,name=negative_int_value" json:"negative_int_value,omitempty"` - DoubleValue *float64 `protobuf:"fixed64,6,opt,name=double_value" json:"double_value,omitempty"` - StringValue []byte `protobuf:"bytes,7,opt,name=string_value" json:"string_value,omitempty"` - AggregateValue *string `protobuf:"bytes,8,opt,name=aggregate_value" json:"aggregate_value,omitempty"` + IdentifierValue *string `protobuf:"bytes,3,opt,name=identifier_value,json=identifierValue" json:"identifier_value,omitempty"` + PositiveIntValue *uint64 `protobuf:"varint,4,opt,name=positive_int_value,json=positiveIntValue" json:"positive_int_value,omitempty"` + NegativeIntValue *int64 `protobuf:"varint,5,opt,name=negative_int_value,json=negativeIntValue" json:"negative_int_value,omitempty"` + DoubleValue *float64 `protobuf:"fixed64,6,opt,name=double_value,json=doubleValue" json:"double_value,omitempty"` + StringValue []byte `protobuf:"bytes,7,opt,name=string_value,json=stringValue" json:"string_value,omitempty"` + AggregateValue *string `protobuf:"bytes,8,opt,name=aggregate_value,json=aggregateValue" json:"aggregate_value,omitempty"` XXX_unrecognized []byte `json:"-"` } -func (m *UninterpretedOption) Reset() { *m = UninterpretedOption{} } -func (m *UninterpretedOption) String() string { return proto.CompactTextString(m) } -func (*UninterpretedOption) ProtoMessage() {} +func (m *UninterpretedOption) Reset() { *m = UninterpretedOption{} } +func (m *UninterpretedOption) String() string { return proto.CompactTextString(m) } +func (*UninterpretedOption) ProtoMessage() {} +func (*UninterpretedOption) Descriptor() ([]byte, []int) { return fileDescriptorDescriptor, []int{16} } func (m *UninterpretedOption) GetName() []*UninterpretedOption_NamePart { if m != nil { @@ -1587,14 +1631,17 @@ func (m *UninterpretedOption) GetAggregateValue() string { // E.g.,{ ["foo", false], ["bar.baz", true], ["qux", false] } represents // "foo.(bar.baz).qux". type UninterpretedOption_NamePart struct { - NamePart *string `protobuf:"bytes,1,req,name=name_part" json:"name_part,omitempty"` - IsExtension *bool `protobuf:"varint,2,req,name=is_extension" json:"is_extension,omitempty"` + NamePart *string `protobuf:"bytes,1,req,name=name_part,json=namePart" json:"name_part,omitempty"` + IsExtension *bool `protobuf:"varint,2,req,name=is_extension,json=isExtension" json:"is_extension,omitempty"` XXX_unrecognized []byte `json:"-"` } func (m *UninterpretedOption_NamePart) Reset() { *m = UninterpretedOption_NamePart{} } func (m *UninterpretedOption_NamePart) String() string { return proto.CompactTextString(m) } func (*UninterpretedOption_NamePart) ProtoMessage() {} +func (*UninterpretedOption_NamePart) Descriptor() ([]byte, []int) { + return fileDescriptorDescriptor, []int{16, 0} +} func (m *UninterpretedOption_NamePart) GetNamePart() string { if m != nil && m.NamePart != nil { @@ -1660,9 +1707,10 @@ type SourceCodeInfo struct { XXX_unrecognized []byte `json:"-"` } -func (m *SourceCodeInfo) Reset() { *m = SourceCodeInfo{} } -func (m *SourceCodeInfo) String() string { return proto.CompactTextString(m) } -func (*SourceCodeInfo) ProtoMessage() {} +func (m *SourceCodeInfo) Reset() { *m = SourceCodeInfo{} } +func (m *SourceCodeInfo) String() string { return proto.CompactTextString(m) } +func (*SourceCodeInfo) ProtoMessage() {} +func (*SourceCodeInfo) Descriptor() ([]byte, []int) { return fileDescriptorDescriptor, []int{17} } func (m *SourceCodeInfo) GetLocation() []*SourceCodeInfo_Location { if m != nil { @@ -1749,15 +1797,18 @@ type SourceCodeInfo_Location struct { // optional int32 grault = 6; // // // ignored detached comments. - LeadingComments *string `protobuf:"bytes,3,opt,name=leading_comments" json:"leading_comments,omitempty"` - TrailingComments *string `protobuf:"bytes,4,opt,name=trailing_comments" json:"trailing_comments,omitempty"` - LeadingDetachedComments []string `protobuf:"bytes,6,rep,name=leading_detached_comments" json:"leading_detached_comments,omitempty"` + LeadingComments *string `protobuf:"bytes,3,opt,name=leading_comments,json=leadingComments" json:"leading_comments,omitempty"` + TrailingComments *string `protobuf:"bytes,4,opt,name=trailing_comments,json=trailingComments" json:"trailing_comments,omitempty"` + LeadingDetachedComments []string `protobuf:"bytes,6,rep,name=leading_detached_comments,json=leadingDetachedComments" json:"leading_detached_comments,omitempty"` XXX_unrecognized []byte `json:"-"` } func (m *SourceCodeInfo_Location) Reset() { *m = SourceCodeInfo_Location{} } func (m *SourceCodeInfo_Location) String() string { return proto.CompactTextString(m) } func (*SourceCodeInfo_Location) ProtoMessage() {} +func (*SourceCodeInfo_Location) Descriptor() ([]byte, []int) { + return fileDescriptorDescriptor, []int{17, 0} +} func (m *SourceCodeInfo_Location) GetPath() []int32 { if m != nil { @@ -1823,3 +1874,144 @@ func init() { proto.RegisterEnum("google.protobuf.FieldOptions_CType", FieldOptions_CType_name, FieldOptions_CType_value) proto.RegisterEnum("google.protobuf.FieldOptions_JSType", FieldOptions_JSType_name, FieldOptions_JSType_value) } + +var fileDescriptorDescriptor = []byte{ + // 2192 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xcc, 0x58, 0x4f, 0x73, 0xdb, 0xd6, + 0x11, 0x2f, 0xff, 0x8a, 0x5c, 0x52, 0x24, 0xf4, 0xac, 0xd8, 0xb4, 0x62, 0xc7, 0x31, 0x63, 0xc7, + 0x8e, 0xd3, 0xd2, 0x19, 0xb7, 0x49, 0x5c, 0xa5, 0x93, 0x0e, 0x45, 0xc2, 0x0a, 0x3d, 0x94, 0xc8, + 0x3e, 0x92, 0xad, 0x93, 0x0b, 0x06, 0x02, 0x1f, 0x29, 0xd8, 0x20, 0xc0, 0x02, 0xa0, 0x6d, 0xe5, + 0xd4, 0x99, 0x9e, 0xfa, 0x0d, 0x3a, 0x6d, 0xa7, 0x87, 0x5c, 0x32, 0xd3, 0x0f, 0xd0, 0x43, 0xef, + 0xbd, 0xf6, 0xd0, 0x73, 0x8f, 0x9d, 0x69, 0xbf, 0x41, 0xaf, 0xdd, 0xf7, 0x1e, 0x00, 0x02, 0x24, + 0x15, 0xab, 0x99, 0x49, 0x13, 0x5d, 0xc4, 0xb7, 0xfb, 0xdb, 0xc5, 0xbe, 0x7d, 0xbf, 0xb7, 0xbb, + 0x00, 0x28, 0x63, 0xe6, 0x19, 0xae, 0x39, 0xf7, 0x1d, 0xb7, 0x31, 0x77, 0x1d, 0xdf, 0x21, 0xd5, + 0xa9, 0xe3, 0x4c, 0x2d, 0x26, 0x57, 0x27, 0x8b, 0x49, 0xfd, 0x08, 0x76, 0x1e, 0x99, 0x16, 0x6b, + 0x47, 0xc0, 0x01, 0xf3, 0xc9, 0x43, 0xc8, 0x4e, 0x50, 0x58, 0x4b, 0xbd, 0x99, 0xb9, 0x5b, 0x7a, + 0x70, 0xab, 0xb1, 0x62, 0xd4, 0x48, 0x5a, 0xf4, 0xb9, 0x98, 0x0a, 0x8b, 0xfa, 0x3f, 0xb3, 0x70, + 0x69, 0x83, 0x96, 0x10, 0xc8, 0xda, 0xfa, 0x8c, 0x7b, 0x4c, 0xdd, 0x2d, 0x52, 0xf1, 0x9b, 0xd4, + 0x60, 0x6b, 0xae, 0x1b, 0xcf, 0xf4, 0x29, 0xab, 0xa5, 0x85, 0x38, 0x5c, 0x92, 0x37, 0x00, 0xc6, + 0x6c, 0xce, 0xec, 0x31, 0xb3, 0x8d, 0xb3, 0x5a, 0x06, 0xa3, 0x28, 0xd2, 0x98, 0x84, 0xbc, 0x0b, + 0x3b, 0xf3, 0xc5, 0x89, 0x65, 0x1a, 0x5a, 0x0c, 0x06, 0x08, 0xcb, 0x51, 0x45, 0x2a, 0xda, 0x4b, + 0xf0, 0x1d, 0xa8, 0xbe, 0x60, 0xfa, 0xb3, 0x38, 0xb4, 0x24, 0xa0, 0x15, 0x2e, 0x8e, 0x01, 0x5b, + 0x50, 0x9e, 0x31, 0xcf, 0xc3, 0x00, 0x34, 0xff, 0x6c, 0xce, 0x6a, 0x59, 0xb1, 0xfb, 0x37, 0xd7, + 0x76, 0xbf, 0xba, 0xf3, 0x52, 0x60, 0x35, 0x44, 0x23, 0xd2, 0x84, 0x22, 0xb3, 0x17, 0x33, 0xe9, + 0x21, 0x77, 0x4e, 0xfe, 0x54, 0x44, 0xac, 0x7a, 0x29, 0x70, 0xb3, 0xc0, 0xc5, 0x96, 0xc7, 0xdc, + 0xe7, 0xa6, 0xc1, 0x6a, 0x79, 0xe1, 0xe0, 0xce, 0x9a, 0x83, 0x81, 0xd4, 0xaf, 0xfa, 0x08, 0xed, + 0x70, 0x2b, 0x45, 0xf6, 0xd2, 0x67, 0xb6, 0x67, 0x3a, 0x76, 0x6d, 0x4b, 0x38, 0xb9, 0xbd, 0xe1, + 0x14, 0x99, 0x35, 0x5e, 0x75, 0xb1, 0xb4, 0x23, 0x1f, 0xc0, 0x96, 0x33, 0xf7, 0xf1, 0x97, 0x57, + 0x2b, 0xe0, 0xf9, 0x94, 0x1e, 0x5c, 0xdb, 0x48, 0x84, 0x9e, 0xc4, 0xd0, 0x10, 0x4c, 0x3a, 0xa0, + 0x78, 0xce, 0xc2, 0x35, 0x98, 0x66, 0x38, 0x63, 0xa6, 0x99, 0xf6, 0xc4, 0xa9, 0x15, 0x85, 0x83, + 0x1b, 0xeb, 0x1b, 0x11, 0xc0, 0x16, 0xe2, 0x3a, 0x08, 0xa3, 0x15, 0x2f, 0xb1, 0x26, 0x97, 0x21, + 0xef, 0x9d, 0xd9, 0xbe, 0xfe, 0xb2, 0x56, 0x16, 0x0c, 0x09, 0x56, 0xf5, 0xff, 0xe4, 0xa0, 0x7a, + 0x11, 0x8a, 0x7d, 0x04, 0xb9, 0x09, 0xdf, 0x25, 0x12, 0xec, 0x7f, 0xc8, 0x81, 0xb4, 0x49, 0x26, + 0x31, 0xff, 0x35, 0x93, 0xd8, 0x84, 0x92, 0xcd, 0x3c, 0x9f, 0x8d, 0x25, 0x23, 0x32, 0x17, 0xe4, + 0x14, 0x48, 0xa3, 0x75, 0x4a, 0x65, 0xbf, 0x16, 0xa5, 0x9e, 0x40, 0x35, 0x0a, 0x49, 0x73, 0x75, + 0x7b, 0x1a, 0x72, 0xf3, 0xfe, 0xab, 0x22, 0x69, 0xa8, 0xa1, 0x1d, 0xe5, 0x66, 0xb4, 0xc2, 0x12, + 0x6b, 0xd2, 0x06, 0x70, 0x6c, 0xe6, 0x4c, 0xf0, 0x7a, 0x19, 0x16, 0xf2, 0x64, 0x73, 0x96, 0x7a, + 0x1c, 0xb2, 0x96, 0x25, 0x47, 0x4a, 0x0d, 0x8b, 0xfc, 0x78, 0x49, 0xb5, 0xad, 0x73, 0x98, 0x72, + 0x24, 0x2f, 0xd9, 0x1a, 0xdb, 0x46, 0x50, 0x71, 0x19, 0xe7, 0x3d, 0xa6, 0x58, 0xee, 0xac, 0x28, + 0x82, 0x68, 0xbc, 0x72, 0x67, 0x34, 0x30, 0x93, 0x1b, 0xdb, 0x76, 0xe3, 0x4b, 0xf2, 0x16, 0x44, + 0x02, 0x4d, 0xd0, 0x0a, 0x44, 0x15, 0x2a, 0x87, 0xc2, 0x63, 0x94, 0xed, 0x3d, 0x84, 0x4a, 0x32, + 0x3d, 0x64, 0x17, 0x72, 0x9e, 0xaf, 0xbb, 0xbe, 0x60, 0x61, 0x8e, 0xca, 0x05, 0x51, 0x20, 0x83, + 0x45, 0x46, 0x54, 0xb9, 0x1c, 0xe5, 0x3f, 0xf7, 0x3e, 0x84, 0xed, 0xc4, 0xe3, 0x2f, 0x6a, 0x58, + 0xff, 0x6d, 0x1e, 0x76, 0x37, 0x71, 0x6e, 0x23, 0xfd, 0xf1, 0xfa, 0x20, 0x03, 0x4e, 0x98, 0x8b, + 0xbc, 0xe3, 0x1e, 0x82, 0x15, 0x32, 0x2a, 0x67, 0xe9, 0x27, 0xcc, 0x42, 0x36, 0xa5, 0xee, 0x56, + 0x1e, 0xbc, 0x7b, 0x21, 0x56, 0x37, 0xba, 0xdc, 0x84, 0x4a, 0x4b, 0xf2, 0x31, 0x64, 0x83, 0x12, + 0xc7, 0x3d, 0xdc, 0xbb, 0x98, 0x07, 0xce, 0x45, 0x2a, 0xec, 0xc8, 0xeb, 0x50, 0xe4, 0xff, 0x65, + 0x6e, 0xf3, 0x22, 0xe6, 0x02, 0x17, 0xf0, 0xbc, 0x92, 0x3d, 0x28, 0x08, 0x9a, 0x8d, 0x59, 0xd8, + 0x1a, 0xa2, 0x35, 0x3f, 0x98, 0x31, 0x9b, 0xe8, 0x0b, 0xcb, 0xd7, 0x9e, 0xeb, 0xd6, 0x82, 0x09, + 0xc2, 0xe0, 0xc1, 0x04, 0xc2, 0x9f, 0x73, 0x19, 0xb9, 0x01, 0x25, 0xc9, 0x4a, 0x13, 0x6d, 0x5e, + 0x8a, 0xea, 0x93, 0xa3, 0x92, 0xa8, 0x1d, 0x2e, 0xe1, 0x8f, 0x7f, 0xea, 0xe1, 0x5d, 0x08, 0x8e, + 0x56, 0x3c, 0x82, 0x0b, 0xc4, 0xe3, 0x3f, 0x5c, 0x2d, 0x7c, 0xd7, 0x37, 0x6f, 0x6f, 0x95, 0x8b, + 0xf5, 0x3f, 0xa7, 0x21, 0x2b, 0xee, 0x5b, 0x15, 0x4a, 0xc3, 0x4f, 0xfb, 0xaa, 0xd6, 0xee, 0x8d, + 0x0e, 0xba, 0xaa, 0x92, 0x22, 0x15, 0x00, 0x21, 0x78, 0xd4, 0xed, 0x35, 0x87, 0x4a, 0x3a, 0x5a, + 0x77, 0x8e, 0x87, 0x1f, 0xfc, 0x48, 0xc9, 0x44, 0x06, 0x23, 0x29, 0xc8, 0xc6, 0x01, 0x3f, 0x7c, + 0xa0, 0xe4, 0x90, 0x09, 0x65, 0xe9, 0xa0, 0xf3, 0x44, 0x6d, 0x23, 0x22, 0x9f, 0x94, 0x20, 0x66, + 0x8b, 0x6c, 0x43, 0x51, 0x48, 0x0e, 0x7a, 0xbd, 0xae, 0x52, 0x88, 0x7c, 0x0e, 0x86, 0xb4, 0x73, + 0x7c, 0xa8, 0x14, 0x23, 0x9f, 0x87, 0xb4, 0x37, 0xea, 0x2b, 0x10, 0x79, 0x38, 0x52, 0x07, 0x83, + 0xe6, 0xa1, 0xaa, 0x94, 0x22, 0xc4, 0xc1, 0xa7, 0x43, 0x75, 0xa0, 0x94, 0x13, 0x61, 0xe1, 0x23, + 0xb6, 0xa3, 0x47, 0xa8, 0xc7, 0xa3, 0x23, 0xa5, 0x42, 0x76, 0x60, 0x5b, 0x3e, 0x22, 0x0c, 0xa2, + 0xba, 0x22, 0xc2, 0x48, 0x95, 0x65, 0x20, 0xd2, 0xcb, 0x4e, 0x42, 0x80, 0x08, 0x52, 0x6f, 0x41, + 0x4e, 0xb0, 0x0b, 0x59, 0x5c, 0xe9, 0x36, 0x0f, 0xd4, 0xae, 0xd6, 0xeb, 0x0f, 0x3b, 0xbd, 0xe3, + 0x66, 0x17, 0x73, 0x17, 0xc9, 0xa8, 0xfa, 0xb3, 0x51, 0x87, 0xaa, 0x6d, 0xcc, 0x5f, 0x4c, 0xd6, + 0x57, 0x9b, 0x43, 0x94, 0x65, 0xea, 0xf7, 0x60, 0x77, 0x53, 0x9d, 0xd9, 0x74, 0x33, 0xea, 0x5f, + 0xa4, 0xe0, 0xd2, 0x86, 0x92, 0xb9, 0xf1, 0x16, 0xfd, 0x14, 0x72, 0x92, 0x69, 0xb2, 0x89, 0xbc, + 0xb3, 0xb1, 0xf6, 0x0a, 0xde, 0xad, 0x35, 0x12, 0x61, 0x17, 0x6f, 0xa4, 0x99, 0x73, 0x1a, 0x29, + 0x77, 0xb1, 0x46, 0xa7, 0x5f, 0xa7, 0xa0, 0x76, 0x9e, 0xef, 0x57, 0xdc, 0xf7, 0x74, 0xe2, 0xbe, + 0x7f, 0xb4, 0x1a, 0xc0, 0xcd, 0xf3, 0xf7, 0xb0, 0x16, 0xc5, 0x97, 0x29, 0xb8, 0xbc, 0x79, 0xde, + 0xd8, 0x18, 0xc3, 0xc7, 0x90, 0x9f, 0x31, 0xff, 0xd4, 0x09, 0x7b, 0xee, 0xdb, 0x1b, 0x2a, 0x39, + 0x57, 0xaf, 0xe6, 0x2a, 0xb0, 0x8a, 0xb7, 0x82, 0xcc, 0x79, 0x43, 0x83, 0x8c, 0x66, 0x2d, 0xd2, + 0xdf, 0xa4, 0xe1, 0xb5, 0x8d, 0xce, 0x37, 0x06, 0x7a, 0x1d, 0xc0, 0xb4, 0xe7, 0x0b, 0x5f, 0xf6, + 0x55, 0x59, 0x66, 0x8a, 0x42, 0x22, 0xae, 0x30, 0x2f, 0x21, 0x0b, 0x3f, 0xd2, 0x67, 0x84, 0x1e, + 0xa4, 0x48, 0x00, 0x1e, 0x2e, 0x03, 0xcd, 0x8a, 0x40, 0xdf, 0x38, 0x67, 0xa7, 0x6b, 0x2d, 0xeb, + 0x3d, 0x50, 0x0c, 0xcb, 0x64, 0xb6, 0xaf, 0x79, 0xbe, 0xcb, 0xf4, 0x99, 0x69, 0x4f, 0x45, 0x1d, + 0x2d, 0xec, 0xe7, 0x26, 0xba, 0xe5, 0x31, 0x5a, 0x95, 0xea, 0x41, 0xa8, 0xe5, 0x16, 0xa2, 0x59, + 0xb8, 0x31, 0x8b, 0x7c, 0xc2, 0x42, 0xaa, 0x23, 0x8b, 0xfa, 0xdf, 0xb7, 0xa0, 0x14, 0x9b, 0xce, + 0xc8, 0x4d, 0x28, 0x3f, 0xd5, 0x9f, 0xeb, 0x5a, 0x38, 0x71, 0xcb, 0x4c, 0x94, 0xb8, 0xac, 0x1f, + 0x4c, 0xdd, 0xef, 0xc1, 0xae, 0x80, 0xe0, 0x1e, 0xf1, 0x41, 0x86, 0xa5, 0x7b, 0x9e, 0x48, 0x5a, + 0x41, 0x40, 0x09, 0xd7, 0xf5, 0xb8, 0xaa, 0x15, 0x6a, 0xc8, 0xfb, 0x70, 0x49, 0x58, 0xcc, 0xb0, + 0xf0, 0x9a, 0x73, 0x8b, 0x69, 0xfc, 0x1d, 0xc0, 0x13, 0xf5, 0x34, 0x8a, 0x6c, 0x87, 0x23, 0x8e, + 0x02, 0x00, 0x8f, 0xc8, 0x23, 0x87, 0x70, 0x5d, 0x98, 0x4d, 0x99, 0xcd, 0x5c, 0xdd, 0x67, 0x1a, + 0xfb, 0xe5, 0x02, 0xb1, 0x9a, 0x6e, 0x8f, 0xb5, 0x53, 0xdd, 0x3b, 0xad, 0xed, 0xc6, 0x1d, 0x5c, + 0xe5, 0xd8, 0xc3, 0x00, 0xaa, 0x0a, 0x64, 0xd3, 0x1e, 0x7f, 0x82, 0x38, 0xb2, 0x0f, 0x97, 0x85, + 0x23, 0x4c, 0x0a, 0xee, 0x59, 0x33, 0x4e, 0x99, 0xf1, 0x4c, 0x5b, 0xf8, 0x93, 0x87, 0xb5, 0xd7, + 0xe3, 0x1e, 0x44, 0x90, 0x03, 0x81, 0x69, 0x71, 0xc8, 0x08, 0x11, 0x64, 0x00, 0x65, 0x7e, 0x1e, + 0x33, 0xf3, 0x73, 0x0c, 0xdb, 0x71, 0x45, 0x8f, 0xa8, 0x6c, 0xb8, 0xdc, 0xb1, 0x24, 0x36, 0x7a, + 0x81, 0xc1, 0x11, 0xce, 0xa7, 0xfb, 0xb9, 0x41, 0x5f, 0x55, 0xdb, 0xb4, 0x14, 0x7a, 0x79, 0xe4, + 0xb8, 0x9c, 0x53, 0x53, 0x27, 0xca, 0x71, 0x49, 0x72, 0x6a, 0xea, 0x84, 0x19, 0xc6, 0x7c, 0x19, + 0x86, 0xdc, 0x36, 0xbe, 0xbb, 0x04, 0xc3, 0xba, 0x57, 0x53, 0x12, 0xf9, 0x32, 0x8c, 0x43, 0x09, + 0x08, 0x68, 0xee, 0xe1, 0x95, 0x78, 0x6d, 0x99, 0xaf, 0xb8, 0xe1, 0xce, 0xda, 0x2e, 0x57, 0x4d, + 0xf1, 0x89, 0xf3, 0xb3, 0x75, 0x43, 0x92, 0x78, 0xe2, 0xfc, 0x6c, 0xd5, 0xec, 0xb6, 0x78, 0x01, + 0x73, 0x99, 0x81, 0x29, 0x1f, 0xd7, 0xae, 0xc4, 0xd1, 0x31, 0x05, 0xb9, 0x8f, 0x44, 0x36, 0x34, + 0x66, 0xeb, 0x27, 0x78, 0xf6, 0xba, 0x8b, 0x3f, 0xbc, 0xda, 0x8d, 0x38, 0xb8, 0x62, 0x18, 0xaa, + 0xd0, 0x36, 0x85, 0x92, 0xdc, 0x83, 0x1d, 0xe7, 0xe4, 0xa9, 0x21, 0xc9, 0xa5, 0xa1, 0x9f, 0x89, + 0xf9, 0xb2, 0x76, 0x4b, 0xa4, 0xa9, 0xca, 0x15, 0x82, 0x5a, 0x7d, 0x21, 0x26, 0xef, 0xa0, 0x73, + 0xef, 0x54, 0x77, 0xe7, 0xa2, 0x49, 0x7b, 0x98, 0x54, 0x56, 0xbb, 0x2d, 0xa1, 0x52, 0x7e, 0x1c, + 0x8a, 0x89, 0x0a, 0x37, 0xf8, 0xe6, 0x6d, 0xdd, 0x76, 0xb4, 0x85, 0xc7, 0xb4, 0x65, 0x88, 0xd1, + 0x59, 0xbc, 0xcd, 0xc3, 0xa2, 0xd7, 0x42, 0xd8, 0xc8, 0xc3, 0x62, 0x16, 0x82, 0xc2, 0xe3, 0x79, + 0x02, 0xbb, 0x0b, 0xdb, 0xb4, 0x91, 0xe2, 0xa8, 0xe1, 0xc6, 0xf2, 0xc2, 0xd6, 0xfe, 0xb5, 0x75, + 0xce, 0xd0, 0x3d, 0x8a, 0xa3, 0x25, 0x49, 0xe8, 0xa5, 0xc5, 0xba, 0xb0, 0xbe, 0x0f, 0xe5, 0x38, + 0x77, 0x48, 0x11, 0x24, 0x7b, 0xb0, 0xbb, 0x61, 0x47, 0x6d, 0xf5, 0xda, 0xbc, 0x17, 0x7e, 0xa6, + 0x62, 0x63, 0xc3, 0x9e, 0xdc, 0xed, 0x0c, 0x55, 0x8d, 0x8e, 0x8e, 0x87, 0x9d, 0x23, 0x55, 0xc9, + 0xdc, 0x2b, 0x16, 0xfe, 0xbd, 0xa5, 0xfc, 0x0a, 0xff, 0xd2, 0xf5, 0xbf, 0xa6, 0xa1, 0x92, 0x9c, + 0x83, 0xc9, 0x4f, 0xe0, 0x4a, 0xf8, 0xd2, 0xea, 0x31, 0x5f, 0x7b, 0x61, 0xba, 0x82, 0xce, 0x33, + 0x5d, 0x4e, 0x92, 0xd1, 0x49, 0xec, 0x06, 0x28, 0x7c, 0xbd, 0xff, 0x05, 0x62, 0x1e, 0x09, 0x08, + 0xe9, 0xc2, 0x0d, 0x4c, 0x19, 0xce, 0x9a, 0xf6, 0x58, 0x77, 0xc7, 0xda, 0xf2, 0x73, 0x81, 0xa6, + 0x1b, 0xc8, 0x03, 0xcf, 0x91, 0x9d, 0x24, 0xf2, 0x72, 0xcd, 0x76, 0x06, 0x01, 0x78, 0x59, 0x62, + 0x9b, 0x01, 0x74, 0x85, 0x35, 0x99, 0xf3, 0x58, 0x83, 0xb3, 0xd7, 0x4c, 0x9f, 0x23, 0x6d, 0x7c, + 0xf7, 0x4c, 0x4c, 0x6f, 0x05, 0x5a, 0x40, 0x81, 0xca, 0xd7, 0xdf, 0xdc, 0x19, 0xc4, 0xf3, 0xf8, + 0x8f, 0x0c, 0x94, 0xe3, 0x13, 0x1c, 0x1f, 0x88, 0x0d, 0x51, 0xe6, 0x53, 0xa2, 0x0a, 0xbc, 0xf5, + 0x95, 0xf3, 0x5e, 0xa3, 0xc5, 0xeb, 0xff, 0x7e, 0x5e, 0xce, 0x55, 0x54, 0x5a, 0xf2, 0xde, 0xcb, + 0xb9, 0xc6, 0xe4, 0xb4, 0x5e, 0xa0, 0xc1, 0x0a, 0x8b, 0x5d, 0xfe, 0xa9, 0x27, 0x7c, 0xe7, 0x85, + 0xef, 0x5b, 0x5f, 0xed, 0xfb, 0xf1, 0x40, 0x38, 0x2f, 0x3e, 0x1e, 0x68, 0xc7, 0x3d, 0x7a, 0xd4, + 0xec, 0xd2, 0xc0, 0x9c, 0x5c, 0x85, 0xac, 0xa5, 0x7f, 0x7e, 0x96, 0xec, 0x14, 0x42, 0x74, 0xd1, + 0xc4, 0xa3, 0x07, 0xfe, 0xc9, 0x23, 0x59, 0x9f, 0x85, 0xe8, 0x1b, 0xa4, 0xfe, 0x7d, 0xc8, 0x89, + 0x7c, 0x11, 0x80, 0x20, 0x63, 0xca, 0xf7, 0x48, 0x01, 0xb2, 0xad, 0x1e, 0xe5, 0xf4, 0x47, 0xbe, + 0x4b, 0xa9, 0xd6, 0xef, 0xa8, 0x2d, 0xbc, 0x01, 0xf5, 0xf7, 0x21, 0x2f, 0x93, 0xc0, 0xaf, 0x46, + 0x94, 0x06, 0x34, 0x92, 0xcb, 0xc0, 0x47, 0x2a, 0xd4, 0x8e, 0x8e, 0x0e, 0x54, 0xaa, 0xa4, 0xe3, + 0xc7, 0xfb, 0x97, 0x14, 0x94, 0x62, 0x03, 0x15, 0x6f, 0xe5, 0xba, 0x65, 0x39, 0x2f, 0x34, 0xdd, + 0x32, 0xb1, 0x42, 0xc9, 0xf3, 0x01, 0x21, 0x6a, 0x72, 0xc9, 0x45, 0xf3, 0xf7, 0x7f, 0xe1, 0xe6, + 0x1f, 0x53, 0xa0, 0xac, 0x0e, 0x63, 0x2b, 0x01, 0xa6, 0xbe, 0xd5, 0x00, 0xff, 0x90, 0x82, 0x4a, + 0x72, 0x02, 0x5b, 0x09, 0xef, 0xe6, 0xb7, 0x1a, 0xde, 0xef, 0x53, 0xb0, 0x9d, 0x98, 0xbb, 0xbe, + 0x53, 0xd1, 0xfd, 0x2e, 0x03, 0x97, 0x36, 0xd8, 0x61, 0x01, 0x92, 0x03, 0xaa, 0x9c, 0x99, 0x7f, + 0x70, 0x91, 0x67, 0x35, 0x78, 0xff, 0xeb, 0xeb, 0xae, 0x1f, 0xcc, 0xb3, 0xd8, 0x2f, 0xcd, 0x31, + 0x16, 0x55, 0x73, 0x62, 0xe2, 0xf8, 0x26, 0xdf, 0x58, 0xe4, 0xd4, 0x5a, 0x5d, 0xca, 0xe5, 0xeb, + 0xf1, 0xf7, 0x81, 0xcc, 0x1d, 0xcf, 0xf4, 0xcd, 0xe7, 0xfc, 0xf3, 0x5c, 0xf8, 0x22, 0xcd, 0xa7, + 0xd8, 0x2c, 0x55, 0x42, 0x4d, 0xc7, 0xf6, 0x23, 0xb4, 0xcd, 0xa6, 0xfa, 0x0a, 0x9a, 0x97, 0xa1, + 0x0c, 0x55, 0x42, 0x4d, 0x84, 0xc6, 0x41, 0x73, 0xec, 0x2c, 0xf8, 0x40, 0x20, 0x71, 0xbc, 0xea, + 0xa5, 0x68, 0x49, 0xca, 0x22, 0x48, 0x30, 0xb1, 0x2d, 0xdf, 0xe0, 0xcb, 0xb4, 0x24, 0x65, 0x12, + 0x72, 0x07, 0xaa, 0xfa, 0x74, 0xea, 0x72, 0xe7, 0xa1, 0x23, 0x39, 0x86, 0x56, 0x22, 0xb1, 0x00, + 0xee, 0x3d, 0x86, 0x42, 0x98, 0x07, 0xde, 0x58, 0x78, 0x26, 0xb0, 0xe7, 0x8b, 0xef, 0x28, 0x69, + 0xfe, 0x52, 0x6f, 0x87, 0x4a, 0x7c, 0xa8, 0xe9, 0x69, 0xcb, 0x0f, 0x7a, 0x69, 0xd4, 0x17, 0x68, + 0xc9, 0xf4, 0xa2, 0x2f, 0x38, 0xf5, 0x2f, 0xb1, 0xbd, 0x26, 0x3f, 0x48, 0x92, 0x36, 0x14, 0x2c, + 0x07, 0xf9, 0xc1, 0x2d, 0xe4, 0xd7, 0xf0, 0xbb, 0xaf, 0xf8, 0x86, 0xd9, 0xe8, 0x06, 0x78, 0x1a, + 0x59, 0xee, 0xfd, 0x2d, 0x05, 0x85, 0x50, 0x8c, 0x8d, 0x22, 0x3b, 0xd7, 0xfd, 0x53, 0xe1, 0x2e, + 0x77, 0x90, 0x56, 0x52, 0x54, 0xac, 0xb9, 0x1c, 0xa7, 0x19, 0x5b, 0x50, 0x20, 0x90, 0xf3, 0x35, + 0x3f, 0x57, 0x8b, 0xe9, 0x63, 0x31, 0xe0, 0x3a, 0xb3, 0x19, 0x9e, 0xa4, 0x17, 0x9e, 0x6b, 0x20, + 0x6f, 0x05, 0x62, 0xfe, 0x5d, 0xdc, 0x77, 0x75, 0xd3, 0x4a, 0x60, 0xb3, 0x02, 0xab, 0x84, 0x8a, + 0x08, 0xbc, 0x0f, 0x57, 0x43, 0xbf, 0x63, 0xe6, 0xeb, 0x38, 0x3c, 0x8f, 0x97, 0x46, 0x79, 0xf1, + 0xb5, 0xeb, 0x4a, 0x00, 0x68, 0x07, 0xfa, 0xd0, 0xf6, 0xe0, 0x09, 0x0e, 0xb2, 0xce, 0x6c, 0x35, + 0x13, 0x07, 0xca, 0xca, 0x7b, 0x97, 0xf7, 0x49, 0xea, 0x33, 0x58, 0x0e, 0x15, 0x5f, 0xa4, 0x33, + 0x87, 0xfd, 0x83, 0x3f, 0xa5, 0xf7, 0x0e, 0xa5, 0x5d, 0x3f, 0xcc, 0x20, 0x65, 0x13, 0x8b, 0x19, + 0x3c, 0x3b, 0xff, 0x0d, 0x00, 0x00, 0xff, 0xff, 0x78, 0x42, 0x69, 0x71, 0xb3, 0x18, 0x00, 0x00, +} diff --git a/vendor/github.com/gogo/protobuf/protoc-gen-gogo/descriptor/helper.go b/vendor/github.com/gogo/protobuf/protoc-gen-gogo/descriptor/helper.go index cf88f3cc506..ab170f913a2 100644 --- a/vendor/github.com/gogo/protobuf/protoc-gen-gogo/descriptor/helper.go +++ b/vendor/github.com/gogo/protobuf/protoc-gen-gogo/descriptor/helper.go @@ -127,13 +127,22 @@ func (file *FileDescriptorProto) GetMessage(typeName string) *DescriptorProto { if msg.GetName() == typeName { return msg } - for _, nes := range msg.GetNestedType() { - if nes.GetName() == typeName { - return nes - } - if msg.GetName()+"."+nes.GetName() == typeName { - return nes - } + nes := file.GetNestedMessage(msg, strings.TrimPrefix(typeName, msg.GetName()+".")) + if nes != nil { + return nes + } + } + return nil +} + +func (file *FileDescriptorProto) GetNestedMessage(msg *DescriptorProto, typeName string) *DescriptorProto { + for _, nes := range msg.GetNestedType() { + if nes.GetName() == typeName { + return nes + } + res := file.GetNestedMessage(nes, strings.TrimPrefix(typeName, nes.GetName()+".")) + if res != nil { + return res } } return nil @@ -329,6 +338,10 @@ func (f *FieldDescriptorProto) IsString() bool { return *f.Type == FieldDescriptorProto_TYPE_STRING } +func (f *FieldDescriptorProto) IsBool() bool { + return *f.Type == FieldDescriptorProto_TYPE_BOOL +} + func (f *FieldDescriptorProto) IsRequired() bool { return f.Label != nil && *f.Label == FieldDescriptorProto_LABEL_REQUIRED } diff --git a/vendor/github.com/gogo/protobuf/protoc-gen-gogo/generator/generator.go b/vendor/github.com/gogo/protobuf/protoc-gen-gogo/generator/generator.go index 33c501b3e42..3141ae2abe0 100644 --- a/vendor/github.com/gogo/protobuf/protoc-gen-gogo/generator/generator.go +++ b/vendor/github.com/gogo/protobuf/protoc-gen-gogo/generator/generator.go @@ -44,6 +44,7 @@ package generator import ( "bufio" "bytes" + "compress/gzip" "fmt" "go/parser" "go/printer" @@ -63,6 +64,12 @@ import ( plugin "github.com/gogo/protobuf/protoc-gen-gogo/plugin" ) +// generatedCodeVersion indicates a version of the generated code. +// It is incremented whenever an incompatibility between the generated code and +// proto package is introduced; the generated code references +// a constant, proto.ProtoPackageIsVersionN (where N is generatedCodeVersion). +const generatedCodeVersion = 1 + // A Plugin provides functionality to add to the output during Go code generation, // such as to produce RPC stubs. type Plugin interface { @@ -190,14 +197,26 @@ func (e *EnumDescriptor) TypeName() (s []string) { return s } +// alias provides the TypeName corrected for the application of any naming +// extensions on the enum type. It should be used for generating references to +// the Go types and for calculating prefixes. +func (e *EnumDescriptor) alias() (s []string) { + s = e.TypeName() + if gogoproto.IsEnumCustomName(e.EnumDescriptorProto) { + s[len(s)-1] = gogoproto.GetEnumCustomName(e.EnumDescriptorProto) + } + + return +} + // Everything but the last element of the full type name, CamelCased. // The values of type Foo.Bar are call Foo_value1... not Foo_Bar_value1... . func (e *EnumDescriptor) prefix() string { + typeName := e.alias() if e.parent == nil { // If the enum is not part of a message, the prefix is just the type name. - return CamelCase(*e.Name) + "_" + return CamelCase(typeName[len(typeName)-1]) + "_" } - typeName := e.TypeName() return CamelCaseSlice(typeName[0:len(typeName)-1]) + "_" } @@ -281,6 +300,36 @@ type FileDescriptor struct { // PackageName is the package name we'll use in the generated code to refer to this file. func (d *FileDescriptor) PackageName() string { return uniquePackageOf(d.FileDescriptorProto) } +// VarName is the variable name we'll use in the generated code to refer +// to the compressed bytes of this descriptor. It is not exported, so +// it is only valid inside the generated package. +func (d *FileDescriptor) VarName() string { return fmt.Sprintf("fileDescriptor%v", FileName(d)) } + +// goPackageOption interprets the file's go_package option. +// If there is no go_package, it returns ("", "", false). +// If there's a simple name, it returns ("", pkg, true). +// If the option implies an import path, it returns (impPath, pkg, true). +func (d *FileDescriptor) goPackageOption() (impPath, pkg string, ok bool) { + pkg = d.GetOptions().GetGoPackage() + if pkg == "" { + return + } + ok = true + // The presence of a slash implies there's an import path. + slash := strings.LastIndex(pkg, "/") + if slash < 0 { + return + } + impPath, pkg = pkg, pkg[slash+1:] + // A semicolon-delimited suffix overrides the package name. + sc := strings.IndexByte(impPath, ';') + if sc < 0 { + return + } + impPath, pkg = impPath[:sc], impPath[sc+1:] + return +} + // goPackageName returns the Go package name to use in the // generated Go file. The result explicit reports whether the name // came from an option go_package statement. If explicit is false, @@ -288,10 +337,8 @@ func (d *FileDescriptor) PackageName() string { return uniquePackageOf(d.FileDes // or the input file name. func (d *FileDescriptor) goPackageName() (name string, explicit bool) { // Does the file have a "go_package" option? - if opts := d.Options; opts != nil { - if pkg := opts.GetGoPackage(); pkg != "" { - return pkg, true - } + if _, pkg, ok := d.goPackageOption(); ok { + return pkg, true } // Does the file have a package clause? @@ -302,6 +349,26 @@ func (d *FileDescriptor) goPackageName() (name string, explicit bool) { return baseName(d.GetName()), false } +// goFileName returns the output name for the generated Go file. +func (d *FileDescriptor) goFileName() string { + name := *d.Name + if ext := path.Ext(name); ext == ".proto" || ext == ".protodevel" { + name = name[:len(name)-len(ext)] + } + name += ".pb.go" + + // Does the file have a "go_package" option? + // If it does, it may override the filename. + if impPath, _, ok := d.goPackageOption(); ok && impPath != "" { + // Replace the existing dirname with the declared import path. + _, name = path.Split(name) + name = path.Join(impPath, name) + return name + } + + return name +} + func (d *FileDescriptor) addExport(obj Object, sym symbol) { d.exported[obj] = append(d.exported[obj], sym) } @@ -352,25 +419,34 @@ func (ms *messageSymbol) GenerateAlias(g *Generator, pkg string) { // but they're going to break weirdly for text/JSON. enc := "_" + ms.sym + "_OneofMarshaler" dec := "_" + ms.sym + "_OneofUnmarshaler" + size := "_" + ms.sym + "_OneofSizer" encSig := "(msg " + g.Pkg["proto"] + ".Message, b *" + g.Pkg["proto"] + ".Buffer) error" decSig := "(msg " + g.Pkg["proto"] + ".Message, tag, wire int, b *" + g.Pkg["proto"] + ".Buffer) (bool, error)" - g.P("func (m *", ms.sym, ") XXX_OneofFuncs() (func", encSig, ", func", decSig, ", []interface{}) {") - g.P("return ", enc, ", ", dec, ", nil") + sizeSig := "(msg " + g.Pkg["proto"] + ".Message) int" + g.P("func (m *", ms.sym, ") XXX_OneofFuncs() (func", encSig, ", func", decSig, ", func", sizeSig, ", []interface{}) {") + g.P("return ", enc, ", ", dec, ", ", size, ", nil") g.P("}") g.P("func ", enc, encSig, " {") g.P("m := msg.(*", ms.sym, ")") g.P("m0 := (*", remoteSym, ")(m)") - g.P("enc, _, _ := m0.XXX_OneofFuncs()") + g.P("enc, _, _, _ := m0.XXX_OneofFuncs()") g.P("return enc(m0, b)") g.P("}") g.P("func ", dec, decSig, " {") g.P("m := msg.(*", ms.sym, ")") g.P("m0 := (*", remoteSym, ")(m)") - g.P("_, dec, _ := m0.XXX_OneofFuncs()") + g.P("_, dec, _, _ := m0.XXX_OneofFuncs()") g.P("return dec(m0, tag, wire, b)") g.P("}") + + g.P("func ", size, sizeSig, " {") + g.P("m := msg.(*", ms.sym, ")") + g.P("m0 := (*", remoteSym, ")(m)") + g.P("_, _, size, _ := m0.XXX_OneofFuncs()") + g.P("return size(m0)") + g.P("}") } for _, get := range ms.getters { @@ -439,11 +515,11 @@ func (ms *messageSymbol) GenerateAlias(g *Generator, pkg string) { valTyp = "*" + valTyp } - typ := "map[" + keyTyp + "]" + valTyp + maptyp := "map[" + keyTyp + "]" + valTyp g.P("func (m *", ms.sym, ") ", get.name, "() ", typ, " {") g.P("o := ", val) g.P("if o == nil { return nil }") - g.P("s := make(", typ, ", len(o))") + g.P("s := make(", maptyp, ", len(o))") g.P("for k, v := range o {") g.P("s[k] = (", valTyp, ")(v)") g.P("}") @@ -520,7 +596,7 @@ type Generator struct { Param map[string]string // Command-line parameters. PackageImportPath string // Go import path of the package we're generating code for ImportPrefix string // String to prefix to imported package file names. - ImportMap map[string]string // Mapping from import name to generated name + ImportMap map[string]string // Mapping from .proto file name to import path Pkg map[string]string // The names under which we import support packages @@ -601,7 +677,7 @@ func (g *Generator) CommandLineParameters(parameter string) { if pluginList == "none" { pluginList = "" } - gogoPluginNames := []string{"unmarshal", "unsafeunmarshaler", "union", "stringer", "size", "protosizer", "populate", "marshalto", "unsafemarshaler", "gostring", "face", "equal", "enumstringer", "embedcheck", "description", "defaultcheck", "oneofcheck"} + gogoPluginNames := []string{"unmarshal", "unsafeunmarshaler", "union", "stringer", "size", "protosizer", "populate", "marshalto", "unsafemarshaler", "gostring", "face", "equal", "enumstringer", "embedcheck", "description", "defaultcheck", "oneofcheck", "compare"} pluginList = strings.Join(append(gogoPluginNames, pluginList), "+") if pluginList != "" { // Amend the set of plugins. @@ -795,9 +871,9 @@ AllFiles: // and FileDescriptorProtos into file-referenced objects within the Generator. // It also creates the list of files to generate and so should be called before GenerateAllFiles. func (g *Generator) WrapTypes() { - g.allFiles = make([]*FileDescriptor, len(g.Request.ProtoFile)) + g.allFiles = make([]*FileDescriptor, 0, len(g.Request.ProtoFile)) g.allFilesByName = make(map[string]*FileDescriptor, len(g.allFiles)) - for i, f := range g.Request.ProtoFile { + for _, f := range g.Request.ProtoFile { // We must wrap the descriptors before we wrap the enums descs := wrapDescriptors(f) g.buildNestedDescriptors(descs) @@ -813,22 +889,22 @@ func (g *Generator) WrapTypes() { proto3: fileIsProto3(f), } extractComments(fd) - g.allFiles[i] = fd + g.allFiles = append(g.allFiles, fd) g.allFilesByName[f.GetName()] = fd } for _, fd := range g.allFiles { fd.imp = wrapImported(fd.FileDescriptorProto, g) } - g.genFiles = make([]*FileDescriptor, len(g.Request.FileToGenerate)) - for i, fileName := range g.Request.FileToGenerate { - g.genFiles[i] = g.allFilesByName[fileName] - if g.genFiles[i] == nil { + g.genFiles = make([]*FileDescriptor, 0, len(g.Request.FileToGenerate)) + for _, fileName := range g.Request.FileToGenerate { + fd := g.allFilesByName[fileName] + if fd == nil { g.Fail("could not find file named", fileName) } - g.genFiles[i].index = i + fd.index = len(g.genFiles) + g.genFiles = append(g.genFiles, fd) } - g.Response.File = make([]*plugin.CodeGeneratorResponse_File, len(g.genFiles)) } // Scan the descriptors in this file. For each one, build the slice of nested descriptors @@ -892,9 +968,8 @@ func newDescriptor(desc *descriptor.DescriptorProto, parent *Descriptor, file *d } } - d.ext = make([]*ExtensionDescriptor, len(desc.Extension)) - for i, field := range desc.Extension { - d.ext[i] = &ExtensionDescriptor{common{file}, field, d} + for _, field := range desc.Extension { + d.ext = append(d.ext, &ExtensionDescriptor{common{file}, field, d}) } return d @@ -953,9 +1028,9 @@ func wrapEnumDescriptors(file *descriptor.FileDescriptorProto, descs []*Descript // Return a slice of all the top-level ExtensionDescriptors defined within this file. func wrapExtensions(file *descriptor.FileDescriptorProto) []*ExtensionDescriptor { - sl := make([]*ExtensionDescriptor, len(file.Extension)) - for i, field := range file.Extension { - sl[i] = &ExtensionDescriptor{common{file}, field, nil} + var sl []*ExtensionDescriptor + for _, field := range file.Extension { + sl = append(sl, &ExtensionDescriptor{common{file}, field, nil}) } return sl } @@ -1133,7 +1208,6 @@ func (g *Generator) GenerateAllFiles() { for _, file := range g.genFiles { genFileMap[file] = true } - i := 0 for _, file := range g.allFiles { g.Reset() g.writeOutput = genFileMap[file] @@ -1141,10 +1215,10 @@ func (g *Generator) GenerateAllFiles() { if !g.writeOutput { continue } - g.Response.File[i] = new(plugin.CodeGeneratorResponse_File) - g.Response.File[i].Name = proto.String(goFileName(*file.Name)) - g.Response.File[i].Content = proto.String(g.String()) - i++ + g.Response.File = append(g.Response.File, &plugin.CodeGeneratorResponse_File{ + Name: proto.String(file.goFileName()), + Content: proto.String(g.String()), + }) } } @@ -1172,6 +1246,19 @@ func (g *Generator) generate(file *FileDescriptor) { g.customImports = make([]string, 0) g.file = g.FileOf(file.FileDescriptorProto) g.usedPackages = make(map[string]bool) + + if g.file.index == 0 { + // For one file in the package, assert version compatibility. + g.P("// This is a compile-time assertion to ensure that this generated file") + g.P("// is compatible with the proto package it is being compiled against.") + if gogoproto.ImportsGoGoProto(file.FileDescriptorProto) { + g.P("const _ = ", g.Pkg["proto"], ".GoGoProtoPackageIsVersion", generatedCodeVersion) + } else { + g.P("const _ = ", g.Pkg["proto"], ".ProtoPackageIsVersion", generatedCodeVersion) + } + g.P() + } + // Reset on each file g.writtenImports = make(map[string]bool) @@ -1196,6 +1283,8 @@ func (g *Generator) generate(file *FileDescriptor) { // Run the plugins before the imports so we know which imports are necessary. g.runPlugins(file) + g.generateFileDescriptor(file) + // Generate header and imports last, though they appear first in the output. rem := g.Buffer g.Buffer = new(bytes.Buffer) @@ -1343,7 +1432,7 @@ func (g *Generator) generateImports() { if fd.PackageName() == g.packageName { continue } - filename := goFileName(s) + filename := fd.goFileName() // By default, import path is the dirname of the Go filename. importPath := path.Dir(filename) if substitution, ok := g.ImportMap[s]; ok { @@ -1411,7 +1500,7 @@ func (g *Generator) generateImported(id *ImportedDescriptor) { // Generate the enum definitions for this EnumDescriptor. func (g *Generator) generateEnum(enum *EnumDescriptor) { // The full type name - typeName := enum.TypeName() + typeName := enum.alias() // The full type name, CamelCased. ccTypeName := CamelCaseSlice(typeName) ccPrefix := enum.prefix() @@ -1426,8 +1515,12 @@ func (g *Generator) generateEnum(enum *EnumDescriptor) { g.In() for i, e := range enum.Value { g.PrintComments(fmt.Sprintf("%s,%d,%d", enum.path, enumValuePath, i)) + name := *e.Name + if gogoproto.IsEnumValueCustomName(e) { + name = gogoproto.GetEnumValueCustomName(e) + } + name = ccPrefix + name - name := ccPrefix + *e.Name g.P(name, " ", ccTypeName, " = ", e.Number) g.file.addExport(enum, constOrVarSymbol{name, "const", ccTypeName}) } @@ -1493,6 +1586,15 @@ func (g *Generator) generateEnum(enum *EnumDescriptor) { g.Out() g.P("}") } + + var indexes []string + for m := enum.parent; m != nil; m = m.parent { + // XXX: skip groups? + indexes = append([]string{strconv.Itoa(m.index)}, indexes...) + } + indexes = append(indexes, strconv.Itoa(enum.index)) + g.P("func (", ccTypeName, ") EnumDescriptor() ([]byte, []int) { return ", g.file.VarName(), ", []int{", strings.Join(indexes, ", "), "} }") + g.P() } @@ -1583,6 +1685,11 @@ func (g *Generator) goTag(message *Descriptor, field *descriptor.FieldDescriptor name = name[i+1:] } } + if json := field.GetJsonName(); json != "" && json != name { + // TODO: escaping might be needed, in which case + // perhaps this should be in its own "json" tag. + name += ",json=" + json + } name = ",name=" + name embed := "" @@ -1967,8 +2074,8 @@ func (g *Generator) generateMessage(message *Descriptor) { dname := "is" + ccTypeName + "_" + fname oneofFieldName[*field.OneofIndex] = fname oneofDisc[*field.OneofIndex] = dname - tag := `protobuf_oneof:"` + odp.GetName() + `"` - g.P(fname, " ", dname, " `", tag, "`") + otag := `protobuf_oneof:"` + odp.GetName() + `"` + g.P(fname, " ", dname, " `", otag, "`") } if *field.Type == descriptor.FieldDescriptorProto_TYPE_MESSAGE { @@ -2053,6 +2160,11 @@ func (g *Generator) generateMessage(message *Descriptor) { g.P("func (m *", ccTypeName, ") String() string { return ", g.Pkg["proto"], ".CompactTextString(m) }") } g.P("func (*", ccTypeName, ") ProtoMessage() {}") + var indexes []string + for m := message; m != nil; m = m.parent { + indexes = append([]string{strconv.Itoa(m.index)}, indexes...) + } + g.P("func (*", ccTypeName, ") Descriptor() ([]byte, []int) { return ", g.file.VarName(), ", []int{", strings.Join(indexes, ", "), "} }") // Extension support methods var hasExtensions, isMessageSet bool @@ -2178,6 +2290,25 @@ func (g *Generator) generateMessage(message *Descriptor) { log.Printf("don't know how to generate constant for %s", fieldname) continue } + + // hunt down the actual enum corresponding to the default + var enumValue *descriptor.EnumValueDescriptorProto + for _, ev := range enum.Value { + if def == ev.GetName() { + enumValue = ev + } + } + + if enumValue != nil { + if gogoproto.IsEnumValueCustomName(enumValue) { + def = gogoproto.GetEnumValueCustomName(enumValue) + } + } else { + g.Fail(fmt.Sprintf("could not resolve default enum value for %v.%v", + g.DefaultPackageName(obj), def)) + + } + if gogoproto.EnabledGoEnumPrefix(enum.file, enum.EnumDescriptorProto) { def = g.DefaultPackageName(obj) + enum.prefix() + def } else { @@ -2397,6 +2528,10 @@ func (g *Generator) generateMessage(message *Descriptor) { g.P("return 0 // empty enum") } else { first := enum.Value[0].GetName() + if gogoproto.IsEnumValueCustomName(enum.Value[0]) { + first = gogoproto.GetEnumValueCustomName(enum.Value[0]) + } + if gogoproto.EnabledGoEnumPrefix(enum.file, enum.EnumDescriptorProto) { g.P("return ", g.DefaultPackageName(obj)+enum.prefix()+first) } else { @@ -2430,12 +2565,14 @@ func (g *Generator) generateMessage(message *Descriptor) { // method enc := "_" + ccTypeName + "_OneofMarshaler" dec := "_" + ccTypeName + "_OneofUnmarshaler" + size := "_" + ccTypeName + "_OneofSizer" encSig := "(msg " + g.Pkg["proto"] + ".Message, b *" + g.Pkg["proto"] + ".Buffer) error" decSig := "(msg " + g.Pkg["proto"] + ".Message, tag, wire int, b *" + g.Pkg["proto"] + ".Buffer) (bool, error)" + sizeSig := "(msg " + g.Pkg["proto"] + ".Message) (n int)" g.P("// XXX_OneofFuncs is for the internal use of the proto package.") - g.P("func (*", ccTypeName, ") XXX_OneofFuncs() (func", encSig, ", func", decSig, ", []interface{}) {") - g.P("return ", enc, ", ", dec, ", []interface{}{") + g.P("func (*", ccTypeName, ") XXX_OneofFuncs() (func", encSig, ", func", decSig, ", func", sizeSig, ", []interface{}) {") + g.P("return ", enc, ", ", dec, ", ", size, ", []interface{}{") for _, field := range message.Field { if field.OneofIndex == nil { continue @@ -2655,6 +2792,94 @@ func (g *Generator) generateMessage(message *Descriptor) { g.P("}") g.P("}") g.P() + + // sizer + g.P("func ", size, sizeSig, " {") + g.P("m := msg.(*", ccTypeName, ")") + for oi, odp := range message.OneofDecl { + g.P("// ", odp.GetName()) + fname := oneofFieldName[int32(oi)] + g.P("switch x := m.", fname, ".(type) {") + for _, field := range message.Field { + if field.OneofIndex == nil || int(*field.OneofIndex) != oi { + continue + } + g.P("case *", oneofTypeName[field], ":") + val := "x." + fieldNames[field] + var wire, varint, fixed string + switch *field.Type { + case descriptor.FieldDescriptorProto_TYPE_DOUBLE: + wire = "WireFixed64" + fixed = "8" + case descriptor.FieldDescriptorProto_TYPE_FLOAT: + wire = "WireFixed32" + fixed = "4" + case descriptor.FieldDescriptorProto_TYPE_INT64, + descriptor.FieldDescriptorProto_TYPE_UINT64, + descriptor.FieldDescriptorProto_TYPE_INT32, + descriptor.FieldDescriptorProto_TYPE_UINT32, + descriptor.FieldDescriptorProto_TYPE_ENUM: + wire = "WireVarint" + varint = val + case descriptor.FieldDescriptorProto_TYPE_FIXED64, + descriptor.FieldDescriptorProto_TYPE_SFIXED64: + wire = "WireFixed64" + fixed = "8" + case descriptor.FieldDescriptorProto_TYPE_FIXED32, + descriptor.FieldDescriptorProto_TYPE_SFIXED32: + wire = "WireFixed32" + fixed = "4" + case descriptor.FieldDescriptorProto_TYPE_BOOL: + wire = "WireVarint" + fixed = "1" + case descriptor.FieldDescriptorProto_TYPE_STRING: + wire = "WireBytes" + fixed = "len(" + val + ")" + varint = fixed + case descriptor.FieldDescriptorProto_TYPE_GROUP: + wire = "WireStartGroup" + fixed = g.Pkg["proto"] + ".Size(" + val + ")" + case descriptor.FieldDescriptorProto_TYPE_MESSAGE: + wire = "WireBytes" + g.P("s := ", g.Pkg["proto"], ".Size(", val, ")") + fixed = "s" + varint = fixed + case descriptor.FieldDescriptorProto_TYPE_BYTES: + wire = "WireBytes" + if gogoproto.IsCustomType(field) { + fixed = val + ".Size()" + } else { + fixed = "len(" + val + ")" + } + varint = fixed + case descriptor.FieldDescriptorProto_TYPE_SINT32: + wire = "WireVarint" + varint = "(uint32(" + val + ") << 1) ^ uint32((int32(" + val + ") >> 31))" + case descriptor.FieldDescriptorProto_TYPE_SINT64: + wire = "WireVarint" + varint = "uint64(" + val + " << 1) ^ uint64((int64(" + val + ") >> 63))" + default: + g.Fail("unhandled oneof field type ", field.Type.String()) + } + g.P("n += ", g.Pkg["proto"], ".SizeVarint(", field.Number, "<<3|", g.Pkg["proto"], ".", wire, ")") + if varint != "" { + g.P("n += ", g.Pkg["proto"], ".SizeVarint(uint64(", varint, "))") + } + if fixed != "" { + g.P("n += ", fixed) + } + if *field.Type == descriptor.FieldDescriptorProto_TYPE_GROUP { + g.P("n += ", g.Pkg["proto"], ".SizeVarint(", field.Number, "<<3|", g.Pkg["proto"], ".WireEndGroup)") + } + } + g.P("case nil:") + g.P("default:") + g.P("panic(", g.Pkg["fmt"], ".Sprintf(\"proto: unexpected type %T in oneof\", x))") + g.P("}") + } + g.P("return n") + g.P("}") + g.P() } for _, ext := range message.ext { @@ -2754,6 +2979,46 @@ func (g *Generator) generateInitFunction() { g.init = nil } +func (g *Generator) generateFileDescriptor(file *FileDescriptor) { + // Make a copy and trim source_code_info data. + // TODO: Trim this more when we know exactly what we need. + pb := proto.Clone(file.FileDescriptorProto).(*descriptor.FileDescriptorProto) + pb.SourceCodeInfo = nil + + b, err := proto.Marshal(pb) + if err != nil { + g.Fail(err.Error()) + } + + var buf bytes.Buffer + w, _ := gzip.NewWriterLevel(&buf, gzip.BestCompression) + w.Write(b) + w.Close() + b = buf.Bytes() + + v := file.VarName() + g.P() + g.P("var ", v, " = []byte{") + g.In() + g.P("// ", len(b), " bytes of a gzipped FileDescriptorProto") + for len(b) > 0 { + n := 16 + if n > len(b) { + n = len(b) + } + + s := "" + for _, c := range b[:n] { + s += fmt.Sprintf("0x%02x,", c) + } + g.P(s) + + b = b[n:] + } + g.Out() + g.P("}") +} + func (g *Generator) generateEnumRegistration(enum *EnumDescriptor) { // // We always print the full (proto-world) package name here. pkg := enum.File().GetPackage() @@ -2837,15 +3102,6 @@ func CamelCaseSlice(elem []string) string { return CamelCase(strings.Join(elem, // dottedSlice turns a sliced name into a dotted name. func dottedSlice(elem []string) string { return strings.Join(elem, ".") } -// Given a .proto file name, return the output name for the generated Go program. -func goFileName(name string) string { - ext := path.Ext(name) - if ext == ".proto" || ext == ".protodevel" { - name = name[0 : len(name)-len(ext)] - } - return name + ".pb.go" -} - // Is this field optional? func isOptional(field *descriptor.FieldDescriptorProto) bool { return field.Label != nil && *field.Label == descriptor.FieldDescriptorProto_LABEL_OPTIONAL diff --git a/vendor/github.com/gogo/protobuf/protoc-gen-gogo/generator/helper.go b/vendor/github.com/gogo/protobuf/protoc-gen-gogo/generator/helper.go index 258d6a9b6af..07f955f265a 100644 --- a/vendor/github.com/gogo/protobuf/protoc-gen-gogo/generator/helper.go +++ b/vendor/github.com/gogo/protobuf/protoc-gen-gogo/generator/helper.go @@ -31,9 +31,8 @@ import ( "go/parser" "go/printer" "go/token" - "strings" - "path" + "strings" "github.com/gogo/protobuf/gogoproto" "github.com/gogo/protobuf/proto" @@ -211,25 +210,6 @@ func (g *Generator) GetOneOfFieldName(message *Descriptor, field *descriptor.Fie return fieldname } -func GetMap(file *descriptor.FileDescriptorProto, field *descriptor.FieldDescriptorProto) *descriptor.DescriptorProto { - if !field.IsMessage() { - return nil - } - typeName := strings.TrimPrefix(field.GetTypeName(), "."+file.GetPackage()+".") - if strings.Contains(typeName, "Map") && !strings.HasSuffix(typeName, "Entry") { - typeName += "." + CamelCase(field.GetName()) + "Entry" - } - return file.GetMessage(typeName) -} - -func IsMap(file *descriptor.FileDescriptorProto, field *descriptor.FieldDescriptorProto) bool { - msg := GetMap(file, field) - if msg == nil { - return false - } - return msg.GetOptions().GetMapEntry() -} - func (g *Generator) IsMap(field *descriptor.FieldDescriptorProto) bool { if !field.IsMessage() { return false @@ -322,7 +302,6 @@ func (g *Generator) GeneratePlugin(p Plugin) { for _, file := range g.genFiles { genFileMap[file] = true } - i := 0 for _, file := range g.allFiles { g.Reset() g.writeOutput = genFileMap[file] @@ -330,10 +309,10 @@ func (g *Generator) GeneratePlugin(p Plugin) { if !g.writeOutput { continue } - g.Response.File[i] = new(plugin.CodeGeneratorResponse_File) - g.Response.File[i].Name = proto.String(goFileName(*file.Name)) - g.Response.File[i].Content = proto.String(g.String()) - i++ + g.Response.File = append(g.Response.File, &plugin.CodeGeneratorResponse_File{ + Name: proto.String(file.goFileName()), + Content: proto.String(g.String()), + }) } } @@ -447,6 +426,7 @@ func FileName(file *FileDescriptor) string { fname := path.Base(file.FileDescriptorProto.GetName()) fname = strings.Replace(fname, ".proto", "", -1) fname = strings.Replace(fname, "-", "_", -1) + fname = strings.Replace(fname, ".", "_", -1) return CamelCase(fname) } diff --git a/vendor/github.com/gogo/protobuf/plugin/grpc/grpc.go b/vendor/github.com/gogo/protobuf/protoc-gen-gogo/grpc/grpc.go similarity index 89% rename from vendor/github.com/gogo/protobuf/plugin/grpc/grpc.go rename to vendor/github.com/gogo/protobuf/protoc-gen-gogo/grpc/grpc.go index d769adc9a69..4b8c9dd2cfa 100644 --- a/vendor/github.com/gogo/protobuf/plugin/grpc/grpc.go +++ b/vendor/github.com/gogo/protobuf/protoc-gen-gogo/grpc/grpc.go @@ -44,6 +44,12 @@ import ( "github.com/gogo/protobuf/protoc-gen-gogo/generator" ) +// generatedCodeVersion indicates a version of the generated code. +// It is incremented whenever an incompatibility between the generated code and +// the grpc package is introduced; the generated code references +// a constant, grpc.SupportPackageIsVersionN (where N is generatedCodeVersion). +const generatedCodeVersion = 3 + // Paths for packages used by code generated in this file, // relative to the import_prefix of the generator.Generator. const ( @@ -101,10 +107,18 @@ func (g *grpc) Generate(file *generator.FileDescriptor) { if len(file.FileDescriptorProto.Service) == 0 { return } + g.P("// Reference imports to suppress errors if they are not otherwise used.") g.P("var _ ", contextPkg, ".Context") g.P("var _ ", grpcPkg, ".ClientConn") g.P() + + // Assert version compatibility. + g.P("// This is a compile-time assertion to ensure that this generated file") + g.P("// is compatible with the grpc package it is being compiled against.") + g.P("const _ = ", grpcPkg, ".SupportPackageIsVersion", generatedCodeVersion) + g.P() + for i, service := range file.FileDescriptorProto.Service { g.generateService(file, service, i) } @@ -134,7 +148,10 @@ func (g *grpc) generateService(file *generator.FileDescriptor, service *pb.Servi path := fmt.Sprintf("6,%d", index) // 6 means service. origServName := service.GetName() - fullServName := file.GetPackage() + "." + origServName + fullServName := origServName + if pkg := file.GetPackage(); pkg != "" { + fullServName = pkg + "." + fullServName + } servName := generator.CamelCase(origServName) g.P() @@ -201,7 +218,7 @@ func (g *grpc) generateService(file *generator.FileDescriptor, service *pb.Servi // Server handler implementations. var handlerNames []string for _, method := range service.Method { - hname := g.generateServerMethod(servName, method) + hname := g.generateServerMethod(servName, fullServName, method) handlerNames = append(handlerNames, hname) } @@ -237,6 +254,7 @@ func (g *grpc) generateService(file *generator.FileDescriptor, service *pb.Servi g.P("},") } g.P("},") + g.P("Metadata: ", file.VarName(), ",") g.P("}") g.P() } @@ -361,19 +379,25 @@ func (g *grpc) generateServerSignature(servName string, method *pb.MethodDescrip return methName + "(" + strings.Join(reqArgs, ", ") + ") " + ret } -func (g *grpc) generateServerMethod(servName string, method *pb.MethodDescriptorProto) string { +func (g *grpc) generateServerMethod(servName, fullServName string, method *pb.MethodDescriptorProto) string { methName := generator.CamelCase(method.GetName()) hname := fmt.Sprintf("_%s_%s_Handler", servName, methName) inType := g.typeName(method.GetInputType()) outType := g.typeName(method.GetOutputType()) if !method.GetServerStreaming() && !method.GetClientStreaming() { - g.P("func ", hname, "(srv interface{}, ctx ", contextPkg, ".Context, dec func(interface{}) error) (interface{}, error) {") + g.P("func ", hname, "(srv interface{}, ctx ", contextPkg, ".Context, dec func(interface{}) error, interceptor ", grpcPkg, ".UnaryServerInterceptor) (interface{}, error) {") g.P("in := new(", inType, ")") g.P("if err := dec(in); err != nil { return nil, err }") - g.P("out, err := srv.(", servName, "Server).", methName, "(ctx, in)") - g.P("if err != nil { return nil, err }") - g.P("return out, nil") + g.P("if interceptor == nil { return srv.(", servName, "Server).", methName, "(ctx, in) }") + g.P("info := &", grpcPkg, ".UnaryServerInfo{") + g.P("Server: srv,") + g.P("FullMethod: ", strconv.Quote(fmt.Sprintf("/%s/%s", fullServName, methName)), ",") + g.P("}") + g.P("handler := func(ctx ", contextPkg, ".Context, req interface{}) (interface{}, error) {") + g.P("return srv.(", servName, "Server).", methName, "(ctx, req.(*", inType, "))") + g.P("}") + g.P("return interceptor(ctx, in, info, handler)") g.P("}") g.P() return hname diff --git a/vendor/github.com/gogo/protobuf/protoc-gen-gogo/plugin/plugin.pb.go b/vendor/github.com/gogo/protobuf/protoc-gen-gogo/plugin/plugin.pb.go index 8e8ebf7069e..6195da80e6e 100644 --- a/vendor/github.com/gogo/protobuf/protoc-gen-gogo/plugin/plugin.pb.go +++ b/vendor/github.com/gogo/protobuf/protoc-gen-gogo/plugin/plugin.pb.go @@ -24,12 +24,16 @@ var _ = proto.Marshal var _ = fmt.Errorf 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.GoGoProtoPackageIsVersion1 + // An encoded CodeGeneratorRequest is written to the plugin's stdin. type CodeGeneratorRequest struct { // The .proto files that were explicitly listed on the command-line. The // code generator should generate code only for these files. Each file's // descriptor will be included in proto_file, below. - FileToGenerate []string `protobuf:"bytes,1,rep,name=file_to_generate" json:"file_to_generate,omitempty"` + FileToGenerate []string `protobuf:"bytes,1,rep,name=file_to_generate,json=fileToGenerate" json:"file_to_generate,omitempty"` // The generator parameter passed on the command-line. Parameter *string `protobuf:"bytes,2,opt,name=parameter" json:"parameter,omitempty"` // FileDescriptorProtos for all files in files_to_generate and everything @@ -43,13 +47,14 @@ type CodeGeneratorRequest struct { // the entire set into memory at once. However, as of this writing, this // is not similarly optimized on protoc's end -- it will store all fields in // memory at once before sending them to the plugin. - ProtoFile []*google_protobuf.FileDescriptorProto `protobuf:"bytes,15,rep,name=proto_file" json:"proto_file,omitempty"` + ProtoFile []*google_protobuf.FileDescriptorProto `protobuf:"bytes,15,rep,name=proto_file,json=protoFile" json:"proto_file,omitempty"` XXX_unrecognized []byte `json:"-"` } -func (m *CodeGeneratorRequest) Reset() { *m = CodeGeneratorRequest{} } -func (m *CodeGeneratorRequest) String() string { return proto.CompactTextString(m) } -func (*CodeGeneratorRequest) ProtoMessage() {} +func (m *CodeGeneratorRequest) Reset() { *m = CodeGeneratorRequest{} } +func (m *CodeGeneratorRequest) String() string { return proto.CompactTextString(m) } +func (*CodeGeneratorRequest) ProtoMessage() {} +func (*CodeGeneratorRequest) Descriptor() ([]byte, []int) { return fileDescriptorPlugin, []int{0} } func (m *CodeGeneratorRequest) GetFileToGenerate() []string { if m != nil { @@ -87,9 +92,10 @@ type CodeGeneratorResponse struct { XXX_unrecognized []byte `json:"-"` } -func (m *CodeGeneratorResponse) Reset() { *m = CodeGeneratorResponse{} } -func (m *CodeGeneratorResponse) String() string { return proto.CompactTextString(m) } -func (*CodeGeneratorResponse) ProtoMessage() {} +func (m *CodeGeneratorResponse) Reset() { *m = CodeGeneratorResponse{} } +func (m *CodeGeneratorResponse) String() string { return proto.CompactTextString(m) } +func (*CodeGeneratorResponse) ProtoMessage() {} +func (*CodeGeneratorResponse) Descriptor() ([]byte, []int) { return fileDescriptorPlugin, []int{1} } func (m *CodeGeneratorResponse) GetError() string { if m != nil && m.Error != nil { @@ -156,7 +162,7 @@ type CodeGeneratorResponse_File struct { // command line. // // If |insertion_point| is present, |name| must also be present. - InsertionPoint *string `protobuf:"bytes,2,opt,name=insertion_point" json:"insertion_point,omitempty"` + InsertionPoint *string `protobuf:"bytes,2,opt,name=insertion_point,json=insertionPoint" json:"insertion_point,omitempty"` // The file contents. Content *string `protobuf:"bytes,15,opt,name=content" json:"content,omitempty"` XXX_unrecognized []byte `json:"-"` @@ -165,6 +171,9 @@ type CodeGeneratorResponse_File struct { func (m *CodeGeneratorResponse_File) Reset() { *m = CodeGeneratorResponse_File{} } func (m *CodeGeneratorResponse_File) String() string { return proto.CompactTextString(m) } func (*CodeGeneratorResponse_File) ProtoMessage() {} +func (*CodeGeneratorResponse_File) Descriptor() ([]byte, []int) { + return fileDescriptorPlugin, []int{1, 0} +} func (m *CodeGeneratorResponse_File) GetName() string { if m != nil && m.Name != nil { @@ -192,3 +201,26 @@ func init() { proto.RegisterType((*CodeGeneratorResponse)(nil), "google.protobuf.compiler.CodeGeneratorResponse") proto.RegisterType((*CodeGeneratorResponse_File)(nil), "google.protobuf.compiler.CodeGeneratorResponse.File") } + +var fileDescriptorPlugin = []byte{ + // 304 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x74, 0x51, 0x4f, 0x4b, 0xfb, 0x40, + 0x14, 0x24, 0xbf, 0x5f, 0x44, 0xf2, 0x2c, 0x8d, 0x2c, 0x15, 0x42, 0xe9, 0x21, 0x14, 0xc1, 0x9e, + 0x52, 0x10, 0xc1, 0x7b, 0x2b, 0xea, 0x31, 0x04, 0x4f, 0x82, 0x84, 0x98, 0xbe, 0x86, 0x85, 0x74, + 0xdf, 0xba, 0xd9, 0x7c, 0x22, 0xbf, 0x93, 0x9f, 0xc7, 0xfd, 0x93, 0x56, 0x29, 0xf6, 0x94, 0xbc, + 0x99, 0xd9, 0x99, 0xd9, 0x7d, 0x30, 0x92, 0x6d, 0xdf, 0x70, 0x91, 0x49, 0x45, 0x9a, 0x58, 0xd2, + 0x10, 0x35, 0x2d, 0xfa, 0xe9, 0xbd, 0xdf, 0x66, 0x35, 0xed, 0x24, 0x6f, 0x51, 0x4d, 0x53, 0xcf, + 0x2c, 0xf7, 0xcc, 0x72, 0x83, 0x5d, 0xad, 0xb8, 0xd4, 0xa4, 0xbc, 0x7a, 0xfe, 0x19, 0xc0, 0x64, + 0x4d, 0x1b, 0x7c, 0x42, 0x81, 0xaa, 0x32, 0x78, 0x81, 0x1f, 0x3d, 0x76, 0x9a, 0x2d, 0xe0, 0x72, + 0x6b, 0x3c, 0x4a, 0x4d, 0x65, 0xe3, 0x39, 0x4c, 0x82, 0xf4, 0xff, 0x22, 0x2a, 0xc6, 0x16, 0x7f, + 0xa1, 0xe1, 0x04, 0xb2, 0x19, 0x44, 0xb2, 0x52, 0xd5, 0x0e, 0x35, 0xaa, 0xe4, 0x5f, 0x1a, 0x18, + 0xc9, 0x0f, 0xc0, 0xd6, 0x00, 0x2e, 0xa9, 0xb4, 0xa7, 0x92, 0xd8, 0x38, 0x5c, 0xdc, 0x5e, 0x67, + 0xc7, 0x8d, 0x1f, 0x0d, 0xf9, 0x70, 0xe8, 0x96, 0x5b, 0xd8, 0x98, 0xd8, 0x8f, 0x65, 0xe6, 0x5f, + 0x01, 0x5c, 0x1d, 0xb5, 0xec, 0x24, 0x89, 0x0e, 0xd9, 0x04, 0xce, 0x50, 0x29, 0x52, 0xa6, 0x9b, + 0x0d, 0xf6, 0x03, 0x7b, 0x86, 0xf0, 0x57, 0xdc, 0x5d, 0x76, 0xea, 0x81, 0xb2, 0x3f, 0x4d, 0x5d, + 0x9b, 0xc2, 0x39, 0x4c, 0xdf, 0x20, 0xb4, 0x13, 0x63, 0x10, 0x0a, 0x73, 0xa3, 0x21, 0xc6, 0xfd, + 0xb3, 0x1b, 0x88, 0xb9, 0x91, 0x2b, 0xcd, 0x49, 0x94, 0x92, 0xb8, 0xd0, 0xc3, 0xf5, 0xc7, 0x07, + 0x38, 0xb7, 0x28, 0x4b, 0xe0, 0xbc, 0x26, 0xa1, 0xd1, 0x08, 0x62, 0x27, 0xd8, 0x8f, 0xab, 0x7b, + 0x98, 0x99, 0x2e, 0x27, 0xfb, 0xad, 0x46, 0xb9, 0x5b, 0xb4, 0x7b, 0x90, 0xee, 0x35, 0xf2, 0x6b, + 0x2f, 0x1b, 0xfa, 0x0e, 0x00, 0x00, 0xff, 0xff, 0x70, 0xa2, 0xbd, 0x30, 0x02, 0x02, 0x00, 0x00, +} diff --git a/vendor/github.com/gogo/protobuf/vanity/command/command.go b/vendor/github.com/gogo/protobuf/vanity/command/command.go index 2c6191477a8..7e8368aa39e 100644 --- a/vendor/github.com/gogo/protobuf/vanity/command/command.go +++ b/vendor/github.com/gogo/protobuf/vanity/command/command.go @@ -36,8 +36,9 @@ import ( "github.com/gogo/protobuf/protoc-gen-gogo/generator" plugin "github.com/gogo/protobuf/protoc-gen-gogo/plugin" - _ "github.com/gogo/protobuf/plugin/grpc" + _ "github.com/gogo/protobuf/protoc-gen-gogo/grpc" + _ "github.com/gogo/protobuf/plugin/compare" _ "github.com/gogo/protobuf/plugin/defaultcheck" _ "github.com/gogo/protobuf/plugin/description" _ "github.com/gogo/protobuf/plugin/embedcheck" diff --git a/vendor/github.com/gogo/protobuf/vanity/file.go b/vendor/github.com/gogo/protobuf/vanity/file.go index cfe18f208bb..d82fcdabba1 100644 --- a/vendor/github.com/gogo/protobuf/vanity/file.go +++ b/vendor/github.com/gogo/protobuf/vanity/file.go @@ -29,10 +29,11 @@ package vanity import ( + "strings" + "github.com/gogo/protobuf/gogoproto" "github.com/gogo/protobuf/proto" descriptor "github.com/gogo/protobuf/protoc-gen-gogo/descriptor" - "strings" ) func NotInPackageGoogleProtobuf(file *descriptor.FileDescriptorProto) bool { @@ -137,6 +138,10 @@ func TurnOnUnmarshalerAll(file *descriptor.FileDescriptorProto) { SetBoolFileOption(gogoproto.E_UnmarshalerAll, true)(file) } +func TurnOnStable_MarshalerAll(file *descriptor.FileDescriptorProto) { + SetBoolFileOption(gogoproto.E_StableMarshalerAll, true)(file) +} + func TurnOnSizerAll(file *descriptor.FileDescriptorProto) { SetBoolFileOption(gogoproto.E_SizerAll, true)(file) } diff --git a/vendor/github.com/golang/protobuf/jsonpb/jsonpb.go b/vendor/github.com/golang/protobuf/jsonpb/jsonpb.go new file mode 100644 index 00000000000..6308548cb93 --- /dev/null +++ b/vendor/github.com/golang/protobuf/jsonpb/jsonpb.go @@ -0,0 +1,799 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2015 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 jsonpb provides marshaling and unmarshaling between protocol buffers and JSON. +It follows the specification at https://developers.google.com/protocol-buffers/docs/proto3#json. + +This package produces a different output than the standard "encoding/json" package, +which does not operate correctly on protocol buffers. +*/ +package jsonpb + +import ( + "bytes" + "encoding/json" + "errors" + "fmt" + "io" + "reflect" + "sort" + "strconv" + "strings" + "time" + + "github.com/golang/protobuf/proto" +) + +// Marshaler is a configurable object for converting between +// protocol buffer objects and a JSON representation for them. +type Marshaler struct { + // Whether to render enum values as integers, as opposed to string values. + EnumsAsInts bool + + // Whether to render fields with zero values. + EmitDefaults bool + + // A string to indent each level by. The presence of this field will + // also cause a space to appear between the field separator and + // value, and for newlines to be appear between fields and array + // elements. + Indent string + + // Whether to use the original (.proto) name for fields. + OrigName bool +} + +// Marshal marshals a protocol buffer into JSON. +func (m *Marshaler) Marshal(out io.Writer, pb proto.Message) error { + writer := &errWriter{writer: out} + return m.marshalObject(writer, pb, "", "") +} + +// MarshalToString converts a protocol buffer object to JSON string. +func (m *Marshaler) MarshalToString(pb proto.Message) (string, error) { + var buf bytes.Buffer + if err := m.Marshal(&buf, pb); err != nil { + return "", err + } + return buf.String(), nil +} + +type int32Slice []int32 + +// For sorting extensions ids to ensure stable output. +func (s int32Slice) Len() int { return len(s) } +func (s int32Slice) Less(i, j int) bool { return s[i] < s[j] } +func (s int32Slice) Swap(i, j int) { s[i], s[j] = s[j], s[i] } + +type wkt interface { + XXX_WellKnownType() string +} + +// marshalObject writes a struct to the Writer. +func (m *Marshaler) marshalObject(out *errWriter, v proto.Message, indent, typeURL string) error { + s := reflect.ValueOf(v).Elem() + + // Handle well-known types. + if wkt, ok := v.(wkt); ok { + switch wkt.XXX_WellKnownType() { + case "DoubleValue", "FloatValue", "Int64Value", "UInt64Value", + "Int32Value", "UInt32Value", "BoolValue", "StringValue", "BytesValue": + // "Wrappers use the same representation in JSON + // as the wrapped primitive type, ..." + sprop := proto.GetProperties(s.Type()) + return m.marshalValue(out, sprop.Prop[0], s.Field(0), indent) + case "Any": + // Any is a bit more involved. + return m.marshalAny(out, v, indent) + case "Duration": + // "Generated output always contains 3, 6, or 9 fractional digits, + // depending on required precision." + s, ns := s.Field(0).Int(), s.Field(1).Int() + d := time.Duration(s)*time.Second + time.Duration(ns)*time.Nanosecond + x := fmt.Sprintf("%.9f", d.Seconds()) + x = strings.TrimSuffix(x, "000") + x = strings.TrimSuffix(x, "000") + out.write(`"`) + out.write(x) + out.write(`s"`) + return out.err + case "Struct": + // Let marshalValue handle the `fields` map. + // TODO: pass the correct Properties if needed. + return m.marshalValue(out, &proto.Properties{}, s.Field(0), indent) + case "Timestamp": + // "RFC 3339, where generated output will always be Z-normalized + // and uses 3, 6 or 9 fractional digits." + s, ns := s.Field(0).Int(), s.Field(1).Int() + t := time.Unix(s, ns).UTC() + // time.RFC3339Nano isn't exactly right (we need to get 3/6/9 fractional digits). + x := t.Format("2006-01-02T15:04:05.000000000") + x = strings.TrimSuffix(x, "000") + x = strings.TrimSuffix(x, "000") + out.write(`"`) + out.write(x) + out.write(`Z"`) + return out.err + case "Value": + // Value has a single oneof. + kind := s.Field(0) + if kind.IsNil() { + // "absence of any variant indicates an error" + return errors.New("nil Value") + } + // oneof -> *T -> T -> T.F + x := kind.Elem().Elem().Field(0) + // TODO: pass the correct Properties if needed. + return m.marshalValue(out, &proto.Properties{}, x, indent) + } + } + + out.write("{") + if m.Indent != "" { + out.write("\n") + } + + firstField := true + + if typeURL != "" { + if err := m.marshalTypeURL(out, indent, typeURL); err != nil { + return err + } + firstField = false + } + + for i := 0; i < s.NumField(); i++ { + value := s.Field(i) + valueField := s.Type().Field(i) + if strings.HasPrefix(valueField.Name, "XXX_") { + continue + } + + // IsNil will panic on most value kinds. + switch value.Kind() { + case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice: + if value.IsNil() { + continue + } + } + + if !m.EmitDefaults { + switch value.Kind() { + case reflect.Bool: + if !value.Bool() { + continue + } + case reflect.Int32, reflect.Int64: + if value.Int() == 0 { + continue + } + case reflect.Uint32, reflect.Uint64: + if value.Uint() == 0 { + continue + } + case reflect.Float32, reflect.Float64: + if value.Float() == 0 { + continue + } + case reflect.String: + if value.Len() == 0 { + continue + } + } + } + + // Oneof fields need special handling. + if valueField.Tag.Get("protobuf_oneof") != "" { + // value is an interface containing &T{real_value}. + sv := value.Elem().Elem() // interface -> *T -> T + value = sv.Field(0) + valueField = sv.Type().Field(0) + } + prop := jsonProperties(valueField, m.OrigName) + if !firstField { + m.writeSep(out) + } + if err := m.marshalField(out, prop, value, indent); err != nil { + return err + } + firstField = false + } + + // Handle proto2 extensions. + if ep, ok := v.(proto.Message); ok { + extensions := proto.RegisteredExtensions(v) + // Sort extensions for stable output. + ids := make([]int32, 0, len(extensions)) + for id, desc := range extensions { + if !proto.HasExtension(ep, desc) { + continue + } + ids = append(ids, id) + } + sort.Sort(int32Slice(ids)) + for _, id := range ids { + desc := extensions[id] + if desc == nil { + // unknown extension + continue + } + ext, extErr := proto.GetExtension(ep, desc) + if extErr != nil { + return extErr + } + value := reflect.ValueOf(ext) + var prop proto.Properties + prop.Parse(desc.Tag) + prop.JSONName = fmt.Sprintf("[%s]", desc.Name) + if !firstField { + m.writeSep(out) + } + if err := m.marshalField(out, &prop, value, indent); err != nil { + return err + } + firstField = false + } + + } + + if m.Indent != "" { + out.write("\n") + out.write(indent) + } + out.write("}") + return out.err +} + +func (m *Marshaler) writeSep(out *errWriter) { + if m.Indent != "" { + out.write(",\n") + } else { + out.write(",") + } +} + +func (m *Marshaler) marshalAny(out *errWriter, any proto.Message, indent string) error { + // "If the Any contains a value that has a special JSON mapping, + // it will be converted as follows: {"@type": xxx, "value": yyy}. + // Otherwise, the value will be converted into a JSON object, + // and the "@type" field will be inserted to indicate the actual data type." + v := reflect.ValueOf(any).Elem() + turl := v.Field(0).String() + val := v.Field(1).Bytes() + + // Only the part of type_url after the last slash is relevant. + mname := turl + if slash := strings.LastIndex(mname, "/"); slash >= 0 { + mname = mname[slash+1:] + } + mt := proto.MessageType(mname) + if mt == nil { + return fmt.Errorf("unknown message type %q", mname) + } + msg := reflect.New(mt.Elem()).Interface().(proto.Message) + if err := proto.Unmarshal(val, msg); err != nil { + return err + } + + if _, ok := msg.(wkt); ok { + out.write("{") + if m.Indent != "" { + out.write("\n") + } + if err := m.marshalTypeURL(out, indent, turl); err != nil { + return err + } + m.writeSep(out) + if m.Indent != "" { + out.write(indent) + out.write(m.Indent) + out.write(`"value": `) + } else { + out.write(`"value":`) + } + if err := m.marshalObject(out, msg, indent+m.Indent, ""); err != nil { + return err + } + if m.Indent != "" { + out.write("\n") + out.write(indent) + } + out.write("}") + return out.err + } + + return m.marshalObject(out, msg, indent, turl) +} + +func (m *Marshaler) marshalTypeURL(out *errWriter, indent, typeURL string) error { + if m.Indent != "" { + out.write(indent) + out.write(m.Indent) + } + out.write(`"@type":`) + if m.Indent != "" { + out.write(" ") + } + b, err := json.Marshal(typeURL) + if err != nil { + return err + } + out.write(string(b)) + return out.err +} + +// marshalField writes field description and value to the Writer. +func (m *Marshaler) marshalField(out *errWriter, prop *proto.Properties, v reflect.Value, indent string) error { + if m.Indent != "" { + out.write(indent) + out.write(m.Indent) + } + out.write(`"`) + out.write(prop.JSONName) + out.write(`":`) + if m.Indent != "" { + out.write(" ") + } + if err := m.marshalValue(out, prop, v, indent); err != nil { + return err + } + return nil +} + +// marshalValue writes the value to the Writer. +func (m *Marshaler) marshalValue(out *errWriter, prop *proto.Properties, v reflect.Value, indent string) error { + + var err error + v = reflect.Indirect(v) + + // Handle repeated elements. + if v.Kind() == reflect.Slice && v.Type().Elem().Kind() != reflect.Uint8 { + out.write("[") + comma := "" + for i := 0; i < v.Len(); i++ { + sliceVal := v.Index(i) + out.write(comma) + if m.Indent != "" { + out.write("\n") + out.write(indent) + out.write(m.Indent) + out.write(m.Indent) + } + if err := m.marshalValue(out, prop, sliceVal, indent+m.Indent); err != nil { + return err + } + comma = "," + } + if m.Indent != "" { + out.write("\n") + out.write(indent) + out.write(m.Indent) + } + out.write("]") + return out.err + } + + // Handle well-known types. + // Most are handled up in marshalObject (because 99% are messages). + type wkt interface { + XXX_WellKnownType() string + } + if wkt, ok := v.Interface().(wkt); ok { + switch wkt.XXX_WellKnownType() { + case "NullValue": + out.write("null") + return out.err + } + } + + // Handle enumerations. + if !m.EnumsAsInts && prop.Enum != "" { + // Unknown enum values will are stringified by the proto library as their + // value. Such values should _not_ be quoted or they will be interpreted + // as an enum string instead of their value. + enumStr := v.Interface().(fmt.Stringer).String() + var valStr string + if v.Kind() == reflect.Ptr { + valStr = strconv.Itoa(int(v.Elem().Int())) + } else { + valStr = strconv.Itoa(int(v.Int())) + } + isKnownEnum := enumStr != valStr + if isKnownEnum { + out.write(`"`) + } + out.write(enumStr) + if isKnownEnum { + out.write(`"`) + } + return out.err + } + + // Handle nested messages. + if v.Kind() == reflect.Struct { + return m.marshalObject(out, v.Addr().Interface().(proto.Message), indent+m.Indent, "") + } + + // Handle maps. + // Since Go randomizes map iteration, we sort keys for stable output. + if v.Kind() == reflect.Map { + out.write(`{`) + keys := v.MapKeys() + sort.Sort(mapKeys(keys)) + for i, k := range keys { + if i > 0 { + out.write(`,`) + } + if m.Indent != "" { + out.write("\n") + out.write(indent) + out.write(m.Indent) + out.write(m.Indent) + } + + b, err := json.Marshal(k.Interface()) + if err != nil { + return err + } + s := string(b) + + // If the JSON is not a string value, encode it again to make it one. + if !strings.HasPrefix(s, `"`) { + b, err := json.Marshal(s) + if err != nil { + return err + } + s = string(b) + } + + out.write(s) + out.write(`:`) + if m.Indent != "" { + out.write(` `) + } + + if err := m.marshalValue(out, prop, v.MapIndex(k), indent+m.Indent); err != nil { + return err + } + } + if m.Indent != "" { + out.write("\n") + out.write(indent) + out.write(m.Indent) + } + out.write(`}`) + return out.err + } + + // Default handling defers to the encoding/json library. + b, err := json.Marshal(v.Interface()) + if err != nil { + return err + } + needToQuote := string(b[0]) != `"` && (v.Kind() == reflect.Int64 || v.Kind() == reflect.Uint64) + if needToQuote { + out.write(`"`) + } + out.write(string(b)) + if needToQuote { + out.write(`"`) + } + return out.err +} + +// 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 { + inputValue := json.RawMessage{} + if err := dec.Decode(&inputValue); err != nil { + return err + } + return 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 Unmarshal(r io.Reader, pb proto.Message) error { + dec := json.NewDecoder(r) + return UnmarshalNext(dec, 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) +} + +// unmarshalValue converts/copies a value into the target. +// prop may be nil. +func 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) + } + + // Handle well-known types. + type wkt interface { + XXX_WellKnownType() string + } + if wkt, ok := target.Addr().Interface().(wkt); ok { + switch wkt.XXX_WellKnownType() { + case "DoubleValue", "FloatValue", "Int64Value", "UInt64Value", + "Int32Value", "UInt32Value", "BoolValue", "StringValue", "BytesValue": + // "Wrappers use the same representation in JSON + // 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) + case "Any": + return fmt.Errorf("unmarshaling Any not supported yet") + case "Duration": + unq, err := strconv.Unquote(string(inputValue)) + if err != nil { + return err + } + d, err := time.ParseDuration(unq) + if err != nil { + return fmt.Errorf("bad Duration: %v", err) + } + ns := d.Nanoseconds() + s := ns / 1e9 + ns %= 1e9 + target.Field(0).SetInt(s) + target.Field(1).SetInt(ns) + return nil + case "Timestamp": + unq, err := strconv.Unquote(string(inputValue)) + if err != nil { + return err + } + t, err := time.Parse(time.RFC3339Nano, unq) + 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) + return nil + } + } + + // Handle enums, which have an underlying type of int32, + // and may appear as strings. + // The case of an enum appearing as a number is handled + // at the bottom of this function. + if inputValue[0] == '"' && prop != nil && prop.Enum != "" { + vmap := proto.EnumValueMap(prop.Enum) + // Don't need to do unquoting; valid enum names + // are from a limited character set. + s := inputValue[1 : len(inputValue)-1] + n, ok := vmap[string(s)] + if !ok { + return fmt.Errorf("unknown value %q for enum %s", s, prop.Enum) + } + if target.Kind() == reflect.Ptr { // proto2 + target.Set(reflect.New(targetType.Elem())) + target = target.Elem() + } + target.SetInt(int64(n)) + return nil + } + + // Handle nested messages. + if targetType.Kind() == reflect.Struct { + var jsonFields map[string]json.RawMessage + if err := json.Unmarshal(inputValue, &jsonFields); err != nil { + return err + } + + consumeField := func(prop *proto.Properties) (json.RawMessage, bool) { + // Be liberal in what names we accept; both orig_name and camelName are okay. + fieldNames := acceptedJSONFieldNames(prop) + + vOrig, okOrig := jsonFields[fieldNames.orig] + vCamel, okCamel := jsonFields[fieldNames.camel] + if !okOrig && !okCamel { + return nil, false + } + // If, for some reason, both are present in the data, favour the camelName. + var raw json.RawMessage + if okOrig { + raw = vOrig + delete(jsonFields, fieldNames.orig) + } + if okCamel { + raw = vCamel + delete(jsonFields, fieldNames.camel) + } + return raw, true + } + + sprops := proto.GetProperties(targetType) + for i := 0; i < target.NumField(); i++ { + ft := target.Type().Field(i) + if strings.HasPrefix(ft.Name, "XXX_") { + continue + } + + valueForField, ok := consumeField(sprops.Prop[i]) + if !ok { + continue + } + + if err := unmarshalValue(target.Field(i), valueForField, sprops.Prop[i]); err != nil { + return err + } + } + // Check for any oneof fields. + if len(jsonFields) > 0 { + for _, oop := range sprops.OneofTypes { + raw, ok := consumeField(oop.Prop) + if !ok { + continue + } + nv := reflect.New(oop.Type.Elem()) + target.Field(oop.Field).Set(nv) + if err := unmarshalValue(nv.Elem().Field(0), raw, oop.Prop); err != nil { + return err + } + } + } + if len(jsonFields) > 0 { + // Pick any field to be the scapegoat. + var f string + for fname := range jsonFields { + f = fname + break + } + return fmt.Errorf("unknown field %q in %v", f, targetType) + } + return nil + } + + // Handle arrays (which aren't encoded bytes) + if targetType.Kind() == reflect.Slice && targetType.Elem().Kind() != reflect.Uint8 { + var slc []json.RawMessage + if err := json.Unmarshal(inputValue, &slc); err != nil { + return err + } + 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 { + return err + } + } + return nil + } + + // Handle maps (whose keys are always strings) + if targetType.Kind() == reflect.Map { + var mp map[string]json.RawMessage + if err := json.Unmarshal(inputValue, &mp); err != nil { + return err + } + target.Set(reflect.MakeMap(targetType)) + var keyprop, valprop *proto.Properties + if prop != nil { + // These could still be nil if the protobuf metadata is broken somehow. + // TODO: This won't work because the fields are unexported. + // We should probably just reparse them. + //keyprop, valprop = prop.mkeyprop, prop.mvalprop + } + for ks, raw := range mp { + // Unmarshal map key. The core json library already decoded the key into a + // string, so we handle that specially. Other types were quoted post-serialization. + var k reflect.Value + if targetType.Key().Kind() == reflect.String { + k = reflect.ValueOf(ks) + } else { + k = reflect.New(targetType.Key()).Elem() + if err := 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 { + return err + } + target.SetMapIndex(k, v) + } + return nil + } + + // 64-bit integers can be encoded as strings. In this case we drop + // the quotes and proceed as normal. + isNum := targetType.Kind() == reflect.Int64 || targetType.Kind() == reflect.Uint64 + if isNum && strings.HasPrefix(string(inputValue), `"`) { + inputValue = inputValue[1 : len(inputValue)-1] + } + + // Use the encoding/json for parsing other value types. + return json.Unmarshal(inputValue, target.Addr().Interface()) +} + +// jsonProperties returns parsed proto.Properties for the field and corrects JSONName attribute. +func jsonProperties(f reflect.StructField, origName bool) *proto.Properties { + var prop proto.Properties + prop.Init(f.Type, f.Name, f.Tag.Get("protobuf"), &f) + if origName || prop.JSONName == "" { + prop.JSONName = prop.OrigName + } + return &prop +} + +type fieldNames struct { + orig, camel string +} + +func acceptedJSONFieldNames(prop *proto.Properties) fieldNames { + opts := fieldNames{orig: prop.OrigName, camel: prop.OrigName} + if prop.JSONName != "" { + opts.camel = prop.JSONName + } + return opts +} + +// Writer wrapper inspired by https://blog.golang.org/errors-are-values +type errWriter struct { + writer io.Writer + err error +} + +func (w *errWriter) write(str string) { + if w.err != nil { + return + } + _, w.err = w.writer.Write([]byte(str)) +} + +// Map fields may have key types of non-float scalars, strings and enums. +// 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. +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 { + return fmt.Sprint(s[i].Interface()) < fmt.Sprint(s[j].Interface()) +} diff --git a/vendor/github.com/golang/protobuf/proto/Makefile b/vendor/github.com/golang/protobuf/proto/Makefile index f1f06564a15..e2e0651a934 100644 --- a/vendor/github.com/golang/protobuf/proto/Makefile +++ b/vendor/github.com/golang/protobuf/proto/Makefile @@ -39,5 +39,5 @@ test: install generate-test-pbs generate-test-pbs: make install make -C testdata - protoc --go_out=Mtestdata/test.proto=github.com/golang/protobuf/proto/testdata:. proto3_proto/proto3.proto + protoc --go_out=Mtestdata/test.proto=github.com/golang/protobuf/proto/testdata,Mgoogle/protobuf/any.proto=github.com/golang/protobuf/ptypes/any:. proto3_proto/proto3.proto make diff --git a/vendor/github.com/golang/protobuf/proto/clone.go b/vendor/github.com/golang/protobuf/proto/clone.go index e98ddec9815..e392575b353 100644 --- a/vendor/github.com/golang/protobuf/proto/clone.go +++ b/vendor/github.com/golang/protobuf/proto/clone.go @@ -84,9 +84,15 @@ func mergeStruct(out, in reflect.Value) { mergeAny(out.Field(i), in.Field(i), false, sprop.Prop[i]) } - if emIn, ok := in.Addr().Interface().(extendableProto); ok { - emOut := out.Addr().Interface().(extendableProto) - mergeExtension(emOut.ExtensionMap(), emIn.ExtensionMap()) + 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/golang/protobuf/proto/decode.go b/vendor/github.com/golang/protobuf/proto/decode.go index 5810782fd84..07288a250b4 100644 --- a/vendor/github.com/golang/protobuf/proto/decode.go +++ b/vendor/github.com/golang/protobuf/proto/decode.go @@ -390,11 +390,12 @@ 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 e, _ := extendable(structPointer_Interface(base, st)); isExtensionField(e, int32(tag)) { if err = o.skip(st, tag, wire); err == nil { - ext := e.ExtensionMap()[int32(tag)] // may be missing + extmap := e.extensionsWrite() + ext := extmap[int32(tag)] // may be missing ext.enc = append(ext.enc, o.buf[oi:o.index]...) - e.ExtensionMap()[int32(tag)] = ext + extmap[int32(tag)] = ext } continue } @@ -768,10 +769,11 @@ func (o *Buffer) dec_new_map(p *Properties, base structPointer) error { } } keyelem, valelem := keyptr.Elem(), valptr.Elem() - if !keyelem.IsValid() || !valelem.IsValid() { - // We did not decode the key or the value in the map entry. - // Either way, it's an invalid map entry. - return fmt.Errorf("proto: bad map data: missing key/val") + if !keyelem.IsValid() { + keyelem = reflect.Zero(p.mtype.Key()) + } + if !valelem.IsValid() { + valelem = reflect.Zero(p.mtype.Elem()) } v.SetMapIndex(keyelem, valelem) diff --git a/vendor/github.com/golang/protobuf/proto/encode.go b/vendor/github.com/golang/protobuf/proto/encode.go index 231b07401a3..8c1b8fd1f68 100644 --- a/vendor/github.com/golang/protobuf/proto/encode.go +++ b/vendor/github.com/golang/protobuf/proto/encode.go @@ -64,8 +64,16 @@ var ( // a struct with a repeated field containing a nil element. errRepeatedHasNil = errors.New("proto: repeated field has nil element") + // errOneofHasNil is the error returned if Marshal is called with + // a struct with a oneof field containing a nil element. + errOneofHasNil = errors.New("proto: oneof field has nil value") + // 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. @@ -74,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 @@ -273,6 +285,9 @@ func (p *Buffer) Marshal(pb Message) error { stats.Encode++ } + if len(p.buf) > maxMarshalSize { + return ErrTooLarge + } return err } @@ -1058,10 +1073,25 @@ 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) + if err := encodeExtensions(exts); err != nil { + return err + } + v, _ := exts.extensionsRead() + + 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 { @@ -1084,8 +1114,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. @@ -1114,7 +1149,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 @@ -1124,11 +1159,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) @@ -1216,13 +1246,18 @@ func (o *Buffer) enc_struct(prop *StructProperties, base structPointer) error { return err } } + if len(o.buf) > maxMarshalSize { + return ErrTooLarge + } } } // Do oneof fields. if prop.oneofMarshaler != nil { m := structPointer_Interface(base, prop.stype).(Message) - if err := prop.oneofMarshaler(m, o); err != nil { + if err := prop.oneofMarshaler(m, o); err == ErrNil { + return errOneofHasNil + } else if err != nil { return err } } @@ -1230,6 +1265,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/golang/protobuf/proto/equal.go b/vendor/github.com/golang/protobuf/proto/equal.go index f5db1def3c2..8b16f951c71 100644 --- a/vendor/github.com/golang/protobuf/proto/equal.go +++ b/vendor/github.com/golang/protobuf/proto/equal.go @@ -121,9 +121,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 +191,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 +237,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/golang/protobuf/proto/extensions.go b/vendor/github.com/golang/protobuf/proto/extensions.go index 054f4f1df78..9f484f53a3a 100644 --- a/vendor/github.com/golang/protobuf/proto/extensions.go +++ b/vendor/github.com/golang/protobuf/proto/extensions.go @@ -52,14 +52,99 @@ 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) +} + +// 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 } +// 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 +} + var extendableProtoType = reflect.TypeOf((*extendableProto)(nil)).Elem() +var extendableProtoV1Type = reflect.TypeOf((*extendableProtoV1)(nil)).Elem() // ExtensionDesc represents an extension specification. // Used in generated code from the protocol compiler. @@ -92,8 +177,13 @@ type Extension struct { } // SetRawExtension is for testing only. -func SetRawExtension(base extendableProto, id int32, b []byte) { - base.ExtensionMap()[id] = Extension{enc: b} +func SetRawExtension(base Message, id int32, b []byte) { + 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. @@ -108,8 +198,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. @@ -155,8 +249,19 @@ 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 { if e.value == nil || e.desc == nil { // Extension is only in its encoded form. @@ -184,7 +289,17 @@ func encodeExtensionMap(m map[int32]Extension) error { return nil } -func sizeExtensionMap(m map[int32]Extension) (n int) { +func extensionsSize(e *XXX_InternalExtensions) (n int) { + m, mu := e.extensionsRead() + if m == nil { + return 0 + } + mu.Lock() + defer mu.Unlock() + return extensionsMapSize(m) +} + +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. @@ -209,26 +324,51 @@ 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 { +func HasExtension(pb Message, extension *ExtensionDesc) bool { // TODO: Check types, field numbers, etc.? - _, ok := pb.ExtensionMap()[extension.Field] + 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 } // ClearExtension removes the given extension from pb. -func ClearExtension(pb extendableProto, extension *ExtensionDesc) { +func ClearExtension(pb Message, extension *ExtensionDesc) { + epb, ok := extendable(pb) + if !ok { + return + } // TODO: Check types, field numbers, etc.? - delete(pb.ExtensionMap(), extension.Field) + extmap := epb.extensionsWrite() + delete(extmap, extension.Field) } // GetExtension parses and returns the given extension of pb. // If the extension is not present and has no default value it returns ErrMissingExtension. -func GetExtension(pb extendableProto, extension *ExtensionDesc) (interface{}, error) { - if err := checkExtensionTypes(pb, extension); err != nil { +func GetExtension(pb Message, extension *ExtensionDesc) (interface{}, error) { + 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 := pb.ExtensionMap() + 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 @@ -332,10 +472,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) + epb, ok := extendable(pb) if !ok { - err = errors.New("proto: not an extendable proto") - return + return nil, errors.New("proto: not an extendable proto") } extensions = make([]interface{}, len(es)) for i, e := range es { @@ -351,8 +490,12 @@ func GetExtensions(pb Message, es []*ExtensionDesc) (extensions []interface{}, e } // 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 { + 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) @@ -368,10 +511,23 @@ func SetExtension(pb extendableProto, extension *ExtensionDesc, value interface{ return fmt.Errorf("proto: SetExtension called with nil value of type %T", value) } - pb.ExtensionMap()[extension.Field] = Extension{desc: extension, value: value} + extmap := epb.extensionsWrite() + extmap[extension.Field] = Extension{desc: extension, value: value} return nil } +// ClearAllExtensions clears all extensions from pb. +func ClearAllExtensions(pb Message) { + epb, ok := extendable(pb) + if !ok { + return + } + m := epb.extensionsWrite() + for k := range m { + delete(m, k) + } +} + // A global registry of extensions. // The generated code will register the generated descriptors by calling RegisterExtension. diff --git a/vendor/github.com/golang/protobuf/proto/lib.go b/vendor/github.com/golang/protobuf/proto/lib.go index 0de8f8dffd0..170b8e87d2e 100644 --- a/vendor/github.com/golang/protobuf/proto/lib.go +++ b/vendor/github.com/golang/protobuf/proto/lib.go @@ -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 ProtoPackageIsVersion2 = true + // ProtoPackageIsVersion1 is referenced from generated protocol buffer files // to assert that that code is compatible with this version of the proto package. const ProtoPackageIsVersion1 = true diff --git a/vendor/github.com/golang/protobuf/proto/message_set.go b/vendor/github.com/golang/protobuf/proto/message_set.go index e25e01e6374..fd982decd66 100644 --- a/vendor/github.com/golang/protobuf/proto/message_set.go +++ b/vendor/github.com/golang/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/golang/protobuf/proto/pointer_reflect.go b/vendor/github.com/golang/protobuf/proto/pointer_reflect.go index 749919d250a..fb512e2e16d 100644 --- a/vendor/github.com/golang/protobuf/proto/pointer_reflect.go +++ b/vendor/github.com/golang/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/golang/protobuf/proto/pointer_unsafe.go b/vendor/github.com/golang/protobuf/proto/pointer_unsafe.go index e9be0fe92ee..6b5567d47cd 100644 --- a/vendor/github.com/golang/protobuf/proto/pointer_unsafe.go +++ b/vendor/github.com/golang/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/golang/protobuf/proto/properties.go b/vendor/github.com/golang/protobuf/proto/properties.go index d4531c05638..69ddda8d4ba 100644 --- a/vendor/github.com/golang/protobuf/proto/properties.go +++ b/vendor/github.com/golang/protobuf/proto/properties.go @@ -173,6 +173,7 @@ func (sp *StructProperties) Swap(i, j int) { sp.order[i], sp.order[j] = sp.order type Properties struct { Name string // name of the field, for error messages OrigName string // original name before protocol compiler (always set) + JSONName string // name to use for JSON; determined by protoc Wire string WireType int Tag int @@ -229,8 +230,9 @@ func (p *Properties) String() string { if p.Packed { s += ",packed" } - if p.OrigName != p.Name { - s += ",name=" + p.OrigName + s += ",name=" + p.OrigName + if p.JSONName != p.OrigName { + s += ",json=" + p.JSONName } if p.proto3 { s += ",proto3" @@ -310,6 +312,8 @@ func (p *Properties) Parse(s string) { p.Packed = true case strings.HasPrefix(f, "name="): p.OrigName = f[5:] + case strings.HasPrefix(f, "json="): + p.JSONName = f[5:] case strings.HasPrefix(f, "enum="): p.Enum = f[5:] case f == "proto3": @@ -469,17 +473,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() { @@ -678,7 +678,8 @@ 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) prop.unrecField = invalidField prop.Prop = make([]*Properties, t.NumField()) prop.order = make([]int, t.NumField()) @@ -689,15 +690,22 @@ 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 p.enc = (*Buffer).enc_map 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 + oneof := f.Tag.Get("protobuf_oneof") // special case + if oneof != "" { + // Oneof fields don't use the traditional protobuf tag. + p.OrigName = oneof + } prop.Prop[i] = p prop.order[i] = i if debug { @@ -707,7 +715,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]") } } @@ -840,3 +848,17 @@ func MessageName(x Message) string { 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/golang/protobuf/proto/text.go b/vendor/github.com/golang/protobuf/proto/text.go index 2336b144c12..8214ce326b5 100644 --- a/vendor/github.com/golang/protobuf/proto/text.go +++ b/vendor/github.com/golang/protobuf/proto/text.go @@ -175,7 +175,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++ { @@ -227,7 +313,7 @@ func writeStruct(w *textWriter, sv reflect.Value) error { } continue } - if err := writeAny(w, v, props); err != nil { + if err := tm.writeAny(w, v, props); err != nil { return err } if err := w.WriteByte('\n'); err != nil { @@ -269,7 +355,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 { @@ -286,7 +372,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 { @@ -358,7 +444,7 @@ func writeStruct(w *textWriter, sv reflect.Value) error { } // Enums have a String method, so writeAny will work fine. - if err := writeAny(w, fv, props); err != nil { + if err := tm.writeAny(w, fv, props); err != nil { return err } @@ -369,8 +455,8 @@ func writeStruct(w *textWriter, sv reflect.Value) error { // Extensions (the XXX_extensions field). pv := sv.Addr() - if pv.Type().Implements(extendableProtoType) { - if err := writeExtensions(w, pv); err != nil { + if _, ok := extendable(pv.Interface()); ok { + if err := tm.writeExtensions(w, pv); err != nil { return err } } @@ -400,7 +486,7 @@ 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) // Floats have special cases. @@ -427,7 +513,7 @@ func writeAny(w *textWriter, v reflect.Value, props *Properties) error { switch v.Kind() { case reflect.Slice: // Should only be a []byte; repeated fields are handled in writeStruct. - if err := writeString(w, string(v.Interface().([]byte))); err != nil { + if err := writeString(w, string(v.Bytes())); err != nil { return err } case reflect.String: @@ -449,15 +535,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() @@ -601,19 +687,24 @@ 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) + ep, _ := extendable(pv.Interface()) // Order the extensions by ID. // This isn't strictly necessary, but it will give us // canonical output, which will also make testing easier. - m := ep.ExtensionMap() + m, mu := ep.extensionsRead() + if m == nil { + return nil + } + 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] @@ -636,13 +727,13 @@ func writeExtensions(w *textWriter, pv reflect.Value) error { // 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 } } @@ -651,7 +742,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 } @@ -660,7 +751,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 { @@ -685,7 +776,15 @@ func (w *textWriter) writeIndent() { w.complete = false } -func marshalText(w io.Writer, pb Message, compact bool) error { +// TextMarshaler is a configurable text format marshaler. +type TextMarshaler struct { + 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 (tm *TextMarshaler) Marshal(w io.Writer, pb Message) error { val := reflect.ValueOf(pb) if pb == nil || val.IsNil() { w.Write([]byte("")) @@ -700,11 +799,11 @@ func marshalText(w io.Writer, pb Message, compact bool) error { aw := &textWriter{ w: ww, complete: true, - compact: 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 } @@ -718,7 +817,7 @@ func marshalText(w io.Writer, pb Message, compact bool) 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 { @@ -727,25 +826,29 @@ func marshalText(w io.Writer, pb Message, compact bool) error { return nil } +// Text is the same as Marshal, but returns the string directly. +func (tm *TextMarshaler) Text(pb Message) string { + var buf bytes.Buffer + tm.Marshal(&buf, pb) + return buf.String() +} + +var ( + defaultTextMarshaler = TextMarshaler{} + compactTextMarshaler = TextMarshaler{Compact: true} +) + +// TODO: consider removing some of the Marshal functions below. + // MarshalText writes a given protocol buffer in text format. // The only errors returned are from w. -func MarshalText(w io.Writer, pb Message) error { - return marshalText(w, pb, false) -} +func MarshalText(w io.Writer, pb Message) error { return defaultTextMarshaler.Marshal(w, pb) } // MarshalTextString is the same as MarshalText, but returns the string directly. -func MarshalTextString(pb Message) string { - var buf bytes.Buffer - marshalText(&buf, pb, false) - return buf.String() -} +func MarshalTextString(pb Message) string { return defaultTextMarshaler.Text(pb) } // CompactText writes a given protocol buffer in compact text format (one line). -func CompactText(w io.Writer, pb Message) error { return marshalText(w, pb, true) } +func CompactText(w io.Writer, pb Message) error { return compactTextMarshaler.Marshal(w, pb) } // CompactTextString is the same as CompactText, but returns the string directly. -func CompactTextString(pb Message) string { - var buf bytes.Buffer - marshalText(&buf, pb, true) - return buf.String() -} +func CompactTextString(pb Message) string { return compactTextMarshaler.Text(pb) } diff --git a/vendor/github.com/golang/protobuf/proto/text_parser.go b/vendor/github.com/golang/protobuf/proto/text_parser.go index 451323262cf..0b8c59f746e 100644 --- a/vendor/github.com/golang/protobuf/proto/text_parser.go +++ b/vendor/github.com/golang/protobuf/proto/text_parser.go @@ -163,7 +163,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 '"', '\'': @@ -451,7 +451,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 { @@ -461,33 +464,66 @@ 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) + } + sv.FieldByName("TypeUrl").SetString(extName) + sv.FieldByName("Value").SetBytes(b) + 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{} @@ -514,7 +550,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 { @@ -566,8 +602,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 @@ -579,32 +616,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) @@ -627,7 +671,8 @@ func (p *textParser) readStruct(sv reflect.Value, terminator string) error { return err } reqFieldErr = err - } else if props.Required { + } + if props.Required { reqCount-- } @@ -643,6 +688,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 { diff --git a/vendor/github.com/google/btree/README.md b/vendor/github.com/google/btree/README.md index 26d687ef864..6062a4dacd4 100644 --- a/vendor/github.com/google/btree/README.md +++ b/vendor/github.com/google/btree/README.md @@ -2,7 +2,7 @@ ![Travis CI Build Status](https://api.travis-ci.org/google/btree.svg?branch=master) -This package provides an in-memory B-Tree implementation for Go, useful as a +This package provides an in-memory B-Tree implementation for Go, useful as an ordered, mutable data structure. The API is based off of the wonderful diff --git a/vendor/github.com/google/btree/btree.go b/vendor/github.com/google/btree/btree.go index eb1f75cda69..fc5aaaa13aa 100644 --- a/vendor/github.com/google/btree/btree.go +++ b/vendor/github.com/google/btree/btree.go @@ -64,6 +64,39 @@ type Item interface { Less(than Item) bool } +const ( + DefaultFreeListSize = 32 +) + +// FreeList represents a free list of btree nodes. By default each +// BTree has its own FreeList, but multiple BTrees can share the same +// FreeList. +// Two Btrees using the same freelist are not safe for concurrent write access. +type FreeList struct { + freelist []*node +} + +// NewFreeList creates a new free list. +// size is the maximum size of the returned free list. +func NewFreeList(size int) *FreeList { + return &FreeList{freelist: make([]*node, 0, size)} +} + +func (f *FreeList) newNode() (n *node) { + index := len(f.freelist) - 1 + if index < 0 { + return new(node) + } + f.freelist, n = f.freelist[:index], f.freelist[index] + return +} + +func (f *FreeList) freeNode(n *node) { + if len(f.freelist) < cap(f.freelist) { + f.freelist = append(f.freelist, n) + } +} + // ItemIterator allows callers of Ascend* to iterate in-order over portions of // the tree. When this function returns false, iteration will stop and the // associated Ascend* function will immediately return. @@ -74,12 +107,17 @@ type ItemIterator func(i Item) bool // New(2), for example, will create a 2-3-4 tree (each node contains 1-3 items // and 2-4 children). func New(degree int) *BTree { + return NewWithFreeList(degree, NewFreeList(DefaultFreeListSize)) +} + +// NewWithFreeList creates a new B-Tree that uses the given node free list. +func NewWithFreeList(degree int, f *FreeList) *BTree { if degree <= 1 { panic("bad degree") } return &BTree{ degree: degree, - freelist: make([]*node, 0, 32), + freelist: f, } } @@ -100,6 +138,7 @@ func (s *items) insertAt(index int, item Item) { // back. func (s *items) removeAt(index int) Item { item := (*s)[index] + (*s)[index] = nil copy((*s)[index:], (*s)[index+1:]) *s = (*s)[:len(*s)-1] return item @@ -108,7 +147,9 @@ func (s *items) removeAt(index int) Item { // pop removes and returns the last element in the list. func (s *items) pop() (out Item) { index := len(*s) - 1 - out, *s = (*s)[index], (*s)[:index] + out = (*s)[index] + (*s)[index] = nil + *s = (*s)[:index] return } @@ -142,6 +183,7 @@ func (s *children) insertAt(index int, n *node) { // back. func (s *children) removeAt(index int) *node { n := (*s)[index] + (*s)[index] = nil copy((*s)[index:], (*s)[index+1:]) *s = (*s)[:len(*s)-1] return n @@ -150,7 +192,9 @@ func (s *children) removeAt(index int) *node { // pop removes and returns the last element in the list. func (s *children) pop() (out *node) { index := len(*s) - 1 - out, *s = (*s)[index], (*s)[:index] + out = (*s)[index] + (*s)[index] = nil + *s = (*s)[:index] return } @@ -234,6 +278,34 @@ func (n *node) get(key Item) Item { return nil } +// min returns the first item in the subtree. +func min(n *node) Item { + if n == nil { + return nil + } + for len(n.children) > 0 { + n = n.children[0] + } + if len(n.items) == 0 { + return nil + } + return n.items[0] +} + +// max returns the last item in the subtree. +func max(n *node) Item { + if n == nil { + return nil + } + for len(n.children) > 0 { + n = n.children[len(n.children)-1] + } + if len(n.items) == 0 { + return nil + } + return n.items[len(n.items)-1] +} + // toRemove details what item to remove in a node.remove call. type toRemove int @@ -396,7 +468,7 @@ type BTree struct { degree int length int root *node - freelist []*node + freelist *FreeList } // maxItems returns the max number of items to allow per node. @@ -411,26 +483,22 @@ func (t *BTree) minItems() int { } func (t *BTree) newNode() (n *node) { - index := len(t.freelist) - 1 - if index < 0 { - return &node{t: t} - } - t.freelist, n = t.freelist[:index], t.freelist[index] + n = t.freelist.newNode() + n.t = t return } func (t *BTree) freeNode(n *node) { - if len(t.freelist) < cap(t.freelist) { - for i := range n.items { - n.items[i] = nil // clear to allow GC - } - n.items = n.items[:0] - for i := range n.children { - n.children[i] = nil // clear to allow GC - } - n.children = n.children[:0] - t.freelist = append(t.freelist, n) + for i := range n.items { + n.items[i] = nil // clear to allow GC } + n.items = n.items[:0] + for i := range n.children { + n.children[i] = nil // clear to allow GC + } + n.children = n.children[:0] + n.t = nil // clear to allow GC + t.freelist.freeNode(n) } // ReplaceOrInsert adds the given item to the tree. If an item in the tree @@ -552,6 +620,16 @@ func (t *BTree) Get(key Item) Item { return t.root.get(key) } +// Min returns the smallest item in the tree, or nil if the tree is empty. +func (t *BTree) Min() Item { + return min(t.root) +} + +// Max returns the largest item in the tree, or nil if the tree is empty. +func (t *BTree) Max() Item { + return max(t.root) +} + // Has returns true if the given key is in the tree. func (t *BTree) Has(key Item) bool { return t.Get(key) != nil diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/LICENSE.txt b/vendor/github.com/grpc-ecosystem/grpc-gateway/LICENSE.txt new file mode 100644 index 00000000000..364516251b9 --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/LICENSE.txt @@ -0,0 +1,27 @@ +Copyright (c) 2015, Gengo, Inc. +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 Gengo, 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/github.com/grpc-ecosystem/grpc-gateway/runtime/context.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/context.go new file mode 100644 index 00000000000..ad42535662a --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/context.go @@ -0,0 +1,139 @@ +package runtime + +import ( + "fmt" + "net" + "net/http" + "strconv" + "strings" + "time" + + "golang.org/x/net/context" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/metadata" +) + +const metadataHeaderPrefix = "Grpc-Metadata-" +const metadataTrailerPrefix = "Grpc-Trailer-" +const metadataGrpcTimeout = "Grpc-Timeout" + +const xForwardedFor = "X-Forwarded-For" +const xForwardedHost = "X-Forwarded-Host" + +var ( + // DefaultContextTimeout is used for gRPC call context.WithTimeout whenever a Grpc-Timeout inbound + // header isn't present. If the value is 0 the sent `context` will not have a timeout. + DefaultContextTimeout = 0 * time.Second +) + +/* +AnnotateContext adds context information such as metadata from the request. + +At a minimum, the RemoteAddr is included in the fashion of "X-Forwarded-For", +except that the forwarded destination is not another HTTP service but rather +a gRPC service. +*/ +func AnnotateContext(ctx context.Context, req *http.Request) (context.Context, error) { + var pairs []string + timeout := DefaultContextTimeout + if tm := req.Header.Get(metadataGrpcTimeout); tm != "" { + var err error + timeout, err = timeoutDecode(tm) + if err != nil { + return nil, grpc.Errorf(codes.InvalidArgument, "invalid grpc-timeout: %s", tm) + } + } + + for key, vals := range req.Header { + for _, val := range vals { + if key == "Authorization" { + pairs = append(pairs, "authorization", val) + continue + } + if strings.HasPrefix(key, metadataHeaderPrefix) { + pairs = append(pairs, key[len(metadataHeaderPrefix):], val) + } + } + } + if host := req.Header.Get(xForwardedHost); host != "" { + pairs = append(pairs, strings.ToLower(xForwardedHost), host) + } else if req.Host != "" { + pairs = append(pairs, strings.ToLower(xForwardedHost), req.Host) + } + + if addr := req.RemoteAddr; addr != "" { + if remoteIP, _, err := net.SplitHostPort(addr); err == nil { + if fwd := req.Header.Get(xForwardedFor); fwd == "" { + pairs = append(pairs, strings.ToLower(xForwardedFor), remoteIP) + } else { + pairs = append(pairs, strings.ToLower(xForwardedFor), fmt.Sprintf("%s, %s", fwd, remoteIP)) + } + } else { + grpclog.Printf("invalid remote addr: %s", addr) + } + } + + if timeout != 0 { + ctx, _ = context.WithTimeout(ctx, timeout) + } + if len(pairs) == 0 { + return ctx, nil + } + return metadata.NewContext(ctx, metadata.Pairs(pairs...)), nil +} + +// ServerMetadata consists of metadata sent from gRPC server. +type ServerMetadata struct { + HeaderMD metadata.MD + TrailerMD metadata.MD +} + +type serverMetadataKey struct{} + +// NewServerMetadataContext creates a new context with ServerMetadata +func NewServerMetadataContext(ctx context.Context, md ServerMetadata) context.Context { + return context.WithValue(ctx, serverMetadataKey{}, md) +} + +// ServerMetadataFromContext returns the ServerMetadata in ctx +func ServerMetadataFromContext(ctx context.Context) (md ServerMetadata, ok bool) { + md, ok = ctx.Value(serverMetadataKey{}).(ServerMetadata) + return +} + +func timeoutDecode(s string) (time.Duration, error) { + size := len(s) + if size < 2 { + return 0, fmt.Errorf("timeout string is too short: %q", s) + } + d, ok := timeoutUnitToDuration(s[size-1]) + if !ok { + return 0, fmt.Errorf("timeout unit is not recognized: %q", s) + } + t, err := strconv.ParseInt(s[:size-1], 10, 64) + if err != nil { + return 0, err + } + return d * time.Duration(t), nil +} + +func timeoutUnitToDuration(u uint8) (d time.Duration, ok bool) { + switch u { + case 'H': + return time.Hour, true + case 'M': + return time.Minute, true + case 'S': + return time.Second, true + case 'm': + return time.Millisecond, true + case 'u': + return time.Microsecond, true + case 'n': + return time.Nanosecond, true + default: + } + return +} diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/convert.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/convert.go new file mode 100644 index 00000000000..1af5cc4ebdd --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/convert.go @@ -0,0 +1,58 @@ +package runtime + +import ( + "strconv" +) + +// String just returns the given string. +// It is just for compatibility to other types. +func String(val string) (string, error) { + return val, nil +} + +// Bool converts the given string representation of a boolean value into bool. +func Bool(val string) (bool, error) { + return strconv.ParseBool(val) +} + +// Float64 converts the given string representation into representation of a floating point number into float64. +func Float64(val string) (float64, error) { + return strconv.ParseFloat(val, 64) +} + +// Float32 converts the given string representation of a floating point number into float32. +func Float32(val string) (float32, error) { + f, err := strconv.ParseFloat(val, 32) + if err != nil { + return 0, err + } + return float32(f), nil +} + +// Int64 converts the given string representation of an integer into int64. +func Int64(val string) (int64, error) { + return strconv.ParseInt(val, 0, 64) +} + +// Int32 converts the given string representation of an integer into int32. +func Int32(val string) (int32, error) { + i, err := strconv.ParseInt(val, 0, 32) + if err != nil { + return 0, err + } + return int32(i), nil +} + +// Uint64 converts the given string representation of an integer into uint64. +func Uint64(val string) (uint64, error) { + return strconv.ParseUint(val, 0, 64) +} + +// Uint32 converts the given string representation of an integer into uint32. +func Uint32(val string) (uint32, error) { + i, err := strconv.ParseUint(val, 0, 32) + if err != nil { + return 0, err + } + return uint32(i), nil +} diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/doc.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/doc.go new file mode 100644 index 00000000000..b6e5ddf7a9f --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/doc.go @@ -0,0 +1,5 @@ +/* +Package runtime contains runtime helper functions used by +servers which protoc-gen-grpc-gateway generates. +*/ +package runtime diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/errors.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/errors.go new file mode 100644 index 00000000000..7d7a9b22415 --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/errors.go @@ -0,0 +1,121 @@ +package runtime + +import ( + "io" + "net/http" + + "github.com/golang/protobuf/proto" + "golang.org/x/net/context" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/grpclog" +) + +// HTTPStatusFromCode converts a gRPC error code into the corresponding HTTP response status. +func HTTPStatusFromCode(code codes.Code) int { + switch code { + case codes.OK: + return http.StatusOK + case codes.Canceled: + return http.StatusRequestTimeout + case codes.Unknown: + return http.StatusInternalServerError + case codes.InvalidArgument: + return http.StatusBadRequest + case codes.DeadlineExceeded: + return http.StatusRequestTimeout + case codes.NotFound: + return http.StatusNotFound + case codes.AlreadyExists: + return http.StatusConflict + case codes.PermissionDenied: + return http.StatusForbidden + case codes.Unauthenticated: + return http.StatusUnauthorized + case codes.ResourceExhausted: + return http.StatusForbidden + case codes.FailedPrecondition: + return http.StatusPreconditionFailed + case codes.Aborted: + return http.StatusConflict + case codes.OutOfRange: + return http.StatusBadRequest + case codes.Unimplemented: + return http.StatusNotImplemented + case codes.Internal: + return http.StatusInternalServerError + case codes.Unavailable: + return http.StatusServiceUnavailable + case codes.DataLoss: + return http.StatusInternalServerError + } + + grpclog.Printf("Unknown gRPC error code: %v", code) + return http.StatusInternalServerError +} + +var ( + // HTTPError replies to the request with the error. + // You can set a custom function to this variable to customize error format. + HTTPError = DefaultHTTPError + // OtherErrorHandler handles the following error used by the gateway: StatusMethodNotAllowed StatusNotFound and StatusBadRequest + OtherErrorHandler = DefaultOtherErrorHandler +) + +type errorBody struct { + Error string `json:"error"` + Code int `json:"code"` +} + +//Make this also conform to proto.Message for builtin JSONPb Marshaler +func (e *errorBody) Reset() { *e = errorBody{} } +func (e *errorBody) String() string { return proto.CompactTextString(e) } +func (*errorBody) ProtoMessage() {} + +// DefaultHTTPError is the default implementation of HTTPError. +// If "err" is an error from gRPC system, the function replies with the status code mapped by HTTPStatusFromCode. +// If otherwise, it replies with http.StatusInternalServerError. +// +// The response body returned by this function is a JSON object, +// which contains a member whose key is "error" and whose value is err.Error(). +func DefaultHTTPError(ctx context.Context, marshaler Marshaler, w http.ResponseWriter, _ *http.Request, err error) { + const fallback = `{"error": "failed to marshal error message"}` + + w.Header().Del("Trailer") + w.Header().Set("Content-Type", marshaler.ContentType()) + body := &errorBody{ + Error: grpc.ErrorDesc(err), + Code: int(grpc.Code(err)), + } + + buf, merr := marshaler.Marshal(body) + if merr != nil { + grpclog.Printf("Failed to marshal error message %q: %v", body, merr) + w.WriteHeader(http.StatusInternalServerError) + if _, err := io.WriteString(w, fallback); err != nil { + grpclog.Printf("Failed to write response: %v", err) + } + return + } + + md, ok := ServerMetadataFromContext(ctx) + if !ok { + grpclog.Printf("Failed to extract ServerMetadata from context") + } + + handleForwardResponseServerMetadata(w, md) + handleForwardResponseTrailerHeader(w, md) + st := HTTPStatusFromCode(grpc.Code(err)) + w.WriteHeader(st) + if _, err := w.Write(buf); err != nil { + grpclog.Printf("Failed to write response: %v", err) + } + + handleForwardResponseTrailer(w, md) +} + +// DefaultOtherErrorHandler is the default implementation of OtherErrorHandler. +// It simply writes a string representation of the given error into "w". +func DefaultOtherErrorHandler(w http.ResponseWriter, _ *http.Request, msg string, code int) { + http.Error(w, msg, code) +} diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/handler.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/handler.go new file mode 100644 index 00000000000..bafa4285f91 --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/handler.go @@ -0,0 +1,164 @@ +package runtime + +import ( + "fmt" + "io" + "net/http" + "net/textproto" + + "github.com/golang/protobuf/proto" + "github.com/grpc-ecosystem/grpc-gateway/runtime/internal" + "golang.org/x/net/context" + "google.golang.org/grpc" + "google.golang.org/grpc/grpclog" +) + +// ForwardResponseStream forwards the stream from gRPC server to REST client. +func ForwardResponseStream(ctx context.Context, marshaler Marshaler, w http.ResponseWriter, req *http.Request, recv func() (proto.Message, error), opts ...func(context.Context, http.ResponseWriter, proto.Message) error) { + f, ok := w.(http.Flusher) + if !ok { + grpclog.Printf("Flush not supported in %T", w) + http.Error(w, "unexpected type of web server", http.StatusInternalServerError) + return + } + + md, ok := ServerMetadataFromContext(ctx) + if !ok { + grpclog.Printf("Failed to extract ServerMetadata from context") + http.Error(w, "unexpected error", http.StatusInternalServerError) + return + } + handleForwardResponseServerMetadata(w, md) + + w.Header().Set("Transfer-Encoding", "chunked") + w.Header().Set("Content-Type", marshaler.ContentType()) + if err := handleForwardResponseOptions(ctx, w, nil, opts); err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + w.WriteHeader(http.StatusOK) + f.Flush() + for { + resp, err := recv() + if err == io.EOF { + return + } + if err != nil { + handleForwardResponseStreamError(marshaler, w, err) + return + } + if err := handleForwardResponseOptions(ctx, w, resp, opts); err != nil { + handleForwardResponseStreamError(marshaler, w, err) + return + } + + buf, err := marshaler.Marshal(streamChunk(resp, nil)) + if err != nil { + grpclog.Printf("Failed to marshal response chunk: %v", err) + return + } + if _, err = fmt.Fprintf(w, "%s\n", buf); err != nil { + grpclog.Printf("Failed to send response chunk: %v", err) + return + } + f.Flush() + } +} + +func handleForwardResponseServerMetadata(w http.ResponseWriter, md ServerMetadata) { + for k, vs := range md.HeaderMD { + hKey := fmt.Sprintf("%s%s", metadataHeaderPrefix, k) + for i := range vs { + w.Header().Add(hKey, vs[i]) + } + } +} + +func handleForwardResponseTrailerHeader(w http.ResponseWriter, md ServerMetadata) { + for k := range md.TrailerMD { + 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) + for i := range vs { + w.Header().Add(tKey, vs[i]) + } + } +} + +// ForwardResponseMessage forwards the message "resp" from gRPC server to REST client. +func ForwardResponseMessage(ctx context.Context, marshaler Marshaler, w http.ResponseWriter, req *http.Request, resp proto.Message, opts ...func(context.Context, http.ResponseWriter, proto.Message) error) { + md, ok := ServerMetadataFromContext(ctx) + if !ok { + grpclog.Printf("Failed to extract ServerMetadata from context") + } + + handleForwardResponseServerMetadata(w, md) + handleForwardResponseTrailerHeader(w, md) + w.Header().Set("Content-Type", marshaler.ContentType()) + if err := handleForwardResponseOptions(ctx, w, resp, opts); err != nil { + HTTPError(ctx, marshaler, w, req, err) + return + } + + buf, err := marshaler.Marshal(resp) + if err != nil { + grpclog.Printf("Marshal error: %v", err) + HTTPError(ctx, marshaler, w, req, err) + return + } + + if _, err = w.Write(buf); err != nil { + grpclog.Printf("Failed to write response: %v", err) + } + + handleForwardResponseTrailer(w, md) +} + +func handleForwardResponseOptions(ctx context.Context, w http.ResponseWriter, resp proto.Message, opts []func(context.Context, http.ResponseWriter, proto.Message) error) error { + if len(opts) == 0 { + return nil + } + for _, opt := range opts { + if err := opt(ctx, w, resp); err != nil { + grpclog.Printf("Error handling ForwardResponseOptions: %v", err) + return err + } + } + return nil +} + +func handleForwardResponseStreamError(marshaler Marshaler, w http.ResponseWriter, err error) { + buf, merr := marshaler.Marshal(streamChunk(nil, err)) + if merr != nil { + grpclog.Printf("Failed to marshal an error: %v", merr) + return + } + if _, werr := fmt.Fprintf(w, "%s\n", buf); werr != nil { + grpclog.Printf("Failed to notify error to client: %v", werr) + return + } +} + +func streamChunk(result proto.Message, err error) map[string]proto.Message { + if err != nil { + grpcCode := grpc.Code(err) + httpCode := HTTPStatusFromCode(grpcCode) + return map[string]proto.Message{ + "error": &internal.StreamError{ + GrpcCode: int32(grpcCode), + HttpCode: int32(httpCode), + Message: err.Error(), + HttpStatus: http.StatusText(httpCode), + }, + } + } + if result == nil { + return streamChunk(nil, fmt.Errorf("empty response")) + } + return map[string]proto.Message{"result": result} +} 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 new file mode 100644 index 00000000000..524e0d3c34c --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/internal/stream_chunk.pb.go @@ -0,0 +1,65 @@ +// Code generated by protoc-gen-go. +// source: runtime/internal/stream_chunk.proto +// DO NOT EDIT! + +/* +Package internal is a generated protocol buffer package. + +It is generated from these files: + runtime/internal/stream_chunk.proto + +It has these top-level messages: + StreamError +*/ +package internal + +import proto "github.com/golang/protobuf/proto" +import fmt "fmt" +import math "math" + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +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. +// 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 + +// StreamError is a response type which is returned when +// streaming rpc returns an error. +type StreamError struct { + GrpcCode int32 `protobuf:"varint,1,opt,name=grpc_code,json=grpcCode" json:"grpc_code,omitempty"` + HttpCode int32 `protobuf:"varint,2,opt,name=http_code,json=httpCode" json:"http_code,omitempty"` + Message string `protobuf:"bytes,3,opt,name=message" json:"message,omitempty"` + HttpStatus string `protobuf:"bytes,4,opt,name=http_status,json=httpStatus" json:"http_status,omitempty"` +} + +func (m *StreamError) Reset() { *m = StreamError{} } +func (m *StreamError) String() string { return proto.CompactTextString(m) } +func (*StreamError) ProtoMessage() {} +func (*StreamError) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} } + +func init() { + proto.RegisterType((*StreamError)(nil), "grpc.gateway.runtime.StreamError") +} + +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, +} diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/internal/stream_chunk.proto b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/internal/stream_chunk.proto new file mode 100644 index 00000000000..f7fba56c35b --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/internal/stream_chunk.proto @@ -0,0 +1,12 @@ +syntax = "proto3"; +package grpc.gateway.runtime; +option go_package = "internal"; + +// StreamError is a response type which is returned when +// streaming rpc returns an error. +message StreamError { + int32 grpc_code = 1; + int32 http_code = 2; + string message = 3; + string http_status = 4; +} diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshal_json.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshal_json.go new file mode 100644 index 00000000000..0acd2ca29ef --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshal_json.go @@ -0,0 +1,37 @@ +package runtime + +import ( + "encoding/json" + "io" +) + +// JSONBuiltin is a Marshaler which marshals/unmarshals into/from JSON +// with the standard "encoding/json" package of Golang. +// Although it is generally faster for simple proto messages than JSONPb, +// it does not support advanced features of protobuf, e.g. map, oneof, .... +type JSONBuiltin struct{} + +// ContentType always Returns "application/json". +func (*JSONBuiltin) ContentType() string { + return "application/json" +} + +// Marshal marshals "v" into JSON +func (j *JSONBuiltin) Marshal(v interface{}) ([]byte, error) { + return json.Marshal(v) +} + +// Unmarshal unmarshals JSON data into "v". +func (j *JSONBuiltin) Unmarshal(data []byte, v interface{}) error { + return json.Unmarshal(data, v) +} + +// NewDecoder returns a Decoder which reads JSON stream from "r". +func (j *JSONBuiltin) NewDecoder(r io.Reader) Decoder { + return json.NewDecoder(r) +} + +// NewEncoder returns an Encoder which writes JSON stream into "w". +func (j *JSONBuiltin) NewEncoder(w io.Writer) Encoder { + return json.NewEncoder(w) +} 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 new file mode 100644 index 00000000000..9a42191119a --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshal_jsonpb.go @@ -0,0 +1,182 @@ +package runtime + +import ( + "bytes" + "encoding/json" + "fmt" + "io" + "reflect" + + "github.com/golang/protobuf/jsonpb" + "github.com/golang/protobuf/proto" +) + +// JSONPb is a Marshaler which marshals/unmarshals into/from JSON +// with the "github.com/golang/protobuf/jsonpb". +// It supports fully functionality of protobuf unlike JSONBuiltin. +type JSONPb jsonpb.Marshaler + +// ContentType always returns "application/json". +func (*JSONPb) ContentType() string { + return "application/json" +} + +// Marshal marshals "v" into JSON +// Currently it can marshal only proto.Message. +// TODO(yugui) Support fields of primitive types in a message. +func (j *JSONPb) Marshal(v interface{}) ([]byte, error) { + if _, ok := v.(proto.Message); !ok { + return j.marshalNonProtoField(v) + } + + var buf bytes.Buffer + if err := j.marshalTo(&buf, v); err != nil { + return nil, err + } + return buf.Bytes(), nil +} + +func (j *JSONPb) marshalTo(w io.Writer, v interface{}) error { + p, ok := v.(proto.Message) + if !ok { + buf, err := j.marshalNonProtoField(v) + if err != nil { + return err + } + _, err = w.Write(buf) + return err + } + return (*jsonpb.Marshaler)(j).Marshal(w, p) +} + +// marshalNonProto marshals a non-message field of a protobuf message. +// This function does not correctly marshals arbitary data structure into JSON, +// but it is only capable of marshaling non-message field values of protobuf, +// i.e. primitive types, enums; pointers to primitives or enums; maps from +// integer/string types to primitives/enums/pointers to messages. +func (j *JSONPb) marshalNonProtoField(v interface{}) ([]byte, error) { + rv := reflect.ValueOf(v) + for rv.Kind() == reflect.Ptr { + if rv.IsNil() { + return []byte("null"), nil + } + rv = rv.Elem() + } + + if rv.Kind() == reflect.Map { + m := make(map[string]*json.RawMessage) + for _, k := range rv.MapKeys() { + buf, err := j.Marshal(rv.MapIndex(k).Interface()) + if err != nil { + return nil, err + } + m[fmt.Sprintf("%v", k.Interface())] = (*json.RawMessage)(&buf) + } + if j.Indent != "" { + return json.MarshalIndent(m, "", j.Indent) + } + return json.Marshal(m) + } + if enum, ok := rv.Interface().(protoEnum); ok && !j.EnumsAsInts { + return json.Marshal(enum.String()) + } + return json.Marshal(rv.Interface()) +} + +// Unmarshal unmarshals JSON "data" into "v" +// Currently it can marshal only proto.Message. +// TODO(yugui) Support fields of primitive types in a message. +func (j *JSONPb) Unmarshal(data []byte, v interface{}) error { + return unmarshalJSONPb(data, v) +} + +// NewDecoder returns a Decoder which reads JSON stream from "r". +func (j *JSONPb) NewDecoder(r io.Reader) Decoder { + d := json.NewDecoder(r) + return DecoderFunc(func(v interface{}) error { return decodeJSONPb(d, v) }) +} + +// NewEncoder returns an Encoder which writes JSON stream into "w". +func (j *JSONPb) NewEncoder(w io.Writer) Encoder { + return EncoderFunc(func(v interface{}) error { return j.marshalTo(w, v) }) +} + +func unmarshalJSONPb(data []byte, v interface{}) error { + d := json.NewDecoder(bytes.NewReader(data)) + return decodeJSONPb(d, v) +} + +func decodeJSONPb(d *json.Decoder, v interface{}) error { + p, ok := v.(proto.Message) + if !ok { + return decodeNonProtoField(d, v) + } + return jsonpb.UnmarshalNext(d, p) +} + +func decodeNonProtoField(d *json.Decoder, v interface{}) error { + rv := reflect.ValueOf(v) + if rv.Kind() != reflect.Ptr { + return fmt.Errorf("%T is not a pointer", v) + } + for rv.Kind() == reflect.Ptr { + if rv.IsNil() { + rv.Set(reflect.New(rv.Type().Elem())) + } + if rv.Type().ConvertibleTo(typeProtoMessage) { + return jsonpb.UnmarshalNext(d, rv.Interface().(proto.Message)) + } + rv = rv.Elem() + } + if rv.Kind() == reflect.Map { + if rv.IsNil() { + rv.Set(reflect.MakeMap(rv.Type())) + } + conv, ok := convFromType[rv.Type().Key().Kind()] + if !ok { + return fmt.Errorf("unsupported type of map field key: %v", rv.Type().Key()) + } + + m := make(map[string]*json.RawMessage) + if err := d.Decode(&m); err != nil { + return err + } + for k, v := range m { + result := conv.Call([]reflect.Value{reflect.ValueOf(k)}) + if err := result[1].Interface(); err != nil { + return err.(error) + } + bk := result[0] + bv := reflect.New(rv.Type().Elem()) + if err := unmarshalJSONPb([]byte(*v), bv.Interface()); err != nil { + return err + } + rv.SetMapIndex(bk, bv.Elem()) + } + return nil + } + if _, ok := rv.Interface().(protoEnum); ok { + var repr interface{} + if err := d.Decode(&repr); err != nil { + return err + } + switch repr.(type) { + case string: + // TODO(yugui) Should use proto.StructProperties? + return fmt.Errorf("unmarshaling of symbolic enum %q not supported: %T", repr, rv.Interface()) + case float64: + rv.Set(reflect.ValueOf(int32(repr.(float64))).Convert(rv.Type())) + return nil + default: + return fmt.Errorf("cannot assign %#v into Go type %T", repr, rv.Interface()) + } + } + return d.Decode(v) +} + +type protoEnum interface { + fmt.Stringer + EnumDescriptor() ([]byte, []int) +} + +var typeProtoMessage = reflect.TypeOf((*proto.Message)(nil)).Elem() diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshaler.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshaler.go new file mode 100644 index 00000000000..6d434f13cb4 --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshaler.go @@ -0,0 +1,42 @@ +package runtime + +import ( + "io" +) + +// Marshaler defines a conversion between byte sequence and gRPC payloads / fields. +type Marshaler interface { + // Marshal marshals "v" into byte sequence. + Marshal(v interface{}) ([]byte, error) + // Unmarshal unmarshals "data" into "v". + // "v" must be a pointer value. + Unmarshal(data []byte, v interface{}) error + // NewDecoder returns a Decoder which reads byte sequence from "r". + NewDecoder(r io.Reader) Decoder + // NewEncoder returns an Encoder which writes bytes sequence into "w". + NewEncoder(w io.Writer) Encoder + // ContentType returns the Content-Type which this marshaler is responsible for. + ContentType() string +} + +// Decoder decodes a byte sequence +type Decoder interface { + Decode(v interface{}) error +} + +// Encoder encodes gRPC payloads / fields into byte sequence. +type Encoder interface { + Encode(v interface{}) error +} + +// DecoderFunc adapts an decoder function into Decoder. +type DecoderFunc func(v interface{}) error + +// Decode delegates invocations to the underlying function itself. +func (f DecoderFunc) Decode(v interface{}) error { return f(v) } + +// EncoderFunc adapts an encoder function into Encoder +type EncoderFunc func(v interface{}) error + +// Encode delegates invocations to the underlying function itself. +func (f EncoderFunc) Encode(v interface{}) error { return f(v) } diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshaler_registry.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshaler_registry.go new file mode 100644 index 00000000000..928f0733214 --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshaler_registry.go @@ -0,0 +1,91 @@ +package runtime + +import ( + "errors" + "net/http" +) + +// MIMEWildcard is the fallback MIME type used for requests which do not match +// a registered MIME type. +const MIMEWildcard = "*" + +var ( + acceptHeader = http.CanonicalHeaderKey("Accept") + contentTypeHeader = http.CanonicalHeaderKey("Content-Type") + + defaultMarshaler = &JSONPb{OrigName: true} +) + +// MarshalerForRequest returns the inbound/outbound marshalers for this request. +// It checks the registry on the ServeMux for the MIME type set by the Content-Type header. +// If it isn't set (or the request Content-Type is empty), checks for "*". +// If there are multiple Content-Type headers set, choose the first one that it can +// exactly match in the registry. +// Otherwise, it follows the above logic for "*"/InboundMarshaler/OutboundMarshaler. +func MarshalerForRequest(mux *ServeMux, r *http.Request) (inbound Marshaler, outbound Marshaler) { + for _, acceptVal := range r.Header[acceptHeader] { + if m, ok := mux.marshalers.mimeMap[acceptVal]; ok { + outbound = m + break + } + } + + for _, contentTypeVal := range r.Header[contentTypeHeader] { + if m, ok := mux.marshalers.mimeMap[contentTypeVal]; ok { + inbound = m + break + } + } + + if inbound == nil { + inbound = mux.marshalers.mimeMap[MIMEWildcard] + } + if outbound == nil { + outbound = inbound + } + + return inbound, outbound +} + +// marshalerRegistry is a mapping from MIME types to Marshalers. +type marshalerRegistry struct { + mimeMap map[string]Marshaler +} + +// add adds a marshaler for a case-sensitive MIME type string ("*" to match any +// MIME type). +func (m marshalerRegistry) add(mime string, marshaler Marshaler) error { + if len(mime) == 0 { + return errors.New("empty MIME type") + } + + m.mimeMap[mime] = marshaler + + return nil +} + +// makeMarshalerMIMERegistry returns a new registry of marshalers. +// It allows for a mapping of case-sensitive Content-Type MIME type string to runtime.Marshaler interfaces. +// +// For example, you could allow the client to specify the use of the runtime.JSONPb marshaler +// with a "applicaton/jsonpb" Content-Type and the use of the runtime.JSONBuiltin marshaler +// with a "application/json" Content-Type. +// "*" can be used to match any Content-Type. +// This can be attached to a ServerMux with the marshaler option. +func makeMarshalerMIMERegistry() marshalerRegistry { + return marshalerRegistry{ + mimeMap: map[string]Marshaler{ + MIMEWildcard: defaultMarshaler, + }, + } +} + +// WithMarshalerOption returns a ServeMuxOption which associates inbound and outbound +// Marshalers to a MIME type in mux. +func WithMarshalerOption(mime string, marshaler Marshaler) ServeMuxOption { + return func(mux *ServeMux) { + if err := mux.marshalers.add(mime, marshaler); err != nil { + panic(err) + } + } +} diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/mux.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/mux.go new file mode 100644 index 00000000000..2e6c5621302 --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/mux.go @@ -0,0 +1,132 @@ +package runtime + +import ( + "net/http" + "strings" + + "golang.org/x/net/context" + + "github.com/golang/protobuf/proto" +) + +// A HandlerFunc handles a specific pair of path pattern and HTTP method. +type HandlerFunc func(w http.ResponseWriter, r *http.Request, pathParams map[string]string) + +// ServeMux is a request multiplexer for grpc-gateway. +// It matches http requests to patterns and invokes the corresponding handler. +type ServeMux struct { + // handlers maps HTTP method to a list of handlers. + handlers map[string][]handler + forwardResponseOptions []func(context.Context, http.ResponseWriter, proto.Message) error + marshalers marshalerRegistry +} + +// ServeMuxOption is an option that can be given to a ServeMux on construction. +type ServeMuxOption func(*ServeMux) + +// WithForwardResponseOption returns a ServeMuxOption representing the forwardResponseOption. +// +// forwardResponseOption is an option that will be called on the relevant context.Context, +// http.ResponseWriter, and proto.Message before every forwarded response. +// +// The message may be nil in the case where just a header is being sent. +func WithForwardResponseOption(forwardResponseOption func(context.Context, http.ResponseWriter, proto.Message) error) ServeMuxOption { + return func(serveMux *ServeMux) { + serveMux.forwardResponseOptions = append(serveMux.forwardResponseOptions, forwardResponseOption) + } +} + +// NewServeMux returns a new ServeMux whose internal mapping is empty. +func NewServeMux(opts ...ServeMuxOption) *ServeMux { + serveMux := &ServeMux{ + handlers: make(map[string][]handler), + forwardResponseOptions: make([]func(context.Context, http.ResponseWriter, proto.Message) error, 0), + marshalers: makeMarshalerMIMERegistry(), + } + + for _, opt := range opts { + opt(serveMux) + } + return serveMux +} + +// Handle associates "h" to the pair of HTTP method and path pattern. +func (s *ServeMux) Handle(meth string, pat Pattern, h HandlerFunc) { + s.handlers[meth] = append(s.handlers[meth], handler{pat: pat, h: h}) +} + +// ServeHTTP dispatches the request to the first handler whose pattern matches to r.Method and r.Path. +func (s *ServeMux) ServeHTTP(w http.ResponseWriter, r *http.Request) { + path := r.URL.Path + if !strings.HasPrefix(path, "/") { + OtherErrorHandler(w, r, http.StatusText(http.StatusBadRequest), http.StatusBadRequest) + return + } + + components := strings.Split(path[1:], "/") + l := len(components) + var verb string + if idx := strings.LastIndex(components[l-1], ":"); idx == 0 { + OtherErrorHandler(w, r, http.StatusText(http.StatusNotFound), http.StatusNotFound) + return + } else if idx > 0 { + c := components[l-1] + components[l-1], verb = c[:idx], c[idx+1:] + } + + if override := r.Header.Get("X-HTTP-Method-Override"); override != "" && isPathLengthFallback(r) { + r.Method = strings.ToUpper(override) + if err := r.ParseForm(); err != nil { + OtherErrorHandler(w, r, err.Error(), http.StatusBadRequest) + return + } + } + for _, h := range s.handlers[r.Method] { + pathParams, err := h.pat.Match(components, verb) + if err != nil { + continue + } + h.h(w, r, pathParams) + return + } + + // lookup other methods to handle fallback from GET to POST and + // to determine if it is MethodNotAllowed or NotFound. + for m, handlers := range s.handlers { + if m == r.Method { + continue + } + for _, h := range handlers { + pathParams, err := h.pat.Match(components, verb) + if err != nil { + continue + } + // X-HTTP-Method-Override is optional. Always allow fallback to POST. + if isPathLengthFallback(r) { + if err := r.ParseForm(); err != nil { + OtherErrorHandler(w, r, err.Error(), http.StatusBadRequest) + return + } + h.h(w, r, pathParams) + return + } + OtherErrorHandler(w, r, http.StatusText(http.StatusMethodNotAllowed), http.StatusMethodNotAllowed) + return + } + } + OtherErrorHandler(w, r, http.StatusText(http.StatusNotFound), http.StatusNotFound) +} + +// GetForwardResponseOptions returns the ForwardResponseOptions associated with this ServeMux. +func (s *ServeMux) GetForwardResponseOptions() []func(context.Context, http.ResponseWriter, proto.Message) error { + return s.forwardResponseOptions +} + +func isPathLengthFallback(r *http.Request) bool { + return r.Method == "POST" && r.Header.Get("Content-Type") == "application/x-www-form-urlencoded" +} + +type handler struct { + pat Pattern + h HandlerFunc +} diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/pattern.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/pattern.go new file mode 100644 index 00000000000..3947dbea023 --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/pattern.go @@ -0,0 +1,227 @@ +package runtime + +import ( + "errors" + "fmt" + "strings" + + "github.com/grpc-ecosystem/grpc-gateway/utilities" + "google.golang.org/grpc/grpclog" +) + +var ( + // ErrNotMatch indicates that the given HTTP request path does not match to the pattern. + ErrNotMatch = errors.New("not match to the path pattern") + // ErrInvalidPattern indicates that the given definition of Pattern is not valid. + ErrInvalidPattern = errors.New("invalid pattern") +) + +type op struct { + code utilities.OpCode + operand int +} + +// Pattern is a template pattern of http request paths defined in third_party/googleapis/google/api/http.proto. +type Pattern struct { + // ops is a list of operations + ops []op + // pool is a constant pool indexed by the operands or vars. + pool []string + // vars is a list of variables names to be bound by this pattern + vars []string + // stacksize is the max depth of the stack + stacksize int + // tailLen is the length of the fixed-size segments after a deep wildcard + tailLen int + // verb is the VERB part of the path pattern. It is empty if the pattern does not have VERB part. + verb string +} + +// NewPattern returns a new Pattern from the given definition values. +// "ops" is a sequence of op codes. "pool" is a constant pool. +// "verb" is the verb part of the pattern. It is empty if the pattern does not have the part. +// "version" must be 1 for now. +// It returns an error if the given definition is invalid. +func NewPattern(version int, ops []int, pool []string, verb string) (Pattern, error) { + if version != 1 { + grpclog.Printf("unsupported version: %d", version) + return Pattern{}, ErrInvalidPattern + } + + l := len(ops) + if l%2 != 0 { + grpclog.Printf("odd number of ops codes: %d", l) + return Pattern{}, ErrInvalidPattern + } + + var ( + typedOps []op + stack, maxstack int + tailLen int + pushMSeen bool + vars []string + ) + for i := 0; i < l; i += 2 { + op := op{code: utilities.OpCode(ops[i]), operand: ops[i+1]} + switch op.code { + case utilities.OpNop: + continue + case utilities.OpPush: + if pushMSeen { + tailLen++ + } + stack++ + case utilities.OpPushM: + if pushMSeen { + grpclog.Printf("pushM appears twice") + return Pattern{}, ErrInvalidPattern + } + pushMSeen = true + stack++ + case utilities.OpLitPush: + if op.operand < 0 || len(pool) <= op.operand { + grpclog.Printf("negative literal index: %d", op.operand) + return Pattern{}, ErrInvalidPattern + } + if pushMSeen { + tailLen++ + } + stack++ + case utilities.OpConcatN: + if op.operand <= 0 { + grpclog.Printf("negative concat size: %d", op.operand) + return Pattern{}, ErrInvalidPattern + } + stack -= op.operand + if stack < 0 { + grpclog.Print("stack underflow") + return Pattern{}, ErrInvalidPattern + } + stack++ + case utilities.OpCapture: + if op.operand < 0 || len(pool) <= op.operand { + grpclog.Printf("variable name index out of bound: %d", op.operand) + return Pattern{}, ErrInvalidPattern + } + v := pool[op.operand] + op.operand = len(vars) + vars = append(vars, v) + stack-- + if stack < 0 { + grpclog.Printf("stack underflow") + return Pattern{}, ErrInvalidPattern + } + default: + grpclog.Printf("invalid opcode: %d", op.code) + return Pattern{}, ErrInvalidPattern + } + + if maxstack < stack { + maxstack = stack + } + typedOps = append(typedOps, op) + } + return Pattern{ + ops: typedOps, + pool: pool, + vars: vars, + stacksize: maxstack, + tailLen: tailLen, + verb: verb, + }, nil +} + +// MustPattern is a helper function which makes it easier to call NewPattern in variable initialization. +func MustPattern(p Pattern, err error) Pattern { + if err != nil { + grpclog.Fatalf("Pattern initialization failed: %v", err) + } + return p +} + +// Match examines components if it matches to the Pattern. +// If it matches, the function returns a mapping from field paths to their captured values. +// If otherwise, the function returns an error. +func (p Pattern) Match(components []string, verb string) (map[string]string, error) { + if p.verb != verb { + return nil, ErrNotMatch + } + + var pos int + stack := make([]string, 0, p.stacksize) + captured := make([]string, len(p.vars)) + l := len(components) + for _, op := range p.ops { + switch op.code { + case utilities.OpNop: + continue + case utilities.OpPush, utilities.OpLitPush: + if pos >= l { + return nil, ErrNotMatch + } + c := components[pos] + if op.code == utilities.OpLitPush { + if lit := p.pool[op.operand]; c != lit { + return nil, ErrNotMatch + } + } + stack = append(stack, c) + pos++ + case utilities.OpPushM: + end := len(components) + if end < pos+p.tailLen { + return nil, ErrNotMatch + } + end -= p.tailLen + stack = append(stack, strings.Join(components[pos:end], "/")) + pos = end + case utilities.OpConcatN: + n := op.operand + l := len(stack) - n + stack = append(stack[:l], strings.Join(stack[l:], "/")) + case utilities.OpCapture: + n := len(stack) - 1 + captured[op.operand] = stack[n] + stack = stack[:n] + } + } + if pos < l { + return nil, ErrNotMatch + } + bindings := make(map[string]string) + for i, val := range captured { + bindings[p.vars[i]] = val + } + return bindings, nil +} + +// Verb returns the verb part of the Pattern. +func (p Pattern) Verb() string { return p.verb } + +func (p Pattern) String() string { + var stack []string + for _, op := range p.ops { + switch op.code { + case utilities.OpNop: + continue + case utilities.OpPush: + stack = append(stack, "*") + case utilities.OpLitPush: + stack = append(stack, p.pool[op.operand]) + case utilities.OpPushM: + stack = append(stack, "**") + case utilities.OpConcatN: + n := op.operand + l := len(stack) - n + stack = append(stack[:l], strings.Join(stack[l:], "/")) + case utilities.OpCapture: + n := len(stack) - 1 + stack[n] = fmt.Sprintf("{%s=%s}", p.vars[op.operand], stack[n]) + } + } + segs := strings.Join(stack, "/") + if p.verb != "" { + return fmt.Sprintf("/%s:%s", segs, p.verb) + } + return "/" + segs +} diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/proto2_convert.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/proto2_convert.go new file mode 100644 index 00000000000..a3151e2a552 --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/proto2_convert.go @@ -0,0 +1,80 @@ +package runtime + +import ( + "github.com/golang/protobuf/proto" +) + +// StringP returns a pointer to a string whose pointee is same as the given string value. +func StringP(val string) (*string, error) { + return proto.String(val), nil +} + +// BoolP parses the given string representation of a boolean value, +// and returns a pointer to a bool whose value is same as the parsed value. +func BoolP(val string) (*bool, error) { + b, err := Bool(val) + if err != nil { + return nil, err + } + return proto.Bool(b), nil +} + +// Float64P parses the given string representation of a floating point number, +// and returns a pointer to a float64 whose value is same as the parsed number. +func Float64P(val string) (*float64, error) { + f, err := Float64(val) + if err != nil { + return nil, err + } + return proto.Float64(f), nil +} + +// Float32P parses the given string representation of a floating point number, +// and returns a pointer to a float32 whose value is same as the parsed number. +func Float32P(val string) (*float32, error) { + f, err := Float32(val) + if err != nil { + return nil, err + } + return proto.Float32(f), nil +} + +// Int64P parses the given string representation of an integer +// and returns a pointer to a int64 whose value is same as the parsed integer. +func Int64P(val string) (*int64, error) { + i, err := Int64(val) + if err != nil { + return nil, err + } + return proto.Int64(i), nil +} + +// Int32P parses the given string representation of an integer +// and returns a pointer to a int32 whose value is same as the parsed integer. +func Int32P(val string) (*int32, error) { + i, err := Int32(val) + if err != nil { + return nil, err + } + return proto.Int32(i), err +} + +// Uint64P parses the given string representation of an integer +// and returns a pointer to a uint64 whose value is same as the parsed integer. +func Uint64P(val string) (*uint64, error) { + i, err := Uint64(val) + if err != nil { + return nil, err + } + return proto.Uint64(i), err +} + +// Uint32P parses the given string representation of an integer +// and returns a pointer to a uint32 whose value is same as the parsed integer. +func Uint32P(val string) (*uint32, error) { + i, err := Uint32(val) + if err != nil { + return nil, err + } + return proto.Uint32(i), err +} diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/query.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/query.go new file mode 100644 index 00000000000..56a919a52f1 --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/query.go @@ -0,0 +1,140 @@ +package runtime + +import ( + "fmt" + "net/url" + "reflect" + "strings" + + "github.com/golang/protobuf/proto" + "github.com/grpc-ecosystem/grpc-gateway/utilities" + "google.golang.org/grpc/grpclog" +) + +// PopulateQueryParameters populates "values" into "msg". +// A value is ignored if its key starts with one of the elements in "filter". +func PopulateQueryParameters(msg proto.Message, values url.Values, filter *utilities.DoubleArray) error { + for key, values := range values { + fieldPath := strings.Split(key, ".") + if filter.HasCommonPrefix(fieldPath) { + continue + } + if err := populateFieldValueFromPath(msg, fieldPath, values); err != nil { + return err + } + } + return nil +} + +// PopulateFieldFromPath sets a value in a nested Protobuf structure. +// It instantiates missing protobuf fields as it goes. +func PopulateFieldFromPath(msg proto.Message, fieldPathString string, value string) error { + fieldPath := strings.Split(fieldPathString, ".") + return populateFieldValueFromPath(msg, fieldPath, []string{value}) +} + +func populateFieldValueFromPath(msg proto.Message, fieldPath []string, values []string) error { + m := reflect.ValueOf(msg) + if m.Kind() != reflect.Ptr { + return fmt.Errorf("unexpected type %T: %v", msg, msg) + } + m = m.Elem() + for i, fieldName := range fieldPath { + isLast := i == len(fieldPath)-1 + if !isLast && m.Kind() != reflect.Struct { + return fmt.Errorf("non-aggregate type in the mid of path: %s", strings.Join(fieldPath, ".")) + } + f := fieldByProtoName(m, fieldName) + if !f.IsValid() { + grpclog.Printf("field not found in %T: %s", msg, strings.Join(fieldPath, ".")) + return nil + } + + switch f.Kind() { + case reflect.Bool, reflect.Float32, reflect.Float64, reflect.Int32, reflect.Int64, reflect.String, reflect.Uint32, reflect.Uint64: + m = f + case reflect.Slice: + // TODO(yugui) Support []byte + if !isLast { + return fmt.Errorf("unexpected repeated field in %s", strings.Join(fieldPath, ".")) + } + return populateRepeatedField(f, values) + case reflect.Ptr: + if f.IsNil() { + m = reflect.New(f.Type().Elem()) + f.Set(m) + } + m = f.Elem() + continue + case reflect.Struct: + m = f + continue + default: + return fmt.Errorf("unexpected type %s in %T", f.Type(), msg) + } + } + switch len(values) { + case 0: + return fmt.Errorf("no value of field: %s", strings.Join(fieldPath, ".")) + case 1: + default: + grpclog.Printf("too many field values: %s", strings.Join(fieldPath, ".")) + } + return populateField(m, values[0]) +} + +// fieldByProtoName looks up a field whose corresponding protobuf field name is "name". +// "m" must be a struct value. It returns zero reflect.Value if no such field found. +func fieldByProtoName(m reflect.Value, name string) reflect.Value { + props := proto.GetProperties(m.Type()) + for _, p := range props.Prop { + if p.OrigName == name { + return m.FieldByName(p.Name) + } + } + return reflect.Value{} +} + +func populateRepeatedField(f reflect.Value, values []string) error { + elemType := f.Type().Elem() + conv, ok := convFromType[elemType.Kind()] + if !ok { + return fmt.Errorf("unsupported field type %s", elemType) + } + f.Set(reflect.MakeSlice(f.Type(), len(values), len(values))) + for i, v := range values { + result := conv.Call([]reflect.Value{reflect.ValueOf(v)}) + if err := result[1].Interface(); err != nil { + return err.(error) + } + f.Index(i).Set(result[0]) + } + return nil +} + +func populateField(f reflect.Value, value string) error { + conv, ok := convFromType[f.Kind()] + if !ok { + return fmt.Errorf("unsupported field type %T", f) + } + result := conv.Call([]reflect.Value{reflect.ValueOf(value)}) + if err := result[1].Interface(); err != nil { + return err.(error) + } + f.Set(result[0]) + return nil +} + +var ( + convFromType = map[reflect.Kind]reflect.Value{ + reflect.String: reflect.ValueOf(String), + reflect.Bool: reflect.ValueOf(Bool), + reflect.Float64: reflect.ValueOf(Float64), + reflect.Float32: reflect.ValueOf(Float32), + reflect.Int64: reflect.ValueOf(Int64), + reflect.Int32: reflect.ValueOf(Int32), + reflect.Uint64: reflect.ValueOf(Uint64), + reflect.Uint32: reflect.ValueOf(Uint32), + // TODO(yugui) Support []byte + } +) diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/utilities/doc.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/utilities/doc.go new file mode 100644 index 00000000000..cf79a4d5886 --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/utilities/doc.go @@ -0,0 +1,2 @@ +// Package utilities provides members for internal use in grpc-gateway. +package utilities diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/utilities/pattern.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/utilities/pattern.go new file mode 100644 index 00000000000..28ad9461f86 --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/utilities/pattern.go @@ -0,0 +1,22 @@ +package utilities + +// An OpCode is a opcode of compiled path patterns. +type OpCode int + +// These constants are the valid values of OpCode. +const ( + // OpNop does nothing + OpNop = OpCode(iota) + // OpPush pushes a component to stack + OpPush + // OpLitPush pushes a component to stack if it matches to the literal + OpLitPush + // OpPushM concatenates the remaining components and pushes it to stack + OpPushM + // OpConcatN pops N items from stack, concatenates them and pushes it back to stack + OpConcatN + // OpCapture pops an item and binds it to the variable + OpCapture + // OpEnd is the least postive invalid opcode. + OpEnd +) diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/utilities/trie.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/utilities/trie.go new file mode 100644 index 00000000000..c2b7b30dd91 --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/utilities/trie.go @@ -0,0 +1,177 @@ +package utilities + +import ( + "sort" +) + +// DoubleArray is a Double Array implementation of trie on sequences of strings. +type DoubleArray struct { + // Encoding keeps an encoding from string to int + Encoding map[string]int + // Base is the base array of Double Array + Base []int + // Check is the check array of Double Array + Check []int +} + +// NewDoubleArray builds a DoubleArray from a set of sequences of strings. +func NewDoubleArray(seqs [][]string) *DoubleArray { + da := &DoubleArray{Encoding: make(map[string]int)} + if len(seqs) == 0 { + return da + } + + encoded := registerTokens(da, seqs) + sort.Sort(byLex(encoded)) + + root := node{row: -1, col: -1, left: 0, right: len(encoded)} + addSeqs(da, encoded, 0, root) + + for i := len(da.Base); i > 0; i-- { + if da.Check[i-1] != 0 { + da.Base = da.Base[:i] + da.Check = da.Check[:i] + break + } + } + return da +} + +func registerTokens(da *DoubleArray, seqs [][]string) [][]int { + var result [][]int + for _, seq := range seqs { + var encoded []int + for _, token := range seq { + if _, ok := da.Encoding[token]; !ok { + da.Encoding[token] = len(da.Encoding) + } + encoded = append(encoded, da.Encoding[token]) + } + result = append(result, encoded) + } + for i := range result { + result[i] = append(result[i], len(da.Encoding)) + } + return result +} + +type node struct { + row, col int + left, right int +} + +func (n node) value(seqs [][]int) int { + return seqs[n.row][n.col] +} + +func (n node) children(seqs [][]int) []*node { + var result []*node + lastVal := int(-1) + last := new(node) + for i := n.left; i < n.right; i++ { + if lastVal == seqs[i][n.col+1] { + continue + } + last.right = i + last = &node{ + row: i, + col: n.col + 1, + left: i, + } + result = append(result, last) + } + last.right = n.right + return result +} + +func addSeqs(da *DoubleArray, seqs [][]int, pos int, n node) { + ensureSize(da, pos) + + children := n.children(seqs) + var i int + for i = 1; ; i++ { + ok := func() bool { + for _, child := range children { + code := child.value(seqs) + j := i + code + ensureSize(da, j) + if da.Check[j] != 0 { + return false + } + } + return true + }() + if ok { + break + } + } + da.Base[pos] = i + for _, child := range children { + code := child.value(seqs) + j := i + code + da.Check[j] = pos + 1 + } + terminator := len(da.Encoding) + for _, child := range children { + code := child.value(seqs) + if code == terminator { + continue + } + j := i + code + addSeqs(da, seqs, j, *child) + } +} + +func ensureSize(da *DoubleArray, i int) { + for i >= len(da.Base) { + da.Base = append(da.Base, make([]int, len(da.Base)+1)...) + da.Check = append(da.Check, make([]int, len(da.Check)+1)...) + } +} + +type byLex [][]int + +func (l byLex) Len() int { return len(l) } +func (l byLex) Swap(i, j int) { l[i], l[j] = l[j], l[i] } +func (l byLex) Less(i, j int) bool { + si := l[i] + sj := l[j] + var k int + for k = 0; k < len(si) && k < len(sj); k++ { + if si[k] < sj[k] { + return true + } + if si[k] > sj[k] { + return false + } + } + if k < len(sj) { + return true + } + return false +} + +// HasCommonPrefix determines if any sequence in the DoubleArray is a prefix of the given sequence. +func (da *DoubleArray) HasCommonPrefix(seq []string) bool { + if len(da.Base) == 0 { + return false + } + + var i int + for _, t := range seq { + code, ok := da.Encoding[t] + if !ok { + break + } + j := da.Base[i] + code + if len(da.Check) <= j || da.Check[j] != i+1 { + break + } + i = j + } + j := da.Base[i] + len(da.Encoding) + if len(da.Check) <= j || da.Check[j] != i+1 { + return false + } + return true +} diff --git a/vendor/github.com/jonboulle/clockwork/.travis.yml b/vendor/github.com/jonboulle/clockwork/.travis.yml deleted file mode 100644 index 6a363c70f86..00000000000 --- a/vendor/github.com/jonboulle/clockwork/.travis.yml +++ /dev/null @@ -1,3 +0,0 @@ -language: go -go: - - 1.3 diff --git a/vendor/github.com/jonboulle/clockwork/README.md b/vendor/github.com/jonboulle/clockwork/README.md index d43a6c799a0..236c86a2442 100644 --- a/vendor/github.com/jonboulle/clockwork/README.md +++ b/vendor/github.com/jonboulle/clockwork/README.md @@ -1,9 +1,6 @@ clockwork ========= -[![Build Status](https://travis-ci.org/jonboulle/clockwork.png?branch=master)](https://travis-ci.org/jonboulle/clockwork) -[![godoc](https://godoc.org/github.com/jonboulle/clockwork?status.svg)](http://godoc.org/github.com/jonboulle/clockwork) - a simple fake clock for golang # Usage @@ -58,4 +55,4 @@ See [example_test.go](example_test.go) for a full example. # Credits -clockwork is inspired by @wickman's [threaded fake clock](https://gist.github.com/wickman/3840816), and the [Golang playground](http://blog.golang.org/playground#Faking time) +Inspired by @wickman's [threaded fake clock](https://gist.github.com/wickman/3840816), and the [Golang playground](http://blog.golang.org/playground#Faking time) diff --git a/vendor/github.com/jonboulle/clockwork/clockwork.go b/vendor/github.com/jonboulle/clockwork/clockwork.go index 1f1045bc0d9..4b6918b522a 100644 --- a/vendor/github.com/jonboulle/clockwork/clockwork.go +++ b/vendor/github.com/jonboulle/clockwork/clockwork.go @@ -36,9 +36,6 @@ func NewRealClock() Clock { func NewFakeClock() FakeClock { return &fakeClock{ l: sync.RWMutex{}, - - // use a fixture that does not fulfill Time.IsZero() - time: time.Date(1900, time.January, 1, 0, 0, 0, 0, time.UTC), } } diff --git a/vendor/github.com/prometheus/client_golang/prometheus/go_collector.go b/vendor/github.com/prometheus/client_golang/prometheus/go_collector.go index 85fa20be455..8be24769518 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/go_collector.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/go_collector.go @@ -1,6 +1,7 @@ package prometheus import ( + "fmt" "runtime" "runtime/debug" "time" @@ -9,6 +10,9 @@ import ( type goCollector struct { goroutines Gauge gcDesc *Desc + + // metrics to describe and collect + metrics memStatsMetrics } // NewGoCollector returns a collector which exports metrics about the current @@ -16,20 +20,216 @@ type goCollector struct { func NewGoCollector() *goCollector { return &goCollector{ goroutines: NewGauge(GaugeOpts{ - Name: "go_goroutines", - Help: "Number of goroutines that currently exist.", + Namespace: "go", + Name: "goroutines", + Help: "Number of goroutines that currently exist.", }), gcDesc: NewDesc( "go_gc_duration_seconds", "A summary of the GC invocation durations.", nil, nil), + metrics: memStatsMetrics{ + { + desc: NewDesc( + memstatNamespace("alloc_bytes"), + "Number of bytes allocated and still in use.", + nil, nil, + ), + eval: func(ms *runtime.MemStats) float64 { return float64(ms.Alloc) }, + valType: GaugeValue, + }, { + desc: NewDesc( + memstatNamespace("alloc_bytes_total"), + "Total number of bytes allocated, even if freed.", + nil, nil, + ), + eval: func(ms *runtime.MemStats) float64 { return float64(ms.TotalAlloc) }, + valType: CounterValue, + }, { + desc: NewDesc( + memstatNamespace("sys_bytes"), + "Number of bytes obtained by system. Sum of all system allocations.", + nil, nil, + ), + eval: func(ms *runtime.MemStats) float64 { return float64(ms.Sys) }, + valType: GaugeValue, + }, { + desc: NewDesc( + memstatNamespace("lookups_total"), + "Total number of pointer lookups.", + nil, nil, + ), + eval: func(ms *runtime.MemStats) float64 { return float64(ms.Lookups) }, + valType: CounterValue, + }, { + desc: NewDesc( + memstatNamespace("mallocs_total"), + "Total number of mallocs.", + nil, nil, + ), + eval: func(ms *runtime.MemStats) float64 { return float64(ms.Mallocs) }, + valType: CounterValue, + }, { + desc: NewDesc( + memstatNamespace("frees_total"), + "Total number of frees.", + nil, nil, + ), + eval: func(ms *runtime.MemStats) float64 { return float64(ms.Frees) }, + valType: CounterValue, + }, { + desc: NewDesc( + memstatNamespace("heap_alloc_bytes"), + "Number of heap bytes allocated and still in use.", + nil, nil, + ), + eval: func(ms *runtime.MemStats) float64 { return float64(ms.HeapAlloc) }, + valType: GaugeValue, + }, { + desc: NewDesc( + memstatNamespace("heap_sys_bytes"), + "Number of heap bytes obtained from system.", + nil, nil, + ), + eval: func(ms *runtime.MemStats) float64 { return float64(ms.HeapSys) }, + valType: GaugeValue, + }, { + desc: NewDesc( + memstatNamespace("heap_idle_bytes"), + "Number of heap bytes waiting to be used.", + nil, nil, + ), + eval: func(ms *runtime.MemStats) float64 { return float64(ms.HeapIdle) }, + valType: GaugeValue, + }, { + desc: NewDesc( + memstatNamespace("heap_inuse_bytes"), + "Number of heap bytes that are in use.", + nil, nil, + ), + eval: func(ms *runtime.MemStats) float64 { return float64(ms.HeapInuse) }, + valType: GaugeValue, + }, { + desc: NewDesc( + memstatNamespace("heap_released_bytes_total"), + "Total number of heap bytes released to OS.", + nil, nil, + ), + eval: func(ms *runtime.MemStats) float64 { return float64(ms.HeapReleased) }, + valType: CounterValue, + }, { + desc: NewDesc( + memstatNamespace("heap_objects"), + "Number of allocated objects.", + nil, nil, + ), + eval: func(ms *runtime.MemStats) float64 { return float64(ms.HeapObjects) }, + valType: GaugeValue, + }, { + desc: NewDesc( + memstatNamespace("stack_inuse_bytes"), + "Number of bytes in use by the stack allocator.", + nil, nil, + ), + eval: func(ms *runtime.MemStats) float64 { return float64(ms.StackInuse) }, + valType: GaugeValue, + }, { + desc: NewDesc( + memstatNamespace("stack_sys_bytes"), + "Number of bytes obtained from system for stack allocator.", + nil, nil, + ), + eval: func(ms *runtime.MemStats) float64 { return float64(ms.StackSys) }, + valType: GaugeValue, + }, { + desc: NewDesc( + memstatNamespace("mspan_inuse_bytes"), + "Number of bytes in use by mspan structures.", + nil, nil, + ), + eval: func(ms *runtime.MemStats) float64 { return float64(ms.MSpanInuse) }, + valType: GaugeValue, + }, { + desc: NewDesc( + memstatNamespace("mspan_sys_bytes"), + "Number of bytes used for mspan structures obtained from system.", + nil, nil, + ), + eval: func(ms *runtime.MemStats) float64 { return float64(ms.MSpanSys) }, + valType: GaugeValue, + }, { + desc: NewDesc( + memstatNamespace("mcache_inuse_bytes"), + "Number of bytes in use by mcache structures.", + nil, nil, + ), + eval: func(ms *runtime.MemStats) float64 { return float64(ms.MCacheInuse) }, + valType: GaugeValue, + }, { + desc: NewDesc( + memstatNamespace("mcache_sys_bytes"), + "Number of bytes used for mcache structures obtained from system.", + nil, nil, + ), + eval: func(ms *runtime.MemStats) float64 { return float64(ms.MCacheSys) }, + valType: GaugeValue, + }, { + desc: NewDesc( + memstatNamespace("buck_hash_sys_bytes"), + "Number of bytes used by the profiling bucket hash table.", + nil, nil, + ), + eval: func(ms *runtime.MemStats) float64 { return float64(ms.BuckHashSys) }, + valType: GaugeValue, + }, { + desc: NewDesc( + memstatNamespace("gc_sys_bytes"), + "Number of bytes used for garbage collection system metadata.", + nil, nil, + ), + eval: func(ms *runtime.MemStats) float64 { return float64(ms.GCSys) }, + valType: GaugeValue, + }, { + desc: NewDesc( + memstatNamespace("other_sys_bytes"), + "Number of bytes used for other system allocations.", + nil, nil, + ), + eval: func(ms *runtime.MemStats) float64 { return float64(ms.OtherSys) }, + valType: GaugeValue, + }, { + desc: NewDesc( + memstatNamespace("next_gc_bytes"), + "Number of heap bytes when next garbage collection will take place.", + nil, nil, + ), + eval: func(ms *runtime.MemStats) float64 { return float64(ms.NextGC) }, + valType: GaugeValue, + }, { + desc: NewDesc( + memstatNamespace("last_gc_time_seconds"), + "Number of seconds since 1970 of last garbage collection.", + nil, nil, + ), + eval: func(ms *runtime.MemStats) float64 { return float64(ms.LastGC*10 ^ 9) }, + valType: GaugeValue, + }, + }, } } +func memstatNamespace(s string) string { + return fmt.Sprintf("go_memstats_%s", s) +} + // Describe returns all descriptions of the collector. func (c *goCollector) Describe(ch chan<- *Desc) { ch <- c.goroutines.Desc() ch <- c.gcDesc + + for _, i := range c.metrics { + ch <- i.desc + } } // Collect returns the current state of all metrics of the collector. @@ -47,4 +247,17 @@ func (c *goCollector) Collect(ch chan<- Metric) { } quantiles[0.0] = stats.PauseQuantiles[0].Seconds() ch <- MustNewConstSummary(c.gcDesc, uint64(stats.NumGC), float64(stats.PauseTotal.Seconds()), quantiles) + + ms := &runtime.MemStats{} + runtime.ReadMemStats(ms) + for _, i := range c.metrics { + ch <- MustNewConstMetric(i.desc, i.valType, i.eval(ms)) + } +} + +// memStatsMetrics provide description, value, and value type for memstat metrics. +type memStatsMetrics []struct { + desc *Desc + eval func(*runtime.MemStats) float64 + valType ValueType } diff --git a/vendor/github.com/prometheus/common/expfmt/decode.go b/vendor/github.com/prometheus/common/expfmt/decode.go index a98696dfc30..b72c9bedefc 100644 --- a/vendor/github.com/prometheus/common/expfmt/decode.go +++ b/vendor/github.com/prometheus/common/expfmt/decode.go @@ -107,29 +107,7 @@ type protoDecoder struct { // Decode implements the Decoder interface. func (d *protoDecoder) Decode(v *dto.MetricFamily) error { _, err := pbutil.ReadDelimited(d.r, v) - if err != nil { - return err - } - if !model.IsValidMetricName(model.LabelValue(v.GetName())) { - return fmt.Errorf("invalid metric name %q", v.GetName()) - } - for _, m := range v.GetMetric() { - if m == nil { - continue - } - for _, l := range m.GetLabel() { - if l == nil { - continue - } - if !model.LabelValue(l.GetValue()).IsValid() { - return fmt.Errorf("invalid label value %q", l.GetValue()) - } - if !model.LabelName(l.GetName()).IsValid() { - return fmt.Errorf("invalid label name %q", l.GetName()) - } - } - } - return nil + return err } // textDecoder implements the Decoder interface for the text protcol. diff --git a/vendor/github.com/prometheus/common/expfmt/encode.go b/vendor/github.com/prometheus/common/expfmt/encode.go index 11839ed65ce..392ca90ee25 100644 --- a/vendor/github.com/prometheus/common/expfmt/encode.go +++ b/vendor/github.com/prometheus/common/expfmt/encode.go @@ -18,9 +18,9 @@ import ( "io" "net/http" + "bitbucket.org/ww/goautoneg" "github.com/golang/protobuf/proto" "github.com/matttproud/golang_protobuf_extensions/pbutil" - "github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg" dto "github.com/prometheus/client_model/go" ) diff --git a/vendor/github.com/prometheus/common/expfmt/fuzz.go b/vendor/github.com/prometheus/common/expfmt/fuzz.go index dc2eedeefca..14f92014692 100644 --- a/vendor/github.com/prometheus/common/expfmt/fuzz.go +++ b/vendor/github.com/prometheus/common/expfmt/fuzz.go @@ -20,8 +20,8 @@ import "bytes" // Fuzz text metric parser with with github.com/dvyukov/go-fuzz: // -// go-fuzz-build github.com/prometheus/common/expfmt -// go-fuzz -bin expfmt-fuzz.zip -workdir fuzz +// go-fuzz-build github.com/prometheus/client_golang/text +// go-fuzz -bin text-fuzz.zip -workdir fuzz // // Further input samples should go in the folder fuzz/corpus. func Fuzz(in []byte) int { diff --git a/vendor/github.com/prometheus/common/expfmt/json_decode.go b/vendor/github.com/prometheus/common/expfmt/json_decode.go index cf86545188b..67e3a0d4d65 100644 --- a/vendor/github.com/prometheus/common/expfmt/json_decode.go +++ b/vendor/github.com/prometheus/common/expfmt/json_decode.go @@ -46,7 +46,7 @@ type counter002 struct { Value float64 `json:"value"` } -func protoLabelSet(base, ext model.LabelSet) ([]*dto.LabelPair, error) { +func protoLabelSet(base, ext model.LabelSet) []*dto.LabelPair { labels := base.Clone().Merge(ext) delete(labels, model.MetricNameLabel) @@ -59,9 +59,6 @@ func protoLabelSet(base, ext model.LabelSet) ([]*dto.LabelPair, error) { pairs := make([]*dto.LabelPair, 0, len(labels)) for _, ln := range names { - if !model.LabelNameRE.MatchString(ln) { - return nil, fmt.Errorf("invalid label name %q", ln) - } lv := labels[model.LabelName(ln)] pairs = append(pairs, &dto.LabelPair{ @@ -70,7 +67,7 @@ func protoLabelSet(base, ext model.LabelSet) ([]*dto.LabelPair, error) { }) } - return pairs, nil + return pairs } func (d *json2Decoder) more() error { @@ -105,12 +102,8 @@ func (d *json2Decoder) more() error { } for _, ctr := range values { - labels, err := protoLabelSet(e.BaseLabels, ctr.Labels) - if err != nil { - return err - } f.Metric = append(f.Metric, &dto.Metric{ - Label: labels, + Label: protoLabelSet(e.BaseLabels, ctr.Labels), Untyped: &dto.Untyped{ Value: proto.Float64(ctr.Value), }, @@ -138,13 +131,8 @@ func (d *json2Decoder) more() error { // this remains "percentile" hist.Labels["percentile"] = model.LabelValue(q) - labels, err := protoLabelSet(e.BaseLabels, hist.Labels) - if err != nil { - return err - } - f.Metric = append(f.Metric, &dto.Metric{ - Label: labels, + Label: protoLabelSet(e.BaseLabels, hist.Labels), Untyped: &dto.Untyped{ Value: proto.Float64(value), }, diff --git a/vendor/github.com/prometheus/common/expfmt/text_parse.go b/vendor/github.com/prometheus/common/expfmt/text_parse.go index bd170b1675f..84433bc4f6e 100644 --- a/vendor/github.com/prometheus/common/expfmt/text_parse.go +++ b/vendor/github.com/prometheus/common/expfmt/text_parse.go @@ -108,13 +108,6 @@ func (p *TextParser) TextToMetricFamilies(in io.Reader) (map[string]*dto.MetricF delete(p.metricFamiliesByName, k) } } - // If p.err is io.EOF now, we have run into a premature end of the input - // stream. Turn this error into something nicer and more - // meaningful. (io.EOF is often used as a signal for the legitimate end - // of an input stream.) - if p.err == io.EOF { - p.parseError("unexpected end of input stream") - } return p.metricFamiliesByName, p.err } diff --git a/vendor/github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg/README.txt b/vendor/github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg/README.txt deleted file mode 100644 index 7723656d58d..00000000000 --- a/vendor/github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg/README.txt +++ /dev/null @@ -1,67 +0,0 @@ -PACKAGE - -package goautoneg -import "bitbucket.org/ww/goautoneg" - -HTTP Content-Type Autonegotiation. - -The functions in this package implement the behaviour specified in -http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html - -Copyright (c) 2011, Open Knowledge Foundation Ltd. -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 the Open Knowledge Foundation Ltd. 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 -HOLDER 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. - - -FUNCTIONS - -func Negotiate(header string, alternatives []string) (content_type string) -Negotiate the most appropriate content_type given the accept header -and a list of alternatives. - -func ParseAccept(header string) (accept []Accept) -Parse an Accept Header string returning a sorted list -of clauses - - -TYPES - -type Accept struct { - Type, SubType string - Q float32 - Params map[string]string -} -Structure to represent a clause in an HTTP Accept Header - - -SUBDIRECTORIES - - .hg diff --git a/vendor/github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg/autoneg.go b/vendor/github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg/autoneg.go deleted file mode 100644 index 648b38cb654..00000000000 --- a/vendor/github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg/autoneg.go +++ /dev/null @@ -1,162 +0,0 @@ -/* -HTTP Content-Type Autonegotiation. - -The functions in this package implement the behaviour specified in -http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html - -Copyright (c) 2011, Open Knowledge Foundation Ltd. -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 the Open Knowledge Foundation Ltd. 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 -HOLDER 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 goautoneg - -import ( - "sort" - "strconv" - "strings" -) - -// Structure to represent a clause in an HTTP Accept Header -type Accept struct { - Type, SubType string - Q float64 - Params map[string]string -} - -// For internal use, so that we can use the sort interface -type accept_slice []Accept - -func (accept accept_slice) Len() int { - slice := []Accept(accept) - return len(slice) -} - -func (accept accept_slice) Less(i, j int) bool { - slice := []Accept(accept) - ai, aj := slice[i], slice[j] - if ai.Q > aj.Q { - return true - } - if ai.Type != "*" && aj.Type == "*" { - return true - } - if ai.SubType != "*" && aj.SubType == "*" { - return true - } - return false -} - -func (accept accept_slice) Swap(i, j int) { - slice := []Accept(accept) - slice[i], slice[j] = slice[j], slice[i] -} - -// Parse an Accept Header string returning a sorted list -// of clauses -func ParseAccept(header string) (accept []Accept) { - parts := strings.Split(header, ",") - accept = make([]Accept, 0, len(parts)) - for _, part := range parts { - part := strings.Trim(part, " ") - - a := Accept{} - a.Params = make(map[string]string) - a.Q = 1.0 - - mrp := strings.Split(part, ";") - - media_range := mrp[0] - sp := strings.Split(media_range, "/") - a.Type = strings.Trim(sp[0], " ") - - switch { - case len(sp) == 1 && a.Type == "*": - a.SubType = "*" - case len(sp) == 2: - a.SubType = strings.Trim(sp[1], " ") - default: - continue - } - - if len(mrp) == 1 { - accept = append(accept, a) - continue - } - - for _, param := range mrp[1:] { - sp := strings.SplitN(param, "=", 2) - if len(sp) != 2 { - continue - } - token := strings.Trim(sp[0], " ") - if token == "q" { - a.Q, _ = strconv.ParseFloat(sp[1], 32) - } else { - a.Params[token] = strings.Trim(sp[1], " ") - } - } - - accept = append(accept, a) - } - - slice := accept_slice(accept) - sort.Sort(slice) - - return -} - -// Negotiate the most appropriate content_type given the accept header -// and a list of alternatives. -func Negotiate(header string, alternatives []string) (content_type string) { - asp := make([][]string, 0, len(alternatives)) - for _, ctype := range alternatives { - asp = append(asp, strings.SplitN(ctype, "/", 2)) - } - for _, clause := range ParseAccept(header) { - for i, ctsp := range asp { - if clause.Type == ctsp[0] && clause.SubType == ctsp[1] { - content_type = alternatives[i] - return - } - if clause.Type == ctsp[0] && clause.SubType == "*" { - content_type = alternatives[i] - return - } - if clause.Type == "*" && clause.SubType == "*" { - content_type = alternatives[i] - return - } - } - } - return -} diff --git a/vendor/github.com/prometheus/common/model/alert.go b/vendor/github.com/prometheus/common/model/alert.go index 35e739c7ad2..b027e9f3db3 100644 --- a/vendor/github.com/prometheus/common/model/alert.go +++ b/vendor/github.com/prometheus/common/model/alert.go @@ -35,9 +35,8 @@ type Alert struct { Annotations LabelSet `json:"annotations"` // The known time range for this alert. Both ends are optional. - StartsAt time.Time `json:"startsAt,omitempty"` - EndsAt time.Time `json:"endsAt,omitempty"` - GeneratorURL string `json:"generatorURL"` + StartsAt time.Time `json:"startsAt,omitempty"` + EndsAt time.Time `json:"endsAt,omitempty"` } // Name returns the name of the alert. It is equivalent to the "alertname" label. @@ -61,16 +60,10 @@ func (a *Alert) String() string { // Resolved returns true iff the activity interval ended in the past. func (a *Alert) Resolved() bool { - return a.ResolvedAt(time.Now()) -} - -// ResolvedAt returns true off the activity interval ended before -// the given timestamp. -func (a *Alert) ResolvedAt(ts time.Time) bool { if a.EndsAt.IsZero() { return false } - return !a.EndsAt.After(ts) + return !a.EndsAt.After(time.Now()) } // Status returns the status of the alert. @@ -81,26 +74,6 @@ func (a *Alert) Status() AlertStatus { return AlertFiring } -// Validate checks whether the alert data is inconsistent. -func (a *Alert) Validate() error { - if a.StartsAt.IsZero() { - return fmt.Errorf("start time missing") - } - if !a.EndsAt.IsZero() && a.EndsAt.Before(a.StartsAt) { - return fmt.Errorf("start time must be before end time") - } - if err := a.Labels.Validate(); err != nil { - return fmt.Errorf("invalid label set: %s", err) - } - if len(a.Labels) == 0 { - return fmt.Errorf("at least one label pair required") - } - if err := a.Annotations.Validate(); err != nil { - return fmt.Errorf("invalid annotations: %s", err) - } - return nil -} - // Alert is a list of alerts that can be sorted in chronological order. type Alerts []*Alert diff --git a/vendor/github.com/prometheus/common/model/fnv.go b/vendor/github.com/prometheus/common/model/fnv.go deleted file mode 100644 index 038fc1c9003..00000000000 --- a/vendor/github.com/prometheus/common/model/fnv.go +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright 2015 The Prometheus 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 model - -// Inline and byte-free variant of hash/fnv's fnv64a. - -const ( - offset64 = 14695981039346656037 - prime64 = 1099511628211 -) - -// hashNew initializies a new fnv64a hash value. -func hashNew() uint64 { - return offset64 -} - -// hashAdd adds a string to a fnv64a hash value, returning the updated hash. -func hashAdd(h uint64, s string) uint64 { - for i := 0; i < len(s); i++ { - h ^= uint64(s[i]) - h *= prime64 - } - return h -} - -// hashAddByte adds a byte to a fnv64a hash value, returning the updated hash. -func hashAddByte(h uint64, b byte) uint64 { - h ^= uint64(b) - h *= prime64 - return h -} diff --git a/vendor/github.com/prometheus/common/model/labels.go b/vendor/github.com/prometheus/common/model/labels.go index 3b72e7ff8f6..6459c8f791b 100644 --- a/vendor/github.com/prometheus/common/model/labels.go +++ b/vendor/github.com/prometheus/common/model/labels.go @@ -17,8 +17,8 @@ import ( "encoding/json" "fmt" "regexp" + "sort" "strings" - "unicode/utf8" ) const ( @@ -87,19 +87,6 @@ var LabelNameRE = regexp.MustCompile("^[a-zA-Z_][a-zA-Z0-9_]*$") // therewith. type LabelName string -// IsValid is true iff the label name matches the pattern of LabelNameRE. -func (ln LabelName) IsValid() bool { - if len(ln) == 0 { - return false - } - for i, b := range ln { - if !((b >= 'a' && b <= 'z') || (b >= 'A' && b <= 'Z') || b == '_' || (b >= '0' && b <= '9' && i > 0)) { - return false - } - } - return true -} - // UnmarshalYAML implements the yaml.Unmarshaler interface. func (ln *LabelName) UnmarshalYAML(unmarshal func(interface{}) error) error { var s string @@ -152,11 +139,6 @@ func (l LabelNames) String() string { // A LabelValue is an associated value for a LabelName. type LabelValue string -// IsValid returns true iff the string is a valid UTF8. -func (lv LabelValue) IsValid() bool { - return utf8.ValidString(string(lv)) -} - // LabelValues is a sortable LabelValue slice. It implements sort.Interface. type LabelValues []LabelValue @@ -165,7 +147,7 @@ func (l LabelValues) Len() int { } func (l LabelValues) Less(i, j int) bool { - return string(l[i]) < string(l[j]) + return sort.StringsAreSorted([]string{string(l[i]), string(l[j])}) } func (l LabelValues) Swap(i, j int) { diff --git a/vendor/github.com/prometheus/common/model/labelset.go b/vendor/github.com/prometheus/common/model/labelset.go index 5f931cdb9b3..142b9d1e2d3 100644 --- a/vendor/github.com/prometheus/common/model/labelset.go +++ b/vendor/github.com/prometheus/common/model/labelset.go @@ -27,21 +27,6 @@ import ( // match. type LabelSet map[LabelName]LabelValue -// Validate checks whether all names and values in the label set -// are valid. -func (ls LabelSet) Validate() error { - for ln, lv := range ls { - if !ln.IsValid() { - return fmt.Errorf("invalid name %q", ln) - } - if !lv.IsValid() { - return fmt.Errorf("invalid value %q", lv) - } - } - return nil -} - -// Equal returns true iff both label sets have exactly the same key/value pairs. func (ls LabelSet) Equal(o LabelSet) bool { if len(ls) != len(o) { return false @@ -105,7 +90,6 @@ func (ls LabelSet) Before(o LabelSet) bool { return false } -// Clone returns a copy of the label set. func (ls LabelSet) Clone() LabelSet { lsn := make(LabelSet, len(ls)) for ln, lv := range ls { diff --git a/vendor/github.com/prometheus/common/model/metric.go b/vendor/github.com/prometheus/common/model/metric.go index a5da59a5055..25fc3c94258 100644 --- a/vendor/github.com/prometheus/common/model/metric.go +++ b/vendor/github.com/prometheus/common/model/metric.go @@ -15,15 +15,11 @@ package model import ( "fmt" - "regexp" "sort" "strings" ) -var ( - separator = []byte{0} - MetricNameRE = regexp.MustCompile(`^[a-zA-Z_][a-zA-Z0-9_:]*$`) -) +var separator = []byte{0} // A Metric is similar to a LabelSet, but the key difference is that a Metric is // a singleton and refers to one and only one stream of samples. @@ -83,16 +79,3 @@ func (m Metric) Fingerprint() Fingerprint { func (m Metric) FastFingerprint() Fingerprint { return LabelSet(m).FastFingerprint() } - -// IsValidMetricName returns true iff name matches the pattern of MetricNameRE. -func IsValidMetricName(n LabelValue) bool { - if len(n) == 0 { - return false - } - for i, b := range n { - if !((b >= 'a' && b <= 'z') || (b >= 'A' && b <= 'Z') || b == '_' || b == ':' || (b >= '0' && b <= '9' && i > 0)) { - return false - } - } - return true -} diff --git a/vendor/github.com/prometheus/common/model/signature.go b/vendor/github.com/prometheus/common/model/signature.go index 8762b13c63d..28f370065a9 100644 --- a/vendor/github.com/prometheus/common/model/signature.go +++ b/vendor/github.com/prometheus/common/model/signature.go @@ -14,7 +14,11 @@ package model import ( + "bytes" + "hash" + "hash/fnv" "sort" + "sync" ) // SeparatorByte is a byte that cannot occur in valid UTF-8 sequences and is @@ -24,9 +28,30 @@ const SeparatorByte byte = 255 var ( // cache the signature of an empty label set. - emptyLabelSignature = hashNew() + emptyLabelSignature = fnv.New64a().Sum64() + + hashAndBufPool sync.Pool ) +type hashAndBuf struct { + h hash.Hash64 + b bytes.Buffer +} + +func getHashAndBuf() *hashAndBuf { + hb := hashAndBufPool.Get() + if hb == nil { + return &hashAndBuf{h: fnv.New64a()} + } + return hb.(*hashAndBuf) +} + +func putHashAndBuf(hb *hashAndBuf) { + hb.h.Reset() + hb.b.Reset() + hashAndBufPool.Put(hb) +} + // LabelsToSignature returns a quasi-unique signature (i.e., fingerprint) for a // given label set. (Collisions are possible but unlikely if the number of label // sets the function is applied to is small.) @@ -41,14 +66,18 @@ func LabelsToSignature(labels map[string]string) uint64 { } sort.Strings(labelNames) - sum := hashNew() + hb := getHashAndBuf() + defer putHashAndBuf(hb) + for _, labelName := range labelNames { - sum = hashAdd(sum, labelName) - sum = hashAddByte(sum, SeparatorByte) - sum = hashAdd(sum, labels[labelName]) - sum = hashAddByte(sum, SeparatorByte) + hb.b.WriteString(labelName) + hb.b.WriteByte(SeparatorByte) + hb.b.WriteString(labels[labelName]) + hb.b.WriteByte(SeparatorByte) + hb.h.Write(hb.b.Bytes()) + hb.b.Reset() } - return sum + return hb.h.Sum64() } // labelSetToFingerprint works exactly as LabelsToSignature but takes a LabelSet as @@ -64,14 +93,18 @@ func labelSetToFingerprint(ls LabelSet) Fingerprint { } sort.Sort(labelNames) - sum := hashNew() + hb := getHashAndBuf() + defer putHashAndBuf(hb) + for _, labelName := range labelNames { - sum = hashAdd(sum, string(labelName)) - sum = hashAddByte(sum, SeparatorByte) - sum = hashAdd(sum, string(ls[labelName])) - sum = hashAddByte(sum, SeparatorByte) + hb.b.WriteString(string(labelName)) + hb.b.WriteByte(SeparatorByte) + hb.b.WriteString(string(ls[labelName])) + hb.b.WriteByte(SeparatorByte) + hb.h.Write(hb.b.Bytes()) + hb.b.Reset() } - return Fingerprint(sum) + return Fingerprint(hb.h.Sum64()) } // labelSetToFastFingerprint works similar to labelSetToFingerprint but uses a @@ -83,12 +116,17 @@ func labelSetToFastFingerprint(ls LabelSet) Fingerprint { } var result uint64 + hb := getHashAndBuf() + defer putHashAndBuf(hb) + for labelName, labelValue := range ls { - sum := hashNew() - sum = hashAdd(sum, string(labelName)) - sum = hashAddByte(sum, SeparatorByte) - sum = hashAdd(sum, string(labelValue)) - result ^= sum + hb.b.WriteString(string(labelName)) + hb.b.WriteByte(SeparatorByte) + hb.b.WriteString(string(labelValue)) + hb.h.Write(hb.b.Bytes()) + result ^= hb.h.Sum64() + hb.h.Reset() + hb.b.Reset() } return Fingerprint(result) } @@ -98,20 +136,24 @@ func labelSetToFastFingerprint(ls LabelSet) Fingerprint { // specified LabelNames into the signature calculation. The labels passed in // will be sorted by this function. func SignatureForLabels(m Metric, labels ...LabelName) uint64 { - if len(labels) == 0 { + if len(m) == 0 || len(labels) == 0 { return emptyLabelSignature } sort.Sort(LabelNames(labels)) - sum := hashNew() + hb := getHashAndBuf() + defer putHashAndBuf(hb) + for _, label := range labels { - sum = hashAdd(sum, string(label)) - sum = hashAddByte(sum, SeparatorByte) - sum = hashAdd(sum, string(m[label])) - sum = hashAddByte(sum, SeparatorByte) + hb.b.WriteString(string(label)) + hb.b.WriteByte(SeparatorByte) + hb.b.WriteString(string(m[label])) + hb.b.WriteByte(SeparatorByte) + hb.h.Write(hb.b.Bytes()) + hb.b.Reset() } - return sum + return hb.h.Sum64() } // SignatureWithoutLabels works like LabelsToSignature but takes a Metric as @@ -133,12 +175,16 @@ func SignatureWithoutLabels(m Metric, labels map[LabelName]struct{}) uint64 { } sort.Sort(labelNames) - sum := hashNew() + hb := getHashAndBuf() + defer putHashAndBuf(hb) + for _, labelName := range labelNames { - sum = hashAdd(sum, string(labelName)) - sum = hashAddByte(sum, SeparatorByte) - sum = hashAdd(sum, string(m[labelName])) - sum = hashAddByte(sum, SeparatorByte) + hb.b.WriteString(string(labelName)) + hb.b.WriteByte(SeparatorByte) + hb.b.WriteString(string(m[labelName])) + hb.b.WriteByte(SeparatorByte) + hb.h.Write(hb.b.Bytes()) + hb.b.Reset() } - return sum + return hb.h.Sum64() } diff --git a/vendor/github.com/prometheus/common/model/silence.go b/vendor/github.com/prometheus/common/model/silence.go index 7538e299774..b4b96eae9d4 100644 --- a/vendor/github.com/prometheus/common/model/silence.go +++ b/vendor/github.com/prometheus/common/model/silence.go @@ -44,21 +44,6 @@ func (m *Matcher) UnmarshalJSON(b []byte) error { return nil } -// Validate returns true iff all fields of the matcher have valid values. -func (m *Matcher) Validate() error { - if !m.Name.IsValid() { - return fmt.Errorf("invalid name %q", m.Name) - } - if m.IsRegex { - if _, err := regexp.Compile(m.Value); err != nil { - return fmt.Errorf("invalid regular expression %q", m.Value) - } - } else if !LabelValue(m.Value).IsValid() || len(m.Value) == 0 { - return fmt.Errorf("invalid value %q", m.Value) - } - return nil -} - // Silence defines the representation of a silence definiton // in the Prometheus eco-system. type Silence struct { @@ -73,34 +58,3 @@ type Silence struct { CreatedBy string `json:"createdBy"` Comment string `json:"comment,omitempty"` } - -// Validate returns true iff all fields of the silence have valid values. -func (s *Silence) Validate() error { - if len(s.Matchers) == 0 { - return fmt.Errorf("at least one matcher required") - } - for _, m := range s.Matchers { - if err := m.Validate(); err != nil { - return fmt.Errorf("invalid matcher: %s", err) - } - } - if s.StartsAt.IsZero() { - return fmt.Errorf("start time missing") - } - if s.EndsAt.IsZero() { - return fmt.Errorf("end time missing") - } - if s.EndsAt.Before(s.StartsAt) { - return fmt.Errorf("start time must be before end time") - } - if s.CreatedBy == "" { - return fmt.Errorf("creator information missing") - } - if s.Comment == "" { - return fmt.Errorf("comment missing") - } - if s.CreatedAt.IsZero() { - return fmt.Errorf("creation timestamp missing") - } - return nil -} diff --git a/vendor/github.com/prometheus/common/model/time.go b/vendor/github.com/prometheus/common/model/time.go index 548968aebe6..ebc8bf6cc84 100644 --- a/vendor/github.com/prometheus/common/model/time.go +++ b/vendor/github.com/prometheus/common/model/time.go @@ -163,70 +163,51 @@ func (t *Time) UnmarshalJSON(b []byte) error { // This type should not propagate beyond the scope of input/output processing. type Duration time.Duration -var durationRE = regexp.MustCompile("^([0-9]+)(y|w|d|h|m|s|ms)$") - // StringToDuration parses a string into a time.Duration, assuming that a year -// always has 365d, a week always has 7d, and a day always has 24h. +// a day always has 24h. func ParseDuration(durationStr string) (Duration, error) { matches := durationRE.FindStringSubmatch(durationStr) if len(matches) != 3 { return 0, fmt.Errorf("not a valid duration string: %q", durationStr) } - var ( - n, _ = strconv.Atoi(matches[1]) - dur = time.Duration(n) * time.Millisecond - ) - switch unit := matches[2]; unit { - case "y": - dur *= 1000 * 60 * 60 * 24 * 365 - case "w": - dur *= 1000 * 60 * 60 * 24 * 7 + durSeconds, _ := strconv.Atoi(matches[1]) + dur := time.Duration(durSeconds) * time.Second + unit := matches[2] + switch unit { case "d": - dur *= 1000 * 60 * 60 * 24 + dur *= 60 * 60 * 24 case "h": - dur *= 1000 * 60 * 60 + dur *= 60 * 60 case "m": - dur *= 1000 * 60 + dur *= 60 case "s": - dur *= 1000 - case "ms": - // Value already correct + dur *= 1 default: return 0, fmt.Errorf("invalid time unit in duration string: %q", unit) } return Duration(dur), nil } -func (d Duration) String() string { - var ( - ms = int64(time.Duration(d) / time.Millisecond) - unit = "ms" - ) - factors := map[string]int64{ - "y": 1000 * 60 * 60 * 24 * 365, - "w": 1000 * 60 * 60 * 24 * 7, - "d": 1000 * 60 * 60 * 24, - "h": 1000 * 60 * 60, - "m": 1000 * 60, - "s": 1000, - "ms": 1, - } +var durationRE = regexp.MustCompile("^([0-9]+)([ywdhms]+)$") - switch int64(0) { - case ms % factors["y"]: - unit = "y" - case ms % factors["w"]: - unit = "w" - case ms % factors["d"]: - unit = "d" - case ms % factors["h"]: - unit = "h" - case ms % factors["m"]: - unit = "m" - case ms % factors["s"]: - unit = "s" +func (d Duration) String() string { + seconds := int64(time.Duration(d) / time.Second) + factors := map[string]int64{ + "d": 60 * 60 * 24, + "h": 60 * 60, + "m": 60, + "s": 1, } - return fmt.Sprintf("%v%v", ms/factors[unit], unit) + unit := "s" + switch int64(0) { + case seconds % factors["d"]: + unit = "d" + case seconds % factors["h"]: + unit = "h" + case seconds % factors["m"]: + unit = "m" + } + return fmt.Sprintf("%v%v", seconds/factors[unit], unit) } // MarshalYAML implements the yaml.Marshaler interface. diff --git a/vendor/github.com/prometheus/common/model/value.go b/vendor/github.com/prometheus/common/model/value.go index dbf5d10e431..10ffb0bd611 100644 --- a/vendor/github.com/prometheus/common/model/value.go +++ b/vendor/github.com/prometheus/common/model/value.go @@ -16,7 +16,6 @@ package model import ( "encoding/json" "fmt" - "math" "sort" "strconv" "strings" @@ -44,14 +43,8 @@ func (v *SampleValue) UnmarshalJSON(b []byte) error { return nil } -// Equal returns true if the value of v and o is equal or if both are NaN. Note -// that v==o is false if both are NaN. If you want the conventional float -// behavior, use == to compare two SampleValues. func (v SampleValue) Equal(o SampleValue) bool { - if v == o { - return true - } - return math.IsNaN(float64(v)) && math.IsNaN(float64(o)) + return v == o } func (v SampleValue) String() string { @@ -84,9 +77,9 @@ func (s *SamplePair) UnmarshalJSON(b []byte) error { } // Equal returns true if this SamplePair and o have equal Values and equal -// Timestamps. The sematics of Value equality is defined by SampleValue.Equal. +// Timestamps. func (s *SamplePair) Equal(o *SamplePair) bool { - return s == o || (s.Value.Equal(o.Value) && s.Timestamp.Equal(o.Timestamp)) + return s == o || (s.Value == o.Value && s.Timestamp.Equal(o.Timestamp)) } func (s SamplePair) String() string { @@ -100,8 +93,7 @@ type Sample struct { Timestamp Time `json:"timestamp"` } -// Equal compares first the metrics, then the timestamp, then the value. The -// sematics of value equality is defined by SampleValue.Equal. +// Equal compares first the metrics, then the timestamp, then the value. func (s *Sample) Equal(o *Sample) bool { if s == o { return true @@ -113,7 +105,7 @@ func (s *Sample) Equal(o *Sample) bool { if !s.Timestamp.Equal(o.Timestamp) { return false } - if s.Value.Equal(o.Value) { + if s.Value != o.Value { return false } diff --git a/vendor/github.com/prometheus/procfs/.travis.yml b/vendor/github.com/prometheus/procfs/.travis.yml index b1e6743f9c9..25e169dd010 100644 --- a/vendor/github.com/prometheus/procfs/.travis.yml +++ b/vendor/github.com/prometheus/procfs/.travis.yml @@ -1,5 +1,7 @@ +sudo: false language: go go: - 1.3 - 1.4 + - 1.5 - tip diff --git a/vendor/github.com/prometheus/procfs/AUTHORS.md b/vendor/github.com/prometheus/procfs/AUTHORS.md index 6eb1935cdfc..f1c27ccb013 100644 --- a/vendor/github.com/prometheus/procfs/AUTHORS.md +++ b/vendor/github.com/prometheus/procfs/AUTHORS.md @@ -8,4 +8,13 @@ Maintainers of this repository: The following individuals have contributed code to this repository (listed in alphabetical order): -* Tobias Schmidt +* Armen Baghumian +* Bjoern Rabenstein +* David Cournapeau +* Ji-Hoon, Seol +* Jonas Große Sundrup +* Julius Volz +* Matthias Rampke +* Nicky Gerritsen +* Rémi Audebert +* Tobias Schmidt diff --git a/vendor/github.com/prometheus/procfs/Makefile b/vendor/github.com/prometheus/procfs/Makefile new file mode 100644 index 00000000000..e8acbbc5ec9 --- /dev/null +++ b/vendor/github.com/prometheus/procfs/Makefile @@ -0,0 +1,6 @@ +ci: + go fmt + go vet + go test -v ./... + go get github.com/golang/lint/golint + golint *.go diff --git a/vendor/github.com/prometheus/procfs/README.md b/vendor/github.com/prometheus/procfs/README.md index 761d31cd4dc..6e7ee6b8b75 100644 --- a/vendor/github.com/prometheus/procfs/README.md +++ b/vendor/github.com/prometheus/procfs/README.md @@ -3,5 +3,8 @@ This procfs package provides functions to retrieve system, kernel and process metrics from the pseudo-filesystem proc. +*WARNING*: This package is a work in progress. Its API may still break in +backwards-incompatible ways without warnings. Use it at your own risk. + [![GoDoc](https://godoc.org/github.com/prometheus/procfs?status.png)](https://godoc.org/github.com/prometheus/procfs) [![Build Status](https://travis-ci.org/prometheus/procfs.svg?branch=master)](https://travis-ci.org/prometheus/procfs) diff --git a/vendor/github.com/prometheus/procfs/fs.go b/vendor/github.com/prometheus/procfs/fs.go index 838474aba40..6a8d97b11e9 100644 --- a/vendor/github.com/prometheus/procfs/fs.go +++ b/vendor/github.com/prometheus/procfs/fs.go @@ -34,3 +34,7 @@ func (fs FS) stat(p string) (os.FileInfo, error) { func (fs FS) open(p string) (*os.File, error) { return os.Open(path.Join(string(fs), p)) } + +func (fs FS) readlink(p string) (string, error) { + return os.Readlink(path.Join(string(fs), p)) +} diff --git a/vendor/github.com/prometheus/procfs/ipvs.go b/vendor/github.com/prometheus/procfs/ipvs.go new file mode 100644 index 00000000000..26da5000e39 --- /dev/null +++ b/vendor/github.com/prometheus/procfs/ipvs.go @@ -0,0 +1,223 @@ +package procfs + +import ( + "bufio" + "encoding/hex" + "errors" + "fmt" + "io" + "io/ioutil" + "net" + "strconv" + "strings" +) + +// IPVSStats holds IPVS statistics, as exposed by the kernel in `/proc/net/ip_vs_stats`. +type IPVSStats struct { + // Total count of connections. + Connections uint64 + // Total incoming packages processed. + IncomingPackets uint64 + // Total outgoing packages processed. + OutgoingPackets uint64 + // Total incoming traffic. + IncomingBytes uint64 + // Total outgoing traffic. + OutgoingBytes uint64 +} + +// IPVSBackendStatus holds current metrics of one virtual / real address pair. +type IPVSBackendStatus struct { + // The local (virtual) IP address. + LocalAddress net.IP + // The local (virtual) port. + LocalPort uint16 + // The transport protocol (TCP, UDP). + Proto string + // The remote (real) IP address. + RemoteAddress net.IP + // The remote (real) port. + RemotePort uint16 + // The current number of active connections for this virtual/real address pair. + ActiveConn uint64 + // The current number of inactive connections for this virtual/real address pair. + InactConn uint64 + // The current weight of this virtual/real address pair. + Weight uint64 +} + +// NewIPVSStats reads the IPVS statistics. +func NewIPVSStats() (IPVSStats, error) { + fs, err := NewFS(DefaultMountPoint) + if err != nil { + return IPVSStats{}, err + } + + return fs.NewIPVSStats() +} + +// NewIPVSStats reads the IPVS statistics from the specified `proc` filesystem. +func (fs FS) NewIPVSStats() (IPVSStats, error) { + file, err := fs.open("net/ip_vs_stats") + if err != nil { + return IPVSStats{}, err + } + defer file.Close() + + return parseIPVSStats(file) +} + +// parseIPVSStats performs the actual parsing of `ip_vs_stats`. +func parseIPVSStats(file io.Reader) (IPVSStats, error) { + var ( + statContent []byte + statLines []string + statFields []string + stats IPVSStats + ) + + statContent, err := ioutil.ReadAll(file) + if err != nil { + return IPVSStats{}, err + } + + statLines = strings.SplitN(string(statContent), "\n", 4) + if len(statLines) != 4 { + return IPVSStats{}, errors.New("ip_vs_stats corrupt: too short") + } + + statFields = strings.Fields(statLines[2]) + if len(statFields) != 5 { + return IPVSStats{}, errors.New("ip_vs_stats corrupt: unexpected number of fields") + } + + stats.Connections, err = strconv.ParseUint(statFields[0], 16, 64) + if err != nil { + return IPVSStats{}, err + } + stats.IncomingPackets, err = strconv.ParseUint(statFields[1], 16, 64) + if err != nil { + return IPVSStats{}, err + } + stats.OutgoingPackets, err = strconv.ParseUint(statFields[2], 16, 64) + if err != nil { + return IPVSStats{}, err + } + stats.IncomingBytes, err = strconv.ParseUint(statFields[3], 16, 64) + if err != nil { + return IPVSStats{}, err + } + stats.OutgoingBytes, err = strconv.ParseUint(statFields[4], 16, 64) + if err != nil { + return IPVSStats{}, err + } + + return stats, nil +} + +// NewIPVSBackendStatus reads and returns the status of all (virtual,real) server pairs. +func NewIPVSBackendStatus() ([]IPVSBackendStatus, error) { + fs, err := NewFS(DefaultMountPoint) + if err != nil { + return []IPVSBackendStatus{}, err + } + + return fs.NewIPVSBackendStatus() +} + +// NewIPVSBackendStatus reads and returns the status of all (virtual,real) server pairs from the specified `proc` filesystem. +func (fs FS) NewIPVSBackendStatus() ([]IPVSBackendStatus, error) { + file, err := fs.open("net/ip_vs") + if err != nil { + return nil, err + } + defer file.Close() + + return parseIPVSBackendStatus(file) +} + +func parseIPVSBackendStatus(file io.Reader) ([]IPVSBackendStatus, error) { + var ( + status []IPVSBackendStatus + scanner = bufio.NewScanner(file) + proto string + localAddress net.IP + localPort uint16 + err error + ) + + for scanner.Scan() { + fields := strings.Fields(string(scanner.Text())) + if len(fields) == 0 { + continue + } + switch { + case fields[0] == "IP" || fields[0] == "Prot" || fields[1] == "RemoteAddress:Port": + continue + case fields[0] == "TCP" || fields[0] == "UDP": + if len(fields) < 2 { + continue + } + proto = fields[0] + localAddress, localPort, err = parseIPPort(fields[1]) + if err != nil { + return nil, err + } + case fields[0] == "->": + if len(fields) < 6 { + continue + } + remoteAddress, remotePort, err := parseIPPort(fields[1]) + if err != nil { + return nil, err + } + weight, err := strconv.ParseUint(fields[3], 10, 64) + if err != nil { + return nil, err + } + activeConn, err := strconv.ParseUint(fields[4], 10, 64) + if err != nil { + return nil, err + } + inactConn, err := strconv.ParseUint(fields[5], 10, 64) + if err != nil { + return nil, err + } + status = append(status, IPVSBackendStatus{ + LocalAddress: localAddress, + LocalPort: localPort, + RemoteAddress: remoteAddress, + RemotePort: remotePort, + Proto: proto, + Weight: weight, + ActiveConn: activeConn, + InactConn: inactConn, + }) + } + } + return status, nil +} + +func parseIPPort(s string) (net.IP, uint16, error) { + tmp := strings.SplitN(s, ":", 2) + + if len(tmp) != 2 { + return nil, 0, fmt.Errorf("invalid IP:Port: %s", s) + } + + if len(tmp[0]) != 8 && len(tmp[0]) != 32 { + return nil, 0, fmt.Errorf("invalid IP: %s", tmp[0]) + } + + ip, err := hex.DecodeString(tmp[0]) + if err != nil { + return nil, 0, err + } + + port, err := strconv.ParseUint(tmp[1], 16, 16) + if err != nil { + return nil, 0, err + } + + return ip, uint16(port), nil +} diff --git a/vendor/github.com/prometheus/procfs/mdstat.go b/vendor/github.com/prometheus/procfs/mdstat.go new file mode 100644 index 00000000000..09ed6b5ebc1 --- /dev/null +++ b/vendor/github.com/prometheus/procfs/mdstat.go @@ -0,0 +1,158 @@ +package procfs + +import ( + "fmt" + "io/ioutil" + "path" + "regexp" + "strconv" + "strings" +) + +var ( + statuslineRE = regexp.MustCompile(`(\d+) blocks .*\[(\d+)/(\d+)\] \[[U_]+\]`) + buildlineRE = regexp.MustCompile(`\((\d+)/\d+\)`) +) + +// MDStat holds info parsed from /proc/mdstat. +type MDStat struct { + // Name of the device. + Name string + // activity-state of the device. + ActivityState string + // Number of active disks. + DisksActive int64 + // Total number of disks the device consists of. + DisksTotal int64 + // Number of blocks the device holds. + BlocksTotal int64 + // Number of blocks on the device that are in sync. + BlocksSynced int64 +} + +// ParseMDStat parses an mdstat-file and returns a struct with the relevant infos. +func (fs FS) ParseMDStat() (mdstates []MDStat, err error) { + mdStatusFilePath := path.Join(string(fs), "mdstat") + content, err := ioutil.ReadFile(mdStatusFilePath) + if err != nil { + return []MDStat{}, fmt.Errorf("error parsing %s: %s", mdStatusFilePath, err) + } + + mdStatusFile := string(content) + + lines := strings.Split(mdStatusFile, "\n") + var currentMD string + + // Each md has at least the deviceline, statusline and one empty line afterwards + // so we will have probably something of the order len(lines)/3 devices + // so we use that for preallocation. + estimateMDs := len(lines) / 3 + mdStates := make([]MDStat, 0, estimateMDs) + + for i, l := range lines { + if l == "" { + // Skip entirely empty lines. + continue + } + + if l[0] == ' ' { + // Those lines are not the beginning of a md-section. + continue + } + + if strings.HasPrefix(l, "Personalities") || strings.HasPrefix(l, "unused") { + // We aren't interested in lines with general info. + continue + } + + mainLine := strings.Split(l, " ") + if len(mainLine) < 3 { + return mdStates, fmt.Errorf("error parsing mdline: %s", l) + } + currentMD = mainLine[0] // name of md-device + activityState := mainLine[2] // activity status of said md-device + + if len(lines) <= i+3 { + return mdStates, fmt.Errorf("error parsing %s: entry for %s has fewer lines than expected", mdStatusFilePath, currentMD) + } + + active, total, size, err := evalStatusline(lines[i+1]) // parse statusline, always present + if err != nil { + return mdStates, fmt.Errorf("error parsing %s: %s", mdStatusFilePath, err) + } + + // + // Now get the number of synced blocks. + // + + // Get the line number of the syncing-line. + var j int + if strings.Contains(lines[i+2], "bitmap") { // then skip the bitmap line + j = i + 3 + } else { + j = i + 2 + } + + // If device is syncing at the moment, get the number of currently synced bytes, + // otherwise that number equals the size of the device. + syncedBlocks := size + if strings.Contains(lines[j], "recovery") || strings.Contains(lines[j], "resync") { + syncedBlocks, err = evalBuildline(lines[j]) + if err != nil { + return mdStates, fmt.Errorf("error parsing %s: %s", mdStatusFilePath, err) + } + } + + mdStates = append(mdStates, MDStat{currentMD, activityState, active, total, size, syncedBlocks}) + + } + + return mdStates, nil +} + +func evalStatusline(statusline string) (active, total, size int64, err error) { + matches := statuslineRE.FindStringSubmatch(statusline) + + // +1 to make it more obvious that the whole string containing the info is also returned as matches[0]. + if len(matches) != 3+1 { + return 0, 0, 0, fmt.Errorf("unexpected number matches found in statusline: %s", statusline) + } + + size, err = strconv.ParseInt(matches[1], 10, 64) + if err != nil { + return 0, 0, 0, fmt.Errorf("%s in statusline: %s", err, statusline) + } + + total, err = strconv.ParseInt(matches[2], 10, 64) + if err != nil { + return 0, 0, 0, fmt.Errorf("%s in statusline: %s", err, statusline) + } + + active, err = strconv.ParseInt(matches[3], 10, 64) + if err != nil { + return 0, 0, 0, fmt.Errorf("%s in statusline: %s", err, statusline) + } + + return active, total, size, nil +} + +// Gets the size that has already been synced out of the sync-line. +func evalBuildline(buildline string) (int64, error) { + matches := buildlineRE.FindStringSubmatch(buildline) + + // +1 to make it more obvious that the whole string containing the info is also returned as matches[0]. + if len(matches) < 1+1 { + return 0, fmt.Errorf("too few matches found in buildline: %s", buildline) + } + + if len(matches) > 1+1 { + return 0, fmt.Errorf("too many matches found in buildline: %s", buildline) + } + + syncedSize, err := strconv.ParseInt(matches[1], 10, 64) + if err != nil { + return 0, fmt.Errorf("%s in buildline: %s", err, buildline) + } + + return syncedSize, nil +} diff --git a/vendor/github.com/prometheus/procfs/proc.go b/vendor/github.com/prometheus/procfs/proc.go index 21445cf1761..efc8502789c 100644 --- a/vendor/github.com/prometheus/procfs/proc.go +++ b/vendor/github.com/prometheus/procfs/proc.go @@ -24,9 +24,13 @@ func (p Procs) Len() int { return len(p) } func (p Procs) Swap(i, j int) { p[i], p[j] = p[j], p[i] } func (p Procs) Less(i, j int) bool { return p[i].PID < p[j].PID } -// Self returns a process for the current process. +// Self returns a process for the current process read via /proc/self. func Self() (Proc, error) { - return NewProc(os.Getpid()) + fs, err := NewFS(DefaultMountPoint) + if err != nil { + return Proc{}, err + } + return fs.Self() } // NewProc returns a process for the given pid under /proc. @@ -35,7 +39,6 @@ func NewProc(pid int) (Proc, error) { if err != nil { return Proc{}, err } - return fs.NewProc(pid) } @@ -45,16 +48,27 @@ func AllProcs() (Procs, error) { if err != nil { return Procs{}, err } - return fs.AllProcs() } +// Self returns a process for the current process. +func (fs FS) Self() (Proc, error) { + p, err := fs.readlink("self") + if err != nil { + return Proc{}, err + } + pid, err := strconv.Atoi(strings.Replace(p, string(fs), "", -1)) + if err != nil { + return Proc{}, err + } + return fs.NewProc(pid) +} + // NewProc returns a process for the given pid. func (fs FS) NewProc(pid int) (Proc, error) { if _, err := fs.stat(strconv.Itoa(pid)); err != nil { return Proc{}, err } - return Proc{PID: pid, fs: fs}, nil } @@ -96,9 +110,24 @@ func (p Proc) CmdLine() ([]string, error) { return nil, err } + if len(data) < 1 { + return []string{}, nil + } + return strings.Split(string(data[:len(data)-1]), string(byte(0))), nil } +// Executable returns the absolute path of the executable command of a process. +func (p Proc) Executable() (string, error) { + exe, err := p.readlink("exe") + + if os.IsNotExist(err) { + return "", nil + } + + return exe, err +} + // FileDescriptors returns the currently open file descriptors of a process. func (p Proc) FileDescriptors() ([]uintptr, error) { names, err := p.fileDescriptors() @@ -118,6 +147,26 @@ func (p Proc) FileDescriptors() ([]uintptr, error) { return fds, nil } +// FileDescriptorTargets returns the targets of all file descriptors of a process. +// If a file descriptor is not a symlink to a file (like a socket), that value will be the empty string. +func (p Proc) FileDescriptorTargets() ([]string, error) { + names, err := p.fileDescriptors() + if err != nil { + return nil, err + } + + targets := make([]string, len(names)) + + for i, name := range names { + target, err := p.readlink("fd/" + name) + if err == nil { + targets[i] = target + } + } + + return targets, nil +} + // FileDescriptorsLen returns the number of currently open file descriptors of // a process. func (p Proc) FileDescriptorsLen() (int, error) { @@ -147,3 +196,7 @@ func (p Proc) fileDescriptors() ([]string, error) { func (p Proc) open(pa string) (*os.File, error) { return p.fs.open(path.Join(strconv.Itoa(p.PID), pa)) } + +func (p Proc) readlink(pa string) (string, error) { + return p.fs.readlink(path.Join(strconv.Itoa(p.PID), pa)) +} diff --git a/vendor/github.com/prometheus/procfs/proc_io.go b/vendor/github.com/prometheus/procfs/proc_io.go new file mode 100644 index 00000000000..7c6dc86970d --- /dev/null +++ b/vendor/github.com/prometheus/procfs/proc_io.go @@ -0,0 +1,54 @@ +package procfs + +import ( + "fmt" + "io/ioutil" +) + +// ProcIO models the content of /proc//io. +type ProcIO struct { + // Chars read. + RChar uint64 + // Chars written. + WChar uint64 + // Read syscalls. + SyscR uint64 + // Write syscalls. + SyscW uint64 + // Bytes read. + ReadBytes uint64 + // Bytes written. + WriteBytes uint64 + // Bytes written, but taking into account truncation. See + // Documentation/filesystems/proc.txt in the kernel sources for + // detailed explanation. + CancelledWriteBytes int64 +} + +// NewIO creates a new ProcIO instance from a given Proc instance. +func (p Proc) NewIO() (ProcIO, error) { + pio := ProcIO{} + + f, err := p.open("io") + if err != nil { + return pio, err + } + defer f.Close() + + data, err := ioutil.ReadAll(f) + if err != nil { + return pio, err + } + + ioFormat := "rchar: %d\nwchar: %d\nsyscr: %d\nsyscw: %d\n" + + "read_bytes: %d\nwrite_bytes: %d\n" + + "cancelled_write_bytes: %d\n" + + _, err = fmt.Sscanf(string(data), ioFormat, &pio.RChar, &pio.WChar, &pio.SyscR, + &pio.SyscW, &pio.ReadBytes, &pio.WriteBytes, &pio.CancelledWriteBytes) + if err != nil { + return pio, err + } + + return pio, nil +} diff --git a/vendor/github.com/russross/blackfriday/.travis.yml b/vendor/github.com/russross/blackfriday/.travis.yml index c6dc2752903..208fd25bcd5 100644 --- a/vendor/github.com/russross/blackfriday/.travis.yml +++ b/vendor/github.com/russross/blackfriday/.travis.yml @@ -7,6 +7,8 @@ language: go go: - 1.2 - 1.3 + - 1.4 + - 1.5 install: - go get -d -t -v ./... diff --git a/vendor/github.com/russross/blackfriday/README.md b/vendor/github.com/russross/blackfriday/README.md index 179978d4e72..dd8eb161e69 100644 --- a/vendor/github.com/russross/blackfriday/README.md +++ b/vendor/github.com/russross/blackfriday/README.md @@ -10,7 +10,7 @@ punctuation substitutions, etc.), and it is safe for all utf-8 HTML output is currently supported, along with Smartypants extensions. An experimental LaTeX output engine is also included. -It started as a translation from C of [upskirt][3]. +It started as a translation from C of [Sundown][3]. Installation @@ -97,7 +97,7 @@ dependencies and library versions. Features -------- -All features of upskirt are supported, including: +All features of Sundown are supported, including: * **Compatibility**. The Markdown v1.0.3 test suite passes with the `--tidy` option. Without `--tidy`, the differences are @@ -169,6 +169,25 @@ implements the following extensions: You can use 3 or more backticks to mark the beginning of the block, and the same number to mark the end of the block. +* **Definition lists**. A simple definition list is made of a single-line + term followed by a colon and the definition for that term. + + Cat + : Fluffy animal everyone likes + + Internet + : Vector of transmission for pictures of cats + + Terms must be separated from the previous definition by a blank line. + +* **Footnotes**. A marker in the text that will become a superscript number; + a footnote definition that will be placed in a list of footnotes at the + end of the document. A footnote looks like this: + + This is a footnote.[^1] + + [^1]: the footnote text. + * **Autolinking**. Blackfriday can find URLs that have not been explicitly marked as links and turn them into links. @@ -203,7 +222,7 @@ Other renderers Blackfriday is structured to allow alternative rendering engines. Here are a few of note: -* [github_flavored_markdown](https://godoc.org/github.com/shurcooL/go/github_flavored_markdown): +* [github_flavored_markdown](https://godoc.org/github.com/shurcooL/github_flavored_markdown): provides a GitHub Flavored Markdown renderer with fenced code block highlighting, clickable header anchor links. @@ -223,6 +242,8 @@ are a few of note: point. In particular, it does not do any inline escaping, so input that happens to look like LaTeX code will be passed through without modification. + +* [Md2Vim](https://github.com/FooSoft/md2vim): transforms markdown files into vimdoc format. Todo @@ -243,4 +264,4 @@ License [1]: http://daringfireball.net/projects/markdown/ "Markdown" [2]: http://golang.org/ "Go Language" - [3]: http://github.com/tanoku/upskirt "Upskirt" + [3]: https://github.com/vmg/sundown "Sundown" diff --git a/vendor/github.com/russross/blackfriday/block.go b/vendor/github.com/russross/blackfriday/block.go index 59c6d2842e9..b5b084117ce 100644 --- a/vendor/github.com/russross/blackfriday/block.go +++ b/vendor/github.com/russross/blackfriday/block.go @@ -166,6 +166,21 @@ func (p *parser) block(out *bytes.Buffer, data []byte) { continue } + // definition lists: + // + // Term 1 + // : Definition a + // : Definition b + // + // Term 2 + // : Definition c + if p.flags&EXTENSION_DEFINITION_LISTS != 0 { + if p.dliPrefix(data) > 0 { + data = data[p.list(out, data, LIST_TYPE_DEFINITION):] + continue + } + } + // anything else must look like a normal paragraph // note: this finds underlined headers, too data = data[p.paragraph(out, data):] @@ -196,11 +211,8 @@ func (p *parser) prefixHeader(out *bytes.Buffer, data []byte) int { for level < 6 && data[level] == '#' { level++ } - i, end := 0, 0 - for i = level; data[i] == ' '; i++ { - } - for end = i; data[end] != '\n'; end++ { - } + i := skipChar(data, level, ' ') + end := skipUntilChar(data, i, '\n') skip := end id := "" if p.flags&EXTENSION_HEADER_IDS != 0 { @@ -221,6 +233,9 @@ func (p *parser) prefixHeader(out *bytes.Buffer, data []byte) int { } } for end > 0 && data[end-1] == '#' { + if isBackslashEscaped(data, end-1) { + break + } end-- } for end > 0 && data[end-1] == ' ' { @@ -242,13 +257,8 @@ func (p *parser) prefixHeader(out *bytes.Buffer, data []byte) int { func (p *parser) isUnderlinedHeader(data []byte) int { // test of level 1 header if data[0] == '=' { - i := 1 - for data[i] == '=' { - i++ - } - for data[i] == ' ' { - i++ - } + i := skipChar(data, 1, '=') + i = skipChar(data, i, ' ') if data[i] == '\n' { return 1 } else { @@ -258,13 +268,8 @@ func (p *parser) isUnderlinedHeader(data []byte) int { // test of level 2 header if data[0] == '-' { - i := 1 - for data[i] == '-' { - i++ - } - for data[i] == ' ' { - i++ - } + i := skipChar(data, 1, '-') + i = skipChar(data, i, ' ') if data[i] == '\n' { return 2 } else { @@ -394,23 +399,7 @@ func (p *parser) html(out *bytes.Buffer, data []byte, doRender bool) int { // HTML comment, lax form func (p *parser) htmlComment(out *bytes.Buffer, data []byte, doRender bool) int { - if data[0] != '<' || data[1] != '!' || data[2] != '-' || data[3] != '-' { - return 0 - } - - i := 5 - - // scan for an end-of-comment marker, across lines if necessary - for i < len(data) && !(data[i-2] == '-' && data[i-1] == '-' && data[i] == '>') { - i++ - } - i++ - - // no end-of-comment marker - if i >= len(data) { - return 0 - } - + i := p.inlineHtmlComment(out, data) // needs to end with a blank line if j := p.isEmpty(data[i:]); j > 0 { size := i + j @@ -424,7 +413,6 @@ func (p *parser) htmlComment(out *bytes.Buffer, data []byte, doRender bool) int } return size } - return 0 } @@ -468,7 +456,7 @@ func (p *parser) htmlFindTag(data []byte) (string, bool) { i++ } key := string(data[:i]) - if blockTags[key] { + if _, ok := blockTags[key]; ok { return key, true } return "", false @@ -593,10 +581,7 @@ func (p *parser) isFencedCode(data []byte, syntax **string, oldmarker string) (s if syntax != nil { syn := 0 - - for i < len(data) && data[i] == ' ' { - i++ - } + i = skipChar(data, i, ' ') if i >= len(data) { return @@ -640,9 +625,7 @@ func (p *parser) isFencedCode(data []byte, syntax **string, oldmarker string) (s *syntax = &language } - for i < len(data) && data[i] == ' ' { - i++ - } + i = skipChar(data, i, ' ') if i >= len(data) || data[i] != '\n' { return } @@ -671,11 +654,7 @@ func (p *parser) fencedCode(out *bytes.Buffer, data []byte, doRender bool) int { } // copy the current line - end := beg - for end < len(data) && data[end] != '\n' { - end++ - } - end++ + end := skipUntilChar(data, beg, '\n') + 1 // did we reach the end of the buffer without a closing marker? if end >= len(data) { @@ -733,7 +712,7 @@ func (p *parser) table(out *bytes.Buffer, data []byte) int { return i } -// check if the specified position is preceeded by an odd number of backslashes +// check if the specified position is preceded by an odd number of backslashes func isBackslashEscaped(data []byte, i int) bool { backslashes := 0 for i-backslashes-1 >= 0 && data[i-backslashes-1] == '\\' { @@ -778,9 +757,7 @@ func (p *parser) tableHeader(out *bytes.Buffer, data []byte) (size int, columns if data[i] == '|' && !isBackslashEscaped(data, i) { i++ } - for data[i] == ' ' { - i++ - } + i = skipChar(data, i, ' ') // each column header is of form: / *:?-+:? *|/ with # dashes + # colons >= 3 // and trailing | optional on last column @@ -914,13 +891,35 @@ func (p *parser) quotePrefix(data []byte) int { return 0 } +// blockquote ends with at least one blank line +// followed by something without a blockquote prefix +func (p *parser) terminateBlockquote(data []byte, beg, end int) bool { + if p.isEmpty(data[beg:]) <= 0 { + return false + } + if end >= len(data) { + return true + } + return p.quotePrefix(data[end:]) == 0 && p.isEmpty(data[end:]) == 0 +} + // parse a blockquote fragment func (p *parser) quote(out *bytes.Buffer, data []byte) int { var raw bytes.Buffer beg, end := 0, 0 for beg < len(data) { end = beg + // Step over whole lines, collecting them. While doing that, check for + // fenced code and if one's found, incorporate it altogether, + // irregardless of any contents inside it for data[end] != '\n' { + if p.flags&EXTENSION_FENCED_CODE != 0 { + if i := p.fencedCode(out, data[end:], false); i > 0 { + // -1 to compensate for the extra end++ after the loop: + end += i - 1 + break + } + } end++ } end++ @@ -928,11 +927,7 @@ func (p *parser) quote(out *bytes.Buffer, data []byte) int { if pre := p.quotePrefix(data[beg:]); pre > 0 { // skip the prefix beg += pre - } else if p.isEmpty(data[beg:]) > 0 && - (end >= len(data) || - (p.quotePrefix(data[end:]) == 0 && p.isEmpty(data[end:]) == 0)) { - // blockquote ends with at least one blank line - // followed by something without a blockquote prefix + } else if p.terminateBlockquote(data, beg, end) { break } @@ -1039,6 +1034,20 @@ func (p *parser) oliPrefix(data []byte) int { return i + 2 } +// returns definition list item prefix +func (p *parser) dliPrefix(data []byte) int { + i := 0 + + // need a : followed by a spaces + if data[i] != ':' || data[i+1] != ' ' { + return 0 + } + for data[i] == ' ' { + i++ + } + return i + 2 +} + // parse ordered or unordered list block func (p *parser) list(out *bytes.Buffer, data []byte, flags int) int { i := 0 @@ -1074,7 +1083,19 @@ func (p *parser) listItem(out *bytes.Buffer, data []byte, flags *int) int { i = p.oliPrefix(data) } if i == 0 { - return 0 + i = p.dliPrefix(data) + // reset definition term flag + if i > 0 { + *flags &= ^LIST_TYPE_TERM + } + } + if i == 0 { + // if in defnition list, set term flag and continue + if *flags&LIST_TYPE_DEFINITION != 0 { + *flags |= LIST_TYPE_TERM + } else { + return 0 + } } // skip leading whitespace on first line @@ -1084,7 +1105,7 @@ func (p *parser) listItem(out *bytes.Buffer, data []byte, flags *int) int { // find the end of the line line := i - for data[i-1] != '\n' { + for i > 0 && data[i-1] != '\n' { i++ } @@ -1128,7 +1149,8 @@ gatherlines: switch { // is this a nested list item? case (p.uliPrefix(chunk) > 0 && !p.isHRule(chunk)) || - p.oliPrefix(chunk) > 0: + p.oliPrefix(chunk) > 0 || + p.dliPrefix(chunk) > 0: if containsBlankLine { *flags |= LIST_ITEM_CONTAINS_BLOCK @@ -1140,7 +1162,7 @@ gatherlines: break gatherlines } - // is this the first item in the the nested list? + // is this the first item in the nested list? if sublist == 0 { sublist = raw.Len() } @@ -1159,7 +1181,21 @@ gatherlines: // of this item if it is indented 4 spaces // (regardless of the indentation of the beginning of the item) case containsBlankLine && indent < 4: - *flags |= LIST_ITEM_END_OF_LIST + if *flags&LIST_TYPE_DEFINITION != 0 && i < len(data)-1 { + // is the next item still a part of this list? + next := i + for data[next] != '\n' { + next++ + } + for next < len(data)-1 && data[next] == '\n' { + next++ + } + if i < len(data)-1 && data[i] != ':' && data[next] != ':' { + *flags |= LIST_ITEM_END_OF_LIST + } + } else { + *flags |= LIST_ITEM_END_OF_LIST + } break gatherlines // a blank line means this should be parsed as a block @@ -1173,6 +1209,7 @@ gatherlines: if containsBlankLine { containsBlankLine = false raw.WriteByte('\n') + } // add the line into the working buffer without prefix @@ -1185,8 +1222,8 @@ gatherlines: // render the contents of the list item var cooked bytes.Buffer - if *flags&LIST_ITEM_CONTAINS_BLOCK != 0 { - // intermediate render of block li + if *flags&LIST_ITEM_CONTAINS_BLOCK != 0 && *flags&LIST_TYPE_TERM == 0 { + // intermediate render of block item, except for definition term if sublist > 0 { p.block(&cooked, rawBytes[:sublist]) p.block(&cooked, rawBytes[sublist:]) @@ -1194,7 +1231,7 @@ gatherlines: p.block(&cooked, rawBytes) } } else { - // intermediate render of inline li + // intermediate render of inline item if sublist > 0 { p.inline(&cooked, rawBytes[:sublist]) p.block(&cooked, rawBytes[sublist:]) @@ -1258,6 +1295,13 @@ func (p *parser) paragraph(out *bytes.Buffer, data []byte) int { // did we find a blank line marking the end of the paragraph? if n := p.isEmpty(current); n > 0 { + // did this blank line followed by a definition list item? + if p.flags&EXTENSION_DEFINITION_LISTS != 0 { + if i < len(data)-1 && data[i+1] == ':' { + return p.list(out, data[prev:], LIST_TYPE_DEFINITION) + } + } + p.renderParagraph(out, data[:i]) return i + n } @@ -1316,6 +1360,21 @@ func (p *parser) paragraph(out *bytes.Buffer, data []byte) int { return i } + // if there's a fenced code block, paragraph is over + if p.flags&EXTENSION_FENCED_CODE != 0 { + if p.fencedCode(out, current, false) > 0 { + p.renderParagraph(out, data[:i]) + return i + } + } + + // if there's a definition list item, prev line is a definition term + if p.flags&EXTENSION_DEFINITION_LISTS != 0 { + if p.dliPrefix(current) != 0 { + return p.list(out, data[prev:], LIST_TYPE_DEFINITION) + } + } + // if there's a list after this, paragraph is over if p.flags&EXTENSION_NO_EMPTY_LINE_BEFORE_BLOCK != 0 { if p.uliPrefix(current) != 0 || diff --git a/vendor/github.com/russross/blackfriday/html.go b/vendor/github.com/russross/blackfriday/html.go index 666d0e3dd5c..74e67ee82bd 100644 --- a/vendor/github.com/russross/blackfriday/html.go +++ b/vendor/github.com/russross/blackfriday/html.go @@ -31,6 +31,7 @@ const ( HTML_SKIP_LINKS // skip all links HTML_SAFELINK // only link to trusted protocols HTML_NOFOLLOW_LINKS // only link with rel="nofollow" + HTML_NOREFERRER_LINKS // only link with rel="noreferrer" HTML_HREF_TARGET_BLANK // add a blank target HTML_TOC // generate a table of contents HTML_OMIT_CONTENTS // skip the main contents (for a standalone table of contents) @@ -38,7 +39,8 @@ const ( HTML_USE_XHTML // generate XHTML output instead of HTML HTML_USE_SMARTYPANTS // enable smart punctuation substitutions HTML_SMARTYPANTS_FRACTIONS // enable smart fractions (with HTML_USE_SMARTYPANTS) - HTML_SMARTYPANTS_LATEX_DASHES // enable LaTeX-style dashes (with HTML_USE_SMARTYPANTS) + HTML_SMARTYPANTS_DASHES // enable smart dashes (with HTML_USE_SMARTYPANTS) + HTML_SMARTYPANTS_LATEX_DASHES // enable LaTeX-style dashes (with HTML_USE_SMARTYPANTS and HTML_SMARTYPANTS_DASHES) HTML_SMARTYPANTS_ANGLED_QUOTES // enable angled double quotes (with HTML_USE_SMARTYPANTS) for double quotes rendering HTML_FOOTNOTE_RETURN_LINKS // generate a link at the end of a footnote to return to the source ) @@ -75,7 +77,7 @@ type HtmlRendererParameters struct { // Do not create this directly, instead use the HtmlRenderer function. type Html struct { flags int // HTML_* options - closeTag string // how to end singleton tags: either " />\n" or ">\n" + closeTag string // how to end singleton tags: either " />" or ">" title string // document title css string // optional css file url (used with HTML_COMPLETE_PAGE) @@ -94,8 +96,8 @@ type Html struct { } const ( - xhtmlClose = " />\n" - htmlClose = ">\n" + xhtmlClose = " />" + htmlClose = ">" ) // HtmlRenderer creates and configures an Html object, which @@ -249,6 +251,7 @@ func (options *Html) HRule(out *bytes.Buffer) { doubleSpace(out) out.WriteString("") + } else if flags&LIST_TYPE_ORDERED != 0 { out.WriteString("
    ") } else { out.WriteString("
      ") @@ -382,7 +387,9 @@ func (options *Html) List(out *bytes.Buffer, text func() bool, flags int) { out.Truncate(marker) return } - if flags&LIST_TYPE_ORDERED != 0 { + if flags&LIST_TYPE_DEFINITION != 0 { + out.WriteString("\n") + } else if flags&LIST_TYPE_ORDERED != 0 { out.WriteString("
\n") } else { out.WriteString("\n") @@ -390,12 +397,25 @@ func (options *Html) List(out *bytes.Buffer, text func() bool, flags int) { } func (options *Html) ListItem(out *bytes.Buffer, text []byte, flags int) { - if flags&LIST_ITEM_CONTAINS_BLOCK != 0 || flags&LIST_ITEM_BEGINNING_OF_LIST != 0 { + if (flags&LIST_ITEM_CONTAINS_BLOCK != 0 && flags&LIST_TYPE_DEFINITION == 0) || + flags&LIST_ITEM_BEGINNING_OF_LIST != 0 { doubleSpace(out) } - out.WriteString("
  • ") + if flags&LIST_TYPE_TERM != 0 { + out.WriteString("
    ") + } else if flags&LIST_TYPE_DEFINITION != 0 { + out.WriteString("
    ") + } else { + out.WriteString("
  • ") + } out.Write(text) - out.WriteString("
  • \n") + if flags&LIST_TYPE_TERM != 0 { + out.WriteString("\n") + } else if flags&LIST_TYPE_DEFINITION != 0 { + out.WriteString("
    \n") + } else { + out.WriteString("
  • \n") + } } func (options *Html) Paragraph(out *bytes.Buffer, text func() bool) { @@ -429,9 +449,17 @@ func (options *Html) AutoLink(out *bytes.Buffer, link []byte, kind int) { entityEscapeWithSkip(out, link, skipRanges) + var relAttrs []string if options.flags&HTML_NOFOLLOW_LINKS != 0 && !isRelativeLink(link) { - out.WriteString("\" rel=\"nofollow") + relAttrs = append(relAttrs, "nofollow") } + if options.flags&HTML_NOREFERRER_LINKS != 0 && !isRelativeLink(link) { + relAttrs = append(relAttrs, "noreferrer") + } + if len(relAttrs) > 0 { + out.WriteString(fmt.Sprintf("\" rel=\"%s", strings.Join(relAttrs, " "))) + } + // blank target only add to external link if options.flags&HTML_HREF_TARGET_BLANK != 0 && !isRelativeLink(link) { out.WriteString("\" target=\"_blank") @@ -476,7 +504,7 @@ func (options *Html) Emphasis(out *bytes.Buffer, text []byte) { } func (options *Html) maybeWriteAbsolutePrefix(out *bytes.Buffer, link []byte) { - if options.parameters.AbsolutePrefix != "" && isRelativeLink(link) { + if options.parameters.AbsolutePrefix != "" && isRelativeLink(link) && link[0] != '.' { out.WriteString(options.parameters.AbsolutePrefix) if link[0] != '/' { out.WriteByte('/') @@ -503,12 +531,12 @@ func (options *Html) Image(out *bytes.Buffer, link []byte, title []byte, alt []b out.WriteByte('"') out.WriteString(options.closeTag) - return } func (options *Html) LineBreak(out *bytes.Buffer) { out.WriteString(" 0 { + out.WriteString(fmt.Sprintf("\" rel=\"%s", strings.Join(relAttrs, " "))) + } + // blank target only add to external link if options.flags&HTML_HREF_TARGET_BLANK != 0 && !isRelativeLink(link) { out.WriteString("\" target=\"_blank") @@ -850,6 +886,14 @@ func skipSpace(tag []byte, i int) int { return i } +func skipChar(data []byte, start int, char byte) int { + i := start + for i < len(data) && data[i] == char { + i++ + } + return i +} + func doubleSpace(out *bytes.Buffer) { if out.Len() > 0 { out.WriteByte('\n') @@ -857,23 +901,32 @@ func doubleSpace(out *bytes.Buffer) { } func isRelativeLink(link []byte) (yes bool) { - yes = false - // a tag begin with '#' if link[0] == '#' { - yes = true + return true } // link begin with '/' but not '//', the second maybe a protocol relative link if len(link) >= 2 && link[0] == '/' && link[1] != '/' { - yes = true + return true } // only the root '/' if len(link) == 1 && link[0] == '/' { - yes = true + return true } - return + + // current directory : begin with "./" + if bytes.HasPrefix(link, []byte("./")) { + return true + } + + // parent directory : begin with "../" + if bytes.HasPrefix(link, []byte("../")) { + return true + } + + return false } func (options *Html) ensureUniqueHeaderID(id string) string { diff --git a/vendor/github.com/russross/blackfriday/inline.go b/vendor/github.com/russross/blackfriday/inline.go index f76d7b375cd..a28bb660d41 100644 --- a/vendor/github.com/russross/blackfriday/inline.go +++ b/vendor/github.com/russross/blackfriday/inline.go @@ -167,12 +167,17 @@ func lineBreak(p *parser, out *bytes.Buffer, data []byte, offset int) int { out.Truncate(eol) precededByTwoSpaces := offset >= 2 && data[offset-2] == ' ' && data[offset-1] == ' ' + precededByBackslash := offset >= 1 && data[offset-1] == '\\' // see http://spec.commonmark.org/0.18/#example-527 + precededByBackslash = precededByBackslash && p.flags&EXTENSION_BACKSLASH_LINE_BREAK != 0 // should there be a hard line break here? - if p.flags&EXTENSION_HARD_LINE_BREAK == 0 && !precededByTwoSpaces { + if p.flags&EXTENSION_HARD_LINE_BREAK == 0 && !precededByTwoSpaces && !precededByBackslash { return 0 } + if precededByBackslash && eol > 0 { + out.Truncate(eol - 1) + } p.r.LineBreak(out) return 1 } @@ -186,6 +191,13 @@ const ( linkInlineFootnote ) +func isReferenceStyleLink(data []byte, pos int, t linkType) bool { + if t == linkDeferredFootnote { + return false + } + return pos < len(data)-1 && data[pos] == '[' && data[pos+1] != '^' +} + // '[': parse a link or an image or a footnote func link(p *parser, out *bytes.Buffer, data []byte, offset int) int { // no links allowed inside regular links, footnote, and deferred footnotes @@ -193,28 +205,35 @@ func link(p *parser, out *bytes.Buffer, data []byte, offset int) int { return 0 } - // [text] == regular link + var t linkType + switch { + // special case: ![^text] == deferred footnote (that follows something with + // an exclamation point) + case p.flags&EXTENSION_FOOTNOTES != 0 && len(data)-1 > offset && data[offset+1] == '^': + t = linkDeferredFootnote // ![alt] == image + case offset > 0 && data[offset-1] == '!': + t = linkImg // ^[text] == inline footnote // [^refId] == deferred footnote - var t linkType - if offset > 0 && data[offset-1] == '!' { - t = linkImg - } else if p.flags&EXTENSION_FOOTNOTES != 0 { + case p.flags&EXTENSION_FOOTNOTES != 0: if offset > 0 && data[offset-1] == '^' { t = linkInlineFootnote } else if len(data)-1 > offset && data[offset+1] == '^' { t = linkDeferredFootnote } + // [text] == regular link + default: + t = linkNormal } data = data[offset:] var ( - i = 1 - noteId int - title, link []byte - textHasNl = false + i = 1 + noteId int + title, link, altContent []byte + textHasNl = false ) if t == linkDeferredFootnote { @@ -348,8 +367,9 @@ func link(p *parser, out *bytes.Buffer, data []byte, offset int) int { i++ // reference style link - case i < len(data) && data[i] == '[': + case isReferenceStyleLink(data, i, t): var id []byte + altContentConsidered := false // look for the id i++ @@ -379,22 +399,24 @@ func link(p *parser, out *bytes.Buffer, data []byte, offset int) int { id = b.Bytes() } else { id = data[1:txtE] + altContentConsidered = true } } else { id = data[linkB:linkE] } - // find the reference with matching id (ids are case-insensitive) - key := string(bytes.ToLower(id)) - lr, ok := p.refs[key] + // find the reference with matching id + lr, ok := p.getRef(string(id)) if !ok { return 0 - } // keep link and title from reference link = lr.link title = lr.title + if altContentConsidered { + altContent = lr.text + } i++ // shortcut reference style link or reference or inline footnote @@ -423,7 +445,6 @@ func link(p *parser, out *bytes.Buffer, data []byte, offset int) int { } } - key := string(bytes.ToLower(id)) if t == linkInlineFootnote { // create a new reference noteId = len(p.notes) + 1 @@ -453,7 +474,7 @@ func link(p *parser, out *bytes.Buffer, data []byte, offset int) int { title = ref.title } else { // find the reference with matching id - lr, ok := p.refs[key] + lr, ok := p.getRef(string(id)) if !ok { return 0 } @@ -505,7 +526,11 @@ func link(p *parser, out *bytes.Buffer, data []byte, offset int) int { // call the relevant rendering function switch t { case linkNormal: - p.r.Link(out, uLink, title, content.Bytes()) + if len(altContent) > 0 { + p.r.Link(out, uLink, title, altContent) + } else { + p.r.Link(out, uLink, title, content.Bytes()) + } case linkImg: outSize := out.Len() @@ -535,12 +560,33 @@ func link(p *parser, out *bytes.Buffer, data []byte, offset int) int { return i } +func (p *parser) inlineHtmlComment(out *bytes.Buffer, data []byte) int { + if len(data) < 5 { + return 0 + } + if data[0] != '<' || data[1] != '!' || data[2] != '-' || data[3] != '-' { + return 0 + } + i := 5 + // scan for an end-of-comment marker, across lines if necessary + for i < len(data) && !(data[i-2] == '-' && data[i-1] == '-' && data[i] == '>') { + i++ + } + // no end-of-comment marker + if i >= len(data) { + return 0 + } + return i + 1 +} + // '<' when tags or autolinks are allowed func leftAngle(p *parser, out *bytes.Buffer, data []byte, offset int) int { data = data[offset:] altype := LINK_TYPE_NOT_AUTOLINK end := tagLength(data, &altype) - + if size := p.inlineHtmlComment(out, data); size > 0 { + end = size + } if end > 2 { if altype != LINK_TYPE_NOT_AUTOLINK { var uLink bytes.Buffer @@ -622,10 +668,7 @@ func entity(p *parser, out *bytes.Buffer, data []byte, offset int) int { func linkEndsWithEntity(data []byte, linkEnd int) bool { entityRanges := htmlEntity.FindAllIndex(data[:linkEnd], -1) - if entityRanges != nil && entityRanges[len(entityRanges)-1][1] == linkEnd { - return true - } - return false + return entityRanges != nil && entityRanges[len(entityRanges)-1][1] == linkEnd } func autoLink(p *parser, out *bytes.Buffer, data []byte, offset int) int { @@ -757,9 +800,20 @@ func isEndOfLink(char byte) bool { return isspace(char) || char == '<' } -var validUris = [][]byte{[]byte("http://"), []byte("https://"), []byte("ftp://"), []byte("mailto://"), []byte("/")} +var validUris = [][]byte{[]byte("http://"), []byte("https://"), []byte("ftp://"), []byte("mailto://")} +var validPaths = [][]byte{[]byte("/"), []byte("./"), []byte("../")} func isSafeLink(link []byte) bool { + for _, path := range validPaths { + if len(link) >= len(path) && bytes.Equal(link[:len(path)], path) { + if len(link) == len(path) { + return true + } else if isalnum(link[len(path)]) { + return true + } + } + } + for _, prefix := range validUris { // TODO: handle unicode here // case-insensitive prefix test @@ -887,7 +941,7 @@ func isMailtoAutoLink(data []byte) int { // look for the next emph char, skipping other constructs func helperFindEmphChar(data []byte, c byte) int { - i := 1 + i := 0 for i < len(data) { for i < len(data) && data[i] != c && data[i] != '`' && data[i] != '[' { @@ -896,15 +950,14 @@ func helperFindEmphChar(data []byte, c byte) int { if i >= len(data) { return 0 } - if data[i] == c { - return i - } - // do not count escaped chars if i != 0 && data[i-1] == '\\' { i++ continue } + if data[i] == c { + return i + } if data[i] == '`' { // skip a code span diff --git a/vendor/github.com/russross/blackfriday/latex.go b/vendor/github.com/russross/blackfriday/latex.go index 85627463b8f..70705aa9c17 100644 --- a/vendor/github.com/russross/blackfriday/latex.go +++ b/vendor/github.com/russross/blackfriday/latex.go @@ -259,7 +259,7 @@ func (options *Latex) FootnoteRef(out *bytes.Buffer, ref []byte, id int) { } func needsBackslash(c byte) bool { - for _, r := range []byte("_{}%$&\\~") { + for _, r := range []byte("_{}%$&\\~#") { if c == r { return true } diff --git a/vendor/github.com/russross/blackfriday/markdown.go b/vendor/github.com/russross/blackfriday/markdown.go index 4315488f337..746905bf353 100644 --- a/vendor/github.com/russross/blackfriday/markdown.go +++ b/vendor/github.com/russross/blackfriday/markdown.go @@ -20,10 +20,12 @@ package blackfriday import ( "bytes" + "fmt" + "strings" "unicode/utf8" ) -const VERSION = "1.1" +const VERSION = "1.4" // These are the supported markdown parsing extensions. // OR these values together to select multiple extensions. @@ -38,15 +40,18 @@ const ( EXTENSION_HARD_LINE_BREAK // translate newlines into line breaks EXTENSION_TAB_SIZE_EIGHT // expand tabs to eight spaces instead of four EXTENSION_FOOTNOTES // Pandoc-style footnotes - EXTENSION_NO_EMPTY_LINE_BEFORE_BLOCK // No need to insert an empty line to start a (code, quote, order list, unorder list)block + EXTENSION_NO_EMPTY_LINE_BEFORE_BLOCK // No need to insert an empty line to start a (code, quote, ordered list, unordered list) block EXTENSION_HEADER_IDS // specify header IDs with {#id} EXTENSION_TITLEBLOCK // Titleblock ala pandoc EXTENSION_AUTO_HEADER_IDS // Create the header ID from the text + EXTENSION_BACKSLASH_LINE_BREAK // translate trailing backslashes into line breaks + EXTENSION_DEFINITION_LISTS // render definition lists commonHtmlFlags = 0 | HTML_USE_XHTML | HTML_USE_SMARTYPANTS | HTML_SMARTYPANTS_FRACTIONS | + HTML_SMARTYPANTS_DASHES | HTML_SMARTYPANTS_LATEX_DASHES commonExtensions = 0 | @@ -56,7 +61,9 @@ const ( EXTENSION_AUTOLINK | EXTENSION_STRIKETHROUGH | EXTENSION_SPACE_HEADERS | - EXTENSION_HEADER_IDS + EXTENSION_HEADER_IDS | + EXTENSION_BACKSLASH_LINE_BREAK | + EXTENSION_DEFINITION_LISTS ) // These are the possible flag values for the link renderer. @@ -73,6 +80,8 @@ const ( // These are mostly of interest if you are writing a new output format. const ( LIST_TYPE_ORDERED = 1 << iota + LIST_TYPE_DEFINITION + LIST_TYPE_TERM LIST_ITEM_CONTAINS_BLOCK LIST_ITEM_BEGINNING_OF_LIST LIST_ITEM_END_OF_LIST @@ -93,45 +102,49 @@ const ( TAB_SIZE_EIGHT = 8 ) -// These are the tags that are recognized as HTML block tags. +// blockTags is a set of tags that are recognized as HTML block tags. // Any of these can be included in markdown text without special escaping. -var blockTags = map[string]bool{ - "p": true, - "dl": true, - "h1": true, - "h2": true, - "h3": true, - "h4": true, - "h5": true, - "h6": true, - "ol": true, - "ul": true, - "del": true, - "div": true, - "ins": true, - "pre": true, - "form": true, - "math": true, - "table": true, - "iframe": true, - "script": true, - "fieldset": true, - "noscript": true, - "blockquote": true, +var blockTags = map[string]struct{}{ + "blockquote": struct{}{}, + "del": struct{}{}, + "div": struct{}{}, + "dl": struct{}{}, + "fieldset": struct{}{}, + "form": struct{}{}, + "h1": struct{}{}, + "h2": struct{}{}, + "h3": struct{}{}, + "h4": struct{}{}, + "h5": struct{}{}, + "h6": struct{}{}, + "iframe": struct{}{}, + "ins": struct{}{}, + "math": struct{}{}, + "noscript": struct{}{}, + "ol": struct{}{}, + "pre": struct{}{}, + "p": struct{}{}, + "script": struct{}{}, + "style": struct{}{}, + "table": struct{}{}, + "ul": struct{}{}, // HTML5 - "video": true, - "aside": true, - "canvas": true, - "figure": true, - "footer": true, - "header": true, - "hgroup": true, - "output": true, - "article": true, - "section": true, - "progress": true, - "figcaption": true, + "address": struct{}{}, + "article": struct{}{}, + "aside": struct{}{}, + "canvas": struct{}{}, + "figcaption": struct{}{}, + "figure": struct{}{}, + "footer": struct{}{}, + "header": struct{}{}, + "hgroup": struct{}{}, + "main": struct{}{}, + "nav": struct{}{}, + "output": struct{}{}, + "progress": struct{}{}, + "section": struct{}{}, + "video": struct{}{}, } // Renderer is the rendering interface. @@ -196,6 +209,7 @@ type inlineParser func(p *parser, out *bytes.Buffer, data []byte, offset int) in // This is constructed by the Markdown function. type parser struct { r Renderer + refOverride ReferenceOverrideFunc refs map[string]*reference inlineCallback [256]inlineParser flags int @@ -209,12 +223,74 @@ type parser struct { notes []*reference } +func (p *parser) getRef(refid string) (ref *reference, found bool) { + if p.refOverride != nil { + r, overridden := p.refOverride(refid) + if overridden { + if r == nil { + return nil, false + } + return &reference{ + link: []byte(r.Link), + title: []byte(r.Title), + noteId: 0, + hasBlock: false, + text: []byte(r.Text)}, true + } + } + // refs are case insensitive + ref, found = p.refs[strings.ToLower(refid)] + return ref, found +} + // // // Public interface // // +// Reference represents the details of a link. +// See the documentation in Options for more details on use-case. +type Reference struct { + // Link is usually the URL the reference points to. + Link string + // Title is the alternate text describing the link in more detail. + Title string + // Text is the optional text to override the ref with if the syntax used was + // [refid][] + Text string +} + +// ReferenceOverrideFunc is expected to be called with a reference string and +// return either a valid Reference type that the reference string maps to or +// nil. If overridden is false, the default reference logic will be executed. +// See the documentation in Options for more details on use-case. +type ReferenceOverrideFunc func(reference string) (ref *Reference, overridden bool) + +// Options represents configurable overrides and callbacks (in addition to the +// extension flag set) for configuring a Markdown parse. +type Options struct { + // Extensions is a flag set of bit-wise ORed extension bits. See the + // EXTENSION_* flags defined in this package. + Extensions int + + // ReferenceOverride is an optional function callback that is called every + // time a reference is resolved. + // + // In Markdown, the link reference syntax can be made to resolve a link to + // a reference instead of an inline URL, in one of the following ways: + // + // * [link text][refid] + // * [refid][] + // + // Usually, the refid is defined at the bottom of the Markdown document. If + // this override function is provided, the refid is passed to the override + // function first, before consulting the defined refids at the bottom. If + // the override function indicates an override did not occur, the refids at + // the bottom will be used to fill in the link details. + ReferenceOverride ReferenceOverrideFunc +} + // MarkdownBasic is a convenience function for simple rendering. // It processes markdown input with no extensions enabled. func MarkdownBasic(input []byte) []byte { @@ -223,9 +299,7 @@ func MarkdownBasic(input []byte) []byte { renderer := HtmlRenderer(htmlFlags, "", "") // set up the parser - extensions := 0 - - return Markdown(input, renderer, extensions) + return MarkdownOptions(input, renderer, Options{Extensions: 0}) } // Call Markdown with most useful extensions enabled @@ -250,7 +324,8 @@ func MarkdownBasic(input []byte) []byte { func MarkdownCommon(input []byte) []byte { // set up the HTML renderer renderer := HtmlRenderer(commonHtmlFlags, "", "") - return Markdown(input, renderer, commonExtensions) + return MarkdownOptions(input, renderer, Options{ + Extensions: commonExtensions}) } // Markdown is the main rendering function. @@ -261,15 +336,25 @@ func MarkdownCommon(input []byte) []byte { // To use the supplied Html or LaTeX renderers, see HtmlRenderer and // LatexRenderer, respectively. func Markdown(input []byte, renderer Renderer, extensions int) []byte { + return MarkdownOptions(input, renderer, Options{ + Extensions: extensions}) +} + +// MarkdownOptions is just like Markdown but takes additional options through +// the Options struct. +func MarkdownOptions(input []byte, renderer Renderer, opts Options) []byte { // no point in parsing if we can't render if renderer == nil { return nil } + extensions := opts.Extensions + // fill in the render structure p := new(parser) p.r = renderer p.flags = extensions + p.refOverride = opts.ReferenceOverride p.refs = make(map[string]*reference) p.maxNesting = 16 p.insideLink = false @@ -305,7 +390,6 @@ func Markdown(input []byte, renderer Renderer, extensions int) []byte { // - expand tabs // - normalize newlines // - copy everything else -// - add missing newlines before fenced code blocks func firstPass(p *parser, input []byte) []byte { var out bytes.Buffer tabSize := TAB_SIZE_DEFAULT @@ -313,7 +397,6 @@ func firstPass(p *parser, input []byte) []byte { tabSize = TAB_SIZE_EIGHT } beg, end := 0, 0 - lastLineWasBlank := false lastFencedCodeBlockEnd := 0 for beg < len(input) { // iterate over lines if end = isReference(p, input[beg:], tabSize); end > 0 { @@ -325,16 +408,13 @@ func firstPass(p *parser, input []byte) []byte { } if p.flags&EXTENSION_FENCED_CODE != 0 { - // when last line was none blank and a fenced code block comes after + // track fenced code block boundaries to suppress tab expansion + // inside them: if beg >= lastFencedCodeBlockEnd { if i := p.fencedCode(&out, input[beg:], false); i > 0 { - if !lastLineWasBlank { - out.WriteByte('\n') // need to inject additional linebreak - } lastFencedCodeBlockEnd = beg + i } } - lastLineWasBlank = end == beg } // add the line body if present @@ -376,7 +456,8 @@ func secondPass(p *parser, input []byte) []byte { if p.flags&EXTENSION_FOOTNOTES != 0 && len(p.notes) > 0 { p.r.Footnotes(&output, func() bool { flags := LIST_ITEM_BEGINNING_OF_LIST - for _, ref := range p.notes { + for i := 0; i < len(p.notes); i += 1 { + ref := p.notes[i] var buf bytes.Buffer if ref.hasBlock { flags |= LIST_ITEM_CONTAINS_BLOCK @@ -436,6 +517,12 @@ type reference struct { title []byte noteId int // 0 if not a footnote ref hasBlock bool + text []byte +} + +func (r *reference) String() string { + return fmt.Sprintf("{link: %q, title: %q, text: %q, noteId: %d, hasBlock: %v}", + r.link, r.title, r.text, r.noteId, r.hasBlock) } // Check whether or not data starts with a reference link. @@ -461,7 +548,7 @@ func isReference(p *parser, data []byte, tabSize int) int { } i++ if p.flags&EXTENSION_FOOTNOTES != 0 { - if data[i] == '^' { + if i < len(data) && data[i] == '^' { // we can set it to anything here because the proper noteIds will // be assigned later during the second pass. It just has to be != 0 noteId = 1 @@ -551,6 +638,9 @@ func scanLinkRef(p *parser, data []byte, i int) (linkOffset, linkEnd, titleOffse for i < len(data) && data[i] != ' ' && data[i] != '\t' && data[i] != '\n' && data[i] != '\r' { i++ } + if i == len(data) { + return + } linkEnd = i if data[linkOffset] == '<' && data[linkEnd-1] == '>' { linkOffset++ diff --git a/vendor/github.com/russross/blackfriday/smartypants.go b/vendor/github.com/russross/blackfriday/smartypants.go index 8027571df33..eeffa5e1e1a 100644 --- a/vendor/github.com/russross/blackfriday/smartypants.go +++ b/vendor/github.com/russross/blackfriday/smartypants.go @@ -378,10 +378,12 @@ func smartypants(flags int) *smartypantsRenderer { } r['\''] = smartSingleQuote r['('] = smartParens - if flags&HTML_SMARTYPANTS_LATEX_DASHES == 0 { - r['-'] = smartDash - } else { - r['-'] = smartDashLatex + if flags&HTML_SMARTYPANTS_DASHES != 0 { + if flags&HTML_SMARTYPANTS_LATEX_DASHES == 0 { + r['-'] = smartDash + } else { + r['-'] = smartDashLatex + } } r['.'] = smartPeriod if flags&HTML_SMARTYPANTS_FRACTIONS == 0 { diff --git a/vendor/github.com/ugorji/go/codec/0doc.go b/vendor/github.com/ugorji/go/codec/0doc.go index bd7361c8796..caa7e0a3b50 100644 --- a/vendor/github.com/ugorji/go/codec/0doc.go +++ b/vendor/github.com/ugorji/go/codec/0doc.go @@ -64,7 +64,6 @@ Rich Feature Set includes: - Never silently skip data when decoding. User decides whether to return an error or silently skip data when keys or indexes in the data stream do not map to fields in the struct. - - Detect and error when encoding a cyclic reference (instead of stack overflow shutdown) - Encode/Decode from/to chan types (for iterative streaming support) - Drop-in replacement for encoding/json. `json:` key in struct tag supported. - Provides a RPC Server and Client Codec for net/rpc communication protocol. @@ -172,8 +171,6 @@ package codec // TODO: // -// - optimization for codecgen: -// if len of entity is <= 3 words, then support a value receiver for encode. // - (En|De)coder should store an error when it occurs. // Until reset, subsequent calls return that error that was stored. // This means that free panics must go away. @@ -186,14 +183,11 @@ package codec // Name string // Ys []Y // Ys chan <- Y -// Ys func(Y) -> call this function for each entry +// Ys func(interface{}) -> call this interface for each entry in there. // } // - Consider adding a isZeroer interface { isZero() bool } // It is used within isEmpty, for omitEmpty support. // - Consider making Handle used AS-IS within the encoding/decoding session. // This means that we don't cache Handle information within the (En|De)coder, // except we really need it at Reset(...) -// - Consider adding math/big support -// - Consider reducing the size of the generated functions: -// Maybe use one loop, and put the conditionals in the loop. -// for ... { if cLen > 0 { if j == cLen { break } } else if dd.CheckBreak() { break } } +// - Handle recursive types during encoding/decoding? diff --git a/vendor/github.com/ugorji/go/codec/binc.go b/vendor/github.com/ugorji/go/codec/binc.go index 766d26cf6d7..c884d14dce5 100644 --- a/vendor/github.com/ugorji/go/codec/binc.go +++ b/vendor/github.com/ugorji/go/codec/binc.go @@ -908,14 +908,10 @@ func (h *BincHandle) newDecDriver(d *Decoder) decDriver { func (e *bincEncDriver) reset() { e.w = e.e.w - e.s = 0 - e.m = nil } func (d *bincDecDriver) reset() { d.r = d.d.r - d.s = nil - d.bd, d.bdRead, d.vd, d.vs = 0, false, 0, 0 } var _ decDriver = (*bincDecDriver)(nil) diff --git a/vendor/github.com/ugorji/go/codec/cbor.go b/vendor/github.com/ugorji/go/codec/cbor.go index a224cd3a72c..0e5d32b2ea9 100644 --- a/vendor/github.com/ugorji/go/codec/cbor.go +++ b/vendor/github.com/ugorji/go/codec/cbor.go @@ -508,7 +508,7 @@ func (d *cborDecDriver) DecodeNaked() { n.v = valueTypeExt n.u = d.decUint() n.l = nil - // d.bdRead = false + d.bdRead = false // d.d.decode(&re.Value) // handled by decode itself. // decodeFurther = true default: @@ -578,7 +578,6 @@ func (e *cborEncDriver) reset() { func (d *cborDecDriver) reset() { d.r = d.d.r - d.bd, d.bdRead = 0, false } var _ decDriver = (*cborDecDriver)(nil) diff --git a/vendor/github.com/ugorji/go/codec/decode.go b/vendor/github.com/ugorji/go/codec/decode.go index 7e56f1eca56..b3b99f03670 100644 --- a/vendor/github.com/ugorji/go/codec/decode.go +++ b/vendor/github.com/ugorji/go/codec/decode.go @@ -583,16 +583,14 @@ func (f *decFnInfo) kInterfaceNaked() (rvn reflect.Value) { if d.mtid == 0 || d.mtid == mapIntfIntfTypId { l := len(n.ms) n.ms = append(n.ms, nil) - var v2 interface{} = &n.ms[l] - d.decode(v2) - rvn = reflect.ValueOf(v2).Elem() + d.decode(&n.ms[l]) + rvn = reflect.ValueOf(&n.ms[l]).Elem() n.ms = n.ms[:l] } else if d.mtid == mapStrIntfTypId { // for json performance l := len(n.ns) n.ns = append(n.ns, nil) - var v2 interface{} = &n.ns[l] - d.decode(v2) - rvn = reflect.ValueOf(v2).Elem() + d.decode(&n.ns[l]) + rvn = reflect.ValueOf(&n.ns[l]).Elem() n.ns = n.ns[:l] } else { rvn = reflect.New(d.h.MapType).Elem() @@ -603,9 +601,8 @@ func (f *decFnInfo) kInterfaceNaked() (rvn reflect.Value) { if d.stid == 0 || d.stid == intfSliceTypId { l := len(n.ss) n.ss = append(n.ss, nil) - var v2 interface{} = &n.ss[l] - d.decode(v2) - rvn = reflect.ValueOf(v2).Elem() + d.decode(&n.ss[l]) + rvn = reflect.ValueOf(&n.ss[l]).Elem() n.ss = n.ss[:l] } else { rvn = reflect.New(d.h.SliceType).Elem() @@ -618,9 +615,9 @@ func (f *decFnInfo) kInterfaceNaked() (rvn reflect.Value) { l := len(n.is) n.is = append(n.is, nil) v2 := &n.is[l] + n.is = n.is[:l] d.decode(v2) v = *v2 - n.is = n.is[:l] } bfn := d.h.getExtForTag(tag) if bfn == nil { @@ -1456,8 +1453,8 @@ func (d *Decoder) swallow() { l := len(n.is) n.is = append(n.is, nil) v2 := &n.is[l] - d.decode(v2) n.is = n.is[:l] + d.decode(v2) } } } @@ -1865,7 +1862,6 @@ func (d *Decoder) intern(s string) { } } -// nextValueBytes returns the next value in the stream as a set of bytes. func (d *Decoder) nextValueBytes() []byte { d.d.uncacheRead() d.r.track() diff --git a/vendor/github.com/ugorji/go/codec/encode.go b/vendor/github.com/ugorji/go/codec/encode.go index a874c744b81..99af6fa555a 100644 --- a/vendor/github.com/ugorji/go/codec/encode.go +++ b/vendor/github.com/ugorji/go/codec/encode.go @@ -110,15 +110,6 @@ type EncodeOptions struct { // Canonical bool - // CheckCircularRef controls whether we check for circular references - // and error fast during an encode. - // - // If enabled, an error is received if a pointer to a struct - // references itself either directly or through one of its fields (iteratively). - // - // This is opt-in, as there may be a performance hit to checking circular references. - CheckCircularRef bool - // AsSymbols defines what should be encoded as symbols. // // Encoding as symbols can reduce the encoded size significantly. @@ -473,7 +464,7 @@ func (f *encFnInfo) kSlice(rv reflect.Value) { for j := 0; j < l; j++ { if cr != nil { if ti.mbs { - if j%2 == 0 { + if l%2 == 0 { cr.sendContainerState(containerMapKey) } else { cr.sendContainerState(containerMapValue) @@ -512,7 +503,7 @@ func (f *encFnInfo) kStruct(rv reflect.Value) { newlen := len(fti.sfi) // Use sync.Pool to reduce allocating slices unnecessarily. - // The cost of sync.Pool is less than the cost of new allocation. + // The cost of the occasional locking is less than the cost of new allocation. pool, poolv, fkvs := encStructPoolGet(newlen) // if toMap, use the sorted array. If toArray, use unsorted array (to match sequence in struct) @@ -523,6 +514,11 @@ func (f *encFnInfo) kStruct(rv reflect.Value) { var kv stringRv for _, si := range tisfi { kv.r = si.field(rv, false) + // if si.i != -1 { + // rvals[newlen] = rv.Field(int(si.i)) + // } else { + // rvals[newlen] = rv.FieldByIndex(si.is) + // } if toMap { if si.omitEmpty && isEmptyValue(kv.r) { continue @@ -600,15 +596,13 @@ func (f *encFnInfo) kStruct(rv reflect.Value) { // f.e.encodeValue(rv.Elem()) // } -// func (f *encFnInfo) kInterface(rv reflect.Value) { -// println("kInterface called") -// debug.PrintStack() -// if rv.IsNil() { -// f.e.e.EncodeNil() -// return -// } -// f.e.encodeValue(rv.Elem(), nil) -// } +func (f *encFnInfo) kInterface(rv reflect.Value) { + if rv.IsNil() { + f.e.e.EncodeNil() + return + } + f.e.encodeValue(rv.Elem(), nil) +} func (f *encFnInfo) kMap(rv reflect.Value) { ee := f.e.e @@ -883,7 +877,6 @@ type Encoder struct { // as the handler MAY need to do some coordination. w encWriter s []encRtidFn - ci set be bool // is binary encoding js bool // is json handle @@ -1140,23 +1133,20 @@ func (e *Encoder) encode(iv interface{}) { } } -func (e *Encoder) preEncodeValue(rv reflect.Value) (rv2 reflect.Value, sptr uintptr, proceed bool) { +func (e *Encoder) encodeI(iv interface{}, checkFastpath, checkCodecSelfer bool) { + if rv, proceed := e.preEncodeValue(reflect.ValueOf(iv)); proceed { + rt := rv.Type() + rtid := reflect.ValueOf(rt).Pointer() + fn := e.getEncFn(rtid, rt, checkFastpath, checkCodecSelfer) + fn.f(&fn.i, rv) + } +} + +func (e *Encoder) preEncodeValue(rv reflect.Value) (rv2 reflect.Value, proceed bool) { // use a goto statement instead of a recursive function for ptr/interface. TOP: switch rv.Kind() { - case reflect.Ptr: - if rv.IsNil() { - e.e.EncodeNil() - return - } - rv = rv.Elem() - if e.h.CheckCircularRef && rv.Kind() == reflect.Struct { - // TODO: Movable pointers will be an issue here. Future problem. - sptr = rv.UnsafeAddr() - break TOP - } - goto TOP - case reflect.Interface: + case reflect.Ptr, reflect.Interface: if rv.IsNil() { e.e.EncodeNil() return @@ -1173,40 +1163,18 @@ TOP: return } - proceed = true - rv2 = rv - return -} - -func (e *Encoder) doEncodeValue(rv reflect.Value, fn *encFn, sptr uintptr, - checkFastpath, checkCodecSelfer bool) { - if sptr != 0 { - if (&e.ci).add(sptr) { - e.errorf("circular reference found: # %d", sptr) - } - } - if fn == nil { - rt := rv.Type() - rtid := reflect.ValueOf(rt).Pointer() - // fn = e.getEncFn(rtid, rt, true, true) - fn = e.getEncFn(rtid, rt, checkFastpath, checkCodecSelfer) - } - fn.f(&fn.i, rv) - if sptr != 0 { - (&e.ci).remove(sptr) - } -} - -func (e *Encoder) encodeI(iv interface{}, checkFastpath, checkCodecSelfer bool) { - if rv, sptr, proceed := e.preEncodeValue(reflect.ValueOf(iv)); proceed { - e.doEncodeValue(rv, nil, sptr, checkFastpath, checkCodecSelfer) - } + return rv, true } func (e *Encoder) encodeValue(rv reflect.Value, fn *encFn) { // if a valid fn is passed, it MUST BE for the dereferenced type of rv - if rv, sptr, proceed := e.preEncodeValue(rv); proceed { - e.doEncodeValue(rv, fn, sptr, true, true) + if rv, proceed := e.preEncodeValue(rv); proceed { + if fn == nil { + rt := rv.Type() + rtid := reflect.ValueOf(rt).Pointer() + fn = e.getEncFn(rtid, rt, true, true) + } + fn.f(&fn.i, rv) } } @@ -1266,7 +1234,7 @@ func (e *Encoder) getEncFn(rtid uintptr, rt reflect.Type, checkFastpath, checkCo } else { rk := rt.Kind() if fastpathEnabled && checkFastpath && (rk == reflect.Map || rk == reflect.Slice) { - if rt.PkgPath() == "" { // un-named slice or map + if rt.PkgPath() == "" { if idx := fastpathAV.index(rtid); idx != -1 { fn.f = fastpathAV[idx].encfn } @@ -1316,11 +1284,10 @@ func (e *Encoder) getEncFn(rtid uintptr, rt reflect.Type, checkFastpath, checkCo fn.f = (*encFnInfo).kSlice case reflect.Struct: fn.f = (*encFnInfo).kStruct - // reflect.Ptr and reflect.Interface are handled already by preEncodeValue // case reflect.Ptr: // fn.f = (*encFnInfo).kPtr - // case reflect.Interface: - // fn.f = (*encFnInfo).kInterface + case reflect.Interface: + fn.f = (*encFnInfo).kInterface case reflect.Map: fn.f = (*encFnInfo).kMap default: @@ -1386,6 +1353,25 @@ func encStructPoolGet(newlen int) (p *sync.Pool, v interface{}, s []stringRv) { // panic(errors.New("encStructPoolLen must be equal to 4")) // defensive, in case it is changed // } // idxpool := newlen / 8 + + // if pool == nil { + // fkvs = make([]stringRv, newlen) + // } else { + // poolv = pool.Get() + // switch vv := poolv.(type) { + // case *[8]stringRv: + // fkvs = vv[:newlen] + // case *[16]stringRv: + // fkvs = vv[:newlen] + // case *[32]stringRv: + // fkvs = vv[:newlen] + // case *[64]stringRv: + // fkvs = vv[:newlen] + // case *[128]stringRv: + // fkvs = vv[:newlen] + // } + // } + if newlen <= 8 { p = &encStructPool[0] v = p.Get() diff --git a/vendor/github.com/ugorji/go/codec/fast-path.generated.go b/vendor/github.com/ugorji/go/codec/fast-path.generated.go index cf6e00df217..d968a500fde 100644 --- a/vendor/github.com/ugorji/go/codec/fast-path.generated.go +++ b/vendor/github.com/ugorji/go/codec/fast-path.generated.go @@ -3124,11 +3124,7 @@ func fastpathEncodeTypeSwitchMap(iv interface{}, e *Encoder) bool { // -- -- fast path functions func (f *encFnInfo) fastpathEncSliceIntfR(rv reflect.Value) { - if f.ti.mbs { - fastpathTV.EncAsMapSliceIntfV(rv.Interface().([]interface{}), fastpathCheckNilFalse, f.e) - } else { - fastpathTV.EncSliceIntfV(rv.Interface().([]interface{}), fastpathCheckNilFalse, f.e) - } + fastpathTV.EncSliceIntfV(rv.Interface().([]interface{}), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncSliceIntfV(v []interface{}, checkNil bool, e *Encoder) { ee := e.e @@ -3149,39 +3145,8 @@ func (_ fastpathT) EncSliceIntfV(v []interface{}, checkNil bool, e *Encoder) { } } -func (_ fastpathT) EncAsMapSliceIntfV(v []interface{}, checkNil bool, e *Encoder) { - ee := e.e - cr := e.cr - if checkNil && v == nil { - ee.EncodeNil() - return - } - if len(v)%2 == 1 { - e.errorf("mapBySlice requires even slice length, but got %v", len(v)) - return - } - ee.EncodeMapStart(len(v) / 2) - for j, v2 := range v { - if cr != nil { - if j%2 == 0 { - cr.sendContainerState(containerMapKey) - } else { - cr.sendContainerState(containerMapValue) - } - } - e.encode(v2) - } - if cr != nil { - cr.sendContainerState(containerMapEnd) - } -} - func (f *encFnInfo) fastpathEncSliceStringR(rv reflect.Value) { - if f.ti.mbs { - fastpathTV.EncAsMapSliceStringV(rv.Interface().([]string), fastpathCheckNilFalse, f.e) - } else { - fastpathTV.EncSliceStringV(rv.Interface().([]string), fastpathCheckNilFalse, f.e) - } + fastpathTV.EncSliceStringV(rv.Interface().([]string), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncSliceStringV(v []string, checkNil bool, e *Encoder) { ee := e.e @@ -3202,39 +3167,8 @@ func (_ fastpathT) EncSliceStringV(v []string, checkNil bool, e *Encoder) { } } -func (_ fastpathT) EncAsMapSliceStringV(v []string, checkNil bool, e *Encoder) { - ee := e.e - cr := e.cr - if checkNil && v == nil { - ee.EncodeNil() - return - } - if len(v)%2 == 1 { - e.errorf("mapBySlice requires even slice length, but got %v", len(v)) - return - } - ee.EncodeMapStart(len(v) / 2) - for j, v2 := range v { - if cr != nil { - if j%2 == 0 { - cr.sendContainerState(containerMapKey) - } else { - cr.sendContainerState(containerMapValue) - } - } - ee.EncodeString(c_UTF8, v2) - } - if cr != nil { - cr.sendContainerState(containerMapEnd) - } -} - func (f *encFnInfo) fastpathEncSliceFloat32R(rv reflect.Value) { - if f.ti.mbs { - fastpathTV.EncAsMapSliceFloat32V(rv.Interface().([]float32), fastpathCheckNilFalse, f.e) - } else { - fastpathTV.EncSliceFloat32V(rv.Interface().([]float32), fastpathCheckNilFalse, f.e) - } + fastpathTV.EncSliceFloat32V(rv.Interface().([]float32), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncSliceFloat32V(v []float32, checkNil bool, e *Encoder) { ee := e.e @@ -3255,39 +3189,8 @@ func (_ fastpathT) EncSliceFloat32V(v []float32, checkNil bool, e *Encoder) { } } -func (_ fastpathT) EncAsMapSliceFloat32V(v []float32, checkNil bool, e *Encoder) { - ee := e.e - cr := e.cr - if checkNil && v == nil { - ee.EncodeNil() - return - } - if len(v)%2 == 1 { - e.errorf("mapBySlice requires even slice length, but got %v", len(v)) - return - } - ee.EncodeMapStart(len(v) / 2) - for j, v2 := range v { - if cr != nil { - if j%2 == 0 { - cr.sendContainerState(containerMapKey) - } else { - cr.sendContainerState(containerMapValue) - } - } - ee.EncodeFloat32(v2) - } - if cr != nil { - cr.sendContainerState(containerMapEnd) - } -} - func (f *encFnInfo) fastpathEncSliceFloat64R(rv reflect.Value) { - if f.ti.mbs { - fastpathTV.EncAsMapSliceFloat64V(rv.Interface().([]float64), fastpathCheckNilFalse, f.e) - } else { - fastpathTV.EncSliceFloat64V(rv.Interface().([]float64), fastpathCheckNilFalse, f.e) - } + fastpathTV.EncSliceFloat64V(rv.Interface().([]float64), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncSliceFloat64V(v []float64, checkNil bool, e *Encoder) { ee := e.e @@ -3308,39 +3211,8 @@ func (_ fastpathT) EncSliceFloat64V(v []float64, checkNil bool, e *Encoder) { } } -func (_ fastpathT) EncAsMapSliceFloat64V(v []float64, checkNil bool, e *Encoder) { - ee := e.e - cr := e.cr - if checkNil && v == nil { - ee.EncodeNil() - return - } - if len(v)%2 == 1 { - e.errorf("mapBySlice requires even slice length, but got %v", len(v)) - return - } - ee.EncodeMapStart(len(v) / 2) - for j, v2 := range v { - if cr != nil { - if j%2 == 0 { - cr.sendContainerState(containerMapKey) - } else { - cr.sendContainerState(containerMapValue) - } - } - ee.EncodeFloat64(v2) - } - if cr != nil { - cr.sendContainerState(containerMapEnd) - } -} - func (f *encFnInfo) fastpathEncSliceUintR(rv reflect.Value) { - if f.ti.mbs { - fastpathTV.EncAsMapSliceUintV(rv.Interface().([]uint), fastpathCheckNilFalse, f.e) - } else { - fastpathTV.EncSliceUintV(rv.Interface().([]uint), fastpathCheckNilFalse, f.e) - } + fastpathTV.EncSliceUintV(rv.Interface().([]uint), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncSliceUintV(v []uint, checkNil bool, e *Encoder) { ee := e.e @@ -3361,39 +3233,8 @@ func (_ fastpathT) EncSliceUintV(v []uint, checkNil bool, e *Encoder) { } } -func (_ fastpathT) EncAsMapSliceUintV(v []uint, checkNil bool, e *Encoder) { - ee := e.e - cr := e.cr - if checkNil && v == nil { - ee.EncodeNil() - return - } - if len(v)%2 == 1 { - e.errorf("mapBySlice requires even slice length, but got %v", len(v)) - return - } - ee.EncodeMapStart(len(v) / 2) - for j, v2 := range v { - if cr != nil { - if j%2 == 0 { - cr.sendContainerState(containerMapKey) - } else { - cr.sendContainerState(containerMapValue) - } - } - ee.EncodeUint(uint64(v2)) - } - if cr != nil { - cr.sendContainerState(containerMapEnd) - } -} - func (f *encFnInfo) fastpathEncSliceUint16R(rv reflect.Value) { - if f.ti.mbs { - fastpathTV.EncAsMapSliceUint16V(rv.Interface().([]uint16), fastpathCheckNilFalse, f.e) - } else { - fastpathTV.EncSliceUint16V(rv.Interface().([]uint16), fastpathCheckNilFalse, f.e) - } + fastpathTV.EncSliceUint16V(rv.Interface().([]uint16), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncSliceUint16V(v []uint16, checkNil bool, e *Encoder) { ee := e.e @@ -3414,39 +3255,8 @@ func (_ fastpathT) EncSliceUint16V(v []uint16, checkNil bool, e *Encoder) { } } -func (_ fastpathT) EncAsMapSliceUint16V(v []uint16, checkNil bool, e *Encoder) { - ee := e.e - cr := e.cr - if checkNil && v == nil { - ee.EncodeNil() - return - } - if len(v)%2 == 1 { - e.errorf("mapBySlice requires even slice length, but got %v", len(v)) - return - } - ee.EncodeMapStart(len(v) / 2) - for j, v2 := range v { - if cr != nil { - if j%2 == 0 { - cr.sendContainerState(containerMapKey) - } else { - cr.sendContainerState(containerMapValue) - } - } - ee.EncodeUint(uint64(v2)) - } - if cr != nil { - cr.sendContainerState(containerMapEnd) - } -} - func (f *encFnInfo) fastpathEncSliceUint32R(rv reflect.Value) { - if f.ti.mbs { - fastpathTV.EncAsMapSliceUint32V(rv.Interface().([]uint32), fastpathCheckNilFalse, f.e) - } else { - fastpathTV.EncSliceUint32V(rv.Interface().([]uint32), fastpathCheckNilFalse, f.e) - } + fastpathTV.EncSliceUint32V(rv.Interface().([]uint32), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncSliceUint32V(v []uint32, checkNil bool, e *Encoder) { ee := e.e @@ -3467,39 +3277,8 @@ func (_ fastpathT) EncSliceUint32V(v []uint32, checkNil bool, e *Encoder) { } } -func (_ fastpathT) EncAsMapSliceUint32V(v []uint32, checkNil bool, e *Encoder) { - ee := e.e - cr := e.cr - if checkNil && v == nil { - ee.EncodeNil() - return - } - if len(v)%2 == 1 { - e.errorf("mapBySlice requires even slice length, but got %v", len(v)) - return - } - ee.EncodeMapStart(len(v) / 2) - for j, v2 := range v { - if cr != nil { - if j%2 == 0 { - cr.sendContainerState(containerMapKey) - } else { - cr.sendContainerState(containerMapValue) - } - } - ee.EncodeUint(uint64(v2)) - } - if cr != nil { - cr.sendContainerState(containerMapEnd) - } -} - func (f *encFnInfo) fastpathEncSliceUint64R(rv reflect.Value) { - if f.ti.mbs { - fastpathTV.EncAsMapSliceUint64V(rv.Interface().([]uint64), fastpathCheckNilFalse, f.e) - } else { - fastpathTV.EncSliceUint64V(rv.Interface().([]uint64), fastpathCheckNilFalse, f.e) - } + fastpathTV.EncSliceUint64V(rv.Interface().([]uint64), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncSliceUint64V(v []uint64, checkNil bool, e *Encoder) { ee := e.e @@ -3520,39 +3299,8 @@ func (_ fastpathT) EncSliceUint64V(v []uint64, checkNil bool, e *Encoder) { } } -func (_ fastpathT) EncAsMapSliceUint64V(v []uint64, checkNil bool, e *Encoder) { - ee := e.e - cr := e.cr - if checkNil && v == nil { - ee.EncodeNil() - return - } - if len(v)%2 == 1 { - e.errorf("mapBySlice requires even slice length, but got %v", len(v)) - return - } - ee.EncodeMapStart(len(v) / 2) - for j, v2 := range v { - if cr != nil { - if j%2 == 0 { - cr.sendContainerState(containerMapKey) - } else { - cr.sendContainerState(containerMapValue) - } - } - ee.EncodeUint(uint64(v2)) - } - if cr != nil { - cr.sendContainerState(containerMapEnd) - } -} - func (f *encFnInfo) fastpathEncSliceUintptrR(rv reflect.Value) { - if f.ti.mbs { - fastpathTV.EncAsMapSliceUintptrV(rv.Interface().([]uintptr), fastpathCheckNilFalse, f.e) - } else { - fastpathTV.EncSliceUintptrV(rv.Interface().([]uintptr), fastpathCheckNilFalse, f.e) - } + fastpathTV.EncSliceUintptrV(rv.Interface().([]uintptr), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncSliceUintptrV(v []uintptr, checkNil bool, e *Encoder) { ee := e.e @@ -3573,39 +3321,8 @@ func (_ fastpathT) EncSliceUintptrV(v []uintptr, checkNil bool, e *Encoder) { } } -func (_ fastpathT) EncAsMapSliceUintptrV(v []uintptr, checkNil bool, e *Encoder) { - ee := e.e - cr := e.cr - if checkNil && v == nil { - ee.EncodeNil() - return - } - if len(v)%2 == 1 { - e.errorf("mapBySlice requires even slice length, but got %v", len(v)) - return - } - ee.EncodeMapStart(len(v) / 2) - for j, v2 := range v { - if cr != nil { - if j%2 == 0 { - cr.sendContainerState(containerMapKey) - } else { - cr.sendContainerState(containerMapValue) - } - } - e.encode(v2) - } - if cr != nil { - cr.sendContainerState(containerMapEnd) - } -} - func (f *encFnInfo) fastpathEncSliceIntR(rv reflect.Value) { - if f.ti.mbs { - fastpathTV.EncAsMapSliceIntV(rv.Interface().([]int), fastpathCheckNilFalse, f.e) - } else { - fastpathTV.EncSliceIntV(rv.Interface().([]int), fastpathCheckNilFalse, f.e) - } + fastpathTV.EncSliceIntV(rv.Interface().([]int), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncSliceIntV(v []int, checkNil bool, e *Encoder) { ee := e.e @@ -3626,39 +3343,8 @@ func (_ fastpathT) EncSliceIntV(v []int, checkNil bool, e *Encoder) { } } -func (_ fastpathT) EncAsMapSliceIntV(v []int, checkNil bool, e *Encoder) { - ee := e.e - cr := e.cr - if checkNil && v == nil { - ee.EncodeNil() - return - } - if len(v)%2 == 1 { - e.errorf("mapBySlice requires even slice length, but got %v", len(v)) - return - } - ee.EncodeMapStart(len(v) / 2) - for j, v2 := range v { - if cr != nil { - if j%2 == 0 { - cr.sendContainerState(containerMapKey) - } else { - cr.sendContainerState(containerMapValue) - } - } - ee.EncodeInt(int64(v2)) - } - if cr != nil { - cr.sendContainerState(containerMapEnd) - } -} - func (f *encFnInfo) fastpathEncSliceInt8R(rv reflect.Value) { - if f.ti.mbs { - fastpathTV.EncAsMapSliceInt8V(rv.Interface().([]int8), fastpathCheckNilFalse, f.e) - } else { - fastpathTV.EncSliceInt8V(rv.Interface().([]int8), fastpathCheckNilFalse, f.e) - } + fastpathTV.EncSliceInt8V(rv.Interface().([]int8), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncSliceInt8V(v []int8, checkNil bool, e *Encoder) { ee := e.e @@ -3679,39 +3365,8 @@ func (_ fastpathT) EncSliceInt8V(v []int8, checkNil bool, e *Encoder) { } } -func (_ fastpathT) EncAsMapSliceInt8V(v []int8, checkNil bool, e *Encoder) { - ee := e.e - cr := e.cr - if checkNil && v == nil { - ee.EncodeNil() - return - } - if len(v)%2 == 1 { - e.errorf("mapBySlice requires even slice length, but got %v", len(v)) - return - } - ee.EncodeMapStart(len(v) / 2) - for j, v2 := range v { - if cr != nil { - if j%2 == 0 { - cr.sendContainerState(containerMapKey) - } else { - cr.sendContainerState(containerMapValue) - } - } - ee.EncodeInt(int64(v2)) - } - if cr != nil { - cr.sendContainerState(containerMapEnd) - } -} - func (f *encFnInfo) fastpathEncSliceInt16R(rv reflect.Value) { - if f.ti.mbs { - fastpathTV.EncAsMapSliceInt16V(rv.Interface().([]int16), fastpathCheckNilFalse, f.e) - } else { - fastpathTV.EncSliceInt16V(rv.Interface().([]int16), fastpathCheckNilFalse, f.e) - } + fastpathTV.EncSliceInt16V(rv.Interface().([]int16), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncSliceInt16V(v []int16, checkNil bool, e *Encoder) { ee := e.e @@ -3732,39 +3387,8 @@ func (_ fastpathT) EncSliceInt16V(v []int16, checkNil bool, e *Encoder) { } } -func (_ fastpathT) EncAsMapSliceInt16V(v []int16, checkNil bool, e *Encoder) { - ee := e.e - cr := e.cr - if checkNil && v == nil { - ee.EncodeNil() - return - } - if len(v)%2 == 1 { - e.errorf("mapBySlice requires even slice length, but got %v", len(v)) - return - } - ee.EncodeMapStart(len(v) / 2) - for j, v2 := range v { - if cr != nil { - if j%2 == 0 { - cr.sendContainerState(containerMapKey) - } else { - cr.sendContainerState(containerMapValue) - } - } - ee.EncodeInt(int64(v2)) - } - if cr != nil { - cr.sendContainerState(containerMapEnd) - } -} - func (f *encFnInfo) fastpathEncSliceInt32R(rv reflect.Value) { - if f.ti.mbs { - fastpathTV.EncAsMapSliceInt32V(rv.Interface().([]int32), fastpathCheckNilFalse, f.e) - } else { - fastpathTV.EncSliceInt32V(rv.Interface().([]int32), fastpathCheckNilFalse, f.e) - } + fastpathTV.EncSliceInt32V(rv.Interface().([]int32), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncSliceInt32V(v []int32, checkNil bool, e *Encoder) { ee := e.e @@ -3785,39 +3409,8 @@ func (_ fastpathT) EncSliceInt32V(v []int32, checkNil bool, e *Encoder) { } } -func (_ fastpathT) EncAsMapSliceInt32V(v []int32, checkNil bool, e *Encoder) { - ee := e.e - cr := e.cr - if checkNil && v == nil { - ee.EncodeNil() - return - } - if len(v)%2 == 1 { - e.errorf("mapBySlice requires even slice length, but got %v", len(v)) - return - } - ee.EncodeMapStart(len(v) / 2) - for j, v2 := range v { - if cr != nil { - if j%2 == 0 { - cr.sendContainerState(containerMapKey) - } else { - cr.sendContainerState(containerMapValue) - } - } - ee.EncodeInt(int64(v2)) - } - if cr != nil { - cr.sendContainerState(containerMapEnd) - } -} - func (f *encFnInfo) fastpathEncSliceInt64R(rv reflect.Value) { - if f.ti.mbs { - fastpathTV.EncAsMapSliceInt64V(rv.Interface().([]int64), fastpathCheckNilFalse, f.e) - } else { - fastpathTV.EncSliceInt64V(rv.Interface().([]int64), fastpathCheckNilFalse, f.e) - } + fastpathTV.EncSliceInt64V(rv.Interface().([]int64), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncSliceInt64V(v []int64, checkNil bool, e *Encoder) { ee := e.e @@ -3838,39 +3431,8 @@ func (_ fastpathT) EncSliceInt64V(v []int64, checkNil bool, e *Encoder) { } } -func (_ fastpathT) EncAsMapSliceInt64V(v []int64, checkNil bool, e *Encoder) { - ee := e.e - cr := e.cr - if checkNil && v == nil { - ee.EncodeNil() - return - } - if len(v)%2 == 1 { - e.errorf("mapBySlice requires even slice length, but got %v", len(v)) - return - } - ee.EncodeMapStart(len(v) / 2) - for j, v2 := range v { - if cr != nil { - if j%2 == 0 { - cr.sendContainerState(containerMapKey) - } else { - cr.sendContainerState(containerMapValue) - } - } - ee.EncodeInt(int64(v2)) - } - if cr != nil { - cr.sendContainerState(containerMapEnd) - } -} - func (f *encFnInfo) fastpathEncSliceBoolR(rv reflect.Value) { - if f.ti.mbs { - fastpathTV.EncAsMapSliceBoolV(rv.Interface().([]bool), fastpathCheckNilFalse, f.e) - } else { - fastpathTV.EncSliceBoolV(rv.Interface().([]bool), fastpathCheckNilFalse, f.e) - } + fastpathTV.EncSliceBoolV(rv.Interface().([]bool), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncSliceBoolV(v []bool, checkNil bool, e *Encoder) { ee := e.e @@ -3891,33 +3453,6 @@ func (_ fastpathT) EncSliceBoolV(v []bool, checkNil bool, e *Encoder) { } } -func (_ fastpathT) EncAsMapSliceBoolV(v []bool, checkNil bool, e *Encoder) { - ee := e.e - cr := e.cr - if checkNil && v == nil { - ee.EncodeNil() - return - } - if len(v)%2 == 1 { - e.errorf("mapBySlice requires even slice length, but got %v", len(v)) - return - } - ee.EncodeMapStart(len(v) / 2) - for j, v2 := range v { - if cr != nil { - if j%2 == 0 { - cr.sendContainerState(containerMapKey) - } else { - cr.sendContainerState(containerMapValue) - } - } - ee.EncodeBool(v2) - } - if cr != nil { - cr.sendContainerState(containerMapEnd) - } -} - func (f *encFnInfo) fastpathEncMapIntfIntfR(rv reflect.Value) { fastpathTV.EncMapIntfIntfV(rv.Interface().(map[interface{}]interface{}), fastpathCheckNilFalse, f.e) } @@ -18177,7 +17712,7 @@ func (_ fastpathT) DecSliceIntfV(v []interface{}, checkNil bool, canChange bool, changed = true } slh.End() - return v, changed + return } if containerLenS > 0 { @@ -18236,7 +17771,7 @@ func (_ fastpathT) DecSliceIntfV(v []interface{}, checkNil bool, canChange bool, changed = true } slh.End() - return v, changed + return } if cap(v) == 0 { v = make([]interface{}, 1, 4) @@ -18311,7 +17846,7 @@ func (_ fastpathT) DecSliceStringV(v []string, checkNil bool, canChange bool, d changed = true } slh.End() - return v, changed + return } if containerLenS > 0 { @@ -18370,7 +17905,7 @@ func (_ fastpathT) DecSliceStringV(v []string, checkNil bool, canChange bool, d changed = true } slh.End() - return v, changed + return } if cap(v) == 0 { v = make([]string, 1, 4) @@ -18444,7 +17979,7 @@ func (_ fastpathT) DecSliceFloat32V(v []float32, checkNil bool, canChange bool, changed = true } slh.End() - return v, changed + return } if containerLenS > 0 { @@ -18503,7 +18038,7 @@ func (_ fastpathT) DecSliceFloat32V(v []float32, checkNil bool, canChange bool, changed = true } slh.End() - return v, changed + return } if cap(v) == 0 { v = make([]float32, 1, 4) @@ -18577,7 +18112,7 @@ func (_ fastpathT) DecSliceFloat64V(v []float64, checkNil bool, canChange bool, changed = true } slh.End() - return v, changed + return } if containerLenS > 0 { @@ -18636,7 +18171,7 @@ func (_ fastpathT) DecSliceFloat64V(v []float64, checkNil bool, canChange bool, changed = true } slh.End() - return v, changed + return } if cap(v) == 0 { v = make([]float64, 1, 4) @@ -18710,7 +18245,7 @@ func (_ fastpathT) DecSliceUintV(v []uint, checkNil bool, canChange bool, d *Dec changed = true } slh.End() - return v, changed + return } if containerLenS > 0 { @@ -18769,7 +18304,7 @@ func (_ fastpathT) DecSliceUintV(v []uint, checkNil bool, canChange bool, d *Dec changed = true } slh.End() - return v, changed + return } if cap(v) == 0 { v = make([]uint, 1, 4) @@ -18843,7 +18378,7 @@ func (_ fastpathT) DecSliceUint16V(v []uint16, checkNil bool, canChange bool, d changed = true } slh.End() - return v, changed + return } if containerLenS > 0 { @@ -18902,7 +18437,7 @@ func (_ fastpathT) DecSliceUint16V(v []uint16, checkNil bool, canChange bool, d changed = true } slh.End() - return v, changed + return } if cap(v) == 0 { v = make([]uint16, 1, 4) @@ -18976,7 +18511,7 @@ func (_ fastpathT) DecSliceUint32V(v []uint32, checkNil bool, canChange bool, d changed = true } slh.End() - return v, changed + return } if containerLenS > 0 { @@ -19035,7 +18570,7 @@ func (_ fastpathT) DecSliceUint32V(v []uint32, checkNil bool, canChange bool, d changed = true } slh.End() - return v, changed + return } if cap(v) == 0 { v = make([]uint32, 1, 4) @@ -19109,7 +18644,7 @@ func (_ fastpathT) DecSliceUint64V(v []uint64, checkNil bool, canChange bool, d changed = true } slh.End() - return v, changed + return } if containerLenS > 0 { @@ -19168,7 +18703,7 @@ func (_ fastpathT) DecSliceUint64V(v []uint64, checkNil bool, canChange bool, d changed = true } slh.End() - return v, changed + return } if cap(v) == 0 { v = make([]uint64, 1, 4) @@ -19242,7 +18777,7 @@ func (_ fastpathT) DecSliceUintptrV(v []uintptr, checkNil bool, canChange bool, changed = true } slh.End() - return v, changed + return } if containerLenS > 0 { @@ -19301,7 +18836,7 @@ func (_ fastpathT) DecSliceUintptrV(v []uintptr, checkNil bool, canChange bool, changed = true } slh.End() - return v, changed + return } if cap(v) == 0 { v = make([]uintptr, 1, 4) @@ -19375,7 +18910,7 @@ func (_ fastpathT) DecSliceIntV(v []int, checkNil bool, canChange bool, d *Decod changed = true } slh.End() - return v, changed + return } if containerLenS > 0 { @@ -19434,7 +18969,7 @@ func (_ fastpathT) DecSliceIntV(v []int, checkNil bool, canChange bool, d *Decod changed = true } slh.End() - return v, changed + return } if cap(v) == 0 { v = make([]int, 1, 4) @@ -19508,7 +19043,7 @@ func (_ fastpathT) DecSliceInt8V(v []int8, checkNil bool, canChange bool, d *Dec changed = true } slh.End() - return v, changed + return } if containerLenS > 0 { @@ -19567,7 +19102,7 @@ func (_ fastpathT) DecSliceInt8V(v []int8, checkNil bool, canChange bool, d *Dec changed = true } slh.End() - return v, changed + return } if cap(v) == 0 { v = make([]int8, 1, 4) @@ -19641,7 +19176,7 @@ func (_ fastpathT) DecSliceInt16V(v []int16, checkNil bool, canChange bool, d *D changed = true } slh.End() - return v, changed + return } if containerLenS > 0 { @@ -19700,7 +19235,7 @@ func (_ fastpathT) DecSliceInt16V(v []int16, checkNil bool, canChange bool, d *D changed = true } slh.End() - return v, changed + return } if cap(v) == 0 { v = make([]int16, 1, 4) @@ -19774,7 +19309,7 @@ func (_ fastpathT) DecSliceInt32V(v []int32, checkNil bool, canChange bool, d *D changed = true } slh.End() - return v, changed + return } if containerLenS > 0 { @@ -19833,7 +19368,7 @@ func (_ fastpathT) DecSliceInt32V(v []int32, checkNil bool, canChange bool, d *D changed = true } slh.End() - return v, changed + return } if cap(v) == 0 { v = make([]int32, 1, 4) @@ -19907,7 +19442,7 @@ func (_ fastpathT) DecSliceInt64V(v []int64, checkNil bool, canChange bool, d *D changed = true } slh.End() - return v, changed + return } if containerLenS > 0 { @@ -19966,7 +19501,7 @@ func (_ fastpathT) DecSliceInt64V(v []int64, checkNil bool, canChange bool, d *D changed = true } slh.End() - return v, changed + return } if cap(v) == 0 { v = make([]int64, 1, 4) @@ -20040,7 +19575,7 @@ func (_ fastpathT) DecSliceBoolV(v []bool, checkNil bool, canChange bool, d *Dec changed = true } slh.End() - return v, changed + return } if containerLenS > 0 { @@ -20099,7 +19634,7 @@ func (_ fastpathT) DecSliceBoolV(v []bool, checkNil bool, canChange bool, d *Dec changed = true } slh.End() - return v, changed + return } if cap(v) == 0 { v = make([]bool, 1, 4) diff --git a/vendor/github.com/ugorji/go/codec/fast-path.go.tmpl b/vendor/github.com/ugorji/go/codec/fast-path.go.tmpl index 04c173fbaaa..58cc6df4c54 100644 --- a/vendor/github.com/ugorji/go/codec/fast-path.go.tmpl +++ b/vendor/github.com/ugorji/go/codec/fast-path.go.tmpl @@ -165,11 +165,7 @@ func fastpathEncodeTypeSwitchMap(iv interface{}, e *Encoder) bool { {{range .Values}}{{if not .Primitive}}{{if not .MapKey }} func (f *encFnInfo) {{ .MethodNamePfx "fastpathEnc" false }}R(rv reflect.Value) { - if f.ti.mbs { - fastpathTV.{{ .MethodNamePfx "EncAsMap" false }}V(rv.Interface().([]{{ .Elem }}), fastpathCheckNilFalse, f.e) - } else { - fastpathTV.{{ .MethodNamePfx "Enc" false }}V(rv.Interface().([]{{ .Elem }}), fastpathCheckNilFalse, f.e) - } + fastpathTV.{{ .MethodNamePfx "Enc" false }}V(rv.Interface().([]{{ .Elem }}), fastpathCheckNilFalse, f.e) } func (_ fastpathT) {{ .MethodNamePfx "Enc" false }}V(v []{{ .Elem }}, checkNil bool, e *Encoder) { ee := e.e @@ -186,31 +182,6 @@ func (_ fastpathT) {{ .MethodNamePfx "Enc" false }}V(v []{{ .Elem }}, checkNil b if cr != nil { cr.sendContainerState(containerArrayEnd) }{{/* ee.EncodeEnd() */}} } -func (_ fastpathT) {{ .MethodNamePfx "EncAsMap" false }}V(v []{{ .Elem }}, checkNil bool, e *Encoder) { - ee := e.e - cr := e.cr - if checkNil && v == nil { - ee.EncodeNil() - return - } - if len(v)%2 == 1 { - e.errorf("mapBySlice requires even slice length, but got %v", len(v)) - return - } - ee.EncodeMapStart(len(v) / 2) - for j, v2 := range v { - if cr != nil { - if j%2 == 0 { - cr.sendContainerState(containerMapKey) - } else { - cr.sendContainerState(containerMapValue) - } - } - {{ encmd .Elem "v2"}} - } - if cr != nil { cr.sendContainerState(containerMapEnd) } -} - {{end}}{{end}}{{end}} {{range .Values}}{{if not .Primitive}}{{if .MapKey }} @@ -357,7 +328,7 @@ func (_ fastpathT) {{ .MethodNamePfx "Dec" false }}V(v []{{ .Elem }}, checkNil b changed = true } slh.End() - return v, changed + return } if containerLenS > 0 { @@ -420,7 +391,7 @@ func (_ fastpathT) {{ .MethodNamePfx "Dec" false }}V(v []{{ .Elem }}, checkNil b changed = true } slh.End() - return v, changed + return } if cap(v) == 0 { v = make([]{{ .Elem }}, 1, 4) diff --git a/vendor/github.com/ugorji/go/codec/gen-dec-array.go.tmpl b/vendor/github.com/ugorji/go/codec/gen-dec-array.go.tmpl index 32df54144ca..2caae5bfdaf 100644 --- a/vendor/github.com/ugorji/go/codec/gen-dec-array.go.tmpl +++ b/vendor/github.com/ugorji/go/codec/gen-dec-array.go.tmpl @@ -1,7 +1,6 @@ {{var "v"}} := {{if not isArray}}*{{end}}{{ .Varname }} -{{var "h"}}, {{var "l"}} := z.DecSliceHelperStart() {{/* // helper, containerLenS */}}{{if not isArray}} +{{var "h"}}, {{var "l"}} := z.DecSliceHelperStart() {{/* // helper, containerLenS */}} var {{var "c"}} bool {{/* // changed */}} -_ = {{var "c"}}{{end}} if {{var "l"}} == 0 { {{if isSlice }}if {{var "v"}} == nil { {{var "v"}} = []{{ .Typ }}{} @@ -27,8 +26,6 @@ if {{var "l"}} == 0 { } {{ else }} var {{var "rr"}}, {{var "rl"}} int {{/* // num2read, length of slice/array/chan */}} var {{var "rt"}} bool {{/* truncated */}} - _, _ = {{var "rl"}}, {{var "rt"}} - {{var "rr"}} = {{var "l"}} // len({{var "v"}}) if {{var "l"}} > cap({{var "v"}}) { {{if isArray }}z.DecArrayCannotExpand(len({{var "v"}}), {{var "l"}}) {{ else }}{{if not .Immutable }} diff --git a/vendor/github.com/ugorji/go/codec/gen.generated.go b/vendor/github.com/ugorji/go/codec/gen.generated.go index 2ace97b78cd..fb6f4b80974 100644 --- a/vendor/github.com/ugorji/go/codec/gen.generated.go +++ b/vendor/github.com/ugorji/go/codec/gen.generated.go @@ -68,9 +68,8 @@ z.DecSendContainerState(codecSelfer_containerMapEnd{{ .Sfx }}) const genDecListTmpl = ` {{var "v"}} := {{if not isArray}}*{{end}}{{ .Varname }} -{{var "h"}}, {{var "l"}} := z.DecSliceHelperStart() {{/* // helper, containerLenS */}}{{if not isArray}} +{{var "h"}}, {{var "l"}} := z.DecSliceHelperStart() {{/* // helper, containerLenS */}} var {{var "c"}} bool {{/* // changed */}} -_ = {{var "c"}}{{end}} if {{var "l"}} == 0 { {{if isSlice }}if {{var "v"}} == nil { {{var "v"}} = []{{ .Typ }}{} @@ -96,8 +95,6 @@ if {{var "l"}} == 0 { } {{ else }} var {{var "rr"}}, {{var "rl"}} int {{/* // num2read, length of slice/array/chan */}} var {{var "rt"}} bool {{/* truncated */}} - _, _ = {{var "rl"}}, {{var "rt"}} - {{var "rr"}} = {{var "l"}} // len({{var "v"}}) if {{var "l"}} > cap({{var "v"}}) { {{if isArray }}z.DecArrayCannotExpand(len({{var "v"}}), {{var "l"}}) {{ else }}{{if not .Immutable }} diff --git a/vendor/github.com/ugorji/go/codec/gen.go b/vendor/github.com/ugorji/go/codec/gen.go index ffc5aecf6c6..a075e7c0d62 100644 --- a/vendor/github.com/ugorji/go/codec/gen.go +++ b/vendor/github.com/ugorji/go/codec/gen.go @@ -21,8 +21,6 @@ import ( "sync" "text/template" "time" - "unicode" - "unicode/utf8" ) // --------------------------------------------------- @@ -268,7 +266,6 @@ func Gen(w io.Writer, buildTags, pkgName, uid string, useUnsafe bool, ti *TypeIn x.line("type " + x.hn + " struct{}") x.line("") - x.varsfxreset() x.line("func init() {") x.linef("if %sGenVersion != %v {", x.cpfx, GenVersion) x.line("_, file, _, _ := runtime.Caller(0)") @@ -312,7 +309,6 @@ func Gen(w io.Writer, buildTags, pkgName, uid string, useUnsafe bool, ti *TypeIn for _, t := range x.ts { rtid := reflect.ValueOf(t).Pointer() // generate enc functions for all these slice/map types. - x.varsfxreset() x.linef("func (x %s) enc%s(v %s%s, e *%sEncoder) {", x.hn, x.genMethodNameT(t), x.arr2str(t, "*"), x.genTypeName(t), x.cpfx) x.genRequiredMethodVars(true) switch t.Kind() { @@ -327,7 +323,6 @@ func Gen(w io.Writer, buildTags, pkgName, uid string, useUnsafe bool, ti *TypeIn x.line("") // generate dec functions for all these slice/map types. - x.varsfxreset() x.linef("func (x %s) dec%s(v *%s, d *%sDecoder) {", x.hn, x.genMethodNameT(t), x.genTypeName(t), x.cpfx) x.genRequiredMethodVars(false) switch t.Kind() { @@ -382,7 +377,7 @@ func (x *genRunner) genRefPkgs(t reflect.Type) { x.imn[tpkg] = tpkg } else { x.imc++ - x.imn[tpkg] = "pkg" + strconv.FormatUint(x.imc, 10) + "_" + genGoIdentifier(tpkg[idx+1:], false) + x.imn[tpkg] = "pkg" + strconv.FormatUint(x.imc, 10) + "_" + tpkg[idx+1:] } } } @@ -413,10 +408,6 @@ func (x *genRunner) varsfx() string { return strconv.FormatUint(x.c, 10) } -func (x *genRunner) varsfxreset() { - x.c = 0 -} - func (x *genRunner) out(s string) { if _, err := io.WriteString(x.w, s); err != nil { panic(err) @@ -503,7 +494,6 @@ func (x *genRunner) selfer(encode bool) { // always make decode use a pointer receiver, // and structs always use a ptr receiver (encode|decode) isptr := !encode || t.Kind() == reflect.Struct - x.varsfxreset() fnSigPfx := "func (x " if isptr { fnSigPfx += "*" @@ -576,28 +566,9 @@ func (x *genRunner) xtraSM(varname string, encode bool, t reflect.Type) { } else { x.linef("h.dec%s((*%s)(%s), d)", x.genMethodNameT(t), x.genTypeName(t), varname) } - x.registerXtraT(t) -} - -func (x *genRunner) registerXtraT(t reflect.Type) { - // recursively register the types - if _, ok := x.tm[t]; ok { - return - } - var tkey reflect.Type - switch t.Kind() { - case reflect.Chan, reflect.Slice, reflect.Array: - case reflect.Map: - tkey = t.Key() - default: - return - } - x.tm[t] = struct{}{} - x.ts = append(x.ts, t) - // check if this refers to any xtra types eg. a slice of array: add the array - x.registerXtraT(t.Elem()) - if tkey != nil { - x.registerXtraT(tkey) + if _, ok := x.tm[t]; !ok { + x.tm[t] = struct{}{} + x.ts = append(x.ts, t) } } @@ -637,33 +608,22 @@ func (x *genRunner) encVar(varname string, t reflect.Type) { } -// enc will encode a variable (varname) of type t, -// except t is of kind reflect.Struct or reflect.Array, wherein varname is of type ptrTo(T) (to prevent copying) +// enc will encode a variable (varname) of type T, +// except t is of kind reflect.Struct or reflect.Array, wherein varname is of type *T (to prevent copying) func (x *genRunner) enc(varname string, t reflect.Type) { + // varName here must be to a pointer to a struct/array, or to a value directly. rtid := reflect.ValueOf(t).Pointer() // We call CodecEncodeSelf if one of the following are honored: // - the type already implements Selfer, call that // - the type has a Selfer implementation just created, use that // - the type is in the list of the ones we will generate for, but it is not currently being generated - mi := x.varsfx() tptr := reflect.PtrTo(t) tk := t.Kind() if x.checkForSelfer(t, varname) { - if tk == reflect.Array || tk == reflect.Struct { // varname is of type *T - if tptr.Implements(selferTyp) || t.Implements(selferTyp) { - x.line(varname + ".CodecEncodeSelf(e)") - return - } - } else { // varname is of type T - if t.Implements(selferTyp) { - x.line(varname + ".CodecEncodeSelf(e)") - return - } else if tptr.Implements(selferTyp) { - x.linef("%ssf%s := &%s", genTempVarPfx, mi, varname) - x.linef("%ssf%s.CodecEncodeSelf(e)", genTempVarPfx, mi) - return - } + if t.Implements(selferTyp) || (tptr.Implements(selferTyp) && (tk == reflect.Array || tk == reflect.Struct)) { + x.line(varname + ".CodecEncodeSelf(e)") + return } if _, ok := x.te[rtid]; ok { @@ -693,6 +653,7 @@ func (x *genRunner) enc(varname string, t reflect.Type) { // check if // - type is RawExt // - the type implements (Text|JSON|Binary)(Unm|M)arshal + mi := x.varsfx() x.linef("%sm%s := z.EncBinary()", genTempVarPfx, mi) x.linef("_ = %sm%s", genTempVarPfx, mi) x.line("if false {") //start if block @@ -715,31 +676,15 @@ func (x *genRunner) enc(varname string, t reflect.Type) { // first check if extensions are configued, before doing the interface conversion x.linef("} else if z.HasExtensions() && z.EncExt(%s) {", varname) } - if tk == reflect.Array || tk == reflect.Struct { // varname is of type *T - if t.Implements(binaryMarshalerTyp) || tptr.Implements(binaryMarshalerTyp) { - x.linef("} else if %sm%s { z.EncBinaryMarshal(%v) ", genTempVarPfx, mi, varname) - } - if t.Implements(jsonMarshalerTyp) || tptr.Implements(jsonMarshalerTyp) { - x.linef("} else if !%sm%s && z.IsJSONHandle() { z.EncJSONMarshal(%v) ", genTempVarPfx, mi, varname) - } else if t.Implements(textMarshalerTyp) || tptr.Implements(textMarshalerTyp) { - x.linef("} else if !%sm%s { z.EncTextMarshal(%v) ", genTempVarPfx, mi, varname) - } - } else { // varname is of type T - if t.Implements(binaryMarshalerTyp) { - x.linef("} else if %sm%s { z.EncBinaryMarshal(%v) ", genTempVarPfx, mi, varname) - } else if tptr.Implements(binaryMarshalerTyp) { - x.linef("} else if %sm%s { z.EncBinaryMarshal(&%v) ", genTempVarPfx, mi, varname) - } - if t.Implements(jsonMarshalerTyp) { - x.linef("} else if !%sm%s && z.IsJSONHandle() { z.EncJSONMarshal(%v) ", genTempVarPfx, mi, varname) - } else if tptr.Implements(jsonMarshalerTyp) { - x.linef("} else if !%sm%s && z.IsJSONHandle() { z.EncJSONMarshal(&%v) ", genTempVarPfx, mi, varname) - } else if t.Implements(textMarshalerTyp) { - x.linef("} else if !%sm%s { z.EncTextMarshal(%v) ", genTempVarPfx, mi, varname) - } else if tptr.Implements(textMarshalerTyp) { - x.linef("} else if !%sm%s { z.EncTextMarshal(&%v) ", genTempVarPfx, mi, varname) - } + if t.Implements(binaryMarshalerTyp) || tptr.Implements(binaryMarshalerTyp) { + x.linef("} else if %sm%s { z.EncBinaryMarshal(%v) ", genTempVarPfx, mi, varname) } + if t.Implements(jsonMarshalerTyp) || tptr.Implements(jsonMarshalerTyp) { + x.linef("} else if !%sm%s && z.IsJSONHandle() { z.EncJSONMarshal(%v) ", genTempVarPfx, mi, varname) + } else if t.Implements(textMarshalerTyp) || tptr.Implements(textMarshalerTyp) { + x.linef("} else if !%sm%s { z.EncTextMarshal(%v) ", genTempVarPfx, mi, varname) + } + x.line("} else {") switch t.Kind() { @@ -1075,8 +1020,6 @@ func (x *genRunner) decVar(varname string, t reflect.Type, canBeNil bool) { } } -// dec will decode a variable (varname) of type ptrTo(t). -// t is always a basetype (i.e. not of kind reflect.Ptr). func (x *genRunner) dec(varname string, t reflect.Type) { // assumptions: // - the varname is to a pointer already. No need to take address of it @@ -1649,26 +1592,6 @@ func genImportPath(t reflect.Type) (s string) { return } -// A go identifier is (letter|_)[letter|number|_]* -func genGoIdentifier(s string, checkFirstChar bool) string { - b := make([]byte, 0, len(s)) - t := make([]byte, 4) - var n int - for i, r := range s { - if checkFirstChar && i == 0 && !unicode.IsLetter(r) { - b = append(b, '_') - } - // r must be unicode_letter, unicode_digit or _ - if unicode.IsLetter(r) || unicode.IsDigit(r) { - n = utf8.EncodeRune(t, r) - b = append(b, t[:n]...) - } else { - b = append(b, '_') - } - } - return string(b) -} - func genNonPtr(t reflect.Type) reflect.Type { for t.Kind() == reflect.Ptr { t = t.Elem() diff --git a/vendor/github.com/ugorji/go/codec/helper.go b/vendor/github.com/ugorji/go/codec/helper.go index 40065a01c8b..560014ae393 100644 --- a/vendor/github.com/ugorji/go/codec/helper.go +++ b/vendor/github.com/ugorji/go/codec/helper.go @@ -155,10 +155,8 @@ const ( resetSliceElemToZeroValue bool = false ) -var ( - oneByteArr = [1]byte{0} - zeroByteSlice = oneByteArr[:0:0] -) +var oneByteArr = [1]byte{0} +var zeroByteSlice = oneByteArr[:0:0] type charEncoding uint8 @@ -217,24 +215,6 @@ const ( containerArrayEnd ) -type rgetPoolT struct { - encNames [8]string - fNames [8]string - etypes [8]uintptr - sfis [8]*structFieldInfo -} - -var rgetPool = sync.Pool{ - New: func() interface{} { return new(rgetPoolT) }, -} - -type rgetT struct { - fNames []string - encNames []string - etypes []uintptr - sfis []*structFieldInfo -} - type containerStateRecv interface { sendContainerState(containerState) } @@ -853,17 +833,14 @@ func (x *TypeInfos) get(rtid uintptr, rt reflect.Type) (pti *typeInfo) { siInfo = parseStructFieldInfo(structInfoFieldName, x.structTag(f.Tag)) ti.toArray = siInfo.toArray } - pi := rgetPool.Get() - pv := pi.(*rgetPoolT) - pv.etypes[0] = ti.baseId - vv := rgetT{pv.fNames[:0], pv.encNames[:0], pv.etypes[:1], pv.sfis[:0]} - x.rget(rt, rtid, nil, &vv, siInfo) - ti.sfip = make([]*structFieldInfo, len(vv.sfis)) - ti.sfi = make([]*structFieldInfo, len(vv.sfis)) - copy(ti.sfip, vv.sfis) - sort.Sort(sfiSortedByEncName(vv.sfis)) - copy(ti.sfi, vv.sfis) - rgetPool.Put(pi) + sfip := make([]*structFieldInfo, 0, rt.NumField()) + x.rget(rt, nil, make(map[string]bool, 16), &sfip, siInfo) + + ti.sfip = make([]*structFieldInfo, len(sfip)) + ti.sfi = make([]*structFieldInfo, len(sfip)) + copy(ti.sfip, sfip) + sort.Sort(sfiSortedByEncName(sfip)) + copy(ti.sfi, sfip) } // sfi = sfip @@ -876,37 +853,16 @@ func (x *TypeInfos) get(rtid uintptr, rt reflect.Type) (pti *typeInfo) { return } -func (x *TypeInfos) rget(rt reflect.Type, rtid uintptr, - indexstack []int, pv *rgetT, siInfo *structFieldInfo, +func (x *TypeInfos) rget(rt reflect.Type, indexstack []int, fnameToHastag map[string]bool, + sfi *[]*structFieldInfo, siInfo *structFieldInfo, ) { - // This will read up the fields and store how to access the value. - // It uses the go language's rules for embedding, as below: - // - if a field has been seen while traversing, skip it - // - if an encName has been seen while traversing, skip it - // - if an embedded type has been seen, skip it - // - // Also, per Go's rules, embedded fields must be analyzed AFTER all top-level fields. - // - // Note: we consciously use slices, not a map, to simulate a set. - // Typically, types have < 16 fields, and iteration using equals is faster than maps there - - type anonField struct { - ft reflect.Type - idx int - } - - var anonFields []anonField - -LOOP: - for j, jlen := 0, rt.NumField(); j < jlen; j++ { + for j := 0; j < rt.NumField(); j++ { f := rt.Field(j) fkind := f.Type.Kind() // skip if a func type, or is unexported, or structTag value == "-" - switch fkind { - case reflect.Func, reflect.Complex64, reflect.Complex128, reflect.UnsafePointer: - continue LOOP + if fkind == reflect.Func { + continue } - // if r1, _ := utf8.DecodeRuneInString(f.Name); r1 == utf8.RuneError || !unicode.IsUpper(r1) { if f.PkgPath != "" && !f.Anonymous { // unexported, not embedded continue @@ -930,8 +886,11 @@ LOOP: ft = ft.Elem() } if ft.Kind() == reflect.Struct { - // handle anonymous fields after handling all the non-anon fields - anonFields = append(anonFields, anonField{ft, j}) + indexstack2 := make([]int, len(indexstack)+1, len(indexstack)+4) + copy(indexstack2, indexstack) + indexstack2[len(indexstack)] = j + // indexstack2 := append(append(make([]int, 0, len(indexstack)+4), indexstack...), j) + x.rget(ft, indexstack2, fnameToHastag, sfi, siInfo) continue } } @@ -942,39 +901,26 @@ LOOP: continue } + // do not let fields with same name in embedded structs override field at higher level. + // this must be done after anonymous check, to allow anonymous field + // still include their child fields + if _, ok := fnameToHastag[f.Name]; ok { + continue + } if f.Name == "" { panic(noFieldNameToStructFieldInfoErr) } - - for _, k := range pv.fNames { - if k == f.Name { - continue LOOP - } - } - pv.fNames = append(pv.fNames, f.Name) - if si == nil { si = parseStructFieldInfo(f.Name, stag) } else if si.encName == "" { si.encName = f.Name } - - for _, k := range pv.encNames { - if k == si.encName { - continue LOOP - } - } - pv.encNames = append(pv.encNames, si.encName) - // si.ikind = int(f.Type.Kind()) if len(indexstack) == 0 { si.i = int16(j) } else { si.i = -1 - si.is = make([]int, len(indexstack)+1) - copy(si.is, indexstack) - si.is[len(indexstack)] = j - // si.is = append(append(make([]int, 0, len(indexstack)+4), indexstack...), j) + si.is = append(append(make([]int, 0, len(indexstack)+4), indexstack...), j) } if siInfo != nil { @@ -982,26 +928,8 @@ LOOP: si.omitEmpty = true } } - pv.sfis = append(pv.sfis, si) - } - - // now handle anonymous fields -LOOP2: - for _, af := range anonFields { - // if etypes contains this, then do not call rget again (as the fields are already seen here) - ftid := reflect.ValueOf(af.ft).Pointer() - for _, k := range pv.etypes { - if k == ftid { - continue LOOP2 - } - } - pv.etypes = append(pv.etypes, ftid) - - indexstack2 := make([]int, len(indexstack)+1) - copy(indexstack2, indexstack) - indexstack2[len(indexstack)] = af.idx - // indexstack2 := append(append(make([]int, 0, len(indexstack)+4), indexstack...), j) - x.rget(af.ft, ftid, indexstack2, pv, siInfo) + *sfi = append(*sfi, si) + fnameToHastag[f.Name] = stag != "" } } @@ -1199,73 +1127,3 @@ type bytesISlice []bytesI func (p bytesISlice) Len() int { return len(p) } func (p bytesISlice) Less(i, j int) bool { return bytes.Compare(p[i].v, p[j].v) == -1 } func (p bytesISlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] } - -// ----------------- - -type set []uintptr - -func (s *set) add(v uintptr) (exists bool) { - // e.ci is always nil, or len >= 1 - // defer func() { fmt.Printf("$$$$$$$$$$$ cirRef Add: %v, exists: %v\n", v, exists) }() - x := *s - if x == nil { - x = make([]uintptr, 1, 8) - x[0] = v - *s = x - return - } - // typically, length will be 1. make this perform. - if len(x) == 1 { - if j := x[0]; j == 0 { - x[0] = v - } else if j == v { - exists = true - } else { - x = append(x, v) - *s = x - } - return - } - // check if it exists - for _, j := range x { - if j == v { - exists = true - return - } - } - // try to replace a "deleted" slot - for i, j := range x { - if j == 0 { - x[i] = v - return - } - } - // if unable to replace deleted slot, just append it. - x = append(x, v) - *s = x - return -} - -func (s *set) remove(v uintptr) (exists bool) { - // defer func() { fmt.Printf("$$$$$$$$$$$ cirRef Rm: %v, exists: %v\n", v, exists) }() - x := *s - if len(x) == 0 { - return - } - if len(x) == 1 { - if x[0] == v { - x[0] = 0 - } - return - } - for i, j := range x { - if j == v { - exists = true - x[i] = 0 // set it to 0, as way to delete it. - // copy(x[i:], x[i+1:]) - // x = x[:len(x)-1] - return - } - } - return -} diff --git a/vendor/github.com/ugorji/go/codec/json.go b/vendor/github.com/ugorji/go/codec/json.go index a04dfcb9d3a..a18a5f7063e 100644 --- a/vendor/github.com/ugorji/go/codec/json.go +++ b/vendor/github.com/ugorji/go/codec/json.go @@ -43,23 +43,18 @@ import ( //-------------------------------- -var ( - jsonLiterals = [...]byte{'t', 'r', 'u', 'e', 'f', 'a', 'l', 's', 'e', 'n', 'u', 'l', 'l'} +var jsonLiterals = [...]byte{'t', 'r', 'u', 'e', 'f', 'a', 'l', 's', 'e', 'n', 'u', 'l', 'l'} - jsonFloat64Pow10 = [...]float64{ - 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, - 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, - 1e20, 1e21, 1e22, - } +var jsonFloat64Pow10 = [...]float64{ + 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, + 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, + 1e20, 1e21, 1e22, +} - jsonUint64Pow10 = [...]uint64{ - 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, - 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, - } - - // jsonTabs and jsonSpaces are used as caches for indents - jsonTabs, jsonSpaces string -) +var jsonUint64Pow10 = [...]uint64{ + 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, + 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, +} const ( // jsonUnreadAfterDecNum controls whether we unread after decoding a number. @@ -90,23 +85,8 @@ const ( jsonNumUintMaxVal = 1< 1<<53 || v < -(1<<53)) { - e.w.writen1('"') - e.w.writeb(strconv.AppendInt(e.b[:0], v, 10)) - e.w.writen1('"') - return - } e.w.writeb(strconv.AppendInt(e.b[:0], v, 10)) } func (e *jsonEncDriver) EncodeUint(v uint64) { - if x := e.h.IntegerAsString; x == 'A' || x == 'L' && v > 1<<53 { - e.w.writen1('"') - e.w.writeb(strconv.AppendUint(e.b[:0], v, 10)) - e.w.writen1('"') - return - } e.w.writeb(strconv.AppendUint(e.b[:0], v, 10)) } @@ -243,17 +165,11 @@ func (e *jsonEncDriver) EncodeRawExt(re *RawExt, en *Encoder) { } func (e *jsonEncDriver) EncodeArrayStart(length int) { - if e.d { - e.dl++ - } e.w.writen1('[') e.c = containerArrayStart } func (e *jsonEncDriver) EncodeMapStart(length int) { - if e.d { - e.dl++ - } e.w.writen1('{') e.c = containerMapStart } @@ -648,11 +564,6 @@ func (d *jsonDecDriver) decNum(storeBytes bool) { d.tok = b } b := d.tok - var str bool - if b == '"' { - str = true - b = d.r.readn1() - } if !(b == '+' || b == '-' || b == '.' || (b >= '0' && b <= '9')) { d.d.errorf("json: decNum: got first char '%c'", b) return @@ -667,10 +578,6 @@ func (d *jsonDecDriver) decNum(storeBytes bool) { n.reset() d.bs = d.bs[:0] - if str && storeBytes { - d.bs = append(d.bs, '"') - } - // The format of a number is as below: // parsing: sign? digit* dot? digit* e? sign? digit* // states: 0 1* 2 3* 4 5* 6 7 @@ -761,14 +668,6 @@ LOOP: default: break LOOP } - case '"': - if str { - if storeBytes { - d.bs = append(d.bs, '"') - } - b, eof = r.readn1eof() - } - break LOOP default: break LOOP } @@ -1134,24 +1033,6 @@ type JsonHandle struct { // RawBytesExt, if configured, is used to encode and decode raw bytes in a custom way. // If not configured, raw bytes are encoded to/from base64 text. RawBytesExt InterfaceExt - - // Indent indicates how a value is encoded. - // - If positive, indent by that number of spaces. - // - If negative, indent by that number of tabs. - Indent int8 - - // IntegerAsString controls how integers (signed and unsigned) are encoded. - // - // Per the JSON Spec, JSON numbers are 64-bit floating point numbers. - // Consequently, integers > 2^53 cannot be represented as a JSON number without losing precision. - // This can be mitigated by configuring how to encode integers. - // - // IntegerAsString interpretes the following values: - // - if 'L', then encode integers > 2^53 as a json string. - // - if 'A', then encode all integers as a json string - // containing the exact integer representation as a decimal. - // - else encode all integers as a json number (default) - IntegerAsString uint8 } func (h *JsonHandle) SetInterfaceExt(rt reflect.Type, tag uint64, ext InterfaceExt) (err error) { @@ -1159,48 +1040,26 @@ func (h *JsonHandle) SetInterfaceExt(rt reflect.Type, tag uint64, ext InterfaceE } func (h *JsonHandle) newEncDriver(e *Encoder) encDriver { - hd := jsonEncDriver{e: e, h: h} + hd := jsonEncDriver{e: e, w: e.w, h: h} hd.bs = hd.b[:0] - - hd.reset() - + hd.se.i = h.RawBytesExt return &hd } func (h *JsonHandle) newDecDriver(d *Decoder) decDriver { // d := jsonDecDriver{r: r.(*bytesDecReader), h: h} - hd := jsonDecDriver{d: d, h: h} + hd := jsonDecDriver{d: d, r: d.r, h: h} hd.bs = hd.b[:0] - hd.reset() + hd.se.i = h.RawBytesExt return &hd } func (e *jsonEncDriver) reset() { e.w = e.e.w - e.se.i = e.h.RawBytesExt - if e.bs != nil { - e.bs = e.bs[:0] - } - e.d, e.dt, e.dl, e.ds = false, false, 0, "" - e.c = 0 - if e.h.Indent > 0 { - e.d = true - e.ds = jsonSpaces[:e.h.Indent] - } else if e.h.Indent < 0 { - e.d = true - e.dt = true - e.ds = jsonTabs[:-(e.h.Indent)] - } } func (d *jsonDecDriver) reset() { d.r = d.d.r - d.se.i = d.h.RawBytesExt - if d.bs != nil { - d.bs = d.bs[:0] - } - d.c, d.tok = 0, 0 - d.n.reset() } var jsonEncodeTerminate = []byte{' '} diff --git a/vendor/github.com/ugorji/go/codec/msgpack.go b/vendor/github.com/ugorji/go/codec/msgpack.go index f9f87236277..5eb4c96368c 100644 --- a/vendor/github.com/ugorji/go/codec/msgpack.go +++ b/vendor/github.com/ugorji/go/codec/msgpack.go @@ -374,7 +374,7 @@ func (d *msgpackDecDriver) DecodeNaked() { } if n.v == valueTypeUint && d.h.SignedInteger { n.v = valueTypeInt - n.i = int64(n.u) + n.i = int64(n.v) } return } @@ -729,7 +729,6 @@ func (e *msgpackEncDriver) reset() { func (d *msgpackDecDriver) reset() { d.r = d.d.r - d.bd, d.bdRead = 0, false } //-------------------------------------------------- diff --git a/vendor/github.com/ugorji/go/codec/prebuild.sh b/vendor/github.com/ugorji/go/codec/prebuild.sh index 909f4bb0f24..98f442487a7 100755 --- a/vendor/github.com/ugorji/go/codec/prebuild.sh +++ b/vendor/github.com/ugorji/go/codec/prebuild.sh @@ -171,7 +171,7 @@ do 'xf') zforce=1;; 'xb') zbak=1;; 'xx') zexternal=1;; - *) echo "prebuild.sh accepts [-fbx] only"; return 1;; + *) echo "prebuild.sh accepts [-fb] only"; return 1;; esac done shift $((OPTIND-1)) diff --git a/vendor/github.com/ugorji/go/codec/simple.go b/vendor/github.com/ugorji/go/codec/simple.go index 7c0ba7affc7..c1504965095 100644 --- a/vendor/github.com/ugorji/go/codec/simple.go +++ b/vendor/github.com/ugorji/go/codec/simple.go @@ -512,7 +512,6 @@ func (e *simpleEncDriver) reset() { func (d *simpleDecDriver) reset() { d.r = d.d.r - d.bd, d.bdRead = 0, false } var _ decDriver = (*simpleDecDriver)(nil) diff --git a/vendor/github.com/ugorji/go/codec/test.py b/vendor/github.com/ugorji/go/codec/test.py index c0ad20b34cb..dfe3b0c9a07 100755 --- a/vendor/github.com/ugorji/go/codec/test.py +++ b/vendor/github.com/ugorji/go/codec/test.py @@ -9,8 +9,6 @@ # sudo apt-get install python-pip # pip install --user msgpack-python msgpack-rpc-python cbor -# Ensure all "string" keys are utf strings (else encoded as bytes) - import cbor, msgpack, msgpackrpc, sys, os, threading def get_test_data_list(): @@ -28,39 +26,35 @@ def get_test_data_list(): -3232.0, -6464646464.0, 3232.0, - 6464.0, 6464646464.0, False, True, - u"null", None, u"someday", - 1328176922000002000, u"", - -2206187877999998000, u"bytestring", + 1328176922000002000, + -2206187877999998000, 270, - u"none", -2013855847999995777, #-6795364578871345152, ] l1 = [ { "true": True, "false": False }, - { "true": u"True", + { "true": "True", "false": False, "uint16(1616)": 1616 }, { "list": [1616, 32323232, True, -3232.0, {"TRUE":True, "FALSE":False}, [True, False] ], "int32":32323232, "bool": True, - "LONG STRING": u"123456789012345678901234567890123456789012345678901234567890", - "SHORT STRING": u"1234567890" }, - { True: "true", 138: False, "false": 200 } + "LONG STRING": "123456789012345678901234567890123456789012345678901234567890", + "SHORT STRING": "1234567890" }, + { True: "true", 8: False, "false": 0 } ] l = [] l.extend(l0) l.append(l0) - l.append(1) l.extend(l1) return l diff --git a/vendor/github.com/ugorji/go/codec/tests.sh b/vendor/github.com/ugorji/go/codec/tests.sh index 00857b6209a..b1602ea7e75 100755 --- a/vendor/github.com/ugorji/go/codec/tests.sh +++ b/vendor/github.com/ugorji/go/codec/tests.sh @@ -6,7 +6,6 @@ _run() { # 1. VARIATIONS: regular (t), canonical (c), IO R/W (i), # binc-nosymbols (n), struct2array (s), intern string (e), - # json-indent (d), circular (l) # 2. MODE: reflection (r), external (x), codecgen (g), unsafe (u), notfastpath (f) # 3. OPTIONS: verbose (v), reset (z), must (m), # @@ -17,7 +16,7 @@ _run() { zargs="" local OPTIND OPTIND=1 - while getopts "_xurtcinsvgzmefdl" flag + while getopts "xurtcinsvgzmef" flag do case "x$flag" in 'xr') ;; @@ -28,7 +27,6 @@ _run() { 'xv') zargs="$zargs -tv" ;; 'xz') zargs="$zargs -tr" ;; 'xm') zargs="$zargs -tm" ;; - 'xl') zargs="$zargs -tl" ;; *) ;; esac done @@ -37,19 +35,15 @@ _run() { # echo ">>>>>>> TAGS: $ztags" OPTIND=1 - while getopts "_xurtcinsvgzmefdl" flag + while getopts "xurtcinsvgzmef" flag do case "x$flag" in 'xt') printf ">>>>>>> REGULAR : "; go test "-tags=$ztags" $zargs ; sleep 2 ;; 'xc') printf ">>>>>>> CANONICAL : "; go test "-tags=$ztags" $zargs -tc; sleep 2 ;; 'xi') printf ">>>>>>> I/O : "; go test "-tags=$ztags" $zargs -ti; sleep 2 ;; - 'xn') printf ">>>>>>> NO_SYMBOLS : "; go test "-tags=$ztags" -run=Binc $zargs -tn; sleep 2 ;; + 'xn') printf ">>>>>>> NO_SYMBOLS : "; go test "-tags=$ztags" $zargs -tn; sleep 2 ;; 'xs') printf ">>>>>>> TO_ARRAY : "; go test "-tags=$ztags" $zargs -ts; sleep 2 ;; 'xe') printf ">>>>>>> INTERN : "; go test "-tags=$ztags" $zargs -te; sleep 2 ;; - 'xd') printf ">>>>>>> INDENT : "; - go test "-tags=$ztags" -run=JsonCodecsTable -td=-1 $zargs; - go test "-tags=$ztags" -run=JsonCodecsTable -td=8 $zargs; - sleep 2 ;; *) ;; esac done @@ -61,20 +55,20 @@ _run() { # echo ">>>>>>> RUNNING VARIATIONS OF TESTS" if [[ "x$@" = "x" ]]; then # All: r, x, g, gu - _run "-_tcinsed_ml" # regular - _run "-_tcinsed_ml_z" # regular with reset - _run "-_tcinsed_ml_f" # regular with no fastpath (notfastpath) - _run "-x_tcinsed_ml" # external - _run "-gx_tcinsed_ml" # codecgen: requires external - _run "-gxu_tcinsed_ml" # codecgen + unsafe + _run "-rtcinsm" # regular + _run "-rtcinsmz" # regular with reset + _run "-rtcinsmf" # regular with no fastpath (notfastpath) + _run "-xtcinsm" # external + _run "-gxtcinsm" # codecgen: requires external + _run "-gxutcinsm" # codecgen + unsafe elif [[ "x$@" = "x-Z" ]]; then # Regular - _run "-_tcinsed_ml" # regular - _run "-_tcinsed_ml_z" # regular with reset + _run "-rtcinsm" # regular + _run "-rtcinsmz" # regular with reset elif [[ "x$@" = "x-F" ]]; then # regular with notfastpath - _run "-_tcinsed_ml_f" # regular - _run "-_tcinsed_ml_zf" # regular with reset + _run "-rtcinsmf" # regular + _run "-rtcinsmzf" # regular with reset else _run "$@" fi diff --git a/vendor/github.com/ugorji/go/codec/time.go b/vendor/github.com/ugorji/go/codec/time.go index 718b731ec58..fc4c63e1def 100644 --- a/vendor/github.com/ugorji/go/codec/time.go +++ b/vendor/github.com/ugorji/go/codec/time.go @@ -5,22 +5,11 @@ package codec import ( "fmt" - "reflect" "time" ) var ( - timeDigits = [...]byte{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'} - timeExtEncFn = func(rv reflect.Value) (bs []byte, err error) { - defer panicToErr(&err) - bs = timeExt{}.WriteExt(rv.Interface()) - return - } - timeExtDecFn = func(rv reflect.Value, bs []byte) (err error) { - defer panicToErr(&err) - timeExt{}.ReadExt(rv.Interface(), bs) - return - } + timeDigits = [...]byte{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'} ) type timeExt struct{} diff --git a/vendor/golang.org/x/sys/unix/.gitignore b/vendor/golang.org/x/sys/unix/.gitignore deleted file mode 100644 index e482715909b..00000000000 --- a/vendor/golang.org/x/sys/unix/.gitignore +++ /dev/null @@ -1 +0,0 @@ -_obj/ diff --git a/vendor/golang.org/x/sys/unix/mkall.sh b/vendor/golang.org/x/sys/unix/mkall.sh index de95a4bbcf5..d41d6100ed8 100755 --- a/vendor/golang.org/x/sys/unix/mkall.sh +++ b/vendor/golang.org/x/sys/unix/mkall.sh @@ -116,12 +116,12 @@ _* | *_ | _) darwin_386) mkerrors="$mkerrors -m32" mksyscall="./mksyscall.pl -l32" - mksysnum="./mksysnum_darwin.pl $(xcrun --show-sdk-path --sdk macosx)/usr/include/sys/syscall.h" + mksysnum="./mksysnum_darwin.pl /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.10.sdk/usr/include/sys/syscall.h" mktypes="GOARCH=$GOARCH go tool cgo -godefs" ;; darwin_amd64) mkerrors="$mkerrors -m64" - mksysnum="./mksysnum_darwin.pl $(xcrun --show-sdk-path --sdk macosx)/usr/include/sys/syscall.h" + mksysnum="./mksysnum_darwin.pl /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.10.sdk/usr/include/sys/syscall.h" mktypes="GOARCH=$GOARCH go tool cgo -godefs" ;; darwin_arm) @@ -131,7 +131,7 @@ darwin_arm) ;; darwin_arm64) mkerrors="$mkerrors -m64" - mksysnum="./mksysnum_darwin.pl $(xcrun --show-sdk-path --sdk iphoneos)/usr/include/sys/syscall.h" + mksysnum="./mksysnum_darwin.pl /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/usr/include/sys/syscall.h" mktypes="GOARCH=$GOARCH go tool cgo -godefs" ;; dragonfly_386) diff --git a/vendor/golang.org/x/sys/unix/mkerrors.sh b/vendor/golang.org/x/sys/unix/mkerrors.sh index c40d788c4ab..77c48048eec 100755 --- a/vendor/golang.org/x/sys/unix/mkerrors.sh +++ b/vendor/golang.org/x/sys/unix/mkerrors.sh @@ -12,16 +12,11 @@ export LC_ALL=C export LC_CTYPE=C if test -z "$GOARCH" -o -z "$GOOS"; then - echo 1>&2 "GOARCH or GOOS not defined in environment" - exit 1 + echo 1>&2 "GOARCH or GOOS not defined in environment" + exit 1 fi -CC=${CC:-cc} - -if [[ "$GOOS" -eq "solaris" ]]; then - # Assumes GNU versions of utilities in PATH. - export PATH=/usr/gnu/bin:$PATH -fi +CC=${CC:-gcc} uname=$(uname) @@ -128,7 +123,7 @@ includes_Linux=' #include #include #include -#include +#include #ifndef MSG_FASTOPEN #define MSG_FASTOPEN 0x20000000 @@ -205,7 +200,6 @@ includes_OpenBSD=' ' includes_SunOS=' -#include #include #include #include @@ -276,31 +270,21 @@ ccflags="$@" $2 !~ /^EXPR_/ && $2 ~ /^E[A-Z0-9_]+$/ || $2 ~ /^B[0-9_]+$/ || - $2 == "BOTHER" || - $2 ~ /^CI?BAUD(EX)?$/ || - $2 == "IBSHIFT" || $2 ~ /^V[A-Z0-9]+$/ || $2 ~ /^CS[A-Z0-9]/ || - $2 ~ /^I(SIG|CANON|CRNL|UCLC|EXTEN|MAXBEL|STRIP|UTF8)$/ || + $2 ~ /^I(SIG|CANON|CRNL|EXTEN|MAXBEL|STRIP|UTF8)$/ || $2 ~ /^IGN/ || $2 ~ /^IX(ON|ANY|OFF)$/ || $2 ~ /^IN(LCR|PCK)$/ || $2 ~ /(^FLU?SH)|(FLU?SH$)/ || - $2 ~ /^C(LOCAL|READ|MSPAR|RTSCTS)$/ || + $2 ~ /^C(LOCAL|READ)$/ || $2 == "BRKINT" || $2 == "HUPCL" || $2 == "PENDIN" || $2 == "TOSTOP" || - $2 == "XCASE" || - $2 == "ALTWERASE" || - $2 == "NOKERNINFO" || $2 ~ /^PAR/ || $2 ~ /^SIG[^_]/ || - $2 ~ /^O[CNPFPL][A-Z]+[^_][A-Z]+$/ || - $2 ~ /^(NL|CR|TAB|BS|VT|FF)DLY$/ || - $2 ~ /^(NL|CR|TAB|BS|VT|FF)[0-9]$/ || - $2 ~ /^O?XTABS$/ || - $2 ~ /^TC[IO](ON|OFF)$/ || + $2 ~ /^O[CNPFP][A-Z]+[^_][A-Z]+$/ || $2 ~ /^IN_/ || $2 ~ /^LOCK_(SH|EX|NB|UN)$/ || $2 ~ /^(AF|SOCK|SO|SOL|IPPROTO|IP|IPV6|ICMP6|TCP|EVFILT|NOTE|EV|SHUT|PROT|MAP|PACKET|MSG|SCM|MCL|DT|MADV|PR)_/ || @@ -319,9 +303,6 @@ ccflags="$@" $2 ~ /^(NETLINK|NLM|NLMSG|NLA|IFA|IFAN|RT|RTCF|RTN|RTPROT|RTNH|ARPHRD|ETH_P)_/ || $2 ~ /^SIOC/ || $2 ~ /^TIOC/ || - $2 ~ /^TCGET/ || - $2 ~ /^TCSET/ || - $2 ~ /^TC(FLSH|SBRKP?|XONC)$/ || $2 !~ "RTF_BITS" && $2 ~ /^(IFF|IFT|NET_RT|RTM|RTF|RTV|RTA|RTAX)_/ || $2 ~ /^BIOC/ || diff --git a/vendor/golang.org/x/sys/unix/mksyscall_solaris.pl b/vendor/golang.org/x/sys/unix/mksyscall_solaris.pl index 06bade76877..f17b6125b51 100755 --- a/vendor/golang.org/x/sys/unix/mksyscall_solaris.pl +++ b/vendor/golang.org/x/sys/unix/mksyscall_solaris.pl @@ -110,9 +110,9 @@ while(<>) { $sysname =~ y/A-Z/a-z/; # All libc functions are lowercase. # Runtime import of function to allow cross-platform builds. - $dynimports .= "//go:cgo_import_dynamic libc_${sysname} ${sysname} \"$modname.so\"\n"; + $dynimports .= "//go:cgo_import_dynamic ${modname}_${sysname} ${sysname} \"$modname.so\"\n"; # Link symbol to proc address variable. - $linknames .= "//go:linkname ${sysvarname} libc_${sysname}\n"; + $linknames .= "//go:linkname ${sysvarname} ${modname}_${sysname}\n"; # Library proc address variable. push @vars, $sysvarname; diff --git a/vendor/golang.org/x/sys/unix/sockcmsg_unix.go b/vendor/golang.org/x/sys/unix/sockcmsg_unix.go index 70af5a728e5..6668bec711d 100644 --- a/vendor/golang.org/x/sys/unix/sockcmsg_unix.go +++ b/vendor/golang.org/x/sys/unix/sockcmsg_unix.go @@ -77,10 +77,10 @@ func UnixRights(fds ...int) []byte { h.Level = SOL_SOCKET h.Type = SCM_RIGHTS h.SetLen(CmsgLen(datalen)) - data := cmsgData(h) + data := uintptr(cmsgData(h)) for _, fd := range fds { - *(*int32)(data) = int32(fd) - data = unsafe.Pointer(uintptr(data) + 4) + *(*int32)(unsafe.Pointer(data)) = int32(fd) + data += 4 } return b } diff --git a/vendor/golang.org/x/sys/unix/syscall_bsd.go b/vendor/golang.org/x/sys/unix/syscall_bsd.go index e9671764ccb..9679dec8982 100644 --- a/vendor/golang.org/x/sys/unix/syscall_bsd.go +++ b/vendor/golang.org/x/sys/unix/syscall_bsd.go @@ -450,34 +450,16 @@ func Kevent(kq int, changes, events []Kevent_t, timeout *Timespec) (n int, err e //sys sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) = SYS___SYSCTL -// sysctlmib translates name to mib number and appends any additional args. -func sysctlmib(name string, args ...int) ([]_C_int, error) { +func Sysctl(name string) (value string, err error) { // Translate name to mib number. mib, err := nametomib(name) - if err != nil { - return nil, err - } - - for _, a := range args { - mib = append(mib, _C_int(a)) - } - - return mib, nil -} - -func Sysctl(name string) (string, error) { - return SysctlArgs(name) -} - -func SysctlArgs(name string, args ...int) (string, error) { - mib, err := sysctlmib(name, args...) if err != nil { return "", err } // Find size. n := uintptr(0) - if err := sysctl(mib, nil, &n, nil, 0); err != nil { + if err = sysctl(mib, nil, &n, nil, 0); err != nil { return "", err } if n == 0 { @@ -486,7 +468,7 @@ func SysctlArgs(name string, args ...int) (string, error) { // Read into buffer of that size. buf := make([]byte, n) - if err := sysctl(mib, &buf[0], &n, nil, 0); err != nil { + if err = sysctl(mib, &buf[0], &n, nil, 0); err != nil { return "", err } @@ -497,19 +479,17 @@ func SysctlArgs(name string, args ...int) (string, error) { return string(buf[0:n]), nil } -func SysctlUint32(name string) (uint32, error) { - return SysctlUint32Args(name) -} - -func SysctlUint32Args(name string, args ...int) (uint32, error) { - mib, err := sysctlmib(name, args...) +func SysctlUint32(name string) (value uint32, err error) { + // Translate name to mib number. + mib, err := nametomib(name) if err != nil { return 0, err } + // Read into buffer of that size. n := uintptr(4) buf := make([]byte, 4) - if err := sysctl(mib, &buf[0], &n, nil, 0); err != nil { + if err = sysctl(mib, &buf[0], &n, nil, 0); err != nil { return 0, err } if n != 4 { @@ -518,49 +498,6 @@ func SysctlUint32Args(name string, args ...int) (uint32, error) { return *(*uint32)(unsafe.Pointer(&buf[0])), nil } -func SysctlUint64(name string, args ...int) (uint64, error) { - mib, err := sysctlmib(name, args...) - if err != nil { - return 0, err - } - - n := uintptr(8) - buf := make([]byte, 8) - if err := sysctl(mib, &buf[0], &n, nil, 0); err != nil { - return 0, err - } - if n != 8 { - return 0, EIO - } - return *(*uint64)(unsafe.Pointer(&buf[0])), nil -} - -func SysctlRaw(name string, args ...int) ([]byte, error) { - mib, err := sysctlmib(name, args...) - if err != nil { - return nil, err - } - - // Find size. - n := uintptr(0) - if err := sysctl(mib, nil, &n, nil, 0); err != nil { - return nil, err - } - if n == 0 { - return nil, nil - } - - // Read into buffer of that size. - buf := make([]byte, n) - if err := sysctl(mib, &buf[0], &n, nil, 0); err != nil { - return nil, err - } - - // The actual call may return less than the original reported required - // size so ensure we deal with that. - return buf[:n], nil -} - //sys utimes(path string, timeval *[2]Timeval) (err error) func Utimes(path string, tv []Timeval) error { diff --git a/vendor/golang.org/x/sys/unix/syscall_darwin_amd64.go b/vendor/golang.org/x/sys/unix/syscall_darwin_amd64.go index 7adb98ded51..db5a02dc640 100644 --- a/vendor/golang.org/x/sys/unix/syscall_darwin_amd64.go +++ b/vendor/golang.org/x/sys/unix/syscall_darwin_amd64.go @@ -11,8 +11,6 @@ import ( "unsafe" ) -//sys Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) - func Getpagesize() int { return 4096 } func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) } diff --git a/vendor/golang.org/x/sys/unix/syscall_linux.go b/vendor/golang.org/x/sys/unix/syscall_linux.go index d3ee5d2c2f6..9df719571d1 100644 --- a/vendor/golang.org/x/sys/unix/syscall_linux.go +++ b/vendor/golang.org/x/sys/unix/syscall_linux.go @@ -886,7 +886,6 @@ func Getpgrp() (pid int) { //sys Pause() (err error) //sys PivotRoot(newroot string, putold string) (err error) = SYS_PIVOT_ROOT //sysnb prlimit(pid int, resource int, old *Rlimit, newlimit *Rlimit) (err error) = SYS_PRLIMIT64 -//sys Prctl(option int, arg2 uintptr, arg3 uintptr, arg4 uintptr, arg5 uintptr) (err error) //sys read(fd int, p []byte) (n int, err error) //sys Removexattr(path string, attr string) (err error) //sys Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) @@ -1023,6 +1022,7 @@ func Munmap(b []byte) (err error) { // Personality // Poll // Ppoll +// Prctl // Pselect6 // Ptrace // Putpmsg diff --git a/vendor/golang.org/x/sys/unix/syscall_solaris.go b/vendor/golang.org/x/sys/unix/syscall_solaris.go index 00837326481..ab54718f63d 100644 --- a/vendor/golang.org/x/sys/unix/syscall_solaris.go +++ b/vendor/golang.org/x/sys/unix/syscall_solaris.go @@ -13,7 +13,6 @@ package unix import ( - "sync/atomic" "syscall" "unsafe" ) @@ -139,8 +138,6 @@ func (sa *SockaddrUnix) sockaddr() (unsafe.Pointer, _Socklen, error) { return unsafe.Pointer(&sa.raw), sl, nil } -//sys getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) = libsocket.getsockname - func Getsockname(fd int) (sa Sockaddr, err error) { var rsa RawSockaddrAny var len _Socklen = SizeofSockaddrAny @@ -150,23 +147,12 @@ func Getsockname(fd int) (sa Sockaddr, err error) { return anyToSockaddr(&rsa) } -const ImplementsGetwd = true +// The const provides a compile-time constant so clients +// can adjust to whether there is a working Getwd and avoid +// even linking this function into the binary. See ../os/getwd.go. +const ImplementsGetwd = false -//sys Getcwd(buf []byte) (n int, err error) - -func Getwd() (wd string, err error) { - var buf [PathMax]byte - // Getcwd will return an error if it failed for any reason. - _, err = Getcwd(buf[0:]) - if err != nil { - return "", err - } - n := clen(buf[:]) - if n < 1 { - return "", EINVAL - } - return string(buf[:n]), nil -} +func Getwd() (string, error) { return "", ENOTSUP } /* * Wrapped @@ -177,20 +163,21 @@ func Getwd() (wd string, err error) { func Getgroups() (gids []int, err error) { n, err := getgroups(0, nil) - // Check for error and sanity check group count. Newer versions of - // Solaris allow up to 1024 (NGROUPS_MAX). - if n < 0 || n > 1024 { - if err != nil { - return nil, err - } - return nil, EINVAL - } else if n == 0 { + if err != nil { + return nil, err + } + if n == 0 { return nil, nil } + // Sanity check group count. Max is 16 on BSD. + if n < 0 || n > 1000 { + return nil, EINVAL + } + a := make([]_Gid_t, n) n, err = getgroups(n, &a[0]) - if n == -1 { + if err != nil { return nil, err } gids = make([]int, n) @@ -289,38 +276,19 @@ func Gethostname() (name string, err error) { return name, err } -//sys utimes(path string, times *[2]Timeval) (err error) - -func Utimes(path string, tv []Timeval) (err error) { - if tv == nil { - return utimes(path, nil) - } - if len(tv) != 2 { - return EINVAL - } - return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0]))) -} - -//sys utimensat(fd int, path string, times *[2]Timespec, flag int) (err error) - func UtimesNano(path string, ts []Timespec) error { if ts == nil { - return utimensat(AT_FDCWD, path, nil, 0) + return Utimes(path, nil) } if len(ts) != 2 { return EINVAL } - return utimensat(AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0) -} - -func UtimesNanoAt(dirfd int, path string, ts []Timespec, flags int) error { - if ts == nil { - return utimensat(dirfd, path, nil, flags) + var tv [2]Timeval + for i := 0; i < 2; i++ { + tv[i].Sec = ts[i].Sec + tv[i].Usec = ts[i].Nsec / 1000 } - if len(ts) != 2 { - return EINVAL - } - return utimensat(dirfd, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), flags) + return Utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0]))) } //sys fcntl(fd int, cmd int, arg int) (val int, err error) @@ -334,35 +302,6 @@ func FcntlFlock(fd uintptr, cmd int, lk *Flock_t) error { return nil } -//sys futimesat(fildes int, path *byte, times *[2]Timeval) (err error) - -func Futimesat(dirfd int, path string, tv []Timeval) error { - pathp, err := BytePtrFromString(path) - if err != nil { - return err - } - if tv == nil { - return futimesat(dirfd, pathp, nil) - } - if len(tv) != 2 { - return EINVAL - } - return futimesat(dirfd, pathp, (*[2]Timeval)(unsafe.Pointer(&tv[0]))) -} - -// Solaris doesn't have an futimes function because it allows NULL to be -// specified as the path for futimesat. However, Go doesn't like -// NULL-style string interfaces, so this simple wrapper is provided. -func Futimes(fd int, tv []Timeval) error { - if tv == nil { - return futimesat(fd, nil, nil) - } - if len(tv) != 2 { - return EINVAL - } - return futimesat(fd, nil, (*[2]Timeval)(unsafe.Pointer(&tv[0]))) -} - func anyToSockaddr(rsa *RawSockaddrAny) (Sockaddr, error) { switch rsa.Addr.Family { case AF_UNIX: @@ -411,7 +350,7 @@ func Accept(fd int) (nfd int, sa Sockaddr, err error) { var rsa RawSockaddrAny var len _Socklen = SizeofSockaddrAny nfd, err = accept(fd, &rsa, &len) - if nfd == -1 { + if err != nil { return } sa, err = anyToSockaddr(&rsa) @@ -422,8 +361,6 @@ func Accept(fd int) (nfd int, sa Sockaddr, err error) { return } -//sys recvmsg(s int, msg *Msghdr, flags int) (n int, err error) = libsocket.recvmsg - func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) { var msg Msghdr var rsa RawSockaddrAny @@ -445,7 +382,7 @@ func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from } msg.Iov = &iov msg.Iovlen = 1 - if n, err = recvmsg(fd, &msg, flags); n == -1 { + if n, err = recvmsg(fd, &msg, flags); err != nil { return } oobn = int(msg.Accrightslen) @@ -500,67 +437,6 @@ func SendmsgN(fd int, p, oob []byte, to Sockaddr, flags int) (n int, err error) return n, nil } -//sys acct(path *byte) (err error) - -func Acct(path string) (err error) { - if len(path) == 0 { - // Assume caller wants to disable accounting. - return acct(nil) - } - - pathp, err := BytePtrFromString(path) - if err != nil { - return err - } - return acct(pathp) -} - -/* - * Expose the ioctl function - */ - -//sys ioctl(fd int, req int, arg uintptr) (err error) - -func IoctlSetInt(fd int, req int, value int) (err error) { - return ioctl(fd, req, uintptr(value)) -} - -func IoctlSetWinsize(fd int, req int, value *Winsize) (err error) { - return ioctl(fd, req, uintptr(unsafe.Pointer(value))) -} - -func IoctlSetTermios(fd int, req int, value *Termios) (err error) { - return ioctl(fd, req, uintptr(unsafe.Pointer(value))) -} - -func IoctlSetTermio(fd int, req int, value *Termio) (err error) { - return ioctl(fd, req, uintptr(unsafe.Pointer(value))) -} - -func IoctlGetInt(fd int, req int) (int, error) { - var value int - err := ioctl(fd, req, uintptr(unsafe.Pointer(&value))) - return value, err -} - -func IoctlGetWinsize(fd int, req int) (*Winsize, error) { - var value Winsize - err := ioctl(fd, req, uintptr(unsafe.Pointer(&value))) - return &value, err -} - -func IoctlGetTermios(fd int, req int) (*Termios, error) { - var value Termios - err := ioctl(fd, req, uintptr(unsafe.Pointer(&value))) - return &value, err -} - -func IoctlGetTermio(fd int, req int) (*Termio, error) { - var value Termio - err := ioctl(fd, req, uintptr(unsafe.Pointer(&value))) - return &value, err -} - /* * Exposed directly */ @@ -571,29 +447,21 @@ func IoctlGetTermio(fd int, req int) (*Termio, error) { //sys Chown(path string, uid int, gid int) (err error) //sys Chroot(path string) (err error) //sys Close(fd int) (err error) -//sys Creat(path string, mode uint32) (fd int, err error) //sys Dup(fd int) (nfd int, err error) -//sys Dup2(oldfd int, newfd int) (err error) //sys Exit(code int) //sys Fchdir(fd int) (err error) //sys Fchmod(fd int, mode uint32) (err error) -//sys Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) //sys Fchown(fd int, uid int, gid int) (err error) -//sys Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error) -//sys Fdatasync(fd int) (err error) //sys Fpathconf(fd int, name int) (val int, err error) //sys Fstat(fd int, stat *Stat_t) (err error) //sys Getdents(fd int, buf []byte, basep *uintptr) (n int, err error) //sysnb Getgid() (gid int) //sysnb Getpid() (pid int) -//sysnb Getpgid(pid int) (pgid int, err error) -//sysnb Getpgrp() (pgid int, err error) //sys Geteuid() (euid int) //sys Getegid() (egid int) //sys Getppid() (ppid int) //sys Getpriority(which int, who int) (n int, err error) //sysnb Getrlimit(which int, lim *Rlimit) (err error) -//sysnb Getrusage(who int, rusage *Rusage) (err error) //sysnb Gettimeofday(tv *Timeval) (err error) //sysnb Getuid() (uid int) //sys Kill(pid int, signum syscall.Signal) (err error) @@ -603,33 +471,20 @@ func IoctlGetTermio(fd int, req int) (*Termio, error) { //sys Lstat(path string, stat *Stat_t) (err error) //sys Madvise(b []byte, advice int) (err error) //sys Mkdir(path string, mode uint32) (err error) -//sys Mkdirat(dirfd int, path string, mode uint32) (err error) -//sys Mkfifo(path string, mode uint32) (err error) -//sys Mkfifoat(dirfd int, path string, mode uint32) (err error) //sys Mknod(path string, mode uint32, dev int) (err error) -//sys Mknodat(dirfd int, path string, mode uint32, dev int) (err error) -//sys Mlock(b []byte) (err error) -//sys Mlockall(flags int) (err error) -//sys Mprotect(b []byte, prot int) (err error) -//sys Munlock(b []byte) (err error) -//sys Munlockall() (err error) //sys Nanosleep(time *Timespec, leftover *Timespec) (err error) //sys Open(path string, mode int, perm uint32) (fd int, err error) -//sys Openat(dirfd int, path string, flags int, mode uint32) (fd int, err error) //sys Pathconf(path string, name int) (val int, err error) -//sys Pause() (err error) //sys Pread(fd int, p []byte, offset int64) (n int, err error) //sys Pwrite(fd int, p []byte, offset int64) (n int, err error) //sys read(fd int, p []byte) (n int, err error) //sys Readlink(path string, buf []byte) (n int, err error) //sys Rename(from string, to string) (err error) -//sys Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) //sys Rmdir(path string) (err error) //sys Seek(fd int, offset int64, whence int) (newoffset int64, err error) = lseek //sysnb Setegid(egid int) (err error) //sysnb Seteuid(euid int) (err error) //sysnb Setgid(gid int) (err error) -//sys Sethostname(p []byte) (err error) //sysnb Setpgid(pid int, pgid int) (err error) //sys Setpriority(which int, who int, prio int) (err error) //sysnb Setregid(rgid int, egid int) (err error) @@ -641,17 +496,12 @@ func IoctlGetTermio(fd int, req int) (*Termio, error) { //sys Stat(path string, stat *Stat_t) (err error) //sys Symlink(path string, link string) (err error) //sys Sync() (err error) -//sysnb Times(tms *Tms) (ticks uintptr, err error) //sys Truncate(path string, length int64) (err error) //sys Fsync(fd int) (err error) //sys Ftruncate(fd int, length int64) (err error) -//sys Umask(mask int) (oldmask int) -//sysnb Uname(buf *Utsname) (err error) -//sys Unmount(target string, flags int) (err error) = libc.umount +//sys Umask(newmask int) (oldmask int) //sys Unlink(path string) (err error) -//sys Unlinkat(dirfd int, path string) (err error) -//sys Ustat(dev int, ubuf *Ustat_t) (err error) -//sys Utime(path string, buf *Utimbuf) (err error) +//sys Utimes(path string, times *[2]Timeval) (err error) //sys bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) = libsocket.bind //sys connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) = libsocket.connect //sys mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error) @@ -662,8 +512,10 @@ func IoctlGetTermio(fd int, req int) (*Termio, error) { //sys write(fd int, p []byte) (n int, err error) //sys getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) = libsocket.getsockopt //sysnb getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) = libsocket.getpeername +//sys getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) = libsocket.getsockname //sys setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) = libsocket.setsockopt //sys recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) = libsocket.recvfrom +//sys recvmsg(s int, msg *Msghdr, flags int) (n int, err error) = libsocket.recvmsg func readlen(fd int, buf *byte, nbuf int) (n int, err error) { r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procread)), 3, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf), 0, 0, 0) @@ -696,18 +548,3 @@ func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, e func Munmap(b []byte) (err error) { return mapper.Munmap(b) } - -//sys sysconf(name int) (n int64, err error) - -// pageSize caches the value of Getpagesize, since it can't change -// once the system is booted. -var pageSize int64 // accessed atomically - -func Getpagesize() int { - n := atomic.LoadInt64(&pageSize) - if n == 0 { - n, _ = sysconf(_SC_PAGESIZE) - atomic.StoreInt64(&pageSize, n) - } - return int(n) -} diff --git a/vendor/golang.org/x/sys/unix/syscall_solaris_amd64.go b/vendor/golang.org/x/sys/unix/syscall_solaris_amd64.go index 2e44630cd06..9c173cd5f2b 100644 --- a/vendor/golang.org/x/sys/unix/syscall_solaris_amd64.go +++ b/vendor/golang.org/x/sys/unix/syscall_solaris_amd64.go @@ -6,6 +6,8 @@ package unix +func Getpagesize() int { return 4096 } + func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) } func NsecToTimespec(nsec int64) (ts Timespec) { diff --git a/vendor/golang.org/x/sys/unix/types_darwin.go b/vendor/golang.org/x/sys/unix/types_darwin.go index 1153261822b..2bb15cb8b7e 100644 --- a/vendor/golang.org/x/sys/unix/types_darwin.go +++ b/vendor/golang.org/x/sys/unix/types_darwin.go @@ -241,10 +241,3 @@ type BpfHdr C.struct_bpf_hdr // Terminal handling type Termios C.struct_termios - -// fchmodat-like syscalls. - -const ( - AT_FDCWD = C.AT_FDCWD - AT_SYMLINK_NOFOLLOW = C.AT_SYMLINK_NOFOLLOW -) diff --git a/vendor/golang.org/x/sys/unix/types_linux.go b/vendor/golang.org/x/sys/unix/types_linux.go index d5275875f87..9b75633b379 100644 --- a/vendor/golang.org/x/sys/unix/types_linux.go +++ b/vendor/golang.org/x/sys/unix/types_linux.go @@ -50,19 +50,12 @@ package unix #include #include #include -#include +#include #include #include #include #include -#ifdef TCSETS2 -// On systems that have "struct termios2" use this as type Termios. -typedef struct termios2 termios_t; -#else -typedef struct termios termios_t; -#endif - enum { sizeofPtr = sizeof(void*), }; @@ -403,4 +396,4 @@ const ( // Terminal handling -type Termios C.termios_t +type Termios C.struct_termios diff --git a/vendor/golang.org/x/sys/unix/types_solaris.go b/vendor/golang.org/x/sys/unix/types_solaris.go index 6ad50eaba61..753c7996b1d 100644 --- a/vendor/golang.org/x/sys/unix/types_solaris.go +++ b/vendor/golang.org/x/sys/unix/types_solaris.go @@ -15,17 +15,10 @@ package unix /* #define KERNEL -// These defines ensure that builds done on newer versions of Solaris are -// backwards-compatible with older versions of Solaris and -// OpenSolaris-based derivatives. -#define __USE_SUNOS_SOCKETS__ // msghdr -#define __USE_LEGACY_PROTOTYPES__ // iovec #include #include -#include #include #include -#include #include #include #include @@ -37,9 +30,7 @@ package unix #include #include #include -#include #include -#include #include #include #include @@ -49,8 +40,6 @@ package unix #include #include #include -#include -#include enum { sizeofPtr = sizeof(void*), @@ -80,7 +69,6 @@ const ( sizeofInt = C.sizeof_int sizeofLong = C.sizeof_long sizeofLongLong = C.sizeof_longlong - PathMax = C.PATH_MAX ) // Basic types @@ -100,10 +88,6 @@ type Timeval C.struct_timeval type Timeval32 C.struct_timeval32 -type Tms C.struct_tms - -type Utimbuf C.struct_utimbuf - // Processes type Rusage C.struct_rusage @@ -191,20 +175,6 @@ const ( type FdSet C.fd_set -// Misc - -type Utsname C.struct_utsname - -type Ustat_t C.struct_ustat - -const ( - AT_FDCWD = C.AT_FDCWD - AT_SYMLINK_NOFOLLOW = C.AT_SYMLINK_NOFOLLOW - AT_SYMLINK_FOLLOW = C.AT_SYMLINK_FOLLOW - AT_REMOVEDIR = C.AT_REMOVEDIR - AT_EACCESS = C.AT_EACCESS -) - // Routing and interface messages const ( @@ -247,14 +217,6 @@ type BpfTimeval C.struct_bpf_timeval type BpfHdr C.struct_bpf_hdr -// sysconf information - -const _SC_PAGESIZE = C._SC_PAGESIZE - // Terminal handling type Termios C.struct_termios - -type Termio C.struct_termio - -type Winsize C.struct_winsize diff --git a/vendor/golang.org/x/sys/unix/zerrors_freebsd_386.go b/vendor/golang.org/x/sys/unix/zerrors_freebsd_386.go index 7b95751c3db..3c2a5bfc2e7 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_freebsd_386.go +++ b/vendor/golang.org/x/sys/unix/zerrors_freebsd_386.go @@ -225,20 +225,6 @@ const ( BRKINT = 0x2 CFLUSH = 0xf CLOCAL = 0x8000 - CLOCK_MONOTONIC = 0x4 - CLOCK_MONOTONIC_FAST = 0xc - CLOCK_MONOTONIC_PRECISE = 0xb - CLOCK_PROCESS_CPUTIME_ID = 0xf - CLOCK_PROF = 0x2 - CLOCK_REALTIME = 0x0 - CLOCK_REALTIME_FAST = 0xa - CLOCK_REALTIME_PRECISE = 0x9 - CLOCK_SECOND = 0xd - CLOCK_THREAD_CPUTIME_ID = 0xe - CLOCK_UPTIME = 0x5 - CLOCK_UPTIME_FAST = 0x8 - CLOCK_UPTIME_PRECISE = 0x7 - CLOCK_VIRTUAL = 0x1 CREAD = 0x800 CS5 = 0x0 CS6 = 0x100 diff --git a/vendor/golang.org/x/sys/unix/zerrors_freebsd_amd64.go b/vendor/golang.org/x/sys/unix/zerrors_freebsd_amd64.go index e48e7799a1d..3b3f7a9d22d 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_freebsd_amd64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_freebsd_amd64.go @@ -225,20 +225,6 @@ const ( BRKINT = 0x2 CFLUSH = 0xf CLOCAL = 0x8000 - CLOCK_MONOTONIC = 0x4 - CLOCK_MONOTONIC_FAST = 0xc - CLOCK_MONOTONIC_PRECISE = 0xb - CLOCK_PROCESS_CPUTIME_ID = 0xf - CLOCK_PROF = 0x2 - CLOCK_REALTIME = 0x0 - CLOCK_REALTIME_FAST = 0xa - CLOCK_REALTIME_PRECISE = 0x9 - CLOCK_SECOND = 0xd - CLOCK_THREAD_CPUTIME_ID = 0xe - CLOCK_UPTIME = 0x5 - CLOCK_UPTIME_FAST = 0x8 - CLOCK_UPTIME_PRECISE = 0x7 - CLOCK_VIRTUAL = 0x1 CREAD = 0x800 CS5 = 0x0 CS6 = 0x100 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_386.go b/vendor/golang.org/x/sys/unix/zerrors_linux_386.go index d370be0ecb3..6fbef752263 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_386.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_386.go @@ -145,7 +145,6 @@ const ( B75 = 0x2 B921600 = 0x1007 B9600 = 0xd - BOTHER = 0x1000 BPF_A = 0x10 BPF_ABS = 0x20 BPF_ADD = 0x0 @@ -187,13 +186,7 @@ const ( BPF_W = 0x0 BPF_X = 0x8 BRKINT = 0x2 - BS0 = 0x0 - BS1 = 0x2000 - BSDLY = 0x2000 - CBAUD = 0x100f - CBAUDEX = 0x1000 CFLUSH = 0xf - CIBAUD = 0x100f0000 CLOCAL = 0x800 CLOCK_BOOTTIME = 0x7 CLOCK_BOOTTIME_ALARM = 0x9 @@ -232,14 +225,7 @@ const ( CLONE_UNTRACED = 0x800000 CLONE_VFORK = 0x4000 CLONE_VM = 0x100 - CMSPAR = 0x40000000 - CR0 = 0x0 - CR1 = 0x200 - CR2 = 0x400 - CR3 = 0x600 - CRDLY = 0x600 CREAD = 0x80 - CRTSCTS = 0x80000000 CS5 = 0x0 CS6 = 0x10 CS7 = 0x20 @@ -367,9 +353,6 @@ const ( EXTPROC = 0x10000 FD_CLOEXEC = 0x1 FD_SETSIZE = 0x400 - FF0 = 0x0 - FF1 = 0x8000 - FFDLY = 0x8000 FLUSHO = 0x1000 F_DUPFD = 0x0 F_DUPFD_CLOEXEC = 0x406 @@ -405,7 +388,6 @@ const ( F_UNLCK = 0x2 F_WRLCK = 0x1 HUPCL = 0x400 - IBSHIFT = 0x10 ICANON = 0x2 ICMPV6_FILTER = 0x1 ICRNL = 0x100 @@ -637,7 +619,6 @@ const ( IP_XFRM_POLICY = 0x11 ISIG = 0x1 ISTRIP = 0x20 - IUCLC = 0x200 IUTF8 = 0x4000 IXANY = 0x800 IXOFF = 0x1000 @@ -769,13 +750,10 @@ const ( NETLINK_UNUSED = 0x1 NETLINK_USERSOCK = 0x2 NETLINK_XFRM = 0x6 - NL0 = 0x0 - NL1 = 0x100 NLA_ALIGNTO = 0x4 NLA_F_NESTED = 0x8000 NLA_F_NET_BYTEORDER = 0x4000 NLA_HDRLEN = 0x4 - NLDLY = 0x100 NLMSG_ALIGNTO = 0x4 NLMSG_DONE = 0x3 NLMSG_ERROR = 0x2 @@ -800,7 +778,6 @@ const ( OCRNL = 0x8 OFDEL = 0x80 OFILL = 0x40 - OLCUC = 0x2 ONLCR = 0x4 ONLRET = 0x20 ONOCR = 0x10 @@ -1298,23 +1275,10 @@ const ( S_IXGRP = 0x8 S_IXOTH = 0x1 S_IXUSR = 0x40 - TAB0 = 0x0 - TAB1 = 0x800 - TAB2 = 0x1000 - TAB3 = 0x1800 - TABDLY = 0x1800 TCFLSH = 0x540b - TCGETA = 0x5405 - TCGETS = 0x5401 - TCGETS2 = 0x802c542a - TCGETX = 0x5432 TCIFLUSH = 0x0 - TCIOFF = 0x2 TCIOFLUSH = 0x2 - TCION = 0x3 TCOFLUSH = 0x1 - TCOOFF = 0x0 - TCOON = 0x1 TCP_CONGESTION = 0xd TCP_CORK = 0x3 TCP_DEFER_ACCEPT = 0x9 @@ -1334,32 +1298,14 @@ const ( TCP_SYNCNT = 0x7 TCP_WINDOW_CLAMP = 0xa TCSAFLUSH = 0x2 - TCSBRK = 0x5409 - TCSBRKP = 0x5425 - TCSETA = 0x5406 - TCSETAF = 0x5408 - TCSETAW = 0x5407 - TCSETS = 0x5402 - TCSETS2 = 0x402c542b - TCSETSF = 0x5404 - TCSETSF2 = 0x402c542d - TCSETSW = 0x5403 - TCSETSW2 = 0x402c542c - TCSETX = 0x5433 - TCSETXF = 0x5434 - TCSETXW = 0x5435 - TCXONC = 0x540a TIOCCBRK = 0x5428 TIOCCONS = 0x541d TIOCEXCL = 0x540c TIOCGDEV = 0x80045432 TIOCGETD = 0x5424 - TIOCGEXCL = 0x80045440 TIOCGICOUNT = 0x545d TIOCGLCKTRMIOS = 0x5456 TIOCGPGRP = 0x540f - TIOCGPKT = 0x80045438 - TIOCGPTLCK = 0x80045439 TIOCGPTN = 0x80045430 TIOCGRS485 = 0x542e TIOCGSERIAL = 0x541e @@ -1465,8 +1411,6 @@ const ( WORDSIZE = 0x20 WSTOPPED = 0x2 WUNTRACED = 0x2 - XCASE = 0x4 - XTABS = 0x1800 ) // Errors diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go index b83fb40b395..b40ccb8d7e5 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go @@ -145,7 +145,6 @@ const ( B75 = 0x2 B921600 = 0x1007 B9600 = 0xd - BOTHER = 0x1000 BPF_A = 0x10 BPF_ABS = 0x20 BPF_ADD = 0x0 @@ -187,13 +186,7 @@ const ( BPF_W = 0x0 BPF_X = 0x8 BRKINT = 0x2 - BS0 = 0x0 - BS1 = 0x2000 - BSDLY = 0x2000 - CBAUD = 0x100f - CBAUDEX = 0x1000 CFLUSH = 0xf - CIBAUD = 0x100f0000 CLOCAL = 0x800 CLOCK_BOOTTIME = 0x7 CLOCK_BOOTTIME_ALARM = 0x9 @@ -232,14 +225,7 @@ const ( CLONE_UNTRACED = 0x800000 CLONE_VFORK = 0x4000 CLONE_VM = 0x100 - CMSPAR = 0x40000000 - CR0 = 0x0 - CR1 = 0x200 - CR2 = 0x400 - CR3 = 0x600 - CRDLY = 0x600 CREAD = 0x80 - CRTSCTS = 0x80000000 CS5 = 0x0 CS6 = 0x10 CS7 = 0x20 @@ -367,9 +353,6 @@ const ( EXTPROC = 0x10000 FD_CLOEXEC = 0x1 FD_SETSIZE = 0x400 - FF0 = 0x0 - FF1 = 0x8000 - FFDLY = 0x8000 FLUSHO = 0x1000 F_DUPFD = 0x0 F_DUPFD_CLOEXEC = 0x406 @@ -405,7 +388,6 @@ const ( F_UNLCK = 0x2 F_WRLCK = 0x1 HUPCL = 0x400 - IBSHIFT = 0x10 ICANON = 0x2 ICMPV6_FILTER = 0x1 ICRNL = 0x100 @@ -637,7 +619,6 @@ const ( IP_XFRM_POLICY = 0x11 ISIG = 0x1 ISTRIP = 0x20 - IUCLC = 0x200 IUTF8 = 0x4000 IXANY = 0x800 IXOFF = 0x1000 @@ -769,13 +750,10 @@ const ( NETLINK_UNUSED = 0x1 NETLINK_USERSOCK = 0x2 NETLINK_XFRM = 0x6 - NL0 = 0x0 - NL1 = 0x100 NLA_ALIGNTO = 0x4 NLA_F_NESTED = 0x8000 NLA_F_NET_BYTEORDER = 0x4000 NLA_HDRLEN = 0x4 - NLDLY = 0x100 NLMSG_ALIGNTO = 0x4 NLMSG_DONE = 0x3 NLMSG_ERROR = 0x2 @@ -800,7 +778,6 @@ const ( OCRNL = 0x8 OFDEL = 0x80 OFILL = 0x40 - OLCUC = 0x2 ONLCR = 0x4 ONLRET = 0x20 ONOCR = 0x10 @@ -1299,23 +1276,10 @@ const ( S_IXGRP = 0x8 S_IXOTH = 0x1 S_IXUSR = 0x40 - TAB0 = 0x0 - TAB1 = 0x800 - TAB2 = 0x1000 - TAB3 = 0x1800 - TABDLY = 0x1800 TCFLSH = 0x540b - TCGETA = 0x5405 - TCGETS = 0x5401 - TCGETS2 = 0x802c542a - TCGETX = 0x5432 TCIFLUSH = 0x0 - TCIOFF = 0x2 TCIOFLUSH = 0x2 - TCION = 0x3 TCOFLUSH = 0x1 - TCOOFF = 0x0 - TCOON = 0x1 TCP_CONGESTION = 0xd TCP_CORK = 0x3 TCP_DEFER_ACCEPT = 0x9 @@ -1335,32 +1299,14 @@ const ( TCP_SYNCNT = 0x7 TCP_WINDOW_CLAMP = 0xa TCSAFLUSH = 0x2 - TCSBRK = 0x5409 - TCSBRKP = 0x5425 - TCSETA = 0x5406 - TCSETAF = 0x5408 - TCSETAW = 0x5407 - TCSETS = 0x5402 - TCSETS2 = 0x402c542b - TCSETSF = 0x5404 - TCSETSF2 = 0x402c542d - TCSETSW = 0x5403 - TCSETSW2 = 0x402c542c - TCSETX = 0x5433 - TCSETXF = 0x5434 - TCSETXW = 0x5435 - TCXONC = 0x540a TIOCCBRK = 0x5428 TIOCCONS = 0x541d TIOCEXCL = 0x540c TIOCGDEV = 0x80045432 TIOCGETD = 0x5424 - TIOCGEXCL = 0x80045440 TIOCGICOUNT = 0x545d TIOCGLCKTRMIOS = 0x5456 TIOCGPGRP = 0x540f - TIOCGPKT = 0x80045438 - TIOCGPTLCK = 0x80045439 TIOCGPTN = 0x80045430 TIOCGRS485 = 0x542e TIOCGSERIAL = 0x541e @@ -1466,8 +1412,6 @@ const ( WORDSIZE = 0x40 WSTOPPED = 0x2 WUNTRACED = 0x2 - XCASE = 0x4 - XTABS = 0x1800 ) // Errors diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go b/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go index 1cc76a78cf4..4535b78b777 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go @@ -110,38 +110,6 @@ const ( ARPHRD_TUNNEL6 = 0x301 ARPHRD_VOID = 0xffff ARPHRD_X25 = 0x10f - B0 = 0x0 - B1000000 = 0x1008 - B110 = 0x3 - B115200 = 0x1002 - B1152000 = 0x1009 - B1200 = 0x9 - B134 = 0x4 - B150 = 0x5 - B1500000 = 0x100a - B1800 = 0xa - B19200 = 0xe - B200 = 0x6 - B2000000 = 0x100b - B230400 = 0x1003 - B2400 = 0xb - B2500000 = 0x100c - B300 = 0x7 - B3000000 = 0x100d - B3500000 = 0x100e - B38400 = 0xf - B4000000 = 0x100f - B460800 = 0x1004 - B4800 = 0xc - B50 = 0x1 - B500000 = 0x1005 - B57600 = 0x1001 - B576000 = 0x1006 - B600 = 0x8 - B75 = 0x2 - B921600 = 0x1007 - B9600 = 0xd - BOTHER = 0x1000 BPF_A = 0x10 BPF_ABS = 0x20 BPF_ADD = 0x0 @@ -182,15 +150,6 @@ const ( BPF_TXA = 0x80 BPF_W = 0x0 BPF_X = 0x8 - BRKINT = 0x2 - BS0 = 0x0 - BS1 = 0x2000 - BSDLY = 0x2000 - CBAUD = 0x100f - CBAUDEX = 0x1000 - CFLUSH = 0xf - CIBAUD = 0x100f0000 - CLOCAL = 0x800 CLOCK_BOOTTIME = 0x7 CLOCK_BOOTTIME_ALARM = 0x9 CLOCK_DEFAULT = 0x0 @@ -228,25 +187,6 @@ const ( CLONE_UNTRACED = 0x800000 CLONE_VFORK = 0x4000 CLONE_VM = 0x100 - CMSPAR = 0x40000000 - CR0 = 0x0 - CR1 = 0x200 - CR2 = 0x400 - CR3 = 0x600 - CRDLY = 0x600 - CREAD = 0x80 - CRTSCTS = 0x80000000 - CS5 = 0x0 - CS6 = 0x10 - CS7 = 0x20 - CS8 = 0x30 - CSIGNAL = 0xff - CSIZE = 0x30 - CSTART = 0x11 - CSTATUS = 0x0 - CSTOP = 0x13 - CSTOPB = 0x40 - CSUSP = 0x1a DT_BLK = 0x6 DT_CHR = 0x2 DT_DIR = 0x4 @@ -258,13 +198,6 @@ const ( DT_WHT = 0xe ELF_NGREG = 0x12 ELF_PRARGSZ = 0x50 - ECHO = 0x8 - ECHOCTL = 0x200 - ECHOE = 0x10 - ECHOK = 0x20 - ECHOKE = 0x800 - ECHONL = 0x40 - ECHOPRT = 0x400 EPOLLERR = 0x8 EPOLLET = -0x80000000 EPOLLHUP = 0x10 @@ -347,15 +280,8 @@ const ( ETH_P_WAN_PPP = 0x7 ETH_P_WCCP = 0x883e ETH_P_X25 = 0x805 - EXTA = 0xe - EXTB = 0xf - EXTPROC = 0x10000 FD_CLOEXEC = 0x1 FD_SETSIZE = 0x400 - FF0 = 0x0 - FF1 = 0x8000 - FFDLY = 0x8000 - FLUSHO = 0x1000 F_DUPFD = 0x0 F_DUPFD_CLOEXEC = 0x406 F_EXLCK = 0x4 @@ -389,12 +315,7 @@ const ( F_ULOCK = 0x0 F_UNLCK = 0x2 F_WRLCK = 0x1 - HUPCL = 0x400 - IBSHIFT = 0x10 - ICANON = 0x2 ICMPV6_FILTER = 0x1 - ICRNL = 0x100 - IEXTEN = 0x8000 IFA_F_DADFAILED = 0x8 IFA_F_DEPRECATED = 0x20 IFA_F_HOMEADDRESS = 0x10 @@ -428,12 +349,6 @@ const ( IFF_UP = 0x1 IFF_VNET_HDR = 0x4000 IFNAMSIZ = 0x10 - IGNBRK = 0x1 - IGNCR = 0x80 - IGNPAR = 0x4 - IMAXBEL = 0x2000 - INLCR = 0x40 - INPCK = 0x10 IN_ACCESS = 0x1 IN_ALL_EVENTS = 0xfff IN_ATTRIB = 0x4 @@ -597,13 +512,6 @@ const ( IP_TTL = 0x2 IP_UNBLOCK_SOURCE = 0x25 IP_XFRM_POLICY = 0x11 - ISIG = 0x1 - ISTRIP = 0x20 - IUCLC = 0x200 - IUTF8 = 0x4000 - IXANY = 0x800 - IXOFF = 0x1000 - IXON = 0x400 LINUX_REBOOT_CMD_CAD_OFF = 0x0 LINUX_REBOOT_CMD_CAD_ON = 0x89abcdef LINUX_REBOOT_CMD_HALT = 0xcdef0123 @@ -727,13 +635,10 @@ const ( NETLINK_UNUSED = 0x1 NETLINK_USERSOCK = 0x2 NETLINK_XFRM = 0x6 - NL0 = 0x0 - NL1 = 0x100 NLA_ALIGNTO = 0x4 NLA_F_NESTED = 0x8000 NLA_F_NET_BYTEORDER = 0x4000 NLA_HDRLEN = 0x4 - NLDLY = 0x100 NLMSG_ALIGNTO = 0x4 NLMSG_DONE = 0x3 NLMSG_ERROR = 0x2 @@ -753,15 +658,6 @@ const ( NLM_F_REPLACE = 0x100 NLM_F_REQUEST = 0x1 NLM_F_ROOT = 0x100 - NOFLSH = 0x80 - OCRNL = 0x8 - OFDEL = 0x80 - OFILL = 0x40 - OLCUC = 0x2 - ONLCR = 0x4 - ONLRET = 0x20 - ONOCR = 0x10 - OPOST = 0x1 O_ACCMODE = 0x3 O_APPEND = 0x400 O_ASYNC = 0x2000 @@ -778,7 +674,6 @@ const ( O_NOCTTY = 0x100 O_NOFOLLOW = 0x8000 O_NONBLOCK = 0x800 - O_PATH = 0x200000 O_RDONLY = 0x0 O_RDWR = 0x2 O_RSYNC = 0x1000 @@ -800,10 +695,6 @@ const ( PACKET_RECV_OUTPUT = 0x3 PACKET_RX_RING = 0x5 PACKET_STATISTICS = 0x6 - PARENB = 0x100 - PARMRK = 0x8 - PARODD = 0x200 - PENDIN = 0x4000 PRIO_PGRP = 0x1 PRIO_PROCESS = 0x0 PRIO_USER = 0x2 @@ -1223,23 +1114,9 @@ const ( S_IXGRP = 0x8 S_IXOTH = 0x1 S_IXUSR = 0x40 - TAB0 = 0x0 - TAB1 = 0x800 - TAB2 = 0x1000 - TAB3 = 0x1800 - TABDLY = 0x1800 - TCFLSH = 0x540b - TCGETA = 0x5405 - TCGETS = 0x5401 - TCGETS2 = 0x802c542a - TCGETX = 0x5432 TCIFLUSH = 0x0 - TCIOFF = 0x2 TCIOFLUSH = 0x2 - TCION = 0x3 TCOFLUSH = 0x1 - TCOOFF = 0x0 - TCOON = 0x1 TCP_CONGESTION = 0xd TCP_CORK = 0x3 TCP_DEFER_ACCEPT = 0x9 @@ -1258,33 +1135,14 @@ const ( TCP_QUICKACK = 0xc TCP_SYNCNT = 0x7 TCP_WINDOW_CLAMP = 0xa - TCSAFLUSH = 0x2 - TCSBRK = 0x5409 - TCSBRKP = 0x5425 - TCSETA = 0x5406 - TCSETAF = 0x5408 - TCSETAW = 0x5407 - TCSETS = 0x5402 - TCSETS2 = 0x402c542b - TCSETSF = 0x5404 - TCSETSF2 = 0x402c542d - TCSETSW = 0x5403 - TCSETSW2 = 0x402c542c - TCSETX = 0x5433 - TCSETXF = 0x5434 - TCSETXW = 0x5435 - TCXONC = 0x540a TIOCCBRK = 0x5428 TIOCCONS = 0x541d TIOCEXCL = 0x540c TIOCGDEV = 0x80045432 TIOCGETD = 0x5424 - TIOCGEXCL = 0x80045440 TIOCGICOUNT = 0x545d TIOCGLCKTRMIOS = 0x5456 TIOCGPGRP = 0x540f - TIOCGPKT = 0x80045438 - TIOCGPTLCK = 0x80045439 TIOCGPTN = 0x80045430 TIOCGRS485 = 0x542e TIOCGSERIAL = 0x541e @@ -1342,7 +1200,6 @@ const ( TIOCSTI = 0x5412 TIOCSWINSZ = 0x5414 TIOCVHANGUP = 0x5437 - TOSTOP = 0x100 TUNATTACHFILTER = 0x400854d5 TUNDETACHFILTER = 0x400854d6 TUNGETFEATURES = 0x800454cf @@ -1360,26 +1217,6 @@ const ( TUNSETSNDBUF = 0x400454d4 TUNSETTXFILTER = 0x400454d1 TUNSETVNETHDRSZ = 0x400454d8 - VDISCARD = 0xd - VEOF = 0x4 - VEOL = 0xb - VEOL2 = 0x10 - VERASE = 0x2 - VINTR = 0x0 - VKILL = 0x3 - VLNEXT = 0xf - VMIN = 0x6 - VQUIT = 0x1 - VREPRINT = 0xc - VSTART = 0x8 - VSTOP = 0x9 - VSUSP = 0xa - VSWTC = 0x7 - VT0 = 0x0 - VT1 = 0x4000 - VTDLY = 0x4000 - VTIME = 0x5 - VWERASE = 0xe WALL = 0x40000000 WCLONE = 0x80000000 WCONTINUED = 0x8 @@ -1390,8 +1227,6 @@ const ( WORDSIZE = 0x20 WSTOPPED = 0x2 WUNTRACED = 0x2 - XCASE = 0x4 - XTABS = 0x1800 ) // Errors diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go index 47027b79c9d..165073f1326 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go @@ -149,7 +149,6 @@ const ( B75 = 0x2 B921600 = 0x1007 B9600 = 0xd - BOTHER = 0x1000 BPF_A = 0x10 BPF_ABS = 0x20 BPF_ADD = 0x0 @@ -193,13 +192,7 @@ const ( BPF_X = 0x8 BPF_XOR = 0xa0 BRKINT = 0x2 - BS0 = 0x0 - BS1 = 0x2000 - BSDLY = 0x2000 - CBAUD = 0x100f - CBAUDEX = 0x1000 CFLUSH = 0xf - CIBAUD = 0x100f0000 CLOCAL = 0x800 CLOCK_BOOTTIME = 0x7 CLOCK_BOOTTIME_ALARM = 0x9 @@ -238,14 +231,7 @@ const ( CLONE_UNTRACED = 0x800000 CLONE_VFORK = 0x4000 CLONE_VM = 0x100 - CMSPAR = 0x40000000 - CR0 = 0x0 - CR1 = 0x200 - CR2 = 0x400 - CR3 = 0x600 - CRDLY = 0x600 CREAD = 0x80 - CRTSCTS = 0x80000000 CS5 = 0x0 CS6 = 0x10 CS7 = 0x20 @@ -381,9 +367,6 @@ const ( EXTPROC = 0x10000 FD_CLOEXEC = 0x1 FD_SETSIZE = 0x400 - FF0 = 0x0 - FF1 = 0x8000 - FFDLY = 0x8000 FLUSHO = 0x1000 F_DUPFD = 0x0 F_DUPFD_CLOEXEC = 0x406 @@ -419,7 +402,6 @@ const ( F_UNLCK = 0x2 F_WRLCK = 0x1 HUPCL = 0x400 - IBSHIFT = 0x10 ICANON = 0x2 ICMPV6_FILTER = 0x1 ICRNL = 0x100 @@ -663,7 +645,6 @@ const ( IP_XFRM_POLICY = 0x11 ISIG = 0x1 ISTRIP = 0x20 - IUCLC = 0x200 IUTF8 = 0x4000 IXANY = 0x800 IXOFF = 0x1000 @@ -801,13 +782,10 @@ const ( NETLINK_UNUSED = 0x1 NETLINK_USERSOCK = 0x2 NETLINK_XFRM = 0x6 - NL0 = 0x0 - NL1 = 0x100 NLA_ALIGNTO = 0x4 NLA_F_NESTED = 0x8000 NLA_F_NET_BYTEORDER = 0x4000 NLA_HDRLEN = 0x4 - NLDLY = 0x100 NLMSG_ALIGNTO = 0x4 NLMSG_DONE = 0x3 NLMSG_ERROR = 0x2 @@ -832,7 +810,6 @@ const ( OCRNL = 0x8 OFDEL = 0x80 OFILL = 0x40 - OLCUC = 0x2 ONLCR = 0x4 ONLRET = 0x20 ONOCR = 0x10 @@ -1355,23 +1332,10 @@ const ( S_IXGRP = 0x8 S_IXOTH = 0x1 S_IXUSR = 0x40 - TAB0 = 0x0 - TAB1 = 0x800 - TAB2 = 0x1000 - TAB3 = 0x1800 - TABDLY = 0x1800 TCFLSH = 0x540b - TCGETA = 0x5405 - TCGETS = 0x5401 - TCGETS2 = 0x802c542a - TCGETX = 0x5432 TCIFLUSH = 0x0 - TCIOFF = 0x2 TCIOFLUSH = 0x2 - TCION = 0x3 TCOFLUSH = 0x1 - TCOOFF = 0x0 - TCOON = 0x1 TCP_CONGESTION = 0xd TCP_COOKIE_IN_ALWAYS = 0x1 TCP_COOKIE_MAX = 0x10 @@ -1410,21 +1374,6 @@ const ( TCP_USER_TIMEOUT = 0x12 TCP_WINDOW_CLAMP = 0xa TCSAFLUSH = 0x2 - TCSBRK = 0x5409 - TCSBRKP = 0x5425 - TCSETA = 0x5406 - TCSETAF = 0x5408 - TCSETAW = 0x5407 - TCSETS = 0x5402 - TCSETS2 = 0x402c542b - TCSETSF = 0x5404 - TCSETSF2 = 0x402c542d - TCSETSW = 0x5403 - TCSETSW2 = 0x402c542c - TCSETX = 0x5433 - TCSETXF = 0x5434 - TCSETXW = 0x5435 - TCXONC = 0x540a TIOCCBRK = 0x5428 TIOCCONS = 0x541d TIOCEXCL = 0x540c @@ -1544,8 +1493,6 @@ const ( WORDSIZE = 0x40 WSTOPPED = 0x2 WUNTRACED = 0x2 - XCASE = 0x4 - XTABS = 0x1800 ) // Errors diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go index 5b90d07ed23..9d908d7199f 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go @@ -150,7 +150,6 @@ const ( B75 = 0x2 B921600 = 0x16 B9600 = 0xd - BOTHER = 0x1f BPF_A = 0x10 BPF_ABS = 0x20 BPF_ADD = 0x0 @@ -194,13 +193,7 @@ const ( BPF_X = 0x8 BPF_XOR = 0xa0 BRKINT = 0x2 - BS0 = 0x0 - BS1 = 0x8000 - BSDLY = 0x8000 - CBAUD = 0xff - CBAUDEX = 0x0 CFLUSH = 0xf - CIBAUD = 0xff0000 CLOCAL = 0x8000 CLOCK_BOOTTIME = 0x7 CLOCK_BOOTTIME_ALARM = 0x9 @@ -239,14 +232,7 @@ const ( CLONE_UNTRACED = 0x800000 CLONE_VFORK = 0x4000 CLONE_VM = 0x100 - CMSPAR = 0x40000000 - CR0 = 0x0 - CR1 = 0x1000 - CR2 = 0x2000 - CR3 = 0x3000 - CRDLY = 0x3000 CREAD = 0x800 - CRTSCTS = 0x80000000 CS5 = 0x0 CS6 = 0x100 CS7 = 0x200 @@ -383,9 +369,6 @@ const ( EXTPROC = 0x10000000 FD_CLOEXEC = 0x1 FD_SETSIZE = 0x400 - FF0 = 0x0 - FF1 = 0x4000 - FFDLY = 0x4000 FLUSHO = 0x800000 F_DUPFD = 0x0 F_DUPFD_CLOEXEC = 0x406 @@ -424,7 +407,6 @@ const ( F_UNLCK = 0x2 F_WRLCK = 0x1 HUPCL = 0x4000 - IBSHIFT = 0x10 ICANON = 0x100 ICMPV6_FILTER = 0x1 ICRNL = 0x100 @@ -653,7 +635,6 @@ const ( IP_XFRM_POLICY = 0x11 ISIG = 0x80 ISTRIP = 0x20 - IUCLC = 0x1000 IUTF8 = 0x4000 IXANY = 0x800 IXOFF = 0x400 @@ -791,15 +772,10 @@ const ( NETLINK_UNUSED = 0x1 NETLINK_USERSOCK = 0x2 NETLINK_XFRM = 0x6 - NL0 = 0x0 - NL1 = 0x100 - NL2 = 0x200 - NL3 = 0x300 NLA_ALIGNTO = 0x4 NLA_F_NESTED = 0x8000 NLA_F_NET_BYTEORDER = 0x4000 NLA_HDRLEN = 0x4 - NLDLY = 0x300 NLMSG_ALIGNTO = 0x4 NLMSG_DONE = 0x3 NLMSG_ERROR = 0x2 @@ -824,7 +800,6 @@ const ( OCRNL = 0x8 OFDEL = 0x80 OFILL = 0x40 - OLCUC = 0x4 ONLCR = 0x2 ONLRET = 0x20 ONOCR = 0x10 @@ -1423,21 +1398,10 @@ const ( S_IXGRP = 0x8 S_IXOTH = 0x1 S_IXUSR = 0x40 - TAB0 = 0x0 - TAB1 = 0x400 - TAB2 = 0x800 - TAB3 = 0xc00 - TABDLY = 0xc00 TCFLSH = 0x2000741f - TCGETA = 0x40147417 - TCGETS = 0x402c7413 TCIFLUSH = 0x0 - TCIOFF = 0x2 TCIOFLUSH = 0x2 - TCION = 0x3 TCOFLUSH = 0x1 - TCOOFF = 0x0 - TCOON = 0x1 TCP_CONGESTION = 0xd TCP_COOKIE_IN_ALWAYS = 0x1 TCP_COOKIE_MAX = 0x10 @@ -1476,15 +1440,6 @@ const ( TCP_USER_TIMEOUT = 0x12 TCP_WINDOW_CLAMP = 0xa TCSAFLUSH = 0x2 - TCSBRK = 0x2000741d - TCSBRKP = 0x5425 - TCSETA = 0x80147418 - TCSETAF = 0x8014741c - TCSETAW = 0x80147419 - TCSETS = 0x802c7414 - TCSETSF = 0x802c7416 - TCSETSW = 0x802c7415 - TCXONC = 0x2000741e TIOCCBRK = 0x5428 TIOCCONS = 0x541d TIOCEXCL = 0x540c @@ -1616,8 +1571,6 @@ const ( WORDSIZE = 0x40 WSTOPPED = 0x2 WUNTRACED = 0x2 - XCASE = 0x4000 - XTABS = 0xc00 ) // Errors diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go index 0861bd5666b..ccf05a27415 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go @@ -149,7 +149,6 @@ const ( B75 = 0x2 B921600 = 0x16 B9600 = 0xd - BOTHER = 0x1f BPF_A = 0x10 BPF_ABS = 0x20 BPF_ADD = 0x0 @@ -193,13 +192,7 @@ const ( BPF_X = 0x8 BPF_XOR = 0xa0 BRKINT = 0x2 - BS0 = 0x0 - BS1 = 0x8000 - BSDLY = 0x8000 - CBAUD = 0xff - CBAUDEX = 0x0 CFLUSH = 0xf - CIBAUD = 0xff0000 CLOCAL = 0x8000 CLOCK_BOOTTIME = 0x7 CLOCK_BOOTTIME_ALARM = 0x9 @@ -238,14 +231,7 @@ const ( CLONE_UNTRACED = 0x800000 CLONE_VFORK = 0x4000 CLONE_VM = 0x100 - CMSPAR = 0x40000000 - CR0 = 0x0 - CR1 = 0x1000 - CR2 = 0x2000 - CR3 = 0x3000 - CRDLY = 0x3000 CREAD = 0x800 - CRTSCTS = 0x80000000 CS5 = 0x0 CS6 = 0x100 CS7 = 0x200 @@ -379,9 +365,6 @@ const ( EXTPROC = 0x10000000 FD_CLOEXEC = 0x1 FD_SETSIZE = 0x400 - FF0 = 0x0 - FF1 = 0x4000 - FFDLY = 0x4000 FLUSHO = 0x800000 F_DUPFD = 0x0 F_DUPFD_CLOEXEC = 0x406 @@ -417,7 +400,6 @@ const ( F_UNLCK = 0x2 F_WRLCK = 0x1 HUPCL = 0x4000 - IBSHIFT = 0x10 ICANON = 0x100 ICMPV6_FILTER = 0x1 ICRNL = 0x100 @@ -661,7 +643,6 @@ const ( IP_XFRM_POLICY = 0x11 ISIG = 0x80 ISTRIP = 0x20 - IUCLC = 0x1000 IUTF8 = 0x4000 IXANY = 0x800 IXOFF = 0x400 @@ -799,15 +780,10 @@ const ( NETLINK_UNUSED = 0x1 NETLINK_USERSOCK = 0x2 NETLINK_XFRM = 0x6 - NL0 = 0x0 - NL1 = 0x100 - NL2 = 0x200 - NL3 = 0x300 NLA_ALIGNTO = 0x4 NLA_F_NESTED = 0x8000 NLA_F_NET_BYTEORDER = 0x4000 NLA_HDRLEN = 0x4 - NLDLY = 0x300 NLMSG_ALIGNTO = 0x4 NLMSG_DONE = 0x3 NLMSG_ERROR = 0x2 @@ -832,7 +808,6 @@ const ( OCRNL = 0x8 OFDEL = 0x80 OFILL = 0x40 - OLCUC = 0x4 ONLCR = 0x2 ONLRET = 0x20 ONOCR = 0x10 @@ -1422,21 +1397,10 @@ const ( S_IXGRP = 0x8 S_IXOTH = 0x1 S_IXUSR = 0x40 - TAB0 = 0x0 - TAB1 = 0x400 - TAB2 = 0x800 - TAB3 = 0xc00 - TABDLY = 0xc00 TCFLSH = 0x2000741f - TCGETA = 0x40147417 - TCGETS = 0x402c7413 TCIFLUSH = 0x0 - TCIOFF = 0x2 TCIOFLUSH = 0x2 - TCION = 0x3 TCOFLUSH = 0x1 - TCOOFF = 0x0 - TCOON = 0x1 TCP_CONGESTION = 0xd TCP_COOKIE_IN_ALWAYS = 0x1 TCP_COOKIE_MAX = 0x10 @@ -1475,15 +1439,6 @@ const ( TCP_USER_TIMEOUT = 0x12 TCP_WINDOW_CLAMP = 0xa TCSAFLUSH = 0x2 - TCSBRK = 0x2000741d - TCSBRKP = 0x5425 - TCSETA = 0x80147418 - TCSETAF = 0x8014741c - TCSETAW = 0x80147419 - TCSETS = 0x802c7414 - TCSETSF = 0x802c7416 - TCSETSW = 0x802c7415 - TCXONC = 0x2000741e TIOCCBRK = 0x5428 TIOCCONS = 0x541d TIOCEXCL = 0x540c @@ -1615,8 +1570,6 @@ const ( WORDSIZE = 0x40 WSTOPPED = 0x2 WUNTRACED = 0x2 - XCASE = 0x4000 - XTABS = 0xc00 ) // Errors diff --git a/vendor/golang.org/x/sys/unix/zerrors_solaris_amd64.go b/vendor/golang.org/x/sys/unix/zerrors_solaris_amd64.go index a08922b9818..afdf7c565ed 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_solaris_amd64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_solaris_amd64.go @@ -161,14 +161,6 @@ const ( BRKINT = 0x2 CFLUSH = 0xf CLOCAL = 0x800 - CLOCK_HIGHRES = 0x4 - CLOCK_LEVEL = 0xa - CLOCK_MONOTONIC = 0x4 - CLOCK_PROCESS_CPUTIME_ID = 0x5 - CLOCK_PROF = 0x2 - CLOCK_REALTIME = 0x3 - CLOCK_THREAD_CPUTIME_ID = 0x2 - CLOCK_VIRTUAL = 0x1 CREAD = 0x80 CS5 = 0x0 CS6 = 0x10 @@ -176,7 +168,6 @@ const ( CS8 = 0x30 CSIZE = 0x30 CSTART = 0x11 - CSTATUS = 0x14 CSTOP = 0x13 CSTOPB = 0x40 CSUSP = 0x1a @@ -766,7 +757,9 @@ const ( SIOCDARP = -0x7fdb96e0 SIOCDELMULTI = -0x7fdf96ce SIOCDELRT = -0x7fcf8df5 + SIOCDIPSECONFIG = -0x7ffb9669 SIOCDXARP = -0x7fff9658 + SIOCFIPSECONFIG = -0x7ffb966b SIOCGARP = -0x3fdb96e1 SIOCGDSTINFO = -0x3fff965c SIOCGENADDR = -0x3fdf96ab @@ -828,6 +821,7 @@ const ( SIOCLIFGETND = -0x3f879672 SIOCLIFREMOVEIF = -0x7f879692 SIOCLIFSETND = -0x7f879671 + SIOCLIPSECONFIG = -0x7ffb9668 SIOCLOWER = -0x7fdf96d7 SIOCSARP = -0x7fdb96e2 SIOCSCTPGOPT = -0x3fef9653 @@ -850,6 +844,7 @@ const ( SIOCSIFNETMASK = -0x7fdf96e6 SIOCSIP6ADDRPOLICY = -0x7fff965d SIOCSIPMSFILTER = -0x7ffb964b + SIOCSIPSECONFIG = -0x7ffb966a SIOCSLGETREQ = -0x3fdf96b9 SIOCSLIFADDR = -0x7f879690 SIOCSLIFBRDADDR = -0x7f879684 @@ -956,8 +951,6 @@ const ( SO_VRRP = 0x1017 SO_WROFF = 0x2 TCFLSH = 0x5407 - TCGETA = 0x5401 - TCGETS = 0x540d TCIFLUSH = 0x0 TCIOFLUSH = 0x2 TCOFLUSH = 0x1 @@ -984,14 +977,6 @@ const ( TCP_RTO_MAX = 0x1b TCP_RTO_MIN = 0x1a TCSAFLUSH = 0x5410 - TCSBRK = 0x5405 - TCSETA = 0x5402 - TCSETAF = 0x5404 - TCSETAW = 0x5403 - TCSETS = 0x540e - TCSETSF = 0x5410 - TCSETSW = 0x540f - TCXONC = 0x5406 TIOC = 0x5400 TIOCCBRK = 0x747a TIOCCDTR = 0x7478 @@ -1067,7 +1052,6 @@ const ( VQUIT = 0x1 VREPRINT = 0xc VSTART = 0x8 - VSTATUS = 0x10 VSTOP = 0x9 VSUSP = 0xa VSWTCH = 0x7 @@ -1231,7 +1215,6 @@ const ( SIGFREEZE = syscall.Signal(0x22) SIGHUP = syscall.Signal(0x1) SIGILL = syscall.Signal(0x4) - SIGINFO = syscall.Signal(0x29) SIGINT = syscall.Signal(0x2) SIGIO = syscall.Signal(0x16) SIGIOT = syscall.Signal(0x6) @@ -1432,5 +1415,4 @@ var signals = [...]string{ 38: "resource Control Exceeded", 39: "reserved for JVM 1", 40: "reserved for JVM 2", - 41: "information Request", } diff --git a/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go b/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go index 74606b2f499..e28b044e9fe 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go @@ -1415,22 +1415,6 @@ func writelen(fd int, buf *byte, nbuf int) (n int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall6(SYS_FCHMODAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0) - use(unsafe.Pointer(_p0)) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func gettimeofday(tp *Timeval) (sec int64, usec int32, err error) { r0, r1, e1 := RawSyscall(SYS_GETTIMEOFDAY, uintptr(unsafe.Pointer(tp)), 0, 0) sec = int64(r0) diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_386.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_386.go index ff6c39dc244..81ae498a38f 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_linux_386.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_386.go @@ -788,16 +788,6 @@ func prlimit(pid int, resource int, old *Rlimit, newlimit *Rlimit) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Prctl(option int, arg2 uintptr, arg3 uintptr, arg4 uintptr, arg5 uintptr) (err error) { - _, _, e1 := Syscall6(SYS_PRCTL, uintptr(option), uintptr(arg2), uintptr(arg3), uintptr(arg4), uintptr(arg5), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func read(fd int, p []byte) (n int, err error) { var _p0 unsafe.Pointer if len(p) > 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_amd64.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_amd64.go index c2438522d34..2adb9284a34 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_linux_amd64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_amd64.go @@ -788,16 +788,6 @@ func prlimit(pid int, resource int, old *Rlimit, newlimit *Rlimit) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Prctl(option int, arg2 uintptr, arg3 uintptr, arg4 uintptr, arg5 uintptr) (err error) { - _, _, e1 := Syscall6(SYS_PRCTL, uintptr(option), uintptr(arg2), uintptr(arg3), uintptr(arg4), uintptr(arg5), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func read(fd int, p []byte) (n int, err error) { var _p0 unsafe.Pointer if len(p) > 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_arm.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_arm.go index dd66c975879..ca00ed3dfb9 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_linux_arm.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_arm.go @@ -788,16 +788,6 @@ func prlimit(pid int, resource int, old *Rlimit, newlimit *Rlimit) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Prctl(option int, arg2 uintptr, arg3 uintptr, arg4 uintptr, arg5 uintptr) (err error) { - _, _, e1 := Syscall6(SYS_PRCTL, uintptr(option), uintptr(arg2), uintptr(arg3), uintptr(arg4), uintptr(arg5), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func read(fd int, p []byte) (n int, err error) { var _p0 unsafe.Pointer if len(p) > 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_arm64.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_arm64.go index d0a6ed82927..8eafcebcbfd 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_linux_arm64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_arm64.go @@ -788,16 +788,6 @@ func prlimit(pid int, resource int, old *Rlimit, newlimit *Rlimit) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Prctl(option int, arg2 uintptr, arg3 uintptr, arg4 uintptr, arg5 uintptr) (err error) { - _, _, e1 := Syscall6(SYS_PRCTL, uintptr(option), uintptr(arg2), uintptr(arg3), uintptr(arg4), uintptr(arg5), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func read(fd int, p []byte) (n int, err error) { var _p0 unsafe.Pointer if len(p) > 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64.go index f58a3ff2f92..008a52638b9 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64.go @@ -788,16 +788,6 @@ func prlimit(pid int, resource int, old *Rlimit, newlimit *Rlimit) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Prctl(option int, arg2 uintptr, arg3 uintptr, arg4 uintptr, arg5 uintptr) (err error) { - _, _, e1 := Syscall6(SYS_PRCTL, uintptr(option), uintptr(arg2), uintptr(arg3), uintptr(arg4), uintptr(arg5), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func read(fd int, p []byte) (n int, err error) { var _p0 unsafe.Pointer if len(p) > 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64le.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64le.go index 22fc7a45725..d91f763af9d 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64le.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64le.go @@ -788,16 +788,6 @@ func prlimit(pid int, resource int, old *Rlimit, newlimit *Rlimit) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Prctl(option int, arg2 uintptr, arg3 uintptr, arg4 uintptr, arg5 uintptr) (err error) { - _, _, e1 := Syscall6(SYS_PRCTL, uintptr(option), uintptr(arg2), uintptr(arg3), uintptr(arg4), uintptr(arg5), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func read(fd int, p []byte) (n int, err error) { var _p0 unsafe.Pointer if len(p) > 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_solaris_amd64.go b/vendor/golang.org/x/sys/unix/zsyscall_solaris_amd64.go index 8d2a8365b2f..95cb1f65f7e 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_solaris_amd64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_solaris_amd64.go @@ -10,19 +10,11 @@ import ( "unsafe" ) -//go:cgo_import_dynamic libc_getsockname getsockname "libsocket.so" -//go:cgo_import_dynamic libc_getcwd getcwd "libc.so" //go:cgo_import_dynamic libc_getgroups getgroups "libc.so" //go:cgo_import_dynamic libc_setgroups setgroups "libc.so" -//go:cgo_import_dynamic libc_utimes utimes "libc.so" -//go:cgo_import_dynamic libc_utimensat utimensat "libc.so" //go:cgo_import_dynamic libc_fcntl fcntl "libc.so" -//go:cgo_import_dynamic libc_futimesat futimesat "libc.so" -//go:cgo_import_dynamic libc_accept accept "libsocket.so" -//go:cgo_import_dynamic libc_recvmsg recvmsg "libsocket.so" -//go:cgo_import_dynamic libc_sendmsg sendmsg "libsocket.so" -//go:cgo_import_dynamic libc_acct acct "libc.so" -//go:cgo_import_dynamic libc_ioctl ioctl "libc.so" +//go:cgo_import_dynamic libsocket_accept accept "libsocket.so" +//go:cgo_import_dynamic libsocket_sendmsg sendmsg "libsocket.so" //go:cgo_import_dynamic libc_access access "libc.so" //go:cgo_import_dynamic libc_adjtime adjtime "libc.so" //go:cgo_import_dynamic libc_chdir chdir "libc.so" @@ -30,65 +22,44 @@ import ( //go:cgo_import_dynamic libc_chown chown "libc.so" //go:cgo_import_dynamic libc_chroot chroot "libc.so" //go:cgo_import_dynamic libc_close close "libc.so" -//go:cgo_import_dynamic libc_creat creat "libc.so" //go:cgo_import_dynamic libc_dup dup "libc.so" -//go:cgo_import_dynamic libc_dup2 dup2 "libc.so" //go:cgo_import_dynamic libc_exit exit "libc.so" //go:cgo_import_dynamic libc_fchdir fchdir "libc.so" //go:cgo_import_dynamic libc_fchmod fchmod "libc.so" -//go:cgo_import_dynamic libc_fchmodat fchmodat "libc.so" //go:cgo_import_dynamic libc_fchown fchown "libc.so" -//go:cgo_import_dynamic libc_fchownat fchownat "libc.so" -//go:cgo_import_dynamic libc_fdatasync fdatasync "libc.so" //go:cgo_import_dynamic libc_fpathconf fpathconf "libc.so" //go:cgo_import_dynamic libc_fstat fstat "libc.so" //go:cgo_import_dynamic libc_getdents getdents "libc.so" //go:cgo_import_dynamic libc_getgid getgid "libc.so" //go:cgo_import_dynamic libc_getpid getpid "libc.so" -//go:cgo_import_dynamic libc_getpgid getpgid "libc.so" -//go:cgo_import_dynamic libc_getpgrp getpgrp "libc.so" //go:cgo_import_dynamic libc_geteuid geteuid "libc.so" //go:cgo_import_dynamic libc_getegid getegid "libc.so" //go:cgo_import_dynamic libc_getppid getppid "libc.so" //go:cgo_import_dynamic libc_getpriority getpriority "libc.so" //go:cgo_import_dynamic libc_getrlimit getrlimit "libc.so" -//go:cgo_import_dynamic libc_getrusage getrusage "libc.so" //go:cgo_import_dynamic libc_gettimeofday gettimeofday "libc.so" //go:cgo_import_dynamic libc_getuid getuid "libc.so" //go:cgo_import_dynamic libc_kill kill "libc.so" //go:cgo_import_dynamic libc_lchown lchown "libc.so" //go:cgo_import_dynamic libc_link link "libc.so" -//go:cgo_import_dynamic libc_listen listen "libsocket.so" +//go:cgo_import_dynamic libsocket_listen listen "libsocket.so" //go:cgo_import_dynamic libc_lstat lstat "libc.so" //go:cgo_import_dynamic libc_madvise madvise "libc.so" //go:cgo_import_dynamic libc_mkdir mkdir "libc.so" -//go:cgo_import_dynamic libc_mkdirat mkdirat "libc.so" -//go:cgo_import_dynamic libc_mkfifo mkfifo "libc.so" -//go:cgo_import_dynamic libc_mkfifoat mkfifoat "libc.so" //go:cgo_import_dynamic libc_mknod mknod "libc.so" -//go:cgo_import_dynamic libc_mknodat mknodat "libc.so" -//go:cgo_import_dynamic libc_mlock mlock "libc.so" -//go:cgo_import_dynamic libc_mlockall mlockall "libc.so" -//go:cgo_import_dynamic libc_mprotect mprotect "libc.so" -//go:cgo_import_dynamic libc_munlock munlock "libc.so" -//go:cgo_import_dynamic libc_munlockall munlockall "libc.so" //go:cgo_import_dynamic libc_nanosleep nanosleep "libc.so" //go:cgo_import_dynamic libc_open open "libc.so" -//go:cgo_import_dynamic libc_openat openat "libc.so" //go:cgo_import_dynamic libc_pathconf pathconf "libc.so" -//go:cgo_import_dynamic libc_pause pause "libc.so" //go:cgo_import_dynamic libc_pread pread "libc.so" //go:cgo_import_dynamic libc_pwrite pwrite "libc.so" //go:cgo_import_dynamic libc_read read "libc.so" //go:cgo_import_dynamic libc_readlink readlink "libc.so" //go:cgo_import_dynamic libc_rename rename "libc.so" -//go:cgo_import_dynamic libc_renameat renameat "libc.so" //go:cgo_import_dynamic libc_rmdir rmdir "libc.so" //go:cgo_import_dynamic libc_lseek lseek "libc.so" //go:cgo_import_dynamic libc_setegid setegid "libc.so" //go:cgo_import_dynamic libc_seteuid seteuid "libc.so" //go:cgo_import_dynamic libc_setgid setgid "libc.so" -//go:cgo_import_dynamic libc_sethostname sethostname "libc.so" //go:cgo_import_dynamic libc_setpgid setpgid "libc.so" //go:cgo_import_dynamic libc_setpriority setpriority "libc.so" //go:cgo_import_dynamic libc_setregid setregid "libc.so" @@ -96,48 +67,36 @@ import ( //go:cgo_import_dynamic libc_setrlimit setrlimit "libc.so" //go:cgo_import_dynamic libc_setsid setsid "libc.so" //go:cgo_import_dynamic libc_setuid setuid "libc.so" -//go:cgo_import_dynamic libc_shutdown shutdown "libsocket.so" +//go:cgo_import_dynamic libsocket_shutdown shutdown "libsocket.so" //go:cgo_import_dynamic libc_stat stat "libc.so" //go:cgo_import_dynamic libc_symlink symlink "libc.so" //go:cgo_import_dynamic libc_sync sync "libc.so" -//go:cgo_import_dynamic libc_times times "libc.so" //go:cgo_import_dynamic libc_truncate truncate "libc.so" //go:cgo_import_dynamic libc_fsync fsync "libc.so" //go:cgo_import_dynamic libc_ftruncate ftruncate "libc.so" //go:cgo_import_dynamic libc_umask umask "libc.so" -//go:cgo_import_dynamic libc_uname uname "libc.so" -//go:cgo_import_dynamic libc_umount umount "libc.so" //go:cgo_import_dynamic libc_unlink unlink "libc.so" -//go:cgo_import_dynamic libc_unlinkat unlinkat "libc.so" -//go:cgo_import_dynamic libc_ustat ustat "libc.so" -//go:cgo_import_dynamic libc_utime utime "libc.so" -//go:cgo_import_dynamic libc_bind bind "libsocket.so" -//go:cgo_import_dynamic libc_connect connect "libsocket.so" +//go:cgo_import_dynamic libc_utimes utimes "libc.so" +//go:cgo_import_dynamic libsocket_bind bind "libsocket.so" +//go:cgo_import_dynamic libsocket_connect connect "libsocket.so" //go:cgo_import_dynamic libc_mmap mmap "libc.so" //go:cgo_import_dynamic libc_munmap munmap "libc.so" -//go:cgo_import_dynamic libc_sendto sendto "libsocket.so" -//go:cgo_import_dynamic libc_socket socket "libsocket.so" -//go:cgo_import_dynamic libc_socketpair socketpair "libsocket.so" +//go:cgo_import_dynamic libsocket_sendto sendto "libsocket.so" +//go:cgo_import_dynamic libsocket_socket socket "libsocket.so" +//go:cgo_import_dynamic libsocket_socketpair socketpair "libsocket.so" //go:cgo_import_dynamic libc_write write "libc.so" -//go:cgo_import_dynamic libc_getsockopt getsockopt "libsocket.so" -//go:cgo_import_dynamic libc_getpeername getpeername "libsocket.so" -//go:cgo_import_dynamic libc_setsockopt setsockopt "libsocket.so" -//go:cgo_import_dynamic libc_recvfrom recvfrom "libsocket.so" -//go:cgo_import_dynamic libc_sysconf sysconf "libc.so" +//go:cgo_import_dynamic libsocket_getsockopt getsockopt "libsocket.so" +//go:cgo_import_dynamic libsocket_getpeername getpeername "libsocket.so" +//go:cgo_import_dynamic libsocket_getsockname getsockname "libsocket.so" +//go:cgo_import_dynamic libsocket_setsockopt setsockopt "libsocket.so" +//go:cgo_import_dynamic libsocket_recvfrom recvfrom "libsocket.so" +//go:cgo_import_dynamic libsocket_recvmsg recvmsg "libsocket.so" -//go:linkname procgetsockname libc_getsockname -//go:linkname procGetcwd libc_getcwd //go:linkname procgetgroups libc_getgroups //go:linkname procsetgroups libc_setgroups -//go:linkname procutimes libc_utimes -//go:linkname procutimensat libc_utimensat //go:linkname procfcntl libc_fcntl -//go:linkname procfutimesat libc_futimesat -//go:linkname procaccept libc_accept -//go:linkname procrecvmsg libc_recvmsg -//go:linkname procsendmsg libc_sendmsg -//go:linkname procacct libc_acct -//go:linkname procioctl libc_ioctl +//go:linkname procaccept libsocket_accept +//go:linkname procsendmsg libsocket_sendmsg //go:linkname procAccess libc_access //go:linkname procAdjtime libc_adjtime //go:linkname procChdir libc_chdir @@ -145,65 +104,44 @@ import ( //go:linkname procChown libc_chown //go:linkname procChroot libc_chroot //go:linkname procClose libc_close -//go:linkname procCreat libc_creat //go:linkname procDup libc_dup -//go:linkname procDup2 libc_dup2 //go:linkname procExit libc_exit //go:linkname procFchdir libc_fchdir //go:linkname procFchmod libc_fchmod -//go:linkname procFchmodat libc_fchmodat //go:linkname procFchown libc_fchown -//go:linkname procFchownat libc_fchownat -//go:linkname procFdatasync libc_fdatasync //go:linkname procFpathconf libc_fpathconf //go:linkname procFstat libc_fstat //go:linkname procGetdents libc_getdents //go:linkname procGetgid libc_getgid //go:linkname procGetpid libc_getpid -//go:linkname procGetpgid libc_getpgid -//go:linkname procGetpgrp libc_getpgrp //go:linkname procGeteuid libc_geteuid //go:linkname procGetegid libc_getegid //go:linkname procGetppid libc_getppid //go:linkname procGetpriority libc_getpriority //go:linkname procGetrlimit libc_getrlimit -//go:linkname procGetrusage libc_getrusage //go:linkname procGettimeofday libc_gettimeofday //go:linkname procGetuid libc_getuid //go:linkname procKill libc_kill //go:linkname procLchown libc_lchown //go:linkname procLink libc_link -//go:linkname proclisten libc_listen +//go:linkname proclisten libsocket_listen //go:linkname procLstat libc_lstat //go:linkname procMadvise libc_madvise //go:linkname procMkdir libc_mkdir -//go:linkname procMkdirat libc_mkdirat -//go:linkname procMkfifo libc_mkfifo -//go:linkname procMkfifoat libc_mkfifoat //go:linkname procMknod libc_mknod -//go:linkname procMknodat libc_mknodat -//go:linkname procMlock libc_mlock -//go:linkname procMlockall libc_mlockall -//go:linkname procMprotect libc_mprotect -//go:linkname procMunlock libc_munlock -//go:linkname procMunlockall libc_munlockall //go:linkname procNanosleep libc_nanosleep //go:linkname procOpen libc_open -//go:linkname procOpenat libc_openat //go:linkname procPathconf libc_pathconf -//go:linkname procPause libc_pause //go:linkname procPread libc_pread //go:linkname procPwrite libc_pwrite //go:linkname procread libc_read //go:linkname procReadlink libc_readlink //go:linkname procRename libc_rename -//go:linkname procRenameat libc_renameat //go:linkname procRmdir libc_rmdir //go:linkname proclseek libc_lseek //go:linkname procSetegid libc_setegid //go:linkname procSeteuid libc_seteuid //go:linkname procSetgid libc_setgid -//go:linkname procSethostname libc_sethostname //go:linkname procSetpgid libc_setpgid //go:linkname procSetpriority libc_setpriority //go:linkname procSetregid libc_setregid @@ -211,49 +149,37 @@ import ( //go:linkname procSetrlimit libc_setrlimit //go:linkname procSetsid libc_setsid //go:linkname procSetuid libc_setuid -//go:linkname procshutdown libc_shutdown +//go:linkname procshutdown libsocket_shutdown //go:linkname procStat libc_stat //go:linkname procSymlink libc_symlink //go:linkname procSync libc_sync -//go:linkname procTimes libc_times //go:linkname procTruncate libc_truncate //go:linkname procFsync libc_fsync //go:linkname procFtruncate libc_ftruncate //go:linkname procUmask libc_umask -//go:linkname procUname libc_uname -//go:linkname procumount libc_umount //go:linkname procUnlink libc_unlink -//go:linkname procUnlinkat libc_unlinkat -//go:linkname procUstat libc_ustat -//go:linkname procUtime libc_utime -//go:linkname procbind libc_bind -//go:linkname procconnect libc_connect +//go:linkname procUtimes libc_utimes +//go:linkname procbind libsocket_bind +//go:linkname procconnect libsocket_connect //go:linkname procmmap libc_mmap //go:linkname procmunmap libc_munmap -//go:linkname procsendto libc_sendto -//go:linkname procsocket libc_socket -//go:linkname procsocketpair libc_socketpair +//go:linkname procsendto libsocket_sendto +//go:linkname procsocket libsocket_socket +//go:linkname procsocketpair libsocket_socketpair //go:linkname procwrite libc_write -//go:linkname procgetsockopt libc_getsockopt -//go:linkname procgetpeername libc_getpeername -//go:linkname procsetsockopt libc_setsockopt -//go:linkname procrecvfrom libc_recvfrom -//go:linkname procsysconf libc_sysconf +//go:linkname procgetsockopt libsocket_getsockopt +//go:linkname procgetpeername libsocket_getpeername +//go:linkname procgetsockname libsocket_getsockname +//go:linkname procsetsockopt libsocket_setsockopt +//go:linkname procrecvfrom libsocket_recvfrom +//go:linkname procrecvmsg libsocket_recvmsg var ( - procgetsockname, - procGetcwd, procgetgroups, procsetgroups, - procutimes, - procutimensat, procfcntl, - procfutimesat, procaccept, - procrecvmsg, procsendmsg, - procacct, - procioctl, procAccess, procAdjtime, procChdir, @@ -261,29 +187,21 @@ var ( procChown, procChroot, procClose, - procCreat, procDup, - procDup2, procExit, procFchdir, procFchmod, - procFchmodat, procFchown, - procFchownat, - procFdatasync, procFpathconf, procFstat, procGetdents, procGetgid, procGetpid, - procGetpgid, - procGetpgrp, procGeteuid, procGetegid, procGetppid, procGetpriority, procGetrlimit, - procGetrusage, procGettimeofday, procGetuid, procKill, @@ -293,33 +211,20 @@ var ( procLstat, procMadvise, procMkdir, - procMkdirat, - procMkfifo, - procMkfifoat, procMknod, - procMknodat, - procMlock, - procMlockall, - procMprotect, - procMunlock, - procMunlockall, procNanosleep, procOpen, - procOpenat, procPathconf, - procPause, procPread, procPwrite, procread, procReadlink, procRename, - procRenameat, procRmdir, proclseek, procSetegid, procSeteuid, procSetgid, - procSethostname, procSetpgid, procSetpriority, procSetregid, @@ -331,17 +236,12 @@ var ( procStat, procSymlink, procSync, - procTimes, procTruncate, procFsync, procFtruncate, procUmask, - procUname, - procumount, procUnlink, - procUnlinkat, - procUstat, - procUtime, + procUtimes, procbind, procconnect, procmmap, @@ -352,32 +252,12 @@ var ( procwrite, procgetsockopt, procgetpeername, + procgetsockname, procsetsockopt, procrecvfrom, - procsysconf syscallFunc + procrecvmsg syscallFunc ) -func getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) { - _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procgetsockname)), 3, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), 0, 0, 0) - if e1 != 0 { - err = e1 - } - return -} - -func Getcwd(buf []byte) (n int, err error) { - var _p0 *byte - if len(buf) > 0 { - _p0 = &buf[0] - } - r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procGetcwd)), 2, uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), 0, 0, 0, 0) - n = int(r0) - if e1 != 0 { - err = e1 - } - return -} - func getgroups(ngid int, gid *_Gid_t) (n int, err error) { r0, _, e1 := rawSysvicall6(uintptr(unsafe.Pointer(&procgetgroups)), 2, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0, 0, 0, 0) n = int(r0) @@ -395,34 +275,6 @@ func setgroups(ngid int, gid *_Gid_t) (err error) { return } -func utimes(path string, times *[2]Timeval) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procutimes)), 2, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), 0, 0, 0, 0) - use(unsafe.Pointer(_p0)) - if e1 != 0 { - err = e1 - } - return -} - -func utimensat(fd int, path string, times *[2]Timespec, flag int) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procutimensat)), 4, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), uintptr(flag), 0, 0) - use(unsafe.Pointer(_p0)) - if e1 != 0 { - err = e1 - } - return -} - func fcntl(fd int, cmd int, arg int) (val int, err error) { r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procfcntl)), 3, uintptr(fd), uintptr(cmd), uintptr(arg), 0, 0, 0) val = int(r0) @@ -432,14 +284,6 @@ func fcntl(fd int, cmd int, arg int) (val int, err error) { return } -func futimesat(fildes int, path *byte, times *[2]Timeval) (err error) { - _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procfutimesat)), 3, uintptr(fildes), uintptr(unsafe.Pointer(path)), uintptr(unsafe.Pointer(times)), 0, 0, 0) - if e1 != 0 { - err = e1 - } - return -} - func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) { r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procaccept)), 3, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), 0, 0, 0) fd = int(r0) @@ -449,15 +293,6 @@ func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) { return } -func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) { - r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procrecvmsg)), 3, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags), 0, 0, 0) - n = int(r0) - if e1 != 0 { - err = e1 - } - return -} - func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) { r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procsendmsg)), 3, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags), 0, 0, 0) n = int(r0) @@ -467,22 +302,6 @@ func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) { return } -func acct(path *byte) (err error) { - _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procacct)), 1, uintptr(unsafe.Pointer(path)), 0, 0, 0, 0, 0) - if e1 != 0 { - err = e1 - } - return -} - -func ioctl(fd int, req int, arg uintptr) (err error) { - _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procioctl)), 3, uintptr(fd), uintptr(req), uintptr(arg), 0, 0, 0) - if e1 != 0 { - err = e1 - } - return -} - func Access(path string, mode uint32) (err error) { var _p0 *byte _p0, err = BytePtrFromString(path) @@ -569,21 +388,6 @@ func Close(fd int) (err error) { return } -func Creat(path string, mode uint32) (fd int, err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procCreat)), 2, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0, 0, 0, 0) - use(unsafe.Pointer(_p0)) - fd = int(r0) - if e1 != 0 { - err = e1 - } - return -} - func Dup(fd int) (nfd int, err error) { r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procDup)), 1, uintptr(fd), 0, 0, 0, 0, 0) nfd = int(r0) @@ -593,14 +397,6 @@ func Dup(fd int) (nfd int, err error) { return } -func Dup2(oldfd int, newfd int) (err error) { - _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procDup2)), 2, uintptr(oldfd), uintptr(newfd), 0, 0, 0, 0) - if e1 != 0 { - err = e1 - } - return -} - func Exit(code int) { sysvicall6(uintptr(unsafe.Pointer(&procExit)), 1, uintptr(code), 0, 0, 0, 0, 0) return @@ -622,20 +418,6 @@ func Fchmod(fd int, mode uint32) (err error) { return } -func Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procFchmodat)), 4, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0) - use(unsafe.Pointer(_p0)) - if e1 != 0 { - err = e1 - } - return -} - func Fchown(fd int, uid int, gid int) (err error) { _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procFchown)), 3, uintptr(fd), uintptr(uid), uintptr(gid), 0, 0, 0) if e1 != 0 { @@ -644,28 +426,6 @@ func Fchown(fd int, uid int, gid int) (err error) { return } -func Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procFchownat)), 5, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid), uintptr(flags), 0) - use(unsafe.Pointer(_p0)) - if e1 != 0 { - err = e1 - } - return -} - -func Fdatasync(fd int) (err error) { - _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procFdatasync)), 1, uintptr(fd), 0, 0, 0, 0, 0) - if e1 != 0 { - err = e1 - } - return -} - func Fpathconf(fd int, name int) (val int, err error) { r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procFpathconf)), 2, uintptr(fd), uintptr(name), 0, 0, 0, 0) val = int(r0) @@ -708,24 +468,6 @@ func Getpid() (pid int) { return } -func Getpgid(pid int) (pgid int, err error) { - r0, _, e1 := rawSysvicall6(uintptr(unsafe.Pointer(&procGetpgid)), 1, uintptr(pid), 0, 0, 0, 0, 0) - pgid = int(r0) - if e1 != 0 { - err = e1 - } - return -} - -func Getpgrp() (pgid int, err error) { - r0, _, e1 := rawSysvicall6(uintptr(unsafe.Pointer(&procGetpgrp)), 0, 0, 0, 0, 0, 0, 0) - pgid = int(r0) - if e1 != 0 { - err = e1 - } - return -} - func Geteuid() (euid int) { r0, _, _ := sysvicall6(uintptr(unsafe.Pointer(&procGeteuid)), 0, 0, 0, 0, 0, 0, 0) euid = int(r0) @@ -761,14 +503,6 @@ func Getrlimit(which int, lim *Rlimit) (err error) { return } -func Getrusage(who int, rusage *Rusage) (err error) { - _, _, e1 := rawSysvicall6(uintptr(unsafe.Pointer(&procGetrusage)), 2, uintptr(who), uintptr(unsafe.Pointer(rusage)), 0, 0, 0, 0) - if e1 != 0 { - err = e1 - } - return -} - func Gettimeofday(tv *Timeval) (err error) { _, _, e1 := rawSysvicall6(uintptr(unsafe.Pointer(&procGettimeofday)), 1, uintptr(unsafe.Pointer(tv)), 0, 0, 0, 0, 0) if e1 != 0 { @@ -873,48 +607,6 @@ func Mkdir(path string, mode uint32) (err error) { return } -func Mkdirat(dirfd int, path string, mode uint32) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procMkdirat)), 3, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0, 0, 0) - use(unsafe.Pointer(_p0)) - if e1 != 0 { - err = e1 - } - return -} - -func Mkfifo(path string, mode uint32) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procMkfifo)), 2, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0, 0, 0, 0) - use(unsafe.Pointer(_p0)) - if e1 != 0 { - err = e1 - } - return -} - -func Mkfifoat(dirfd int, path string, mode uint32) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procMkfifoat)), 3, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0, 0, 0) - use(unsafe.Pointer(_p0)) - if e1 != 0 { - err = e1 - } - return -} - func Mknod(path string, mode uint32, dev int) (err error) { var _p0 *byte _p0, err = BytePtrFromString(path) @@ -929,72 +621,6 @@ func Mknod(path string, mode uint32, dev int) (err error) { return } -func Mknodat(dirfd int, path string, mode uint32, dev int) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procMknodat)), 4, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev), 0, 0) - use(unsafe.Pointer(_p0)) - if e1 != 0 { - err = e1 - } - return -} - -func Mlock(b []byte) (err error) { - var _p0 *byte - if len(b) > 0 { - _p0 = &b[0] - } - _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procMlock)), 2, uintptr(unsafe.Pointer(_p0)), uintptr(len(b)), 0, 0, 0, 0) - if e1 != 0 { - err = e1 - } - return -} - -func Mlockall(flags int) (err error) { - _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procMlockall)), 1, uintptr(flags), 0, 0, 0, 0, 0) - if e1 != 0 { - err = e1 - } - return -} - -func Mprotect(b []byte, prot int) (err error) { - var _p0 *byte - if len(b) > 0 { - _p0 = &b[0] - } - _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procMprotect)), 3, uintptr(unsafe.Pointer(_p0)), uintptr(len(b)), uintptr(prot), 0, 0, 0) - if e1 != 0 { - err = e1 - } - return -} - -func Munlock(b []byte) (err error) { - var _p0 *byte - if len(b) > 0 { - _p0 = &b[0] - } - _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procMunlock)), 2, uintptr(unsafe.Pointer(_p0)), uintptr(len(b)), 0, 0, 0, 0) - if e1 != 0 { - err = e1 - } - return -} - -func Munlockall() (err error) { - _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procMunlockall)), 0, 0, 0, 0, 0, 0, 0) - if e1 != 0 { - err = e1 - } - return -} - func Nanosleep(time *Timespec, leftover *Timespec) (err error) { _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procNanosleep)), 2, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0, 0, 0, 0) if e1 != 0 { @@ -1018,21 +644,6 @@ func Open(path string, mode int, perm uint32) (fd int, err error) { return } -func Openat(dirfd int, path string, flags int, mode uint32) (fd int, err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procOpenat)), 4, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags), uintptr(mode), 0, 0) - use(unsafe.Pointer(_p0)) - fd = int(r0) - if e1 != 0 { - err = e1 - } - return -} - func Pathconf(path string, name int) (val int, err error) { var _p0 *byte _p0, err = BytePtrFromString(path) @@ -1048,14 +659,6 @@ func Pathconf(path string, name int) (val int, err error) { return } -func Pause() (err error) { - _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procPause)), 0, 0, 0, 0, 0, 0, 0) - if e1 != 0 { - err = e1 - } - return -} - func Pread(fd int, p []byte, offset int64) (n int, err error) { var _p0 *byte if len(p) > 0 { @@ -1134,26 +737,6 @@ func Rename(from string, to string) (err error) { return } -func Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(oldpath) - if err != nil { - return - } - var _p1 *byte - _p1, err = BytePtrFromString(newpath) - if err != nil { - return - } - _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procRenameat)), 4, uintptr(olddirfd), uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1)), 0, 0) - use(unsafe.Pointer(_p0)) - use(unsafe.Pointer(_p1)) - if e1 != 0 { - err = e1 - } - return -} - func Rmdir(path string) (err error) { var _p0 *byte _p0, err = BytePtrFromString(path) @@ -1201,18 +784,6 @@ func Setgid(gid int) (err error) { return } -func Sethostname(p []byte) (err error) { - var _p0 *byte - if len(p) > 0 { - _p0 = &p[0] - } - _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procSethostname)), 2, uintptr(unsafe.Pointer(_p0)), uintptr(len(p)), 0, 0, 0, 0) - if e1 != 0 { - err = e1 - } - return -} - func Setpgid(pid int, pgid int) (err error) { _, _, e1 := rawSysvicall6(uintptr(unsafe.Pointer(&procSetpgid)), 2, uintptr(pid), uintptr(pgid), 0, 0, 0, 0) if e1 != 0 { @@ -1320,15 +891,6 @@ func Sync() (err error) { return } -func Times(tms *Tms) (ticks uintptr, err error) { - r0, _, e1 := rawSysvicall6(uintptr(unsafe.Pointer(&procTimes)), 1, uintptr(unsafe.Pointer(tms)), 0, 0, 0, 0, 0) - ticks = uintptr(r0) - if e1 != 0 { - err = e1 - } - return -} - func Truncate(path string, length int64) (err error) { var _p0 *byte _p0, err = BytePtrFromString(path) @@ -1359,34 +921,12 @@ func Ftruncate(fd int, length int64) (err error) { return } -func Umask(mask int) (oldmask int) { - r0, _, _ := sysvicall6(uintptr(unsafe.Pointer(&procUmask)), 1, uintptr(mask), 0, 0, 0, 0, 0) +func Umask(newmask int) (oldmask int) { + r0, _, _ := sysvicall6(uintptr(unsafe.Pointer(&procUmask)), 1, uintptr(newmask), 0, 0, 0, 0, 0) oldmask = int(r0) return } -func Uname(buf *Utsname) (err error) { - _, _, e1 := rawSysvicall6(uintptr(unsafe.Pointer(&procUname)), 1, uintptr(unsafe.Pointer(buf)), 0, 0, 0, 0, 0) - if e1 != 0 { - err = e1 - } - return -} - -func Unmount(target string, flags int) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(target) - if err != nil { - return - } - _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procumount)), 2, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0, 0, 0, 0) - use(unsafe.Pointer(_p0)) - if e1 != 0 { - err = e1 - } - return -} - func Unlink(path string) (err error) { var _p0 *byte _p0, err = BytePtrFromString(path) @@ -1401,35 +941,13 @@ func Unlink(path string) (err error) { return } -func Unlinkat(dirfd int, path string) (err error) { +func Utimes(path string, times *[2]Timeval) (err error) { var _p0 *byte _p0, err = BytePtrFromString(path) if err != nil { return } - _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procUnlinkat)), 2, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), 0, 0, 0, 0) - use(unsafe.Pointer(_p0)) - if e1 != 0 { - err = e1 - } - return -} - -func Ustat(dev int, ubuf *Ustat_t) (err error) { - _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procUstat)), 2, uintptr(dev), uintptr(unsafe.Pointer(ubuf)), 0, 0, 0, 0) - if e1 != 0 { - err = e1 - } - return -} - -func Utime(path string, buf *Utimbuf) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procUtime)), 2, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(buf)), 0, 0, 0, 0) + _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procUtimes)), 2, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), 0, 0, 0, 0) use(unsafe.Pointer(_p0)) if e1 != 0 { err = e1 @@ -1528,6 +1046,14 @@ func getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) { return } +func getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) { + _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procgetsockname)), 3, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), 0, 0, 0) + if e1 != 0 { + err = e1 + } + return +} + func setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) { _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procsetsockopt)), 5, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(vallen), 0) if e1 != 0 { @@ -1549,9 +1075,9 @@ func recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Sockl return } -func sysconf(name int) (n int64, err error) { - r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procsysconf)), 1, uintptr(name), 0, 0, 0, 0, 0) - n = int64(r0) +func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) { + r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procrecvmsg)), 3, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags), 0, 0, 0) + n = int(r0) if e1 != 0 { err = e1 } diff --git a/vendor/golang.org/x/sys/unix/zsysnum_darwin_arm64.go b/vendor/golang.org/x/sys/unix/zsysnum_darwin_arm64.go index 26677ebbf5b..39537d21086 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_darwin_arm64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_darwin_arm64.go @@ -1,4 +1,4 @@ -// mksysnum_darwin.pl /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS8.4.sdk/usr/include/sys/syscall.h +// mksysnum_darwin.pl /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/usr/include/sys/syscall.h // MACHINE GENERATED BY THE ABOVE COMMAND; DO NOT EDIT // +build arm64,darwin diff --git a/vendor/golang.org/x/sys/unix/ztypes_darwin_amd64.go b/vendor/golang.org/x/sys/unix/ztypes_darwin_amd64.go index 044657878c8..6bedd16f638 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_darwin_amd64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_darwin_amd64.go @@ -455,8 +455,3 @@ type Termios struct { Ispeed uint64 Ospeed uint64 } - -const ( - AT_FDCWD = -0x2 - AT_SYMLINK_NOFOLLOW = 0x20 -) diff --git a/vendor/golang.org/x/sys/unix/ztypes_freebsd_386.go b/vendor/golang.org/x/sys/unix/ztypes_freebsd_386.go index 8cf30947b41..330c0e6356f 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_freebsd_386.go +++ b/vendor/golang.org/x/sys/unix/ztypes_freebsd_386.go @@ -1,7 +1,8 @@ -// +build 386,freebsd // Created by cgo -godefs - DO NOT EDIT // cgo -godefs types_freebsd.go +// +build 386,freebsd + package unix const ( @@ -139,15 +140,6 @@ type Fsid struct { Val [2]int32 } -const ( - FADV_NORMAL = 0x0 - FADV_RANDOM = 0x1 - FADV_SEQUENTIAL = 0x2 - FADV_WILLNEED = 0x3 - FADV_DONTNEED = 0x4 - FADV_NOREUSE = 0x5 -) - type RawSockaddrInet4 struct { Len uint8 Family uint8 diff --git a/vendor/golang.org/x/sys/unix/ztypes_freebsd_amd64.go b/vendor/golang.org/x/sys/unix/ztypes_freebsd_amd64.go index e5feb207be6..93395924c48 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_freebsd_amd64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_freebsd_amd64.go @@ -1,7 +1,8 @@ -// +build amd64,freebsd // Created by cgo -godefs - DO NOT EDIT // cgo -godefs types_freebsd.go +// +build amd64,freebsd + package unix const ( @@ -139,15 +140,6 @@ type Fsid struct { Val [2]int32 } -const ( - FADV_NORMAL = 0x0 - FADV_RANDOM = 0x1 - FADV_SEQUENTIAL = 0x2 - FADV_WILLNEED = 0x3 - FADV_DONTNEED = 0x4 - FADV_NOREUSE = 0x5 -) - type RawSockaddrInet4 struct { Len uint8 Family uint8 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_386.go b/vendor/golang.org/x/sys/unix/ztypes_linux_386.go index cf5db0e1b67..9a58381b4dc 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_386.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_386.go @@ -1,7 +1,8 @@ -// +build 386,linux // Created by cgo -godefs - DO NOT EDIT // cgo -godefs types_linux.go +// +build 386,linux + package unix const ( @@ -579,12 +580,13 @@ const ( ) type Termios struct { - Iflag uint32 - Oflag uint32 - Cflag uint32 - Lflag uint32 - Line uint8 - Cc [19]uint8 - Ispeed uint32 - Ospeed uint32 + Iflag uint32 + Oflag uint32 + Cflag uint32 + Lflag uint32 + Line uint8 + Cc [32]uint8 + Pad_cgo_0 [3]byte + Ispeed uint32 + Ospeed uint32 } diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go index ac27784ab2e..f1937a62756 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go @@ -1,7 +1,8 @@ -// +build amd64,linux // Created by cgo -godefs - DO NOT EDIT // cgo -godefs types_linux.go +// +build amd64,linux + package unix const ( @@ -597,12 +598,13 @@ const ( ) type Termios struct { - Iflag uint32 - Oflag uint32 - Cflag uint32 - Lflag uint32 - Line uint8 - Cc [19]uint8 - Ispeed uint32 - Ospeed uint32 + Iflag uint32 + Oflag uint32 + Cflag uint32 + Lflag uint32 + Line uint8 + Cc [32]uint8 + Pad_cgo_0 [3]byte + Ispeed uint32 + Ospeed uint32 } diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_arm.go b/vendor/golang.org/x/sys/unix/ztypes_linux_arm.go index b318bb851c7..c8a0de45adf 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_arm.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_arm.go @@ -1,7 +1,8 @@ -// +build arm,linux // Created by cgo -godefs - DO NOT EDIT // cgo -godefs types_linux.go +// +build arm,linux + package unix const ( @@ -568,12 +569,115 @@ const ( ) type Termios struct { - Iflag uint32 - Oflag uint32 - Cflag uint32 - Lflag uint32 - Line uint8 - Cc [19]uint8 - Ispeed uint32 - Ospeed uint32 + Iflag uint32 + Oflag uint32 + Cflag uint32 + Lflag uint32 + Line uint8 + Cc [32]uint8 + Pad_cgo_0 [3]byte + Ispeed uint32 + Ospeed uint32 } + +const ( + VINTR = 0x0 + VQUIT = 0x1 + VERASE = 0x2 + VKILL = 0x3 + VEOF = 0x4 + VTIME = 0x5 + VMIN = 0x6 + VSWTC = 0x7 + VSTART = 0x8 + VSTOP = 0x9 + VSUSP = 0xa + VEOL = 0xb + VREPRINT = 0xc + VDISCARD = 0xd + VWERASE = 0xe + VLNEXT = 0xf + VEOL2 = 0x10 + IGNBRK = 0x1 + BRKINT = 0x2 + IGNPAR = 0x4 + PARMRK = 0x8 + INPCK = 0x10 + ISTRIP = 0x20 + INLCR = 0x40 + IGNCR = 0x80 + ICRNL = 0x100 + IUCLC = 0x200 + IXON = 0x400 + IXANY = 0x800 + IXOFF = 0x1000 + IMAXBEL = 0x2000 + IUTF8 = 0x4000 + OPOST = 0x1 + OLCUC = 0x2 + ONLCR = 0x4 + OCRNL = 0x8 + ONOCR = 0x10 + ONLRET = 0x20 + OFILL = 0x40 + OFDEL = 0x80 + B0 = 0x0 + B50 = 0x1 + B75 = 0x2 + B110 = 0x3 + B134 = 0x4 + B150 = 0x5 + B200 = 0x6 + B300 = 0x7 + B600 = 0x8 + B1200 = 0x9 + B1800 = 0xa + B2400 = 0xb + B4800 = 0xc + B9600 = 0xd + B19200 = 0xe + B38400 = 0xf + CSIZE = 0x30 + CS5 = 0x0 + CS6 = 0x10 + CS7 = 0x20 + CS8 = 0x30 + CSTOPB = 0x40 + CREAD = 0x80 + PARENB = 0x100 + PARODD = 0x200 + HUPCL = 0x400 + CLOCAL = 0x800 + B57600 = 0x1001 + B115200 = 0x1002 + B230400 = 0x1003 + B460800 = 0x1004 + B500000 = 0x1005 + B576000 = 0x1006 + B921600 = 0x1007 + B1000000 = 0x1008 + B1152000 = 0x1009 + B1500000 = 0x100a + B2000000 = 0x100b + B2500000 = 0x100c + B3000000 = 0x100d + B3500000 = 0x100e + B4000000 = 0x100f + ISIG = 0x1 + ICANON = 0x2 + XCASE = 0x4 + ECHO = 0x8 + ECHOE = 0x10 + ECHOK = 0x20 + ECHONL = 0x40 + NOFLSH = 0x80 + TOSTOP = 0x100 + ECHOCTL = 0x200 + ECHOPRT = 0x400 + ECHOKE = 0x800 + FLUSHO = 0x1000 + PENDIN = 0x4000 + IEXTEN = 0x8000 + TCGETS = 0x5401 + TCSETS = 0x5402 +) diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go index a159aadab69..f989a36052c 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go @@ -1,7 +1,8 @@ -// +build arm64,linux // Created by cgo -godefs - DO NOT EDIT // cgo -godefs -- -fsigned-char types_linux.go +// +build arm64,linux + package unix const ( @@ -584,12 +585,13 @@ const ( ) type Termios struct { - Iflag uint32 - Oflag uint32 - Cflag uint32 - Lflag uint32 - Line uint8 - Cc [19]uint8 - Ispeed uint32 - Ospeed uint32 + Iflag uint32 + Oflag uint32 + Cflag uint32 + Lflag uint32 + Line uint8 + Cc [32]uint8 + Pad_cgo_0 [3]byte + Ispeed uint32 + Ospeed uint32 } diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go index b14cbfef0d8..808203d071b 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go @@ -1,7 +1,8 @@ -// +build ppc64,linux // Created by cgo -godefs - DO NOT EDIT // cgo -godefs types_linux.go +// +build ppc64,linux + package unix const ( @@ -594,12 +595,13 @@ const ( ) type Termios struct { - Iflag uint32 - Oflag uint32 - Cflag uint32 - Lflag uint32 - Cc [19]uint8 - Line uint8 - Ispeed uint32 - Ospeed uint32 + Iflag uint32 + Oflag uint32 + Cflag uint32 + Lflag uint32 + Line uint8 + Cc [32]uint8 + Pad_cgo_0 [3]byte + Ispeed uint32 + Ospeed uint32 } diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go b/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go index 22c96a2f0a0..d4a689faffa 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go @@ -1,7 +1,8 @@ -// +build ppc64le,linux // Created by cgo -godefs - DO NOT EDIT // cgo -godefs types_linux.go +// +build ppc64le,linux + package unix const ( @@ -594,12 +595,13 @@ const ( ) type Termios struct { - Iflag uint32 - Oflag uint32 - Cflag uint32 - Lflag uint32 - Cc [19]uint8 - Line uint8 - Ispeed uint32 - Ospeed uint32 + Iflag uint32 + Oflag uint32 + Cflag uint32 + Lflag uint32 + Line uint8 + Cc [32]uint8 + Pad_cgo_0 [3]byte + Ispeed uint32 + Ospeed uint32 } diff --git a/vendor/golang.org/x/sys/unix/ztypes_solaris_amd64.go b/vendor/golang.org/x/sys/unix/ztypes_solaris_amd64.go index b3b928a51e6..45e9f422217 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_solaris_amd64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_solaris_amd64.go @@ -1,7 +1,8 @@ -// +build amd64,solaris // Created by cgo -godefs - DO NOT EDIT // cgo -godefs types_solaris.go +// +build amd64,solaris + package unix const ( @@ -10,7 +11,6 @@ const ( sizeofInt = 0x4 sizeofLong = 0x8 sizeofLongLong = 0x8 - PathMax = 0x400 ) type ( @@ -35,18 +35,6 @@ type Timeval32 struct { Usec int32 } -type Tms struct { - Utime int64 - Stime int64 - Cutime int64 - Cstime int64 -} - -type Utimbuf struct { - Actime int64 - Modtime int64 -} - type Rusage struct { Utime Timeval Stime Timeval @@ -242,30 +230,6 @@ type FdSet struct { Bits [1024]int64 } -type Utsname struct { - Sysname [257]int8 - Nodename [257]int8 - Release [257]int8 - Version [257]int8 - Machine [257]int8 -} - -type Ustat_t struct { - Tfree int64 - Tinode uint64 - Fname [6]int8 - Fpack [6]int8 - Pad_cgo_0 [4]byte -} - -const ( - AT_FDCWD = 0xffd19553 - AT_SYMLINK_NOFOLLOW = 0x1000 - AT_SYMLINK_FOLLOW = 0x2000 - AT_REMOVEDIR = 0x1 - AT_EACCESS = 0x4 -) - const ( SizeofIfMsghdr = 0x54 SizeofIfData = 0x44 @@ -393,8 +357,6 @@ type BpfHdr struct { Pad_cgo_0 [2]byte } -const _SC_PAGESIZE = 0xb - type Termios struct { Iflag uint32 Oflag uint32 @@ -403,20 +365,3 @@ type Termios struct { Cc [19]uint8 Pad_cgo_0 [1]byte } - -type Termio struct { - Iflag uint16 - Oflag uint16 - Cflag uint16 - Lflag uint16 - Line int8 - Cc [8]uint8 - Pad_cgo_0 [1]byte -} - -type Winsize struct { - Row uint16 - Col uint16 - Xpixel uint16 - Ypixel uint16 -} diff --git a/vendor/google.golang.org/grpc/.travis.yml b/vendor/google.golang.org/grpc/.travis.yml index 3f83776ec5f..9bc2c12793c 100644 --- a/vendor/google.golang.org/grpc/.travis.yml +++ b/vendor/google.golang.org/grpc/.travis.yml @@ -1,5 +1,9 @@ language: go +go: + - 1.5.3 + - 1.6 + before_install: - go get github.com/axw/gocov/gocov - go get github.com/mattn/goveralls @@ -11,4 +15,3 @@ install: script: - make test testrace - - make coverage diff --git a/vendor/google.golang.org/grpc/CONTRIBUTING.md b/vendor/google.golang.org/grpc/CONTRIBUTING.md index 407d384a7c8..36cd6f7581b 100644 --- a/vendor/google.golang.org/grpc/CONTRIBUTING.md +++ b/vendor/google.golang.org/grpc/CONTRIBUTING.md @@ -1,16 +1,39 @@ # How to contribute -We definitely welcome patches and contribution to grpc! Here is some guideline +We definitely welcome patches and contribution to grpc! Here are some guidelines and information about how to do so. -## Getting started +## Sending patches -### Legal requirements +### Getting started + +1. Check out the code: + + $ go get google.golang.org/grpc + $ cd $GOPATH/src/google.golang.org/grpc + +1. Create a fork of the grpc-go repository. +1. Add your fork as a remote: + + $ git remote add fork git@github.com:$YOURGITHUBUSERNAME/grpc-go.git + +1. Make changes, commit them. +1. Run the test suite: + + $ make test + +1. Push your changes to your fork: + + $ git push fork ... + +1. Open a pull request. + +## Legal requirements In order to protect both you and ourselves, you will need to sign the [Contributor License Agreement](https://cla.developers.google.com/clas). -### Filing Issues +## Filing Issues When filing an issue, make sure to answer these five questions: 1. What version of Go are you using (`go version`)? diff --git a/vendor/google.golang.org/grpc/Makefile b/vendor/google.golang.org/grpc/Makefile index 12e84e4e5be..03bb01f0b35 100644 --- a/vendor/google.golang.org/grpc/Makefile +++ b/vendor/google.golang.org/grpc/Makefile @@ -1,15 +1,3 @@ -.PHONY: \ - all \ - deps \ - updatedeps \ - testdeps \ - updatetestdeps \ - build \ - proto \ - test \ - testrace \ - clean \ - all: test testrace deps: @@ -32,9 +20,10 @@ proto: echo "error: protoc not installed" >&2; \ exit 1; \ fi - go get -v github.com/golang/protobuf/protoc-gen-go - for file in $$(git ls-files '*.proto'); do \ - protoc -I $$(dirname $$file) --go_out=plugins=grpc:$$(dirname $$file) $$file; \ + go get -u -v github.com/golang/protobuf/protoc-gen-go + # use $$dir as the root for all proto files in the same directory + for dir in $$(git ls-files '*.proto' | xargs -n1 dirname | uniq); do \ + protoc -I $$dir --go_out=plugins=grpc:$$dir $$dir/*.proto; \ done test: testdeps @@ -44,7 +33,20 @@ testrace: testdeps go test -v -race -cpu 1,4 google.golang.org/grpc/... clean: - go clean google.golang.org/grpc/... + go clean -i google.golang.org/grpc/... coverage: testdeps ./coverage.sh --coveralls + +.PHONY: \ + all \ + deps \ + updatedeps \ + testdeps \ + updatetestdeps \ + build \ + proto \ + test \ + testrace \ + clean \ + coverage diff --git a/vendor/google.golang.org/grpc/PATENTS b/vendor/google.golang.org/grpc/PATENTS index 619f9dbfe63..69b47959fab 100644 --- a/vendor/google.golang.org/grpc/PATENTS +++ b/vendor/google.golang.org/grpc/PATENTS @@ -1,22 +1,22 @@ Additional IP Rights Grant (Patents) "This implementation" means the copyrightable works distributed by -Google as part of the GRPC project. +Google as part of the gRPC 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 GRPC, where such license applies only to those patent +implementation of gRPC, 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 GRPC. This grant does not include claims that would be +implementation of gRPC. 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 GRPC or any code incorporated within this -implementation of GRPC constitutes direct or contributory patent +that this implementation of gRPC or any code incorporated within this +implementation of gRPC 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 GRPC +rights granted to you under this License for this implementation of gRPC shall terminate as of the date such litigation is filed. diff --git a/vendor/google.golang.org/grpc/README.md b/vendor/google.golang.org/grpc/README.md index 37b05f0953d..90e9453d52e 100644 --- a/vendor/google.golang.org/grpc/README.md +++ b/vendor/google.golang.org/grpc/README.md @@ -7,7 +7,7 @@ The Go implementation of [gRPC](http://www.grpc.io/): A high performance, open s Installation ------------ -To install this package, you need to install Go 1.4 or above and setup your Go workspace on your computer. The simplest way to install the library is to run: +To install this package, you need to install Go and setup your Go workspace on your computer. The simplest way to install the library is to run: ``` $ go get google.golang.org/grpc @@ -16,7 +16,7 @@ $ go get google.golang.org/grpc Prerequisites ------------- -This requires Go 1.4 or above. +This requires Go 1.5 or later . Constraints ----------- diff --git a/vendor/google.golang.org/grpc/backoff.go b/vendor/google.golang.org/grpc/backoff.go new file mode 100644 index 00000000000..52f4f10fc25 --- /dev/null +++ b/vendor/google.golang.org/grpc/backoff.go @@ -0,0 +1,80 @@ +package grpc + +import ( + "math/rand" + "time" +) + +// DefaultBackoffConfig uses values specified for backoff in +// https://github.com/grpc/grpc/blob/master/doc/connection-backoff.md. +var ( + DefaultBackoffConfig = BackoffConfig{ + MaxDelay: 120 * time.Second, + baseDelay: 1.0 * time.Second, + factor: 1.6, + jitter: 0.2, + } +) + +// backoffStrategy defines the methodology for backing off after a grpc +// connection failure. +// +// This is unexported until the gRPC project decides whether or not to allow +// alternative backoff strategies. Once a decision is made, this type and its +// method may be exported. +type backoffStrategy interface { + // backoff returns the amount of time to wait before the next retry given + // the number of consecutive failures. + backoff(retries int) time.Duration +} + +// BackoffConfig defines the parameters for the default gRPC backoff strategy. +type BackoffConfig struct { + // MaxDelay is the upper bound of backoff delay. + MaxDelay time.Duration + + // TODO(stevvooe): The following fields are not exported, as allowing + // changes would violate the current gRPC specification for backoff. If + // gRPC decides to allow more interesting backoff strategies, these fields + // may be opened up in the future. + + // baseDelay is the amount of time to wait before retrying after the first + // failure. + baseDelay time.Duration + + // factor is applied to the backoff after each retry. + factor float64 + + // jitter provides a range to randomize backoff delays. + jitter float64 +} + +func setDefaults(bc *BackoffConfig) { + md := bc.MaxDelay + *bc = DefaultBackoffConfig + + if md > 0 { + bc.MaxDelay = md + } +} + +func (bc BackoffConfig) backoff(retries int) (t time.Duration) { + if retries == 0 { + return bc.baseDelay + } + backoff, max := float64(bc.baseDelay), float64(bc.MaxDelay) + for backoff < max && retries > 0 { + backoff *= bc.factor + retries-- + } + if backoff > max { + backoff = max + } + // Randomize backoff delays so that if a cluster of requests start at + // the same time, they won't operate in lockstep. + backoff *= 1 + bc.jitter*(rand.Float64()*2-1) + if backoff < 0 { + return 0 + } + return time.Duration(backoff) +} diff --git a/vendor/google.golang.org/grpc/balancer.go b/vendor/google.golang.org/grpc/balancer.go new file mode 100644 index 00000000000..419e2146113 --- /dev/null +++ b/vendor/google.golang.org/grpc/balancer.go @@ -0,0 +1,385 @@ +/* + * + * Copyright 2016, Google Inc. + * 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. + * + */ + +package grpc + +import ( + "fmt" + "sync" + + "golang.org/x/net/context" + "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/naming" +) + +// Address represents a server the client connects to. +// This is the EXPERIMENTAL API and may be changed or extended in the future. +type Address struct { + // Addr is the server address on which a connection will be established. + Addr string + // Metadata is the information associated with Addr, which may be used + // to make load balancing decision. + Metadata interface{} +} + +// BalancerGetOptions configures a Get call. +// This is the EXPERIMENTAL API and may be changed or extended in the future. +type BalancerGetOptions struct { + // BlockingWait specifies whether Get should block when there is no + // connected address. + BlockingWait bool +} + +// Balancer chooses network addresses for RPCs. +// This is the EXPERIMENTAL API and may be changed or extended in the future. +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 + // 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 + // 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. + // i) If it returns a connected address, gRPC internals issues the RPC on the + // connection to this address; + // ii) If it returns an address on which the connection is under construction + // (initiated by Notify(...)) but not connected, gRPC internals + // * fails RPC if the RPC is fail-fast and connection is in the TransientFailure or + // Shutdown state; + // or + // * issues RPC on the connection otherwise. + // iii) If it returns an address on which the connection does not exist, gRPC + // internals treats it as an error and will fail the corresponding RPC. + // + // Therefore, the following is the recommended rule when writing a custom Balancer. + // If opts.BlockingWait is true, it should return a connected address or + // block if there is no connected address. It should respect the timeout or + // cancellation of ctx when blocking. If opts.BlockingWait is false (for fail-fast + // RPCs), it should return an address it has notified via Notify(...) immediately + // instead of blocking. + // + // The function returns put which is called once the rpc has completed or failed. + // put can collect and report RPC stats to a remote load balancer. + // + // This function should only return the errors Balancer cannot recover by itself. + // gRPC internals will fail the RPC if an error is returned. + Get(ctx context.Context, opts BalancerGetOptions) (addr Address, put func(), err error) + // Notify returns a channel that is used by gRPC internals to watch the addresses + // gRPC needs to connect. The addresses might be from a name resolver or remote + // load balancer. gRPC internals will compare it with the existing connected + // addresses. If the address Balancer notified is not in the existing connected + // addresses, gRPC starts to connect the address. If an address in the existing + // connected addresses is not in the notification list, the corresponding connection + // is shutdown gracefully. Otherwise, there are no operations to take. Note that + // the Address slice must be the full list of the Addresses which should be connected. + // It is NOT delta. + Notify() <-chan []Address + // Close shuts down the balancer. + Close() error +} + +// downErr implements net.Error. It is constructed by gRPC internals and passed to the down +// call of Balancer. +type downErr struct { + timeout bool + temporary bool + desc string +} + +func (e downErr) Error() string { return e.desc } +func (e downErr) Timeout() bool { return e.timeout } +func (e downErr) Temporary() bool { return e.temporary } + +func downErrorf(timeout, temporary bool, format string, a ...interface{}) downErr { + return downErr{ + timeout: timeout, + temporary: temporary, + desc: fmt.Sprintf(format, a...), + } +} + +// RoundRobin returns a Balancer that selects addresses round-robin. It uses r to watch +// the name resolution updates and updates the addresses available correspondingly. +func RoundRobin(r naming.Resolver) Balancer { + return &roundRobin{r: r} +} + +type addrInfo struct { + addr Address + connected bool +} + +type roundRobin struct { + r naming.Resolver + w naming.Watcher + addrs []*addrInfo // all the addresses the client should potentially connect + mu sync.Mutex + addrCh chan []Address // the channel to notify gRPC internals the list of addresses the client should connect to. + next int // index of the next address to return for Get() + waitCh chan struct{} // the channel to block when there is no connected address available + done bool // The Balancer is closed. +} + +func (rr *roundRobin) watchAddrUpdates() error { + updates, err := rr.w.Next() + if err != nil { + grpclog.Printf("grpc: the naming watcher stops working due to %v.\n", err) + return err + } + rr.mu.Lock() + defer rr.mu.Unlock() + for _, update := range updates { + addr := Address{ + Addr: update.Addr, + Metadata: update.Metadata, + } + switch update.Op { + case naming.Add: + var exist bool + for _, v := range rr.addrs { + if addr == v.addr { + exist = true + grpclog.Println("grpc: The name resolver wanted to add an existing address: ", addr) + break + } + } + if exist { + continue + } + rr.addrs = append(rr.addrs, &addrInfo{addr: addr}) + case naming.Delete: + for i, v := range rr.addrs { + if addr == v.addr { + copy(rr.addrs[i:], rr.addrs[i+1:]) + rr.addrs = rr.addrs[:len(rr.addrs)-1] + break + } + } + default: + grpclog.Println("Unknown update.Op ", update.Op) + } + } + // Make a copy of rr.addrs and write it onto rr.addrCh so that gRPC internals gets notified. + open := make([]Address, len(rr.addrs)) + for i, v := range rr.addrs { + open[i] = v.addr + } + if rr.done { + return ErrClientConnClosing + } + rr.addrCh <- open + return nil +} + +func (rr *roundRobin) Start(target string) error { + 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 + // as the only address available and rr.addrCh stays nil. + rr.addrs = append(rr.addrs, &addrInfo{addr: Address{Addr: target}}) + return nil + } + w, err := rr.r.Resolve(target) + if err != nil { + return err + } + rr.w = w + rr.addrCh = make(chan []Address) + go func() { + for { + if err := rr.watchAddrUpdates(); err != nil { + return + } + } + }() + return nil +} + +// Up sets the connected state of addr and sends notification if there are pending +// Get() calls. +func (rr *roundRobin) Up(addr Address) func(error) { + rr.mu.Lock() + defer rr.mu.Unlock() + var cnt int + for _, a := range rr.addrs { + if a.addr == addr { + if a.connected { + return nil + } + a.connected = true + } + if a.connected { + cnt++ + } + } + // addr is only one which is connected. Notify the Get() callers who are blocking. + if cnt == 1 && rr.waitCh != nil { + close(rr.waitCh) + rr.waitCh = nil + } + return func(err error) { + rr.down(addr, err) + } +} + +// down unsets the connected state of addr. +func (rr *roundRobin) down(addr Address, err error) { + rr.mu.Lock() + defer rr.mu.Unlock() + for _, a := range rr.addrs { + if addr == a.addr { + a.connected = false + break + } + } +} + +// Get returns the next addr in the rotation. +func (rr *roundRobin) Get(ctx context.Context, opts BalancerGetOptions) (addr Address, put func(), err error) { + var ch chan struct{} + rr.mu.Lock() + if rr.done { + rr.mu.Unlock() + err = ErrClientConnClosing + return + } + + if len(rr.addrs) > 0 { + if rr.next >= len(rr.addrs) { + rr.next = 0 + } + next := rr.next + for { + a := rr.addrs[next] + next = (next + 1) % len(rr.addrs) + if a.connected { + addr = a.addr + rr.next = next + rr.mu.Unlock() + return + } + if next == rr.next { + // Has iterated all the possible address but none is connected. + break + } + } + } + if !opts.BlockingWait { + if len(rr.addrs) == 0 { + rr.mu.Unlock() + err = fmt.Errorf("there is no address available") + return + } + // Returns the next addr on rr.addrs for failfast RPCs. + addr = rr.addrs[rr.next].addr + rr.next++ + rr.mu.Unlock() + return + } + // Wait on rr.waitCh for non-failfast RPCs. + if rr.waitCh == nil { + ch = make(chan struct{}) + rr.waitCh = ch + } else { + ch = rr.waitCh + } + rr.mu.Unlock() + for { + select { + case <-ctx.Done(): + err = ctx.Err() + return + case <-ch: + rr.mu.Lock() + if rr.done { + rr.mu.Unlock() + err = ErrClientConnClosing + return + } + + if len(rr.addrs) > 0 { + if rr.next >= len(rr.addrs) { + rr.next = 0 + } + next := rr.next + for { + a := rr.addrs[next] + next = (next + 1) % len(rr.addrs) + if a.connected { + addr = a.addr + rr.next = next + rr.mu.Unlock() + return + } + if next == rr.next { + // Has iterated all the possible address but none is connected. + break + } + } + } + // The newly added addr got removed by Down() again. + if rr.waitCh == nil { + ch = make(chan struct{}) + rr.waitCh = ch + } else { + ch = rr.waitCh + } + rr.mu.Unlock() + } + } +} + +func (rr *roundRobin) Notify() <-chan []Address { + return rr.addrCh +} + +func (rr *roundRobin) Close() error { + rr.mu.Lock() + defer rr.mu.Unlock() + rr.done = true + if rr.w != nil { + rr.w.Close() + } + if rr.waitCh != nil { + close(rr.waitCh) + rr.waitCh = nil + } + if rr.addrCh != nil { + close(rr.addrCh) + } + return nil +} diff --git a/vendor/google.golang.org/grpc/call.go b/vendor/google.golang.org/grpc/call.go index d4ae68bee1f..84ac178c434 100644 --- a/vendor/google.golang.org/grpc/call.go +++ b/vendor/google.golang.org/grpc/call.go @@ -55,7 +55,7 @@ func recvResponse(dopts dialOptions, t transport.ClientTransport, c *callInfo, s if err != nil { return err } - p := &parser{s: stream} + p := &parser{r: stream} for { if err = recv(p, dopts.codec, stream, dopts.dc, reply); err != nil { if err == io.EOF { @@ -97,10 +97,11 @@ func sendRequest(ctx context.Context, codec Codec, compressor Compressor, callHd return stream, nil } -// Invoke is called by the generated code. It sends the RPC request on the -// wire and returns after response is received. +// 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) { - var c callInfo + c := defaultCallInfo for _, o := range opts { if err := o.before(&c); err != nil { return toRPCErr(err) @@ -131,19 +132,16 @@ func Invoke(ctx context.Context, method string, args, reply interface{}, cc *Cli Last: true, Delay: false, } - var ( - lastErr error // record the error that happened - ) for { var ( err error t transport.ClientTransport stream *transport.Stream + // Record the put handler from Balancer.Get(...). It is called once the + // RPC has completed or failed. + put func() ) - // TODO(zhaoq): Need a formal spec of retry strategy for non-failfast rpcs. - if lastErr != nil && c.failFast { - return toRPCErr(lastErr) - } + // TODO(zhaoq): Need a formal spec of fail-fast. callHdr := &transport.CallHdr{ Host: cc.authority, Method: method, @@ -151,40 +149,65 @@ func Invoke(ctx context.Context, method string, args, reply interface{}, cc *Cli if cc.dopts.cp != nil { callHdr.SendCompress = cc.dopts.cp.Type() } - t, err = cc.dopts.picker.Pick(ctx) + gopts := BalancerGetOptions{ + BlockingWait: !c.failFast, + } + t, put, err = cc.getTransport(ctx, gopts) if err != nil { - if lastErr != nil { - // This was a retry; return the error from the last attempt. - return toRPCErr(lastErr) + // TODO(zhaoq): Probably revisit the error handling. + if _, ok := err.(*rpcError); ok { + return err } - return toRPCErr(err) + if err == errConnClosing { + if c.failFast { + return Errorf(codes.Unavailable, "%v", errConnClosing) + } + continue + } + // All the other errors are treated as Internal errors. + return Errorf(codes.Internal, "%v", err) } if c.traceInfo.tr != nil { c.traceInfo.tr.LazyLog(&payload{sent: true, msg: args}, true) } stream, err = sendRequest(ctx, cc.dopts.codec, cc.dopts.cp, callHdr, t, args, topts) if err != nil { - if _, ok := err.(transport.ConnectionError); ok { - lastErr = err - continue + if put != nil { + put() + put = nil } - if lastErr != nil { - return toRPCErr(lastErr) + if _, ok := err.(transport.ConnectionError); ok { + if c.failFast { + return toRPCErr(err) + } + continue } return toRPCErr(err) } // Receive the response - lastErr = recvResponse(cc.dopts, t, &c, stream, reply) - if _, ok := lastErr.(transport.ConnectionError); ok { - continue + err = recvResponse(cc.dopts, t, &c, stream, reply) + if err != nil { + if put != nil { + put() + put = nil + } + if _, ok := err.(transport.ConnectionError); ok { + if c.failFast { + return toRPCErr(err) + } + continue + } + t.CloseStream(stream, err) + return toRPCErr(err) } if c.traceInfo.tr != nil { c.traceInfo.tr.LazyLog(&payload{sent: false, msg: reply}, true) } - t.CloseStream(stream, lastErr) - if lastErr != nil { - return toRPCErr(lastErr) + t.CloseStream(stream, nil) + if put != nil { + put() + put = nil } - return Errorf(stream.StatusCode(), stream.StatusDesc()) + return Errorf(stream.StatusCode(), "%s", stream.StatusDesc()) } } diff --git a/vendor/google.golang.org/grpc/clientconn.go b/vendor/google.golang.org/grpc/clientconn.go index 28e74da8b92..c3c7691dc0b 100644 --- a/vendor/google.golang.org/grpc/clientconn.go +++ b/vendor/google.golang.org/grpc/clientconn.go @@ -43,28 +43,38 @@ import ( "golang.org/x/net/context" "golang.org/x/net/trace" + "google.golang.org/grpc/codes" "google.golang.org/grpc/credentials" "google.golang.org/grpc/grpclog" "google.golang.org/grpc/transport" ) var ( - // ErrUnspecTarget indicates that the target address is unspecified. - ErrUnspecTarget = errors.New("grpc: target is unspecified") - // ErrNoTransportSecurity indicates that there is no transport security - // being set for ClientConn. Users should either set one or explicityly - // call WithInsecure DialOption to disable security. - ErrNoTransportSecurity = errors.New("grpc: no transport security set (use grpc.WithInsecure() explicitly or set credentials)") - // ErrCredentialsMisuse indicates that users want to transmit security infomation - // (e.g., oauth2 token) which requires secure connection on an insecure - // connection. - ErrCredentialsMisuse = errors.New("grpc: the credentials require transport level security (use grpc.WithTransportAuthenticator() to set)") // ErrClientConnClosing indicates that the operation is illegal because - // the session is closing. + // the ClientConn is closing. ErrClientConnClosing = errors.New("grpc: the client connection is closing") - // ErrClientConnTimeout indicates that the connection could not be - // established or re-established within the specified timeout. - ErrClientConnTimeout = errors.New("grpc: timed out trying to connect") + // ErrClientConnTimeout indicates that the ClientConn cannot establish the + // underlying connections within the specified timeout. + ErrClientConnTimeout = errors.New("grpc: timed out when dialing") + + // errNoTransportSecurity indicates that there is no transport security + // being set for ClientConn. Users should either set one or explicitly + // call WithInsecure DialOption to disable security. + errNoTransportSecurity = errors.New("grpc: no transport security set (use grpc.WithInsecure() explicitly or set credentials)") + // errTransportCredentialsMissing indicates that users want to transmit security + // information (e.g., oauth2 token) which requires secure connection on an insecure + // connection. + errTransportCredentialsMissing = errors.New("grpc: the credentials require transport level security (use grpc.WithTransportCredentials() to set)") + // errCredentialsConflict indicates that grpc.WithTransportCredentials() + // and grpc.WithInsecure() are both called for a connection. + errCredentialsConflict = errors.New("grpc: transport credentials are set for an insecure connection (grpc.WithTransportCredentials() and grpc.WithInsecure() are both called)") + // errNetworkIP indicates that the connection is down due to some network I/O error. + errNetworkIO = errors.New("grpc: failed with network I/O error") + // errConnDrain indicates that the connection starts to be drained and does not accept any new RPCs. + errConnDrain = errors.New("grpc: the connection is drained") + // errConnClosing indicates that the connection is closing. + errConnClosing = errors.New("grpc: the connection is closing") + errNoAddr = errors.New("grpc: there is no address available to dial") // minimum time to give a connection to complete minConnectTimeout = 20 * time.Second ) @@ -75,9 +85,11 @@ type dialOptions struct { codec Codec cp Compressor dc Decompressor - picker Picker + bs backoffStrategy + balancer Balancer block bool insecure bool + timeout time.Duration copts transport.ConnectOptions } @@ -107,10 +119,38 @@ func WithDecompressor(dc Decompressor) DialOption { } } -// WithPicker returns a DialOption which sets a picker for connection selection. -func WithPicker(p Picker) DialOption { +// WithBalancer returns a DialOption which sets a load balancer. +func WithBalancer(b Balancer) DialOption { return func(o *dialOptions) { - o.picker = p + o.balancer = b + } +} + +// WithBackoffMaxDelay configures the dialer to use the provided maximum delay +// when backing off after failed connection attempts. +func WithBackoffMaxDelay(md time.Duration) DialOption { + return WithBackoffConfig(BackoffConfig{MaxDelay: md}) +} + +// WithBackoffConfig configures the dialer to use the provided backoff +// parameters after connection failures. +// +// Use WithBackoffMaxDelay until more parameters on BackoffConfig are opened up +// for use. +func WithBackoffConfig(b BackoffConfig) DialOption { + // Set defaults to ensure that provided BackoffConfig is valid and + // unexported fields get default values. + setDefaults(&b) + return withBackoff(b) +} + +// withBackoff sets the backoff strategy used for retries after a +// failed connection attempt. +// +// This can be exported if arbitrary backoff strategies are allowed by gRPC. +func withBackoff(bs backoffStrategy) DialOption { + return func(o *dialOptions) { + o.bs = bs } } @@ -133,24 +173,25 @@ func WithInsecure() DialOption { // WithTransportCredentials returns a DialOption which configures a // connection level security credentials (e.g., TLS/SSL). -func WithTransportCredentials(creds credentials.TransportAuthenticator) DialOption { +func WithTransportCredentials(creds credentials.TransportCredentials) DialOption { return func(o *dialOptions) { - o.copts.AuthOptions = append(o.copts.AuthOptions, creds) + o.copts.TransportCredentials = creds } } // WithPerRPCCredentials returns a DialOption which sets // credentials which will place auth state on each outbound RPC. -func WithPerRPCCredentials(creds credentials.Credentials) DialOption { +func WithPerRPCCredentials(creds credentials.PerRPCCredentials) DialOption { return func(o *dialOptions) { - o.copts.AuthOptions = append(o.copts.AuthOptions, creds) + o.copts.PerRPCCredentials = append(o.copts.PerRPCCredentials, creds) } } -// WithTimeout returns a DialOption that configures a timeout for dialing a client connection. +// WithTimeout returns a DialOption that configures a timeout for dialing a ClientConn +// initially. This is valid if and only if WithBlock() is present. func WithTimeout(d time.Duration) DialOption { return func(o *dialOptions) { - o.copts.Timeout = d + o.timeout = d } } @@ -172,21 +213,66 @@ func WithUserAgent(s string) DialOption { func Dial(target string, opts ...DialOption) (*ClientConn, error) { cc := &ClientConn{ target: target, + conns: make(map[Address]*addrConn), } for _, opt := range opts { opt(&cc.dopts) } + + // Set defaults. if cc.dopts.codec == nil { - // Set the default codec. cc.dopts.codec = protoCodec{} } - if cc.dopts.picker == nil { - cc.dopts.picker = &unicastPicker{ - target: target, + if cc.dopts.bs == nil { + cc.dopts.bs = DefaultBackoffConfig + } + if cc.dopts.balancer == nil { + cc.dopts.balancer = RoundRobin(nil) + } + + if err := cc.dopts.balancer.Start(target); err != nil { + return nil, err + } + var ( + ok bool + addrs []Address + ) + 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 } } - if err := cc.dopts.picker.Init(cc); err != nil { - return nil, err + waitC := make(chan error, 1) + go func() { + for _, a := range addrs { + if err := cc.newAddrConn(a, false); err != nil { + waitC <- err + return + } + } + close(waitC) + }() + var timeoutCh <-chan time.Time + if cc.dopts.timeout > 0 { + timeoutCh = time.After(cc.dopts.timeout) + } + select { + case err := <-waitC: + if err != nil { + cc.Close() + return nil, err + } + case <-timeoutCh: + cc.Close() + return nil, ErrClientConnTimeout + } + if ok { + go cc.lbWatcher() } colonPos := strings.LastIndex(target, ":") if colonPos == -1 { @@ -229,328 +315,363 @@ func (s ConnectivityState) String() string { } } -// ClientConn represents a client connection to an RPC service. +// ClientConn represents a client connection to an RPC server. type ClientConn struct { target string authority string dopts dialOptions + + mu sync.RWMutex + conns map[Address]*addrConn } -// State returns the connectivity state of cc. -// This is EXPERIMENTAL API. -func (cc *ClientConn) State() (ConnectivityState, error) { - return cc.dopts.picker.State() +func (cc *ClientConn) lbWatcher() { + for addrs := range cc.dopts.balancer.Notify() { + var ( + add []Address // Addresses need to setup connections. + del []*addrConn // Connections need to tear down. + ) + cc.mu.Lock() + for _, a := range addrs { + if _, ok := cc.conns[a]; !ok { + add = append(add, a) + } + } + for k, c := range cc.conns { + var keep bool + for _, a := range addrs { + if k == a { + keep = true + break + } + } + if !keep { + del = append(del, c) + } + } + cc.mu.Unlock() + for _, a := range add { + cc.newAddrConn(a, true) + } + for _, c := range del { + c.tearDown(errConnDrain) + } + } } -// WaitForStateChange blocks until the state changes to something other than the sourceState. -// It returns the new state or error. -// This is EXPERIMENTAL API. -func (cc *ClientConn) WaitForStateChange(ctx context.Context, sourceState ConnectivityState) (ConnectivityState, error) { - return cc.dopts.picker.WaitForStateChange(ctx, sourceState) +func (cc *ClientConn) newAddrConn(addr Address, skipWait bool) error { + ac := &addrConn{ + cc: cc, + addr: addr, + dopts: cc.dopts, + shutdownChan: make(chan struct{}), + } + if EnableTracing { + ac.events = trace.NewEventLog("grpc.ClientConn", ac.addr.Addr) + } + if !ac.dopts.insecure { + if ac.dopts.copts.TransportCredentials == nil { + return errNoTransportSecurity + } + } else { + if ac.dopts.copts.TransportCredentials != nil { + return errCredentialsConflict + } + for _, cd := range ac.dopts.copts.PerRPCCredentials { + if cd.RequireTransportSecurity() { + return errTransportCredentialsMissing + } + } + } + // Insert ac into ac.cc.conns. This needs to be done before any getTransport(...) is called. + ac.cc.mu.Lock() + if ac.cc.conns == nil { + ac.cc.mu.Unlock() + return ErrClientConnClosing + } + stale := ac.cc.conns[ac.addr] + ac.cc.conns[ac.addr] = ac + ac.cc.mu.Unlock() + if stale != nil { + // There is an addrConn alive on ac.addr already. This could be due to + // i) stale's Close is undergoing; + // ii) a buggy Balancer notifies duplicated Addresses. + stale.tearDown(errConnDrain) + } + ac.stateCV = sync.NewCond(&ac.mu) + // skipWait may overwrite the decision in ac.dopts.block. + if ac.dopts.block && !skipWait { + if err := ac.resetTransport(false); err != nil { + ac.tearDown(err) + return err + } + // Start to monitor the error status of transport. + go ac.transportMonitor() + } else { + // Start a goroutine connecting to the server asynchronously. + go func() { + if err := ac.resetTransport(false); err != nil { + grpclog.Printf("Failed to dial %s: %v; please retry.", ac.addr.Addr, err) + ac.tearDown(err) + return + } + ac.transportMonitor() + }() + } + return nil } -// Close starts to tear down the ClientConn. +func (cc *ClientConn) getTransport(ctx context.Context, opts BalancerGetOptions) (transport.ClientTransport, func(), error) { + addr, put, err := cc.dopts.balancer.Get(ctx, opts) + if err != nil { + return nil, nil, toRPCErr(err) + } + cc.mu.RLock() + if cc.conns == nil { + cc.mu.RUnlock() + return nil, nil, toRPCErr(ErrClientConnClosing) + } + ac, ok := cc.conns[addr] + cc.mu.RUnlock() + if !ok { + if put != nil { + put() + } + return nil, nil, Errorf(codes.Internal, "grpc: failed to find the transport to send the rpc") + } + t, err := ac.wait(ctx, !opts.BlockingWait) + if err != nil { + if put != nil { + put() + } + return nil, nil, err + } + return t, put, nil +} + +// Close tears down the ClientConn and all underlying connections. func (cc *ClientConn) Close() error { - return cc.dopts.picker.Close() + cc.mu.Lock() + if cc.conns == nil { + cc.mu.Unlock() + return ErrClientConnClosing + } + conns := cc.conns + cc.conns = nil + cc.mu.Unlock() + cc.dopts.balancer.Close() + for _, ac := range conns { + ac.tearDown(ErrClientConnClosing) + } + return nil } -// Conn is a client connection to a single destination. -type Conn struct { - target string +// addrConn is a network connection to a given address. +type addrConn struct { + cc *ClientConn + addr Address dopts dialOptions - resetChan chan int shutdownChan chan struct{} events trace.EventLog mu sync.Mutex state ConnectivityState stateCV *sync.Cond + down func(error) // the handler called when a connection is down. // ready is closed and becomes nil when a new transport is up or failed // due to timeout. ready chan struct{} transport transport.ClientTransport } -// NewConn creates a Conn. -func NewConn(cc *ClientConn) (*Conn, error) { - if cc.target == "" { - return nil, ErrUnspecTarget - } - c := &Conn{ - target: cc.target, - dopts: cc.dopts, - resetChan: make(chan int, 1), - shutdownChan: make(chan struct{}), - } - if EnableTracing { - c.events = trace.NewEventLog("grpc.ClientConn", c.target) - } - if !c.dopts.insecure { - var ok bool - for _, cd := range c.dopts.copts.AuthOptions { - if _, ok := cd.(credentials.TransportAuthenticator); !ok { - continue - } - ok = true - } - if !ok { - return nil, ErrNoTransportSecurity - } - } else { - for _, cd := range c.dopts.copts.AuthOptions { - if cd.RequireTransportSecurity() { - return nil, ErrCredentialsMisuse - } - } - } - c.stateCV = sync.NewCond(&c.mu) - if c.dopts.block { - if err := c.resetTransport(false); err != nil { - c.Close() - return nil, err - } - // Start to monitor the error status of transport. - go c.transportMonitor() - } else { - // Start a goroutine connecting to the server asynchronously. - go func() { - if err := c.resetTransport(false); err != nil { - grpclog.Printf("Failed to dial %s: %v; please retry.", c.target, err) - c.Close() - return - } - c.transportMonitor() - }() - } - return c, nil -} - -// printf records an event in cc's event log, unless cc has been closed. -// REQUIRES cc.mu is held. -func (cc *Conn) printf(format string, a ...interface{}) { - if cc.events != nil { - cc.events.Printf(format, a...) +// printf records an event in ac's event log, unless ac has been closed. +// REQUIRES ac.mu is held. +func (ac *addrConn) printf(format string, a ...interface{}) { + if ac.events != nil { + ac.events.Printf(format, a...) } } -// errorf records an error in cc's event log, unless cc has been closed. -// REQUIRES cc.mu is held. -func (cc *Conn) errorf(format string, a ...interface{}) { - if cc.events != nil { - cc.events.Errorf(format, a...) +// errorf records an error in ac's event log, unless ac has been closed. +// REQUIRES ac.mu is held. +func (ac *addrConn) errorf(format string, a ...interface{}) { + if ac.events != nil { + ac.events.Errorf(format, a...) } } -// State returns the connectivity state of the Conn -func (cc *Conn) State() ConnectivityState { - cc.mu.Lock() - defer cc.mu.Unlock() - return cc.state +// getState returns the connectivity state of the Conn +func (ac *addrConn) getState() ConnectivityState { + ac.mu.Lock() + defer ac.mu.Unlock() + return ac.state } -// WaitForStateChange blocks until the state changes to something other than the sourceState. -func (cc *Conn) WaitForStateChange(ctx context.Context, sourceState ConnectivityState) (ConnectivityState, error) { - cc.mu.Lock() - defer cc.mu.Unlock() - if sourceState != cc.state { - return cc.state, nil +// waitForStateChange blocks until the state changes to something other than the sourceState. +func (ac *addrConn) waitForStateChange(ctx context.Context, sourceState ConnectivityState) (ConnectivityState, error) { + ac.mu.Lock() + defer ac.mu.Unlock() + if sourceState != ac.state { + return ac.state, nil } done := make(chan struct{}) var err error go func() { select { case <-ctx.Done(): - cc.mu.Lock() + ac.mu.Lock() err = ctx.Err() - cc.stateCV.Broadcast() - cc.mu.Unlock() + ac.stateCV.Broadcast() + ac.mu.Unlock() case <-done: } }() defer close(done) - for sourceState == cc.state { - cc.stateCV.Wait() + for sourceState == ac.state { + ac.stateCV.Wait() if err != nil { - return cc.state, err + return ac.state, err } } - return cc.state, nil + return ac.state, nil } -// NotifyReset tries to signal the underlying transport needs to be reset due to -// for example a name resolution change in flight. -func (cc *Conn) NotifyReset() { - select { - case cc.resetChan <- 0: - default: - } -} - -func (cc *Conn) resetTransport(closeTransport bool) error { +func (ac *addrConn) resetTransport(closeTransport bool) error { var retries int - start := time.Now() for { - cc.mu.Lock() - cc.printf("connecting") - if cc.state == Shutdown { - // cc.Close() has been invoked. - cc.mu.Unlock() - return ErrClientConnClosing + ac.mu.Lock() + ac.printf("connecting") + if ac.state == Shutdown { + // ac.tearDown(...) has been invoked. + ac.mu.Unlock() + return errConnClosing } - cc.state = Connecting - cc.stateCV.Broadcast() - cc.mu.Unlock() - if closeTransport { - cc.transport.Close() + if ac.down != nil { + ac.down(downErrorf(false, true, "%v", errNetworkIO)) + ac.down = nil } - // Adjust timeout for the current try. - copts := cc.dopts.copts - if copts.Timeout < 0 { - cc.Close() - return ErrClientConnTimeout + ac.state = Connecting + ac.stateCV.Broadcast() + t := ac.transport + ac.mu.Unlock() + if closeTransport && t != nil { + t.Close() } - if copts.Timeout > 0 { - copts.Timeout -= time.Since(start) - if copts.Timeout <= 0 { - cc.Close() - return ErrClientConnTimeout - } - } - sleepTime := backoff(retries) - timeout := sleepTime - if timeout < minConnectTimeout { - timeout = minConnectTimeout - } - if copts.Timeout == 0 || copts.Timeout > timeout { - copts.Timeout = timeout + sleepTime := ac.dopts.bs.backoff(retries) + ac.dopts.copts.Timeout = sleepTime + if sleepTime < minConnectTimeout { + ac.dopts.copts.Timeout = minConnectTimeout } connectTime := time.Now() - addr, err := cc.dopts.picker.PickAddr() - var newTransport transport.ClientTransport - if err == nil { - newTransport, err = transport.NewClientTransport(addr, &copts) - } + newTransport, err := transport.NewClientTransport(ac.addr.Addr, &ac.dopts.copts) if err != nil { - cc.mu.Lock() - if cc.state == Shutdown { - // cc.Close() has been invoked. - cc.mu.Unlock() - return ErrClientConnClosing + ac.mu.Lock() + if ac.state == Shutdown { + // ac.tearDown(...) has been invoked. + ac.mu.Unlock() + return errConnClosing } - cc.errorf("transient failure: %v", err) - cc.state = TransientFailure - cc.stateCV.Broadcast() - if cc.ready != nil { - close(cc.ready) - cc.ready = nil + ac.errorf("transient failure: %v", err) + ac.state = TransientFailure + ac.stateCV.Broadcast() + if ac.ready != nil { + close(ac.ready) + ac.ready = nil } - cc.mu.Unlock() + ac.mu.Unlock() sleepTime -= time.Since(connectTime) if sleepTime < 0 { sleepTime = 0 } - // Fail early before falling into sleep. - if cc.dopts.copts.Timeout > 0 && cc.dopts.copts.Timeout < sleepTime+time.Since(start) { - cc.mu.Lock() - cc.errorf("connection timeout") - cc.mu.Unlock() - cc.Close() - return ErrClientConnTimeout - } closeTransport = false - time.Sleep(sleepTime) + select { + case <-time.After(sleepTime): + case <-ac.shutdownChan: + } retries++ - grpclog.Printf("grpc: Conn.resetTransport failed to create client transport: %v; Reconnecting to %q", err, cc.target) + grpclog.Printf("grpc: addrConn.resetTransport failed to create client transport: %v; Reconnecting to %q", err, ac.addr) continue } - cc.mu.Lock() - cc.printf("ready") - if cc.state == Shutdown { - // cc.Close() has been invoked. - cc.mu.Unlock() + ac.mu.Lock() + ac.printf("ready") + if ac.state == Shutdown { + // ac.tearDown(...) has been invoked. + ac.mu.Unlock() newTransport.Close() - return ErrClientConnClosing + return errConnClosing } - cc.state = Ready - cc.stateCV.Broadcast() - cc.transport = newTransport - if cc.ready != nil { - close(cc.ready) - cc.ready = nil + ac.state = Ready + ac.stateCV.Broadcast() + ac.transport = newTransport + if ac.ready != nil { + close(ac.ready) + ac.ready = nil } - cc.mu.Unlock() + ac.down = ac.cc.dopts.balancer.Up(ac.addr) + ac.mu.Unlock() return nil } } -func (cc *Conn) reconnect() bool { - cc.mu.Lock() - if cc.state == Shutdown { - // cc.Close() has been invoked. - cc.mu.Unlock() - return false - } - cc.state = TransientFailure - cc.stateCV.Broadcast() - cc.mu.Unlock() - if err := cc.resetTransport(true); err != nil { - // The ClientConn is closing. - cc.mu.Lock() - cc.printf("transport exiting: %v", err) - cc.mu.Unlock() - grpclog.Printf("grpc: Conn.transportMonitor exits due to: %v", err) - return false - } - return true -} - // Run in a goroutine to track the error in transport and create the // new transport if an error happens. It returns when the channel is closing. -func (cc *Conn) transportMonitor() { +func (ac *addrConn) transportMonitor() { for { + ac.mu.Lock() + t := ac.transport + ac.mu.Unlock() select { // shutdownChan is needed to detect the teardown when - // the ClientConn is idle (i.e., no RPC in flight). - case <-cc.shutdownChan: + // the addrConn is idle (i.e., no RPC in flight). + case <-ac.shutdownChan: return - case <-cc.resetChan: - if !cc.reconnect() { + case <-t.Error(): + ac.mu.Lock() + if ac.state == Shutdown { + // ac.tearDown(...) has been invoked. + ac.mu.Unlock() return } - case <-cc.transport.Error(): - if !cc.reconnect() { + ac.state = TransientFailure + ac.stateCV.Broadcast() + ac.mu.Unlock() + if err := ac.resetTransport(true); err != nil { + ac.mu.Lock() + ac.printf("transport exiting: %v", err) + ac.mu.Unlock() + grpclog.Printf("grpc: addrConn.transportMonitor exits due to: %v", err) return } - // Tries to drain reset signal if there is any since it is out-dated. - select { - case <-cc.resetChan: - default: - } } } } -// Wait blocks until i) the new transport is up or ii) ctx is done or iii) cc is closed. -func (cc *Conn) Wait(ctx context.Context) (transport.ClientTransport, error) { +// 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 the RPC is fail-fast. +func (ac *addrConn) wait(ctx context.Context, failFast bool) (transport.ClientTransport, error) { for { - cc.mu.Lock() + ac.mu.Lock() switch { - case cc.state == Shutdown: - cc.mu.Unlock() - return nil, ErrClientConnClosing - case cc.state == Ready: - cc.mu.Unlock() - return cc.transport, nil + case ac.state == Shutdown: + ac.mu.Unlock() + return nil, errConnClosing + case ac.state == Ready: + ct := ac.transport + ac.mu.Unlock() + return ct, nil + case ac.state == TransientFailure && failFast: + ac.mu.Unlock() + return nil, Errorf(codes.Unavailable, "grpc: RPC failed fast due to transport failure") default: - ready := cc.ready + ready := ac.ready if ready == nil { ready = make(chan struct{}) - cc.ready = ready + ac.ready = ready } - cc.mu.Unlock() + ac.mu.Unlock() select { case <-ctx.Done(): - return nil, transport.ContextErr(ctx.Err()) + return nil, toRPCErr(ctx.Err()) // Wait until the new transport is ready or failed. case <-ready: } @@ -558,32 +679,46 @@ func (cc *Conn) Wait(ctx context.Context) (transport.ClientTransport, error) { } } -// Close starts to tear down the Conn. Returns ErrClientConnClosing if -// it has been closed (mostly due to dial time-out). +// tearDown starts to tear down the addrConn. // TODO(zhaoq): Make this synchronous to avoid unbounded memory consumption in -// some edge cases (e.g., the caller opens and closes many ClientConn's in a +// some edge cases (e.g., the caller opens and closes many addrConn's in a // tight loop. -func (cc *Conn) Close() error { - cc.mu.Lock() - defer cc.mu.Unlock() - if cc.state == Shutdown { - return ErrClientConnClosing +func (ac *addrConn) tearDown(err error) { + ac.mu.Lock() + defer func() { + ac.mu.Unlock() + ac.cc.mu.Lock() + if ac.cc.conns != nil { + delete(ac.cc.conns, ac.addr) + } + ac.cc.mu.Unlock() + }() + if ac.state == Shutdown { + return } - cc.state = Shutdown - cc.stateCV.Broadcast() - if cc.events != nil { - cc.events.Finish() - cc.events = nil + ac.state = Shutdown + if ac.down != nil { + ac.down(downErrorf(false, false, "%v", err)) + ac.down = nil } - if cc.ready != nil { - close(cc.ready) - cc.ready = nil + ac.stateCV.Broadcast() + if ac.events != nil { + ac.events.Finish() + ac.events = nil } - if cc.transport != nil { - cc.transport.Close() + if ac.ready != nil { + close(ac.ready) + ac.ready = nil } - if cc.shutdownChan != nil { - close(cc.shutdownChan) + if ac.transport != nil { + if err == errConnDrain { + ac.transport.GracefulClose() + } else { + ac.transport.Close() + } } - return nil + if ac.shutdownChan != nil { + close(ac.shutdownChan) + } + return } diff --git a/vendor/google.golang.org/grpc/credentials/credentials.go b/vendor/google.golang.org/grpc/credentials/credentials.go index 0b0b89b6aa6..b021e1eb7d4 100644 --- a/vendor/google.golang.org/grpc/credentials/credentials.go +++ b/vendor/google.golang.org/grpc/credentials/credentials.go @@ -54,9 +54,9 @@ var ( alpnProtoStr = []string{"h2"} ) -// Credentials defines the common interface all supported credentials must -// implement. -type Credentials interface { +// PerRPCCredentials defines the common interface for the credentials which need to +// attach security information to every RPC (e.g., oauth2). +type PerRPCCredentials interface { // GetRequestMetadata gets the current request metadata, refreshing // tokens if required. This should be called by the transport layer on // each request, and the data should be populated in headers or other @@ -66,7 +66,7 @@ type Credentials interface { // TODO(zhaoq): Define the set of the qualified keys instead of leaving // it as an arbitrary string. GetRequestMetadata(ctx context.Context, uri ...string) (map[string]string, error) - // RequireTransportSecurity indicates whether the credentails requires + // RequireTransportSecurity indicates whether the credentials requires // transport security. RequireTransportSecurity() bool } @@ -87,9 +87,9 @@ type AuthInfo interface { AuthType() string } -// TransportAuthenticator defines the common interface for all the live gRPC wire +// TransportCredentials defines the common interface for all the live gRPC wire // protocols and supported transport security protocols (e.g., TLS, SSL). -type TransportAuthenticator interface { +type TransportCredentials interface { // ClientHandshake does the authentication handshake specified by the corresponding // authentication protocol on rawConn for clients. It returns the authenticated // connection and the corresponding auth information about the connection. @@ -98,9 +98,8 @@ type TransportAuthenticator interface { // the authenticated connection and the corresponding auth information about // the connection. ServerHandshake(rawConn net.Conn) (net.Conn, AuthInfo, error) - // Info provides the ProtocolInfo of this TransportAuthenticator. + // Info provides the ProtocolInfo of this TransportCredentials. Info() ProtocolInfo - Credentials } // TLSInfo contains the auth information for a TLS authenticated connection. @@ -109,6 +108,7 @@ type TLSInfo struct { State tls.ConnectionState } +// AuthType returns the type of TLSInfo as a string. func (t TLSInfo) AuthType() string { return "tls" } @@ -116,7 +116,7 @@ func (t TLSInfo) AuthType() string { // tlsCreds is the credentials required for authenticating a connection using TLS. type tlsCreds struct { // TLS configuration - config tls.Config + config *tls.Config } func (c tlsCreds) Info() ProtocolInfo { @@ -151,14 +151,16 @@ func (c *tlsCreds) ClientHandshake(addr string, rawConn net.Conn, timeout time.D errChannel <- timeoutError{} }) } + // use local cfg to avoid clobbering ServerName if using multiple endpoints + cfg := *c.config if c.config.ServerName == "" { colonPos := strings.LastIndex(addr, ":") if colonPos == -1 { colonPos = len(addr) } - c.config.ServerName = addr[:colonPos] + cfg.ServerName = addr[:colonPos] } - conn := tls.Client(rawConn, &c.config) + conn := tls.Client(rawConn, &cfg) if timeout == 0 { err = conn.Handshake() } else { @@ -177,7 +179,7 @@ func (c *tlsCreds) ClientHandshake(addr string, rawConn net.Conn, timeout time.D } func (c *tlsCreds) ServerHandshake(rawConn net.Conn) (net.Conn, AuthInfo, error) { - conn := tls.Server(rawConn, &c.config) + conn := tls.Server(rawConn, c.config) if err := conn.Handshake(); err != nil { rawConn.Close() return nil, nil, err @@ -185,20 +187,20 @@ func (c *tlsCreds) ServerHandshake(rawConn net.Conn) (net.Conn, AuthInfo, error) return conn, TLSInfo{conn.ConnectionState()}, nil } -// NewTLS uses c to construct a TransportAuthenticator based on TLS. -func NewTLS(c *tls.Config) TransportAuthenticator { - tc := &tlsCreds{*c} +// NewTLS uses c to construct a TransportCredentials based on TLS. +func NewTLS(c *tls.Config) TransportCredentials { + tc := &tlsCreds{c} tc.config.NextProtos = alpnProtoStr return tc } // NewClientTLSFromCert constructs a TLS from the input certificate for client. -func NewClientTLSFromCert(cp *x509.CertPool, serverName string) TransportAuthenticator { +func NewClientTLSFromCert(cp *x509.CertPool, serverName string) TransportCredentials { return NewTLS(&tls.Config{ServerName: serverName, RootCAs: cp}) } // NewClientTLSFromFile constructs a TLS from the input certificate file for client. -func NewClientTLSFromFile(certFile, serverName string) (TransportAuthenticator, error) { +func NewClientTLSFromFile(certFile, serverName string) (TransportCredentials, error) { b, err := ioutil.ReadFile(certFile) if err != nil { return nil, err @@ -211,13 +213,13 @@ func NewClientTLSFromFile(certFile, serverName string) (TransportAuthenticator, } // NewServerTLSFromCert constructs a TLS from the input certificate for server. -func NewServerTLSFromCert(cert *tls.Certificate) TransportAuthenticator { +func NewServerTLSFromCert(cert *tls.Certificate) TransportCredentials { return NewTLS(&tls.Config{Certificates: []tls.Certificate{*cert}}) } // NewServerTLSFromFile constructs a TLS from the input certificate file and key // file for server. -func NewServerTLSFromFile(certFile, keyFile string) (TransportAuthenticator, error) { +func NewServerTLSFromFile(certFile, keyFile string) (TransportCredentials, error) { cert, err := tls.LoadX509KeyPair(certFile, keyFile) if err != nil { return nil, err diff --git a/vendor/google.golang.org/grpc/doc.go b/vendor/google.golang.org/grpc/doc.go index c0f54f75943..b4c0e740e9c 100644 --- a/vendor/google.golang.org/grpc/doc.go +++ b/vendor/google.golang.org/grpc/doc.go @@ -1,6 +1,6 @@ /* Package grpc implements an RPC system called gRPC. -See https://github.com/grpc/grpc for more information about gRPC. +See www.grpc.io for more information about gRPC. */ package grpc diff --git a/vendor/google.golang.org/grpc/interceptor.go b/vendor/google.golang.org/grpc/interceptor.go new file mode 100644 index 00000000000..588f59e5abf --- /dev/null +++ b/vendor/google.golang.org/grpc/interceptor.go @@ -0,0 +1,74 @@ +/* + * + * Copyright 2016, Google Inc. + * 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. + * + */ + +package grpc + +import ( + "golang.org/x/net/context" +) + +// 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 { + // Server is the service implementation the user provides. This is read-only. + Server interface{} + // FullMethod is the full RPC method string, i.e., /package.service/method. + FullMethod string +} + +// UnaryHandler defines the handler invoked by UnaryServerInterceptor to complete the normal +// execution of a unary RPC. +type UnaryHandler func(ctx context.Context, req interface{}) (interface{}, error) + +// UnaryServerInterceptor provides a hook to intercept the execution of a unary RPC on the server. info +// contains all the information of this RPC the interceptor can operate on. And handler is the wrapper +// of the service method implementation. It is the responsibility of the interceptor to invoke handler +// to complete the RPC. +type UnaryServerInterceptor func(ctx context.Context, req interface{}, info *UnaryServerInfo, handler UnaryHandler) (resp interface{}, err error) + +// StreamServerInfo consists of various information about a streaming RPC on +// server side. All per-rpc information may be mutated by the interceptor. +type StreamServerInfo struct { + // FullMethod is the full RPC method string, i.e., /package.service/method. + FullMethod string + // IsClientStream indicates whether the RPC is a client streaming RPC. + IsClientStream bool + // IsServerStream indicates whether the RPC is a server streaming RPC. + IsServerStream bool +} + +// StreamServerInterceptor provides a hook to intercept the execution of a streaming RPC on the server. +// info contains all the information of this RPC the interceptor can operate on. And handler is the +// service method implementation. It is the responsibility of the interceptor to invoke handler to +// complete the RPC. +type StreamServerInterceptor func(srv interface{}, ss ServerStream, info *StreamServerInfo, handler StreamHandler) error diff --git a/vendor/google.golang.org/grpc/internal/internal.go b/vendor/google.golang.org/grpc/internal/internal.go new file mode 100644 index 00000000000..5489143a85c --- /dev/null +++ b/vendor/google.golang.org/grpc/internal/internal.go @@ -0,0 +1,49 @@ +/* + * Copyright 2016, Google Inc. + * 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. + * + */ + +// Package internal contains gRPC-internal code for testing, to avoid polluting +// the godoc of the top-level grpc package. +package internal + +// TestingCloseConns closes all existing transports but keeps +// grpcServer.lis accepting new connections. +// +// The provided grpcServer must be of type *grpc.Server. It is untyped +// for circular dependency reasons. +var TestingCloseConns func(grpcServer interface{}) + +// TestingUseHandlerImpl enables the http.Handler-based server implementation. +// It must be called before Serve and requires TLS credentials. +// +// The provided grpcServer must be of type *grpc.Server. It is untyped +// for circular dependency reasons. +var TestingUseHandlerImpl func(grpcServer interface{}) diff --git a/vendor/google.golang.org/grpc/naming/naming.go b/vendor/google.golang.org/grpc/naming/naming.go index 06605607c37..c2e0871e6f8 100644 --- a/vendor/google.golang.org/grpc/naming/naming.go +++ b/vendor/google.golang.org/grpc/naming/naming.go @@ -66,7 +66,8 @@ type Resolver interface { // Watcher watches for the updates on the specified target. type Watcher interface { // Next blocks until an update or error happens. It may return one or more - // updates. The first call should get the full set of the results. + // updates. The first call should get the full set of the results. It should + // return an error if and only if Watcher cannot recover. Next() ([]*Update, error) // Close closes the Watcher. Close() diff --git a/vendor/google.golang.org/grpc/picker.go b/vendor/google.golang.org/grpc/picker.go deleted file mode 100644 index 50f315b44f3..00000000000 --- a/vendor/google.golang.org/grpc/picker.go +++ /dev/null @@ -1,243 +0,0 @@ -/* - * - * Copyright 2014, Google Inc. - * 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. - * - */ - -package grpc - -import ( - "container/list" - "fmt" - "sync" - - "golang.org/x/net/context" - "google.golang.org/grpc/grpclog" - "google.golang.org/grpc/naming" - "google.golang.org/grpc/transport" -) - -// Picker picks a Conn for RPC requests. -// This is EXPERIMENTAL and please do not implement your own Picker for now. -type Picker interface { - // Init does initial processing for the Picker, e.g., initiate some connections. - Init(cc *ClientConn) error - // Pick blocks until either a transport.ClientTransport is ready for the upcoming RPC - // or some error happens. - Pick(ctx context.Context) (transport.ClientTransport, error) - // PickAddr picks a peer address for connecting. This will be called repeated for - // connecting/reconnecting. - PickAddr() (string, error) - // State returns the connectivity state of the underlying connections. - State() (ConnectivityState, error) - // WaitForStateChange blocks until the state changes to something other than - // the sourceState. It returns the new state or error. - WaitForStateChange(ctx context.Context, sourceState ConnectivityState) (ConnectivityState, error) - // Close closes all the Conn's owned by this Picker. - Close() error -} - -// unicastPicker is the default Picker which is used when there is no custom Picker -// specified by users. It always picks the same Conn. -type unicastPicker struct { - target string - conn *Conn -} - -func (p *unicastPicker) Init(cc *ClientConn) error { - c, err := NewConn(cc) - if err != nil { - return err - } - p.conn = c - return nil -} - -func (p *unicastPicker) Pick(ctx context.Context) (transport.ClientTransport, error) { - return p.conn.Wait(ctx) -} - -func (p *unicastPicker) PickAddr() (string, error) { - return p.target, nil -} - -func (p *unicastPicker) State() (ConnectivityState, error) { - return p.conn.State(), nil -} - -func (p *unicastPicker) WaitForStateChange(ctx context.Context, sourceState ConnectivityState) (ConnectivityState, error) { - return p.conn.WaitForStateChange(ctx, sourceState) -} - -func (p *unicastPicker) Close() error { - if p.conn != nil { - return p.conn.Close() - } - return nil -} - -// unicastNamingPicker picks an address from a name resolver to set up the connection. -type unicastNamingPicker struct { - cc *ClientConn - resolver naming.Resolver - watcher naming.Watcher - mu sync.Mutex - // The list of the addresses are obtained from watcher. - addrs *list.List - // It tracks the current picked addr by PickAddr(). The next PickAddr may - // push it forward on addrs. - pickedAddr *list.Element - conn *Conn -} - -// NewUnicastNamingPicker creates a Picker to pick addresses from a name resolver -// to connect. -func NewUnicastNamingPicker(r naming.Resolver) Picker { - return &unicastNamingPicker{ - resolver: r, - addrs: list.New(), - } -} - -type addrInfo struct { - addr string - // Set to true if this addrInfo needs to be deleted in the next PickAddrr() call. - deleting bool -} - -// processUpdates calls Watcher.Next() once and processes the obtained updates. -func (p *unicastNamingPicker) processUpdates() error { - updates, err := p.watcher.Next() - if err != nil { - return err - } - for _, update := range updates { - switch update.Op { - case naming.Add: - p.mu.Lock() - p.addrs.PushBack(&addrInfo{ - addr: update.Addr, - }) - p.mu.Unlock() - // Initial connection setup - if p.conn == nil { - conn, err := NewConn(p.cc) - if err != nil { - return err - } - p.conn = conn - } - case naming.Delete: - p.mu.Lock() - for e := p.addrs.Front(); e != nil; e = e.Next() { - if update.Addr == e.Value.(*addrInfo).addr { - if e == p.pickedAddr { - // Do not remove the element now if it is the current picked - // one. We leave the deletion to the next PickAddr() call. - e.Value.(*addrInfo).deleting = true - // Notify Conn to close it. All the live RPCs on this connection - // will be aborted. - p.conn.NotifyReset() - } else { - p.addrs.Remove(e) - } - } - } - p.mu.Unlock() - default: - grpclog.Println("Unknown update.Op ", update.Op) - } - } - return nil -} - -// monitor runs in a standalone goroutine to keep watching name resolution updates until the watcher -// is closed. -func (p *unicastNamingPicker) monitor() { - for { - if err := p.processUpdates(); err != nil { - return - } - } -} - -func (p *unicastNamingPicker) Init(cc *ClientConn) error { - w, err := p.resolver.Resolve(cc.target) - if err != nil { - return err - } - p.watcher = w - p.cc = cc - // Get the initial name resolution. - if err := p.processUpdates(); err != nil { - return err - } - go p.monitor() - return nil -} - -func (p *unicastNamingPicker) Pick(ctx context.Context) (transport.ClientTransport, error) { - return p.conn.Wait(ctx) -} - -func (p *unicastNamingPicker) PickAddr() (string, error) { - p.mu.Lock() - defer p.mu.Unlock() - if p.pickedAddr == nil { - p.pickedAddr = p.addrs.Front() - } else { - pa := p.pickedAddr - p.pickedAddr = pa.Next() - if pa.Value.(*addrInfo).deleting { - p.addrs.Remove(pa) - } - if p.pickedAddr == nil { - p.pickedAddr = p.addrs.Front() - } - } - if p.pickedAddr == nil { - return "", fmt.Errorf("there is no address available to pick") - } - return p.pickedAddr.Value.(*addrInfo).addr, nil -} - -func (p *unicastNamingPicker) State() (ConnectivityState, error) { - return 0, fmt.Errorf("State() is not supported for unicastNamingPicker") -} - -func (p *unicastNamingPicker) WaitForStateChange(ctx context.Context, sourceState ConnectivityState) (ConnectivityState, error) { - return 0, fmt.Errorf("WaitForStateChange is not supported for unicastNamingPciker") -} - -func (p *unicastNamingPicker) Close() error { - p.watcher.Close() - p.conn.Close() - return nil -} diff --git a/vendor/google.golang.org/grpc/rpc_util.go b/vendor/google.golang.org/grpc/rpc_util.go index e98ddbcdc5a..d628717560a 100644 --- a/vendor/google.golang.org/grpc/rpc_util.go +++ b/vendor/google.golang.org/grpc/rpc_util.go @@ -41,9 +41,7 @@ import ( "io" "io/ioutil" "math" - "math/rand" "os" - "time" "github.com/golang/protobuf/proto" "golang.org/x/net/context" @@ -63,7 +61,7 @@ type Codec interface { String() string } -// protoCodec is a Codec implemetation with protobuf. It is the default codec for gRPC. +// protoCodec is a Codec implementation with protobuf. It is the default codec for gRPC. type protoCodec struct{} func (protoCodec) Marshal(v interface{}) ([]byte, error) { @@ -143,6 +141,8 @@ type callInfo struct { traceInfo traceInfo // in trace.go } +var defaultCallInfo = callInfo{failFast: true} + // CallOption configures a Call before it starts or extracts information from // a Call after it completes. type CallOption interface { @@ -181,6 +181,19 @@ func Trailer(md *metadata.MD) CallOption { }) } +// FailFast configures the action to take when an RPC is attempted on broken +// connections or unreachable servers. If failfast is true, the RPC will fail +// immediately. Otherwise, the RPC client will block the call until a +// connection is available (or the call is canceled or times out) and will retry +// the call if it fails due to a transient error. Please refer to +// https://github.com/grpc/grpc/blob/master/doc/fail_fast.md +func FailFast(failFast bool) CallOption { + return beforeCall(func(c *callInfo) error { + c.failFast = failFast + return nil + }) +} + // The format of the payload: compressed or not? type payloadFormat uint8 @@ -189,32 +202,46 @@ const ( compressionMade ) -// parser reads complelete gRPC messages from the underlying reader. +// parser reads complete gRPC messages from the underlying reader. type parser struct { - s io.Reader -} + // r is the underlying reader. + // See the comment on recvMsg for the permissible + // error types. + r io.Reader -// recvMsg is to read a complete gRPC message from the stream. It is blocking if -// the message has not been complete yet. It returns the message and its type, -// EOF is returned with nil msg and 0 pf if the entire stream is done. Other -// non-nil error is returned if something is wrong on reading. -func (p *parser) recvMsg() (pf payloadFormat, msg []byte, err error) { // The header of a gRPC message. Find more detail // at http://www.grpc.io/docs/guides/wire.html. - var buf [5]byte + header [5]byte +} - if _, err := io.ReadFull(p.s, buf[:]); err != nil { +// recvMsg reads a complete gRPC message from the stream. +// +// It returns the message and its payload (compression/encoding) +// format. The caller owns the returned msg memory. +// +// If there is an error, possible values are: +// * io.EOF, when no messages remain +// * io.ErrUnexpectedEOF +// * of type transport.ConnectionError +// * of type transport.StreamError +// No other error values or types must be returned, which also means +// that the underlying io.Reader must not return an incompatible +// error. +func (p *parser) recvMsg() (pf payloadFormat, msg []byte, err error) { + if _, err := io.ReadFull(p.r, p.header[:]); err != nil { return 0, nil, err } - pf = payloadFormat(buf[0]) - length := binary.BigEndian.Uint32(buf[1:]) + pf = payloadFormat(p.header[0]) + length := binary.BigEndian.Uint32(p.header[1:]) if length == 0 { return pf, nil, nil } + // TODO(bradfitz,zhaoq): garbage. reuse buffer after proto decoding instead + // of making it for each message: msg = make([]byte, int(length)) - if _, err := io.ReadFull(p.s, msg); err != nil { + if _, err := io.ReadFull(p.r, msg); err != nil { if err == io.EOF { err = io.ErrUnexpectedEOF } @@ -272,14 +299,11 @@ func checkRecvPayload(pf payloadFormat, recvCompress string, dc Decompressor) er switch pf { case compressionNone: case compressionMade: - if recvCompress == "" { - return transport.StreamErrorf(codes.InvalidArgument, "grpc: received unexpected payload format %d", pf) - } if dc == nil || recvCompress != dc.Type() { - return transport.StreamErrorf(codes.InvalidArgument, "grpc: Decompressor is not installed for grpc-encoding %q", recvCompress) + return transport.StreamErrorf(codes.Unimplemented, "grpc: Decompressor is not installed for grpc-encoding %q", recvCompress) } default: - return transport.StreamErrorf(codes.InvalidArgument, "grpc: received unexpected payload format %d", pf) + return transport.StreamErrorf(codes.Internal, "grpc: received unexpected payload format %d", pf) } return nil } @@ -310,8 +334,8 @@ type rpcError struct { desc string } -func (e rpcError) Error() string { - return fmt.Sprintf("rpc error: code = %d desc = %q", e.code, e.desc) +func (e *rpcError) Error() string { + return fmt.Sprintf("rpc error: code = %d desc = %s", e.code, e.desc) } // Code returns the error code for err if it was produced by the rpc system. @@ -320,7 +344,7 @@ func Code(err error) codes.Code { if err == nil { return codes.OK } - if e, ok := err.(rpcError); ok { + if e, ok := err.(*rpcError); ok { return e.code } return codes.Unknown @@ -332,7 +356,7 @@ func ErrorDesc(err error) string { if err == nil { return "" } - if e, ok := err.(rpcError); ok { + if e, ok := err.(*rpcError); ok { return e.desc } return err.Error() @@ -344,7 +368,7 @@ func Errorf(c codes.Code, format string, a ...interface{}) error { if c == codes.OK { return nil } - return rpcError{ + return &rpcError{ code: c, desc: fmt.Sprintf(format, a...), } @@ -353,18 +377,37 @@ func Errorf(c codes.Code, format string, a ...interface{}) error { // toRPCErr converts an error into a rpcError. func toRPCErr(err error) error { switch e := err.(type) { - case rpcError: + case *rpcError: return err case transport.StreamError: - return rpcError{ + return &rpcError{ code: e.Code, desc: e.Desc, } case transport.ConnectionError: - return rpcError{ + return &rpcError{ code: codes.Internal, desc: e.Desc, } + default: + switch err { + case context.DeadlineExceeded: + return &rpcError{ + code: codes.DeadlineExceeded, + desc: err.Error(), + } + case context.Canceled: + return &rpcError{ + code: codes.Canceled, + desc: err.Error(), + } + case ErrClientConnClosing: + return &rpcError{ + code: codes.FailedPrecondition, + desc: err.Error(), + } + } + } return Errorf(codes.Unknown, "%v", err) } @@ -397,34 +440,10 @@ func convertCode(err error) codes.Code { return codes.Unknown } -const ( - // how long to wait after the first failure before retrying - baseDelay = 1.0 * time.Second - // upper bound of backoff delay - maxDelay = 120 * time.Second - // backoff increases by this factor on each retry - backoffFactor = 1.6 - // backoff is randomized downwards by this factor - backoffJitter = 0.2 -) - -func backoff(retries int) (t time.Duration) { - if retries == 0 { - return baseDelay - } - backoff, max := float64(baseDelay), float64(maxDelay) - for backoff < max && retries > 0 { - backoff *= backoffFactor - retries-- - } - if backoff > max { - backoff = max - } - // Randomize backoff delays so that if a cluster of requests start at - // the same time, they won't operate in lockstep. - backoff *= 1 + backoffJitter*(rand.Float64()*2-1) - if backoff < 0 { - return 0 - } - return time.Duration(backoff) -} +// SupportPackageIsVersion3 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 diff --git a/vendor/google.golang.org/grpc/server.go b/vendor/google.golang.org/grpc/server.go index 1c42b6eff27..a2b2b94d48e 100644 --- a/vendor/google.golang.org/grpc/server.go +++ b/vendor/google.golang.org/grpc/server.go @@ -39,6 +39,7 @@ import ( "fmt" "io" "net" + "net/http" "reflect" "runtime" "strings" @@ -46,15 +47,17 @@ import ( "time" "golang.org/x/net/context" + "golang.org/x/net/http2" "golang.org/x/net/trace" "google.golang.org/grpc/codes" "google.golang.org/grpc/credentials" "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/internal" "google.golang.org/grpc/metadata" "google.golang.org/grpc/transport" ) -type methodHandler func(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) +type methodHandler func(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor UnaryServerInterceptor) (interface{}, error) // MethodDesc represents an RPC service's method specification. type MethodDesc struct { @@ -70,6 +73,7 @@ type ServiceDesc struct { HandlerType interface{} Methods []MethodDesc Streams []StreamDesc + Metadata interface{} } // service consists of the information of the server serving this service and @@ -78,24 +82,29 @@ type service struct { server interface{} // the server for service methods md map[string]*MethodDesc sd map[string]*StreamDesc + mdata interface{} } // Server is a gRPC server to serve RPC requests. type Server struct { - opts options - mu sync.Mutex + opts options + + mu sync.Mutex // guards following lis map[net.Listener]bool - conns map[transport.ServerTransport]bool + conns map[io.Closer]bool m map[string]*service // service name -> service info events trace.EventLog } type options struct { - creds credentials.Credentials + creds credentials.TransportCredentials codec Codec cp Compressor dc Decompressor + unaryInt UnaryServerInterceptor + streamInt StreamServerInterceptor maxConcurrentStreams uint32 + useHandlerImpl bool // use http.Handler-based server } // A ServerOption sets options. @@ -108,12 +117,14 @@ func CustomCodec(codec Codec) ServerOption { } } +// RPCCompressor returns a ServerOption that sets a compressor for outbound message. func RPCCompressor(cp Compressor) ServerOption { return func(o *options) { o.cp = cp } } +// RPCDecompressor returns a ServerOption that sets a decompressor for inbound message. func RPCDecompressor(dc Decompressor) ServerOption { return func(o *options) { o.dc = dc @@ -129,12 +140,35 @@ func MaxConcurrentStreams(n uint32) ServerOption { } // Creds returns a ServerOption that sets credentials for server connections. -func Creds(c credentials.Credentials) ServerOption { +func Creds(c credentials.TransportCredentials) ServerOption { return func(o *options) { o.creds = c } } +// UnaryInterceptor returns a ServerOption that sets the UnaryServerInterceptor for the +// server. Only one unary interceptor can be installed. The construction of multiple +// interceptors (e.g., chaining) can be implemented at the caller. +func UnaryInterceptor(i UnaryServerInterceptor) ServerOption { + return func(o *options) { + if o.unaryInt != nil { + panic("The unary server interceptor has been set.") + } + o.unaryInt = i + } +} + +// StreamInterceptor returns a ServerOption that sets the StreamServerInterceptor for the +// server. Only one stream interceptor can be installed. +func StreamInterceptor(i StreamServerInterceptor) ServerOption { + return func(o *options) { + if o.streamInt != nil { + panic("The stream server interceptor has been set.") + } + o.streamInt = i + } +} + // NewServer creates a gRPC server which has no service registered and has not // started to accept requests yet. func NewServer(opt ...ServerOption) *Server { @@ -149,7 +183,7 @@ func NewServer(opt ...ServerOption) *Server { s := &Server{ lis: make(map[net.Listener]bool), opts: opts, - conns: make(map[transport.ServerTransport]bool), + conns: make(map[io.Closer]bool), m: make(map[string]*service), } if EnableTracing { @@ -198,6 +232,7 @@ func (s *Server) register(sd *ServiceDesc, ss interface{}) { server: ss, md: make(map[string]*MethodDesc), sd: make(map[string]*StreamDesc), + mdata: sd.Metadata, } for i := range sd.Methods { d := &sd.Methods[i] @@ -210,64 +245,135 @@ func (s *Server) register(sd *ServiceDesc, ss interface{}) { s.m[sd.ServiceName] = srv } +// MethodInfo contains the information of an RPC including its method name and type. +type MethodInfo struct { + // Name is the method name only, without the service name or package name. + Name string + // IsClientStream indicates whether the RPC is a client streaming RPC. + IsClientStream bool + // IsServerStream indicates whether the RPC is a server streaming RPC. + IsServerStream bool +} + +// ServiceInfo contains unary RPC method info, streaming RPC methid info and metadata for a service. +type ServiceInfo struct { + Methods []MethodInfo + // Metadata is the metadata specified in ServiceDesc when registering service. + Metadata interface{} +} + +// GetServiceInfo returns a map from service names to ServiceInfo. +// Service names include the package names, in the form of .. +func (s *Server) GetServiceInfo() map[string]*ServiceInfo { + ret := make(map[string]*ServiceInfo) + for n, srv := range s.m { + methods := make([]MethodInfo, 0, len(srv.md)+len(srv.sd)) + for m := range srv.md { + methods = append(methods, MethodInfo{ + Name: m, + IsClientStream: false, + IsServerStream: false, + }) + } + for m, d := range srv.sd { + methods = append(methods, MethodInfo{ + Name: m, + IsClientStream: d.ClientStreams, + IsServerStream: d.ServerStreams, + }) + } + + ret[n] = &ServiceInfo{ + Methods: methods, + Metadata: srv.mdata, + } + } + return ret +} + var ( // ErrServerStopped indicates that the operation is now illegal because of // the server being stopped. ErrServerStopped = errors.New("grpc: the server has been stopped") ) +func (s *Server) useTransportAuthenticator(rawConn net.Conn) (net.Conn, credentials.AuthInfo, error) { + if s.opts.creds == nil { + return rawConn, nil, nil + } + return s.opts.creds.ServerHandshake(rawConn) +} + // Serve accepts incoming connections on the listener lis, creating a new // ServerTransport and service goroutine for each. The service goroutines -// read gRPC request and then call the registered handlers to reply to them. -// Service returns when lis.Accept fails. +// read gRPC requests and then call the registered handlers to reply to them. +// Service returns when lis.Accept fails. lis will be closed when +// this method returns. func (s *Server) Serve(lis net.Listener) error { s.mu.Lock() s.printf("serving") if s.lis == nil { s.mu.Unlock() + lis.Close() return ErrServerStopped } s.lis[lis] = true s.mu.Unlock() defer func() { - lis.Close() s.mu.Lock() - delete(s.lis, lis) + if s.lis != nil && s.lis[lis] { + lis.Close() + delete(s.lis, lis) + } s.mu.Unlock() }() for { - c, err := lis.Accept() + rawConn, err := lis.Accept() if err != nil { s.mu.Lock() s.printf("done serving; Accept = %v", err) s.mu.Unlock() return err } - var authInfo credentials.AuthInfo - if creds, ok := s.opts.creds.(credentials.TransportAuthenticator); ok { - var conn net.Conn - conn, authInfo, err = creds.ServerHandshake(c) - if err != nil { - s.mu.Lock() - s.errorf("ServerHandshake(%q) failed: %v", c.RemoteAddr(), err) - s.mu.Unlock() - grpclog.Println("grpc: Server.Serve failed to complete security handshake.") - continue - } - c = conn - } - s.mu.Lock() - if s.conns == nil { - s.mu.Unlock() - c.Close() - return nil - } - s.mu.Unlock() - - go s.serveNewHTTP2Transport(c, authInfo) + // Start a new goroutine to deal with rawConn + // so we don't stall this Accept loop goroutine. + go s.handleRawConn(rawConn) } } +// handleRawConn is run in its own goroutine and handles a just-accepted +// connection that has not had any I/O performed on it yet. +func (s *Server) handleRawConn(rawConn net.Conn) { + conn, authInfo, err := s.useTransportAuthenticator(rawConn) + if err != nil { + s.mu.Lock() + 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() + return + } + + s.mu.Lock() + if s.conns == nil { + s.mu.Unlock() + conn.Close() + return + } + s.mu.Unlock() + + if s.opts.useHandlerImpl { + s.serveUsingHandler(conn) + } else { + s.serveNewHTTP2Transport(conn, authInfo) + } +} + +// serveNewHTTP2Transport sets up a new http/2 transport (using the +// gRPC http2 server transport in transport/http2_server.go) and +// serves streams on it. +// This is run in its own goroutine (it does network I/O in +// transport.NewServerTransport). func (s *Server) serveNewHTTP2Transport(c net.Conn, authInfo credentials.AuthInfo) { st, err := transport.NewServerTransport("http2", c, s.opts.maxConcurrentStreams, authInfo) if err != nil { @@ -279,7 +385,7 @@ func (s *Server) serveNewHTTP2Transport(c net.Conn, authInfo credentials.AuthInf return } if !s.addConn(st) { - c.Close() + st.Close() return } s.serveStreams(st) @@ -299,6 +405,48 @@ func (s *Server) serveStreams(st transport.ServerTransport) { wg.Wait() } +var _ http.Handler = (*Server)(nil) + +// serveUsingHandler is called from handleRawConn when s is configured +// to handle requests via the http.Handler interface. It sets up a +// net/http.Server to handle the just-accepted conn. The http.Server +// is configured to route all incoming requests (all HTTP/2 streams) +// to ServeHTTP, which creates a new ServerTransport for each stream. +// serveUsingHandler blocks until conn closes. +// +// This codepath is only used when Server.TestingUseHandlerImpl has +// been configured. This lets the end2end tests exercise the ServeHTTP +// method as one of the environment types. +// +// conn is the *tls.Conn that's already been authenticated. +func (s *Server) serveUsingHandler(conn net.Conn) { + if !s.addConn(conn) { + conn.Close() + return + } + defer s.removeConn(conn) + h2s := &http2.Server{ + MaxConcurrentStreams: s.opts.maxConcurrentStreams, + } + h2s.ServeConn(conn, &http2.ServeConnOpts{ + Handler: s, + }) +} + +func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { + st, err := transport.NewServerHandlerTransport(w, r) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + if !s.addConn(st) { + st.Close() + return + } + defer s.removeConn(st) + s.serveStreams(st) +} + // traceInfo returns a traceInfo and associates it with stream, if tracing is enabled. // If tracing is not enabled, it returns nil. func (s *Server) traceInfo(st transport.ServerTransport, stream *transport.Stream) (trInfo *traceInfo) { @@ -317,21 +465,21 @@ func (s *Server) traceInfo(st transport.ServerTransport, stream *transport.Strea return trInfo } -func (s *Server) addConn(st transport.ServerTransport) bool { +func (s *Server) addConn(c io.Closer) bool { s.mu.Lock() defer s.mu.Unlock() if s.conns == nil { return false } - s.conns[st] = true + s.conns[c] = true return true } -func (s *Server) removeConn(st transport.ServerTransport) { +func (s *Server) removeConn(c io.Closer) { s.mu.Lock() defer s.mu.Unlock() if s.conns != nil { - delete(s.conns, st) + delete(s.conns, c) } } @@ -366,13 +514,20 @@ func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport. } }() } - p := &parser{s: stream} + if s.opts.cp != nil { + // NOTE: this needs to be ahead of all handling, https://github.com/grpc/grpc-go/issues/686. + stream.SetSendCompress(s.opts.cp.Type()) + } + p := &parser{r: stream} for { pf, req, err := p.recvMsg() if err == io.EOF { // The entire stream is done (for unary RPC only). return err } + if err == io.ErrUnexpectedEOF { + err = transport.StreamError{Code: codes.Internal, Desc: "io.ErrUnexpectedEOF"} + } if err != nil { switch err := err.(type) { case transport.ConnectionError: @@ -422,9 +577,9 @@ func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport. } return nil } - reply, appErr := md.Handler(srv.server, stream.Context(), df) + reply, appErr := md.Handler(srv.server, stream.Context(), df, s.opts.unaryInt) if appErr != nil { - if err, ok := appErr.(rpcError); ok { + if err, ok := appErr.(*rpcError); ok { statusCode = err.code statusDesc = err.desc } else { @@ -448,9 +603,6 @@ func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport. Last: true, Delay: false, } - if s.opts.cp != nil { - stream.SetSendCompress(s.opts.cp.Type()) - } if err := s.sendResponse(t, stream, reply, s.opts.cp, opts); err != nil { switch err := err.(type) { case transport.ConnectionError: @@ -478,7 +630,7 @@ func (s *Server) processStreamingRPC(t transport.ServerTransport, stream *transp ss := &serverStream{ t: t, s: stream, - p: &parser{s: stream}, + p: &parser{r: stream}, codec: s.opts.codec, cp: s.opts.cp, dc: s.opts.dc, @@ -500,8 +652,19 @@ func (s *Server) processStreamingRPC(t transport.ServerTransport, stream *transp ss.mu.Unlock() }() } - if appErr := sd.Handler(srv.server, ss); appErr != nil { - if err, ok := appErr.(rpcError); ok { + var appErr error + if s.opts.streamInt == nil { + appErr = sd.Handler(srv.server, ss) + } else { + info := &StreamServerInfo{ + FullMethod: stream.Method(), + IsClientStream: sd.ClientStreams, + IsServerStream: sd.ServerStreams, + } + appErr = s.opts.streamInt(srv.server, ss, info, sd.Handler) + } + if appErr != nil { + if err, ok := appErr.(*rpcError); ok { ss.statusCode = err.code ss.statusDesc = err.desc } else if err, ok := appErr.(transport.StreamError); ok { @@ -594,8 +757,11 @@ func (s *Server) handleStream(t transport.ServerTransport, stream *transport.Str } } -// Stop stops the gRPC server. Once Stop returns, the server stops accepting -// connection requests and closes all the connected connections. +// Stop stops the gRPC server. It immediately closes all open +// connections and listeners. +// It cancels all active RPCs on the server side and the corresponding +// pending RPCs on the client side will get notified by connection +// errors. func (s *Server) Stop() { s.mu.Lock() listeners := s.lis @@ -603,12 +769,14 @@ func (s *Server) Stop() { cs := s.conns s.conns = nil s.mu.Unlock() + for lis := range listeners { lis.Close() } for c := range cs { c.Close() } + s.mu.Lock() if s.events != nil { s.events.Finish() @@ -617,14 +785,23 @@ func (s *Server) Stop() { s.mu.Unlock() } -// TestingCloseConns closes all exiting transports but keeps s.lis accepting new -// connections. This is for test only now. -func (s *Server) TestingCloseConns() { +func init() { + internal.TestingCloseConns = func(arg interface{}) { + arg.(*Server).testingCloseConns() + } + internal.TestingUseHandlerImpl = func(arg interface{}) { + arg.(*Server).opts.useHandlerImpl = true + } +} + +// testingCloseConns closes all existing transports but keeps s.lis +// accepting new connections. +func (s *Server) testingCloseConns() { s.mu.Lock() for c := range s.conns { c.Close() + delete(s.conns, c) } - s.conns = make(map[transport.ServerTransport]bool) s.mu.Unlock() } diff --git a/vendor/google.golang.org/grpc/stream.go b/vendor/google.golang.org/grpc/stream.go index 4974d8a82ab..7a3bef511ba 100644 --- a/vendor/google.golang.org/grpc/stream.go +++ b/vendor/google.golang.org/grpc/stream.go @@ -47,12 +47,14 @@ import ( "google.golang.org/grpc/transport" ) -type streamHandler func(srv interface{}, stream ServerStream) error +// StreamHandler defines the handler called by gRPC server to complete the +// execution of a streaming RPC. +type StreamHandler func(srv interface{}, stream ServerStream) error // StreamDesc represents a streaming RPC service's method specification. type StreamDesc struct { StreamName string - Handler streamHandler + Handler StreamHandler // At least one of these is true. ServerStreams bool @@ -67,18 +69,19 @@ type Stream interface { // breaks. // On error, it aborts the stream and returns an RPC status on client // side. On server side, it simply returns the error to the caller. - // SendMsg is called by generated code. + // SendMsg is called by generated code. Also Users can call SendMsg + // directly when it is really needed in their use cases. SendMsg(m interface{}) error // RecvMsg blocks until it receives a message or the stream is // done. On client side, it returns io.EOF when the stream is done. On - // any other error, it aborts the streama nd returns an RPC status. On + // any other error, it aborts the stream and returns an RPC status. On // server side, it simply returns the error to the caller. RecvMsg(m interface{}) error } -// ClientStream defines the interface a client stream has to satify. +// ClientStream defines the interface a client stream has to satisfy. type ClientStream interface { - // Header returns the header metedata received from the server if there + // Header returns the header metadata received from the server if there // is any. It blocks if the metadata is not ready to read. Header() (metadata.MD, error) // Trailer returns the trailer metadata from the server. It must be called @@ -99,22 +102,27 @@ type ClientStream interface { func NewClientStream(ctx context.Context, desc *StreamDesc, cc *ClientConn, method string, opts ...CallOption) (ClientStream, error) { var ( t transport.ClientTransport + s *transport.Stream err error + put func() ) - t, err = cc.dopts.picker.Pick(ctx) - if err != nil { - return nil, toRPCErr(err) + c := defaultCallInfo + for _, o := range opts { + if err := o.before(&c); err != nil { + return nil, toRPCErr(err) + } } - // TODO(zhaoq): CallOption is omitted. Add support when it is needed. callHdr := &transport.CallHdr{ Host: cc.authority, Method: method, - Flush: desc.ServerStreams&&desc.ClientStreams, + Flush: desc.ServerStreams && desc.ClientStreams, } if cc.dopts.cp != nil { callHdr.SendCompress = cc.dopts.cp.Type() } cs := &clientStream{ + opts: opts, + c: c, desc: desc, codec: cc.dopts.codec, cp: cc.dopts.cp, @@ -134,14 +142,47 @@ func NewClientStream(ctx context.Context, desc *StreamDesc, cc *ClientConn, meth cs.trInfo.tr.LazyLog(&cs.trInfo.firstLine, false) ctx = trace.NewContext(ctx, cs.trInfo.tr) } - s, err := t.NewStream(ctx, callHdr) - if err != nil { - cs.finish(err) - return nil, toRPCErr(err) + gopts := BalancerGetOptions{ + BlockingWait: !c.failFast, } + for { + t, put, err = cc.getTransport(ctx, gopts) + if err != nil { + // TODO(zhaoq): Probably revisit the error handling. + if _, ok := err.(*rpcError); ok { + return nil, err + } + if err == errConnClosing { + if c.failFast { + return nil, Errorf(codes.Unavailable, "%v", errConnClosing) + } + continue + } + // All the other errors are treated as Internal errors. + return nil, Errorf(codes.Internal, "%v", err) + } + + s, err = t.NewStream(ctx, callHdr) + if err != nil { + if put != nil { + put() + put = nil + } + if _, ok := err.(transport.ConnectionError); ok { + if c.failFast { + cs.finish(err) + return nil, toRPCErr(err) + } + continue + } + return nil, toRPCErr(err) + } + break + } + cs.put = put cs.t = t cs.s = s - cs.p = &parser{s: s} + cs.p = &parser{r: s} // Listen on ctx.Done() to detect cancellation when there is no pending // I/O operations on this stream. go func() { @@ -159,6 +200,8 @@ func NewClientStream(ctx context.Context, desc *StreamDesc, cc *ClientConn, meth // clientStream implements a client side Stream. type clientStream struct { + opts []CallOption + c callInfo t transport.ClientTransport s *transport.Stream p *parser @@ -171,6 +214,7 @@ type clientStream struct { tracing bool // set to EnableTracing when the clientStream is created. mu sync.Mutex + put func() closed bool // trInfo.tr is set when the clientStream is created (if EnableTracing is true), // and is set to nil when the clientStream's finish method is called. @@ -204,6 +248,9 @@ func (cs *clientStream) SendMsg(m interface{}) (err error) { cs.mu.Unlock() } defer func() { + if err != nil { + cs.finish(err) + } if err == nil || err == io.EOF { return } @@ -251,9 +298,10 @@ func (cs *clientStream) RecvMsg(m interface{}) (err error) { } if err == io.EOF { if cs.s.StatusCode() == codes.OK { + cs.finish(err) return nil } - return Errorf(cs.s.StatusCode(), cs.s.StatusDesc()) + return Errorf(cs.s.StatusCode(), "%s", cs.s.StatusDesc()) } return toRPCErr(err) } @@ -265,13 +313,18 @@ func (cs *clientStream) RecvMsg(m interface{}) (err error) { // Returns io.EOF to indicate the end of the stream. return } - return Errorf(cs.s.StatusCode(), cs.s.StatusDesc()) + return Errorf(cs.s.StatusCode(), "%s", cs.s.StatusDesc()) } return toRPCErr(err) } func (cs *clientStream) CloseSend() (err error) { err = cs.t.Write(cs.s, nil, &transport.Options{Last: true}) + defer func() { + if err != nil { + cs.finish(err) + } + }() if err == nil || err == io.EOF { return } @@ -294,11 +347,18 @@ func (cs *clientStream) closeTransportStream(err error) { } func (cs *clientStream) finish(err error) { + cs.mu.Lock() + defer cs.mu.Unlock() + for _, o := range cs.opts { + o.after(&cs.c) + } + if cs.put != nil { + cs.put() + cs.put = nil + } if !cs.tracing { return } - cs.mu.Lock() - defer cs.mu.Unlock() if cs.trInfo.tr != nil { if err == nil || err == io.EOF { cs.trInfo.tr.LazyPrintf("RPC: [OK]") diff --git a/vendor/google.golang.org/grpc/trace.go b/vendor/google.golang.org/grpc/trace.go index cde04fbfc9e..f6747e1dfa4 100644 --- a/vendor/google.golang.org/grpc/trace.go +++ b/vendor/google.golang.org/grpc/trace.go @@ -101,9 +101,8 @@ type payload struct { func (p payload) String() string { if p.sent { return fmt.Sprintf("sent: %v", p.msg) - } else { - return fmt.Sprintf("recv: %v", p.msg) } + return fmt.Sprintf("recv: %v", p.msg) } type fmtStringer struct { diff --git a/vendor/google.golang.org/grpc/transport/control.go b/vendor/google.golang.org/grpc/transport/control.go index f6b38a5a6d2..7e9bdf33506 100644 --- a/vendor/google.golang.org/grpc/transport/control.go +++ b/vendor/google.golang.org/grpc/transport/control.go @@ -56,43 +56,33 @@ type windowUpdate struct { increment uint32 } -func (windowUpdate) isItem() bool { - return true -} +func (*windowUpdate) item() {} type settings struct { ack bool ss []http2.Setting } -func (settings) isItem() bool { - return true -} +func (*settings) item() {} type resetStream struct { streamID uint32 code http2.ErrCode } -func (resetStream) isItem() bool { - return true -} +func (*resetStream) item() {} type flushIO struct { } -func (flushIO) isItem() bool { - return true -} +func (*flushIO) item() {} type ping struct { ack bool data [8]byte } -func (ping) isItem() bool { - return true -} +func (*ping) item() {} // quotaPool is a pool which accumulates the quota and sends it to acquire() // when it is available. @@ -172,10 +162,6 @@ func (qb *quotaPool) acquire() <-chan int { type inFlow struct { // The inbound flow control limit for pending data. limit uint32 - // conn points to the shared connection-level inFlow that is shared - // by all streams on that conn. It is nil for the inFlow on the conn - // directly. - conn *inFlow mu sync.Mutex // pendingData is the overall data which have been received but not been @@ -186,75 +172,39 @@ type inFlow struct { pendingUpdate uint32 } -// onData is invoked when some data frame is received. It increments not only its -// own pendingData but also that of the associated connection-level flow. +// onData is invoked when some data frame is received. It updates pendingData. func (f *inFlow) onData(n uint32) error { - if n == 0 { - return nil - } f.mu.Lock() defer f.mu.Unlock() - if f.pendingData+f.pendingUpdate+n > f.limit { - return fmt.Errorf("recieved %d-bytes data exceeding the limit %d bytes", f.pendingData+f.pendingUpdate+n, f.limit) - } - if f.conn != nil { - if err := f.conn.onData(n); err != nil { - return ConnectionErrorf("%v", err) - } - } f.pendingData += n + if f.pendingData+f.pendingUpdate > f.limit { + return fmt.Errorf("received %d-bytes data exceeding the limit %d bytes", f.pendingData+f.pendingUpdate, f.limit) + } return nil } -// connOnRead updates the connection level states when the application consumes data. -func (f *inFlow) connOnRead(n uint32) uint32 { - if n == 0 || f.conn != nil { - return 0 - } +// onRead is invoked when the application reads the data. It returns the window size +// to be sent to the peer. +func (f *inFlow) onRead(n uint32) uint32 { f.mu.Lock() defer f.mu.Unlock() + if f.pendingData == 0 { + return 0 + } f.pendingData -= n f.pendingUpdate += n if f.pendingUpdate >= f.limit/4 { - ret := f.pendingUpdate + wu := f.pendingUpdate f.pendingUpdate = 0 - return ret + return wu } return 0 } -// onRead is invoked when the application reads the data. It returns the window updates -// for both stream and connection level. -func (f *inFlow) onRead(n uint32) (swu, cwu uint32) { - if n == 0 { - return - } - f.mu.Lock() - defer f.mu.Unlock() - if f.pendingData == 0 { - // pendingData has been adjusted by restoreConn. - return - } - f.pendingData -= n - f.pendingUpdate += n - if f.pendingUpdate >= f.limit/4 { - swu = f.pendingUpdate - f.pendingUpdate = 0 - } - cwu = f.conn.connOnRead(n) - return -} - -// restoreConn is invoked when a stream is terminated. It removes its stake in -// the connection-level flow and resets its own state. -func (f *inFlow) restoreConn() uint32 { - if f.conn == nil { - return 0 - } +func (f *inFlow) resetPendingData() uint32 { f.mu.Lock() defer f.mu.Unlock() n := f.pendingData f.pendingData = 0 - f.pendingUpdate = 0 - return f.conn.connOnRead(n) + return n } diff --git a/vendor/google.golang.org/grpc/transport/handler_server.go b/vendor/google.golang.org/grpc/transport/handler_server.go new file mode 100644 index 00000000000..4b0d525243b --- /dev/null +++ b/vendor/google.golang.org/grpc/transport/handler_server.go @@ -0,0 +1,393 @@ +/* + * Copyright 2016, Google Inc. + * 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. + * + */ + +// This file is the implementation of a gRPC server using HTTP/2 which +// uses the standard Go http2 Server implementation (via the +// http.Handler interface), rather than speaking low-level HTTP/2 +// frames itself. It is the implementation of *grpc.Server.ServeHTTP. + +package transport + +import ( + "errors" + "fmt" + "io" + "net" + "net/http" + "strings" + "sync" + "time" + + "golang.org/x/net/context" + "golang.org/x/net/http2" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/credentials" + "google.golang.org/grpc/metadata" + "google.golang.org/grpc/peer" +) + +// NewServerHandlerTransport returns a ServerTransport handling gRPC +// from inside an http.Handler. It requires that the http Server +// supports HTTP/2. +func NewServerHandlerTransport(w http.ResponseWriter, r *http.Request) (ServerTransport, error) { + if r.ProtoMajor != 2 { + return nil, errors.New("gRPC requires HTTP/2") + } + if r.Method != "POST" { + return nil, errors.New("invalid gRPC request method") + } + if !validContentType(r.Header.Get("Content-Type")) { + return nil, errors.New("invalid gRPC request content-type") + } + if _, ok := w.(http.Flusher); !ok { + return nil, errors.New("gRPC requires a ResponseWriter supporting http.Flusher") + } + if _, ok := w.(http.CloseNotifier); !ok { + return nil, errors.New("gRPC requires a ResponseWriter supporting http.CloseNotifier") + } + + st := &serverHandlerTransport{ + rw: w, + req: r, + closedCh: make(chan struct{}), + writes: make(chan func()), + } + + if v := r.Header.Get("grpc-timeout"); v != "" { + to, err := timeoutDecode(v) + if err != nil { + return nil, StreamErrorf(codes.Internal, "malformed time-out: %v", err) + } + st.timeoutSet = true + st.timeout = to + } + + var metakv []string + if r.Host != "" { + metakv = append(metakv, ":authority", r.Host) + } + for k, vv := range r.Header { + k = strings.ToLower(k) + if isReservedHeader(k) && !isWhitelistedPseudoHeader(k) { + continue + } + for _, v := range vv { + if k == "user-agent" { + // user-agent is special. Copying logic of http_util.go. + if i := strings.LastIndex(v, " "); i == -1 { + // There is no application user agent string being set + continue + } else { + v = v[:i] + } + } + metakv = append(metakv, k, v) + } + } + st.headerMD = metadata.Pairs(metakv...) + + return st, nil +} + +// serverHandlerTransport is an implementation of ServerTransport +// which replies to exactly one gRPC request (exactly one HTTP request), +// using the net/http.Handler interface. This http.Handler is guaranteed +// at this point to be speaking over HTTP/2, so it's able to speak valid +// gRPC. +type serverHandlerTransport struct { + rw http.ResponseWriter + req *http.Request + timeoutSet bool + timeout time.Duration + didCommonHeaders bool + + headerMD metadata.MD + + closeOnce sync.Once + closedCh chan struct{} // closed on Close + + // writes is a channel of code to run serialized in the + // ServeHTTP (HandleStreams) goroutine. The channel is closed + // when WriteStatus is called. + writes chan func() +} + +func (ht *serverHandlerTransport) Close() error { + ht.closeOnce.Do(ht.closeCloseChanOnce) + return nil +} + +func (ht *serverHandlerTransport) closeCloseChanOnce() { close(ht.closedCh) } + +func (ht *serverHandlerTransport) RemoteAddr() net.Addr { return strAddr(ht.req.RemoteAddr) } + +// strAddr is a net.Addr backed by either a TCP "ip:port" string, or +// the empty string if unknown. +type strAddr string + +func (a strAddr) Network() string { + if a != "" { + // Per the documentation on net/http.Request.RemoteAddr, if this is + // set, it's set to the IP:port of the peer (hence, TCP): + // https://golang.org/pkg/net/http/#Request + // + // If we want to support Unix sockets later, we can + // add our own grpc-specific convention within the + // grpc codebase to set RemoteAddr to a different + // format, or probably better: we can attach it to the + // context and use that from serverHandlerTransport.RemoteAddr. + return "tcp" + } + return "" +} + +func (a strAddr) String() string { return string(a) } + +// do runs fn in the ServeHTTP goroutine. +func (ht *serverHandlerTransport) do(fn func()) error { + select { + case ht.writes <- fn: + return nil + case <-ht.closedCh: + return ErrConnClosing + } +} + +func (ht *serverHandlerTransport) WriteStatus(s *Stream, statusCode codes.Code, statusDesc string) error { + err := ht.do(func() { + ht.writeCommonHeaders(s) + + // And flush, in case no header or body has been sent yet. + // This forces a separation of headers and trailers if this is the + // first call (for example, in end2end tests's TestNoService). + ht.rw.(http.Flusher).Flush() + + h := ht.rw.Header() + h.Set("Grpc-Status", fmt.Sprintf("%d", statusCode)) + if statusDesc != "" { + h.Set("Grpc-Message", statusDesc) + } + if md := s.Trailer(); len(md) > 0 { + for k, vv := range md { + // Clients don't tolerate reading restricted headers after some non restricted ones were sent. + if isReservedHeader(k) { + continue + } + for _, v := range vv { + // http2 ResponseWriter mechanism to + // send undeclared Trailers after the + // headers have possibly been written. + h.Add(http2.TrailerPrefix+k, v) + } + } + } + }) + close(ht.writes) + return err +} + +// writeCommonHeaders sets common headers on the first write +// call (Write, WriteHeader, or WriteStatus). +func (ht *serverHandlerTransport) writeCommonHeaders(s *Stream) { + if ht.didCommonHeaders { + return + } + ht.didCommonHeaders = true + + h := ht.rw.Header() + h["Date"] = nil // suppress Date to make tests happy; TODO: restore + h.Set("Content-Type", "application/grpc") + + // Predeclare trailers we'll set later in WriteStatus (after the body). + // This is a SHOULD in the HTTP RFC, and the way you add (known) + // Trailers per the net/http.ResponseWriter contract. + // See https://golang.org/pkg/net/http/#ResponseWriter + // and https://golang.org/pkg/net/http/#example_ResponseWriter_trailers + h.Add("Trailer", "Grpc-Status") + h.Add("Trailer", "Grpc-Message") + + if s.sendCompress != "" { + h.Set("Grpc-Encoding", s.sendCompress) + } +} + +func (ht *serverHandlerTransport) Write(s *Stream, data []byte, opts *Options) error { + return ht.do(func() { + ht.writeCommonHeaders(s) + ht.rw.Write(data) + if !opts.Delay { + ht.rw.(http.Flusher).Flush() + } + }) +} + +func (ht *serverHandlerTransport) WriteHeader(s *Stream, md metadata.MD) error { + return ht.do(func() { + ht.writeCommonHeaders(s) + h := ht.rw.Header() + for k, vv := range md { + // Clients don't tolerate reading restricted headers after some non restricted ones were sent. + if isReservedHeader(k) { + continue + } + for _, v := range vv { + h.Add(k, v) + } + } + ht.rw.WriteHeader(200) + ht.rw.(http.Flusher).Flush() + }) +} + +func (ht *serverHandlerTransport) HandleStreams(startStream func(*Stream)) { + // With this transport type there will be exactly 1 stream: this HTTP request. + + var ctx context.Context + var cancel context.CancelFunc + if ht.timeoutSet { + ctx, cancel = context.WithTimeout(context.Background(), ht.timeout) + } else { + ctx, cancel = context.WithCancel(context.Background()) + } + + // requestOver is closed when either the request's context is done + // or the status has been written via WriteStatus. + requestOver := make(chan struct{}) + + // clientGone receives a single value if peer is gone, either + // because the underlying connection is dead or because the + // peer sends an http2 RST_STREAM. + clientGone := ht.rw.(http.CloseNotifier).CloseNotify() + go func() { + select { + case <-requestOver: + return + case <-ht.closedCh: + case <-clientGone: + } + cancel() + }() + + req := ht.req + + s := &Stream{ + id: 0, // irrelevant + windowHandler: func(int) {}, // nothing + cancel: cancel, + buf: newRecvBuffer(), + st: ht, + method: req.URL.Path, + recvCompress: req.Header.Get("grpc-encoding"), + } + pr := &peer.Peer{ + Addr: ht.RemoteAddr(), + } + if req.TLS != nil { + pr.AuthInfo = credentials.TLSInfo{State: *req.TLS} + } + ctx = metadata.NewContext(ctx, ht.headerMD) + ctx = peer.NewContext(ctx, pr) + s.ctx = newContextWithStream(ctx, s) + s.dec = &recvBufferReader{ctx: s.ctx, recv: s.buf} + + // readerDone is closed when the Body.Read-ing goroutine exits. + readerDone := make(chan struct{}) + go func() { + defer close(readerDone) + + // TODO: minimize garbage, optimize recvBuffer code/ownership + const readSize = 8196 + for buf := make([]byte, readSize); ; { + n, err := req.Body.Read(buf) + if n > 0 { + s.buf.put(&recvMsg{data: buf[:n:n]}) + buf = buf[n:] + } + if err != nil { + s.buf.put(&recvMsg{err: mapRecvMsgError(err)}) + return + } + if len(buf) == 0 { + buf = make([]byte, readSize) + } + } + }() + + // startStream is provided by the *grpc.Server's serveStreams. + // It starts a goroutine serving s and exits immediately. + // The goroutine that is started is the one that then calls + // into ht, calling WriteHeader, Write, WriteStatus, Close, etc. + startStream(s) + + ht.runStream() + close(requestOver) + + // Wait for reading goroutine to finish. + req.Body.Close() + <-readerDone +} + +func (ht *serverHandlerTransport) runStream() { + for { + select { + case fn, ok := <-ht.writes: + if !ok { + return + } + fn() + case <-ht.closedCh: + return + } + } +} + +// mapRecvMsgError returns the non-nil err into the appropriate +// error value as expected by callers of *grpc.parser.recvMsg. +// In particular, in can only be: +// * io.EOF +// * io.ErrUnexpectedEOF +// * of type transport.ConnectionError +// * of type transport.StreamError +func mapRecvMsgError(err error) error { + if err == io.EOF || err == io.ErrUnexpectedEOF { + return err + } + if se, ok := err.(http2.StreamError); ok { + if code, ok := http2ErrConvTab[se.Code]; ok { + return StreamError{ + Code: code, + Desc: se.Error(), + } + } + } + return ConnectionError{Desc: 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 7cf700fe3e4..f66435fdbd5 100644 --- a/vendor/google.golang.org/grpc/transport/http2_client.go +++ b/vendor/google.golang.org/grpc/transport/http2_client.go @@ -35,7 +35,6 @@ package transport import ( "bytes" - "errors" "io" "math" "net" @@ -89,7 +88,7 @@ type http2Client struct { // The scheme used: https if TLS is on, http otherwise. scheme string - authCreds []credentials.Credentials + creds []credentials.PerRPCCredentials mu sync.Mutex // guard the following variables state transportState // the state of underlying connection @@ -118,19 +117,12 @@ func newHTTP2Client(addr string, opts *ConnectOptions) (_ ClientTransport, err e return nil, ConnectionErrorf("transport: %v", connErr) } var authInfo credentials.AuthInfo - for _, c := range opts.AuthOptions { - if ccreds, ok := c.(credentials.TransportAuthenticator); ok { - scheme = "https" - // TODO(zhaoq): Now the first TransportAuthenticator is used if there are - // multiple ones provided. Revisit this if it is not appropriate. Probably - // place the ClientTransport construction into a separate function to make - // things clear. - if timeout > 0 { - timeout -= time.Since(startT) - } - conn, authInfo, connErr = ccreds.ClientHandshake(addr, conn, timeout) - break + if opts.TransportCredentials != nil { + scheme = "https" + if timeout > 0 { + timeout -= time.Since(startT) } + conn, authInfo, connErr = opts.TransportCredentials.ClientHandshake(addr, conn, timeout) } if connErr != nil { return nil, ConnectionErrorf("transport: %v", connErr) @@ -140,29 +132,6 @@ func newHTTP2Client(addr string, opts *ConnectOptions) (_ ClientTransport, err e conn.Close() } }() - // Send connection preface to server. - n, err := conn.Write(clientPreface) - if err != nil { - return nil, ConnectionErrorf("transport: %v", err) - } - if n != len(clientPreface) { - return nil, ConnectionErrorf("transport: preface mismatch, wrote %d bytes; want %d", n, len(clientPreface)) - } - framer := newFramer(conn) - if initialWindowSize != defaultWindowSize { - err = framer.writeSettings(true, http2.Setting{http2.SettingInitialWindowSize, uint32(initialWindowSize)}) - } else { - err = framer.writeSettings(true) - } - if err != nil { - return nil, ConnectionErrorf("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("transport: %v", err) - } - } ua := primaryUA if opts.UserAgent != "" { ua = opts.UserAgent + " " + ua @@ -178,7 +147,7 @@ func newHTTP2Client(addr string, opts *ConnectOptions) (_ ClientTransport, err e writableChan: make(chan int, 1), shutdownChan: make(chan struct{}), errorChan: make(chan struct{}), - framer: framer, + framer: newFramer(conn), hBuf: &buf, hEnc: hpack.NewEncoder(&buf), controlBuf: newRecvBuffer(), @@ -187,32 +156,56 @@ func newHTTP2Client(addr string, opts *ConnectOptions) (_ ClientTransport, err e scheme: scheme, state: reachable, activeStreams: make(map[uint32]*Stream), - authCreds: opts.AuthOptions, + creds: opts.PerRPCCredentials, maxStreams: math.MaxInt32, streamSendQuota: defaultWindowSize, } + // Start the reader goroutine for incoming message. Each transport has + // a dedicated goroutine which reads HTTP2 frame from network. Then it + // dispatches the frame to the corresponding stream entity. + go t.reader() + // Send connection preface to server. + n, err := t.conn.Write(clientPreface) + if err != nil { + t.Close() + return nil, ConnectionErrorf("transport: %v", err) + } + if n != len(clientPreface) { + t.Close() + return nil, ConnectionErrorf("transport: preface mismatch, wrote %d bytes; want %d", n, len(clientPreface)) + } + if initialWindowSize != defaultWindowSize { + err = t.framer.writeSettings(true, http2.Setting{ + ID: http2.SettingInitialWindowSize, + Val: uint32(initialWindowSize), + }) + } else { + err = t.framer.writeSettings(true) + } + if err != nil { + t.Close() + return nil, ConnectionErrorf("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("transport: %v", err) + } + } go t.controller() t.writableChan <- 0 - // Start the reader goroutine for incoming message. The threading model - // on receiving is that each transport has a dedicated goroutine which - // reads HTTP2 frame from network. Then it dispatches the frame to the - // corresponding stream entity. - go t.reader() return t, nil } func (t *http2Client) newStream(ctx context.Context, callHdr *CallHdr) *Stream { - fc := &inFlow{ - limit: initialWindowSize, - conn: t.fc, - } // TODO(zhaoq): Handle uint32 overflow of Stream.id. s := &Stream{ id: t.nextID, method: callHdr.Method, sendCompress: callHdr.SendCompress, buf: newRecvBuffer(), - fc: fc, + fc: &inFlow{limit: initialWindowSize}, sendQuotaPool: newQuotaPool(int(t.streamSendQuota)), headerChan: make(chan struct{}), } @@ -236,9 +229,11 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (_ *Strea var timeout time.Duration if dl, ok := ctx.Deadline(); ok { timeout = dl.Sub(time.Now()) - if timeout <= 0 { - return nil, ContextErr(context.DeadlineExceeded) - } + } + select { + case <-ctx.Done(): + return nil, ContextErr(ctx.Err()) + default: } pr := &peer.Peer{ Addr: t.conn.RemoteAddr(), @@ -249,7 +244,7 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (_ *Strea } ctx = peer.NewContext(ctx, pr) authData := make(map[string]string) - for _, c := range t.authCreds { + for _, c := range t.creds { // Construct URI required to get auth request metadata. var port string if pos := strings.LastIndex(t.target, ":"); pos != -1 { @@ -272,6 +267,10 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (_ *Strea } } t.mu.Lock() + if t.activeStreams == nil { + t.mu.Unlock() + return nil, ErrConnClosing + } if t.state != reachable { t.mu.Unlock() return nil, ErrConnClosing @@ -289,7 +288,10 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (_ *Strea } } if _, err := wait(ctx, t.shutdownChan, t.writableChan); err != nil { - // t.streamsQuota will be updated when t.CloseStream is invoked. + // Return the quota back now because there is no stream returned to the caller. + if _, ok := err.(StreamError); ok && checkStreamsQuota { + t.streamsQuota.add(1) + } return nil, err } t.mu.Lock() @@ -330,6 +332,8 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (_ *Strea t.hEnc.WriteField(hpack.HeaderField{Name: "grpc-timeout", Value: timeoutEncode(timeout)}) } for k, v := range authData { + // Capital header names are illegal in HTTP/2. + k = strings.ToLower(k) t.hEnc.WriteField(hpack.HeaderField{Name: k, Value: v}) } var ( @@ -339,6 +343,10 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (_ *Strea if md, ok := metadata.FromContext(ctx); ok { hasMD = true for k, v := range md { + // HTTP doesn't allow you to set pseudoheaders after non pseudoheaders were set. + if isReservedHeader(k) { + continue + } for _, entry := range v { t.hEnc.WriteField(hpack.HeaderField{Name: k, Value: entry}) } @@ -388,9 +396,19 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (_ *Strea func (t *http2Client) CloseStream(s *Stream, err error) { var updateStreams bool t.mu.Lock() + if t.activeStreams == nil { + t.mu.Unlock() + return + } if t.streamsQuota != nil { updateStreams = true } + if t.state == draining && len(t.activeStreams) == 1 { + // The transport is draining and s is the last live stream on t. + t.mu.Unlock() + t.Close() + return + } delete(t.activeStreams, s.id) t.mu.Unlock() if updateStreams { @@ -402,8 +420,10 @@ func (t *http2Client) CloseStream(s *Stream, err error) { // other goroutines. s.cancel() s.mu.Lock() - if q := s.fc.restoreConn(); q > 0 { - t.controlBuf.put(&windowUpdate{0, q}) + if q := s.fc.resetPendingData(); q > 0 { + if n := t.fc.onRead(q); n > 0 { + t.controlBuf.put(&windowUpdate{0, n}) + } } if s.state == streamDone { s.mu.Unlock() @@ -425,9 +445,12 @@ func (t *http2Client) CloseStream(s *Stream, err error) { // accessed any more. func (t *http2Client) Close() (err error) { t.mu.Lock() + if t.state == reachable { + close(t.errorChan) + } if t.state == closing { t.mu.Unlock() - return errors.New("transport: Close() was already called") + return } t.state = closing t.mu.Unlock() @@ -450,6 +473,25 @@ func (t *http2Client) Close() (err error) { return } +func (t *http2Client) GracefulClose() error { + t.mu.Lock() + if t.state == closing { + t.mu.Unlock() + return nil + } + if t.state == draining { + t.mu.Unlock() + return nil + } + t.state = draining + active := len(t.activeStreams) + t.mu.Unlock() + if active == 0 { + return t.Close() + } + return nil +} + // Write formats the data into HTTP2 data frame(s) and sends it out. The caller // should proceed only if Write returns nil. // TODO(zhaoq): opts.Delay is ignored in this implementation. Support it later @@ -503,6 +545,10 @@ func (t *http2Client) Write(s *Stream, data []byte, opts *Options) error { t.framer.adjustNumWriters(1) // Got some quota. Try to acquire writing privilege on the transport. if _, err := wait(s.ctx, t.shutdownChan, t.writableChan); err != nil { + if _, ok := err.(StreamError); ok { + // Return the connection quota back. + t.sendQuotaPool.add(len(p)) + } if t.framer.adjustNumWriters(-1) == 0 { // This writer is the last one in this batch and has the // responsibility to flush the buffered frames. It queues @@ -512,6 +558,16 @@ func (t *http2Client) Write(s *Stream, data []byte, opts *Options) error { } return err } + select { + case <-s.ctx.Done(): + t.sendQuotaPool.add(len(p)) + if t.framer.adjustNumWriters(-1) == 0 { + t.controlBuf.put(&flushIO{}) + } + t.writableChan <- 0 + return ContextErr(s.ctx.Err()) + default: + } if r.Len() == 0 && t.framer.adjustNumWriters(0) == 1 { // Do a force flush iff this is last frame for the entire gRPC message // and the caller is the only writer at this moment. @@ -550,47 +606,52 @@ func (t *http2Client) Write(s *Stream, data []byte, opts *Options) error { func (t *http2Client) getStream(f http2.Frame) (*Stream, bool) { t.mu.Lock() defer t.mu.Unlock() - if t.activeStreams == nil { - // The transport is closing. - return nil, false - } - if s, ok := t.activeStreams[f.Header().StreamID]; ok { - return s, true - } - return nil, false + s, ok := t.activeStreams[f.Header().StreamID] + return s, ok } // updateWindow adjusts the inbound quota for the stream and the transport. // Window updates will deliver to the controller for sending when // the cumulative quota exceeds the corresponding threshold. func (t *http2Client) updateWindow(s *Stream, n uint32) { - swu, cwu := s.fc.onRead(n) - if swu > 0 { - t.controlBuf.put(&windowUpdate{s.id, swu}) + s.mu.Lock() + defer s.mu.Unlock() + if s.state == streamDone { + return } - if cwu > 0 { - t.controlBuf.put(&windowUpdate{0, cwu}) + if w := t.fc.onRead(n); w > 0 { + t.controlBuf.put(&windowUpdate{0, w}) + } + if w := s.fc.onRead(n); w > 0 { + t.controlBuf.put(&windowUpdate{s.id, w}) } } func (t *http2Client) handleData(f *http2.DataFrame) { + size := len(f.Data()) + if err := t.fc.onData(uint32(size)); err != nil { + t.notifyError(ConnectionErrorf("%v", err)) + return + } // Select the right stream to dispatch. s, ok := t.getStream(f) if !ok { + if w := t.fc.onRead(uint32(size)); w > 0 { + t.controlBuf.put(&windowUpdate{0, w}) + } return } - size := len(f.Data()) if size > 0 { + s.mu.Lock() + if s.state == streamDone { + s.mu.Unlock() + // The stream has been closed. Release the corresponding quota. + if w := t.fc.onRead(uint32(size)); w > 0 { + t.controlBuf.put(&windowUpdate{0, w}) + } + return + } if err := s.fc.onData(uint32(size)); err != nil { - if _, ok := err.(ConnectionError); ok { - t.notifyError(err) - return - } - s.mu.Lock() - if s.state == streamDone { - s.mu.Unlock() - return - } s.state = streamDone s.statusCode = codes.Internal s.statusDesc = err.Error() @@ -599,6 +660,7 @@ func (t *http2Client) handleData(f *http2.DataFrame) { t.controlBuf.put(&resetStream{s.id, http2.ErrCodeFlowControl}) return } + s.mu.Unlock() // TODO(bradfitz, zhaoq): A copy is required here because there is no // guarantee f.Data() is consumed before the arrival of next frame. // Can this copy be eliminated? @@ -637,9 +699,10 @@ func (t *http2Client) handleRSTStream(f *http2.RSTStreamFrame) { close(s.headerChan) s.headerDone = true } - s.statusCode, ok = http2RSTErrConvTab[http2.ErrCode(f.ErrCode)] + s.statusCode, ok = http2ErrConvTab[http2.ErrCode(f.ErrCode)] if !ok { grpclog.Println("transport: http2Client.handleRSTStream found no mapped gRPC status for the received http2 error ", f.ErrCode) + s.statusCode = codes.Unknown } s.mu.Unlock() s.write(recvMsg{err: io.EOF}) @@ -680,54 +743,59 @@ func (t *http2Client) handleWindowUpdate(f *http2.WindowUpdateFrame) { } } -// operateHeader takes action on the decoded headers. It returns the current -// stream if there are remaining headers on the wire (in the following -// Continuation frame). -func (t *http2Client) operateHeaders(hDec *hpackDecoder, s *Stream, frame headerFrame, endStream bool) (pendingStream *Stream) { - defer func() { - if pendingStream == nil { - hDec.state = decodeState{} - } - }() - endHeaders, err := hDec.decodeClientHTTP2Headers(frame) - if s == nil { - // s has been closed. - return nil +// operateHeaders takes action on the decoded headers. +func (t *http2Client) operateHeaders(frame *http2.MetaHeadersFrame) { + s, ok := t.getStream(frame) + if !ok { + return } - if err != nil { - s.write(recvMsg{err: err}) + var state decodeState + for _, hf := range frame.Fields { + state.processHeaderField(hf) + } + if state.err != nil { + s.write(recvMsg{err: state.err}) // Something wrong. Stops reading even when there is remaining. - return nil - } - if !endHeaders { - return s + return } + + endStream := frame.StreamEnded() + s.mu.Lock() if !endStream { - s.recvCompress = hDec.state.encoding + s.recvCompress = state.encoding } if !s.headerDone { - if !endStream && len(hDec.state.mdata) > 0 { - s.header = hDec.state.mdata + if !endStream && len(state.mdata) > 0 { + s.header = state.mdata } close(s.headerChan) s.headerDone = true } if !endStream || s.state == streamDone { s.mu.Unlock() - return nil + return } - if len(hDec.state.mdata) > 0 { - s.trailer = hDec.state.mdata + if len(state.mdata) > 0 { + s.trailer = state.mdata } s.state = streamDone - s.statusCode = hDec.state.statusCode - s.statusDesc = hDec.state.statusDesc + s.statusCode = state.statusCode + s.statusDesc = state.statusDesc s.mu.Unlock() s.write(recvMsg{err: io.EOF}) - return nil +} + +func handleMalformedHTTP2(s *Stream, err error) { + s.mu.Lock() + if !s.headerDone { + close(s.headerChan) + s.headerDone = true + } + s.mu.Unlock() + s.write(recvMsg{err: err}) } // reader runs as a separate goroutine in charge of reading data from network @@ -750,25 +818,31 @@ func (t *http2Client) reader() { } t.handleSettings(sf) - hDec := newHPACKDecoder() - var curStream *Stream // loop to keep reading incoming messages on this transport. for { frame, err := t.framer.readFrame() if err != nil { - t.notifyError(err) - return + // Abort an active stream if the http2.Framer returns a + // http2.StreamError. This can happen only if the server's response + // is malformed http2. + if se, ok := err.(http2.StreamError); ok { + t.mu.Lock() + s := t.activeStreams[se.StreamID] + t.mu.Unlock() + if s != nil { + // use error detail to provide better err message + handleMalformedHTTP2(s, StreamErrorf(http2ErrConvTab[se.Code], "%v", t.framer.errorDetail())) + } + continue + } else { + // Transport error. + t.notifyError(err) + return + } } switch frame := frame.(type) { - case *http2.HeadersFrame: - // operateHeaders has to be invoked regardless the value of curStream - // because the HPACK decoder needs to be updated using the received - // headers. - curStream, _ = t.getStream(frame) - endStream := frame.Header().Flags.Has(http2.FlagHeadersEndStream) - curStream = t.operateHeaders(hDec, curStream, frame, endStream) - case *http2.ContinuationFrame: - curStream = t.operateHeaders(hDec, curStream, frame, frame.HeadersEnded()) + case *http2.MetaHeadersFrame: + t.operateHeaders(frame) case *http2.DataFrame: t.handleData(frame) case *http2.RSTStreamFrame: diff --git a/vendor/google.golang.org/grpc/transport/http2_server.go b/vendor/google.golang.org/grpc/transport/http2_server.go index cce2e12d914..cee15429763 100644 --- a/vendor/google.golang.org/grpc/transport/http2_server.go +++ b/vendor/google.golang.org/grpc/transport/http2_server.go @@ -62,8 +62,8 @@ type http2Server struct { maxStreamID uint32 // max stream ID ever seen authInfo credentials.AuthInfo // auth info about the connection // writableChan synchronizes write access to the transport. - // A writer acquires the write lock by sending a value on writableChan - // and releases it by receiving from writableChan. + // A writer acquires the write lock by receiving a value on writableChan + // and releases it by sending on writableChan. writableChan chan int // shutdownChan is closed when Close is called. // Blocking operations should select on shutdownChan to avoid @@ -100,10 +100,15 @@ func newHTTP2Server(conn net.Conn, maxStreams uint32, authInfo credentials.AuthI if maxStreams == 0 { maxStreams = math.MaxUint32 } else { - settings = append(settings, http2.Setting{http2.SettingMaxConcurrentStreams, maxStreams}) + settings = append(settings, http2.Setting{ + ID: http2.SettingMaxConcurrentStreams, + Val: maxStreams, + }) } if initialWindowSize != defaultWindowSize { - settings = append(settings, http2.Setting{http2.SettingInitialWindowSize, uint32(initialWindowSize)}) + settings = append(settings, http2.Setting{ + ID: http2.SettingInitialWindowSize, + Val: uint32(initialWindowSize)}) } if err := framer.writeSettings(true, settings...); err != nil { return nil, ConnectionErrorf("transport: %v", err) @@ -136,37 +141,34 @@ func newHTTP2Server(conn net.Conn, maxStreams uint32, authInfo credentials.AuthI return t, nil } -// operateHeader takes action on the decoded headers. It returns the current -// stream if there are remaining headers on the wire (in the following -// Continuation frame). -func (t *http2Server) operateHeaders(hDec *hpackDecoder, s *Stream, frame headerFrame, endStream bool, handle func(*Stream)) (pendingStream *Stream) { - defer func() { - if pendingStream == nil { - hDec.state = decodeState{} - } - }() - endHeaders, err := hDec.decodeServerHTTP2Headers(frame) - if s == nil { - // s has been closed. - return nil +// operateHeader takes action on the decoded headers. +func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func(*Stream)) { + buf := newRecvBuffer() + s := &Stream{ + id: frame.Header().StreamID, + st: t, + buf: buf, + fc: &inFlow{limit: initialWindowSize}, } - if err != nil { - grpclog.Printf("transport: http2Server.operateHeader found %v", err) + + var state decodeState + for _, hf := range frame.Fields { + state.processHeaderField(hf) + } + if err := state.err; err != nil { if se, ok := err.(StreamError); ok { t.controlBuf.put(&resetStream{s.id, statusCodeConvTab[se.Code]}) } - return nil + return } - if endStream { + + if frame.StreamEnded() { // s is just created by the caller. No lock needed. s.state = streamReadDone } - if !endHeaders { - return s - } - s.recvCompress = hDec.state.encoding - if hDec.state.timeoutSet { - s.ctx, s.cancel = context.WithTimeout(context.TODO(), hDec.state.timeout) + s.recvCompress = state.encoding + if state.timeoutSet { + s.ctx, s.cancel = context.WithTimeout(context.TODO(), state.timeout) } else { s.ctx, s.cancel = context.WithCancel(context.TODO()) } @@ -183,25 +185,25 @@ func (t *http2Server) operateHeaders(hDec *hpackDecoder, s *Stream, frame header // back to the client (unary call only). s.ctx = newContextWithStream(s.ctx, s) // Attach the received metadata to the context. - if len(hDec.state.mdata) > 0 { - s.ctx = metadata.NewContext(s.ctx, hDec.state.mdata) + if len(state.mdata) > 0 { + s.ctx = metadata.NewContext(s.ctx, state.mdata) } s.dec = &recvBufferReader{ ctx: s.ctx, recv: s.buf, } - s.recvCompress = hDec.state.encoding - s.method = hDec.state.method + s.recvCompress = state.encoding + s.method = state.method t.mu.Lock() if t.state != reachable { t.mu.Unlock() - return nil + return } if uint32(len(t.activeStreams)) >= t.maxStreams { t.mu.Unlock() t.controlBuf.put(&resetStream{s.id, http2.ErrCodeRefusedStream}) - return nil + return } s.sendQuotaPool = newQuotaPool(int(t.streamSendQuota)) t.activeStreams[s.id] = s @@ -210,7 +212,6 @@ func (t *http2Server) operateHeaders(hDec *hpackDecoder, s *Stream, frame header t.updateWindow(s, uint32(n)) } handle(s) - return nil } // HandleStreams receives incoming streams using the given handler. This is @@ -243,16 +244,24 @@ func (t *http2Server) HandleStreams(handle func(*Stream)) { } t.handleSettings(sf) - hDec := newHPACKDecoder() - var curStream *Stream for { frame, err := t.framer.readFrame() if err != nil { + if se, ok := err.(http2.StreamError); ok { + t.mu.Lock() + s := t.activeStreams[se.StreamID] + t.mu.Unlock() + if s != nil { + t.closeStream(s) + } + t.controlBuf.put(&resetStream{se.StreamID, se.Code}) + continue + } t.Close() return } switch frame := frame.(type) { - case *http2.HeadersFrame: + case *http2.MetaHeadersFrame: id := frame.Header().StreamID if id%2 != 1 || id <= t.maxStreamID { // illegal gRPC stream id. @@ -261,21 +270,7 @@ func (t *http2Server) HandleStreams(handle func(*Stream)) { break } t.maxStreamID = id - buf := newRecvBuffer() - fc := &inFlow{ - limit: initialWindowSize, - conn: t.fc, - } - curStream = &Stream{ - id: frame.Header().StreamID, - st: t, - buf: buf, - fc: fc, - } - endStream := frame.Header().Flags.Has(http2.FlagHeadersEndStream) - curStream = t.operateHeaders(hDec, curStream, frame, endStream, handle) - case *http2.ContinuationFrame: - curStream = t.operateHeaders(hDec, curStream, frame, frame.HeadersEnded(), handle) + t.operateHeaders(frame, handle) case *http2.DataFrame: t.handleData(frame) case *http2.RSTStreamFrame: @@ -313,33 +308,51 @@ func (t *http2Server) getStream(f http2.Frame) (*Stream, bool) { // Window updates will deliver to the controller for sending when // the cumulative quota exceeds the corresponding threshold. func (t *http2Server) updateWindow(s *Stream, n uint32) { - swu, cwu := s.fc.onRead(n) - if swu > 0 { - t.controlBuf.put(&windowUpdate{s.id, swu}) + s.mu.Lock() + defer s.mu.Unlock() + if s.state == streamDone { + return } - if cwu > 0 { - t.controlBuf.put(&windowUpdate{0, cwu}) + if w := t.fc.onRead(n); w > 0 { + t.controlBuf.put(&windowUpdate{0, w}) + } + if w := s.fc.onRead(n); w > 0 { + t.controlBuf.put(&windowUpdate{s.id, w}) } } func (t *http2Server) handleData(f *http2.DataFrame) { + size := len(f.Data()) + if err := t.fc.onData(uint32(size)); err != nil { + grpclog.Printf("transport: http2Server %v", err) + t.Close() + return + } // Select the right stream to dispatch. s, ok := t.getStream(f) if !ok { + if w := t.fc.onRead(uint32(size)); w > 0 { + t.controlBuf.put(&windowUpdate{0, w}) + } return } - size := len(f.Data()) if size > 0 { - if err := s.fc.onData(uint32(size)); err != nil { - if _, ok := err.(ConnectionError); ok { - grpclog.Printf("transport: http2Server %v", err) - t.Close() - return + s.mu.Lock() + if s.state == streamDone { + s.mu.Unlock() + // The stream has been closed. Release the corresponding quota. + if w := t.fc.onRead(uint32(size)); w > 0 { + t.controlBuf.put(&windowUpdate{0, w}) } + return + } + if err := s.fc.onData(uint32(size)); err != nil { + s.mu.Unlock() t.closeStream(s) t.controlBuf.put(&resetStream{s.id, http2.ErrCodeFlowControl}) return } + s.mu.Unlock() // TODO(bradfitz, zhaoq): A copy is required here because there is no // guarantee f.Data() is consumed before the arrival of next frame. // Can this copy be eliminated? @@ -452,6 +465,10 @@ func (t *http2Server) WriteHeader(s *Stream, md metadata.MD) error { t.hEnc.WriteField(hpack.HeaderField{Name: "grpc-encoding", Value: s.sendCompress}) } for k, v := range md { + if isReservedHeader(k) { + // Clients don't tolerate reading restricted headers after some non restricted ones were sent. + continue + } for _, entry := range v { t.hEnc.WriteField(hpack.HeaderField{Name: k, Value: entry}) } @@ -494,6 +511,10 @@ func (t *http2Server) WriteStatus(s *Stream, statusCode codes.Code, statusDesc s t.hEnc.WriteField(hpack.HeaderField{Name: "grpc-message", Value: statusDesc}) // Attach the trailer metadata. for k, v := range s.trailer { + // Clients don't tolerate reading restricted headers after some non restricted ones were sent. + if isReservedHeader(k) { + continue + } for _, entry := range v { t.hEnc.WriteField(hpack.HeaderField{Name: k, Value: entry}) } @@ -513,6 +534,10 @@ func (t *http2Server) Write(s *Stream, data []byte, opts *Options) error { // TODO(zhaoq): Support multi-writers for a single stream. var writeHeaderFrame bool s.mu.Lock() + if s.state == streamDone { + s.mu.Unlock() + return StreamErrorf(codes.Unknown, "the stream has been done") + } if !s.headerOk { writeHeaderFrame = true s.headerOk = true @@ -580,6 +605,10 @@ func (t *http2Server) Write(s *Stream, data []byte, opts *Options) error { // Got some quota. Try to acquire writing privilege on the // transport. if _, err := wait(s.ctx, t.shutdownChan, t.writableChan); err != nil { + if _, ok := err.(StreamError); ok { + // Return the connection quota back. + t.sendQuotaPool.add(ps) + } if t.framer.adjustNumWriters(-1) == 0 { // This writer is the last one in this batch and has the // responsibility to flush the buffered frames. It queues @@ -589,6 +618,16 @@ func (t *http2Server) Write(s *Stream, data []byte, opts *Options) error { } return err } + select { + case <-s.ctx.Done(): + t.sendQuotaPool.add(ps) + if t.framer.adjustNumWriters(-1) == 0 { + t.controlBuf.put(&flushIO{}) + } + t.writableChan <- 0 + return ContextErr(s.ctx.Err()) + default: + } var forceFlush bool if r.Len() == 0 && t.framer.adjustNumWriters(0) == 1 && !opts.Last { forceFlush = true @@ -686,20 +725,22 @@ func (t *http2Server) closeStream(s *Stream) { t.mu.Lock() delete(t.activeStreams, s.id) t.mu.Unlock() - if q := s.fc.restoreConn(); q > 0 { - t.controlBuf.put(&windowUpdate{0, q}) - } + // In case stream sending and receiving are invoked in separate + // goroutines (e.g., bi-directional streaming), cancel needs to be + // called to interrupt the potential blocking on other goroutines. + s.cancel() s.mu.Lock() + if q := s.fc.resetPendingData(); q > 0 { + if w := t.fc.onRead(q); w > 0 { + t.controlBuf.put(&windowUpdate{0, w}) + } + } if s.state == streamDone { s.mu.Unlock() return } s.state = streamDone s.mu.Unlock() - // In case stream sending and receiving are invoked in separate - // goroutines (e.g., bi-directional streaming), cancel needs to be - // called to interrupt the potential blocking on other goroutines. - s.cancel() } func (t *http2Server) RemoteAddr() net.Addr { diff --git a/vendor/google.golang.org/grpc/transport/http_util.go b/vendor/google.golang.org/grpc/transport/http_util.go index f9d9fdf0afd..f2e23dcec38 100644 --- a/vendor/google.golang.org/grpc/transport/http_util.go +++ b/vendor/google.golang.org/grpc/transport/http_util.go @@ -62,13 +62,14 @@ const ( ) var ( - clientPreface = []byte(http2.ClientPreface) - http2RSTErrConvTab = map[http2.ErrCode]codes.Code{ + clientPreface = []byte(http2.ClientPreface) + http2ErrConvTab = map[http2.ErrCode]codes.Code{ http2.ErrCodeNo: codes.Internal, http2.ErrCodeProtocol: codes.Internal, http2.ErrCodeInternal: codes.Internal, http2.ErrCodeFlowControl: codes.ResourceExhausted, http2.ErrCodeSettingsTimeout: codes.Internal, + http2.ErrCodeStreamClosed: codes.Internal, http2.ErrCodeFrameSize: codes.Internal, http2.ErrCodeRefusedStream: codes.Unavailable, http2.ErrCodeCancel: codes.Canceled, @@ -76,6 +77,7 @@ var ( http2.ErrCodeConnect: codes.Internal, http2.ErrCodeEnhanceYourCalm: codes.ResourceExhausted, http2.ErrCodeInadequateSecurity: codes.PermissionDenied, + http2.ErrCodeHTTP11Required: codes.FailedPrecondition, } statusCodeConvTab = map[codes.Code]http2.ErrCode{ codes.Internal: http2.ErrCodeInternal, @@ -89,6 +91,8 @@ var ( // Records the states during HPACK decoding. Must be reset once the // decoding of the entire headers are finished. type decodeState struct { + err error // first error encountered decoding + encoding string // statusCode caches the stream status received from the trailer // the server sent. Client side only. @@ -102,25 +106,11 @@ type decodeState struct { mdata map[string][]string } -// An hpackDecoder decodes HTTP2 headers which may span multiple frames. -type hpackDecoder struct { - h *hpack.Decoder - state decodeState - err error // The err when decoding -} - -// A headerFrame is either a http2.HeaderFrame or http2.ContinuationFrame. -type headerFrame interface { - Header() http2.FrameHeader - HeaderBlockFragment() []byte - HeadersEnded() bool -} - // isReservedHeader checks whether hdr belongs to HTTP2 headers // reserved by gRPC protocol. Any other headers are classified as the // user-specified metadata. func isReservedHeader(hdr string) bool { - if hdr[0] == ':' { + if hdr != "" && hdr[0] == ':' { return true } switch hdr { @@ -137,100 +127,86 @@ func isReservedHeader(hdr string) bool { } } -func newHPACKDecoder() *hpackDecoder { - d := &hpackDecoder{} - d.h = hpack.NewDecoder(http2InitHeaderTableSize, func(f hpack.HeaderField) { - switch f.Name { - case "content-type": - if !strings.Contains(f.Value, "application/grpc") { - d.err = StreamErrorf(codes.FailedPrecondition, "transport: received the unexpected header") - return - } - case "grpc-encoding": - d.state.encoding = f.Value - case "grpc-status": - code, err := strconv.Atoi(f.Value) - if err != nil { - d.err = StreamErrorf(codes.Internal, "transport: malformed grpc-status: %v", err) - return - } - d.state.statusCode = codes.Code(code) - case "grpc-message": - d.state.statusDesc = f.Value - case "grpc-timeout": - d.state.timeoutSet = true - var err error - d.state.timeout, err = timeoutDecode(f.Value) - if err != nil { - d.err = StreamErrorf(codes.Internal, "transport: malformed time-out: %v", err) - return - } - case ":path": - d.state.method = f.Value - default: - if !isReservedHeader(f.Name) { - if f.Name == "user-agent" { - i := strings.LastIndex(f.Value, " ") - if i == -1 { - // There is no application user agent string being set. - return - } - // Extract the application user agent string. - f.Value = f.Value[:i] - } - if d.state.mdata == nil { - d.state.mdata = make(map[string][]string) - } - k, v, err := metadata.DecodeKeyValue(f.Name, f.Value) - if err != nil { - grpclog.Printf("Failed to decode (%q, %q): %v", f.Name, f.Value, err) +// isWhitelistedPseudoHeader checks whether hdr belongs to HTTP2 pseudoheaders +// that should be propagated into metadata visible to users. +func isWhitelistedPseudoHeader(hdr string) bool { + switch hdr { + case ":authority": + return true + default: + return false + } +} + +func (d *decodeState) setErr(err error) { + if d.err == nil { + d.err = err + } +} + +func validContentType(t string) bool { + e := "application/grpc" + if !strings.HasPrefix(t, e) { + return false + } + // Support variations on the content-type + // (e.g. "application/grpc+blah", "application/grpc;blah"). + if len(t) > len(e) && t[len(e)] != '+' && t[len(e)] != ';' { + return false + } + return true +} + +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)) + return + } + case "grpc-encoding": + d.encoding = f.Value + case "grpc-status": + code, err := strconv.Atoi(f.Value) + if err != nil { + d.setErr(StreamErrorf(codes.Internal, "transport: malformed grpc-status: %v", err)) + return + } + d.statusCode = codes.Code(code) + case "grpc-message": + d.statusDesc = f.Value + case "grpc-timeout": + d.timeoutSet = true + var err error + d.timeout, err = timeoutDecode(f.Value) + if err != nil { + d.setErr(StreamErrorf(codes.Internal, "transport: malformed time-out: %v", err)) + return + } + case ":path": + d.method = f.Value + default: + if !isReservedHeader(f.Name) || isWhitelistedPseudoHeader(f.Name) { + if f.Name == "user-agent" { + i := strings.LastIndex(f.Value, " ") + if i == -1 { + // There is no application user agent string being set. return } - d.state.mdata[k] = append(d.state.mdata[k], v) + // Extract the application user agent string. + f.Value = f.Value[:i] } + if d.mdata == nil { + d.mdata = make(map[string][]string) + } + k, v, err := metadata.DecodeKeyValue(f.Name, f.Value) + if err != nil { + grpclog.Printf("Failed to decode (%q, %q): %v", f.Name, f.Value, err) + return + } + d.mdata[k] = append(d.mdata[k], v) } - }) - return d -} - -func (d *hpackDecoder) decodeClientHTTP2Headers(frame headerFrame) (endHeaders bool, err error) { - d.err = nil - _, err = d.h.Write(frame.HeaderBlockFragment()) - if err != nil { - err = StreamErrorf(codes.Internal, "transport: HPACK header decode error: %v", err) } - - if frame.HeadersEnded() { - if closeErr := d.h.Close(); closeErr != nil && err == nil { - err = StreamErrorf(codes.Internal, "transport: HPACK decoder close error: %v", closeErr) - } - endHeaders = true - } - - if err == nil && d.err != nil { - err = d.err - } - return -} - -func (d *hpackDecoder) decodeServerHTTP2Headers(frame headerFrame) (endHeaders bool, err error) { - d.err = nil - _, err = d.h.Write(frame.HeaderBlockFragment()) - if err != nil { - err = StreamErrorf(codes.Internal, "transport: HPACK header decode error: %v", err) - } - - if frame.HeadersEnded() { - if closeErr := d.h.Close(); closeErr != nil && err == nil { - err = StreamErrorf(codes.Internal, "transport: HPACK decoder close error: %v", closeErr) - } - endHeaders = true - } - - if err == nil && d.err != nil { - err = d.err - } - return } type timeoutUnit uint8 @@ -321,10 +297,11 @@ type framer struct { func newFramer(conn net.Conn) *framer { f := &framer{ - reader: conn, + reader: bufio.NewReaderSize(conn, http2IOBufSize), writer: bufio.NewWriterSize(conn, http2IOBufSize), } f.fr = http2.NewFramer(f.writer, f.reader) + f.fr.ReadMetaHeaders = hpack.NewDecoder(http2InitHeaderTableSize, nil) return f } @@ -452,3 +429,7 @@ func (f *framer) flushWrite() error { func (f *framer) readFrame() (http2.Frame, error) { return f.fr.ReadFrame() } + +func (f *framer) errorDetail() error { + return f.fr.ErrorDetail() +} diff --git a/vendor/google.golang.org/grpc/transport/transport.go b/vendor/google.golang.org/grpc/transport/transport.go index d99233d2ea2..599f25d177c 100644 --- a/vendor/google.golang.org/grpc/transport/transport.go +++ b/vendor/google.golang.org/grpc/transport/transport.go @@ -63,13 +63,11 @@ type recvMsg struct { err error } -func (recvMsg) isItem() bool { - return true -} +func (*recvMsg) item() {} // All items in an out of a recvBuffer should be the same type. type item interface { - isItem() bool + item() } // recvBuffer is an unbounded channel of item. @@ -89,12 +87,14 @@ func newRecvBuffer() *recvBuffer { func (b *recvBuffer) put(r item) { b.mu.Lock() defer b.mu.Unlock() - b.backlog = append(b.backlog, r) - select { - case b.c <- b.backlog[0]: - b.backlog = b.backlog[1:] - default: + if len(b.backlog) == 0 { + select { + case b.c <- r: + return + default: + } } + b.backlog = append(b.backlog, r) } func (b *recvBuffer) load() { @@ -299,20 +299,18 @@ func (s *Stream) Read(p []byte) (n int, err error) { return } -type key int - // The key to save transport.Stream in the context. -const streamKey = key(0) +type streamKey struct{} // newContextWithStream creates a new context from ctx and attaches stream // to it. func newContextWithStream(ctx context.Context, stream *Stream) context.Context { - return context.WithValue(ctx, streamKey, stream) + return context.WithValue(ctx, streamKey{}, stream) } // StreamFromContext returns the stream saved in ctx. func StreamFromContext(ctx context.Context) (s *Stream, ok bool) { - s, ok = ctx.Value(streamKey).(*Stream) + s, ok = ctx.Value(streamKey{}).(*Stream) return } @@ -323,6 +321,7 @@ const ( reachable transportState = iota unreachable closing + draining ) // NewServerTransport creates a ServerTransport with conn or non-nil error @@ -337,9 +336,11 @@ type ConnectOptions struct { UserAgent string // Dialer specifies how to dial a network address. Dialer func(string, time.Duration) (net.Conn, error) - // AuthOptions stores the credentials required to setup a client connection and/or issue RPCs. - AuthOptions []credentials.Credentials - // Timeout specifies the timeout for dialing a client connection. + // PerRPCCredentials stores the PerRPCCredentials required to issue RPCs. + PerRPCCredentials []credentials.PerRPCCredentials + // TransportCredentials stores the Authenticator required to setup a client connection. + TransportCredentials credentials.TransportCredentials + // Timeout specifies the timeout for dialing a ClientTransport. Timeout time.Duration } @@ -352,30 +353,40 @@ func NewClientTransport(target string, opts *ConnectOptions) (ClientTransport, e // Options provides additional hints and information for message // transmission. type Options struct { - // Indicate whether it is the last piece for this stream. + // Last indicates whether this write is the last piece for + // this stream. Last bool - // The hint to transport impl whether the data could be buffered for - // batching write. Transport impl can feel free to ignore it. + + // Delay is a hint to the transport implementation for whether + // the data could be buffered for a batching write. The + // Transport implementation may ignore the hint. Delay bool } // CallHdr carries the information of a particular RPC. type CallHdr struct { - // Host specifies peer host. + // Host specifies the peer's host. Host string + // Method specifies the operation to perform. Method string - // RecvCompress specifies the compression algorithm applied on inbound messages. + + // RecvCompress specifies the compression algorithm applied on + // inbound messages. RecvCompress string - // SendCompress specifies the compression algorithm applied on outbound message. + + // SendCompress specifies the compression algorithm applied on + // outbound message. SendCompress string - // Flush indicates if new stream command should be sent to the peer without - // waiting for the first data. This is a hint though. The transport may modify - // the flush decision for performance purpose. + + // Flush indicates whether a new stream command should be sent + // to the peer without waiting for the first data. This is + // only a hint. The transport may modify the flush decision + // for performance purposes. Flush bool } -// ClientTransport is the common interface for all gRPC client side transport +// ClientTransport is the common interface for all gRPC client-side transport // implementations. type ClientTransport interface { // Close tears down this transport. Once it returns, the transport @@ -383,6 +394,10 @@ type ClientTransport interface { // is called only once. Close() error + // GracefulClose starts to tear down the transport. It stops accepting + // new RPCs and wait the completion of the pending RPCs. + GracefulClose() error + // Write sends the data for the given stream. A nil stream indicates // the write is to be performed on the transport as a whole. Write(s *Stream, data []byte, opts *Options) error @@ -404,21 +419,33 @@ type ClientTransport interface { Error() <-chan struct{} } -// ServerTransport is the common interface for all gRPC server side transport +// ServerTransport is the common interface for all gRPC server-side transport // implementations. +// +// Methods may be called concurrently from multiple goroutines, but +// Write methods for a given Stream will be called serially. type ServerTransport interface { - // WriteStatus sends the status of a stream to the client. - WriteStatus(s *Stream, statusCode codes.Code, statusDesc string) error - // Write sends the data for the given stream. - Write(s *Stream, data []byte, opts *Options) error - // WriteHeader sends the header metedata for the given stream. - WriteHeader(s *Stream, md metadata.MD) error // HandleStreams receives incoming streams using the given handler. HandleStreams(func(*Stream)) + + // WriteHeader sends the header metadata for the given stream. + // WriteHeader may not be called on all streams. + WriteHeader(s *Stream, md metadata.MD) error + + // Write sends the data for the given stream. + // Write may not be called on all streams. + Write(s *Stream, data []byte, opts *Options) error + + // WriteStatus sends the status of a stream to the client. + // WriteStatus is the final call made on a stream and always + // occurs. + WriteStatus(s *Stream, statusCode codes.Code, statusDesc string) error + // Close tears down the transport. Once it is called, the transport // should not be accessed any more. All the pending streams and their // handlers will be terminated asynchronously. Close() error + // RemoteAddr returns the remote network address. RemoteAddr() net.Addr } @@ -448,7 +475,7 @@ func (e ConnectionError) Error() string { return fmt.Sprintf("connection error: desc = %q", e.Desc) } -// Define some common ConnectionErrors. +// ErrConnClosing indicates that the transport is closing. var ErrConnClosing = ConnectionError{Desc: "transport is closing"} // StreamError is an error that only affects one stream within a connection. diff --git a/vendor/gopkg.in/yaml.v2/.travis.yml b/vendor/gopkg.in/yaml.v2/.travis.yml deleted file mode 100644 index 004172a2e37..00000000000 --- a/vendor/gopkg.in/yaml.v2/.travis.yml +++ /dev/null @@ -1,9 +0,0 @@ -language: go - -go: - - 1.4 - - 1.5 - - 1.6 - - tip - -go_import_path: gopkg.in/yaml.v2 diff --git a/vendor/gopkg.in/yaml.v2/readerc.go b/vendor/gopkg.in/yaml.v2/readerc.go index f450791717b..d5fb0972772 100644 --- a/vendor/gopkg.in/yaml.v2/readerc.go +++ b/vendor/gopkg.in/yaml.v2/readerc.go @@ -247,7 +247,7 @@ func yaml_parser_update_buffer(parser *yaml_parser_t, length int) bool { if parser.encoding == yaml_UTF16LE_ENCODING { low, high = 0, 1 } else { - low, high = 1, 0 + high, low = 1, 0 } // The UTF-16 encoding is not as simple as one might @@ -357,26 +357,23 @@ func yaml_parser_update_buffer(parser *yaml_parser_t, length int) bool { if value <= 0x7F { // 0000 0000-0000 007F . 0xxxxxxx parser.buffer[buffer_len+0] = byte(value) - buffer_len += 1 } else if value <= 0x7FF { // 0000 0080-0000 07FF . 110xxxxx 10xxxxxx parser.buffer[buffer_len+0] = byte(0xC0 + (value >> 6)) parser.buffer[buffer_len+1] = byte(0x80 + (value & 0x3F)) - buffer_len += 2 } else if value <= 0xFFFF { // 0000 0800-0000 FFFF . 1110xxxx 10xxxxxx 10xxxxxx parser.buffer[buffer_len+0] = byte(0xE0 + (value >> 12)) parser.buffer[buffer_len+1] = byte(0x80 + ((value >> 6) & 0x3F)) parser.buffer[buffer_len+2] = byte(0x80 + (value & 0x3F)) - buffer_len += 3 } else { // 0001 0000-0010 FFFF . 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx parser.buffer[buffer_len+0] = byte(0xF0 + (value >> 18)) parser.buffer[buffer_len+1] = byte(0x80 + ((value >> 12) & 0x3F)) parser.buffer[buffer_len+2] = byte(0x80 + ((value >> 6) & 0x3F)) parser.buffer[buffer_len+3] = byte(0x80 + (value & 0x3F)) - buffer_len += 4 } + buffer_len += width parser.unread++ } diff --git a/vendor/gopkg.in/yaml.v2/scannerc.go b/vendor/gopkg.in/yaml.v2/scannerc.go index 25808000f28..d97d76fa55c 100644 --- a/vendor/gopkg.in/yaml.v2/scannerc.go +++ b/vendor/gopkg.in/yaml.v2/scannerc.go @@ -1546,7 +1546,7 @@ func yaml_parser_scan_directive(parser *yaml_parser_t, token *yaml_token_t) bool // Unknown directive. } else { yaml_parser_set_scanner_error(parser, "while scanning a directive", - start_mark, "found unknown directive name") + start_mark, "found uknown directive name") return false } diff --git a/vendor/gopkg.in/yaml.v2/yaml.go b/vendor/gopkg.in/yaml.v2/yaml.go index 36d6b883a6c..d133edf9d34 100644 --- a/vendor/gopkg.in/yaml.v2/yaml.go +++ b/vendor/gopkg.in/yaml.v2/yaml.go @@ -222,7 +222,7 @@ func getStructInfo(st reflect.Type) (*structInfo, error) { inlineMap := -1 for i := 0; i != n; i++ { field := st.Field(i) - if field.PkgPath != "" && !field.Anonymous { + if field.PkgPath != "" { continue // Private field }